containerd

DevOpsコンテナcontainerdランタイムCNCFOCI準拠Kubernetes

DevOpsツール

containerd

概要

containerdは、業界標準のコンテナランタイムです。Kubernetesや他のオーケストレーターの基盤として動作し、高い信頼性とパフォーマンスを提供します。

詳細

containerd(コンテイナーディー)は、Cloud Native Computing Foundation(CNCF)の卒業プロジェクトとして開発された業界標準のコンテナランタイムです。元々はDockerのコンポーネントとして開発されましたが、2017年にCNCFに寄贈され、独立したプロジェクトとして発展。コンテナのライフサイクル管理(作成、実行、削除)、イメージ管理、ストレージ管理、ネットワーク管理を担当し、Kubernetesのデフォルトコンテナランタイムとして広く採用されています。OCI(Open Container Initiative)仕様に完全準拠し、runc、gVisor、Kata Containers等の多様なランタイムをサポート。gRPC APIによる高性能な統合、CRI(Container Runtime Interface)対応によるKubernetesとのシームレスな連携、スナップショット機能による効率的なイメージ管理を提供。軽量でセキュアな設計により、クラウドネイティブ環境でのコンテナ基盤として最適化されており、Google Kubernetes Engine、Amazon EKS、Azure AKS等の主要クラウドサービスで標準採用されています。

メリット・デメリット

メリット

  • 業界標準: CNCFプロジェクトとしての信頼性と継続性
  • 軽量: 最小限の機能でのシンプルな構成
  • 高パフォーマンス: gRPC APIによる高速通信
  • OCI準拠: 標準コンテナ仕様への完全対応
  • Kubernetes統合: CRI対応による最適化された連携
  • マルチランタイム: runc、gVisor、Kata等の選択肢
  • セキュリティ: 最小権限原則とnamespace分離
  • 拡張性: プラグインアーキテクチャによる機能拡張

デメリット

  • 直接利用困難: 開発者向けUI/CLI機能が限定的
  • 学習コスト: 低レベルAPIの理解が必要
  • デバッグ: Docker CLIほどの使いやすさなし
  • 機能制限: イメージビルド等の高レベル機能なし
  • ツール依存: 管理にはctr、crictl等の外部ツールが必要
  • ドキュメント: 開発者向け情報がDockerより少ない
  • エコシステム: サードパーティツールの対応状況
  • 移行コスト: Docker環境からの移行時の学習負荷

主要リンク

書き方の例

containerdのインストール・設定

# Ubuntu/Debianでのインストール
sudo apt-get update
sudo apt-get install containerd

# systemdサービス設定
sudo systemctl enable containerd
sudo systemctl start containerd
sudo systemctl status containerd

# 設定ファイル生成
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

# systemd cgroup使用(Kubernetes推奨)
sudo sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd

ctrコマンドによる基本操作

# イメージ操作
sudo ctr images pull docker.io/library/nginx:alpine
sudo ctr images list
sudo ctr images tag docker.io/library/nginx:alpine my-nginx:latest

# コンテナ作成
sudo ctr containers create docker.io/library/nginx:alpine my-nginx

# コンテナ実行
sudo ctr task start my-nginx
sudo ctr task list
sudo ctr task exec --exec-id bash-session my-nginx bash

# コンテナ停止・削除
sudo ctr task kill my-nginx
sudo ctr task delete my-nginx
sudo ctr containers delete my-nginx

Kubernetes統合(CRI設定)

# /etc/containerd/config.toml の重要設定
[grpc]
  address = "/run/containerd/containerd.sock"
  
[plugins]
  [plugins."io.containerd.grpc.v1.cri"]
    disable_tcp_service = true
    stream_server_address = "127.0.0.1"
    stream_server_port = "0"
    enable_selinux = false
    sandbox_image = "k8s.gcr.io/pause:3.6"
    
    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      
      [plugins."io.containerd.grpc.v1.cri".containerd.runtimes]
        [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc]
          runtime_type = "io.containerd.runc.v2"
          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            SystemdCgroup = true
            
    [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"]

crictl使用(Kubernetes CRI CLI)

# crictl設定
sudo crictl config --set runtime-endpoint=unix:///run/containerd/containerd.sock
sudo crictl config --set image-endpoint=unix:///run/containerd/containerd.sock

# Pod Sandbox作成
cat > pod-config.json << EOF
{
    "metadata": {
        "name": "nginx-sandbox",
        "namespace": "default",
        "attempt": 1,
        "uid": "hdishd83djaidwnduwk28bcsb"
    },
    "linux": {
        "cgroup_parent": "/default"
    }
}
EOF

SANDBOX_ID=$(sudo crictl runp pod-config.json)

# コンテナ設定
cat > container-config.json << EOF
{
    "metadata": {
        "name": "nginx"
    },
    "image":{
        "image": "nginx:alpine"
    },
    "linux": {
    }
}
EOF

# コンテナ実行
sudo crictl pull nginx:alpine
CONTAINER_ID=$(sudo crictl create $SANDBOX_ID container-config.json pod-config.json)
sudo crictl start $CONTAINER_ID

# 状態確認
sudo crictl pods
sudo crictl ps
sudo crictl logs $CONTAINER_ID

高度なランタイム設定(gVisor)

# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc]
  runtime_type = "io.containerd.runsc.v1"

[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runsc.options]
  TypeUrl = "io.containerd.runsc.v1.options"
  ConfigPath = "/etc/containerd/runsc.toml"
# Kubernetes Pod でgVisor使用
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
  annotations:
    io.kubernetes.cri.untrusted-workload: "true"
spec:
  runtimeClassName: gvisor
  containers:
  - name: app
    image: nginx:alpine

プライベートレジストリ設定

# /etc/containerd/config.toml
[plugins."io.containerd.grpc.v1.cri".registry]
  [plugins."io.containerd.grpc.v1.cri".registry.mirrors]
    [plugins."io.containerd.grpc.v1.cri".registry.mirrors."myregistry.example.com"]
      endpoint = ["https://myregistry.example.com"]
      
  [plugins."io.containerd.grpc.v1.cri".registry.configs]
    [plugins."io.containerd.grpc.v1.cri".registry.configs."myregistry.example.com".tls]
      insecure_skip_verify = false
      ca_file = "/etc/certs/registry-ca.pem"
      cert_file = "/etc/certs/registry-cert.pem"
      key_file = "/etc/certs/registry-key.pem"
      
    [plugins."io.containerd.grpc.v1.cri".registry.configs."myregistry.example.com".auth]
      username = "myuser"
      password = "mypassword"

スナップショット管理

# スナップショット一覧
sudo ctr snapshots list

# イメージのスナップショット使用状況
sudo ctr images list -q | xargs sudo ctr images usage

# 未使用スナップショット削除
sudo ctr images prune
sudo ctr snapshots prune

# ガベージコレクション
sudo ctr cleanup

モニタリング・デバッグ

# containerd プロセス情報
sudo systemctl status containerd
sudo journalctl -u containerd -f

# gRPC APIエンドポイント確認
sudo netstat -nlp | grep containerd

# デバッグログ有効化
sudo containerd --log-level debug

# メトリクス収集(Prometheus形式)
curl http://localhost:1234/v1/metrics

# ctr でのデバッグ
sudo ctr --debug containers list
sudo ctr events --timeout 30s

# namespace 管理
sudo ctr namespace list
sudo ctr --namespace k8s.io containers list

systemd service unit

# /etc/systemd/system/containerd.service
[Unit]
Description=containerd container runtime
Documentation=https://containerd.io
After=network.target local-fs.target

[Service]
ExecStartPre=-/sbin/modprobe overlay
ExecStart=/usr/local/bin/containerd
Type=notify
Delegate=yes
KillMode=process
Restart=always
RestartSec=5
LimitNPROC=infinity
LimitCORE=infinity
LimitNOFILE=1048576
TasksMax=infinity
OOMScoreAdjust=-999

[Install]
WantedBy=multi-user.target