sandbox_image 是 Kubernetes 或容器运行时(如 containerd)中用于创建“沙箱”(Pod 沙箱,即 PodSandbox)的一个特殊镜像。它通常也被称为 pause 镜像基础沙箱镜像


一、什么是 sandbox_image

sandbox_image 是一个轻量级的容器镜像,用于在每个 Pod 启动时创建一个“基础容器”(也叫 pause 容器或 infra 容器)。这个容器的主要作用是:

  1. 持有 Pod 的命名空间(Namespace)

    • 比如:网络命名空间、IPC 命名空间、PID 命名空间等。
    • Pod 内的所有其他容器(即应用容器)会共享这些命名空间。
  2. 作为 Pod 的“根容器”存在

    • 当 Pod 被调度时,Kubelet 会首先启动这个 sandbox_image 容器。
    • 然后其他用户定义的容器加入这个沙箱环境。
  3. 生命周期与 Pod 一致

    • 它是第一个启动、最后一个停止的容器。
    • 它本身不运行任何应用逻辑,几乎不消耗资源。

最常见的 sandbox_image 是 Google 提供的 k8s.gcr.io/pause 镜像,例如:

k8s.gcr.io/pause:3.9

二、为什么必须设置 sandbox_image

sandbox_image 必须设置,原因如下:

✅ 1. Pod 沙箱机制的基础

Kubernetes 中的 Pod 是一组共享资源的容器集合。为了实现“共享网络、IPC、PID”等特性,必须有一个“锚点”容器来创建和持有这些命名空间。sandbox_image 就是这个锚点。

没有它,就无法构建 Pod 的共享环境。

✅ 2. CRI(容器运行时接口)要求

Kubernetes 通过 CRI(Container Runtime Interface)与底层容器运行时(如 containerd、CRI-O)通信。CRI 明确要求每个 Pod 必须有一个 sandbox 容器来初始化运行环境。

  • Kubelet 在创建 Pod 时会调用 RunPodSandbox 接口。
  • 该接口需要指定一个 sandbox_image 来启动 pause 容器。
✅ 3. 网络插件依赖

CNI(容器网络接口)插件在为 Pod 配置网络时,通常会将网络设备(如 veth pair)的一端绑定到 pause 容器的网络命名空间中。

如果没有 sandbox_image 启动 pause 容器,就没有网络命名空间,CNI 插件无法工作。

✅ 4. 故障排查与稳定性

pause 容器作为一个稳定的“占位符”,即使应用容器崩溃重启,Pod 的网络和共享资源仍然保持稳定。


三、如何设置 sandbox_image

1. 默认值

大多数 Kubernetes 发行版(如 kubeadm 安装的集群)会自动使用默认的 pause 镜像,例如:

sandbox_image: k8s.gcr.io/pause:3.9
2. 手动配置(以 containerd 为例)

/etc/containerd/config.toml 中:

[plugins."io.containerd.grpc.v1.cri"]
  sandbox_image = "registry.k8s.io/pause:3.9"

注意:registry.k8s.iok8s.gcr.io 的新域名(2023 年起迁移)。

3. 离线环境或私有镜像仓库

在无法访问公网的环境中,你需要:

  • 提前拉取 pause 镜像到本地。
  • 推送到私有镜像仓库。
  • 修改配置指向私有镜像:
sandbox_image = "my-registry.local/pause:3.9"

四、常见问题

问题 原因
Pod 卡在 ContainerCreating 找不到 sandbox_image,镜像拉取失败
Failed to create pod sandbox 镜像名配置错误或网络不通
使用自定义 pause 镜像失败 镜像必须是静态的、不退出的、最小化的

五、总结

项目 说明
作用 创建 Pod 命名空间、作为 infra 容器
必须性 是 Pod 沙箱机制的基础,CRI 要求
典型镜像 registry.k8s.io/pause:3.9
配置位置 containerd 或 CRI-O 的配置文件
能否省略 ❌ 不可省略,否则 Pod 无法创建

结论
sandbox_image 是 Kubernetes 实现 Pod 多容器共享资源机制的关键组件,必须正确配置,否则节点无法正常运行 Pod。

完整版本案例

root@k8s-master:~# cat /etc/containerd/config.toml
disabled_plugins = []
imports = []
oom_score = 0
plugin_dir = ""
required_plugins = []
root = "/var/lib/containerd"
state = "/run/containerd"
version = 2

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

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

[metrics]
  address = "127.0.0.1:1338"
  grpc_histogram = false

[cgroup]
  path = ""

[daemon]
  enable_tls_streaming = false
  graceful_shutdown_timeout = -1
  graceful_restart_timeout = -1
  selinux = false

[plugins]

  [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
    enable_tls_streaming = false
    tolerate_missing_hugetlb_controller = true
    disable_cgroup = false
    disable_apparmor = false
    restrict_oom_score_adj = false
    max_concurrent_downloads = 5
    disable_proc_mount = false
    unset_seccomp_profile = ""
    tolerate_permissions_errors = false

    # ✅ 指定 pause 镜像(必须配置)
    sandbox_image = "registry.cn-hangzhou.aliyuncs.com/google_containers/pause:3.6"

    # 镜像仓库镜像配置(国内加速)
    [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://swr.cn-north-4.myhuaweicloud.com"]

        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."k8s.gcr.io"]
          endpoint = ["https://swr.cn-north-4.myhuaweicloud.com"]

        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."gcr.io"]
          endpoint = ["https://swr.cn-north-4.myhuaweicloud.com"]

        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."quay.io"]
          endpoint = ["https://swr.cn-north-4.myhuaweicloud.com"]

        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."ghcr.io"]
          endpoint = ["https://swr.cn-north-4.myhuaweicloud.com"]

        [plugins."io.containerd.grpc.v1.cri".registry.mirrors."registry.k8s.io"]
          endpoint = ["https://swr.cn-north-4.myhuaweicloud.com"]

      # ✅ 私有仓库认证:使用 IAM 用户名 + 密码(AK/SK)
      [plugins."io.containerd.grpc.v1.cri".registry.auths]
        [plugins."io.containerd.grpc.v1.cri".registry.auths."swr.cn-east-3.myhuaweicloud.com"]
          username = "cn-east-3@HPUAAL2AC4J1SRYWA1NW"
          password = "b39facac2c5dbffb4aa0defa8d4750ce3d148c81a0cb0f3b9d184f755d0fff3f"

    [plugins."io.containerd.grpc.v1.cri".containerd]
      default_runtime_name = "runc"
      snapshotter = "overlayfs"
      disable_snapshot_annotations = true
      discard_unpacked_layers = false

      [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 = ""
          pod_annotations = []
          container_annotations = []
          cni_conf_dir = ""
          cni_max_conf_num = 0
          dummy_cni_bin_dir = ""
          cni_setup_bin = ""
          cni_cleanup_bin = ""

          [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options]
            SystemdCgroup = true  # ✅ 推荐启用

  [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.runc"]
    options = {}

  [plugins."io.containerd.service.v1.diff-service"]
    default = ["walking"]

  [plugins."io.containerd.snapshotter.v1.devmapper"]
    root_path = ""
    pool_name = ""
    base_image_size = "10GB"
    async_remove = false
    delete_check_delay = "1h0m0s"
    discard_blocks = false
    fs_options = ""
    fs_type = ""
    set_xfs_quota = false
    mount_opts = ""

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐