| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- Thread
- 김영한
- 데이터베이스
- 멀티 쓰레드
- RDB
- 도커
- 컨테이너
- 인프런
- 알고리즘
- db
- 함수형 인터페이스
- Docker
- SQL
- 쿠버네티스
- 쓰레드
- 자바 입출력 스트림
- mysql
- Java IO
- 도커 엔진
- 스레드
- 자바
- lambda
- 자료구조
- 람다
- 실전 자바 고급 1편
- 동시성
- java
- Kubernetes
- container
- 시작하세요 도커 & 쿠버네티스
- Today
- Total
쌩로그
[Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 네트워크 본문
목차
- 포스팅 개요
- 본론
2-1. 도커 네트워크 구조
2-2. 도커 네트워크 기능
2-3. 도커 네트워크 구조 - 요약
1. 포스팅 개요
이 포스팅은 위키북스 출판사의 '시작하세요! 도커/쿠버네티스'의 제 2장 도커 엔진에서 도커 네트워크에 대한 부분을 학습하며 기록한 포스팅이다.
참고
윈도우를 사용한다면 커맨드(CMD)보단 WSL 을 사용하자.
또한 학습하다보면 디렉터리를 확인할 수 있다고 하는 부분이 있는데,
윈도우에서는 아무리 찾아도 확인하려는 디렉터리를 찾아볼 수 없는 경우가 있었다.
2. 본론
2-1. 도커 네트워크 구조
컨테이너 내부에서 ifconfig를 입력해서 컨테이너의 네트워크 인터페이스에 eth0 과 lo 네트워크 인터페이스가 있는 것을 확인했었다.
root@7f1497cd89ac:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
...
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
...
(위의 출력은 net-tools 설치 후에 나온 것이다)
- 도커는 컨테이너에 내부 IP를 순차적으로 할당한다.
- 이 IP는 컨테이너를 재시작할 때마다 변경될 수 있다.
- 이 내부 IP는 도커가 설치된 호스트, 즉 내부 망에서만 쓸 수 있는 IP이므로 외부와 연결될 필요가 있다.
- 이 과정은 컨테이너를 시작할 떄마다 호스트에
veth...라는 네트워크 인터페이스를 생성함으로 이뤄진다.
도커는 각 컨테이너에 외부와의 네트워크를 제공하기 위해 컨테이너마다 가상 네트워크 인터페이스를 호스트에 생성하며 이 인터페이스의 이름은 veth로 시작한다.
- veth 인터페이스는 사용자가 직접 생성할 필요는 없다.
- 컨테이너가 생성될 때 도커 엔진이 자동으로 생성한다.
참고로 veth 에서 v는 virtual을 뜻한다.virtual eth라는 의미다.
도커가 설치된 호스트에서 ifconfig나 ip addr과 같은 명령어로 네트워크 인터페이스를 확인하면 실행 중인 컨테이너 수만큼 veth로 시작하는 인터페이스가 생성된 것을 알 수 있다.
(근데 왜 난 안 나옴...?)
밑에서 다시 말하지만, window나 mac에서는 docker0 브릿지나, veth 인터페이스들이 VM 안에 있으므로 확인할 수 없다고 한다.
(WSL로 학습 중인데, net-tools를 설치하니 나온다.)
#출력 결과
# window에서나 mac에서는 veth 인터페이스들이 VM 안에 있기 때문에 확인할 수 없다고 한다.
$ ifconfig
br-1565f9ff21e2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.1 netmask 255.255.0.0 broadcast 172.18.255.255
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:c0ff:fe8b:4a59 prefixlen 64 scopeid 0x20<link>
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.65.3 netmask 255.255.255.0 broadcast 192.168.65.255
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
veth2a232f2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::48d3:f2ff:feda:a5b8 prefixlen 64 scopeid 0x20<link>
ether 4a:d3:f2:da:a5:b8 txqueuelen 0 (Ethernet)
veth39bdbf6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::60a9:f3ff:fe5a:4a1 prefixlen 64 scopeid 0x20<link>
ether 62:a9:f3:5a:04:a1 txqueuelen 0 (Ethernet)
vetha91270a: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet6 fe80::dc63:48ff:fe74:2814 prefixlen 64 scopeid 0x20<link>
ether de:63:48:74:28:14 txqueuelen 0 (Ethernet)
- 출력 결과에서
eth0은 공인 IP 또는 내부 IP가 할당되어 실제로 외부와 통신할 수 있는 호스트의 네트워크 인터페이스다. veth로 시작하는 인터페이스는 컨테이너를 시작할 때 생성됐으며, 각 컨 테이너의eth0과 연결됐다.veth인터페이스뿐 아니라docker0이라는 브리지도 존재한다.docker0브리지는 각veth인터페이스와 바인딩돼 호스트의eth0인터페이스와 이어주는 역할을 한다.
※참고 : window나 mac에서는 docker0 브릿지나, veth 인터페이스들이 VM 안에 있으므로 확인할 수 없다고 한다.
https://joont92.github.io/docker/network-%EA%B5%AC%EC%A1%B0/
https://hanseom.tistory.com/243
컨테이너와 호스트의 네트워크의 구성은 아래 그림과 같다.
컨테이너의 eth0 인터페이스는 호스트의 veth…라는 인터페이스와 연결됐으며 veth 인터페이스는 decker0 브리지와 바인딩돼 외부와 통신할 수 있다.
brctl 명령어를 이용해 docker0 브리지에 veth 이 실제로 바인딩됐는지 알 수 있다.
아래 명령어는
$ brctl show dokcer0
brctl show docker0
bridge name bridge id STP enabled interfaces
docker0 8000.0242c08b4a59 no veth39bdbf6
참고로 ※ 아마 윈도우라 위에 같이 존재하지 않는다고 나오는 거 같다...
다만 docker network ls 라는 명령어를 치면, bridge 라는 이름의 network가 나오긴하는데, 아래에서 보자.
2-2. 도커 네트워크 기능
- 컨테이너를 생성하면 기본적으로
docker0브리지를 통해 외부와 통신할 수 있는 환경을 사용할 수 있다.- 하지만 사용자의 선택에 따라 여러 네트워크 드라이버를 쓸 수도 있다.
- 도커가 자체적으로 제공하는 대표적인 네트워크 드라이버로는 브리지 (bridge), 호스트(host), 논(none), 컨테이너(container), 오버레이(overlay)가 있다.
- 서드파티(third-paKy) 플러그인 솔루션으로는 weave, flannel, openvswitch 등이 있으며, 더 확장된 네트워크 구성을 위해 활용된다.
이번 장에서는 도커 자체만으로 손쉽게 쓸 수 있는 브리지, 호스트, 논, 컨테이너에 대해 알아본다.
먼저 도커에서 기본적으로 쓸 수 있는 네트워크는 무엇이 있는지 확인해본다.
docker network ls 명령어로 네트워크 목록을 확인할 수 있다.
도커의 네트워크를 다루는 명령어는 docker network로 시작한다.
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
7ba1f9be0ef0 bridge bridge local
e08e56703ece host host local
89973e77ff60 none null local
이미 브리지, 호스트, 논 네트워크가 있음을 알 수 있다.
브리지 네트워크는 컨테이너를 생성할 때 자동으로 연결되는 docker0 브리지를 활용하도록 설정돼있다.
이 네트워크는 172.17.0.x IP 대역을 컨테이너에 순차적으로 할당한다.docker network inspect 명령어를 이용하면 네트워크의 자세한 정보를 볼 수 있다.docker inspect --type network 를 사용해도 동일한 출력 결과를 볼 수 있다.
$ docker network inspect bridge
...
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
...
"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"
},
Config 항목의 서브넷과 게이트웨이가 172.17.0.0/16과 172.17.0.1로 설정돼 있다.
또한 브리지 네트워크를 사용 중인 컨테이너의 목록을 Containers 항목에서 확인할 수 있다.
아무런 설정을 하지 않고 컨테이너를 생성하면 컨테이너는 자동으로 docker0 브리지를 사용한다.
참고로 Options에 docker0 라는 이름을 가졌다고 나와있다.
브리지 네트워크
브릿지 네트워크는 docker0 브릿지와 비슷하게 docker0 이 아닌 사용자 정의 브리지를 새로 생성해서 각 컨테이너에 연결하는 네트워크 구조다.
컨테이너는 연결된 브리지를 통해 외부와 통신할 수 있다.
기본적으로 존재하는 docker0을 사용하는 브리지 네트워크가 아닌 새로운 브리지 타입의 네트워크를 생성할 수 있다.
$ docker network create --driver bridge mybridge
1565f9ff21e25536fbe726f49c6bd8523598259388f8a6982bf59d3ff35a3128
브리지 타입의 mybridge 라는 네트워크가 생성됐다.docker run 또는 create 명령어에 --net 옵션의 값을 설정하면 컨테이너가 이 네트워크를 사용하도록 설정할 수 있다.
다음 명령어를 입력해 mybridge 네트워크를 사용하는 컨테이너를 생성한다.
$ docker run -i -t --name mynetwork_container --net mybridge ubuntu
컨테이너 내부에서 ifconfig 를 입력하면 새로운 IP 대역이 할당된 것을 알 수 있다.
브리지 타입의 네트워크를 생성하면 도커는 IP 대역을 차례대로 할당한다.
root@4aa42897c124:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 172.18.0.2 netmask 255.255.0.0 broadcast 172.18.255.255
이렇게 생성된 사용자 정의 네트워크는 docker network disconnect, connect 를 통해 컨테이너에 유동적으로 붙이고 뗄 수 있다.
아래의 명령어는 mynetwork_container 컨테이너에 mybridge 라는 이름의 브리지 네트워크를 끊은 뒤 다시 연결한다.
# docker network disconnect mybridge mynetwork_container
# docker network connect mybridge mynetwork_container
참고로 논 네트워크, 호스트 네트워크 등과 같은 특별한 네트워크 모드에는 docker network connect, disconnect 명령어를 사용할 수 없다.
브리지 네트워크, 또는 뒤에 설명할 오버레이 네트워크와 같이 특정 IP 대역을 갖는 네트워크 모드에만 이 명령어를 사용할 수 있다.
네트워크의 서브넷, 게이트웨이, IP 할당 범위 등을 임의로 설정하려면 네트워크를 생성할 때 아래와 같이 --subnet, --ip--range, --gateway 옵션을 추가한다.
단 --subnet 과 --ip-range 는 같은 대역이어야 한다.
$ docker network create --driver=bridge --subnet=172.72.0.0/16 --ip-range=172.72.0.0/24 --gateway=172.72.0.1 my_custom_network
a351efdcddf4ecd8a96d6f24dea6832c5a96a2b7167720f6b0cf8f6a5dc613f2
호스트 네트워크
네트워크를 호스트로 설정하면 호스트의 네트워크 환경을 그대로 쓸 수 있다.
위의 브리지 드라이버 네트워크와 달리 호스트 드라이버의 네트워크는 별도로 생성할 필요 없이 기존의 host라는 이름의 네트워크를 사용한다.
$ docker run -i -t --name network_host --net host ubuntu
$ echo "컨테이너 내부"
--net 옵션을 입력해 호스트를 설정한 컨테이너의 내부에서 네트워크 환경을 확인하면 호스트와 같은 것을 알 수 있다.
호스트 머신에서 설정한 호스트 이름도 컨테이너가 물려받기 때문에 컨테이너의 호스트 이름도 무작위 16진수가 아닌 도커 엔진이 설치된 호스트 머신의 호스트 이름으로 설정된다.
$ 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:c0ff:fe8b:4a59 prefixlen 64 scopeid 0x20<link>
ether 02:42:c0:8b:4a:59 txqueuelen 0 (Ethernet)
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.65.3 netmask 255.255.255.0 broadcast 192.168.65.255
inet6 fe80::b0a0:46ff:fecd:d99d prefixlen 64 scopeid 0x20<link>
ether b2:a0:46:cd:d9:9d txqueuelen 1000 (Ethernet)
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
- 컨테이너의 네트워크를 호스트 모드로 설정하면 컨테이너 내부의 애플리케이션을 별도의 포트 포워딩 없이 바로 서비스할 수 있다.
- 마치 실제 호스트에서 애플리케이션을 외부에 노출하는 것과 같다.
- 예를 들어, 호스트 모드를 쓰는 컨테이너에서 아파치 웹 서버를 구동한다면 호스트의 IP와 컨테이너의 아파치 웹 서버 포트인 80으로 바로 접근할 수 있다.
논 네트워크
none은 말 그대로 아무런 네트워크를 쓰지 않는 것을 뜻한다.
다음과 같이 컨테이너를 생성하면 외부와 연결이 단절된다.
$ docker run -i -t --name network_none --net none ubuntu:14.04
--net 옵션으로 none 을 설정한 컨테이너 내부에서 네트워크 인터페이스를 확인하면 로컬호스트 를 나타내는 lo 외에는 존재하지 않는 것을 알 수 있다.
ifconfig
lo Link encap:Local Loopback
inet addr:127.0.0.1 Mask:255.0.0.0
컨테이너 네트워크
--net 옵션으로 container를 입력하면 다른 컨테이너의 네트워크 네임스페이스 환경을 공유할 수 있다.
공유되는 속성은 내부 IP, 네트워크 인터페이스의 맥(MAC) 주소 등이다.--net 옵션의 값으로 container:[다른 컨테이너의 ID] 와 같이 입력한다.
$ docker run -i -t -d --name network_container_1 ubuntu:14.04
0a83828050d3911e8de466789048572e2058dc587ea4825a360ff6dfeb5dd50d
$ docker run -i -t -d --name network_container_2 --net container:network_container_1 ubuntu:14.04
6dcaccd7c8fa0cf54cb17b46ea78dcbb06184e91935486431947c525ca610ec0
참고
-i,-t,-d옵션을 함께 사용하면 컨테이너 내부에서 셸을 실행하지만 내부로 들어가지 않으며 컨테이너도 종료되지 않는다.- 위와 같이 테스트용으로 컨테이너를 생성할 때 유용하게 쓸 수 있다.
- 위와 같이 다른 컨테이너의 네트워크 환경을 공유하면 내부 IP를 새로 할당받지 않으며 호스트에 veth로 시작하는 가상 네트워크 인터페이스도 생성되지 않는다.
network_container_2컨테이너의 네트워크와 관련된 사항은 전부 network_container_1 과 같게 설정된다.- 다음 명령어를 입력해 이를 확인할 수 있다.
$ docker exec network_container_1 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:04
inet addr:172.17.0.4 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
$ docker exec network_container_2 ifconfig
eth0 Link encap:Ethernet HWaddr 02:42:ac:11:00:04
inet addr:172.17.0.4 Bcast:172.17.255.255 Mask:255.255.0.0
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
두 컨테이너의 eth0에 대한 정보가 완전히 같은 것을 알 수 있다.
이를 그림으로 나타내면 아래와 같다.
브리지 네트워크와 --net-alias
브리지 타입의 네트워크와 run 명령어의 --net-alias 옵션을 함께 쓰면 특정 호스트 이름으로 컨테이너 여러 개에 접근할 수 있다.
위에서 생성한 mybridge 네트워크를 이용해 컨테이너 를 3개 생성하자.-net-alias 옵션의 값은 alicekl06 으로 설정하며, 다른 컨테이너에서 alicekl06이라는 호스트 이름으로 아래 3개의 컨테이너에 접근할 수 있다.
$ docker run -i -t -d --name network_alias_container1 --net mybridge --net-alias alicek106 ubuntu:14.04
...
$ docker run -i -t -d --name network_alias_container2 --net mybridge --net-alias alicek106 ubuntu:14.04
...
$ docker run -i -t -d --name network_alias_container3 --net mybridge --net-alias alicek106 ubuntu:14.04
...
inspect 명령어로 각 컨테이너의 IP를 확인해보자.
$ docker inspect network_alias_container1 | grep IPAddress
"SecondaryIPAddresses": null,
"IPAddress": "",
"IPAddress": "172.18.0.3",
첫 번째 컨테이너의 IP 주소가 172.18.0.3이므로 두 번째, 세 번째 컨테이너는 각각 172.18.0.4, 172.18.0.5일 것이다.
세 개의 컨테이너에 접근할 컨테이너를 생성한 뒤 alicekl06이라는 호스 트 이름으로 ping 요청을해보자.
$ docker run -i -t --name network_alias_ping --net mybridge ubuntu:14.04
$ ping -c 1 alicek106
PING alicek106 (172.18.0.4) 56(84) bytes of data.
64 bytes from network_alias_container2.mybridge (172.18.0.4): icmp_seq=1 ttl=64 time=0.518 ms
$ ping -c 1 alicek106
PING alicek106 (172.18.0.5) 56(84) bytes of data.
64 bytes from network_alias_container3.mybridge (172.18.0.5): icmp_seq=1 ttl=64 time=0.351 ms
$ ping -c 1 alicek106
PING alicek106 (172.18.0.3) 56(84) bytes of data.
64 bytes from network_alias_container1.mybridge (172.18.0.3): icmp_seq=1 ttl=64 time=0.303 ms
컨테이너 3개의 IP로 각각 ping이 전송된 것을 확인할 수 있다.
매번 달라지는 IP를 결정하는 것은 별도의 알고리즘이 아닌 라운드 로빈(round-robin) 방식이기 때문이다.
- 라운드 로빈 : 하나의 중앙처리장치를 여러 프로세스들이 우선순위 없이 돌아가며 할당받아 실행하는 방식이다.
이것이 가능한 이유는 도커 엔진에 내장된 DNS가 alicekl06이라는 호스트 이름을 --net-alias 옵션으로 alicekl06을 설정한 컨테이너로 변환(resolve)하기 때문아다.
다음 그림은 도커 네트워크에서 사용하는 내장 DNS 와 --net-alias의 관계를 보여주고있다.
- 도커의 DNS는 호스트 이름으로 유동적인 컨테이너를 찾을 때 주로 사용된다.
- 가장 대표적인 예가
--link옵션인데, 이는 컨테이너의 IP가 변경돼도 별명으로 컨테이너를 찾을 수 있게 DNS에 의해 자동으로 관리된다. - 단 이 경우는 디폴트 브리지 네트워크의 컨테이너 DNS라는 점이 다르다.
- 가장 대표적인 예가
--net-alias옵션 또한--link옵션과 비슷한 원리로 작동한다.- 도커는 기본 브리지 네트워크가 아닌 사용자가 정의한 브리지 네트워크에 사용되는 내장 DNS 서버를 가지며, DNS의 IP 는
127.0.0.11이다. mybridge라는 이름의 네트워크에 속한 3개의 컨테이너는 run으로 생성 할 때--net-alias옵션에 alicekl06이라는 값을 입력했으며, 이 컨테이너의 IP는 DNS 서버에 alicekl06이라는 호스트 이름으로 등록된다.- mybridge 네트워크에 속한 컨테이너에서 alicekl06이라는 호스트 이름으로 접근하면 DNS 서버 는 라운드 로빈 방식을 이용해 컨테이너의 IP 리스트를 반환한다.
- ping 명령어는 이 IP 리스트에 서 첫 번째 IP를 사용하므로 매번 다른 IP로 ping을 전송한다.
- 이를 확인하기 위해 dig라는 도구를 사용해보자.
- dig는 DNS로 도메인 이름에 대응하는 IP를 조회할 때 쓰는 도구아다.
- dig는 ubuntu:14.04 이미지에 설치돼 있지 않으므로 방금 생성한 network_alias_ping 컨테이너 내부에서 다음 명령어를 입력해 설치하자.
$ apt-get update
$ apt-get install dnsutils
dig 명령어로 alicekl06 호스트 이름이 변환되는 IP를 확인합니다.
$ dig alicek106
...........
alicek106. 600 IN A 172.18.0.4
alicek106. 600 IN A 172.18.0.5
alicek106. 600 IN A 172.18.0.3
$ dig alicek106
...........
alicek106. 600 IN A 172.18.0.5
alicek106. 600 IN A 172.18.0.4
alicek106. 600 IN A 172.18.0.3
위 명령어를 반복해서 입력해보면 반환되는 IP의 리스트 순서가 모두 다른 것을 알 수 있다.
MacVLAN 네트워크
MacVLAN 은 호스트의 네트워크 인터페이스 카드를 가상화해 물리 네트워크 환경을 컨테이너에게 동일하게 제공한다.
따라서 MacVLAN을 사용하면 컨테이너는 물리 네트워크상에서 가상의 맥 (MAC) 주소를 가지며, 해당 네트워크에 연결된 다른 장치와의 통신이 가능하다.
MacVLAN에 연결된 컨테이너는 기본적으로 할당되는 IP 대역인 172.17.X.X 대신 네트워크 장비의 IP를 할당받는다.
위 그림과 같이 공유기, 라우터, 스위치와 같은 네트워크 장비에 두 대의 서버가 연결돼 있고, 각 서 버는 192.168.0.0/24 대역에서 IP를 동적으로 할당받는다고 가정해보자.
MacVLAN을 사용하면 각 컨테이너에 192.168.0.0/24 대역의 IP를 할당할 수 있다.
따라서 MacVLAN을 사용하는 컨테이너들과 동일한 IP 대역을 사용하는 서버 및 컨테이너들은 서로 통신이 가능하다.
참고
MacVLAN 네트워크를 사용하는 컨테이너는 기본적으로 호스트와 통신이 불가능하다.
위 예시에서 컨테이너 A는 서버 2와는 통신할 수 있지만. 서버 1과는 통신할 수 없다.
MacVLAN을 사용하려면 적어도 1 개의 네트워크 장비와 서버가 필요하다.
그러나 대부분 환경에 서 MacVLAN 네트워크의 사용 방법은 거의 동일하기 때문에 고가의 스위치와 서버 대신 공유기와 라즈베리 파이를 사용할 수 있다.
상황이 여의치 않다면 버추얼박스(VirtualBox) 가상 머신과 호스트 전용 어댑터(Host-only Ethernet Adapter)로 테스트할 수 있다.
필자는 버추얼 박스를 이용한다.
네트워크 정보 : 172.30.1.0/24
서버 1 (node01) : 172.30.1.62
서버 2 (node02) : 172.30.1.14두 서버에서 각각 아래의 명령어를 입력하면 MacVLAN 네트워크를 생성할 수 있다.
$ docker network create -d macvlan --subnet=172.30.1.0/24 --ip-range=172.30.1.64/28 --gateway=172.30.1.254 -o macvlan_mode=bridge -o parent=enp0s3 my_macvlan
13a..
$ docker network create -d macvlan --subnet=172.30.1.0/24 --ip-range=172.30.1.128/28 --gateway=172.30.1.254 -o macvlan_mode=bridge -o parent=enp0s3 my_macvlan
ff07a
브리지 네트워크를 생성했을 때와 동일하게 docker network create 명령어를 사용하면서 여러 옵션이 함께 썻다.
각 옵션은 아래와 같다.
-d: 네트워크 드라이버로 macvlan을 사용한다는 것을 명시한다.--driver와 같다.-subnet: 컨테이너가 사용할 네트워크 정보를 입력한다. 여기서는 네트워크 장비의 IP 대역 기본 설정을 그대로 따른다.--ip-range: MacVLAN을 생성하는 호스트에서 사용할 컨테이너의 IP 범위를 입력한다. node01과 node02의 IP 범위가 겹쳐 동일한 IP의 컨테이너가 각각 생성된다면 컨테이너 네트워크가 정상적으로 동작하지 않을 수 있으므로 반드시 겹치지 않게 설정해야 한다.
참고로 사용 가능한 IP 대역은 IP 뒤에 쓰여진 서브넷을 통해서 나타낸다.
위 예시에서 node01은 2^4개, 즉 192.168.0.64 〜 192.168.0.79까지의 IP를 컨테이너에 할당할 수 있다.
-gateway: 네트워크에 설정된 게이트웨이를 입력한다. 여기서는 네트워크 장비의 기본 설정을 그대로 따른다.-o: 네트워크의 추가적인 옵션을 설정한다. 위 예시에서는macvlan_mode=bridge값을 통해 MacVLAN을 bridge 모드로,parent=eth0값을 통해 MacVLAN으로 생성될 컨테이너 네트워크 인터페이스의 부모(parent) 인터페이스를eth0으로 지정한다.eth0은 공유기에 랜선으로 연결되어 192.168.0.0/24 대역의 IP를 할당받은 네트워크 인터페이스다.
참고
MacVLAN은 여기서 설명하는 것보다 더 복잡한 네트워크 개념을 포함하고 있다.
MacVLAN에는 여러 종류가 있으며 그중에서 bridge 모드를 사용한다는 것, 그리고 MacVLAN을 사용하기 위해서는 부모 네트워크 인터페이스를 지정할 필요가 있다는 것만 알아두면 된다.
이러한 내용에 관심이 있다면 VLAN 개념 과 함께 MacVLAN을 찾아보면 된다.
아래의 명령어를 입력해 MacVLAN 네트워크를 사용하는 컨테이너를 생성해보자.
node01 에서 cl 컨테이너를, node02에서 c2 컨테이너를 생성했다.
$ sudo docker run -it --name c1 --hostname c1 --network my_macvlan ubuntu:14.04
$ ip a
eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether ca:0b:fc:f6:8d:5b brd ff:ff:ff:ff:ff:ff
inet 172.30.1.64/24 brd 172.30.1.255 scope global eth0
$ sudo docker run -it --name c2 --hostname c2 --network my_macvlan ubuntu:14.04
$ ip a
eth0@if2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 8e:15:69:e3:f0:d4 brd ff:ff:ff:ff:ff:ff
inet 172.30.1.128/24 brd 172.30.1.255 scope global eth0
컨테이너 cl에서 node02와 컨테이너 c2로 핑을 전송해 MacVLAN 네트워크가 정상적으로 동작하고 있음을 확인할 수 있다.
핑이 안 될때는 아래를 참고하자.
root©c1:/# ping 172.30.1.128 -c 1
PING 172.30.1.128 (172.30.1.128) 56(84) bytes of data.
64 bytes from 172.30.1.128: icmp_sec=1 ttl=64 time=4.38 ms
— 172.30.1.128 ping statistics —
1 packets transmitted, 1 received, 0움 packet loss, time 0ms
rtt min/avg/max/mdev = 7.300/7.300/7.300/0.000 ms
root©c1:/# ping 172.30.1.64 -c 1
PING 172.30.1.64 (172.30.1.64) 56(84) bytes of data.
64 bytes from 172.30.1.64: icmp_sec=1 ttl=64 time=4.38 ms
— 172.30.1.64 ping statistics —
1 packets transmitted, 1 received, 0움 packet loss, time 0ms
rtt min/avg/max/mdev = 4.381/4.38/4.38/0.000 ms
핑이 되지 않을 때
- 버추얼 박스의 가상 머신의 네트워크가 호스트 전용 어댑터인지 확인하자.
- 네트워크의 무작위 모드를 모두 허용으로 해주자.
- 컨테이너에서 빠져나와서 아래의 명령을 쳐주고, 다시 컨테이너로 들어가서
ping을 날려보자.
root@<노드>:/home/alicek106# ip link set <인터페이스 이름> promisc on
- 인터페이스 이름은 eth0 혹은 enp0s3 같은 것을 말한다.
- 가상머신의 호스트에서 명령어를 입력해야 한다..!!
참고블로그 : https://blog.naver.com/alice_k106/221093585471
3. 요약
- 도커에서 기본적으로 쓸 수 있는 네트워크는 무엇이 있는지 확인했다.
- 도커 자체만으로 손쉽게 쓸 수 있는 브리지, 호스트, 논, 컨테이너에 대해 알아봤다.
'Deploy > Docker' 카테고리의 다른 글
| [Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 컨테이너 자원 할당 제한 (0) | 2025.03.03 |
|---|---|
| [Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 컨네이너 로깅 (0) | 2025.03.03 |
| [Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진 - 도커 볼륨 (1) | 2025.02.27 |
| [Docker] 시작하세요! 도커 & 쿠버네티스 - 02_도커 엔진_컨테이너 다루기(명령어 및 애플리케이션 구축) (0) | 2025.02.27 |
| [Docker] 시작하세요! 도커 & 쿠버네티스 - 01_도커란 (0) | 2025.02.27 |