Kubernetes

[ Kans 3 Study - 1.3 ] 컨테이너 네트워크 & IP Tables (2)

su''@ 2024. 9. 1. 03:36

[ 2. 도커 네트워크 모델 ]

2.0 도커 네트워크 모드
  • 기본 네트워크 모드 : Bridge, Host, None + 추가 네트워크 플러그인 : macvlan, ipvlan, overlay
    docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    5d4ec64ed746   bridge    bridge    local
    71da3212e9dc   host      host      local
    90a304de3e67   none      null      local
    
    docker info | grep Network
      Network: bridge host ipvlan macvlan null overlay
    • Host 는 호스트의 환경을 그대로 사용. 애플리케이션 별도 포트 포워딩 없이 바로 서비스 가능. 컨테이너의 호스트 이름도 호스트 머신의 이름과 동일.
    • None 는 말 그래도 아무런 네트워크를 쓰지 않는 것. 외부와의 연결이 단절됨. 컨테이너 내부에 lo 인터페이스만 존재.
    • http://www.abusedbits.com/2016/09/docker-host-networking-modes.html

 

2.1 Bridge 모드
    • Bridge 모드 기본 정보 확인
      • 도커에서 기본적으로 쓸 수 있는 네트워크 확인, 컨테이너 기본 생성 시 자동으로 docker0 브리지를 사용
      • 기본 172.17.0.0/16 대역을 컨테이너가 사용, 대역 변경 설정 가능
      • 도커는 IPtables 의 PREROUTING POSTROUTING 의 NAT Chains 를 변경한다
        • 컨테이너 → 외부 : POSTROUTING 의 SNAT 처리
        • 외부 → 컨테이너(Exposed services ports) : PREROUTING 에서 DNAT 처리
    • # 도커 네트워크 모드 확인
      docker network ls
      NETWORK ID          NAME                DRIVER              SCOPE
      a22960517f11        bridge              bridge              local
      def31be9614b        host                host                local
      f0bf6fd89f14        none                null                local
      
      # 도커 네트워크(플러그인) 정보 확인
      docker info
      docker info | grep Network
      
      # 도커 bridge 상세 정보 확인 = docker inspect --type network bridge 동일
      # 아래 "Gateway": "172.17.0.1" 정보가 출력되지 않을 경우에는 systemctl restart docker 입력 후 다시 확인
      docker network inspect bridge | jq
      [
          {
              "Name": "bridge",
              "Id": "7c0902c8e4521b25b6a1233b018886256c8f877fed6a088a1a97e54804135613",
              "Created": "2021-10-14T12:22:52.869292205Z",
              "Scope": "local",
              "Driver": "bridge",
              "EnableIPv6": false,
              "IPAM": {
                  "Driver": "default",
                  "Options": null,
                  "Config": [
                      {
                          "Subnet": "172.17.0.0/16",
                          "Gateway": "172.17.0.1"
                      }
                  ]
              },
              "Internal": false,
              "Attachable": false,
              "Ingress": false,
              "ConfigFrom": {
                  "Network": ""
              },
              "ConfigOnly": false,
              "Containers": {},
              "Options": {
                  "com.docker.network.bridge.default_bridge": "true",
                  "com.docker.network.bridge.enable_icc": "true",
                  "com.docker.network.bridge.enable_ip_masquerade": "true",
                  "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
                  "com.docker.network.bridge.name": "docker0",
                  "com.docker.network.driver.mtu": "1500"
              },
              "Labels": {}
          }
      ]
      
      # 브릿지 확인
      brctl show
      bridge name 	bridge id		       STP enabled	interfaces
      docker0	    	8000.024229821c4f	 no
      
      # 네트워크 인터페이스 확인
      ip -c addr show docker0
      4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
          link/ether 02:42:29:82:1c:4f brd ff:ff:ff:ff:ff:ff
          inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
             valid_lft forever preferred_lft forever
      
      # SNAT 정책 확인
      iptables -t nat -S
      iptables -t nat -S | grep MASQUERADE
      -A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
      
      # 라우팅 확인
      ip -c route | grep docker0
      172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown



    • 컨테이너(busybox) 2대 생성
      # 터미널1 (PINK) : PINK 이름의 busybox 컨테이너 생성
      docker run -it --name=PINK --rm busybox
      ip a
      ip neigh
      
      # 터미널3 (ORANGE) : ORANGE 이름의 busybox 컨테이너 생성
      docker run -it --name=ORANGE --rm busybox
      ip a
      ip neigh
      
      # 터미널2 (호스트)
      ## 컨테이너 생성 확인
      docker ps
      
      ## veth 에 각각 서로 연결되는 veth peer 가 추가됬음을 확인, docker UP 확인
      ip -br -c link
      
      ## 브릿지 정보 확인
      brctl show docker0


    • 컨테이너간 통신 확인
      # 터미널2 (호스트)
      tcpdump -i docker0 -n
      iptables -t filter -S
      	-A FORWARD -i docker0 -o docker0 -j ACCEPT # 컨테이너 끼리는 FORWARD 가 ACCEPT(허용)
      
      # 터미널1 (PINK)
      ## ORANGE 로 ping 테스트(IP는 다를 수 있습니다)
      ping -c 1 172.17.0.3
      ip neigh
      route -n
      
      # 터미널3 (ORNAGE)
      ## ORANGE 로 ping 테스트(IP는 다를 수 있습니다)
      ping -c 1 172.17.0.2
      ip neigh
      route -n


    • 컨테이너에서 외부로 통신
      # 터미널2 (호스트)
      tcpdump -i any icmp
      iptables -t nat -S
      	-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
      conntrack -L --src-nat
      	icmp     1 29 src=172.17.0.5 dst=8.8.8.8 type=8 code=0 id=7 src=8.8.8.8 dst=10.0.2.15 type=0 code=0 id=7 mark=0 use=1
      	conntrack v1.4.5 (conntrack-tools): 1 flow entries have been shown.
      
      # 터미널1 (PINK)
      ping 8.8.8.8
      exit # 실습 완료 후
      
      # 터미널3 (ORNAGE)
      ping 8.8.8.8
      exit # 실습 완료 후