Docker Network

김상훈·2024년 6월 23일

Docker

목록 보기
4/4

도커 네트워크란

Docker 컨테이너 간의 통신을 관리하고 격리하기 위한 기능을 제공하는 것

  • 컨테이너화된 애플리케이션은 여러개의 컨테이너로 구성될 수 있는데, 이들 컨테이너가 서로 통신하고 데이터를 주고 받아야 할 경우가 있음
  • 이러한 컨테이너간 통신을 쉽게 설정하고 관리할 수 있도록 도와줌

같은 호스트 내에서 실행중인 컨테이너 간 연결할 수 있도록 돕는 논리적 네트워크 개념

모니터링 시스템을 구축할 때 사용했던 docker-compose.yml

networks:
  elk:
    driver: bridge

services:

  elasticsearch:
    container_name: elasticsearch

    #elasticsearch는 8버전부터 보안설정이 달라짐
    image: elasticsearch:7.17.16
    ports:
      - 9200:9200
      - 9300:9300

    #현재 위치에서 elasticsearch 디렉터리 볼륨마운트
    volumes:
      - ./elk/elasticsearch:/usr/share/elasticsearch/data
    environment:
      discovery.type: single-node

      #시큐리티 on
      xpack.security.enabled: true

      #ssl on
      xpack.security.transport.ssl.enabled: true

      #FE서버 CORS 허용
      http.cors.allow-origin: "*"
      http.cors.enabled: true
      http.cors.allow-credentials: true
      http.cors.allow-methods: OPTIONS, HEAD, GET, POST, PUT, DELETE
      http.cors.allow-headers: X-Requested-With, X-Auth-Token, Content-Type, Content-Length, Authorization, Access-Control-Allow-Headers, Accept, x-elastic-client-meta
      
      #username은 변경 불가
      #password는 5자 이상
      ELASTIC_USERNAME: "elastic"
      ELASTIC_PASSWORD: "elastic123!@#"
    networks:
      - elk
    restart: unless-stopped

  logstash:
    container_name: logstash
    image: docker.elastic.co/logstash/logstash:7.17.16
    ports:
      - 5000:5000
      - 9600:9600
    volumes:
      - ./elk/logstash/pipeline/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
    depends_on:
      - elasticsearch
      - kafka
    networks:
      - elk
    restart: unless-stopped

  kibana:
    container_name: kibana
    image: kibana:7.17.16
    ports:
      - 5601:5601
    depends_on:
      - elasticsearch
    volumes:
      - ./elk/kibana/config/kibana.yml:/usr/share/kibana/config/kibana.yml
    networks:
      - elk
    restart: unless-stopped

  zookeeper:
    container_name: zookeeper
    image: wurstmeister/zookeeper
    ports:
      - 2181:2181
    networks:
      - elk
    restart: unless-stopped

  kafka:
    container_name: kafka
    image: wurstmeister/kafka
    environment:
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181

      #도커 네트워크 내부에선 컨테이너들이 kafka:29092로 접근
      #외부 애플리케이션(스프링부트)에선 localhost:9092로 접근
      KAFKA_LISTENERS: PLAINTEXT://:29092,PLAINTEXT_HOST://:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,PLAINTEXT_HOST://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,PLAINTEXT_HOST:PLAINTEXT
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT

      KAFKA_ADVERTISED_PORT: 9092

      #카프카 토픽 레플리카 갯수
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1

      #카프카 토픽이름/파티션 수/레플리카 수
      KAFKA_CREATE_TOPICS: "kafka-elk:1:1"
    ports:
      - 9092:9092
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    depends_on:
      - zookeeper
    networks:
      - elk
    restart: unless-stopped

  client:
    container_name: client
    build:
      context: "./client"
      dockerfile: Dockerfile 
    ports: 
      - "3000:3000"

    #도커 네트워크 설정 필수
    networks:
      - elk
    restart: unless-stopped

  server:
    container_name: server
    build:
      context: "./server"
      dockerfile: Dockerfile
    depends_on:
      - kafka
    ports:
      - "9100:9100"
    environment:
      - TZ=Asia/Seoul

    #도커 네트워크 설정 필수
    networks:
      - elk
    restart: unless-stopped

elasticsearch, logstash, kibana, kafka, react, springboot 컨테이너는 모두 networks라는 항목을 통해 elk라는 네트워크로 묶여 있dma

  • 여러 컨테이너로 구성된 애플리케이션은 같은 네트워크 내에서 통신하여 데이터를 주고받을 수 있음

도커 네트워크 구조

호스트에서 컨테이너가 생성되는 경우 결국 해당 컨테이너도 어플리케이션이기 때문에 IP 및 포트 등 네트워크을 구성하며, 이에 대한 정보가 할당되어야 함

  • 기본적으로 도커를 호스트 OS 에 설치하면 여러가지 네트워크 드라이버(Network Driver)들이 설치되며, 구동되는 컨테이너에 IP 주소를 순차적으로 할당하고 해당 컨테이너는 네트워크를 구성할 때 원하는 네트워크 드라이버를 선택할 수 있음

네트워크 인터페이스 계층

네트워크 인터페이스(Network Interface)란 컴퓨터나 장치가 네트워크와 상호작용하기 위한 연결점이며, 데이터를 주고받을 수 있는 하드웨어 또는 소프트웨어 구성 요소

네트워크 인터페이스는 컴퓨터와 네트워크 간의 통신을 가능하게 하며, 데이터 전송과 수신을 처리함

네트워크 계층을 통해 컴퓨터와 외부 네트워크의 물리적인 연결이 이루어짐

  1. 컴퓨터로부터 나오는 디지털 데이터를 전기 신호나 전파같은 물리적 신호로 변환하여 네트워크로 변환시킴
  2. 네트워크로부터 받은 물리적 신호를 컴퓨터에서 처리할 수 있는 디지털 데이터로 변환함

OSI 7계층과 TCP/IP 계층

  • 네트워크 인터페이스 계층
    • TCP/IP 모델 최하층에 위치
    • 인접한 네트워크 기기 간에(전송 매체로 연결되어) 전기신호나 전파같은 물리적 신호가 도달하는 범위에서 데이터를 전송하는 역할을 함
    • 네트워크 인터페이스 계층이 직접 연결된 네트워크용 하드웨어 기기 간에 데이터 전송을 제어함으로써 상위 계층은 하드웨어의 종류에 상관없이 통신할 수 있게 됨

veth (Virtual Ethernet Interface)

실제 컴퓨터의 랜카드(NIC)를 통해 랜포트를 열어서 랜 케이블에 연결하는 것이 아닌, 가상의 네트워크 인터페이스를 생성하는 것

  • 컨테이너로 구동된 애플리케이션은 일반적인 컴퓨터 애플리케이션 처럼 물리적인 네트워크 인터페이스를 사용할 수 없음

veth는 일반적인 네트워크 인터페이스와는 달리 패킷을 전달받으면, 자신에게 연결된 다른 네트워크 인터페이스로 패킷을 보내주는 식으로 동작하기 때문에 항상 쌍으로 생성해줘야 함.

한 쪽에서 다른 쪽으로 패킷을 전송할 수 있으며, 한 쪽에 다운된 경우 나머지 한 쪽도 정상적으로 기능하지 않는 것이 특징

  • 도커에서는 실행중인 컨테이너 수 만큼 veth로 시작하는 인터페이스가 생성됨

도커 네트워크 구조

도커 컨테이너도 결국 네트워크를 구성함 → 컨테이너마다의 IP 와 포트가 존재

  • 도커는 호스트로부터 실행되는 컨테이너에 172.17.0.x 의 IP 을 순차적으로 할당

[명령어 예시]

docker container run -it ubuntu:latest

  • ubuntu OS 에서 apt-get update을 통해 ubuntu OS에서 사용 가능한 패키지들과 그 버전에 맞는 정보를 업데이트
  • apt-get install net-tools 을 통해 네트워크 관련 도구를 설치
  • 해당 과정을 꼭 진행시켜야 ubuntu OS에서 네트워크와 관련된 기능을 사용할 수 있음

해당 도커 컨테이너에 아무런 설정을 하지 않는다면 외부에서 접근할 수 없으며

오로지 해당 도커 컨테이너를 구동시킨 호스트에서만 접근 가능함

외부 네트워크에 컨테이너 어플리케이션을 노출하기 위해서는 eth0의 IP/PORT를 호스트의 IP/PORT에 바인딩시켜야함

  • 외부와의 네트워크 연결은 컨테이너마다 eth0에 대응되는 veth라는 가상 네트워크 인터페이스를 호스트에 생성함으로써 이루어짐
  • 각각의 IP 주소와 포트를 입력해 컨테이너를 외부에 노출 시킬 수 있음
  • veth는 도커 호스트에서 ifconfig 명령어를 입력하면 확인 가능함
  • eth0에 대응되는 vethXXXX이라는 이름의 veth interface와 브릿지 네트워크에 컨테이너의 interface가 바인딩되는 형태로 통신함
  • veth 인터페이스는 사용자가 직접 생성할 필요는 없고 컨테이너가 생성될 때 도커 엔진이 자동으로 생성함
  • 도커 컨테이너가 실행될 때 네트워크 드라이버를 따로 지정하지 않으면 docker0라고 하는 브릿지 네트워크를 default로 사용함
    • 브릿지 네트워크: veth와 호스트의 eth0의 다리 역할

도커 네트워크 종류와 개념

  • 도커 네트워크 드라이버는 Native와 Remote로 나뉨
    • Native DriversBridge,Host,None,Overlay를 사용
    • Remote Drivers: 3rd party 드라이버로 외부에서 잘 만들어진 드라이버를 사용

  • 도커 네트워크 드라이버는 단일 호스트, 다중 호스트로 분류할 수 있음
    • 단일 호스트 네트워크 드라이버Bridge, Host, None
    • 다중 호스트 네트워크 드라이버Overlay

Bridge 네트워크

  • 포트를 연결해 컨테이너 애플리케이션의 Port 를 외부에 노출하는 방식
  • 아무런 네트워크 드라이버를 지정하지 않으면 default 로 docker0이라는 bridge 네트워크를 사용
  • 커스텀 bridge 네트워크 또한 생성가능 docker network create --driver=bridge my-bridge

Host 네트워크

  • 도커가 제공해주는 가상 네트워크 인터페이스(veth) 을 사용하는 것이 아님
  • 이름 그대로 host 의 네트워크에 붙어서 사용하는 개념
  • bridge 네트워크처럼 포트 바인딩을 할 필요가 없으며 호스트 네트워크에 접속하면 컨테이너 또한 접속 가능

None 네트워크

  • 해당 컨테이너가 네트워크 기능이 필요 없을 때, 혹은 커스텀 네트워크를 사용
  • 외부 네트워크와의 연결이 단절됨 docker container run -d --network=none nginx:latest

0개의 댓글