티스토리 뷰

728x90
반응형

도커 데몬

도커의 구조

$ which docker

$ ps aux | grep docker

컨테이너나 이미지를 다루는 명령어는 /usr/bin/docker/에서 실행되지만 도커 엔진의 프로세스는 /usr/bin/dockerd 파일로 실행된다. 이는 docker 명령어가 실제 도커 엔진이 아닌 클라이언트로서의 도커이기 때문이다.

도커의 구조는 크게 두 가지로 나뉜다. 하나는 클라이언트로서의 도커이고, 다른 하나는 서버로서의 도커이다. 실제로 컨테이너를 생성하고 실행하며 이미지를 관리하는 주체는 도커 서버이고, 이는 dockerd 프로세스로서 동작한다. 도커 엔진은 외부에서 API 입력을 받아 도커 엔진의 기능을 수행하는데, 도커 프로세스가 실행되어 서버로서 입력을 받을 준비가 된 상태를 도커 데몬이라고 이야기한다.

다른 하나는 도커 클라이언트이다. 도커 데몬은 API 입력을 받아 도커 엔진의 기능을 수행하는데, 이 API를 사용할 수 있도록 CLI를 제공하는 것이 도커 클라이언트이다. 사용자가 docker로 시작하는 명령어를 입력하면 도커 클라이언트를 사용하는 것이며, 도커 클라이언트는 입력된 명령어를 로컬에 존재하는 도커 데몬에세 API로서 전달한다. 이때 도커 클라이언트는 /var/run/docker.sock에 위치한 유닉스 소켓을 통해 도커 데몬의 API를 호출한다.

image

도커 제어 순서

  1. docker ps
  2. /user/bin/docker가 /var/run/docker.sock 유닉스 소켓을 사용해 도커 데몬에게 명령어 전달
  3. 도커 데몬이 명령어 파싱후 작업 수행
  4. 수행 결과 도커 클라이언트에게 반환하고, 사용자에게 결과 출력



도커 데몬 실행

우분투에서는 자동으로 서비스로 등록되서 호스트가 재시작되더라도 자동으로 실행된다.

# 도커 데몬 시작 정지
$ service docker start 
$ service docker stop



도커 데몬 설정

도커 데몬은 dockerd로도 실행할 수 있다.

$ service docker stop
$ dockerd
$ dockerd --help

dockerd 명령어에 옵션을 주어서 도커 데몬을 실행을 하는것보다 설정파일을 사용하는것이 일반적이다.



도커 데몬 제어 : -H

-H 옵션은 도커 데몬의 API를 사용할 수 있는 방법을 추가한다. 아무런 옵션을 설정하지 않고 도커 데몬을 실행하면 도커 클라이언트인 /usr/bin/docker를 위한 유닉스 소켓인 /var/run/docker.sock를 사용한다. 즉 이 두 명령어의 차이는 없다.

$ dockerd 
$ dockerd -H unix:///var/run/docker.sock

-H에 IP 주소와 포트 번호를 입력하면 원격 API인 Docker Remote API로 도커를 제어할 수 있다. 즉 다른 서버에서 이쪽 도커 데몬을 제어할 수 있음. RESTful API 형식을 띠고 있으므로 HTTP 요청으로 도커를 제어한다. 예를 들면

$ dockerd -H tcp://0.0.0.0:2375

근데 이 옵션만 주면 유닉스 소켓이 비활성화되고 본인 서버의 도커 클라이언트 즉 docker 명령어를 못쓴다. 따라서 일반적으로 도커 클라이언트를 위한 유닉스 소켓과 Remote API를 위한 바인딩 주소를 동시에 설정한다.

$ dockerd -H unix:///var/run/docker.sock -H tcp://0.0.0.0:2375

-H로 Remote API를 사용하려면 cURL 같은 HTTP 요청 도구를 사용한다. 예를 들어, IP 주소가 192.168.00.100인 도커 호스트에서 -H로 Remote API를 허용했다면 다른 호스트에서 다음과 같이 Remote API를 사용할 수 있다.

# 데몬
$ dockerd -H tcp://192.168.99.100:2375

# 클라이언트
$ curl 192.168.99.100:2375/version --silent | python -m json.tool

-H tcp://192.168.99.100:2375라는 옵션을 사용해 192.168.99.100이라는 IP 주소와 2375번 포트로 도커 데몬을 바인딩했다. 그리고 다른 호스트에서 192.168.99.100:2375/version이라는 URL로 http 요청을 보내 도커 데몬의 버전을 확인했다. 이건 docker version 명령어와 같다.

셸의 환경변수를 설정해 원격에 있는 도커를 제어할수도 있다.

# 클라이언트
$ export DOCKER_HOST="tcp://192.168.99.100:2375"
$ docker version

또는 도커 클라리언트에 -H 옵션을 설정해 제어할 원격 도커 데몬을 설정할수도 있다.

$ docker -H tcp:///192.168.99.100:2375 version



스토리지 드라이버의 원리

이미지는 읽기 전용 파일로 사용되며 컨테이너는 이 이미지 위에 얇은 컨테이너 레이어를 생성함으로써 컨테이너의 고유한 공간을 생성한다.

실제로 컨테이너 내부에서 읽기와 새로운 파일 쓰기, 기존의 파일 쓰기 작업이 일어날 때는 드라이버에 따라 Copy-on-Write(CoW), Redirect-on-Write(RoW) 개념을 사용한다.

스냅숏의 기본 개념은 원본 파일은 읽기 전용으로 사용하되 이 파일이 변경되면 새로운 공간을 할당한다. 스토리지를 스냅숏으로 만들면 스냅숏 안에 어느 파일이 어디에 저장돼 있는지가 목록으로 저장된다. 그리고 이 스냅숏을 사용하다가 스냅숏 안의 파일에 변화가 생기면 변경된 내역을 따로 관리함으로써 스냅숏을 사용한다.

image

예를 들어, 위의 그림에서 A, B, C파일이 스냅숏으로 생성됐다면 이 파일에 읽기 작업을 수행하는 애플리케이션은 단순히 파일시스템의 원본 파일에 저근해 파일 내용을 읽으면 된다. 그러나 애플리케이션이 스냅숏의 A 파일에 쓰기 작업을 수행해야 할 경우에는 조금 상황이 달라진다. 원본 파일을 유지하면서도 변경된 사항을 저장할 수 있어야 한다. 이를 해결하는 방법에 따라 CoW, RoW로 나뉜다.

image

CoW는 스냅숏의 파일에 쓰기 작업을 수행할 때 스냅숏 공간에 원본 파일을 복사한 뒤 쓰기 요청을 반영한다. 이 과정에서 복사하기 위해 파일을 읽는 작업 한 번, 파일을 스냅숏 공간에 쓰고 변경된 사항을 쓰는 작업으로 총 2번의 쓰기 작업이 일어나므로 오버헤드가 발생한다.

image

RoW는 CoW와 다르게 한 번의 쓰기 작업만 일어난다. 이는 파일을 스냅숏 공간에 복사하는 것이 아니라 스냅숏에 기록된 원본 파일은 스냅숏 파일로 묶은(Freeze) 뒤 변경된 사항을 새로운 장소에 할당받아 덮어쓰는 형식이다. 스냅숏 파일은 그대로 사용하되, 새로운 블록은 변경 사항으로써 사용한다.

이를 도커 컨테이너와 이미지에 적용하면 이미지 레이어는 각 스냅숏에 해당하고, 커네이너는 이 스냅숏을 사용하는 변경점이다. 컨테이너 레이어에는 이전 이미지에서 변경된 사항이 저장돼 있으며, 컨테이너를 이미지로 만들면 변경된 사항이 스냅샷으로 생성되고 하나의 이미지 레이어로서 존재하게 된다.

image



도커 데몬 모니터링

모니터링 방법은 매우 많다. 제한적으로나마 도커 엔진 자체가 지원하는 모니터링 기능도 있고, 도커 프로젝트에서 지원하는 상용 솔루션 및 각종 오픈소스 대시보드도 있다. 도커 데몬 자체를 모니터링하는 방법을 알아보자.



도커 데몬 디버그 모드

$ dockerd -D

도커 데몬을 디버그 옵션으로 실행하면 Remote API의 입출력뿐만 아니라 로컬 도커 클라이언트에서 오가는 모든 명령어를 로그로 출력한다.

도커를 서비스로 구동했을 경우에는 로그 파일에서 이를 확인할 수 있다. (/var/log/upstart/docker.log)

events, stats, system df 명령어

events

도커 데몬에 어떤 일이 일어나고 있는지를 실시간 스트림 로그로 보여준다.

$ docker events
$ docker system events

attach, commit, copy, create 등의 컨테이너 관련 명령어, delete, import, load, pull, push 등의 이미지 관련 명령어, 볼륨, 네트워크, 플러그인 등에 관한 명령어의 수행 결과가 출력된다.

특정 항목에 대한 출력 결과만 보고 싶다면 --filter type=..처럼 옵션을 설정하면 된다.

$ docker events --filter 'type=image' 

stats

실행 중인 모든 컨테이너의 자원 사용량을 스트림으로 출력한다. stats 명령어도 다음과 같이 간단히 사용할 수 있다.

$ docker stats

실행 중인 모든 컨테이너의 CPU, 메모리 제한 및 사용량, 네트워크 입출력(I/O), 블록 입출력(하드웨어 입출력) 정보를 출력한다.

스트림이 아닌 한 번만 출력하는 방식으로 사용하고 싶다면 --no-stream 옵션을 추가한다.

system df

도커에서 사용하고 있는 이미지, 컨테이너, 로컬 볼륨의 총 개수 및 사용중인 개수, 크기, 삭제함으로써 확보 가능한 공간을 출력한다. RECLAIMABLE는 사용 중이지 않은 이미지를 삭제함으로써 확보할 수 있는 공간을 의미한다.

사용 중이지 않은 컨테이너와 볼륨은 각각 docker container prune, docker volume prune로 한꺼번에 삭제할 수 있다. docker image prune 명령어를 사용하면 사용 중이지 않은 댕글링 이미지를 삭제한다.



CAdvisor

구글이 만든 컨테이너 모니터링 도구로, 컨테이너로서 간단히 설치할 수 있고 컨테이너별 실시간 자원 사용량 및 도커 모니터링 정보 등을 시각화해서 보여준다.

$ docker run --volume=/:/rootfs:ro --volume=/var/run:/var/run:ro --volume=/sys:/sys:ro --volume=/var/lib/docker/:/var/lib/docker:ro --publish=8080:8080 --detach=true --name=cadvisor google/cadvisor:latest

생성된 모든 컨테이너의 자원 사용량을 확인할 수 있을 뿐만 아니라 도커 데몬의 정보, 상태, 호스트의 자원 사용량까지 한 번에 확인할 수 있다.

/docker를 클릭하면 도커 데몬의 정보, 컨테이너의 목록을 보여주는 페이지로 이동하고, Subcontainers 항목의 컨테이너 이름을 클릭하면 컨테이너의 자원 사용률도 실시간으로 확인할 수 있다.

CAdvisor의 대시보드는 60초간의 모니터링 정보만 보여주지만 influxDB나 Prometheus 등과 같이 사용하면 장기간의 모니터링 정보를 수집하고 분석할 수 있다.

CAdvisor를 생성할 떄 옵션으로 -v 호스트 볼륨을 공유했다. 도커 데몬의 정보를 가져올 수 있는 호스트의 모든 디렉터리를 CAdvisor 컨테이너에 볼륨으로서 마운트했기 떄문이다. /var/run에는 도커를 제어하기 위한 유닉스 소켓이 있고, /sys에는 도커 컨테이너를 위한 cgroup 정보가 저장돼 있으며 /var/lib/docker에는 도커의 컨테이너, 이미지 등이 파일로 존재한다.

/sys/fs 디렉터리에는 도커 컨테이너에게 격리된 자원을 제공하기 위한 cgroup 디렉터리가 존재한다. 이 디렉터리에는 CPU, Memory 등 컨테이너가 격리되어 할당받아야 할 자원이 디렉터리로서 다시 존재하고, 그 하위 디렉터리에는 각 컨테이너에게 할당된 cgroup 정보가 존재한다.

$ ls /sys/fs/cgroup/(cgroup 할당 자원 예를 들면 메모리, cpu 등)/docker/(컨테이너 ID)/

CAdvisor은 단일 도커 호스트만을 모니터링할 수 있다는 한계가 있다. 그래서 보통은 쿠버네티스나 스웜 모드 등과 같은 오케스트레이션 툴을 설치하고 프로메테우스, InfluxDB 등을 이용해 여러 호스트의 데이터를 수집하는 것이 일반적입니다.



Remote API 라이브러리를 이용한 도커 사용

도커 데몬 제어 옵션 -H 말고 도커를 제어하는 라이브러리를 사용해 도커를 원격으로 제어할 수 있다.

파이썬 라이브러리

파이썬은 리눅스에 기본적으로 설치되어 있고 도커 제어에 사용하는 파이썬 라이브러리는 docker-py이다. 라이브러리 관리 도구 pip를 설치하고, pip로 docker 라이브러리를 설치하자.

$ sudo apt-get install python3-pip -y
$ pip3 install docker
$ python3
>>> import docker
>>> client = docker.DockerClient(base_url='unix://var/run/docker.sock')
>>> client.info()
# TLS
# vi tls_docker_connect.py
import docker
tls_config = docker.tls.TLSConfig(
    client_cert=('/root/.docker/cert.pem', '/root/.docker/key.pem')
)
client = docker.DockerClient(base_url='unix://var/run/docker.sock', tls=tls_config)
print(client.info());
$ python3 tls_docker_connect.py

호스트의 80/tcp 포트를 컨테이너의 80번 포트에 연결하는 Nginx 컨테이너를 Detach 상태로 생성하고 시작하는 예시. docker run -d -p 80:80 nginx와 동일하다.

import docker

client = docker.DockerClient(base_url='unix://var/run/docker.sock')
container = client.containers.run('nginx',
        detach=True,
        ports={'80/tcp': 80})
print(f'Created container is : {container.name}, {container.id}')





출처
시작하세요! 도커/쿠버네티스(용찬호 저, 위키북스)
example

728x90
반응형
댓글
반응형
250x250
글 보관함
최근에 달린 댓글
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
Total
Today
Yesterday
링크