도커 네트워크 모드
기본 네트워크 모드 : Bridge, Host, None + 추가 네트워크 플러그인 : macvlan, ipvlan, overlay
docker network ls
NETWORK ID NAME DRIVER SCOPE
5d4ec64ed746 bridge bridge local
71da3212e9dc host host local
90a304de3e67 none null local
docker info | grep Network
Network: bridge host ipvlan macvlan null overlay
2.1 Bridge
Bridge 모드 기본 정보 확인
도커에서 기본적으로 쓸 수 있는 네트워크 확인, 컨테이너 기본 생성 시 자동으로 docker0 브릿지를 사용
도커는 IPtables 의 PREROUTING POSTROUTING 의 NAT Chains 를 변경한다
- 컨테이너 → 외부 : POSTROUTING 의 SNAT 처리
- 외부 → 컨테이너(Exposed services ports) : PREROUTING 에서 DNAT 처리
# 도커 네트워크 모드 확인
docker network ls
NETWORK ID NAME DRIVER SCOPE
a22960517f11 bridge bridge local
def31be9614b host host local
f0bf6fd89f14 none null local
# 도커 네트워크(플러그인) 정보 확인
docker info
docker info | grep Network
# 도커 bridge 상세 정보 확인 = docker inspect --type network bridge 동일
# 아래 "Gateway": "172.17.0.1" 정보가 출력되지 않을 경우에는 systemctl restart docker 입력 후 다시 확인
docker network inspect bridge | jq
[
{
"Name": "bridge",
"Id": "7c0902c8e4521b25b6a1233b018886256c8f877fed6a088a1a97e54804135613",
"Created": "2021-10-14T12:22:52.869292205Z",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"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"
},
"Labels": {}
}
]
# 브릿지 확인
brctl show
bridge name bridge id STP enabled interfaces
docker0 8000.024229821c4f no
# 네트워크 인터페이스 확인
ip -c addr show docker0
4: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN group default
link/ether 02:42:29:82:1c:4f 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
# SNAT 정책 확인
iptables -t nat -S
iptables -t nat -S | grep MASQUERADE
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
# 라우팅 확인
ip -c route | grep docker0
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
컨테이너(busybox) 2대 생성
# 터미널1 (PINK) : PINK 이름의 busybox 컨테이너 생성
docker run -it --name=PINK --rm busybox
ip a
ip neigh
# 터미널3 (ORANGE) : ORANGE 이름의 busybox 컨테이너 생성
docker run -it --name=ORANGE --rm busybox
ip a
ip neigh
# 터미널2 (호스트)
## 컨테이너 생성 확인
docker ps
## veth 에 각각 서로 연결되는 veth peer 가 추가됬음을 확인, docker UP 확인
ip -br -c link
## 브릿지 정보 확인
brctl show docker0
컨테이너간 통신 확인
# 터미널2 (호스트)
tcpdump -i docker0 -n
iptables -t filter -S
-A FORWARD -i docker0 -o docker0 -j ACCEPT # 컨테이너 끼리는 FORWARD 가 ACCEPT(허용)
# 터미널1 (PINK)
## ORANGE 로 ping 테스트(IP는 다를 수 있습니다)
ping -c 1 172.17.0.3
ip neigh
route -n
# 터미널3 (ORNAGE)
## ORANGE 로 ping 테스트(IP는 다를 수 있습니다)
ping -c 1 172.17.0.2
ip neigh
route -n
컨테이너에서 외부로 통신
# 터미널2 (호스트)
tcpdump -i any icmp
iptables -t nat -S
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
conntrack -L --src-nat
icmp 1 29 src=172.17.0.5 dst=8.8.8.8 type=8 code=0 id=7 src=8.8.8.8 dst=10.0.2.15 type=0 code=0 id=7 mark=0 use=1
conntrack v1.4.5 (conntrack-tools): 1 flow entries have been shown.
# 터미널1 (PINK)
ping 8.8.8.8
exit # 실습 완료 후
# 터미널3 (ORNAGE)
ping 8.8.8.8
exit # 실습 완료 후
2.2 Host 모드
호스트의 환경을 그대로 사용 가능. 호스트 드라이버의 네트워크는 별도로 생성할 필요 없이 기존의 host 라는 이름의 네트워크를 사용 - 링크 링크2
- 컨테이너의 호스트 이름도 호스트 머신의 이름과 동일. 네트워크도 동일. 애플리케이션 별도 포트 포워딩 없이 바로 서비스 할 수 있음.
# 컨테이너 실행
docker run --rm -d --network host --name my_nginx nginx
# HostConfig.NetworkMode "host" , Config.ExposedPorts "80/tcp" , NetworkSettings.Networks "host" 확인
docker inspect my_nginx
# curl 접속 확인
curl -s localhost | grep -o '<title>.*</title>'
# 호스트에서 tcp 80 listen 확인
ss -tnlp
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
LISTEN 0 511 0.0.0.0:80 0.0.0.0:* users:(("nginx",pid=3694,fd=7),("nginx",pid=3693,fd=7),("nginx",pid=3649,fd=7))
# 추가 실행 시도
docker run -d --network host --name my_nginx_2 nginx
# 확인
docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
369c40cf6dfd nginx "/docker-entrypoint.…" 7 seconds ago Exited (1) 3 seconds ago my_nginx_2
...
# 삭제
docker container stop my_nginx
2.3 컨테이너 외부에 노출
설정 및 확인 : bridge mode - 링크
# nginx:alpine 웹 컨테이너 3대 실행
# -p 옵션은 컨테이너 포트를 호스트 포트와 바인딩 연결 [호스트의 포트]:[컨테이너의 포트]
## -p 80 만 사용 시 호스트 포트 중 하나(랜덤)과 컨테이너의 80포트와 연결
## -p 여러개 사용하여 여러개 포트 개방
docker run -d --name=web1 -p 10001:80 --rm nginx:alpine
docker run -d --name=web2 -p 10002:80 --rm nginx:alpine
docker run -d --name=web3 -p 10003:80 --rm nginx:alpine
# 컨테이너 확인
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5747f508fe0b nginx:alpine "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:10003->80/tcp, :::10003->80/tcp web3
222390d43aa5 nginx:alpine "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:10002->80/tcp, :::10002->80/tcp web2
b10d8e163c77 nginx:alpine "/docker-entrypoint.…" About a minute ago Up About a minute 0.0.0.0:10001->80/tcp, :::10001->80/tcp web1
# iptables 정보 확인
iptables -t nat -S | grep :80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 10001 -j DNAT --to-destination 172.17.0.2:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 10002 -j DNAT --to-destination 172.17.0.3:80
-A DOCKER ! -i docker0 -p tcp -m tcp --dport 10003 -j DNAT --to-destination 172.17.0.4:80
iptables -t filter -S
-A FORWARD -o docker0 -j DOCKER
-A DOCKER -d 172.17.0.2/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.17.0.3/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
-A DOCKER -d 172.17.0.4/32 ! -i docker0 -o docker0 -p tcp -m tcp --dport 80 -j ACCEPT
...
# 외부(자신의 PC)에서 접속(curl 혹은 웹브라우저)
curl -s 192.168.50.10:10001 | grep -o '<title>.*</title>'
curl -s 192.168.50.10:10002 | grep -o '<title>.*</title>'
curl -s 192.168.50.10:10003 | grep -o '<title>.*</title>'
# 연결 정보 확인
conntrack -L
iptables -t nat -L -n -v
# 삭제
docker stop $(docker ps -a -q)
iptable을 자동으로 만들어 준다.
2.5 IPvlan (L2) - 링크
IPVLAN - 링크
실습환경
# vm3(gw) 기본 설정
ip -c addr
iptables -t filter -P FORWARD ACCEPT
iptraf-ng
# 공통 - vm1(docker1), vm2(docker2)
# ipvlan l2 mode network 생성 및 확인
docker network create -d ipvlan --subnet=192.168.50.0/24 --gateway=192.168.50.254 -o parent=enp0s8 my_ipvlanl2
docker network ls
docker inspect my_ipvlanl2
# vm1(docker1) - 호스트
tcpdump -n -i docker0 icmp
tcpdump -n -i enp0s8 icmp
# vm1(docker1) - 컨테이너 실행 >> 같은 서브넷에 다른 장비와 통신 가능, 하지만 자신의 호스트와 통신 불가능
docker run --net=my_ipvlanl2 -it --name test1 --hostname test1 --ip 192.168.50.100 --rm ubuntu:14.04 /bin/bash
root@test1:/# ip a
root@test1:/# ping 192.168.50.20
root@test1:/# ping 192.168.50.10 << 자신의 호스트와 통신 불가능
root@test1:/# ping 192.168.50.200
root@test1:/# ping 192.168.50.254
root@test1:/# ping www.google.com
# vm2(docker2) - 호스트
docker run --net=my_ipvlanl2 -it --name test2 --hostname test2 --ip 192.168.50.200 --rm ubuntu:14.04 /bin/bash
root@test2:/# ip a
root@test2:/# ping 192.168.50.10
root@test2:/# ping 192.168.50.20 << 자신의 호스트와 통신 불가능
root@test2:/# ping 192.168.50.100
root@test2:/# ping 192.168.50.254
root@test2:/# ping www.google.com
# (옵션) 호스트에 컨테이너 2대 실행 시 서로 통신 가능 여부, enp0s8 패킷 캡쳐 가능 확인
## vm1(docker1) - 호스트
tcpdump -n -i enp0s8 icmp
## vm1(docker1) - 컨테이너 실행 >> 동일 호스트 내의 컨테이너끼리 통신 가능, tcpdump enp0s8 에 패킷 캡쳐 되지 않는다!
docker run --net=my_ipvlanl2 -it --name test3 --hostname test3 --ip 192.168.50.150 --rm ubuntu:14.04 /bin/bash
root@test3:/# ping 192.168.50.100
# 공통 - 삭제
docker network prune -f
802.1q trunk L2 mode
# 공통 - 기본 설정 >> docker network create 에서 자동으로 enp0s8.10 인터페이스가 생성되긴하지만 직접 생성 후 ip 를 설정해보자!
modinfo 8021q
ip link add link enp0s8 name enp0s8.10 type vlan id 10
ip -d link show enp0s8.10
# vm1(docker1) - 호스트
ip addr add 192.168.10.10/24 dev enp0s8.10
ip link set enp0s8.10 up
ip -c a show enp0s8.10
# vm2(docker2) - 호스트
ip addr add 192.168.10.20/24 dev enp0s8.10
ip link set enp0s8.10 up
ip -c a show enp0s8.10
# vm3(gw) - 호스트
ip addr add 192.168.10.254/24 dev enp0s8.10
ip link set enp0s8.10 up
ip -c a show enp0s8.10
# vm1, vm2 - ipvlan l2 mode(802.1q) 네트워크 생성
docker network create -d ipvlan --subnet=192.168.10.0/24 --gateway=192.168.10.254 -o parent=enp0s8.10 ipvlan10
# 네트워크 확인
docker network ls
docker inspect ipvlan10
# vm1(docker1) - 호스트
tcpdump -n -i enp0s8 icmp
tcpdump -n -i enp0s8.10 icmp
# vm1(docker1) - 컨테이너 실행 >> 같은 서브넷에 다른 장비와 통신 가능, 하지만 자신의 호스트와 통신 불가능
docker run --net=ipvlan10 -it --name vlan10_test1 --hostname vlan10_test1 --ip 192.168.10.100 --rm ubuntu:14.04 /bin/bash
root@vlan10_test1:/# ip a
root@vlan10_test1:/# ping 192.168.10.20
root@vlan10_test1:/# ping 192.168.10.10 << 자신의 호스트와 통신 불가능
root@vlan10_test1:/# ping 192.168.10.200
root@vlan10_test1:/# ping 192.168.10.254
root@vlan10_test1:/# ping www.google.com
# vm2(docker2) - 호스트
tcpdump -n -i enp0s8 icmp
tcpdump -n -i enp0s8.10 icmp
# vm2(docker2) - 컨테이너 실행 >> 같은 서브넷에 다른 장비와 통신 가능, 하지만 자신의 호스트와 통신 불가능
docker run --net=ipvlan10 -it --name vlan10_test2 --hostname vlan10_test2 --ip 192.168.10.200 --rm ubuntu:14.04 /bin/bash
root@vlan10_test2:/# ip a
root@vlan10_test2:/# ping 192.168.10.20
root@vlan10_test2:/# ping 192.168.10.10 << 자신의 호스트와 통신 불가능
root@vlan10_test2:/# ping 192.168.10.200
root@vlan10_test2:/# ping 192.168.10.254
root@vlan10_test2:/# ping www.google.com
# (옵션) 호스트에 컨테이너 2대 실행 시 서로 통신 가능 여부, enp0s8 패킷 캡쳐 가능 확인
## vm1(docker1) - 호스트
tcpdump -n -i enp0s8 icmp
tcpdump -n -i enp0s8.10 icmp
## vm1(docker1) - 컨테이너 실행 >> 동일 호스트 내의 컨테이너끼리 통신 가능, tcpdump enp0s8, enp0s8.10 에 패킷 캡쳐 되지 않는다!
docker run --net=ipvlan10 -it --name vlan10_test3 --hostname vlan10_test3 --ip 192.168.10.150 --rm ubuntu:14.04 /bin/bash
root@vlan10_test3:/# ping 192.168.10.100
# 삭제 (vm1, vm2)
docker network prune -f
ip link del enp0s8.10
보안
보안 가이드 : 2024년, KISA 클라우드 취약점 점검 가이드 - Link
실습환경
# CloudFormation 스택 삭제
aws cloudformation delete-stack --stack-name mylab
# [모니터링] CloudFormation 스택 상태 : 삭제 확인
while true; do
date
AWS_PAGER="" aws cloudformation list-stacks \
--stack-status-filter CREATE_IN_PROGRESS CREATE_COMPLETE CREATE_FAILED DELETE_IN_PROGRESS DELETE_FAILED \
--query "StackSummaries[*].{StackName:StackName, StackStatus:StackStatus}" \
--output table
sleep 1
done
삭제
'study > KANS 3기' 카테고리의 다른 글
KANS 3기 3주차 첫번째 (0) | 2024.09.18 |
---|---|
KANS 3기 3주차 실습환경 구축 (0) | 2024.09.08 |
KANS 3기 2주차 두번째 (0) | 2024.09.07 |
KANS 3기 2주차 첫번째 (0) | 2024.09.07 |
KANS 3기 1주차 첫번째 (0) | 2024.08.31 |