Home > Infrastructure > Docker > 도커(Docker)Dive - 멀티 컨테이너 관리

도커(Docker)Dive - 멀티 컨테이너 관리
Docker

클라우드 네이티브 애플리케이션 (Cloud Native Application)

  • 클라우드
    • 다른 회사의 서버를 빌려서 운영
      • 퍼블릭 클라우드: 누구나 사용할 수 있는 클라우드 서비스 (e.g. Azure, AWS, GCP)
      • 프라이빗 클라우드: 특정 조직만 사용할 수 있는 클라우드 서비스 (e.g. 조직 내 계열사)
        • 보안과 비용이 보다 효율적
    • 특징
      • 요청 즉시 서버를 생성 (Provisioning)
        • 스토리지 저장소에 가상화 기술을 활용
        • 사용자가 서버를 구매할 때마다 스펙에 맞는 VM을 만들어 제공
      • 사용 시간만 비용 지불 (직접 서버를 운영음 비용이 매우 큼)
    • 현대 애플리케이션의 다양한 문제를 해결
      • 확장성 (Scalability) : 트래픽 증가에 유연하고 빠르게 대처
      • 복원력 (Resilience) : 장애 발생 시 빠르게 복구
        • e.g. 서울 데이터 센터에 장애가 났을 때 부산 데이터 센터의 서버로 트래픽 전환 (Disaster Recovery, 복구에 사용하는 서버)
      • 효율적인 운영 비용 처리 : 전문 아키텍트의 적절한 서버 구성과 끊임없는 최적화 필요
    • -> 클라우드는 시작점이고 애플리케이션이 클라우드에 적합하지 않으면 큰 의미 없을 수 있음
  • 클라우드 네이티브 애플리케이션
    • 클라우드 환경을 더 잘 활용할 수 있는 애플리케이션 구조
    • 필요 사항
      • MSA: 트래픽 증가에 빠르게 대처하기 위해선 애플리케이션이 MSA 구조로 개발되어야 함
      • 컨테이너: 컨테이너를 활용해 실행 환경에 종속되지 않는 동작을 보장해야 함
      • 무상태 (Stateless): 상태를 가지지 않는 애플리케이션 서버는 어디에나 즉시 배포 가능
      • DevOpsCI/CD: 배포가 자동화되어야 하고 릴리즈가 빠르게 수행되어야 함
  • 모놀리식과 MSA
    msa
    • 잘 활용하면 클라우드 네이티브 애플리케이션으로서의 장점이 커서 MSA로 많이 전환하는 추세
    • 모놀리식
      • 모든 기능을 하나의 애플리케이션에 구성
      • 수직 확장(Scale-Up) 주로 사용
      • 장점
        • 초반 개발 속도가 빠르다가 코드 베이스가 커질수록 느려짐
        • 복잡성이 낮음
      • 단점
        • 트래픽 대처 능력 감소
          • 하나의 애플리케이션 크기가 큼
            • 애플리케이션 실행 시간이 오래 걸림
            • 개발에 들어가는 빌드 시간 및 배포 시간도 오래 걸림
        • 서버 확장 시 비효율적인 리소스 사용
          • 실제 트래픽은 주문 기능에서만 나는데 상품관리, 회원관리도 함께 확장됨
    • MSA
      • 도메인이나 기능별로 모듈을 분리해 서버 배포
      • 수평 확장(Scale-Out) 주로 사용
      • 장점
        • 각각의 모듈의 크기가 감소해 서버 스케일 아웃 시간 빠름
        • 스케일 아웃 시 효율적인 리소스 사용
          • 트래픽이 늘어난 모듈만 서버 스케일 아웃 가능
        • 모듈별완전히 독립
          • 각각 다른 언어로 개발 가능
          • 기능 장애 발생해도 다른 모듈에 영향 방지 가능
      • 단점
        • 초기 구성이 복잡하고 오래 걸림
        • 복잡성이 높음

네트워크 기본

  • 전세계가 물리적 케이블을 통해 전기 신호로 정보를 주고 받음 (먼 해외는 해저 케이블 사용)
  • IP
    • 전 세계 인터넷상에서 유일한 주소 (동적 IP는 시간에 따라 변하지만 여전히 유일)
    • 회선 당 하나 배정하므로 한 회선(공인 IP)을 사설 IP로 나눠 여러 기기가 동시에 IP 사용 가능
      • 공인 IP: 집주소, 전세계에서 유일
      • 사설 IP: 방번호, 소속된 네트워크 장비(공유기) 내에서 유일
        • 사설 IP 주소 대역 (아래 범위 해당하는 주소는 모두 사설 IP)
          • 10.0.0.0 — 10.255.255.255 (Class A)
          • 172.16.0.0 - 172.31.255.255 (Class B)
          • 192.168.0.0 — 192.168.255.255 (Class C)
      • 공유기: 공인 IP를 사설 IP로 분리하는 장치
        • e.g. IP Time
        • WAN 포트: 공인 IP를 받는 인터넷 선을 꽂는 부분
        • LAN 포트: 각각의 기기를 연결해서 사설 IP를 분배하는 곳
      • 기업 네트워크 (아래보다 더 복잡)
        • 공인망: 공인 IP 끼리 사용하는 네트워크 통신망
        • 사설망: 라우터를 사용해 만들어진 내부 네트워크 통신망 (사설 IP 사용, 실제 서버에게 할당)
        • 라우터: 공유기와 비슷한 역할
  • 네트워크 인터페이스
    • 인터넷에 연결하기 위해 컴퓨터에 장착하는 부품 중 하나
    • 네트워크 인터페이스마다 IP를 할당 (사설 IP)
    • 하나의 기기에는 한 개 이상의 네트워크 인터페이스 장착 가능
      • e.g. 노트북 (유선 인터페이스, 무선 인터페이스)
  • 포트
    • 서버에 있는 프로세스들 중 어떤 프로세스에 데이터를 전달할지 지정
    • IP 뒤에 : 붙여 지정 (e.g. 192.168.0.5:8080)
    • 물리적 존재 X, 서버 안에서 정의해 사용
    • 네트워크를 사용하는 프로그램은 실행될 때 자신이 사용할 포트를 지정
      • Well-Known 포트: 사전에 약속되어 있는 포트
      • e.g. 웹서버 통신(80, 443), SSH(22), FTP(21)
  • 네트워크 통신
    • 아웃바운드 : 자신의 서버에서 출발하는 통신
    • 인바운드 : 외부 서버에서 자신의 서버로 오는 통신
  • NAT (Network Address Translation) - 아웃바운드 통신에 사용
    • 매핑 테이블 활용해 공인 IP와 사설 IP를 매핑해주는 기술
      • 공인 IP의 랜덤한 포트를 여러 개 지정해두고 각각의 포트에 사설 IP 정보 매칭
    • 사설망을 구성하는 라우터가 항상 가지는 기능 (자동 설정)
    • 동적으로 정보를 관리하므로 외부에서 서버로 접근할 때는 혼란이 생김 (인바운드 통신)
    • NAT 테이블 예시
      nat_table
      • 아웃바운드 통신 발생 시 해당 사설 IP 주소 및 포트와 공인 IP 주소 및 포트를 저장
        • 공인포트번호는 랜덤 지정
      • 외부 서버는 공인 IP 주소 124.111.46.91:10001을 출발지로 알고 응답을 보냄
      • 라우터는 돌아온 정보를 NAT 테이블에서 192.168.0.4:80으로 응답을 보냄
  • 포트 포워딩 (Port Forwarding) - 인바운드 통신에 사용
    • 외부에서 사설망으로 접근할 때 사용하는 NAT 테이블 같은 매핑 정보 관리 기술
      • 외부에서 공인 IP에 접근하면 포트 포워딩 룰에 맞는 사설 IP로 변환해 트래픽 전달
    • 사용자가 직접 지정
    • 포트포워딩 예시
      port_forwarding
      • 외부 서버에서 공인 IP 주소 124.111.46.91:80으로 요청 보냄
      • 포트 포워딩 룰에 따라 요청은 사설 IP 192.168.0.4:80으로 보내짐
  • DNS (Domain Name System)
    • 도메인 주소와 공인 IP를 매핑해주는 기술 (도메인명 <-> IP 주소)
    • 일반적인 엔터프라이즈 환경에서는 사내망에서 별도로 DNS 서버를 운영하기도 함
      • 사내 서버들끼리 도메인으로 통신할 수 있도록 정보 제공
      • DNS 서버 주소도 내부 DNS 서버의 IP로 지정
    • DNS 예시
      dns
      • devwiki-docker.com으로 요청을 보냄
      • IP 주소가 8.8.8.8인 DNS 서버에 질문을 던져 도메인 주소에 해당하는 IP 주소 받음
      • 요청은 124.111.46.91로 전달됨

도커 가상 네트워크

  • 가상 네트워크: 한 대의 서버 내에서 논리적으로 여러 네트워크를 구성하는 기술
    • 물리적 네트워크 망에는 네트워크 인터페이스로 공인 IP 혹은 사설 IP가 할당된 PC(서버)가 존재
    • 해당 서버 내에 가상 네트워크 구성
    • SDN(Software Defined Network)라고도 함
  • 도커가상 네트워크 기술을 활용해 컨테이너 네트워크를 구성
    docker_bridge_network
    • e.g. 외부와 컨테이너의 통신, 컨테이너와 컨테이너의 통신
    • 가상 네트워크 생성 과정
      • 도커 설치 및 실행 시 다음 2가지 생성
        • 브릿지(docker0): 가상 공유기
          • 가상의 IP 주소를 할당 받음 (일반적으로 172.17.0.1)
          • 가상의 IP 주소: 서버 내 논리적으로 정의된 IP (실제 존재 X)
        • 브릿지 네트워크: 가상 네트워크
      • 컨테이너 실행
        • 브릿지 네트워크의 IP 주소 범위 내에서 가상의 IP 주소 할당
          • e.g. 172.17.0.2, 172.17.0.3, 172.17.0.4, 172.17.0.5
          • 마치 공유기를 통해 사설 IP 할당되는 것과 비슷
      • 같은 브릿지에서 생성된 컨테이너는 브릿지를 통해 서로 통신 가능
        • 도커는 여러개의 브릿지 네트워크 구성도 가능
  • 네트워크 신호 전달 과정
    docker_bridge_network_traffic
    • 서버(PC)는 물리 네트워크 인터페이스인터넷 선을 연결해 공인 IP 혹은 사설 IP를 할당받음
    • 해당 서버 내 도커 설치 후 실행 시
      • 도커는 호스트 OS가상 인터페이스 1개 생성 (docker0)
    • 컨테이너 실행 시
      • 호스트 OS각각 컨테이너에 해당하는 가상 인터페이스들 생성 (Veth고유번호)
    • 전달: 물리 인터페이스 -> 호스트 OS -> 컨테이너 가상 인터페이스 -> 컨테이너
    • 가상 인터페이스 간 통신은 iptables를 활용해 규칙을 정의하고 소프트웨어적으로 패킷 전달
      • iptables
        • Linux OS의 패킷 필터링 시스템
        • 내부 네트워크 트래픽 제어라우팅 규칙 정의
        • 특정 IP 주소로 네트워크를 보냈을 때 어떤 인터페이스로 전달할지에 대한 규칙 설정
          • e.g. 규칙: 172.17.0.3으로 향하는 요청은 Veth2 인터페이스로 전달하자
      • 물리 네트워크 였다면, 네트워크 장치들이 알아서 해줌
    • 참고: 호스트 OS -> 물리적 인터페이스 1개 : 가상 인터페이스 여러개 = 하드웨어 : 소프트웨어
  • 가상 네트워크와 외부 통신 (포트포워딩)
    docker_bridge_network_port_forwarding
    • 아웃바운드 통신은 가상 네트워크가 알아서 NAT 사용
    • 인바운드 통신은 요청이 원하는 컨테이너의 포트로 전달되도록 직접 포트포워딩 옵션 지정
      • HOST OS의 포트는 아무거나 지정해도 상관 X
      • 이미 등록된 포트는 중복 불가
    • 의도적으로 포트포워딩을 하지 않으면, 컨테이너 간 통신만 허용
      • e.g. DB 서버는 포트포워딩 없이 컨테이너 간 통신만 허용하여 외부 통신을 막음
  • 도커 DNS
    • 직접 생성한 브릿지 내 컨테이너가 사용할 수 있는 기본 DNS 서버 제공 (기본 브릿지 제외)
    • 컨테이너 이름도메인으로 자동 저장됨
      • e.g. containerA - 10.0.02, containerB - 10.0.03
    • 컨테이너 간의 통신에 중요! -> 컨테이너 IP는 컨테이너 재시작 시 계속 바뀔 수 있어 불편
    • 외부 DNS 서버와 연동되어 있어, 컨테이너 외부 도메인으로도 접근 가능 (e.g. 구글)
  • 도커 네트워크 드라이버
    • 브릿지 네트워크 (Bridge)
      • 도커 브릿지를 활용해 컨테이너 간 통신 지원
      • NAT 및 포트포워딩 기술을 활용해 외부 통신 지원
    • 호스트 네트워크 (Host)
      • 호스트 네트워크를 공유해 모든 컨테이너호스트 머신과 동일한 IP 사용하도록 지원
      • 호스트 네트워크와 포트 중복 불가능
    • 오버레이 네트워크 (Overlay)
      • 호스트 머신이 다수일 때 하나의 네트워크처럼 사용하도록 지원 (Kubernetes에서 사용)
    • Macvlan 네트워크
      • 컨테이너에 MAC 주소를 할당해, 물리 네트워크 인터페이스에 직접 연결

스토리지와 볼륨

  • 컨테이너의 중요한 속성: Stateless (무상태)
    • 컨테이너상태가 없음
      • 컨테이너 실행 후 모든 변경 사항은 컨테이너 레이어에만 존재
    • 불변성: 모든 상태이미지에 기록되고 이미지는 한 번 지정된 후 변경되지 않음
      • 컨테이너 상태 변경(e.g. 소프트웨어 버전 변경)이 필요하면 새 버전의 이미지 제작 후 배포
    • 장점
      • 여러 컨테이너다른 여러 환경에서 빠르게 배포 가능
      • 트래픽이나 장애에도 컨테이너를 쉽게 생성해 빠르게 대처
    • 제약
      • 상태가 없으므로 데이터는 무조건 외부에 저장해야 함
        • 데이터 영구 저장을 위해서는 DB 서버 사용이 필수
        • 사용자 세션 정보캐시 같은 정보는 캐시 서버나 쿠키를 통해 관리
          • e.g. 사용자 로그인 정보, 장바구니 상품 리스트
      • 동일한 요청항상 동일한 결과를 제공해야 함
        • 같은 이미지로 생성한 모든 서버에서 같은 응답을 제공해야 함
      • 컨테이너 실행 시점에 설정외부에서 주입할 수 있어야 함
        • 환경 변수구성 파일을 통해 다양한 환경에서 컨테이너 이미지를 활용 가능
  • 도커 볼륨 (Docker Volume)
    docker_volume
    • 데이터를 보관하기 위해 도커가 관리하는 외부 공유 저장소
      • 호스트 OS의 서버 특정 공간에 저장 (e.g. /volumes/volume1)
      • 볼륨 저장 경로에 사용자가 직접 접근하기는 어려움
        • 경로는 리눅스에서는 관찰 가능, MacOS 등은 관찰 불가
        • 도커가 가상머신 형태로 실행되어 경로를 자동 관리하고 가상머신 안에 저장하기 때문
    • 컨테이너가 삭제되도 볼륨은 남아있음
    • 볼륨 마운트
      • 컨테이너들은 컨테이너의 특정 경로도커 볼륨마운트해서 사용
      • 즉, 컨테이너의 특정 폴더는 공유용 폴더
      • e.g. PostgreSQL
        • PostgreSQL은 /var/lib/postgresql/data 경로에 실제 DB 데이터 저장
        • 해당 경로를 도커 볼륨에 마운트
        • 해당 경로에 저장하는 파일들은 컨테이너 레이어가 아니라 외부 볼륨에 저장
        • 여러 컨테이너는 1개의 볼륨을 공유해 동일한 데이터를 제공할 수 있음
        • 컨테이너가 삭제되거나 새 컨테이너가 생성되어도 데이터 영속성 보장
    • 볼륨과 컨테이너의 관계
      • 여러 컨테이너하나의 볼륨 마운트 가능
      • 하나의 컨테이너여러 개의 볼륨 마운트 가능
    • 바인드 마운트 (Bind Mount)
      • 도커가 자동 관리에서 벗어나 Host OS에서 데이터를 직접 관찰 가능 (볼륨 X)
      • 방법: -v 옵션에서 볼륨 이름 대신 사용자 지정 경로를 전달
      • 디버깅에 유용
    • 볼륨은 마운트한 컨테이너가 없을 때삭제 가능

컨테이너의 무상태와 서버 관리 방법론

  • Pet 방식 (전통적 서버 방법론)
    • 서버 한 대 한 대를 소중히 직접 관리하는 방식
    • 서버 에러 및 종료를 서비스 장애로 간주
    • 서버가 상태를 가져서 교체가 어려움
    • e.g. Monolithic, OnPremise
  • Cattle 방식
    • 컨테이너를 활용한 서버 방법론 (서버는 소모품)
    • 서버 에러 및 종료가 충분히 일어난다고 가정
      • 문제 서버 삭제 후 빠르게 새 서버를 생성해 대체하는 방식으로 해결
    • 서버의 상태를 최대한 제거빠르게 교체 가능하도록 함
    • e.g. MSA, WEBAPP

마운트

컴퓨터의 특정 디렉토리를 외부 저장소와 연결하는 것을 말한다.
NFS(Network File System)는 PC의 특정 폴더 혹은 드라이브 단위를 NFS에 마운트 시킬 수 있고, 여러 컴퓨터가 접근할 수 있습니다.

도커 컴포즈 (Docker Compose)

  • 여러 개의 도커 컨테이너편리하게 관리하는 도구
    • 여러 개의 컨테이너를 하나의 파일에 정의해 복잡한 애플리케이션 구조를 관리
    • e.g. 서비스 간 의존성, 도커 네트워크
  • 특징
    • YAML 문법으로 IaC 적용 (docker-compose.yml)
    • 도커 데스크탑 설치 시 기본 제공
    • 도커 컴포즈의 서비스 = 컨테이너
    • 디폴트네트워크를 생성컴포즈 파일 내 컨테이너들을 포함시킴
      • e.g. --network leafy-network
  • 장점
    • 여러 개의 컨테이너를 한 번의 명령어로 실행 혹은 종료 가능 (docker compose up)
    • 로컬 개발 환경에서 활용이 편리 (실제 운영과 비슷한 환경을 빠르게 구성 가능)

YAML 문법 (YAML Ain’t Markup Language, YAML은 마크업 언어가 아니다)

JSON 같은 데이터 표현 형식 중 하나다.
상대적으로 최근에 나온 포멧으로 가독성에 더 초점을 맞춰 간결하다.
JSON이 {}"", 등이 필수인 반면, YAML은 띄어쓰기 기반으로 정보를 구분한다.
예시로, 띄어쓰기와 -로 리스트와 객체를 표현할 수 있다.
정의서 작성과 같은 사용자가 직접 파일을 작성하는 방식에 많이 쓰인다. (Docker, Kubernetes)


Reference

개발자를 위한 쉬운 도커