본문 바로가기

study/KANS 3기

KANS 3기 1주차 두번째

도커 네트워크 모드

기본 네트워크 모드 : 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

 

Networking using the host network

Tutorials for networking using the host network, disabling network isolation

docs.docker.com

 - 컨테이너의 호스트 이름도 호스트 머신의 이름과 동일. 네트워크도 동일. 애플리케이션 별도 포트 포워딩 없이 바로 서비스 할 수 있음.

# 컨테이너 실행
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 - 링크

 

Multiple Containers, Same Port, no Reverse Proxy...

How Docker publishes container ports on the host? How to use SO_REUSEPORT to make multiple containers listening on the same port? How to use iptables to make multiple containers exposed on the same port?

iximiuz.com

# 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 network driver

All about using IPvlan to make your containers appear like physical machines on the network

docs.docker.com

IPVLAN - 링크

 

IPvlan network driver

All about using IPvlan to make your containers appear like physical machines on the network

docs.docker.com

 

실습환경

# 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

 

KISA 정보보호 및 개인정보보호관리체계 인증 클라우드 보안인증제 자료실

 

isms.kisa.or.kr

 

 

실습환경

# 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