1. 컨테이너의 네트워크

1) 리눅스 네트워크

- 도커 네트워크는 리눅스 커널의 네트워크 스택의 하위 스택, 상위에는 네트워크 드라이버 생성

- CNM이라고 하는 인터페이스 위에 구축

- 인터페이스 특성상 해당 기능이 구현되기만 하면 실행에 문제가 없으므로 OS나 인프라에 구애받지 않고 사용 가능

- 리눅스 네트워크 빌딩 블록 : 리눅스 브릿지, 네트워크 네임스페이스, veth pair, iptables 등이 포함

    → 복잡한 네트워크 정책을 위한 규칙 및 네트워크 분할 및 관리 도구 제공

- 2계층에 해당하는 도구로 MAC 주소를 활용하여 식별하고 통신

※ 리눅스 브릿지 : 커널 내부의 물리적인 스위치를 프로그래밍적으로 가상 구현한 OSI L2 디바이스

    → 트래픽을 검사하여 동적으로 학습되는 MAC Address를 기반으로 트래픽 전달

- 브릿지 네트워크의 기본 대역

① 172.17~31.0.0/16 (65536개)

② 192.168.0~240.0/20 (4096개)

- Docker 0 : 리눅스 커널과 os 도구를 통해 관리하고, Docker0 위에 브릿지들이 위치하여 도커엔진하에 관리됨, 브릿지와 컨테이너 사이에 vethernet이 위치해 연결해줌

위와 같이 기본적으로 할당된 이더넷 브릿지 대역(172.17.0.1)을 확인할 수 있다.

 

2) 도커 네트워크

① 네트워크 네임스페이스

- 커널에 격리된 네트워크 스택으로 자체 인터페이스, 라우터, 방화벽 규칙 보유

- 컨테이너와 리눅스의 보안적인 측면으로 컨테이너를 격리하는 데 사용

- 일반적으로 CNM 네트워크 드라이버는 각 컨테이너별로 별도 네임스페이스가 구현됨

② CNM(Container Network Model) : 도커 네트워크가 이런 요소들을 가져야 한다고 정의해둔 인터페이스

- sandbox : 격리된 네트워크 자체 → ethernet, port, route table, DNS 구성 등을 총체적으로 그룹화

- endpoint : 가상 이더넷의 인터페이스 → IP, MAC 주소 등으로 접근

- network : 가상 스위치, 브릿지

※ CNM을 기반으로 구현한 libnetwork가 docker network이다.

위와 같이 실제로 사용 가능한 모델들을 볼 수 있고, bridge, host, none(아무것도 쓰지 않음)을 확인할 수 있다.

브릿지는 기본적으로 싱글 호스트를 지원하여 내부망으로 연결만 해줄뿐 다른 네트워크와 연결되지 않는다.

※ 멀티호스트 지원은 bridge to bridge 수행을 위해 overlay라는 것을 통해 지원된다.

- 컨테이너는 직접 bridge와 연결될 수 없음 → vethernet : 컨테이너와 1:1로 매칭되어 브릿지 사이에서 중개해주는 역할

- 컨테이너 자체의 엔드포인트 조회 : ifconfig, route, ip a, ip addr, ip add 등

- 브릿지 조회 : brctl show

$ sudo apt install bridge-utils
$ brctl show

docker0 네트워크를 활용하는 컨테이너들이 interfaces에 나열된다.

컨테이너 추가 후 다시 조회해보면 인터페이스가 추가된 것을 볼 수 있다. 인터페이스는 꼭 생성 순서대로 나열되지는 않는다.

exec 명령어를 사용하여 ip addr 명령어를 수행해보면 위와 같이 loopback과 vethernet 주소를 확인할 수 있다.

route 명령어를 통해 해당 컨테이너와 연결된 브릿지를 확인할 수 있다. docker0(172.17.0.0)과 연결된 것을 볼 수 있다.

호스트에서 route 명령어를 수행하면 좀 더 확실하게 조회할 수 있다.

또한, inspect 명령어를 통해 해당 컨테이너의 IP, MAC 정보를 확인할 수 있다.

즉, 컨테이너가 네트워크 통신을 위해 갖는 모든 것들은 샌드박스에 의해 정의된다.

위에서 docker network ls 조회 시 나왔던 bridge는 기본 브릿지이고, docker0 위에 얹혀져 있다.

위 명령어를 통해 브릿지 자체에 대해 inspect 해보면 위와 같이 IPAM 내부에서 네트워크 전체 대역에 대한 내용을 볼 수 있다.

또한, Containers를 통해 할당된 컨테이너들도 확인할 수 있다.

 

Veth는 두 네트워크 네임스페이스 사이의 연결을 위해 동작하는 리눅스 네트워킹 인터페이스이다.

Vethernet은 각 네임스페이스에 단일 인터페이스를 가지는 전이중 링크로 양방향 통신이 되어 한 인터페이스의 트래픽을 다른 인터페이스로 전해주는 역할을 한다. 도커 네트워크 생성 시 Veth를 통해 네임스페이스 간 명시적 연결을 제공한다.

컨테이너의 Eth은 Veth보다 기본적으로 1 작은 값으로 연결된다.

위와 같이 veth 값이 배정된 것을 볼 수 있고, 이 경우 컨테이너 자체의 eth 값은 9, 7, 5번이 될 것이다.

해당 컨테이너의 bash로 진입해둔 상태라면 위 명령어로 veth 값을 조회할 수 있다.

 

docker0은 기본적으로 172.17.0.1을 사용하지만 외부에서는 172.17 대역을 쓰지 않으므로 이를 보완하기 위해 NAT이라는 것을 활용한다.

결국 어떤 서버의 IP 주소를 다시 내부 IP로 변환해줘야 하는데 이때 매핑되는 주소를 iptables라는 명령어로 조회할 수 있다.

위와 같이 0.0.0.0/0 (외부 접속자 누구라도) 으로 접속하면 연결되는 포트번호 등을 확인할 수 있다.

 

 

2. 내부망 host들  상호 간 등록하기

host1과 host2 터미널을 오가거나 scp 등으로 파일을 보낼 때 불편했는데 내부망 호스트들을 상호 간 등록하여 IP주소가 아닌 host 이름으로 해당 작업들을 수행할 수 있다.

1) PC 간

$ sudo vi /etc/hosts

먼저, 위 파일을 열어보면 localhost와 hostos1의 주소만 등록되어 있는 것을 볼 수 있다.

위와 같이 hostos1과 hostos2에 설정했던 주소를 192대 대역으로 입력해준다.

$ ssh 계정명@호스트명

위와 같이 ssh 명령어로 hostos1 PC에서 hostos2를 제어할 수 있게 된다.

또한, w를 입력하면 위와 같이 hostos1이 접속중임을 확인할 수 있다.

 

2) 컨테이너 간

컨테이너들도 서로 다른 PC의 호스트 연결과 비슷한 작업을 할 수 있다.

--add-host=host명:ip주소를 통해 컨테이너의 /etc/hosts에 호스트명:IP주소를 매칭하여 저장한 것을 확인할 수 있다.

또한, dns 등록도 가능하다.

--dns=ip주소를 통해 DNS 서버의 ip 주소를 /etc/resolv.conf에 등록해준다. 

--mac-address=mac주소를 통해 MAC 주소를 지정할 수도 있다.

 

3) 네트워크 관련 지정 옵션

--expose=포트번호 방화벽 열기처럼 해당 포트로의 접속을 외부에 공개
--net=bridge
--net=none
--net=host
container의 네트워크 설정, bridge는 docker0
-h
--hostname=호스트명
host의 이름 설정, pid가 디폴트값
-P
--publish-all=true
--publish-all=false
포트바인딩 시 호스트측 접근 포트를 랜덤 지정
-p host포트:컨테이너포트
--publish published=host포트
--target=타겟포트
지정포트바인딩
--link=컨테이너명:컨테이너ID 동일 호스트의 다른 컨테이너에서 이름으로 연결 가능하게 지정

위와 같이 여러 옵션을 사용하여 네트워크 설정을 할 수 있고, expose 옵션으로 지정했던 포트가 잘 열려있는 것을 확인할 수 있다.

물론, 기본적으로는 history 명령어를 통해 Dockerfile에 설정된 포트를 노출하는 것이 제일 중요하다.

위와 같이 포트바인딩 자체는 알아서 32769:80, 32769:30000으로 배정되어 있는 것을 볼 수 있다.

또한, 위와 같이 6367번 PID로 도커 프록시가 돌고 있고, 해당 프록시가 world(0.0.0.0)의 32769번 포트로 접속하는 것을 172.17.0.6의 80번 포트로 연계해주는 것을 볼 수 있다.

 

 

3. 브릿지와 오버레이의 차이

브릿지는 기본적으로 내부망으로 진입할 수 있는 진입점의 기능을 한다. 다만, 브릿지는 자신의 호스트 내부망만을 담당한다.

따라서 브릿지 간 통신, 즉 외부 호스트끼리 연결하기 위해서는 overlay가 추가로 필요하다. 이는 도커 스웜을 통해 구현할 수 있다.

+ Recent posts