CMES

CMES: 컨테이너 & 인프라스터디 3회

taltal 2025. 6. 22. 22:02
728x90
반응형

실습 주제

Docker Compose 및 네트워크 구조 이해

목표

  • Docker Compose를 이용하여 여러 컨테이너로 이루어진 로컬 서비스를 구성하는 방법 습득
  • Docker의 볼륨과 네트워크를 활용하여 컨테이너 간 데이터 공유 및 통신 방식 이해

1. Docker Compose 로컬 서비스 구성

실습 내용

  • 간단한 웹 애플리케이션과 데이터베이스(MySQL)를 연결하여 Docker Compose로 서비스 구성

과제

1. Docker Compose의 정의와 필요성, 구성 요소에 대해 간단히 정리해보세요.

더보기

Docker Compose란?

Docker Compose는 여러 개의 Docker 컨테이너로 이루어진 애플리케이션을 정의하고 실행하기 위한 도구입니다. YAML 파일을 사용하여 애플리케이션의 서비스, 네트워크, 볼륨 등을 한 번에 설정하고 관리할 수 있도록 해줍니다. 즉, 복잡한 다중 컨테이너 애플리케이션을 단일 명령어로 손쉽게 빌드하고 실행할 수 있게 돕는 오케스트레이션 도구의 일종입니다.

Docker Compose의 필요성

단일 컨테이너 애플리케이션이 아닌 실제 서비스 환경에서는 데이터베이스, 웹 서버, 캐시 서버 등 여러 개의 컨테이너가 서로 연동되어 작동하는 경우가 많습니다. 이때 각 컨테이너를 개별적으로 관리하는 것은 다음과 같은 문제점을 야기합니다.

  • 복잡성 증가: 각 컨테이너의 의존성, 네트워크 설정, 환경 변수 등을 수동으로 관리해야 하므로 설정이 복잡해지고 오류 발생 가능성이 높아집니다.
  • 재현성 저하: 개발 환경과 운영 환경 간의 컨테이너 설정 차이로 인해 배포 시 문제가 발생할 수 있습니다.
  • 관리의 어려움: 여러 컨테이너를 동시에 시작, 중지, 재시작하는 작업이 번거롭습니다.

Docker Compose는 이러한 문제점들을 해결하여 다음과 같은 이점을 제공합니다.

  • 간편한 정의: YAML 파일 하나로 전체 애플리케이션 스택을 정의하여 가독성을 높이고 관리의 편의성을 제공합니다.
  • 쉬운 배포 및 확장: docker compose up 명령 하나로 정의된 모든 서비스를 한 번에 배포하고 필요에 따라 스케일링할 수 있습니다.
  • 일관된 환경: 개발, 테스트, 운영 환경 모두에서 동일한 설정 파일을 사용하여 일관된 환경을 보장하고 재현성을 높입니다.
  • 버전 관리 용이: YAML 파일 자체를 버전 관리 시스템(Git 등)으로 관리하여 변경 이력을 추적하고 협업을 용이하게 합니다.

Docker Compose의 주요 구성 요소

Docker Compose의 YAML 파일(일반적으로 docker-compose.yml)은 주로 다음과 같은 섹션으로 구성됩니다.

  1. version:
    • Docker Compose 파일 포맷의 버전을 명시합니다. 버전에 따라 지원하는 기능과 문법이 다를 수 있습니다. (예: version: '3.8')
  2. services:
    • 애플리케이션을 구성하는 각각의 컨테이너 서비스들을 정의하는 핵심 섹션입니다. 각 서비스는 독립적인 컨테이너로 실행됩니다.
    • 각 서비스 내부에는 다음과 같은 주요 설정들이 포함될 수 있습니다.
      • image: 컨테이너를 생성할 Docker 이미지 (예: nginx, mysql:8.0)
      • build: Dockerfile이 있는 경로를 지정하여 이미지를 직접 빌드 (예: build: ./web)
      • ports: 호스트와 컨테이너 간의 포트 매핑 (예: "80:80")
      • environment: 컨테이너 내에서 사용할 환경 변수 설정
      • volumes: 호스트와 컨테이너 간의 볼륨 마운트 (데이터 지속성 유지)
      • depends_on: 서비스 간의 의존성 정의 (예: 웹 서버가 데이터베이스보다 먼저 시작되어야 함)
      • networks: 서비스가 속할 네트워크 지정
      • command: 컨테이너 시작 시 실행할 명령어 재정의
      • restart: 컨테이너 종료 시 재시작 정책 (예: always, on-failure)
  3. networks:
    • 컨테이너들이 통신할 수 있는 가상 네트워크를 정의합니다. Compose는 기본적으로 브릿지 네트워크를 생성하지만, 필요에 따라 사용자 정의 네트워크를 생성할 수 있습니다.
    • 서비스 간의 격리 또는 특정 네트워크 설정이 필요할 때 사용됩니다.
  4. volumes:
    • 컨테이너의 데이터를 호스트 머신에 저장하여 컨테이너가 삭제되더라도 데이터가 보존되도록 하는 볼륨을 정의합니다.
    • 명명된 볼륨(named volumes) 또는 바인드 마운트(bind mounts)를 사용하여 데이터를 관리합니다.

 

 

2. Docker Compose를 이용하여 웹 서버와 데이터 베이스를 동시에 띄워보세요.

  1. 웹 서버 이미지 : nginx:latest
  2. 데이터베이스 이미지 : mysql:8.0
  3. 주의 사항
    1. Depend_on 옵션을 통해 mysql이 먼저 실행되어야 합니다.
    2. 각 컨테이너가 서로 통신 할 수 있게 networks 옵션을 설정해주세요.
  4. 결과 제출
    • 브라우저에 접속하여 Nginx 웹서버가 잘 실행되는지 확인하기
    • DB 컨테이너 내부에서 MySQL 데이터 베이스 확인하기
    • [docker network ls] 명령을 통해 생성된 네트워크를 확인해 봅니다.
    • Nginx 컨테이너에서 mysql 컨테이너로 ping 응답을 날려 확인해봅니다.
    • 컨테이너 내부에서 작성한 파일을 확인해봅니다.
    • 컨테이너에서 빠져나와서 작성된 파일을 확인해봅니다.

 

 

 

 

nginx 서버 컨테이너 내부에서 index.html 파일 다음과 같이 수정

컨테이너 내부에서 파일을 수정한 것이 마운트 되어 있는 호스트의 파일에도 반영되어 있다.

 

* 로그 파일 용량, 갯수 설정 예시 및 결과

더보기
# docker-compose.yml 파일
version: '3.8'

services:
  nginx:
    image: nginx:latest
    ports:
      - "80:80"
    networks:
      - app_network
    depends_on:
      - mysql
    volumes:
      - ./nginx-html:/usr/share/nginx/html # Nginx 웹 서버에 사용할 HTML 파일 볼륨 마운트
    container_name: my-nginx-web
    logging: # Nginx 서비스에 대한 로깅 설정 추가
      driver: "json-file"
      options:
        max-size: "10m" # 각 로그 파일의 최대 크기를 10MB로 제한
        max-file: "3" # 최대 3개의 로그 파일 유지

 

 

 

2. Docker Network 개념 및 실습

실습 내용

  • Docker 네트워크 유형 이해(bridge, host, none)
  • Docker Compose를 통해 커스텀 네트워크를 생성하고 컨테이너 간의 통신 방법 실습

과제

  1. Docker의 기본 네트워크 유형(bridge, host, none)의 특징과 차이점을 간략히 정리하세요. 
  2. 더보기

    1. Bridge 네트워크 (기본값)

    • 특징:
      • Docker를 설치하면 자동으로 docker0이라는 가상 브릿지(Bridge) 네트워크 인터페이스가 생성됩니다.
      • 새로운 컨테이너를 명시적으로 네트워크를 지정하지 않고 실행하면 기본적으로 이 bridge 네트워크에 연결됩니다.
      • 각 컨테이너는 브릿지에 연결된 자체적인 IP 주소를 할당받습니다.
      • 컨테이너 간 통신은 브릿지를 통해 이루어지며, 서로의 IP 주소 또는 서비스 이름(Docker Compose 사용 시)으로 통신할 수 있습니다.
      • 호스트 머신과 컨테이너 간의 통신을 위해 포트 포워딩(Port Forwarding)이 필요합니다 (예: -p 80:80).
      • **네트워크 격리(Isolation)**가 제공됩니다. 즉, 컨테이너는 서로의 네트워크를 직접적으로 볼 수 없으며, 호스트 네트워크와도 분리됩니다.
    • 차이점:
      • 가장 일반적이고 권장되는 네트워크 유형입니다.
      • 기본적인 네트워크 격리를 제공하여 보안성과 유연성을 높입니다.
      • 포트 매핑을 통해 외부에서 컨테이너 서비스에 접근할 수 있습니다.

    2. Host 네트워크

    • 특징:
      • 컨테이너가 호스트 머신의 네트워크 스택을 직접 공유합니다. 즉, 컨테이너는 별도의 네트워크 인터페이스나 IP 주소를 할당받지 않고, 호스트의 IP 주소와 네트워크 설정을 그대로 사용합니다.
      • 컨테이너 내부의 포트가 호스트의 동일한 포트에 직접 바인딩됩니다. 따라서 포트 포워딩(-p 옵션)이 필요 없습니다.
      • 네트워크 성능 측면에서 브릿지 네트워크보다 약간 더 빠를 수 있습니다.
    • 차이점:
      • 네트워크 격리가 없습니다. 컨테이너는 호스트의 모든 네트워크 인터페이스와 포트에 접근할 수 있습니다. 이는 보안상의 위험을 초래할 수 있습니다.
      • 여러 컨테이너가 동일한 포트를 사용하려고 할 때 충돌이 발생할 수 있습니다 (호스트에서 이미 사용 중이거나 다른 컨테이너가 사용 중인 경우).
      • 특별한 성능 요구 사항이나 호스트 네트워크와의 긴밀한 통합이 필요한 경우에 주로 사용됩니다.

    3. None 네트워크

    • 특징:
      • 컨테이너가 어떤 네트워크 인터페이스도 갖지 않습니다. 즉, 컨테이너는 외부 네트워크와 완전히 단절됩니다.
      • localhost 주소만 사용할 수 있으며, 다른 컨테이너나 호스트 머신, 외부 인터넷과 통신할 수 없습니다.
    • 차이점:
      • 가장 강력한 네트워크 격리를 제공합니다.
      • 네트워크 통신이 전혀 필요 없는 경우 (예: 단순히 파일을 처리하고 종료되는 배치 작업)에 사용되거나, 사용자 정의 네트워크 스택을 컨테이너 내부에 직접 구성해야 하는 특수한 경우에 사용됩니다.
      • 일반적인 애플리케이션 서비스에는 적합하지 않습니다.

    요약 비교표

    특징Bridge 네트워크 (기본)Host 네트워크None 네트워크
    IP 주소 자체 IP 주소 할당 호스트의 IP 주소 공유 IP 주소 없음 (localhost만)
    격리 수준 높음 (네트워크 격리 제공) 낮음 (네트워크 격리 없음) 가장 높음 (완전 단절)
    포트 매핑 필요 (-p 옵션) 필요 없음 해당 없음
    통신 방식 가상 브릿지를 통해 컨테이너 간, 포트 매핑으로 외부 통신 호스트 네트워크 스택 직접 사용 외부 통신 불가
    사용 사례 대부분의 애플리케이션, 다중 컨테이너 애플리케이션 높은 네트워크 성능 요구, 호스트와 긴밀한 통합 네트워크 통신 불필요한 배치 작업, 특수 목적

    대부분의 Docker 애플리케이션은 Bridge 네트워크를 사용하며, Docker Compose를 사용하면 서비스 간의 이름 기반 통신을 지원하는 사용자 정의 Bridge 네트워크를 자동으로 생성하여 관리 편의성을 높입니다.

  3. Docker Network 주요 개념에 대해 간단하게 정리해보세요.
    더보기

    Docker Network 주요 개념 정리

    Docker Network는 컨테이너들이 서로 통신하고, 호스트 머신 및 외부 네트워크와 상호 작용하는 방식을 관리하는 Docker의 핵심 기능입니다. 이는 컨테이너 기반 애플리케이션의 유연성과 확장성을 보장하는 데 필수적입니다.

    1. 네트워크 드라이버 (Network Driver)

    Docker는 다양한 네트워크 환경을 지원하기 위해 여러 가지 네트워크 드라이버를 제공합니다. 각 드라이버는 컨테이너에 대한 네트워킹을 구현하는 방식을 정의합니다. 주요 드라이버는 다음과 같습니다:

    • Bridge (브릿지):
      • Docker의 기본 네트워크 드라이버입니다.
      • 컨테이너들이 호스트 머신의 docker0 브릿지를 통해 서로 통신할 수 있도록 합니다.
      • 각 컨테이너는 브릿지 네트워크 내에서 고유한 IP 주소를 할당받습니다.
      • 컨테이너와 외부 네트워크 간의 통신을 위해서는 포트 매핑(Port Mapping)이 필요합니다 (예: -p 80:80).
      • 컨테이너 간의 기본적인 네트워크 격리를 제공합니다.
      • 사용자 정의 브릿지 네트워크를 생성하여 컨테이너 그룹을 격리하고 서비스 이름으로 통신할 수 있게 하는 것이 일반적입니다 (Docker Compose의 기본 동작).
    • Host (호스트):
      • 컨테이너가 호스트 머신의 네트워크 스택을 직접 공유합니다.
      • 컨테이너는 자체적인 네트워크 인터페이스나 IP 주소를 갖지 않으며, 호스트의 IP 주소와 포트를 그대로 사용합니다.
      • 네트워크 성능은 가장 빠를 수 있지만, 네트워크 격리가 전혀 없습니다.
      • 포트 충돌 위험이 있고, 보안에 취약할 수 있습니다.
    • None (없음):
      • 컨테이너가 어떤 네트워크 인터페이스도 갖지 않으며, 외부와 완전히 단절됩니다.
      • localhost 외에는 통신할 수 없습니다.
      • 네트워크 통신이 전혀 필요 없는 특정 작업(예: 데이터를 처리하고 종료되는 배치 스크립트)이나 사용자 정의 네트워크 스택을 직접 구성할 때 사용됩니다.
    • Overlay (오버레이):
      • **다중 Docker 호스트(클러스터 환경, Docker Swarm)**에 걸쳐 컨테이너들이 서로 통신할 수 있도록 하는 네트워크 드라이버입니다.
      • 여러 호스트에 분산된 컨테이너들을 하나의 논리적인 네트워크에 연결하여 마치 동일한 호스트에 있는 것처럼 통신하게 합니다.
      • 서비스 디스커버리 및 로드 밸런싱 기능을 내장하고 있습니다.
    • Macvlan (맥블랜):
      • 컨테이너에 자체적인 MAC 주소와 IP 주소를 부여하여 물리 네트워크의 장치처럼 보이게 합니다.
      • 컨테이너가 물리 네트워크에 직접 연결되는 것처럼 작동하며, VLAN 태그를 지원하여 네트워크 분할을 용이하게 합니다.
      • 기존 네트워크 인프라에 컨테이너를 직접 통합해야 할 때 유용합니다.

    2. 네트워크 스코프 (Network Scope)

    네트워크 드라이버는 그 사용 범위에 따라 스코프를 가집니다.

    • Local Scope (로컬 스코프): bridge, host, none, macvlan 드라이버가 여기에 해당합니다. 이 네트워크들은 단일 Docker 호스트 내에서만 유효합니다.
    • Swarm Scope (스웜 스코프): overlay 드라이버가 여기에 해당합니다. 이 네트워크들은 Docker Swarm 클러스터의 여러 호스트에 걸쳐 유효하며, 분산된 컨테이너 간의 통신을 가능하게 합니다.

    3. 네트워크 구성 요소

    • 네트워크 (Network): 컨테이너들이 연결될 수 있는 가상 네트워크 환경입니다. 컨테이너는 하나 이상의 네트워크에 연결될 수 있습니다.
    • 엔드포인트 (Endpoint): 컨테이너가 네트워크에 연결될 때 생성되는 인터페이스입니다. 각 엔드포인트는 네트워크 내에서 고유한 IP 주소를 가집니다.
    • IP 주소 할당 (IP Address Allocation): Docker는 네트워크에 연결된 컨테이너에 자동으로 IP 주소를 할당합니다. 사용자 정의 네트워크의 경우 서브넷을 지정하여 IP 주소 범위를 제어할 수 있습니다.
    • DNS 기반 서비스 디스커버리 (DNS-based Service Discovery): 특히 사용자 정의 브릿지 네트워크나 오버레이 네트워크에서는, 컨테이너들이 서로의 IP 주소를 몰라도 서비스 이름(컨테이너 이름 또는 서비스 정의 이름)을 통해 통신할 수 있도록 DNS 기반 서비스 디스커버리 기능을 제공합니다. 이는 복잡한 다중 컨테이너 애플리케이션에서 매우 유용합니다.
  4. Docker Network 주요 명령어들에 대해 정리해 봅니다.
    더보기

    Docker Network 주요 명령어 정리

    Docker 네트워크를 관리하는 데 사용되는 주요 명령어들은 docker network 서브커맨드 아래에 있습니다.

    1. 네트워크 목록 조회

    • docker network ls
      • 설명: 현재 Docker 호스트에 존재하는 모든 네트워크 목록을 보여줍니다. 기본 네트워크(bridge, host, none)와 사용자 정의 네트워크를 포함합니다.
      • 예시:
        Bash
         
        docker network ls
        
      • 출력 예시:
        NETWORK ID     NAME           DRIVER    SCOPE
        0391d8e12345   bridge         bridge    local
        ed1b2c3d4567   host           host      local
        0c9a8b7c6d5e   none           null      local
        a1b2c3d4e5f6   my_custom_net  bridge    local
        

    2. 네트워크 생성

    • docker network create [OPTIONS] NETWORK_NAME
      • 설명: 새로운 사용자 정의 네트워크를 생성합니다. 특정 드라이버(--driver)를 지정하거나, 서브넷(--subnet), 게이트웨이(--gateway) 등을 설정할 수 있습니다.
      • 주요 옵션:
        • --driver <DRIVER>: 사용할 네트워크 드라이버 지정 (예: bridge, overlay, macvlan). 기본값은 bridge입니다.
        • --subnet <CIDR>: 네트워크의 서브넷을 CIDR 표기법으로 지정합니다 (예: 172.18.0.0/16).
        • --gateway <IP_ADDRESS>: 네트워크의 게이트웨이 IP 주소를 지정합니다 (예: 172.18.0.1).
        • --attachable: 오버레이 네트워크에서 스웜 서비스가 아닌 독립 실행형 컨테이너도 연결할 수 있도록 합니다.
      • 예시:
        • 기본 브릿지 네트워크 생성:
          Bash
           
          docker network create my_new_bridge_network
          
        • 특정 서브넷을 가진 브릿지 네트워크 생성:
          Bash
           
          docker network create --driver bridge --subnet 172.20.0.0/16 --gateway 172.20.0.1 my_custom_subnet_network
          
        • 오버레이 네트워크 생성 (Swarm Mode 활성화 필요):
          Bash
           
          docker network create --driver overlay --attachable my_overlay_network
          

    3. 네트워크 정보 조회

    • docker network inspect [OPTIONS] NETWORK
      • 설명: 특정 네트워크의 상세 정보를 JSON 형식으로 출력합니다. 연결된 컨테이너, IP 주소, 게이트웨이 등 다양한 정보를 확인할 수 있습니다.
      • NETWORK: 네트워크 이름 또는 네트워크 ID.
      • 예시:
        Bash
         
        docker network inspect my_custom_net
        
      • 출력 예시 (일부):
        JSON
         
        [
            {
                "Name": "my_custom_net",
                "Id": "a1b2c3d4e5f6...",
                "Created": "2023-10-27T10:00:00.123456789Z",
                "Scope": "local",
                "Driver": "bridge",
                "EnableIPv6": false,
                "IPAM": {
                    "Driver": "default",
                    "Config": [
                        {
                            "Subnet": "172.18.0.0/16",
                            "Gateway": "172.18.0.1"
                        }
                    ],
                    "Options": null
                },
                "Containers": {
                    "abcdef123456...": {
                        "Name": "my-web-container",
                        "EndpointID": "0987654321ab...",
                        "MacAddress": "02:42:ac:12:00:02",
                        "IPv4Address": "172.18.0.2/16",
                        "IPv6Address": ""
                    }
                },
                "Options": {},
                "Labels": {}
            }
        ]
        

    4. 컨테이너를 네트워크에 연결/연결 해제

    • docker network connect [OPTIONS] NETWORK CONTAINER
      • 설명: 실행 중인 컨테이너를 특정 네트워크에 연결합니다. 컨테이너는 여러 네트워크에 동시에 연결될 수 있습니다.
      • NETWORK: 연결할 네트워크 이름 또는 ID.
      • CONTAINER: 연결할 컨테이너 이름 또는 ID.
      • 예시:
        Bash
         
        docker network connect my_custom_net my_running_container
        
    • docker network disconnect [OPTIONS] NETWORK CONTAINER
      • 설명: 실행 중인 컨테이너를 특정 네트워크에서 연결 해제합니다.
      • NETWORK: 연결 해제할 네트워크 이름 또는 ID.
      • CONTAINER: 연결 해제할 컨테이너 이름 또는 ID.
      • 예시:
        Bash
         
        docker network disconnect my_custom_net my_running_container
        

    5. 네트워크 삭제

    • docker network rm [OPTIONS] NETWORK [NETWORK...]
      • 설명: 하나 이상의 사용자 정의 네트워크를 삭제합니다. 네트워크에 연결된 컨테이너가 있으면 삭제할 수 없습니다.
      • NETWORK: 삭제할 네트워크 이름 또는 ID.
      • 예시:
        Bash
         
        docker network rm my_new_bridge_network
        
    • docker network prune [OPTIONS]
      • 설명: 사용되지 않는(어떤 컨테이너도 연결되어 있지 않은) 모든 네트워크를 삭제합니다. 공간 확보에 유용합니다.
      • 주요 옵션:
        • -f, --force: 확인 메시지 없이 강제로 삭제합니다.
      • 예시:
        Bash
         
        docker network prune
  5. 이전 실습에서 만든 nginx와 mysql 컨테이너를 띄우는 컴포즈 파일에 bridge 모드로 네트워크를 연결하는 옵션을 추가하고 새롭게 실행해봅니다.
    더보기
    # docker-compose.yml 파일
    version: '3.8'

    services:
      nginx:
        image: nginx:latest
        ports:
          - "80:80"
        networks:
          - app_network
        depends_on:
          - mysql
        volumes:
          - ./nginx-html:/usr/share/nginx/html # Nginx 웹 서버에 사용할 HTML 파일 볼륨 마운트
        container_name: my-nginx-web

      mysql:
        image: mysql:8.0
        environment:
          MYSQL_ROOT_PASSWORD: root_password # MySQL root 비밀번호 설정
          MYSQL_DATABASE: my_database # 생성할 데이터베이스 이름
          MYSQL_USER: my_user # 생성할 사용자 이름
          MYSQL_PASSWORD: my_password # 생성할 사용자 비밀번호
        networks:
          - app_network
        volumes:
          - mysql-data:/var/lib/mysql # MySQL 데이터 지속성을 위한 볼륨 마운트
        container_name: my-mysql-db

    networks:
      app_network:
        driver: bridge # 사용자 정의 브릿지 네트워크

    volumes:
      mysql-data: # MySQL 데이터 볼륨 정의

3. 볼륨(Volume) 실습

실습 내용

  • Docker 컨테이너와 실제 로컬 PC의 볼륨을 마운트해서 데이터 공유가 가능한 환경을 구축해봅시다.

과제

  1. /home/practice 경로를 컨테이너에 연동할 수 있도록 볼륨 마운트를 하는 compose 파일을 작성합니다.
    더보기
    # docker-compose.yml 파일
    version: '3.8'

    services:
      volume_test:
        image: nginx:latest
        volumes:
          - /home/practice:/usr/share/home/practice # Nginx 웹 서버에 사용할 HTML 파일 볼륨 마운트
        container_name: volume_test
  2. Compose 파일은 앞선 실습에서 사용했던 것 보다 간단하게 작성해도 좋습니다.
  3. 컨테이너 내부에 들어가서 마운트한 경로에 여러 파일을 만들어 봅니다.
  4. 컨테이너에서 빠져나와서 /home/practice 경로에 컨테이너 내부에서 만들었던 파일이 있는지 확인해봅니다.
  5. 결과 제출


컨테이너 내부에서 파일 생성

 

호스트의 /home/practice에 마운트되어 파일 생성된 것 확인

728x90
반응형