도커 네트워크-#2 독립형 컨테이너 네트워킹(1)

혀어어언·2023년 4월 8일
0

Docker

목록 보기
6/11

독립형 컨테이너(standalone containers)로 네트워킹하기

기본 브리지 네트워크(default bridge network)

기본 브리지 네트워크 사용에서는 Docker가 자동으로 설정하는 기본 브리지 네트워크를 사용하는 방법에 대해 알아보겠습니다.
기본 브리지 네트워크는 개발 시스템에서 적합하며 프로덕션 환경에서는 사용자 정의 브리지 네트워크를 권장합니다.

기본 브리지 네트워크란?

도커에서 기본 브리지 네트워크(Bridge Network)는 도커 엔진이 설치될 때 자동으로 생성되는 가상 네트워크입니다. 이 가상 네트워크를 통해 도커 컨테이너 간에 통신할 수 있습니다.

기본 브리지 네트워크는 가상의 스위치 역할을 하며, 각 컨테이너에 IP 주소를 할당하여 컨테이너 간 통신을 가능하게 합니다. 이를 통해, 같은 브리지 네트워크에 속한 컨테이너끼리는 서로 통신이 가능해집니다.

기본 브리지 네트워크는 컨테이너에 대한 IP 주소를 DHCP로 할당합니다. 따라서, 컨테이너를 실행할 때마다 다른 IP 주소가 할당됩니다.

또한, 기본 브리지 네트워크는 도커 호스트에만 연결되어 있으며, 다른 호스트에서 실행된 컨테이너와는 통신할 수 없습니다.

하지만, 컨테이너끼리는 IP 주소를 통해 직접적으로 통신하므로, 도커 호스트가 아닌 다른 호스트에서 실행된 컨테이너와도 기본 브리지 네트워크를 통해 통신이 가능합니다.

기본 브리지 네트워크는 보안 측면에서는 취약합니다. 모든 컨테이너가 동일한 네트워크에 속해 있기 때문에, 컨테이너 간에 서로 접근이 가능합니다. 따라서, 보안 상 이슈가 있는 앱을 실행할 때에는 다른 네트워크 모드를 사용하는 것이 좋습니다.

기본 브리지 네트워크 관련 실습

두 개의 다른 alpine 컨테이너를 같은 도커 호스트에서 실행하여 각각의 컨테이너가 어떻게 상호작용하는 지 알아보겠습니다.

실습 진행 순서

  1. 실행전 현재 네트워크 확인
  2. 컨테이너 생성 및 시작
  3. 현재 실행되고 있는 컨테이너 확인
  4. 네트워크에 연결된 컨테이너 확인
  5. 컨테이너 접속하여 네트워킹
    1. 컨테이너 간 연결 확인
    2. 인터넷 연결 확인
  6. 컨테이너 접속 종료
  7. 컨테이너 중지 및 제거

1. 실행 전 현재 네트워크 확인

  • 네트워크 확인 명령어 입력
$ docker network ls
  • 도커 데몬에 네트워크를 추가하거나 스웜이 초기화되지 않았다면 다음과 같은 화면이 확인될 것입니다.

    • 기본 bridge 네트워크가 hostnone과 함께 나열됩니다.
    • hostnone은 완전한 네트워크는 아니지만, 도커 데몬 호스트의 네트워킹 스택에 직접 연결된 컨테이너를 시작하거나 네트워크 디바이스가 없는 컨테이너를 시작하는 데 사용됩니다.
    • [참고] NETWORK ID는 다를 수 있습니다.
    NETWORK ID     NAME      DRIVER    SCOPE
    73d8ecc937bd   bridge    bridge    local
    bf0b858cf267   host      host      local
    c0ef89f4261f   none      null      local

2. 컨테이너 생성 및 시작

bash가 아닌 Alpine의 기본 셸인 ash를 실행하는 두 개의 alpine 컨테이너를 시작합니다.

  • dit 플래그는 컨테이너를 분리된(detached) 상태로(즉, 백그라운드 실행), 입력할 수 있는 기능을 포함한 대화형(interactive)으로, 입력과 출력을 볼 수 있는 TTY로 시작하라는 의미입니다.
  • 분리된 상태(detached)로 시작하기 때문에 컨테이너에 바로 연결되지 않습니다. 대신 컨테이너의 ID가 프린트됩니다. network 플래그를 지정하지 않았기 때문에 컨테이너는 기본 브리지 네트워크에 연결됩니다.
$ docker run -dit --name alpine1 alpine ash
$ docker run -dit --name alpine2 alpine ash

3. 실행중인 컨테이너 확인

  • 컨테이너 확인 명령어

    $ docker container ls
  • 다음과 같은 결과가 출력됩니다.

    CONTAINER ID   IMAGE     COMMAND   CREATED          STATUS          PORTS     NAMES
    91f6824a436c   alpine    "ash"     32 seconds ago   Up 31 seconds             alpine2
    4e7af4a95724   alpine    "ash"     39 seconds ago   Up 38 seconds             alpine1

4. 네트워크에 연결된 컨테이너

  • 명령어 입력

    $ docker network inspect bridge
  • 결과
    - 맨 위에는 Docker 호스트와 브리지 네트워크 사이의 게이트웨이의 IP 주소(172.17.0.1)를 포함한 브리지 네트워크에 대한 정보가 나열됩니다.
    - 컨테이너 키 아래에는 연결된 각 컨테이너가 IP 주소에 대한 정보와 함께 나열됩니다(알파인1의 경우 172.17.0.2, 알파인2의 경우 172.17.0.3).

    [
     {
         "Name": "bridge",
         "Id": "73d8ecc937bd334b444030e26c9f0e2403ea78fa6461165a220149dfdd7b7636",
         "Created": "2023-04-06T11:46:10.8301395Z",
         "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": {
             "4e7af4a957245e77ada3fbbab8cdd19e52d7f7accb2dfbc74debc3b806fc26d1": {	# 컨테이너 키
                 "Name": "alpine1",
                 "EndpointID": "69e4c8e0fd795cf92410fb7d64e82736b59c32866cc0c9ab91774b7c1f9317ce",
                 "MacAddress": "02:42:ac:11:00:02",
                 "IPv4Address": "172.17.0.2/16",
                 "IPv6Address": ""
             },
             "91f6824a436c5444f163cb837eec3c4a05e4a487950e87a883531100f10d6b9c": {	# 컨테이너 키
                 "Name": "alpine2",
                 "EndpointID": "93fe66a1e069339a14122ed8fdb008cacfb6f1aa69d24a2f27bcad638c5b6aa0",
                 "MacAddress": "02:42:ac:11:00:03",
                 "IPv4Address": "172.17.0.3/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": {}
     }
    ]

5. 컨테이너 접속 후 네트워킹

백그라운드에서 실행되고 있는 컨테이너들을 alpine1에 연결하기 위해 alpine1 컨테이너에 접속해 보겠습니다.

  • alpine1 컨테이너에 접속하기 위한 명령어 입력

    $ docker attach alpine1
  • 결과

    • 프롬프트가 #으로 변경되며 컨테이너 내에서 root 사용자임을 나타냅니다.

      / #

5-1. 컨테이너간 연결

  • ip addr show 명령어 사용

    • 컨테이너 내부에서 보이는 alpine1의 네트워크 인터페이스를 표시
    # ip addr show
  • 결과

    • 첫 번째 인터페이스는 루프백 장치입니다.

    • 두 번째 인터페이스의 IP 주소는 172.17.0.2이며, 이전 단계의 alpine1에 표시된 IP주소와 동일합니다.

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
        link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
        inet 127.0.0.1/8 scope host lo
           valid_lft forever preferred_lft forever
    2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
        link/ipip 0.0.0.0 brd 0.0.0.0
    3: ip6tnl0@NONE: <NOARP> mtu 1452 qdisc noop state DOWN qlen 1000
        link/tunnel6 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00 brd 00:00:00:00:00:00:00:00:00:00:00:00:00:00:00:00
    23: eth0@if24: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1500 qdisc noqueue state UP
        link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff
        inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
           valid_lft forever preferred_lft forever

5-2. 인터넷 연결 확인

  • alpine1에서 `google.com을 핑하여 인터넷에 연결할 수 있는지 확인
  1. 첫번째 컨테이너

    • 명령어 입력
      • -c 2 플래그를 사용하면 명령이 두 번의 ping 시도로 제한됩니다.
    # ping -c 2 google.com
    • 결과
    PING google.com (172.217.25.174): 56 data bytes
    
    --- google.com ping statistics ---
    2 packets transmitted, 0 packets received, 100% packet loss
  2. 두번째 컨테이너

    • 명령어 입력
      • 컨테이너의 IP 주소인 172.17.0.3로 ping
    # ping -c 2 172.17.0.3
    • 결과
    PING 172.17.0.3 (172.17.0.3): 56 data bytes
    64 bytes from 172.17.0.3: seq=0 ttl=64 time=2.004 ms
    64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.290 ms
    
    --- 172.17.0.3 ping statistics ---
    2 packets transmitted, 2 packets received, 0% packet loss
    round-trip min/avg/max = 0.290/1.147/2.004 ms

6. 컨테이너 접속 종료

분리 시퀀스인 CTRL + p + q를 사용하여 alpine1을 중지하지 않고 분리합니다.

7. 컨테이너 중지 후 제거

$ docker container stop alpine1 alpine2
$ docker container rm alpine1 alpine2

0개의 댓글