Docker CLI API - 우리 입장(개발자)에서는 거의 dockerD와 함께 하는 것인데, dockerD의 업무가 무엇이 있냐면, 우리가 던지는 모든 도커 명령어, 모든 CLI를 다 받아준다. docker command.
swarmkit - 지금 수업에서는 단순하게 처음에는 싱글 모드의 도커를 쓸 것이다. 물론 싱글 모드 서버 두 대를 만들 건데, 도커 서버 한 대 만들고 그거를 Virtual Box에서 복제 기능이 있어서 복제 기능을 통해서 두 대의 서버를 가지고 연습을 할 것이다. 그 다음에 이제 docker swarm 에 가면, 세 대의 호스트 OS, 이걸 가지고 docker swarm 을 만들어서 컨테이너 서비스를 멀티 클러스터로 확장을 할 것이다. 그 때 쓰는 기술이 swarm 인데, 그 swarm을 만들때 쓰는 swarmkit 이라는 걸 dockerD가 가지고 있다. 그래서 init 작업이라고 하는데, 초기화 작업을 통해서 세 대의 호스트죠, 세 대의 호스트 OS 를 조인시킬 수 있는 키포인트를 제공을 한다. 그게 이제 swarmkit 이다.
Logs mgmt - 도커도 하나의 어떤 플랫폼이다. 당연히 내부적으로 로그는 지속적으로 발생을 한다. 이벤트 로그. 계속 발생을 한다. 그 로그를 기본적으로는 json 파일로 저장을 하고 있는데, 그것을 AWS 또는 리눅스 호스트에 있는 RCS 로그, 또는 GCP 로그, 되게 다양한 형태로 로그를 매니지먼트 할 수 있다. 실제로 도커 플랫폼에서 발생하는 로그들을 '내가 어디다 뿌리겠다', 그러면 네트워크 플러그인, 그 다음에 로그 플러그인 같은 것들을 이용해서 우리들이 로그를 어디에 뿌릴 수 있는 방법을 찾을 수가 있다.
Storage mgmt - 그 다음에 Storage mgmt, 결국에는 도커 컨테이너는 이미지로 출발하고, 그 이미지는 파일이다. 그럼 파일이 저장되기 위해선 파일을 관리하는 스토리지가 필요하다. 그래서 그 스토리지를 관리하고 도커와 연동하는 드라이버가 있는데, 그걸 오버레이 2 드라이버를 쓸 것이다. 그래서 스토리지 매니지먼트를 한다는 건 파일을 관리한다는 걸 의미한다.
libnetwork - 네트워크가 없으면 서비스가 될 수 없다. 도커의 기본적인 네트워크를 libnetwork 라고 한다. libnetwork를 통해서 우리가 브릿지 네트워크, 오버레이 네트워크 이런 것들을 만들 수가 있다. 그 내부를 들어가보면 도커 제로라는 인터페이스, 사용자 정의 인터페이스 이런 것들을 만들고 그 위에 버추얼 이더넷이라고 하는 터널링 서비스, 그 다음 모든 컨테이너는 ETH 제로라는 인터페이스를 가진다. 컨테이너 내부에 네트워크가 좀 필요할텐데, 그게 샌드박스라는 건데, 그 샌드박스를 만드는게 바로 커널 기술에 있는 네임스페이스이다. 그래서 그 안에는 IP, 맥어드레스, 라우팅 테이블, IP 테이블, 되게 다양한 네트워크 기술이 포함이 된다.
buildkit - 그 다음에, 이미지를 만들어야 컨테이너를 띄울 수가 있다. buildkit 이다. 그래서 이미지를 빌드를 해서 새로운 이미지, 새로운 인프라를 개발한다? 그럼 빌드가 당연히 돼야 된다, 이미지가 필요한 거니까. 그래서 이제 dockerD 라는 이 대몬이 내가 도커 명령어에 docker build, 이 명령어를 던져서 이미지를 개발하는 환경에서의 어떤 서비스를 제공한다는 이야기다.
DCT - Docker Contents Trust 의 약자이다. 이미지 보호 기능이라고 한다. 위조, 변조, 이미지의 어떤 위조나 변조를 알려주는 보안 기술 중에 하나이다.
Image mgmt - 마지막으로, 이미지를 관리하는 기술이라고 하는 Image mgmt. 반복적으로 이야기하겠지만, 컨테이너의 모체는 이미지이다. 그 이미지를 관리할 수 있는 기술은 당연히 필요하다. 이미지에 대한 생성, 변경, 삭제부터해서 이미지는 어떻게 만들어지느냐, 레이어 단위로 만들어지는 이미지는 어떻게 관리를 해야 되느냐, 그 이미지를 우리가 파일로 백업받고 다시 집어넣고 등록하는 과정, 이런 모든 것들이 다 dockerD를 통해서 연결이 된다고 생각하면 된다.
그래서 우리가 기본적으로 dockerD, containerD, runC 라는 엔진 모델, 이게 도커 엔진이다. 도커 엔진에서 우리가 중점적으로 볼 것은 사실은, 이 내부에 containerD 나 runC 같은 경우는 우리가 다룰 필요는 없다. dockerD에 명령어들 위주로, 위에서 언급하고 있 dockerD가 가지고 있는 기술들 위주로 배워볼 것이다.
각 항목마다 구조, 역할, 작동 원리를 중심으로 설명을 보강했습니다.
1. Docker CLI API
설명:
- **Docker CLI(Command Line Interface)**는 개발자가 Docker와 상호작용하기 위해 사용하는 명령줄 도구입니다.
- 개발자가 입력한 모든 명령어는 Docker Daemon(dockerD)로 전달되어 처리됩니다.
- 역할:
- Docker CLI는 사용자 → Docker Daemon → Docker Engine의 구성 요소로 작업 요청을 전달하는 인터페이스.
- Docker 명령어(docker run, docker build 등)를 실행하면, 내부적으로 HTTP API 호출로 변환하여 Docker Daemon에 전달.
작동 원리:
- 사용자가 Docker CLI에서 명령을 입력.
- 예: docker run ubuntu는 Ubuntu 이미지를 실행해 컨테이너를 생성하라는 요청.
- Docker CLI는 이 명령을 HTTP 요청으로 변환.
- 요청은 기본적으로 Unix 도메인 소켓(/var/run/docker.sock) 또는 TCP 소켓을 통해 Docker Daemon으로 전달됨.
- Docker Daemon(dockerD)이 명령을 해석하고 작업을 수행.
2. SwarmKit
설명:
- SwarmKit은 Docker에서 컨테이너 오케스트레이션을 담당하는 컴포넌트입니다.
- 여러 대의 Docker Host를 클러스터링하여 단일 관리 단위처럼 동작하도록 만듭니다.
- 역할:
- 다중 노드의 클러스터를 구성.
- 컨테이너 서비스를 클러스터 내에서 배포, 관리.
- 노드 간 네트워크 연결 및 작업 분배.
작동 원리:
- Swarm 초기화:
- Docker Daemon이 SwarmKit을 호출하여 클러스터 초기화(docker swarm init 명령어).
- 리더 노드(Manager Node)가 생성되고, 다른 노드(Worker Node)는 docker swarm join 명령으로 연결.
- 클러스터 관리:
- 리더 노드가 컨테이너 작업을 분배.
- 상태를 지속적으로 모니터링하고 장애가 발생한 노드를 감지하여 복구.
3. Logs Management
설명:
- Docker는 컨테이너에서 발생하는 이벤트 로그를 관리합니다.
- 기본적으로 JSON 파일에 저장되며, 다양한 로그 드라이버를 사용하여 AWS, GCP, RCS와 같은 외부 시스템으로 전송 가능.
- 역할:
- 로그 수집 및 전송.
- 로그 플러그인을 통해 사용자 정의 저장소나 네트워크로 전달.
작동 원리:
- 컨테이너에서 발생한 이벤트 로그가 JSON 형식으로 저장.
- 사용자가 지정한 로그 드라이버(AWS CloudWatch, syslog 등)를 통해 로그를 외부로 전송.
- Docker Daemon은 로그 관리 정책에 따라 로그 데이터를 수집 및 전달.
4. Storage Management
설명:
- Docker는 컨테이너와 이미지를 저장하고 관리하기 위해 스토리지 드라이버를 사용합니다.
- Overlay2는 가장 널리 사용되는 스토리지 드라이버로, 파일 계층 구조를 통해 저장 공간을 효율적으로 사용.
- 역할:
- 컨테이너가 사용하는 파일 시스템 제공.
- 이미지 저장 및 계층 관리.
작동 원리:
- Docker 이미지와 컨테이너는 계층적 파일 시스템으로 구성.
- 컨테이너 실행 시:
- 읽기 전용 계층: 기본 이미지.
- 읽기/쓰기 계층: 컨테이너의 변화 데이터.
- Overlay2 드라이버가 파일 시스템 계층을 조합하여 컨테이너에 제공.
5. libnetwork
설명:
- Docker의 네트워크 관리를 담당하는 라이브러리.
- 역할:
- 브리지 네트워크, 오버레이 네트워크 등 다양한 네트워크 모드 제공.
- 컨테이너 간 통신을 지원하며, 가상 네트워크 인터페이스를 생성.
- 네트워크 격리를 위해 커널의 네임스페이스 기술 사용.
작동 원리:
- 네트워크 생성:
- 기본 브리지 네트워크(docker0) 생성.
- 사용자가 필요에 따라 오버레이 네트워크, 사용자 정의 네트워크 추가 가능.
- 컨테이너 네트워크 설정:
- 컨테이너마다 가상 이더넷 인터페이스(eth0) 생성.
- IP 주소, MAC 주소, 라우팅 테이블 설정.
- 샌드박스 생성:
- 네임스페이스를 사용해 컨테이너별 네트워크 격리.
6. BuildKit
설명:
- Docker 이미지를 빌드하기 위한 도구.
- 역할:
- 효율적인 이미지 빌드 프로세스 제공.
- 병렬 빌드, 캐시 최적화, 멀티스테이지 빌드를 지원.
작동 원리:
- 사용자가 docker build 명령 실행.
- BuildKit이 Dockerfile을 해석하고 빌드 단계를 최적화.
- 중복되지 않은 단계만 다시 빌드하여 속도 향상.
- 빌드 결과를 이미지로 생성 및 저장.
7. Docker Content Trust (DCT)
설명:
- Docker 이미지의 무결성과 신뢰성을 보장하는 보안 기술.
- 역할:
- 이미지 서명(Signing)을 통해 위조 및 변조를 방지.
- 신뢰할 수 있는 이미지인지 확인.
작동 원리:
- DCT가 활성화되면, 이미지를 푸시(push)하거나 풀(pull)할 때 서명된 데이터만 허용.
- Docker Daemon이 서명을 검증하여 변조되지 않은 이미지임을 확인.
8. Image Management
설명:
- Docker 이미지를 생성, 관리, 삭제하는 모든 작업을 담당.
- 역할:
- 이미지의 생성(docker build), 저장(docker save), 복원(docker load).
- 이미지의 계층 구조를 효율적으로 관리.
작동 원리:
- Docker 이미지는 여러 계층(Layer)으로 구성.
- 각 계층은 읽기 전용이며, 필요 시 새로운 쓰기 계층이 추가.
- 이미지는 레지스트리에 저장되며, 필요 시 레지스트리에서 다운로드 가능.
이미지의 계층 구조라는게 무슨 말이야?
Docker 이미지는 여러 계층으로 구성된다고 했는데 어떤 계층으로 나뉘는거야?
1. Docker 이미지의 계층 구조란?
Docker 이미지는 **여러 읽기 전용 계층(Read-Only Layer)**으로 구성되며, 각 계층은 이전 계층 위에 쌓이는 방식으로 동작합니다.
이 계층 구조는 레이어드 파일 시스템(layered filesystem) 기술을 사용하며, 이미지를 효율적으로 저장하고 관리할 수 있도록 합니다.
특징
- 읽기 전용 계층:
- 각 계층은 변경되지 않는 불변 데이터를 포함합니다.
- 이미지의 내용은 레이어로 추가되며, 각 계층은 상위 계층에서 변경이 발생하지 않으면 그대로 재사용됩니다.
- 변경 계층(읽기/쓰기 계층):
- 컨테이너가 실행될 때, 이미지 위에 새로운 읽기/쓰기 계층이 추가됩니다.
- 컨테이너 내부에서 발생하는 모든 변경 사항은 이 읽기/쓰기 계층에 저장됩니다.
2. 계층의 구성 요소
Docker 이미지의 각 계층은 특정 작업(명령)과 연결되며, Dockerfile의 명령어마다 새로운 계층이 생성됩니다.
Dockerfile과 계층 생성
- Dockerfile에 작성된 각 명령어(RUN, COPY, ADD 등)는 새로운 계층을 생성합니다.
- 예: Dockerfile
FROM ubuntu:latest
RUN apt-get update && apt-get install -y curl
COPY ./app /usr/src/app
CMD ["bash"]
-
위 Dockerfile은 다음과 같이 계층을 생성합니다:
- FROM: 베이스 이미지(ubuntu:latest)를 가져옴. (첫 번째 계층)
- RUN: 패키지 업데이트 및 설치. (두 번째 계층)
- COPY: 파일을 이미지에 복사. (세 번째 계층)
- CMD: 컨테이너 실행 시 기본 명령 설정. (메타데이터로 저장됨)
3. 계층의 동작 방식
(1) 이미지 빌드 시:
- 각 계층은 기존 레이어를 기반으로 새로운 레이어를 추가하여 이미지를 만듭니다.
- 동일한 Dockerfile로 빌드할 때 변경되지 않은 레이어는 캐시로 재사용되어 빌드 시간을 단축합니다.
(2) 컨테이너 실행 시:
- 이미지는 읽기 전용 상태로 컨테이너 위에 올라가고, 컨테이너가 실행되면 읽기/쓰기 계층이 생성됩니다.
- 이 읽기/쓰기 계층에서 발생하는 모든 파일 변경 사항(쓰기, 삭제 등)은 기존 이미지 레이어에 영향을 주지 않습니다.
4. 계층 구조의 장점
- 효율적인 저장:
- 동일한 베이스 이미지를 사용하는 여러 컨테이너는 하나의 레이어를 공유하므로 디스크 공간을 절약.
- 빠른 빌드:
- Docker는 이전 빌드에서 생성된 계층을 캐시로 재사용하여 중복 작업을 피함.
- 일관성:
- 이미지의 각 계층은 변경되지 않는 읽기 전용 데이터로 구성되므로 안정적이고 예측 가능.
5. 계층 구조의 단점
- 잘못된 Dockerfile 작성으로 인해 불필요한 계층 생성:
- Dockerfile의 명령어 순서나 구조가 비효율적이면 많은 계층이 불필요하게 생성될 수 있음.
- 예: 여러 RUN 명령어를 별도로 작성하면 각 명령어마다 새로운 계층이 생성됨.
- 캐시 관리 어려움:
- 오래된 캐시 레이어가 불필요하게 디스크 공간을 차지할 수 있음.
6. 예시로 이해하는 계층 구조
예제: Dockerfile을 기반으로 이미지 생성
# 1. 베이스 이미지
FROM ubuntu:20.04
# 2. 패키지 업데이트
RUN apt-get update
# 3. curl 설치
RUN apt-get install -y curl
# 4. 앱 복사
COPY ./my_app /usr/src/app
# 5. 기본 명령 설정
CMD ["bash"]
이미지 계층 구조:
- FROM ubuntu:20.04:
- Ubuntu 20.04 이미지를 가져와 첫 번째 계층으로 사용.
- RUN apt-get update:
- 패키지 목록 업데이트 작업.
- 결과는 새로운 레이어에 저장.
- RUN apt-get install -y curl:
- curl 설치 작업.
- 결과는 또 다른 레이어에 저장.
- COPY ./my_app /usr/src/app:
- ./my_app 디렉토리를 컨테이너에 복사.
- 복사된 파일은 새로운 계층으로 추가.
- CMD ["bash"]:
- 실행 시 사용할 기본 명령어 설정 (메타데이터로 저장).
7. Docker 이미지 계층 시각화
docker history <이미지 ID> 명령을 사용하면 이미지 계층 구조를 확인할 수 있습니다.
예:
docker history my_image
출력 예시:
IMAGE CREATED CREATED BY SIZE
<layer_id> 2 days ago /bin/sh -c apt-get install -y curl 25MB
<layer_id> 2 days ago /bin/sh -c apt-get update 10MB
<layer_id> 2 days ago /bin/sh -c #(nop) COPY ./my_app /usr/src/app 2MB
<layer_id> 2 days ago FROM ubuntu:20.04 100MB
8. 결론
- Docker 이미지의 계층 구조는 각 작업(명령어)을 별도의 레이어로 관리하여 효율적이고 유연한 이미지 관리를 가능하게 합니다.
- 읽기 전용 계층과 읽기/쓰기 계층을 분리하여 디스크 공간 절약, 빌드 속도 향상, 일관성 있는 배포 환경을 제공합니다.
- Dockerfile 작성 시 계층 구조를 고려하면 더 효율적으로 이미지를 빌드할 수 있습니다.
Docker에서 가장 중요한 기술과 학습자의 중점 포인트, 그리고 현업에서 도커를 활용할 때 중요하게 봐야 할 것에 대한 제 생각을 아래에 정리해볼게요.
1. Docker에서 가장 중요한 기술
Docker는 다양한 기술이 결합된 도구이지만, 현업에서 실질적으로 가장 중요한 기술은 다음과 같습니다:
(1) 이미지 관리
- 왜 중요한가?
- Docker의 핵심은 컨테이너이고, 컨테이너는 이미지에서 출발합니다.
- 이미지를 잘 관리해야 일관된 배포 환경을 만들 수 있습니다.
- 중요한 개념:
- 이미지 계층 구조: 이미지를 효율적으로 생성하고 관리하려면 계층 구조를 이해해야 합니다.
- 이미지 최적화: 이미지를 경량화하고 불필요한 레이어를 제거해 빌드 속도와 실행 성능을 높이는 것이 중요합니다.
- 이미지 태깅(tagging): 특정 버전의 이미지를 추적하고 관리하기 위해 이미지 태그를 적절히 사용하는 습관.
(2) 컨테이너 관리
- 왜 중요한가?
- 컨테이너는 실행 가능한 단위이며, 이를 효과적으로 관리해야만 도커의 진가를 발휘할 수 있습니다.
- 중요한 개념:
- 컨테이너의 생성, 실행, 중지, 삭제 기본 명령어(docker run, docker stop 등).
- 컨테이너 상태 관리: 실행 중인 컨테이너 모니터링(docker ps), 로그 확인(docker logs) 등.
- 컨테이너 네트워크: 컨테이너 간 통신을 설정하거나 외부와의 네트워크를 구성.
(3) 스토리지와 볼륨 관리
- 왜 중요한가?
- 컨테이너는 기본적으로 휘발성입니다. 데이터를 영구적으로 저장하려면 **볼륨(volume)**을 활용해야 합니다.
- 중요한 개념:
- 볼륨: 컨테이너와 호스트 간 데이터를 공유하거나 영구적으로 보관.
- 바인드 마운트와 네임드 볼륨 차이.
- 스토리지 드라이버(overlay2)에 대한 이해.
(4) Docker Compose 및 오케스트레이션
- 왜 중요한가?
- 실무에서는 단일 컨테이너가 아니라 여러 컨테이너를 조합한 환경을 다루는 경우가 많습니다.
- Docker Compose나 Kubernetes와 같은 오케스트레이션 도구를 사용해 멀티 컨테이너 환경을 설정, 관리합니다.
- 중요한 개념:
- Docker Compose를 사용한 서비스 정의(docker-compose.yml).
- 컨테이너 간 의존성 설정, 네트워크 연결.
(5) 보안
- 왜 중요한가?
- 도커는 경량화된 컨테이너를 기반으로 하지만, 보안 설정이 제대로 되어 있지 않으면 심각한 취약점이 발생할 수 있습니다.
- 중요한 개념:
- Docker Content Trust (DCT): 이미지의 위조와 변조 방지.
- 컨테이너 권한 제한: 컨테이너가 불필요하게 높은 권한을 가지지 않도록 설정.
- 네트워크 격리: 컨테이너 간 통신 및 외부 네트워크 접근 제한.
2. 학습자가 중점적으로 기억해야 할 것
Docker를 공부할 때 초보자와 중급자로 나눠서 학습 포인트를 정리해볼게요.
(1) 초보자가 기억해야 할 것
- Docker의 기본 개념과 구조:
- 이미지, 컨테이너, 볼륨, 네트워크의 관계.
- 가장 기본적인 명령어:
- docker run, docker ps, docker stop, docker logs, docker exec, docker build 등.
- Dockerfile 작성법:
- 이미지 계층 구조 이해와 효율적인 Dockerfile 작성.
(2) 중급자가 기억해야 할 것
- Docker Compose:
- 여러 컨테이너를 정의하고 관리하는 방법.
- 이미지 최적화:
- 이미지를 경량화하고, 빌드 캐시를 활용하는 기술.
- 네트워크와 데이터 관리:
- 브리지 네트워크, 오버레이 네트워크의 사용법.
- 볼륨과 바인드 마운트의 차이와 활용법.
3. 현업에서 Docker 활용 시 중요하게 봐야 할 것
(1) 일관성 있는 배포 환경
- 왜 중요한가?
- 도커의 가장 큰 장점은 "어디서나 동일하게 동작하는 실행 환경"을 제공하는 것입니다.
- 이를 위해 Dockerfile과 Compose 파일을 체계적으로 관리해야 합니다.
- 어떻게 활용할까?
- CI/CD 파이프라인에 Docker를 통합하여 일관된 배포를 자동화.
(2) 이미지 최적화와 보안
- 이미지 최적화:
- 현업에서는 작은 크기의 이미지가 네트워크 전송 속도를 높이고, 저장 비용을 절감합니다.
- 불필요한 계층을 줄이고, 경량화된 베이스 이미지를 사용하는 것이 중요합니다.
- 예: ubuntu 대신 alpine 사용.
- 이미지 보안:
- 이미지 서명(Docker Content Trust).
- 필요 이상으로 큰 이미지를 사용하지 않도록 주의.
(3) 컨테이너 오케스트레이션
- Docker 단독으로 사용하는 경우도 있지만, Kubernetes 같은 오케스트레이션 툴을 함께 사용하는 경우가 대부분입니다.
- 컨테이너 오케스트레이션을 통해 스케일링, 장애 복구, 롤백 같은 자동화된 작업이 가능합니다.
(4) 효율적인 로그와 모니터링
- 현업에서는 실시간 상태 모니터링과 로그 관리가 중요합니다.
- 컨테이너의 로그를 중앙화된 시스템(예: ELK, Prometheus, Grafana)으로 수집하여 성능을 추적하고 이슈를 분석할 수 있도록 준비해야 합니다.
4. 결론
- 가장 중요한 기술은 Docker의 핵심인 이미지와 컨테이너 관리입니다. 이는 도커의 기본이고, 현업에서 가장 많이 사용됩니다.
- 학습할 때 중점적으로 기억해야 할 것은 기본 명령어, Dockerfile 작성, 네트워크와 볼륨 관리입니다.
- 현업에서는 도커를 활용한 CI/CD 파이프라인 통합, 이미지 최적화, 그리고 오케스트레이션과 모니터링이 중요합니다.
'도커 & 쿠버네티스' 카테고리의 다른 글
어플리케이션 배포 방식 : 컨테이너 (Docker engine : dockerD, containerD, runC) (0) | 2025.01.21 |
---|---|
어플리케이션 배포 방식 비교 : 일반서버 vs. 가상머신 vs. 컨테이너 (0) | 2025.01.20 |
Docker 컨테이너 가상화와 VM 가상화 비교 (1) | 2025.01.17 |
컨테이너 가상화 이해 - 컨테이너 기술이란? (0) | 2025.01.17 |