Cloud/Docker

Docker In Action 5. Single-host networking

로파이 2023. 10. 22. 00:25

Docker Network

로컬 컴퓨터에 연결된 네트워크는 IP 주소를 통해 인터넷 등의 통신을 가능하게 한다.

도커가 만드는 가상 네트워크는 모든 실행 중 인 컨테이너와 로컬 컴퓨터가 연결된 네트워크에 연결한다.

 

Bridge

 

여러 네트워크가 한 네트워크 처럼 동작하도록 연결하는 네트워크 인터페이스, 징검 다리 역할

 

도커 네트워크 확인

 

docker network ls

 

종류

bridge 이름의 네트워크는 bridge 드라이버를 통해 제공되는 네트워크이다. bridge 드라이버는 컨테이너간 연결을 제공한다.

host 이름의 네트워크에 있는 컨테이너들은 컨테이너가 아닌 일반 프로그램이 존재하는 호스트 네트워크를 공유한다. 

none 네트워크는 null 드라이버를 사용하고 해당 네트워크에 있는 컨테이너는 외부와 통신이 단절된, 고립된 네트워크이다.

 

Scope

local, global, swarm 카테고리가 있다. 

local은 네트워크가 존재하는 머신에 한정된다.

global은 클러스터 노드에 모두 생성되어야 하나 그들 사이에 라우팅되면 안된다.

swarm은 Docker Swarm이라는 멀티-호스트, 다중 클러스터 노드 기능에 참여한 호스트와 관련된 연결이다. 

 

도커 네트워크 생성

 

도커는 bridge라는 네트워크 드라이버는 linux namespace를 이용하며 가상 Ethernet 장치와 Linux firewall을 사용하여 커스텀 가능하고 구체적인 가상 네트워크 토폴리지를 형성한다.

 

각 컨테이너는 개인 loopback 주소와 각 컨테이너마다 할당된 네트워크와 연결되어 있는 ethernet 인터페이스를 갖는다.

각 컨테이너는 고유의 IP 주소를 할당받으며 외부로 공개되지 않는다.

각 컨테이너는 또한 도커 bridge 네트워크 인터페이스와 연결되고 도커 bridge는 host의 네트워크 인터페이스에 연결되어 있다.

 

생성

docker network create \
--driver bridge \
--label project=dockerinaction \
--label chapter=5 \
--attachable \
--scope local \
--subnet 10.0.42.0/24 \
--ip-range 10.0.42.128/25 \
user-network

 

user-network 이름의 네트워크를 생성한다.

드라이버 종류, 라벨, scope, 커스텀 서브넷 범위, IP 주소 범위를 설정한다. 이 네트워크에서 생성되는 컨테이너는 10.0.42.128 ~ 10.0.42.255 범위의 주소를 할당 받는다.

 

생성한 네트워크에 컨테이너 실행

docker run -it \
--network user-network \
--name network-explorer \
alpine:3.8 \
 sh

 

컨테이너에서 로컬 IPv4 네트워크 정보를 출력 해본다.

ip -f inet -4 -o addr

하나는 127.0.0.1의 루프백 주소이며 하나는 실제 컨테이너에 할당된 가상 Ethernet 장치의 주소이다.

이 가상 Ethernet은 birdge 네트워크에 연결 되어 있다.

10.0.42.129 IPv4를 할당 받았으며 이는 유효한 IP 주소 범위이다.

 

네트워크 간 연결

docker network connect user-network2 network-explorer

직접 만든 두 네트워크를 연결할 수 있다.

 

기존 network-explorer 실행되던 컨테이너에서 다시 네트워크 리스트를 본다면, 추가된 네트워크 인터페이스를 확인할 수 있다.

 

nmap을 이용한 네트워크 서비스 inspection

apk update && apk add nmap
nmap -sn 10.0.42.* -sn 10.0.43.* -oG /dev/stdout | grep Status

실행 중 인 컨테이너 자신의 IP 주소가 노출되어 있는 것을 확인할 수 있다.

 

두번째로 생성한 네트워크에서 컨테이너를 실행한다. 

docker run -d --name lighthouse --network user-network2 alpine:3.8 1d

 

다시 network-explorer 컨테이너로 돌아와서 nmap을 통해 네트워크 서비스를 식별해본다.

'network connect'를 통해 연결된 네트워크에서 실행된 컨테이너가 노출되는 것을 알 수 있다.

 

host and none 네트워크

docker run --rm \
--network host \
alpine:3.8 ip -o addr

--network 옵션으로 host를 지정한 컨테이너는 특별한 네트워크 adapter나 namepsace를 사용하지 않고 로컬 머신의 네트워크를 사용하여 컨테이너 밖에서 실행되는 환경을 사용한다.

 

docker run --rm \
--network none \
alpineL3.8 ip -o addr

none 네트워크 옵션은 어떠한 가상 Ethernet도 제공하지 않는다. 고유의 네트워크 namespace를 가지나 고립되었으며 외부 컨테이너와 연결되지 않는다.

 

- 컨테이너 내부에서 실행되는 프로그램은 같은 컨테이너에서 실행되는 네트워크 서비스에만 연결 가능하다.

- 외부로의 연결은 불가하고 외부에서도 내부로의 네트워크 연결도 불가능하다.

 

 

컨테이너 네트워크 Inbound traffic 공개하기

 

도커 컨테이너 간 연결은 bridge를 통해 연결되어 있지만, 외부와의 연결이 필요할 경우 트래픽을 내부로 라우팅하는 방법이 필요하다. 

도커 컨테이너 생성 시 외부 노출 포트와 내부 연결 포트를 지정하여 트래픽을 포워딩하는 것이 가능하다.

이로써 외부 클라이언트를 위해 특정 포트를 설정하고 내부 컨테이너에서 실행되는 프로그램은 외부 노출 포트가 어떠하든 상관없이 고유의 포트를 사용하여 서비스 실행이 가능하게 된다.

 

특정 포트 공개하기

- p 혹은 --publish로 포트 공개가 가능하다.

  • container_port : 컨테이너의 해당 고정 port를 host의 dynamic port로 바인딩한다.
  • host_port:container_port : 컨테이너의 고정 port를 host의 고정 port로 바인딩한다.
  • ip::container_port : 컨테이너의 container_port를 host의 특정 ip 주소와 dynamic port로 바인딩한다.
  • ip:hostport:container_port 컨테이너의 container_port를 host의 특정 ip 주소와 포트로 바인딩한다.

- P 옵션은 컨테이너 외부로 공개하는 port를 모두 공개한다.

docker run -d -p 8080 --name listener alpine:3.8 sleep 300
docker port listener

컨테이너를 실행하고 할당된 포트 맵핑을 확인한다.

 

컨테이너 네트워크 커스터 마이즈

Custom DNS configuration

 

Hostname 설정

 

호스트 이름을 사용하여 IP 주소 대신 명명 방식으로 주소를 대체한다.

docker run --rm --hostname barker alpine:3.8 nslookup barker

 

 

컨테이너에 hostname을 지정하고 nslookup을 통해 호스트 이름의 IP 주소를 확인한다.

컨테이너에 할당된 IP 주소가 barker 이름으로 확인되는 것을 알 수 있다.

컨테이너 내부에서 실행되는 프로그램이 hostname을 사용하여 자기 자신을 확인할 수 있다는 장점이 있다.

 

DNS 서버 설정

 

- dns 옵션

컨테이너에 DNS server 주소를 제공하여, 사용할 DNS 서버를 설정할 수 있다.

docker run --rm --dns 8.8.8.8 alpine:3.8 nslookup docker.com

 

 

 

- dns-search 옵션

Top-level domain 부분이 없는 검색에도 hostname을 검색할 수 있도록 한다.

docker run --rm \
--dns-search docker.com \
alpine:3.8 \
nslookup hub

hub.docker.com 의 hostname을 검색할 수 있도록 한다.

 

호스트 이름 맵핑 설정

 

- add-host 옵션

컨테이너 내부에서 hostname에 대한 커스텀 매핑을 제공한다.

docker run --rm \
--add-host test:10.10.10.255 \
alpine:3.8 \
nslookup test