docker를 사용시 여러 컨테이너를 엮어 사용하는 것을 통합적으로 관리할 수 있도록 해주는것. 그것이 바로 Docker-compose다.
기본적으로 Docker 와 동일한 명령어 구조를 가지기 때문에 방식만 알면 어려운 것은 없고, 작성하는 방식도 Dockerfile 와 유사한 방식을 갖고 있다.
다만 큰 차이점이 있다면 Docker-compose로 컨테이너를 동작 시킬때 도커의 기본 네트워크 대역과 별도의 네트워크 대역폭을 지정해주어 배포해준다는 차이점이 있다.
이때 네트워크 대역을 별도로 생성해준다는건 뭘까?
하나하나 알아보도록 하자.
도커 네트워크의 구조는 위 사진과 같다.
docker host 부분은 도커를 동작시키는 메인 서버를 의미한다.
eth0(검정), veth1, docker0, 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) 를 확인할 수 있다.
호스트 서버(도커를 실행중인 리눅스) 에서 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도 인터넷이 되도록 하는 형태라며 비유했다.
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 소항목에서 다시 한번 연결지어 설명한다!
yum -y install iptraf-ng
호스트스 서버에 설치했던 nginx 컨테이너를 동작시킨 후, 다른 세션으로 접속한 뒤에 iptraf-ng 를 입력하여 프로세스를 동작하여 패킷이 어디서 전달되고 있는지를 확인해보자.
실행 후 위와 같은 메뉴가 표기되는데, 하이라이트 된 General interface statistics로 진입.
Loop back: 로컬테스트 네트워크 주소
ens32 : 호스트 서버의 네트워크 인터페이스
virbr0: NAT 설정을 위한 네트워크 인터페이스
docker0 : 외부 네트워크를 컨테이너들에게 알맞게 할당시켜주는 브릿지
우린 컨테이너와 연결된 docker0 와 veth에 패킷이 들어와 수치가 증가하는 것을 확인할 것이다. nginx 컨테이너로 구동한 웹 서버에서 새로고침을 연타해보자.
docker0 는 veth와 함께 동일 량의 패킷을 읽어오는 것을 확인 해 볼 수 있습니다.
즉, 도커 컨테이너 네트워크에 진입시 흐름은 아래와 같습니다.
[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 이 있고 각 역할은 아래와 같습니다.
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 인것을 확인할 수 있다.