containerd 配置参数详解

详解 containerd 在 Ubuntu 22.04 上的 config.toml 全部核心参数(含 1.7.29 真实默认值)、启动 flags、内容与快照驱动、镜像仓库加速(daocloud 实测)、SystemdCgroup 与 CRI 集成及生产最佳实践

containerdcontainerd运行时配置详解运维2026/10/09

containerd 配置参数详解

目标:本文以 Ubuntu 22.04.5 LTS x86_64 + containerd.io v1.7.29 实测为准,系统讲解 containerd 的配置体系:config.toml 单文件配置、启动 flags、运行环境变量、内容与快照驱动、镜像仓库加速、SystemdCgroup 与 CRI 集成。文中所有默认值均来自 containerd config default 的真实输出,请在对应服务器上逐条实测核对。

一、概述

1.1 环境信息

项值
操作系统Ubuntu 22.04.5 LTS(Linux 5.15.0,x86_64)
架构amd64(x86_64)
操作账号root(安装/配置/启动一律 root 执行)
containerd 版本containerd.io v1.7.29(442cb34b)
客户端ctr v1.7.29、crictl(CI 由 CRI 传入使用)
主配置文件/etc/containerd/config.toml
根数据目录(root)/var/lib/containerd
运行时目录(state)/run/containerd
gRPC socket/run/containerd/containerd.sock
镜像加速配置目录/etc/containerd/certs.d/docker.io/hosts.toml

💡 说明:root 目录存放内容、元数据、快照等持久数据;state 目录存放 socket、运行中任务等运行时瞬时数据。二者默认值见 2.1。

1.2 配置承载方式:单文件 + 启动 flags + 环境变量

containerd 守护进程的配置体系由三层组成,优先级从低到高为:

  1. 内置默认值:未指定任何配置时使用的出厂默认。
  2. /etc/containerd/config.toml 主配置:唯一配置文件,绝大多数运行参数集中于此。
  3. 启动 flags:containerd [flags] 命令行参数,可覆盖主配置中的少量关键项(--root、--state、--log-level、--config、--address)。

关于环境变量:实测 env | grep -i containerd 无任何 CONTAINERD_* 运行配置环境变量。containerd 不像部分守护进程那样提供环境变量注入配置的通道,运行配置完全由 config.toml 与启动 flags 决定。这类动态值(如每节点不同的日志目录)一般通过外部渲染 config.toml 时填入,而非进程环境变量。

1.3 生成默认配置:containerd config default

containerd config default 输出一份完整的、可直接落盘的出厂配置,是「增量式用 import、或全量接管」两种配置策略的起点。先备份再生成:

containerd config default > /etc/containerd/config.toml

顶层默认值(真实输出,节选):

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

💡 说明:1.7.x 默认走 version = 2 的 TOML 结构;containerd config dump 输出「最终生效配置」(含所有 import 子配置合并后的结果),用于排查最终落地的真实值。

二、config.toml 详解

2.1 顶层全局参数(version / root / state)

参数默认值含义
version2配置文件 schema 版本;1.x 对应旧版扁平键,2 为当前推荐结构
root/var/lib/containerdcontainerd 持久数据根目录(内容、元数据 bolt 库、快照、CRI 状态)
state/run/containerd运行时瞬时数据目录(socket、运行中任务的 shim 状态)
temp空临时目录;为空时使用 state 下的临时子目录
oom_score0守护进程自身的 OOM 评分附加值
disabled_plugins[]启动时禁用的内置插件 ID 列表,如 ["io.containerd.grpc.v1.cri"]
required_plugins[]缺失即启动失败的必需插件 ID 列表
imports[]额外导入的配置片段文件路径(支持 glob),用于拆分/复用配置
plugin_dir""外部插件(动态库)搜索目录,一般保持空

⚠️ 注意:root 与 state 通常保持默认;磁盘空间规划与备份都以 root 为锚点,变更后需同步调整文件系统挂载。

2.2 [grpc]:socket 与服务端约束

[grpc]
  address = "/run/containerd/containerd.sock"
  gid = 0
  max_recv_message_size = 16777216
  max_send_message_size = 16777216
  tcp_address = ""
  tcp_tls_ca = ""
  tcp_tls_cert = ""
  tcp_tls_key = ""
  uid = 0
参数默认值含义
address/run/containerd/containerd.sock本地 Unix socket 监听路径(ctr/crictl/kubelet 都连它)
max_recv_message_size16777216(16 MiB)接收的单条 gRPC 消息上限;拉大镜像元数据/大 payload 时按需调大
max_send_message_size16777216(16 MiB)发送单条消息上限
tcp_address""非空则额外监听 TCP(如 127.0.0.1:2376)暴露 gRPC
tcp_tls_ca/cert/key""TCP 监听时的 TLS 证书链配置

⚠️ 注意:不要随意把 max_recv_message_size 调得过大;当 ctr images pull 报 rpc error: code = ResourceExhausted 或 grpc: received message larger than max 时,才考虑按需调大。

2.3 [debug] 与 [metrics]:调试与指标接口

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

[metrics]
  address = ""
  grpc_histogram = false
段参数默认值含义
[debug]address""非空则监听 debug HTTP/pprof 端点(如 /run/containerd/debug.sock)
[debug]level""debug socket 的日志级别开关
[metrics]address""非空则暴露 Prometheus 指标端点(如 127.0.0.1:1338)
[metrics]grpc_histogramfalse是否采集 gRPC 调用直方图

默认两项都为空即调试/指标接口默认关闭,需要在生产观测时显式开启,例如:

[metrics]
  address = "127.0.0.1:1338"

[debug]
  address = "/run/containerd/debug.sock"

2.4 [cri] section:CRI 运行时核心段

containerd 作为 Kubernetes CRI 运行时,关键参数都位于 [plugins."io.containerd.grpc.v1.cri"] 下(真实默认值节选):

  [plugins."io.containerd.grpc.v1.cri"]
    image_pull_progress_timeout = "5m0s"
    max_concurrent_downloads = 3
    max_container_log_line_size = 16384
    sandbox_image = "registry.k8s.io/pause:3.8"
    stats_collect_period = 10
    stream_idle_timeout = "4h0m0s"
    stream_server_address = "127.0.0.1"
    systemd_cgroup = false
参数默认值含义
sandbox_imageregistry.k8s.io/pause:3.8Pod 沙箱 pause 镜像,离线/内网需显式改为内网仓库地址
systemd_cgroupfalseCRI 工作负载是否配合 systemd cgroup 驱动(见六章)
max_concurrent_downloads3单节点并发镜像拉取数
max_container_log_line_size16384(16 KiB)单条日志行最大字节,超过即截断
stats_collect_period10每工作负载每隔多少秒采样一次资源统计
image_pull_progress_timeout5m0s镜像拉取进度超时(卡住时判定失败)
stream_idle_timeout4h0m0sexec/attach 流空闲超时
stream_server_address127.0.0.1CRI 流服务器监听地址
stream_server_port"0"0 表示随机端口

2.5 snapshotter 与 SystemdCgroup:两个最常改的开关

① snapshotter(默认 overlayfs)

containerd config default 中,CRI 段与解包段默认快照驱动都是 overlayfs:

  [plugins."io.containerd.grpc.v1.cri".containerd]
    snapshotter = "overlayfs"

  [plugins."io.containerd.transfer.v1.local".unpack_config]
    differ = "walking"
    snapshotter = "overlayfs"

💡 说明:Ubuntu 22.04 上 overlayfs(overlay2)即默认驱动,无需修改;仅当宿主机文件系统不支持 overlay 或需回退时才改用 native(见四章)。

② SystemdCgroup

Ubuntu 22.04 默认以 systemd 作为 cgroup 管理器(cgroup v2),需把 runc 侧从 false 改为 true(见六章)。它在 [runtimes.runc] 段:

    [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
      BinaryName = ""
      CriuImagePath = ""
      CriuPath = ""
      CriuWorkPath = ""
      IoGid = 0
      IoUid = 0
      NoNewKeyring = false
      NoPivotRoot = false
      Root = ""
      ShimCgroup = ""
      SystemdCgroup = false
参数默认值含义
SystemdCgroupfalserunc 是否走 systemd 的 cgroup 驱动
BinaryName""自定义 runc 可执行名(空用内置)
ShimCgroup""shim 所在 cgroup 父路径
NoNewKeyring / NoPivotRootfalse关闭 session keyring / 关闭 pivot_root

2.6 registry config_path:镜像加速入口

CRI 段默认 config_path 为空,指向镜像仓库域名级配置目录(hosts.toml)的基路径:

    [plugins."io.containerd.grpc.v1.cri".registry]
      config_path = ""
  • 1.7.x 默认空,需显式设为 /etc/containerd/certs.d;
  • 2.x 默认已指向 /etc/containerd/certs.d。

在该目录下按 仓库域名/hosts.toml 组织域名级镜像配置(见第五章):

/etc/containerd/certs.d/
└── docker.io/
    └── hosts.toml

三、containerd 命令 flags

containerd 守护进程的全局 flag 是少数可覆盖配置的启动入口。真实 containerd --help 全局选项:

GLOBAL OPTIONS:
   --config value, -c value     Path to the configuration file (default: "/etc/containerd/config.toml")
   --log-level value, -l value  Set the logging level [trace, debug, info, warn, error, fatal, panic]
   --address value, -a value    Address for containerd's GRPC server
   --root value                 containerd root directory
   --state value                containerd state directory
   --help, -h                   show help
   --version, -v                print the version
flag缩写默认值说明
--config-c/etc/containerd/config.toml指定配置文件路径
--log-level-l未默认日志级别:trace/debug/info/warn/error/fatal/panic
--address-a由 config 决定覆盖 gRPC socket 地址
--root无/var/lib/containerd覆盖持久数据根目录
--state无/run/containerd覆盖运行时瞬时目录
--version-v—打印版本

systemd 启动时通过 containerd 二进制读取 /etc/containerd/config.toml,无需显式 -c。若要临时以指定配置文件前台启动做验证:

containerd --config /etc/containerd/config.toml --log-level debug

💡 说明:containerd 顶层子命令包括 config(配置生成/导出)、publish、oci-hook、help;不带子命令运行即以前台启动守护进程。

3.1 config 子命令:default 与 dump

NAME:
   containerd config - Information on the containerd config

COMMANDS:
   default  See the output of the default config
   dump     See the output of the final main config with imported in subconfig files
  • containerd config default:输出出厂默认配置(增量式改造的模板);
  • containerd config dump:输出加载全部 import 后最终生效的配置(排查落地值用)。

四、内容与快照

4.1 内容存储(content store)

镜像的全部内容以「内容寻址」方式落盘到 root 下:

/var/lib/containerd/
├── io.containerd.content.v1.content/
│   ├── blobs/                         # 以 sha256 命名的镜像层 blob
│   └── ingest/                        # 正在写入的临时 blob
├── io.containerd.metadata.v1.bolt/    # bolt 元数据(镜像/内容索引)
├── io.containerd.grpc.v1.cri/         # CRI 相关状态
├── io.containerd.runtime.v2.task/     # 运行中任务的 shim 状态
├── io.containerd.snapshotter.v1.overlayfs/
└── io.containerd.snapshotter.v1.native/
  • blobs 用哈希寻址,同一层多处引用只存一份,天然去重;
  • 元数据存放于 boltdb(io.containerd.metadata.v1.bolt),对应 [plugins."io.containerd.metadata.v1.bolt"].content_sharing_policy 默认 shared(多个命名空间共享内容层)。

4.2 快照驱动(snapshotters)

快照驱动目录标识特点适用
overlayfssnapshotter.v1.overlayfsoverlay 挂载合并层,省磁盘、共享只读底层默认驱动,Ubuntu 22.04 直接用
nativesnapshotter.v1.native每层独立目录全量复制,无共享合并文件系统不支持 overlay 或需兼容时的回退

① 默认 overlayfs(推荐):低层为只读共享,工作负载运行时读写进入可写层,镜像拉取解包走 overlay。对应参数(保持默认即可,无需改动):

  [plugins."io.containerd.snapshotter.v1.overlayfs"]
    mount_options = []
    root_path = ""
    sync_remove = false
    upperdir_label = false

② native 回退:某类文件系统(如部分网络盘)不支持 overlay 挂载时报挂载拒绝(operation not permitted)错误,此时可整体切换为 native。

查看当前生效驱动:

grep -n "snapshotter" /etc/containerd/config.toml | grep -vE "^#|#" | head

4.3 磁盘布局核对

确认内容与快照实际落盘位置:

ls -la /var/lib/containerd/io.containerd.content.v1.content/blobs/
ls -la /var/lib/containerd/io.containerd.snapshotter.v1.overlayfs/
du -sh /var/lib/containerd

⚠️ 注意:root 目录要有足够的磁盘空间并纳入备份/监控;镜像层 blob 长期累积时通过 GC(gc.scheduler 插件)按阈值回收,见七章。

五、镜像仓库配置

5.1 hosts.toml:域名级配置

containerd 2.x(以及指定 config_path 的 1.7.x)用 hosts.toml 按「仓库域名」配置镜像拉取行为。默认 config_path 为空,1.7.x 先启用:

mkdir -p /etc/containerd/certs.d/docker.io
grep -n 'config_path = ""' /etc/containerd/config.toml | head -1
sed -i 's#\tconfig_path = ""#\tconfig_path = "/etc/containerd/certs.d"#' /etc/containerd/config.toml

💡 说明:sed 前用 grep -n 定位行号核对缩进;2.x 默认已是 /etc/containerd/certs.d,无需此步。

5.2 mirror:镜像加速(daocloud 实测)

在国内网络直连 docker.io 常被阻断(实测报 dial tcp 67.228.235.91:443: connect: connection refused)。为 docker.io 配置镜像源:

# /etc/containerd/certs.d/docker.io/hosts.toml
server = "https://docker.io"

[host."https://docker.m.daocloud.io"]
  capabilities = ["pull", "resolve"]
  • server:本文件管辖的仓库地址;
  • [host."https://镜像站"]:候选上游(按文件中实际 URL 写,如上面 daocloud 镜像站),按顺序尝试;
  • capabilities:声明上游支持的能力(pull 拉取、resolve 解析,可含 push 上传)。

重启并实测拉取:

systemctl restart containerd
ctr images pull docker.m.daocloud.io/library/busybox:latest

真实回显:

Completed pull from OCI Registry (docker.m.daocloud.io/library/busybox:latest)
elapsed: 12.2s  total:  2.1 Mi  (180.0 KiB/s)

5.3 auth:私有仓库认证

同一 hosts.toml 中为私有仓库标注 username/password(落实际值,不占位):

# /etc/containerd/certs.d/registry.example.com/hosts.toml
server = "https://registry.example.com"

[host."https://registry.example.com"]
  capabilities = ["pull", "resolve"]
  username = "root"
  password = "q1w2e3r4"
  • 认证信息逐 hosts.toml 声明,仅对对应域名生效;
  • capabilities 不影响认证,username/password 用于对私有仓库做 Basic 认证。

⚠️ 注意:hosts.toml 中的明文凭据是节点本地配置;生产建议将敏感凭据改由注入/受管密钥渠道下发,而非明文维护,但文档示例落实际值以便直接可跑。

六、SystemdCgroup 与 CRI 集成

6.1 为什么改 SystemdCgroup

Ubuntu 22.04 使用 systemd 作为 init 与 cgroup 管理器(cgroup v2)。Kubernetes 侧 kubelet 默认 --cgroup-driver=systemd。若 containerd 的 runc 仍用 cgroupfs 驱动(SystemdCgroup=false),会与 systemd 各自主管同一批 cgroup,造成资源统计/回收冲突,节点负载高时甚至出现 cgroup 目录泄漏。

6.2 修改与验证

把 runc options.SystemdCgroup 由 false 改为 true:

grep -n "SystemdCgroup" /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
grep -n "SystemdCgroup" /etc/containerd/config.toml
systemctl daemon-reload
systemctl restart containerd

改动后核对:

grep -n "SystemdCgroup" /etc/containerd/config.toml   # 应为 true
containerd config dump | grep -A3 'runtimes.runc.options' | grep SystemdCgroup

6.3 与 kubelet 对齐要求

组件必改项目标值
containerdruntimes.runc.options.SystemdCgrouptrue
kubelet--cgroup-driversystemd
CRI 运行时 socketkubelet --container-runtime-endpointunix:///run/containerd/containerd.sock

⚠️ 注意:三处 cgroup 驱动必须一致(都用 systemd),否则 kubelet 上报 Failed to start container / cgroup 驱动不匹配类错误。CRI 侧 CRI socket 即 /run/containerd/containerd.sock。

七、生产最佳实践

场景配置项建议
私有网络/内网(16GB 内存、SSD、多工作负载)[cri].sandbox_image改为内网 pause 镜像地址,避免启动时依赖公网
国内/受限网络[cri].registry.config_path + hosts.toml配 docker.io mirror(daocloud),见五章
cgroup v2 真机SystemdCgrouptrue 并与 kubelet 对齐(六章)
观测[metrics].address开启 127.0.0.1:1338 接入 Prometheus
磁盘root 所在文件系统预留充足空间、纳入监控与备份
日志[debug].level / -l默认 info;排障临时 debug
GC[plugins."io.containerd.gc.v1.scheduler"]默认 mutation_threshold=100、pause_threshold=0.02,按负载微调
配置可追溯containerd config dump上线前后各导出一次比对

生产常用 GC 与调度默认值(节选,真实默认):

  [plugins."io.containerd.gc.v1.scheduler"]
    deletion_threshold = 0
    mutation_threshold = 100
    pause_threshold = 0.02
    schedule_delay = "0s"
    startup_delay = "100ms"

💡 说明:mutation_threshold=100 为每次待回收对象数触发 GC 的阈值,pause_threshold=0.02 为 GC 执行时暂停的负载占比上限;默认即适合绝大多数场景。

八、常见问题

8.1 配置改动不生效

先用 containerd config dump 核对最终生效配置,确认 imports 与主文件的值是否被覆盖;再确认服务已重启:

containerd config dump | grep -nE "SystemdCgroup|snapshotter|config_path"
systemctl daemon-reload && systemctl restart containerd

真机环境还需确认 socket 就绪:

ls -l /run/containerd/containerd.sock

8.2 ctr images pull 报 connection refused

直连 docker.io 被网络阻断(限制公网访问)的典型现象:

dial tcp 67.228.235.91:443: connect: connection refused

解决:要么直接用加速站地址拉取(如 ctr images pull docker.m.daocloud.io/library/busybox:latest),要么按五章 5.2 配 hosts.toml mirror 供 CRI 使用。

8.3 gRPC ResourceExhausted / 消息过大

max_recv_message_size/max_send_message_size 默认 16 MiB;拉取超大镜像元数据或大 payload 时可按需调大,例如 16777216 增大到 1073741824(1 GiB)后重启。改之前先确认确实是消息超限,而非网络问题。

8.4 快照驱动类型错误

在部分不支持 overlay 的文件系统上报挂载拒绝(operation not permitted)时,可将 CRI 段与 transfer 段的 snapshotter 一并改为 native 回退,并清空对应 io.containerd.snapshotter.v1.native 遗留状态后重启。

九、参考链接

containerd 配置参数详解 - Quzuo