Docker Network

진성대·2023년 10월 3일
0

Docker

목록 보기
8/12
post-thumbnail

Docker Network

  • docker network 는 커널의 네트워크 스택의 하위로, 상위에는 네트워크 드라이브를 생성한다. 즉, docker network = Linux network와 같다.
  • Docker network 아키텍처는 CNM(Container Networking Model) 이라고 하는 인터페이스 집합 위에 구축한다. OS 및 인프라에 구애받지 않으므로 인프라 스택에 관계없이 애플리케이션이 동일한 환경을 가질 수 있다.
  • 리눅스 네트워킹 빌딩 블록: 리눅스 브리지, 네트워크 네임스페이스, veth pair 및 iptables가 포함. 이 조합은 복잡한 네트워크 정책을 위한 전달 규칙, 네트워크 분할 및 관리 도구를 제공한다.

CNM

1. Endpoint: 컨테이너 내부의 네트워크 인터페이스를 나타냅니다. 각 컨테이너는 하나 이상의 엔드포인트를 가질 수 있습니다.

2. Sandbox: 컨테이너의 네트워크 스택을 나타냅니다. 샌드박스 안에는 여러 엔드포인트가 존재할 수 있습니다.

3. Network: 동일한 네트워크 설정(예: IP 주소 범위, 라우팅 규칙 등)을 공유하는 일련의 엔드포인트들을 그룹화합니다.

4. Driver/Plugin: CNM의 정의된 API를 구현하여 특정 네트워크 솔루션과 Docker를 통합합니다. 예를 들어, Overlay, Bridge, Host 등의 내장 드라이버가 있으며, 외부 네트워크 솔루션을 통합하기 위해 써드파티 플러그인도 사용할 수 있습니다.

Linux bridge

  • 리눅스 브릿지는 커널 내부의 물리적 스위치를 가상으로 구현한 OSI Layer2 Device 다.
  • 트래픽을 검사하여 동적으로 학습되는 MAC 주소를 기반으로 트래픽을 전달.
  • bridge network의 기본 대역?
    1) 127.{17-31}.0.0/16(65536개)
    2) 192.168.{0-240}.0/20(4096개)

Network namespace

  • 커널에 격리된 네트워크 스택으로 자체 인터페이스, 라우트 및 방화벽 규칙을 보유
  • 컨테이너와 리눅스의 보안적인 측면으로, 컨테이너를 격리하는데 사용
  • 네트워크 네임스페이스는 도커 네트워크를 통해 구성된 경우가 아니면 동일한 호스트의 두 컨테이너가 서로 통신하거나 호스트 자체와 통신할 수 없음을 보장
  • 일반적으로 CNM(Container Network Model)네트워크 드라이버는 각 컨테이너에 대해 별도의 네임스페이스를 구현

참고

CNM(Container Network Model)

  • 가상 이더넷 인터페이스 => Endpoint(이더넷)을 이용해서 Mac addressip를 제공하고 그 주소를 통해서 접근이 가능하도록 한다.

Libnetwork

  • CNM 을 구현한 구현체

[ec2-user@ip-172-31-39-154 ~]$ docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
1b1f9cb59d91   bridge    bridge    local
a6d2dc487604   host      host      local
5964bb59b326   none      null      local

bridge network 사용할 수 있는 부분 확인

  • bridge로 연결된 container 들은 local에서만 연결 가능하다.
  • bridge to bridge 간에 통신은 orverlay driver를 통해서 가능하다.

veth(Virtual ethernet device)

  • 두 네트워크 네임스페이스 사이의 연결선으로 동작하는 리눅스 네트워킹 인터페이스
  • veth는 각 네임스페이스에 단일 인터페이스가 있는 전이중 링크(full duplex link)
  • 한 인터페이스의 트래픽을 다른 인터페이스로 전달
  • 도커 네트워크를 만들 때 도커 네트워크 드라이버는 veth를 사용하여 네임스페이스 간에 명시적인 연결을 제공
  • 컨테이너가 도커 네트워크에 연결되면 veth의 한쪽 끝은 컨테이너 내부에 배치되며, (일반적으로 ethN 인터페이스로 표시) 다른 쪽은 도커 네트워크에 연결된다.

  • Container 는 direct로 bridge와 연결되지 못한다.
  • 중간에 터널 역할을 하는, 터널링 네트워크를 구현하는 virtual ethernet이 존재한다.

    veth는 OSI 2계층 서비스로 컨테이너 내부에 제공되는 네트워크 인터페이스 eth0와 한 쌍(pair)으로 제공되어 docker0와 가상의 "터널링 네트워크"를 제공한다.

[ec2-user@ip-172-31-39-154 ~]$ ip link show type bridge
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default
    link/ether 02:42:d0:20:24:d4 brd ff:ff:ff:ff:ff:ff
    
# Container의 네트워크(eth0)는 vethxxxxxxx의 숫자보다 하나 작은 값을 가진다.
  • bridge network는 docker0 와 연결된 하나의 모델이다.
  • brctl 명령어는 Linux 브리지 관리를 위한 기본 도구였습니다.
  • 최근의 Linux 배포판에서는 brctl이 bridge-utils 패키지의 일부로 제공되지 않을 수 있습니다.
  • 대신, iproute2 패키지의 ip 명령어가 브리지 관리 기능을 포함하게 되면서 brctl을 대체하게 되었습니다.
[ec2-user@ip-172-31-39-154 ~]$ docker network inspect bridge
[
    {
        "Name": "bridge",
        "Id": "1b1f9cb59d91a453d9410b3411633ab5619c50de10518fc981141f39acd08716",
        "Created": "2023-10-04T12:06:13.538637267Z",
        "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": {
            "2fc3fd2105463433d10d0943ee821073747009eceab9323d792ac2805fdc9bf2": {
                "Name": "sjin-ubuntu",
                "EndpointID": "dd072efc037c5fdc13ab5dd5a24e2cab7d64c1ba78213656e5b7ac95008113d3",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "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": {}
    }
]
  • IPAM 을 통해서 IP Addreess 가 관리되고 있다.

docker network option

옵션설명
--add-host=[Host명:IP Address]Container의 /etc/hosts에 Host명과 IP Address를 설정
--dns=[IP Address]DNS 서버의 IP Address를 설정 (/etc/resolv.conf)(168.126.63.1~3/8.8.8.8)
--mac-address=[MAC Address]Container의 MAC Address 설정
--expose=[포트 번호]Container 내부에서 Host로 노출할 포트 번호 지정
-net=[bridge , none , host]Container의 네트워크 설정(birdge = docker0)
-h, --hostname="Host명"Container의 Host명 설정(default, container ID가 호스트명)
-P, --publish-all=[true , false]Container 내부의 노출된 포트를 호스트 임의의(32768~) 포트를 호스트와 연결(명시적)
-p [Host 포트 번호]:[Container 포트 번호] --publish published=5000, target=80Host와 Container의 포트를 매핑(암시적)
--link=[container:container_id]동일 Host의 다른 Container에서 엑세스 시 이름 설정 IP가 아닌 container의 이름을 이용해 통신 가능

docker network

# container DNS 서버 설정
[ec2-user@ip-172-31-39-154 ~]$ docker run -it --dns=8.8.8.8 centos bash

[root@bd746dbb906b /]# cat /etc/resolv.conf
search ap-northeast-2.compute.internal
nameserver 8.8.8.8

# container MAC Address 설정
[ec2-user@ip-172-31-39-154 ~]$ docker run -d --mac-address="92:d0:c6:0a:29:33" centos:7
[ec2-user@ip-172-31-39-154 ~]$ docker inspect --format="{{ .Config.MacAddress }}" sad_mcclintock
92:d0:c6:0a:29:33

# Host 명과 IpAddress 설정
[ec2-user@ip-172-31-39-154 ~]$ docker container run -it --add-host=fastcampus.co.kr:192.168.0.100 centos:7 bash
[root@b74c2c3639eb /]# cat /etc/hosts
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
192.168.0.100	fastcampus.co.kr
172.17.0.3	b74c2c3639eb

# docker-proxy? kernel이 아닌 사용자 환경에서 수행되기 때문에 kernel과 상관없이 host 가 받은 패킷을 그대로 container의 port로 전달. 
# port를 외부로 노출하도록 설정하게 되면, docker host에는 docker-proxy라는 프로세스가 자동으로 생성
[ec2-user@ip-172-31-39-154 ~]$ docker run -d -P --name=myweb --expose=40001 nginx:1.25.0
[ec2-user@ip-172-31-39-154 ~]$ docker port myweb
80/tcp -> 0.0.0.0:32769
80/tcp -> [::]:32769
40001/tcp -> 0.0.0.0:32768
40001/tcp -> [::]:32768

[ec2-user@ip-172-31-39-154 ~]$ docker ps | grep myweb
31d158ad65d5   nginx:1.25.0   "/docker-entrypoint.…"   39 seconds ago   Up 39 seconds   0.0.0.0:32769->80/tcp, :::32769->80/tcp, 0.0.0.0:32768->40001/tcp, :::32768->40001/tcp   myweb

[ec2-user@ip-172-31-39-154 ~]$ sudo netstat -nlp | grep 32769
tcp        0      0 0.0.0.0:32769           0.0.0.0:*               LISTEN      30563/docker-proxy
tcp6       0      0 :::32769                :::*                    LISTEN      30568/docker-proxy


[ec2-user@ip-172-31-39-154 ~]$ ps -ef | grep 30563
root       30563   10836  0 12:58 ?        00:00:00 /usr/bin/docker-proxy -proto tcp -host-ip 0.0.0.0 -host-port 32769 -container-ip 172.17.0.3 -container-port 80
ec2-user   30759   28167  0 13:01 pts/0    00:00:00 grep --color=auto 30563

docker network, overlay

  • Overlay network는 서로 다른 Host(node)에서 서비스되는 컨테이너를 네트워크로 연결하는데 사용 되고, 이런 네트워크 생성을 위해 overlay network driver를 사용한다.
  • 네트워크로 연결된 여러 Docker Host안에 있는 Docker Daemon 간의 통신을 관리하는 가상 네트워크다.
  • 컨테이너는 overlay network의 서브넷에 해당하는 IP대역을 할당 받고, 받은 IP를 통해 상호간의 내부 통신을 수행한다.
  • 따라서, Overlay network에 포함되어 있는 모든 컨테이너들은 서로 다른 Docker Host에 있는 컨테이너와 같은 서버에 있는 것처럼 통신이 가능해진다.
  • Docker swarm을 통해 구현할 수 있다.
~$ docker network inspect {network-ID}를 통해 조회가능

profile
신입 개발자

0개의 댓글