Docker-compose 이해를 위한 Docker Network (1)

삽질장인·2021년 1월 25일
0
post-custom-banner

Docker-compose?

docker를 사용시 여러 컨테이너를 엮어 사용하는 것을 통합적으로 관리할 수 있도록 해주는것. 그것이 바로 Docker-compose다.
기본적으로 Docker 와 동일한 명령어 구조를 가지기 때문에 방식만 알면 어려운 것은 없고, 작성하는 방식도 Dockerfile 와 유사한 방식을 갖고 있다.

다만 큰 차이점이 있다면 Docker-compose로 컨테이너를 동작 시킬때 도커의 기본 네트워크 대역과 별도의 네트워크 대역폭을 지정해주어 배포해준다는 차이점이 있다.

이때 네트워크 대역을 별도로 생성해준다는건 뭘까?
하나하나 알아보도록 하자.

도커 네트워크

도커 네트워크의 구조는 위 사진과 같다.
docker host 부분은 도커를 동작시키는 메인 서버를 의미한다.
eth0(검정), veth1, docker0, eth0(빨강) 총 네가지의 무언가가 있는데, 이들은 전부 가상화 네트워크 인터페이스의 이름을 의미한다.

그림을 대충 보고 보이는대로 이야기 해보자.

  1. 컨테이너는 각자 인터넷 인터페이스 eth0을 갖고 있고,
  2. 각 컨테이너의 eth0와 연결된 veth가 있고
  3. 외부 네트워크와 교류하는 빨강 eth0가 docker0 랑 연결되서 veth들한테 뭔가 해주나보네?

벌써 절반 이해한거다.

eth0 (검정)

컨테이너 내에서 동작하는 os의 IP 주소를 갖고있는 NIC(Network Interface Card) 를 의미한다.

[root@server2 ~]# docker exec ubuntu1 ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:02
          inet addr:172.17.0.2  Bcast:172.17.255.255  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:5 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:426 (426.0 B)  TX bytes:0 (0.0 B)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

컨테이너 내의 ifconfig를 하였을때 확인 가능한 정보이다. eth0 항목으로 아이피 주소와 함께 루프백 아이피 (localhost) 를 확인할 수 있다.

veth (virtual ethernet)

호스트 서버(도커를 실행중인 리눅스) 에서 ifconfig를 입력해보자.

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:16ff:fe0e:c2c4  prefixlen 64  scopeid 0x20<link>
        ether 02:42:16:0e:c2:c4  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12  bytes 1676 (1.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.89.139  netmask 255.255.255.0  broadcast 192.168.89.255
        inet6 fe80::fb29:61eb:338c:2633  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::671f:d30c:4d83:9620  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:ea:c1:a8  txqueuelen 1000  (Ethernet)
        RX packets 42215  bytes 61369366 (58.5 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2527  bytes 247403 (241.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

veth8936142: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::8036:50ff:febf:be7d  prefixlen 64  scopeid 0x20<link>
        ether 82:36:50:bf:be:7d  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20  bytes 2332 (2.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

우리가 사진에서 봤던 용어였던 docker0 과 veth가 있는것을 확인할 수 있다.
여기서 veth 부분을 자세히 보면 자체적인 아이피 주소를 갖고있지 않다는 것을 확인할 수 있다.

veth는 컨테이너 내의 eth0에게 외부 네트워크 정보를 전달해주어 네트워크 기능을 사용할 수 있도록 해주는 역할을 한다고 한다.
강사님은 이때 인터넷과 연결된 PC와 인터넷연결이 되지 않은 다른 PC를 크로스케이블형태로 제작된 랜선으로 연결하면 다른 PC도 인터넷이 되도록 하는 형태라며 비유했다.

docker 0 (브릿지)

docker0 역시 ifconfig 로 확인이 가능했다.

docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:16ff:fe0e:c2c4  prefixlen 64  scopeid 0x20<link>
        ether 02:42:16:0e:c2:c4  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 12  bytes 1676 (1.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

docker0는 veth들과 eth0(빨강) 과 연결되는데, 외부 네트워크에서 요청된 패킷의 경로를 알맞은 컨테이너로 전달해주는 역할을 한다.
또한 특정 네트워크 대역을 가진 브릿지 역할을 하면서, 해당 ip 대역을 활용할 수 있도록 gateway를 포함한다. 이때 게이트웨이는 docker0 를 ifconfig로 172.17.0.1 임을 확인할 수 있다. 게이트웨이에 대한 정보는 아래에 bridge 소항목에서 다시 한번 연결지어 설명한다!

iptraf-ng 로 docker0와 veth의 패킷 정보 확인하기

yum -y install iptraf-ng

호스트스 서버에 설치했던 nginx 컨테이너를 동작시킨 후, 다른 세션으로 접속한 뒤에 iptraf-ng 를 입력하여 프로세스를 동작하여 패킷이 어디서 전달되고 있는지를 확인해보자.

실행 후 위와 같은 메뉴가 표기되는데, 하이라이트 된 General interface statistics로 진입.

Loop back: 로컬테스트 네트워크 주소
ens32 : 호스트 서버의 네트워크 인터페이스
virbr0: NAT 설정을 위한 네트워크 인터페이스
docker0 : 외부 네트워크를 컨테이너들에게 알맞게 할당시켜주는 브릿지

우린 컨테이너와 연결된 docker0 와 veth에 패킷이 들어와 수치가 증가하는 것을 확인할 것이다. nginx 컨테이너로 구동한 웹 서버에서 새로고침을 연타해보자.

docker0 는 veth와 함께 동일 량의 패킷을 읽어오는 것을 확인 해 볼 수 있습니다.
즉, 도커 컨테이너 네트워크에 진입시 흐름은 아래와 같습니다.

  1. 외부 네트워크와 연결된 ens0(빨강) 에서 docker0 로 패킷을 전달
  2. docker0가 요청에 알맞는 패킷정보를 veth에 전달하고 veth는 자신과 연결된 컨테이너 내의 eth0 에 할당
  3. nginx 에서 요청받은 정보를 반환한다.

도커 네트워크 세부구조

[root@server ~2]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
3ff9ff689e9e   bridge    bridge    local
c9e590a32ede   host      host      local
4bf4f35e4f41   none      null      local

docker network ls 로 현재 도커 네트워크의 목록들을 확인할 수 있습니다.
기본적으로 bridge와 host, none 이 있고 각 역할은 아래와 같습니다.

  1. bridge는 컨테이너들이 가질 네트워크의 대역을 잡아주는 역할.
  2. host는 호스트 서버(docker가 깔린 리눅스)의 아이피 네트워크를 활용
  3. none 은 툭정 컨테이너에서 네트워크를 사용하지 않을때 사용하는 옵션.

bridge

network ls 옵션으로 확인한 아이디를 갖고 inpect 옵션으로 세부정보를 확인해보자.

[root@server2 ~]# docker network inspect 3ff9ff689e9e
[
    {
        "Name": "bridge",
        "Id": "3ff9ff689e9e85a3232b9b1dce01004bf8f96121d7e7c37bd6f51739ea5beefd",
        "Created": "2021-01-26T00:23:32.043866388+09:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"
                }
            ]
        },

subnet 항목이 172.17.0.0/16 로 잡혀있고. 이때 /16의 의미는 CIDR를 뜻한다. 이거 나중에 설명할께

Gateway: 172.17.0.1
게이트웨이는 다른 프로토콜과 연결해주는 기능을 하며, 해당 대역의 가장 첫번째 주소를 갖게 됩니다. 이후부터는 컨테이너 생성시마다 해당 아이피 대역에 자동으로 주소가 바인딩되어 활용되게 된다.
위에서 가장 먼저 확인했던 컨테이너의 eth0 아이피 주소가 172.17.0.2 인것을 확인할 수 있다.

profile
코딩공부 하고있습니다
post-custom-banner

0개의 댓글