도커 네트워크란
Docker 컨테이너 간의 통신을 관리하고 격리하기 위한 기능을 제공하는 것
- 컨테이너화된 애플리케이션은 여러개의 컨테이너로 구성될 수 있는데, 이들 컨테이너가 서로 통신하고 데이터를 주고 받아야 할 경우가 있음
- 이러한 컨테이너간 통신을 쉽게 설정하고 관리할 수 있도록 도와줌
같은 호스트 내에서 실행중인 컨테이너 간 연결할 수 있도록 돕는 논리적 네트워크 개념
모니터링 시스템을 구축할 때 사용했던 docker-compose.yml
yamlnetworks: 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
elasticsearchlogstashkibanakafkareactspringbootnetworkselk- 여러 컨테이너로 구성된 애플리케이션은 같은 네트워크 내에서 통신하여 데이터를 주고받을 수 있음
도커 네트워크 구조
호스트에서 컨테이너가 생성되는 경우 결국 해당 컨테이너도 어플리케이션이기 때문에 IP 및 포트 등 네트워크을 구성하며, 이에 대한 정보가 할당되어야 함
- 기본적으로 도커를 호스트 OS 에 설치하면 여러가지 **네트워크 드라이버(Network Driver)**들이 설치되며, 구동되는 컨테이너에 IP 주소를 순차적으로 할당하고 해당 컨테이너는 네트워크를 구성할 때 원하는 네트워크 드라이버를 선택할 수 있음
네트워크 인터페이스 계층

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

네트워크 계층을 통해 컴퓨터와 외부 네트워크의 물리적인 연결이 이루어짐
- 컴퓨터로부터 나오는 디지털 데이터를 전기 신호나 전파같은 물리적 신호로 변환하여 네트워크로 변환시킴
- 네트워크로부터 받은 물리적 신호를 컴퓨터에서 처리할 수 있는 디지털 데이터로 변환함
OSI 7계층과 TCP/IP 계층

- 네트워크 인터페이스 계층
- TCP/IP 모델 최하층에 위치
- 인접한 네트워크 기기 간에(전송 매체로 연결되어) 전기신호나 전파같은 물리적 신호가 도달하는 범위에서 데이터를 전송하는 역할을 함
- 네트워크 인터페이스 계층이 직접 연결된 네트워크용 하드웨어 기기 간에 데이터 전송을 제어함으로써 상위 계층은 하드웨어의 종류에 상관없이 통신할 수 있게 됨
veth (Virtual Ethernet Interface)
실제 컴퓨터의 **랜카드(NIC)**를 통해 랜포트를 열어서 랜 케이블에 연결하는 것이 아닌, 가상의 네트워크 인터페이스를 생성하는 것
- 컨테이너로 구동된 애플리케이션은 일반적인 컴퓨터 애플리케이션 처럼 물리적인 네트워크 인터페이스를 사용할 수 없음
veth는 일반적인 네트워크 인터페이스와는 달리 패킷을 전달받으면, 자신에게 연결된 다른 네트워크 인터페이스로 패킷을 보내주는 식으로 동작하기 때문에 항상 쌍으로 생성해줘야 함.
한 쪽에서 다른 쪽으로 패킷을 전송할 수 있으며, 한 쪽에 다운된 경우 나머지 한 쪽도 정상적으로 기능하지 않는 것이 특징
- 도커에서는 실행중인 컨테이너 수 만큼 veth로 시작하는 인터페이스가 생성됨
도커 네트워크 구조
도커 컨테이너도 결국 네트워크를 구성함 → 컨테이너마다의 IP 와 포트가 존재
- 도커는 호스트로부터 실행되는 컨테이너에 의 IP 을 순차적으로 할당javascript
172.17.0.x
[명령어 예시]
docker container run -it ubuntu:latest- ubuntu OS 에서 을 통해 ubuntu OS에서 사용 가능한 패키지들과 그 버전에 맞는 정보를 업데이트javascript
apt-get update - 을 통해 네트워크 관련 도구를 설치javascript
apt-get install net-tools - 해당 과정을 꼭 진행시켜야 ubuntu OS에서 네트워크와 관련된 기능을 사용할 수 있음
해당 도커 컨테이너에 아무런 설정을 하지 않는다면 외부에서 접근할 수 없으며
오로지 해당 도커 컨테이너를 구동시킨 호스트에서만 접근 가능함

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

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

- 도커 네트워크 드라이버는 단일 호스트, 다중 호스트로 분류할 수 있음
- 단일 호스트 네트워크 드라이버: Bridge, Host, None
- 다중 호스트 네트워크 드라이버: Overlay
Bridge 네트워크
-
포트를 연결해 컨테이너 애플리케이션의 Port 를 외부에 노출하는 방식
-
아무런 네트워크 드라이버를 지정하지 않으면 default 로 docker0이라는 bridge 네트워크를 사용
-
커스텀 bridge 네트워크 또한 생성가능
javascriptdocker network create --driver=bridge my-bridge
Host 네트워크
- 도커가 제공해주는 가상 네트워크 인터페이스(veth) 을 사용하는 것이 아님
- 이름 그대로 host 의 네트워크에 붙어서 사용하는 개념
- bridge 네트워크처럼 포트 바인딩을 할 필요가 없으며 호스트 네트워크에 접속하면 컨테이너 또한 접속 가능
None 네트워크
-
해당 컨테이너가 네트워크 기능이 필요 없을 때, 혹은 커스텀 네트워크를 사용
-
외부 네트워크와의 연결이 단절됨
javascriptdocker container run -d --network=none nginx:latest