개발 기록

> [Docker] Docker 구조와 요소들에 대하여 본문

인프라

> [Docker] Docker 구조와 요소들에 대하여

1z 2023. 11. 27. 00:46



 

0. 개요 

 

도커를 운영체제에 설치할 때 아래의 공식 문서를 보면서 했는데,

☞ 정확히 어떤 항목들을 설치하는 건지! 그 항목이 어떤 역할을 하길래 설치하는 것인지?

 그 항목들은 서로 어떤관계를 가지며 동작하는 것인지를 알아보도록 한다.

Docker install doc

 


1. 설치 항목과 구성 요소  

(1) 설치 패키지와 플러그인 

 

    설치 위치 역할
docker-ce Docker
Community Edition
(도커 소프트웨어)
/usr/bin/docker - 도커 엔진 설치.
- 도컨 엔진: 컨테이너 관리 및 실행
(컨테이너의 실행, 정지, 삭제, 이미지 관리 등)
- 도커 데몬과 그 하부에서 동작하는 containerd를 포함하여 컨테이너를 관리하고 실행한다.
docker-ce-celi 도커  명령어
인터페이스
/usr/bin/docker - 도커 명령어를 통해 도커 엔진과 상호작용할 수 있는 명령어 인터페이스
containerd.io 컨테이너 런타임 /usr/bin/containerd - Docker 엔진 내부에서 컨테이너의 생명주기를 관리를 담당하는 핵심 컴포넌트
- 
도커 데몬이 containerd를 통해 컨테이너를 관리하고 실행한다.

docker-buildx-plugin Docker
Multi-Platform
Build Plugin
도커 CLI 경로
- 다양한 플랫폼에서 동일한 Dockerfile로 멀티 플랫폼 이미지를 빌드할 수 있게 해준다.
- 도커 CLI 확장

 

 

(2) 구성 요소

 

 

▶  Docker Client 

- 사용자가 커맨드 라인 인터페이스(CLI)나 API를 통해 도커와 상호작용하는 도구

- 클라이언트는 사용자가 입력한 명령어를 처리하고, 그 결과를 도커 데몬에게 전달

(UNIX 소켓 또는 네트워크 인터페이스를 통해 REST API를 사용하여 통신한다. )

 

▶  Docker Engine 

- 컨테이너를 생성하고 관리하는 핵심 엔진

- 도커엔진 구성 요소 (Docker Daemon, Docker CLI, containerd, runc, 스토리지 드라이버, 네트워크 드라이버)

 

  Docker Daemon 

- 도커 엔진의 핵심으로 백그라운드에서 실행되는 프로세스

- 컨테이너의 생명주기 관리, 이미지 저장 및 관리, 볼륨, 네트워크 설정 등을 담당

- 일반적으로 dockerd라는 이름의 실행 파일로 나타난다.

- Docker 데몬은 세 가지 유형의 소켓( unix, tcp, fd) 을 통해 Docker Engine API 요청을 수신할 수 있다.

 

  Docker Socket 

- 도커 데몬과 도커 클라이언트(Command Line Interface) 간의 통신을 담당하는 매개체(파일)

- 도커 클라이언트는 명령어를 도커 데몬에게 전달하기 위해 이 소켓을 통해 도커 데몬의 API를 호출한다.  

 

(3) 동작 순서 

https://www.tiuweehan.com/blog/2020-09-10-docker-in-jenkins-in-docker/

 

 <명령어 입력>: Docker CLI 를 사용하여 'docker run' 입력한다.

 <도커 클라이언트의 명령어 전달> : 도커 클라이언트는 입력된 명령어를 API 요청으로 변환한다.

 <도커 데몬의 API 호출> : API 요청은 /var/run/docker.sock에 위치한 Unix 소켓(도커 소켓)을 통해 도커 데몬에게 전달한다.

 <도커 데몬의 명령어 처리> : 도커 데몬은 이 명령어를 파싱하고 명령어에 해당하는 작업을 수행한다. 

 <결과 반환> : 도커 데몬은 작업을 수행한 후 결과를 도커 클라이언트에 반환한다.

 <결과 출력> : 도커 클라이언트는 도커 데몬에서 반환받은 결과를 사용자에게 출력한다.

 

 

 이를 통해 도커는 '클라이언트-서버 아키텍처' 로 클라이언트와 서버의 역할을 분리하여 동작한다는 것을 알 수 있다. 이어서 알아보자!

 


2. 구조  

 

"도커는 클라이언트-서버 아키텍처를 사용한다.

이는 도커 엔진(Docker Engine)이 클라이언트와 서버의 역할을 분리하여 동작한다는 것을 의미한다."

 

 도커 구조로 인한 특징

ⓛ Docker 클라이언트가 Docker 데몬과 별도로 실행될 수 있습니다. 이를 통해 한 호스트에서 Docker 명령을 실행하고 다른 호스트에서 실행할 수 있다.

② Docker 데몬은 여러 소켓을 가질 수 있으며 각 소켓은 여러 클라이언트를 가질 수 있다. 이를 통해 Docker 데몬은 여러 인터페이스에서 받은 명령을 실행할 수 있다.
③ 사용자는 도커 클라이언트를 통해 여러 호스트의 도커 데몬에 접근하고 관리할 수 있다.

 

※ 참고

도커 컴포즈: 다중 컨테이너 도커 애플리케이션을 정의하고 실행하기위한 도구

 


3. 도커 데몬 상세  

 

(1) 도커 데몬  (= dockerd = docker daemon)

 

① 도커의 핵심 백그라운드 프로세스 

② 터미널에서 dockerd 명령을 사용하여 실행할 수 있다.

③ 실행 후에는 로그 메시지가 생성되면서 데몬이 백그라운드에서 동작한다.

    (다른 터미널에서 'docker ps' 와 같은 명령을 실행하여 도커가 제대로 작동하는지 확인할 수 있다.)

 

 

(2) 도커 데몬과 소켓  

 

' Docker daemon은 Docker Engine API의 요청을 Unix, TCP, RD 라는 3개 타입의 소켓으로 받을 수 있다.' 

 

 유닉스 소켓(Unix socket)  -> 도커 클라이언트와 도커 데몬 간의 기본 통신 방식

- 동일한 호스트 내에 있는 도커 데몬에게 명령을 전달할 때 사용된다.

- 주로 /var/run/docker.sock 파일에 위치하며, 클라이언트는 이 소켓을 통해 도커 데몬과 통신한다.

- 클라이언트가 명령을 실행하면, 이 명령은 유닉스 소켓을 통해 데몬에 전송된다.

# Unix 도메인 소켓을 통해 도커 데몬을 실행하기 위한 명령어
dockerd -H unix:///var/run/docker.sock

 

 

 TCP  소켓(TCP socket)  -> 원격에서 도커 데몬을 제어할 때 사용되는 방식

- 특정 TCP 포트(기본적으로 2375 포트)를 통해 도커 데몬이 TCP 소켓을 열어 원격 클라이언트의 요청을 받는다.

- 이 방식은 보안상의 이유로 기본적으로 비활성화되어 있고, 필요한 경우에만 명시적으로 활성화하여 사용해야 한다.

- 보안을 위해 TLS와 같은 암호화 기법을 함께 사용하는 것이 권장된다.

# 포트와 IP 주소를 지정하여 TCP 소켓을 연다
dockerd -H tcp://0.0.0.0:2375

# 원격 접근을 위해 TCP 소켓 추가
dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

 

 

 Socket 동작  

 

 위의 그림으로 볼 수 있듯이 

데몬은 여러 개의 소켓(Unix, TCP)을 가질 수 있어서 로컬 및 원격 클라이언트의 요청을 모두 받을 수 있다는 것과

각 소켓은 여러 개의 클라이언트를 가질 수 있어서 여러 사용자가 동시에 docker run 명령을 실행해도 도커 데몬은 이를 순차적으로 처리하거나 병렬로 처리할 수 있다는 것이다.

 

 

 socket 이슈 파악해보기 

 

아래의 에러 메세지로 도커 데몬과 소켓을 관계를 알 수 있다.

# 도커 클라이언트가 도커 데몬과 통신할 수 없다는 메세지
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?

 

 

일단 메세지를 번역해보면 unix:///var/run/docker.sock에 있는 docker daemon에 연결할 수 없으므로 docker daemon이 돌고있는지 물어보고 있다.

 

하나하나 뜯어보자.

 

1. 'unix:///var/run/docker.sock'  => 도커 데몬이 클라이언트와 통신하기 위해 사용하는 Unix 도메인 소켓 파일의 위치이다.

 

2. 'Docker daemon at unix:///var/run/docker.sock'  => 도커 데몬이 /var/run/docker.sock 파일을 통해 클라이언트 요청을 수신하고 처리하고 있다는 것을 의미한다.

(도커 데몬이 기본적으로 unix 도메인 소켓을 사용하여 통신한다는 것과 특별한 설정 없이도 도커 데몬은 /var/run/docker.sock 파일을 통해 클라이언트 요청을 수신하도록 구성되어 있다는 것을 알 수 있다.)

 

3. 'Cannot connect' => 클라이언트가 이 소켓 파일에 연결할 수 없다는 것은 도커 데몬이 실행 중이지 않거나, 소켓 파일이 존재하지 않거나, 접근 권한 문제 도커 데몬이 다른 소켓을 사용하도록 설정되어 있다는 것을 의미한다. 

(도커 데몬이 정상적으로 실행되고 있다면, /var/run/docker.sock 파일이 존재하고, 이 파일을 통해 클라이언트와 데몬 간의 통신이 가능해야 한다.)

 

 

(3) 도커 데몬 데이터 

 

: Docker 데몬은 모든 데이터를 단일 디렉터리에 저장하는데, 컨테이너, 이미지, 볼륨, 호스트 설정, 서비스 정의 및 비밀을 포함하여 Docker와 관련된 모든 것을 포함한다. 

* 각 데몬마다 전용 디렉터리를 사용해야 한다.

* 두 개의 데몬이 동일한 디렉터리(예: NFS 공유)를 공유하는 경우 문제 해결이 어려운 오류가 발생한다.(ex. 동기화 문제)

 

* 도커 데몬이 사용하는 데이터 디렉터리  경로

/var/lib/docker

 

 

(4) 도커 데몬 옵션 

도커 데몬을 설정할 때는 여러 옵션을 사용할 수 있는데 예를 들어, 컨테이너 자동 시작, 리소스 제한, 스토리지 드라이버 구성(--storage-driver=overlay2), 컨테이너 보안 설정, 그리고 프록시 사용 등의 설정이 가능하다. 이들 옵션을 통해 도커 환경을 사용자의 요구에 맞게 세밀하게 구성할 수 있다. 

 

 

 

 

 

참고

https://docs.docker.com/config/daemon/

https://www.tiuweehan.com/blog/2020-09-10-docker-in-jenkins-in-docker/