[Docker / Kubernetes] 7. 도커 네트워크

서준교·2021년 9월 12일
2

Docker / Kubernetes

목록 보기
9/15
post-thumbnail

👉 이 게시글은 도커 / 쿠버네티스 온라인 부트캠프 with 카카오엔터프라이즈 강의를 바탕으로 작성되었습니다.

1. 호스트-컨테이너 네트워크

네트워크는 기본적으로 복수의 디바이스가 연결되어 있는 것을 의미한다. 연결된 디바이스 간에 데이터를 주고받는 규칙인 프로토콜(protocol) 을 기반으로 통신을 하게 되는데, 도커에도 이와 마찬가지로 동일한 역할을 수행하는 네트워크가 존재한다. 먼저, 호스트와 도커 엔진 간 네트워크 구성도를 살펴보도록 하자.


먼저 호스트와 도커 엔진 간 네트워크 구성도를 살펴보도록 하자. 도커 엔진에서 구동되는 컨테이너들도 역시 네트워크를 통해서 호스트와 연결되어 있다.

1) NIC (Network Interface Controller)

흔히 우리가 LAN 카드라고 부르는 것으로, 호스트와 네트워크간 데이터를 송수신하는 인터페이스의 역할을 수행한다. 물리적으로 구성된 NIC는 ens33으로 인식되며, 구버전 리눅스 배포판에서는 eth0으로 인식되었다. 추가적으로, 리눅스 네트워크의 이름은 아래 표와 같은 규칙에 의해 명명된다.

명칭설명비고
eth[0-N]펌웨어에 인덱스 정보가 없는 경우, 전통적인 방식이더넷
eno[1-N]펌웨어에 인덱스 정보가 있는 경우
ens[1-N]PCI 익스프레스 핫플러그 슬롯
enp[PCI slot]s[card index no]특정 PCI 슬롯에 특정 슬롯 번호가 지정된 경우
PPPpoint to point 프로토콜 장치모뎀
lo루프백 인터페이스루프백
tap가상 이더넷 장치

출처 : 제타위키 - 리눅스 네트워크

2) NAPT (Network Address Port Translation)


전세계의 한정된 IP 자원이 고갈되지 않도록 하기 위해 디바이스에는 사설 IP를 할당하고, 라우터에서 공인 IP를 매핑하여 인터넷망과 통신할 수 있도록 만든 시스템인 NAT (Network Address Translation)와 유사한 개념이다. 변환의 대상이 IP뿐만 아니라 포트까지 포함이 되고, 궁극적으로 호스트에서 도커 컨테이너들과 통신하기 위해 사용되는 기술이다.

이처럼 호스트 IP의 각 포트에 서로 다른 컨테이너의 IP를 매핑시켜주는 것이 NAPT의 역할이라고 할 수 있다.

3) docker0

브릿지 형태의 네트워크이며 도커 엔진을 실행하면 자동으로 생성된다.

컨테이너를 실행하면, 내부의 모든 포트를 docker0라는 가상 브릿지에 개방한다. 호스트는 NIC에서 직접 컨테이너와 연결하는 것이 아니라 이 브릿지를 경유하게 된다. docker0라는 브릿지 네트워크를 통해서 호스트의 요청이 각 컨테이너로 전송된다. 포트를 통해 각 컨테이너에 접근할 수 있도록 다리를 놔주는 역할을 하는 것이다.

4) veth()


컨테이너가 호스트와 통신하기 위해 컨테이너가 가지는 가상의 NIC이다. 각각의 veth는 컨테이너 입장에서 가상의 NIC를 eth0으로 인식하며, veth + 난수의 형태로 생성된다.

2. 도커 네트워크

만약 API를 통해 데이터를 DB에 등록하는 서비스를 구축하고자 하는 경우, API 서버와 DBMS 서버를 각각 컨테이너에 구축하여야 한다. 컨테이너 생성뿐만 아니라 이 두 컨테이너를 서로 통신이 가능하도록 설정해주어야 한다. 지금부터는 컨테이너간 네트워크의 구성 방식에 대해서 살펴보도록 하자.

1) Bridge


bridge 방식은 게이트웨이를 통해 호스트에서 각 컨테이너로 접근할 수 있도록 하는 네트워크 방식이다.
기본적으로 컨테이너를 구동할 때 별도의 네트워크 설정을 하지 않으면 모두 docker0라는 브릿지 네트워크에 연결된다. 같은 브릿지 네트워크에 연결된 컨테이너들은 동일한 네트워크 대역에 존재하므로, 서로 통신이 가능하다. 만약 별도의 브릿지 네트워크를 생성해서 컨테이너를 구성한다면 기존의 docker0에 연결된 컨테이너와는 통신을 할 수 없다.

$ docker container tun -d -p 80:80 --name webserver1 httpd
$ docker container tun -d -p 8080:80 --name webserver2 httpd
$ docker container tun -d -p 8081:80 --name webserver3 httpd

위 명령을 통해 3개의 컨테이너에 각각 웹서버를 구동하였을 때, IP가 어떻게 부여되었는지 확인해보도록 하자.

$ docker container inspect --format="{{ .NetworkSettings.IPAddress }} webserver1 webserver2 webserver3

컨테이너에 할당된 IP가 172.17 대역의 네트워크에 2, 3, 4로 인덱싱된 것을 확인할 수 있다. 1번은 게이트웨이에 할당이 되어 있기 때문에 IP는 2번부터 차례대로 부여된다.

2) Host

host 방식은 컨테이너가 호스트 IP를 그대로 이용하는 방식을 의미한다. 별도의 경유 없이 도커 엔진이 작동하고 있는 Host의 IP 주소를 그대로 사용하는 것이다. 브릿지를 통해 NAPT의 과정을 거치지 않아도 되며, 명시적으로 컨테이너의 포트를 명령어에 작성하지 않아도 된다. 또한, 호스트 형식의 네트워크는 리눅스 운영체제에서만 지원한다는 사실을 꼭 기억해두자.
다음 명령어로 host 방식의 네트워크를 기반으로 ubuntu 이미지를 컨테이너에서 실행해보도록 하자.

$ docker container run -it --network host --name ubuntu-host ubuntu:18.04

ifconfig 명령어가 포함된 net-tools 패키지를 설치한다.

$ apt-get update
$ apt-get install net-tools

설치가 완료되면, ifconfig 명령어를 컨테이너 내부에서 사용할 수 있다. 즉, 해당 컨테이너는 호스트와 격리된 환경이 아니라 호스트 위에서 작동하고 있는 것이다.
ifconfig 명령어를 실행하면 서버의 IP와 컨테이너의 IP가 동일한 것을 확인할 수 있다.

3) None


None은 완벽하게 컨테이너를 외부로부터 격리시키는 방식이다. 컨테이너를 격리된 공간에 차단시켜놓고 어떠한 네트워크와도 연결하지 못하게 하는 것을 의미한다.

$ docker container run -it --network none --name ubuntu-host ubuntu:18.04

외부 네트워크와 통신이 불가능하기 때문에 apt 패키지 저장소로부터 업데이트가 정상적으로 진행되지 않는 것을 확인할 수 있다.

3. 도커 네트워크 명령어

도커 엔진을 처음 실행하게 되면 기본적으로 많은 네트워크가 설정되어 있는 것을 확인할 수 있다. 이러한 네트워크를 확인하고, 여러 네트워크 관련 명령어에 대해 알아보도록 하자.

1) ls - 네트워크 목록 조회

$ docker network ls


ls 명령어로 네트워크 목록을 조회하면 기본적으로 도커 엔진에 설치된 세 종류의 네트워크(bridge, host, none)를 확인할 수 있다.

$ docker network ls --filter driver=bridge

또한, filter 옵션을 통해 특정 조건에 부합하는 네트워크를 조회할 수 있다. filter에는 name, driver, scope를 옵션으로 사용할 수 있다.

2) create - 네트워크 생성

$ docker network create --driver=bridge <네트워크 이름>

create 명령어를 통해 기본적으로 제공되는 네트워크 외에 별도의 네트워크를 추가적으로 생성할 수 있다. 네트워크 생성 시에 driver 옵션을 통해 어떤 타입의 네트워크를 생성할지 선택할 수 있다.
생성된 네트워크는 ls 명령어로 조회 가능하다.

3) connect - 네트워크 연결

$ docker network connect <네트워크 이름> <컨테이너 이름>

기존에 컨테이너 생성시 디폴트로 연결되어 있는 bridge 네트워크는 유지하면서 새롭게 생성한 네트워크에 컨테이너를 연결시킨다. 즉, 하나의 컨테이너가 두 개의 네트워크에서 각각 공유될 수 있는 것이다. 이를 inspect 명령어를 통해 확인해보도록 하자.

$ docker container inspect <컨테이너 이름>

bridge 네트워크의 게이트웨이 주소는 172.17.0.1이고, new-bridge 네트워크의 게이트웨이 주소는 172.18.0.1이다. 즉 하나의 컨테이너가 다른 대역의 네트워크에서 각각 공유될 수 있는 것이다. 해당 컨테이너는 두 네트워크에서 모두 통신이 가능하다.

4) disconnect - 네트워크 연결 해제

$ docker network disconnect <네트워크 이름> <컨테이너 이름>

컨테이너에 연결되어 있는 네트워크를 해제시킨다.Networks에서 bridge 항목이 지워진 것을 확인할 수 있다. 이제 이 컨테이너는 172.18 대역에서만 통신이 가능한 상태가 된 것이다.

5) inspect - 네트워크 상세 정보 조회

$ docker network inspect <네트워크 이름> 

네트워크에 기술되어 있는 다양한 정보들을 확인할 수 있다.

6) rm - 네트워크 삭제

$ docker network rm <네트워크 이름> 

기존의 네트워크를 삭제한다. 만약 삭제하고자 하는 네트워크와 연결되어 있는 컨테이너가 있다면 disconnect 명령어를 통해 연결 해제 후 삭제해야 오류가 발생하지 않는다.
ls 명령어를 통해 정상적으로 삭제된 것을 확인할 수 있다.

profile
매일 성장하는 개발자가 되고 싶습니다. 😊

0개의 댓글