containerd

DevOpscontainerscontainerdruntimeCNCFOCI compliantKubernetes

DevOps Tool

containerd

Overview

containerd is an industry-standard container runtime that operates as the foundation for Kubernetes and other orchestrators, providing high reliability and performance with CRI compliance for easy Kubernetes integration.

Details

containerd is an industry-standard container runtime developed as a graduated project of the Cloud Native Computing Foundation (CNCF). Originally developed as a Docker component, it was donated to CNCF in 2017 and evolved as an independent project. It handles container lifecycle management (creation, execution, deletion), image management, storage management, and network management, and is widely adopted as the default container runtime for Kubernetes. Fully compliant with OCI (Open Container Initiative) specifications, it supports various runtimes including runc, gVisor, and Kata Containers. It provides high-performance integration through gRPC API, seamless integration with Kubernetes through CRI (Container Runtime Interface) support, and efficient image management through snapshot functionality. With its lightweight and secure design optimized for cloud-native environments, it's adopted as standard in major cloud services including Google Kubernetes Engine, Amazon EKS, and Azure AKS.

Advantages and Disadvantages

Advantages

  • Industry standard: Reliability and continuity as a CNCF project
  • Lightweight: Simple configuration with minimal features
  • High performance: Fast communication through gRPC API
  • OCI compliant: Full compliance with standard container specifications
  • Kubernetes integration: Optimized integration through CRI support
  • Multi-runtime: Choice of runc, gVisor, Kata, etc.
  • Security: Principle of least privilege and namespace isolation
  • Extensibility: Feature extension through plugin architecture

Disadvantages

  • Direct use difficulty: Limited developer-facing UI/CLI features
  • Learning curve: Requires understanding of low-level APIs
  • Debugging: Not as user-friendly as Docker CLI
  • Feature limitations: No high-level features like image building
  • Tool dependency: Requires external tools like ctr, crictl for management
  • Documentation: Less developer-oriented information than Docker
  • Ecosystem: Third-party tool support status
  • Migration cost: Learning load when migrating from Docker environments

Key Links

Code Examples

containerd Installation and Configuration

# Install on Ubuntu/Debian
sudo apt-get update
sudo apt-get install containerd

# systemd service configuration
sudo systemctl enable containerd
sudo systemctl start containerd
sudo systemctl status containerd

# Generate configuration file
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml

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

Basic Operations with ctr Command

# Image operations
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

# Container creation
sudo ctr containers create docker.io/library/nginx:alpine my-nginx

# Container execution
sudo ctr task start my-nginx
sudo ctr task list
sudo ctr task exec --exec-id bash-session my-nginx bash

# Container stop and delete
sudo ctr task kill my-nginx
sudo ctr task delete my-nginx
sudo ctr containers delete my-nginx

Kubernetes Integration (CRI Configuration)

# Important settings in /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"]

Using crictl (Kubernetes CRI CLI)

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

# Create 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)

# Container configuration
cat > container-config.json << EOF
{
    "metadata": {
        "name": "nginx"
    },
    "image":{
        "image": "nginx:alpine"
    },
    "linux": {
    }
}
EOF

# Container execution
sudo crictl pull nginx:alpine
CONTAINER_ID=$(sudo crictl create $SANDBOX_ID container-config.json pod-config.json)
sudo crictl start $CONTAINER_ID

# Status check
sudo crictl pods
sudo crictl ps
sudo crictl logs $CONTAINER_ID

Advanced Runtime Configuration (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"
# Using gVisor in Kubernetes Pod
apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
  annotations:
    io.kubernetes.cri.untrusted-workload: "true"
spec:
  runtimeClassName: gvisor
  containers:
  - name: app
    image: nginx:alpine

Private Registry Configuration

# /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"

Snapshot Management

# List snapshots
sudo ctr snapshots list

# Image snapshot usage
sudo ctr images list -q | xargs sudo ctr images usage

# Delete unused snapshots
sudo ctr images prune
sudo ctr snapshots prune

# Garbage collection
sudo ctr cleanup

Monitoring and Debugging

# containerd process information
sudo systemctl status containerd
sudo journalctl -u containerd -f

# Check gRPC API endpoint
sudo netstat -nlp | grep containerd

# Enable debug logging
sudo containerd --log-level debug

# Metrics collection (Prometheus format)
curl http://localhost:1234/v1/metrics

# Debugging with ctr
sudo ctr --debug containers list
sudo ctr events --timeout 30s

# Namespace management
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