안녕하세요 도커 공부에 심취해 있는 요즘, 도커 공부를 하다보니 도커 컨테이너의 Network
에 대해 알고 싶어졌습니다.
도커에 관련된 다양한 기술들을 배우다 보니 이 부분에 대해서 정리하고 넘어가는게 좋을 것 같습니다.
따라서 이번 포스팅에서는 Docker Network
에 대해 정리해보려고 합니다 ❗️
도커 네트워크(Docker Network)
란 Docker 컨테이너 간의 통신을 관리하고 격리하기 위한 기능을 제공하는 것입니다.
컨테이너화된 애플리케이션은 여러개의 컨테이너로 구성될 수 있는데, 이들 컨테이너가 서로 통신하고 데이터를 주고 받아야 할 경우가 있습니다.
도커 네트워크를 통해 이러한 컨테이너간 통신을 쉽게 설정하고 관리할 수 있도록 도와줍니다.
정리하자면, 같은 호스트 내에서 실행중인 컨테이너 간 연결할 수 있도록 돕는 논리적 네트워크 개념이다.
version: '3'
services:
front: # front container
image: frontend
networks:
- mynetwork
backend: # backend container
image: backend
networks:
- mynetwork
db: # db container
image: mysql
networks:
- mynetwork
environment:
MYSQL_ROOT_PASSWORD: mypassword
networks:
mynetwork:
.... # mynetwork 네트워크
위의 yml 은 Docker Compose
로 구성한 다중 컨테이너입니다.
fronted
,backend
,db
컨테이는 모두 networks
라는 항목을 통해 mynetwork
라는 네트워크로 묶여 있습니다.
이렇게 여러 컨테이너로 구성된 애플리케이션은 같은 네트워크 내에서 통신하여 데이터를 주고받을 수 있습니다😊
호스트에서 컨테이너가 생성되는 경우 결국 해당 컨테이너도 어플리케이션이기 때문에 IP 및 포트 등 네트워크을 구성하며, 이에 대한 정보가 할당되어야 합니다.
그렇다면 호스트에 의해 구동되는 컨테이너는 어떻게 네트워크를 구성할까요?
기본적으로 도커를 호스트 OS 에 설치하면 여러가지 네트워크 드라이버(Network Driver)
들이 설치되며, 구동되는 컨테이너에 IP 주소를 순차적으로 할당하고 해당 컨테이너는 네트워크를 구성할 때 원하는 네트워크 드라이버를 선택할 수 있습니다.
어떤 명령어을 통해 컨테이너 구동시 네트워크를 구성하는지는 마지막에 알아봅시다 ❗️
도커 네트워크의 구조를 본격적으로 알아보기 전 네트워크 인터페이스
라는 것을 먼저 정리하고 가겠습니다.
해당 이미지는 일반적인 네트워크 인터페이스 계층
을 설명하는 이미지입니다.
네트워크 인터페이스(Network Interface)
란 컴퓨터나 장치가 네트워크와 상호작용하기 위한 연결점이며, 데이터를 주고받을 수 있는 하드웨어 또는 소프트웨어 구성 요소입니다.네트워크 인터페이스
는 컴퓨터와 네트워크 간의 통신을 가능하게 하며, 데이터 전송과 수신을 처리합니다.
네트워크 계층을 통해 컴퓨터와 외부 네트워크의 물리적인 연결이 이루어지며, [1] 컴퓨터로부터 나오는 디지털 데이터
을 전기 신호나 전파같은 물리적 신호로 변환하여 네트워크로 변환시키며 동시에 [2] 네트워크로부터 받은 물리적 신호를 컴퓨터에서 처리할 수 있는 디지털 데이터로 변환합니다 🛜
TCP/IP
모델 최하층에 위치한 네트워크 인터페이스 계층은 이름에서 알 수 있듯이 인접한 네트워크 기기 간에, 즉 전송 매체로 연결되어 전기신호나 전파같은 물리적 신호가 도달하는 범위에서 데이터를 전송하는 역할을 합니다.
네트워크 인터페이스 계층이 직접 연결된 네트워크용 하드웨어 기기 간에 데이터 전송을 제어함으로써 상위 계층은 하드웨어의 종류에 상관없이 통신할 수 있게 됩니다 🔥
도커 네트워크 구조를 알아보기 전 마지막으로 veth
에 대해 알아봅시다.
리눅스의 Virtual Ethernet Interface
을 의미합니다.
앞서 네트워크 인터페이스
에 관해서 살펴보았던 것처럼 실제 컴퓨터의 랜카드(NIC)
을 통해 랜포트
을 열어서 랜 케이블
에 연결하는 것이 아니라, 가상의 네트워크 인터페이스를 생성하는 것입니다.
생각을 해보면 컨테이너로 구동된 애플리케이션은 일반적인 컴퓨터 애플리케이션 처럼 물리적인 네트워크 인터페이스를 사용할 수 없습니다 ⛔️
veth
는 일반적인 네트워크 인터페이스와는 달리 패킷을 전달받으면, 자신에게 연결된 다른 네트워크 인터페이스로 패킷을 보내주는 식으로 동작하기 때문에 항상 쌍으로 생성해줘야 합니다.
한 쪽에서 다른 쪽으로 패킷을 전송할 수 있으며, 한 쪽에 다운된 경우 나머지 한 쪽도 정상적으로 기능하지 않는 것이 특징입니다.
도커에서는 실행중인 컨테이너 수 만큼 veth
로 시작하는 인터페이스가 생성됩니다.
본격적으로 도커 네트워크의 구조에 대해 알아보겠습니다.
앞서 언급했던 것처럼 도커 컨테이너도 결국 네트워크를 구성합니다. 따라서 컨테이너마다의 IP 와 포트가 존재하겠죠?
도커는 호스트로부터 실행되는 컨테이너에 172.17.0.x
의 IP 을 순차적
으로 할당합니다.
이를 확인해보기 위해 아래의 명령어를 통해 간단한 ubuntu container 을 실행시켜보겠습니다.
docker run -it ubuntu:latest
이후 ubuntu OS 에서 apt-get update
을 통해 ubuntu OS에서 사용 가능한 패키지들과 그 버전에 맞는 정보를 업데이트 합니다.
그 후, apt-get install net-tools
을 통해 네트워크 관련 도구를 설치해줍니다.
해당 과정을 꼭 진행시켜야 ubuntu OS 에서 네트워크와 관련된 기능을 사용할 수 있습니다 ❗️
모든 준비를 마치고 도커 컨테이너로 구동되는 ubuntu OS 에 ifconfig
명령어를 실행시켜보겠습니다 👨💻
참고 - ifconfig 명령어란?
ifconfig
명령어를 통해 컨테이너의 네트워크 인터페이스에 대한 정보를 확인할 수 있습니다.
위의 스크린샷을 보면 IO
네트워크 인터페이스와 eth0
네트워크 인터페이스가 각 172.17.0.1 과 172.17.0.2 가 할당된 것을 확인할 수 있습니다.
여기서 Io
네트워크 인터페이스는 루프백(자기 자신한테 보내는) 과 관련된 것이고 eth0
은 외부 네트워크와 관련된 것입니다 ❗️
해당 도커 컨테이너에 아무런 설정을 하지 않는다면 외부에서 접근할 수 없으며 오로지 해당 도커 컨테이너를 구동시킨 호스트에서만 접근 가능합니다.
그렇다면 외부에서 해당 컨테이너에 접근할 수 있는 방법은 없는걸까요? 🤔
여기서 앞에서 살펴본 veth
가 사용됩니다 ❗️
외부 네트워크에 컨테이너 어플리케이션을 노출하기 위해서는 eth0
의 IP/PORT 을 호스트의 IP/PORT 에 바인딩시켜야합니다.
외부와의 네트워크 연결은 컨테이너마다 eth0
에 대응되는 veth
라는 가상 네트워크 인터페이스를 호스트에 생성함으로써 이루어집니다. 그리고 각각의 IP 주소와 포트를 입력해 컨테이너를 외부에 노출 시킬 수 있습니다. veth
는 도커 호스트에서 ifconfig
명령어를 입력하면 확인 가능합니다.
즉, eth0
에 대응되는 vethXXXX
이라는 이름의 veth
interface와 브릿지 네트워크에 컨테이너의 interface가 바인딩되는 형태로 통신합니다.
veth
인터페이스는 사용자가 직접 생성할 필요는 없고 컨테이너가 생성될 때 도커 엔진이 자동으로 생성합니다. 도커 컨테이너가 실행될 때 네트워크 드라이버를 따로 지정하지 않으면 docker0라고 하는 브릿지 네트워크를 default로 사용합니다. 이 브릿지 네트워크의 역할은 veth
와 호스트의 eth0
의 다리 역할을 합니다. 🦵
[도커 네트워크 구조 정리]
veth(Virtual Ethernet)
이라는 네트워크 인터페이스를 생성가상 네트워크 인터페이스
을 호스트에 생성하며 인터페이스 이름은 veth
로 시작veth
인터페이스는 사용자가 직접 생성할 필요가 없으며 컨테이너가 생성될 때 도커 엔진이 자동으로 생성veth
인터페이스는 호스트가 갖고 있는 eth0
,eth1
등과 연결되어 있음docker0
브리지는 각 veth
인터페이스와 바인딩돼 호스트의 eth0
인터페이스와 이어주는 역할을 함docker network ls
해당 명령어를 통해 로컬 도커에 설치된 네트워크 목록과 해당 네트워크에 드라이버까지 확인 가능합니다.
docker network inspect [도커 네트워크 ID or 도커 네트워크 이름]
Docker network ls
로 조회했던 네트워크 목록에서 이름이 bridge
인 네트워크 상세조회 결과입니다.
여기서 주목할 부분은 Subnet
과 Gateway
부분인데, 서브넷이 172.17.0.0/16
으로 설정되더 있으며, 호스트 내에서 컨테이너 생성시 해당 대역을 부여합니다.
이뿐만 아니라 해당 네트워크에 대한 다양한 정보를 확인할 수 있습니다.
docker network create [만들 네트워크 이름]
test_network
라는 네트워크를 생성한 후 네트워크 목록을 조회한 결과입니다.
네트워크가 정상적으로 생성된 것을 확인할 수 있습니다 ❗️
네트워크를 생성할 때 네트워크 드라이버 또한 지정할 수 있습니다.
docker network create --driver = [네트워크 드라이버 이름][만들 드라이버 이름]
docker run -d ... --network=[네트워크 이름][컨테이너 이름]
앞서 만든 test_network01
이라는 네트워크를 이용해서 ubuntu
컨테이너를 실행시키겠습니다 ❗️
docker network connect [네트워크 이름][컨테이너 이름]
해당 명령은 이미 실행중인 컨테이너에 네트워크를 지정한다는 점에서 4번과 다릅니다.
앞서 만든 test_network01
을 이미 실행중인 mysql
컨테이너에 지정해보겠습니다 ❗️
도커 네트워크 드라이버는 Native
와 Remote
로 나뉩니다.
Native Drivers
: Bridge
,Host
,None
,Overlay
을 사용
Remote Drivers
: 3rd party 드라이버로 외부에서 잘 만들어진 드라이버를 사용
도커 네트워크 드라이버는 단일 호스트
,다중 호스트
로 분류할 수도 있습니다.
단일 호스트 네트워크 드라이버
: Bridge
,Host
,None
다중 호스트 네트워크 드라이버
: Overlay
포트를 연결해 컨테이너 애플리케이션의 Port 를 외부에 노출하는 방식이 bridge 네트워크
입니다.
아무런 네트워크 드라이버를 지정하지 않으면 default 로 docker0
이라는 bridge 네트워크
를 사용합니다.
또한 커스텀 bridge 네트워크
또한 생성가능합니다.
docker network create --driver=bridge my-bridge
앞서 보았던 컨테이너 네트워크 생성 명령어를 통해 my-bridge
라는 컨테이너 네트워크를 만들었습니다 ❗️
아무런 네트워크 설정을 하지 않은 채로, bridge
네트워크를 확인해보면 docker0
네트워크인 것을 확인할 수 있습니다.
IP 172.17.0.0
을 사용하는 것을 확인할 수 있고 컨테이너를 네트워크 드라이버를 지정하지 않고 생성하면 해당 docker0 브릿지 네트워크를 사용합니다.
host 네트워크
는 도커가 제공해주는 가상 네트워크 인터페이스(veth) 을 상요하는 것이 아니라 이름 그대로 host 의 네트워크에 붙어서 사용하는 개념입니다 ❗️
그래서 bridge 네트워크
처럼 포트 바인딩을 할 필요가 없으며 호스트 네트워크에 접속하면 컨테이너 또한 접속 가능합니다 🐳
간단하게 도커를 이용해서 host
네트워크를 이용해서 httpd
컨테이너를 구동시켜보겠습니다.
상단 이미지를 통해 해당 컨테이너에 포트가 따로 지정이 되지 않은 것을 확인할 수 있습니다.
호스트 네트워크에 붙어있기 때문에 별도의 포트가 할당되지 않는게 당연하겠죠? 😊
none 네트워크
는 해당 컨테이너가 네트워크 기능이 필요 없을 때, 혹은 커스텀 네트워크를 사용해야 되는 경우가 있을 때 네트워크 드라이버를 none
으로 설정하고 사용할 수 있습니다 ❗️
즉 외부 네트워크와의 연결이 단절됩니다 🚫
docker run -d --network=none nginx:latest
해당 명령어를 통해 외부 네트워크와 단절된 Nginx
웹 서버가 컨테이너로 구동될 것이라는 것을 이해할 수 있습니다 ❗️
이번 포스팅에서는 도커의 네트워크에 대해서 알아보았습니다.
최대한 깊게 알아보려고 많은 시간을 투자했고 개인적으로 Network
에 대한 지식이 빈약해서 해당 포스팅 내용과 관련된 다양한 네트워크 기술들에 대해 공부하는 시간을 가졌습니다.
도커의 가상화 기술은 공부하면 할 수록 정말 혁신적인 기술인 것 같습니다.
다음 포스팅에서 도커에 대한 더 깊은 공부를 해보겠습니다 🔥 긴 글 읽어주셔서 감사합니다.
6장. 도커 네트워크 구조
06. 도커 네트워크 (Docker Network)
DevOps/Docker [Docker] 도커 네트워크 이해하기
Infra/Docker[Docker] Docker Network 사용하기
쉽게 이해하는 네트워크 10. TCP/IP 네트워크 인터페이스 계층의 역할과 데이터 전송 (ft. 랜카드와 MAC 주소)
쉽게 이해하는 네트워크 7. TCP/IP 계층의 특징과 역할 및 프로토콜
그러면 Overlay드라이버로 여러개의 콘테이너를생성하여 각콘테이너마다 네트워크를 구성하여 각콘테이너마다 vpn서버로 쓸수있나요?