✔️ 네트워크 플러그인 종류
- bridge
- host
- null
- ....
자주 사용하는 건 bridge와 host이다.
✔️ 브릿지 네트워크
✔️ 호스트에서 확인하는 방법
인터페이스 확인
ip addr show
- docker0 : 브릿지
- vethX : 가상 인터페이스
브릿지 확인 명령 설치
sudo apt install bridge-utils
brctl show
NAT 테이블 확인
sudo iptables -t nat -L -n
- MASQUERADE: Source NAT
✔️ 컨테이너에서 확인하는 방법
sudo apt update
sudo apt install iproute2
ip addr show
ip route
✔️ 사용 예제
vagrant@docker ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
b4481141a27b bridge bridge local
4159dc8b15f3 host host local
42eb99a7c805 none null local
도커에서 제공하는 네트워크의 목록을 볼 수 있다.
우리가 기본적으로 사용하는 network는 브릿지 네트워크이다.
vagrant@docker ~ docker inspect c2
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "b4481141a27b0b11d720939fd66f241944615ba65a4d6c0303c692f47fd67ef6",
"EndpointID": "595bc1de6a883a6a7f890c30f53267658db35dc896e1e436ff283051bccb6bd5",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
network ls 에서 봤던 브릿지 네트워크의 NETWORK ID와 컨테이너 실행 후 inspect로 확인한 NetworkID가 같다.
컨테이너를 만들 때 별도로 지정하지 않으면 기본적으로 사용하는 네트워크는 브릿지 네트워크이다.
도커 엔진을 설치하면 자동으로 브릿지 타입의 네트워크가 생성되며 일반적으로 컨테이너는 이것을 사용한다.
vagrant@docker ~ docker inspect b448
[
{
"Name": "bridge",
"Id": "b4481141a27b0b11d720939fd66f241944615ba65a4d6c0303c692f47fd67ef6",
------------------------- 중간 생략 -------------------------
"ConfigOnly": false,
"Containers": { # 현재 브릿지 네트워크를 사용하는 컨테이너의 id
"c21f9b0352f8cb56e4437cf8260fe5238920a4c144ce23a71977b480e0d391d3": {
"Name": "stoic_rosalind",
"EndpointID": "595bc1de6a883a6a7f890c30f53267658db35dc896e1e436ff283051bccb6bd5",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
"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": {}
}
]
브릿지 네트워크 ID로 살펴보면 해당 브릿지 네트워크를 사용하는 컨테이너 목록을 확인할 수 있다.
✔️ 포트 포워딩이 설정된 컨테이너
sudo iptables -t nat -L -n
- DNAT : Destination NAT
vagrant@docker ~ docker run -d -p 8080:80 httpd
0906c8c2e6287cb92bf9b489d1a84cc371ce4f47df05cd67c80a9c4e740ca953
httpd 컨테이너를 포트 포워딩하여 띄워보자
vagrant@docker ~ sudo iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
Chain DOCKER에 DNAT라는 항목이 보인다. DNAT은 Destination NAT이다.
이 DNAT는 -p 옵션을 사용하여 컨테이너를 실행했을 때만 설정된다.
해석하면 출발지와 목적지는 어디든 상관없으나 tcp 프로토콜을 사용하면서 목적지 포트가 8080이면 그 ip를 172.17.0.2:80으로 바꾸라는 뜻이다.
여기서 172.17.0.2는 앞서 만든 컨테이너의 ip이다.
vagrant@docker ~ docker run -d -p 8081:80 httpd
aff4f4f25185679bb184189cc5e1a09faaf1c61779712b6103d5cc917c8cd411
vagrant@docker ~ sudo iptables -t nat -L -n
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 0.0.0.0/0 ADDRTYPE match dst-type LOCAL
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DOCKER all -- 0.0.0.0/0 !127.0.0.0/8 ADDRTYPE match dst-type LOCAL
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 0.0.0.0/0
MASQUERADE tcp -- 172.17.0.2 172.17.0.2 tcp dpt:80
MASQUERADE tcp -- 172.17.0.3 172.17.0.3 tcp dpt:80
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8080 to:172.17.0.2:80
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:8081 to:172.17.0.3:80
vagrant@docker ~
다른 포트로 서비스하는 httpd 컨테이너를 하나 더 띄우고 iptables를 확인해보자
8081 dst 포트는 172.17.0.3의 80번 포트로 포트 포워딩을 하라고 설정되어 있다.
✔️ 네트워크 공유
--network
: 연결할 네트워크의 이름 또는 id를 지정할 수 있다. 별도로 지정하지 않으면 기본 브릿지 네트워크에 연결된다.
✔️ 호스트 네트워크
호스트의 네트워크를 공유해서 사용한다.
vagrant@docker ~ docker run -d --network host httpd
0dae7d393815f8798e66f458d1dbc6b583cd721448f9ce52daf551a256c4a7e2
host 네트워크를 공유하면 지금까지와 다르게 포트를 지정하지 않아도 192.168.100.100으로 접속이 가능하다는 것이다.
어떻게 가능한 것일까 ?
vagrant@docker ~ docker exec -it 0d bash
root@docker:/usr/local/apache2# apt update
root@docker:/usr/local/apache2# apt install iproute2
컨테이너 내부로 들어가서 확인해보자
root@docker:/usr/local/apache2# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: enp0s3: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 02:3d:10:42:9f:64 brd ff:ff:ff:ff:ff:ff
inet 10.0.2.15/24 brd 10.0.2.255 scope global dynamic enp0s3
valid_lft 44739sec preferred_lft 44739sec
inet6 fe80::3d:10ff:fe42:9f64/64 scope link
valid_lft forever preferred_lft forever
3: enp0s8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
link/ether 08:00:27:70:af:dd brd ff:ff:ff:ff:ff:ff
inet 192.168.100.100/24 brd 192.168.100.255 scope global enp0s8
valid_lft forever preferred_lft forever
inet6 fe80::a00:27ff:fe70:afdd/64 scope link
valid_lft forever preferred_lft forever
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:c5:5d:8f:6e 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
inet6 fe80::42:c5ff:fe5d:8f6e/64 scope link
valid_lft forever preferred_lft forever
도커 호스트의 네트워크 인터페이스 항목과 완전히 일치하는 것을 알 수 있다.
호스트 네트워크를 사용한다는 것은 호스트의 네트워크 설정을 그대로 컨테이너에서도 사용한다는 것이다.
"Networks": {
"host": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "4159dc8b15f36a734349b4e60711251bfac453d01fc30e75be69c1fa3cd3a6c6",
"EndpointID": "59ddf33600766d33a8ea0091bf74196e6ba341d0d8787f6ba8868bfdd865f346",
"Gateway": "",
"IPAddress": "",
"IPPrefixLen": 0,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "",
"DriverOpts": null
}
}
vagrant@docker ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
b4481141a27b bridge bridge local
4159dc8b15f3 host host local
42eb99a7c805 none null local
NetworkID와 docker network ls로 확인한 NETWORK ID가 같음을 알 수 있다.
vagrant@docker ~ sudo ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:*
users:(("systemd-resolve",pid=582,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:*
users:(("sshd",pid=690,fd=3))
LISTEN 0 511 *:80 *:*
users:(("httpd",pid=34177,fd=4),("httpd",pid=34051,fd=4),("httpd",pid=34050,fd=4),("httpd",pid=34049,fd=4),("httpd",pid=34010,fd=4))
LISTEN 0 128 [::]:22 [::]:*
users:(("sshd",pid=690,fd=4))
80번 포트가 httpd 에 의해 열려있다.
vagrant@docker ~ docker rm -f 0d
0d
vagrant@docker ~ sudo ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 4096 127.0.0.53%lo:53 0.0.0.0:* users:(("systemd-resolve",pid=582,fd=13))
LISTEN 0 128 0.0.0.0:22 0.0.0.0:* users:(("sshd",pid=690,fd=3))
LISTEN 0 128 [::]:22 [::]:* users:(("sshd",pid=690,fd=4))
이것은 결국 호스트의 port가 열리는 것이다.
네트워크 복제의 의미가 아닌 완전히 같은 네트워크를 쓰는 것이다.
vagrant@docker ~ docker run -d --network host httpd
fa491094eb3ea0298a2eaddb1a5103396e8946412b89d3924da72314c67bd1bf
vagrant@docker ~ docker run -d --network host httpd
4e025f3bff9ca11c49323753c6091217d94b6193d089574e481650ee153146c0
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
4e025f3bff9c httpd "httpd-foreground" 4 seconds ago Exited (1) 3 seconds ago crazy_lehmann
fa491094eb3e httpd "httpd-foreground" 12 seconds ago Up 11 seconds angry_golick
만약 host 네트워크에 두번째 연결을 시도하면 Exited 된다.
vagrant@docker ~ docker logs 4e
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 127.0.2.1. Set the 'ServerName' directive globally to suppress this message
(98)Address already in use: AH00072: make_sock: could not bind to address [::]:80
(98)Address already in use: AH00072: make_sock: could not bind to address 0.0.0.0:80
no listening sockets available, shutting down
AH00015: Unable to open logs
이미 다른 컨테이너에서 사용하고 있어 이 포트와 연결할 수 없다.
같은 포트를 서로 다른 프로세스에서 열 수 없다. 이것은 운영체제의 기본 원칙이다.
✔️ Null 네트워크
네트워크가 없는 컨테이너 생성
docker run -d --network none httpd
vagrant@docker ~ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
vagrant@docker ~ docker run -d --network none httpd
9c74bf68c1656042eeac6b1b1cc154f88695b667e84bd287e9883f471058c367
vagrant@docker ~ docker exec -it 9c bash
root@9c74bf68c165:/usr/local/apache2# apt update
Err:1 http://deb.debian.org/debian bullseye InRelease
Temporary failure resolving 'deb.debian.org'
Err:2 http://security.debian.org/debian-security bullseye-security InRelease
Temporary failure resolving 'security.debian.org'
Err:3 http://deb.debian.org/debian bullseye-updates InRelease
Temporary failure resolving 'deb.debian.org'
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye/InRelease Temporary failure resolving 'deb.debian.org'
W: Failed to fetch http://security.debian.org/debian-security/dists/bullseye-security/InRelease Temporary failure resolving 'security.debian.org'
W: Failed to fetch http://deb.debian.org/debian/dists/bullseye-updates/InRelease Temporary failure resolving 'deb.debian.org'
W: Some index files failed to download. They have been ignored, or old ones used instead.
root@9c74bf68c165:/usr/local/apache2#
이름에서 알 수 있듯이 none은 네트워크가 없다는 것이다.
vagrant@docker ~ docker pull ghcr.io/c1t1d0s7/network-multitool
Using default tag: latest
latest: Pulling from c1t1d0s7/network-multitool
ba3557a56b15: Pull complete
0e3bb546cb89: Pull complete
Digest: sha256:8a1a3bca4a684efe1401e4137790beec2d9d6a35f2768be80a6eaa6c313eabc4
Status: Downloaded newer image for ghcr.io/c1t1d0s7/network-multitool:latest
ghcr.io/c1t1d0s7/network-multitool:latest
vagrant@docker ~ docker run -it --network none ghcr.io/c1t1d0s7/network-multitool bash
bash-5.1# ip a s
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
bash-5.1#
확인해봐도 loop back 외에는 아무런 인터페이스가 없다.
none 네트워크를 사용할 일이 많지는 않으나 그럼에도 none 네트워크의 존재 이유는 다음과 같다.
모든 어플리케이션이 반드시 네트워크 통신을 해야 하는 것은 아니다.
로컬에서만 작동하는 어플리케이션은 굳이 컨테이너에 네트워크를 제공할 필요가 없다.
✔️ 브릿지 네트워크 생성
브릿지 네트워크를 생성할 수 있다.
docker network create --driver bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 wordpress-network
vagrant@docker ~ docker network create --driver bridge --subnet 192.168.200.0/24 --gateway 192.168.200.1 wordpress-network
dd8cb6c53e9b803cc932b6b4b8cb63bfd014c1a2599547245a4333a9348fc6fb
vagrant@docker ~ docker network ls
NETWORK ID NAME DRIVER SCOPE
b4481141a27b bridge bridge local
4159dc8b15f3 host host local
42eb99a7c805 none null local
dd8cb6c53e9b wordpress-network bridge local
subnet을 192.168.200.0/24으로 gateway를 192.168.200.1 으로 설정한다.
vagrant@docker ~ docker network inspect wordpress-network
[
{
"Name": "wordpress-network",
"Id": "dd8cb6c53e9b803cc932b6b4b8cb63bfd014c1a2599547245a4333a9348fc6fb",
"Created": "2022-05-09T12:13:05.261108274Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.200.0/24",
"Gateway": "192.168.200.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
생성한 브릿지 네트워크의 설정을 확인한다.
vagrant@docker ~ brctl show
bridge name bridge id STP enabled interfaces
br-dd8cb6c53e9b 8000.0242fc17845a no # 방금 만든 네트워크의 브릿지
docker0 8000.0242c55d8f6e no
vagrant@docker ~ docker run --name wp-db -d -e MYSQL_ROOT_PASSWORD=P@ssw0rd -e MYSQL_DATABASE=wordpress -e MYSQL_USER=wpadm -e MYSQL_PASSWORD=P@ssw0rd --restart always --cpus 0.5 --memory 1000m -v wp-db-vol:/var/lib/mysql --network wordpress-network mysql:5.7
WARNING: Your kernel does not support swap limit capabilities or the cgroup is not mounted. Memory limited without swap.
c4b94b7ef4d4a67e17a5d53dba01f02d6dcd69bdf37d24e091276cb3d827484f
vagrant@docker ~ docker inspect wp-db
"Networks": {
"wordpress-network": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"c4b94b7ef4d4"
],
"NetworkID": "dd8cb6c53e9b803cc932b6b4b8cb63bfd014c1a2599547245a4333a9348fc6fb",
"EndpointID": "efda2a1dfcadc444d4252f6f396bf34d23385e332c893d89bccdccd95d99cb6d",
"Gateway": "192.168.200.1",
"IPAddress": "192.168.200.2",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:c0:a8:c8:02",
"DriverOpts": null
}
}
vagrant@docker ~ docker run --name wp-web -d --link wp-db:mysql -e WORDPRESS_DB_HOST=mysql -e WORDPRESS_DB_USER=wpadm -e WORDPRESS_DB_PASSWORD=P@ssw0rd -e WORDPRESS_DB_NAME=wordpress --restart always --cpus 0.5 --memory 500m -p 80:80 --network wordpress-network wordpress:5-apache
vagrant@docker ~ docker inspect wp-web
"Networks": {
"wordpress-network": {
"IPAMConfig": null,
"Links": [
"wp-db:mysql"
],
"Aliases": [
"6c19e468fb2a"
],
"NetworkID": "dd8cb6c53e9b803cc932b6b4b8cb63bfd014c1a2599547245a4333a9348fc6fb",
"EndpointID": "9b3356c11a788c31174ac04c0c9121de963180b02ffba9d77170982ea666cc7a",
"Gateway": "192.168.200.1",
"IPAddress": "192.168.200.3",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:c0:a8:c8:03",
"DriverOpts": null
}
}
'DevOps > Docker' 카테고리의 다른 글
[Docker] docker commit 명령을 이용하여 이미지 빌드하기 (0) | 2022.05.10 |
---|---|
[Docker] Netfilter의 역할 (0) | 2022.05.10 |
[Docker] Docker Network - 1 (0) | 2022.05.10 |
[Docker] Docker Volume (볼륨) (0) | 2022.05.09 |
[Docker] Docker 컨테이너 관리 명령어 (3) (0) | 2022.05.07 |
영차영차 성장 블로그
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!