Infra & Devops/Docker

[Docker] 도커 컨테이너 Network (bridge, host, none, macvlan) / 네트워크 연결 (connect, disconnect)

겸둥이xz 2021. 9. 16. 22:30
반응형

도커 컨테이너 Network

  • Docker 컨테이너끼리 통신을 할 때는 Docker 네트워크를 통해 수행한다.
  • docker network ls 명령으로 Docker 네트워크 목록을 확인할 수 있다.

  • 기본 값으로 bridge, host, none 네트워크가 있다.
docker network ls [옵션]
옵션 설명
-f, --filter=[] 출력을 필터링
--no-trunc 상세 정보 출력
-q, --quiet 네트워크 ID만 표시

필터링에서 이용할 수 있는 키

설명
driver 드라이버 지정
id 네트워크 ID
label 네트워크에 설정된 라벨
name 네트워크명
scope 네트워크의 스코프
type 네트워크의 타입
# 네트워크 드라이버가 bridge인 네트워크들의 네트워크 ID를 출력
docker network ls -q --filter driver=bridge

 

컨테이너 네트워크 확인하기 (docker container inspect)

# 컨테이너 실행
docker run --name test -dit centos:latest

# inspect 명령어로 네트워크 확인
docker container inspect test
...
...
        "NetworkSettings": {
            "Bridge": "",
            "SandboxID": "2db298ecda62c00d6cff296c4c589d3da054543e17b8a07b85e5aa67cc615ae0",
            "HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {},
            "SandboxKey": "/var/run/docker/netns/2db298ecda62",
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "EndpointID": "3df01ebfac7296f664de802c9bcbb4382286b8545bfda034e4dd479989ab8d23",
            "Gateway": "172.17.0.1",
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.2",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
            "MacAddress": "02:42:ac:11:00:02",
            "Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "a9713e40efa33015e9cd18f473e32d40e143a75c60c7104f16295d128c9a558c",
                    "EndpointID": "3df01ebfac7296f664de802c9bcbb4382286b8545bfda034e4dd479989ab8d23",
                    "Gateway": "172.17.0.1",
                    "IPAddress": "172.17.0.2",  ✅ 컨테이너 내부적으로 ip 설정
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:02",
                    "DriverOpts": null
                }
            }
        }
...
...

 

호스트에서 확인하기

  • docker0는 bridge의 역할을 한다, veth는 veth를 할당받은 컨테이너들 내부적으로 ip 설정

 

nginx 백그라운드로 실행 / test와 통신해보기

# 컨테이너 실행
docker run --name webserver -d nginx:latest

# IP 확인하기
docker inspect webserver | grep IP
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "SecondaryIPAddresses": null,
            "SecondaryIPv6Addresses": null,
            "GlobalIPv6Address": "",
            "GlobalIPv6PrefixLen": 0,
            "IPAddress": "172.17.0.3",
            "IPPrefixLen": 16,
            "IPv6Gateway": "",
                    "IPAMConfig": null,
                    "IPAddress": "172.17.0.3", ✅ nginx 컨테이너의 IP
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,


# test 컨테이너로 들어가서 nginx와 통신 확인하기
[user@localhost ~]$ docker attach test
[root@3a0e292eac48 /]# curl 172.17.0.3
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
...
..
.
</body>
</html>
  • 같은 bridge 네트워크에 넣어도 상관없지만, 서로 다른 서비스를 같은 bridge에 넣으면 보안상 좋지 않다!!

  • 이런 식으로 네트워크를 만들어 줄 수 있다 (bridge를 만들 수 있다)

 

새로운 네트워크 작성 (docker network create)

docker network create [옵션] 네트워크
옵션 설명
--driver, -d 네트워크 브리지 또는 오버레이 (기본값 : bridge)
--ip-range 컨테이너에 할당하는 IP 주소의 범위를 지정
--subnet 서브넷을 CIDR 형식으로 지정
--ipv6 IPv6 네트워크 유효화 여부(true/false)
-label 네트워크에 설정하는 라벨

 

'web-network' 만들기

# web-network 생성 (bridge)
docker network create --driver bridge web-network

docker network inspect web-network | grep Subnet
                    "Subnet": "172.18.0.0/16",    ✅ 서브넷 자동 지정

 

호스트에서 bridge 생성 확인

 

서브넷, 게이트웨이 지정해서 만들기 (bridge)

docker network create --driver bridge --subnet 172.72.0.0/16 --gateway 172.72.0.1 mybridge

 

호스트에서 확인

  • 호스트에 네트워크 정보를 공유하는 형태로 쓴다

 

컨테이너의 네트워크 설정 (docker container run)

docker container run [네트워크 옵션] 이미지명[:태그명] [인수]
옵션 설명
--add-host=[호스트명:IP 주소] 컨테이너의 /etc/hosts에 호스트명과 IP 주소를 정의
--dns=[IP 주소] 컨테이너용 DNS 서버와 IP 주소 지정
--expose 지정한 범우의 포트 번호를 할당
--mac-address=[MAC 주소] 컨테이너의 MAC 주소를 지정
--net=[bridge | none | host ... ] 컨테이너의 네트워크를 지정
--hostname, -h 컨테이너 자신의 호스트명을 지정
--publish, -p [호스트 포트 번호]:[컨테이너 포트 번호] 호스트와 컨테이너의 포트 매핑
--publish-all, -P 호스트의 임의의 포트를 컨테이너에 할당

 

컨테이너 네트워크 지정하기 (mybridge)

docker network ls

NETWORK ID     NAME          DRIVER    SCOPE
a9713e40efa3   bridge        bridge    local
b1504401f10d   host          host      local
f85752cf06e0   mybridge      bridge    local
0cfba2b8f699   none          null      local
961d7f639edc   web-network   bridge    local


# 컨테이너 생성 (네트워크 지정 : mybridge)
docker container run -dit --name test2 --network mybridge centos:latest

# IP 주소 확인
docker container  inspect test2 | grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "",
                    "IPAddress": "172.72.0.2",  # 설정한 서브넷에서 할당됨

 

Docker host 네트워크 사용하기

  • 호스트 IP 정보를 그대로 공유하는 것을 확인 가능 ⭐️

 

nginx를 host 네트워크로 실행

  • localhost로 접속해도 작동하는 것을 확인 가능
  • 호스트 네트워크로 실행 = 호스트 네트워크의 포트를 열고 있다
  • 호스트의 80번 포트로 연결

이런 느낌, 하지만 충돌이 발생 가능 (충돌 방지가 어려움)

 

None 네트워크로 컨테이너 생성

  • 말 그대로 네트워크가 없다
  • 루프백만 존재함

 

macvlan 네트워크

  • 컨테이너의 MAC 주소를 사용하여 호스트가 사용 중인 네트워크에 연결하는 방식
  • Docker daemon이 트래픽을 컨테이너의 MAC 주소로 라우팅
  • 컨테이너가 Docker내부의 가상 bridge가 아닌 실제 네트워크에 직접 연결하여야 할 때 사용
  • macvlan이 직접 연결할 네트워크에 연결되어 있는 호스트의 NIC에 Promiscuous mode 가 설정되어야 함
  • Promiscuous mode가 설정되어 있지 않을 경우, 컨테이너의 MAC 주소가 목적지로 되어 있는 패킷이 Docker 호스트의 인터페이스로 전달되더라도 패킷을 컨테이너로 전달하지 않아 통신이 정상적으로 이루어지지 않음

 

호스트에서 promisc 모드 설정 (VMware)

 

macvlan 네트워크 만들기

# macvlan 생성
docker network create --driver macvlan \
		      --subnet 172.16.166.0/24 \
                      --ip-range 172.16.166.64/26 \
                      --gateway 172.16.166.1 \
                      -o parent=ens33 macvlantest

 

컨테이너 2개 생성 (macvlan)

# 백그라운드 하나
docker container run -dit --rm --name m1 --network macvlantest centos:latest

# IP주소 확인
docker container inspect m1 | grep IPAddress
"IPAddress": "172.16.166.64",

# 포그라운드 하나
docker container run -it --rm --name m2 --network macvlantest centos:latest

  • ping 172.16.166.64 - m1과 통신 잘됨
  • ping 8.8.8.8 - 외부 통신 연결도 잘된다 (VMware 환경)

 

네트워크 연결 (docker network connect / docker network disconnect)

docker network connect [옵션] 네트워크 컨테이너
옵션 설명
--ip IPv4 주소
--ip6 IPv6 주소
--alias 앨리어스명
--link 다른 컨테이너에 대한 링크

 

다른 컨테이너에 대한 링크 (link 옵션)

# web1 컨테이너 실행
docker run --rm -d --name web1 nginx:latest

# web1 컨테이너에 링크
docker run -it --rm --name centos --link web1 centos:latest

  • 동일한 네트워크상에 있는 다른 컨테이너와 통신 가능
  • 컨테이너의 연결은 IP 주소뿐만 아니라 컨테이너명 또는 컨테이너 ID도 그대로 사용가능

 


<참고자료>

'완벽한 IT 인프라 구축을 위한 Docker 2판'

반응형