본문 바로가기
  • 오늘처럼
소프트웨어 아키텍처/Containerd

Containerd 설치 및 설정

by bluefriday 2021. 9. 4.
반응형

 

1. containerd 

containerd는 docker를 설치하게 되면 함께 설치되는 런타임 패키지이지만, 독립적으로 설치 및 설정도 가능하다. docker를 설치하지 않고 kubernetes 클러스터를 구축하려 하는 경우나, 컨테이너 빌드 도구 없이 단순히 컨테이너를 실행하기만 하는 경우를 위하여 이번에는 containerd를 설치하고 설정하는 방법을 정리해본다.

 

2. conatinerd 다운로드

만약 Ubuntu Trusty 나 Debian jessie 이하 버전을 사용하고 있다면, 라이브러리 의존성을 위해 libseccomp2 라이브러리가 필요하다. 아래와 같이 apt-get 등을 이용하여 설치하거나 바이너리파일을 다운받아서 미리 준비해두자.

sudo apt-get update
sudo apt-get install libseccomp2

conatinerd github release 페이지(https://github.com/containerd/containerd/releases)에서 최신 containerd 압축파일을 다운로드 받는다. linux, windows 환경에 따라 파일을 나눠 구분하므로 사용하려는 운영체제에 맞는 파일을 다운 받아야 한다. 여기서는 1.5.5 버전의 linux 용 containerd 패키지로 진행하나, 이 자료를 참조하는 시점에 따라 최신 버전을 확인하도록 하자.

wget https://github.com/containerd/containerd/releases/download/v1.5.5/containerd-1.5.5-linux-amd64.tar.gz

상단과 같이 링크 주소를 복사하여 wget 으로 받거나, 웹 브라우저에서 다운로드 받아서 물리파일을 해당 OS 에 옮겨둘 수도 있다.

 

3. 압축해제 및 파일 이동

이제 conatinerd 압축파일을 해제한 뒤에 프로그램 실행 디렉토리(/usr/bin/)로 옮겨둔다.

tar -xvf https://github.com/containerd/containerd/releases/download/v1.5.5/containerd-1.5.5-linux-amd64.tar.gz
cd containerd-1.5.5-linux-amd64/* /usr/bin/

 

4. 설정파일 생성 및 변경

설치를 완료한 후 설정파일을 생성하고 필요한 설정 등을 추가해줘야 한다. 이를 위해 containerd 에서 제공하는 config 명령을 사용하여 default config 정보를 얻는다. 먼저 containerd 의 default config 디렉토리를 만들어준 후, 앞의 config 명령의 결과를 표준 출력이 아닌 설정 파일로 저장한다.

mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml

 

다음은 containerd 의 default config 설정파일이다. 몇가지 기본적인 설정들을 살펴보자.

version = 2
root = "/var/lib/containerd"
state = "/run/containerd"
plugin_dir = ""
disabled_plugins = []
required_plugins = []
oom_score = 0

[grpc]
  address = "/run/containerd/containerd.sock"
  tcp_address = ""
  tcp_tls_cert = ""
  tcp_tls_key = ""
  uid = 0
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216

[ttrpc]
  address = ""
  uid = 0
  gid = 0

[debug]
  address = ""
  uid = 0
  gid = 0
  level = ""

[metrics]
  address = ""
  grpc_histogram = false

[cgroup]
  path = ""

[timeouts]
  "io.containerd.timeout.shim.cleanup" = "5s"
  "io.containerd.timeout.shim.load" = "5s"
  "io.containerd.timeout.shim.shutdown" = "3s"
  "io.containerd.timeout.task.state" = "2s"

[plugins]
  [plugins."io.containerd.gc.v1.scheduler"]
    pause_threshold = 0.02
    deletion_threshold = 0
    mutation_threshold = 100
    schedule_delay = "0s"
    startup_delay = "100ms"
  [plugins."io.containerd.grpc.v1.cri"]
    disable_tcp_service = true
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    stream_idle_timeout = "4h0m0s"
    enable_selinux = false
    selinux_category_range = 1024
    sandbox_image = "k8s.gcr.io/pause:3.2"
    stats_collect_period = 10
    systemd_cgroup = false
    enable_tls_streaming = false
    max_container_log_line_size = 16384
    disable_cgroup = false
    disable_apparmor = false
    restrict_oom_score_adj = false
    max_concurrent_downloads = 3
    disable_proc_mount = false
    unset_seccomp_profile = ""
    tolerate_missing_hugetlb_controller = true
    disable_hugetlb_controller = true
    ignore_image_defined_volumes = false
    [plugins."io.containerd.grpc.v1.cri".containerd]
      snapshotter = "overlayfs"
      default_runtime_name = "runc"
      no_pivot = false
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
      [plugins."io.containerd.grpc.v1.cri".containerd.default_runtime]
        runtime_type = ""
        runtime_engine = ""
        runtime_root = ""
        privileged_without_host_devices = false
        base_runtime_spec = ""
      [plugins."io.containerd.grpc.v1.cri".containerd.untrusted_workload_runtime]
        runtime_type = ""
        runtime_engine = ""
        runtime_root = ""
        privileged_without_host_devices = false
        base_runtime_spec = ""
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          runtime_type = "io.containerd.runc.v2"
          runtime_engine = ""
          runtime_root = ""
          privileged_without_host_devices = false
          base_runtime_spec = ""
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
      max_conf_num = 1
      conf_template = ""
    [plugins."io.containerd.grpc.v1.cri".registry]
      [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."docker.io"]
          endpoint = ["https://registry-1.docker.io"]
    [plugins."io.containerd.grpc.v1.cri".image_decryption]
      key_model = ""
    [plugins."io.containerd.grpc.v1.cri".x509_key_pair_streaming]
      tls_cert_file = ""
      tls_key_file = ""
  [plugins."io.containerd.internal.v1.opt"]
    path = "/opt/containerd"
  [plugins."io.containerd.internal.v1.restart"]
    interval = "10s"
  [plugins."io.containerd.metadata.v1.bolt"]
    content_sharing_policy = "shared"
  [plugins."io.containerd.monitor.v1.cgroups"]
    no_prometheus = false
  [plugins."io.containerd.runtime.v1.linux"]
    shim = "containerd-shim"
    runtime = "runc"
    runtime_root = ""
    no_shim = false
    shim_debug = false
  [plugins."io.containerd.runtime.v2.task"]
    platforms = ["linux/amd64"]
  [plugins."io.containerd.service.v1.diff-service"]
    default = ["walking"]
  [plugins."io.containerd.snapshotter.v1.devmapper"]
    root_path = ""
    pool_name = ""
    base_image_size = ""
    async_remove = false


4-1. 데이터 디렉토리 설정

...
root = "/var/lib/containerd"
...

설정 파일 상단의 전역 레벨에서 "root" 키의 값으로 데이터 디렉토리를 지정할 수 있다.

도커의 "/var/lib/docker", mysql 의 "/var/lib/mysql" 과 같이 containerd 와 관련된 데이터를 저장하는 디렉토리이며, containerd를 통하여 받은 컨테이너 이미지, 실행되는 컨테이너에 대한 정보 등이 저장되는 중요 경로이다.

컨테이너 이미지 사용량이 많을 것으로 예상되는 경우 블록스토리지 등으로 따로 할당하여, 해당 경로의 disk 를 충분히 확보하도록 한다. (기본값은 하단과 같이 "/var/lib/contaienrd" 이다.) 

 

4-2. sandbox 이미지 지정

[plugins]
  ...
  [plugins."io.containerd.grpc.v1.cri"]
    ...
    sandbox_image = "k8s.gcr.io/pause:3.2"
    stats_collect_period = 10
	...

containerd 의 커맨드라인 툴인 ctr 등을 이용하여 kubernetes pod를 구동하거나 혹은 k8s 의 런타임으로서 containerd 를 사용하여 pod를 구동할 경우 pod의 sandbox 로 사용 될 이미지를 지정한다.

public, private 레지스트리의 이미지를 모두 지정이 가능하지만 private 레지스트리의 경우 인증을 지원하지 않으므로 인증 없이 image pulling 이 가능한 이미지를 지정해야 한다.

 

4-3. cni 관련 설정

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    ...
    [plugins."io.containerd.grpc.v1.cri".cni]
      bin_dir = "/opt/cni/bin"
      conf_dir = "/etc/cni/net.d"
      max_conf_num = 1
      conf_template = ""
    ...

containerd 가 런타임으로서 컨테이너를 생성하면서, 네트워크 리소스를 부여할 수 있도록 cni 플러그인에 대한 정보를 지정한다. cni 의 경우 별도의 설정을 하지 않았다면 기본적으로 '/opt/cni/bin', '/etc/cni/net.d' 디렉토리에 생성이 되며, containerd 의 default 경로도 이와 동일하게 지정되어 있다.

 

4-4. private registry 설정

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    ...
    [plugins.cri.registry]
      [plugins.cri.registry.mirrors]
        [plugins.cri.registry.mirrors."hello.world.com"]
          endpoint = ["https://hello.world.com"]
        [plugins.cri.registry.auths."hello.world.com"]
          username = "helloworld"
          password = "hellotest!"
    ...

private registry 설정의 경우, sandbox 설정과는 달리 basic auth 인증을 지원한다. (키를 통한 인증은 확인필요)

위 표와 같이 접근하려는 private registry 를 endpoint 로 지정한 후에 username/password 를 지정하여주자.

 

4-5. default runtime 지정

[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    ...
    [plugins."io.containerd.grpc.v1.cri".containerd]
      snapshotter = "overlayfs"
      default_runtime_name = "nvidia-container-runtime"
      no_pivot = false
      disable_snapshot_annotations = true
      discard_unpacked_layers = false
	  ...
  [plugins."io.containerd.runtime.v1.linux"]
    shim = "containerd-shim"
    runtime = "nvidia-container-runtime"
    runtime_root = ""
    no_shim = false
    shim_debug = false

GPU container를 사용하기 위하여 nvidia-container-runtime 을 라이브러리로 설치한 경우, containerd 의 default runtime 설정도 nvidia-container-runtime 으로 변경해줘야 한다. 상단 코드를 참조하도록 한다.

 

5. 재기동 후 구동 확인

systemctl enable containerd
systemctl daemon-reload
systemctl start containerd  ### systemctl restart containerd (이미 구동한 경우)
systemctl status containerd

필요한 설정을 지정한 후 containerd 프로세스를 구동한다. 만약 apt 등의 설치 유틸로 설치하여 이미 프로세스가 구동된 경우, 설정 적용을 위하여 재시작이 필요하다. 위 명령을 참고하여 containerd 설정을 적용 후 프로세스의 상태를 확인한다.

 

댓글