使用 Kubespray 将 CRI-O 部署为 Kubernetes 容器运行时配置、镜像仓库与用户命名空间实战指南【免费下载链接】kubesprayDeploy a Production Ready Kubernetes Cluster项目地址: https://gitcode.com/GitHub_Trending/ku/kubespray导读本文围绕 Kubespray 仓库中 docs/CRI/cri-o.md 的官方文档展开系统讲解如何在 Kubespray 编排的 Kubernetes 集群中启用 CRI-O 作为默认容器运行时涵盖三处核心变量配置、镜像仓库镜像registry mirror与私有仓库认证、用户命名空间user namespace重映射、默认容器能力capabilities调整以及 NRINode Resource Interface的可选启用。读完本文你将掌握一套完整可落地的 CRI-O 启用方案并能对照 roles/container-engine/cri-o 角色源码理解每个配置项在crio.conf、registries.conf.d与 systemd drop-in 中的真实落点。CRI-O 与 Kubespray轻量级运行时集成概览CRI-O 是专为 Kubernetes 设计的轻量级 OCI 容器运行时直接实现了 Kubernetes CRIContainer Runtime Interface服务端无需通过中间层适配即可被 kubelet 调用。在 Kubespray 中它作为container_manager的可选值之一与containerd、docker并列承担集群默认运行时的角色。从 roles/kubespray_defaults/defaults/main/main.yml 可以看到CRI socket 路径会根据运行时选择自动推导cri_socket: - {%- if container_manager crio -%} unix:///var/run/crio/crio.sock {%- elif container_manager containerd -%} unix:///var/run/containerd/containerd.sock {%- elif container_manager docker -%} unix:///var/run/cri-dockerd.sock {%- endif -%}即container_manager: crio时kubelet 将连接unix:///var/run/crio/crio.sock。官方文档明确了两个使用前提Kubernetes 自v1.11.1起开始支持 CRI-Oetcd 需要显式配置为kubeadm 管理etcd_deployment_type: kubeadm或host 部署etcd_deployment_type: host中的一种避免使用 Docker 容器化的 etcd 部署方式。Kubespray 为 CRI-O 提供的是一整套自动化部署链路下载二进制、生成/etc/crio/crio.conf、写入镜像仓库配置、安装 systemd 服务并做运行健康校验全部封装在 roles/container-engine/cri-o 角色中。默认的container_manager是containerd见 roles/kubespray_defaults/defaults/main/main.yml因此启用 CRI-O 本质上是一次显式的变量覆盖。启用 CRI-O 的三步配置按官方文档需要分别在三个 inventory 变量文件中设置对应参数。下面逐一说明其作用与来源。all/all.yml关闭容器镜像下载并指定 etcd 部署方式download_container: false skip_downloads: false etcd_deployment_type: host # optionally kubeadmdownload_container: falseKubespray 默认通过一个部署容器container来执行镜像拉取与文件下载任务默认值为true见 roles/kubespray_defaults/defaults/main/download.yml。当容器运行时本身就是待安装的 CRI-O 时需要先关闭这种用容器下载的引导方式改为由控制节点直接下载文件。skip_downloads: false明确不跳过下载步骤保证download角色正常拉取 CRI-O 二进制与镜像默认值false位于 roles/kubespray_defaults/defaults/main/download.yml。这里显式写出是为了与download_container: false配合防止误以为关闭了下载容器就等价于跳过下载。etcd_deployment_type: hostetcd 以二进制方式直接部署在主机上也可选kubeadm由 kubeadm 托管 etcd 静态 Pod。文档强调二者必选其一这是因为 Docker 容器化的 etcd 部署与 CRI-O 运行时的组合不在支持范围内。k8s_cluster/k8s_cluster.yml切换容器运行时container_manager: crio这一行把集群所有节点的默认运行时切换为 CRI-O。切换后Kubespray 的download角色会在 roles/kubespray_defaults/defaults/main/download.yml 中按需启用/停用对应运行时的下载项例如crio相关的下载条目启用、docker条目禁用并将 kubelet 的--container-runtime-endpoint指向上面推导出的unix:///var/run/crio/crio.sock。all/crio.yml镜像仓库与运行时的细化配置all/crio.yml并不要求必须存在它是社区约定俗成、用于集中存放 CRI-O 专属变量的文件。你可以在其中配置镜像仓库镜像crio_registries、非安全仓库crio_insecure_registries、仓库认证crio_registry_auth、用户命名空间crio_remap_enable等以及默认能力crio_default_capabilities下文逐一展开。实际上这些变量也可以合并到all/all.yml其默认值均定义在 roles/container-engine/cri-o/defaults/main.yml其中crio_insecure_registries的默认空列表定义在 roles/kubespray_defaults/defaults/main/main.yml。配置镜像仓库镜像、非安全仓库与认证使用 crio_registries 配置仓库镜像crio_registries用于为 Docker Hub 等上游仓库配置镜像mirror实现拉取加速或离线镜像。官方文档给出的示例crio_registries: - prefix: docker.io insecure: false blocked: false location: registry-1.docker.io unqualified: false mirrors: - location: 192.168.100.100:5000 insecure: true - location: mirror.gcr.io insecure: false各字段含义字段说明prefix该条目匹配的镜像前缀命名空间前缀如docker.io未显式声明location时由prefix充当locationlocation上游仓库地址必填项如registry-1.docker.ioinsecure是否以非 TLSHTTP方式访问该仓库默认falseblocked是否阻断该仓库的访问默认falseunqualified是否允许以不带仓库限定符的方式即裸镜像名从该仓库搜索拉取默认false出于安全考虑默认不允许非限定镜像mirrors镜像源列表每个镜像源有自己的location与insecure请求先尝试主location失败后按列表顺序回退到各镜像源该配置在部署时被渲染为/etc/containers/registries.conf.d/10-prefix.conf文件渲染逻辑见 roles/container-engine/cri-o/templates/registry.conf.j2。每个crio_registries条目会生成一个[[registry]]块镜像源则生成[[registry.mirror]]子块[[registry]] prefix docker.io insecure false blocked false location registry-1.docker.io [[registry.mirror]] location 192.168.100.100:5000 insecure true写入这些文件的任务位于 roles/container-engine/cri-o/tasks/main.yaml文件名由item.prefix | default(item.location)经regex_replace(:|/, _)处理生成因此docker.io会落成10-docker.io.conf。非限定镜像搜索当crio_registries中存在unqualified: true的条目时roles/container-engine/cri-o/templates/unqualified.conf.j2 会把这些条目的prefix或location收集进/etc/containers/registries.conf.d/01-unqualified.confunqualified-search-registries [docker.io]这决定了 kubelet/CRI-O 拉取裸镜像名如nginx:latest时按什么顺序去哪些仓库搜索。启用非安全仓库对于没有 TLS 证书的私有镜像仓库例如内网10.0.0.2:5000可使用crio_insecure_registriescrio_insecure_registries: - 10.0.0.2:5000该变量会渲染进/etc/crio/crio.conf的[crio.image]段仅当列表非空时才输出见 roles/container-engine/cri-o/templates/crio.conf.j2[crio.image] insecure_registries [10.0.0.2:5000]为仓库配置认证在crio_insecure_registries之后可以为这些仓库配置账号密码crio_registry_auth: - registry: 10.0.0.2:5000 username: user password: passcrio_registry_auth由 roles/container-engine/cri-o/templates/config.json.j2 渲染为/etc/crio/config.jsonDocker 兼容的 auths 格式用户名与密码会被拼成user:pass再做 Base64 编码写入auth字段该文件通过crio.conf中的global_auth_file /etc/crio/config.json见 roles/container-engine/cri-o/templates/crio.conf.j2被 CRI-O 用于拉取私有镜像时的凭据。列表为空时文件内容为{}不产生任何凭据。用户命名空间User Namespace支持CRI-O 原生支持用户命名空间。官方文档说明可以通过以下两个变量启用crio_runtimes: - name: runc path: /usr/bin/runc type: oci root: /run/runc allowed_annotations: - io.kubernetes.cri-o.userns-mode crio_remap_enable: truecrio_runtimes定义 CRI-O 可用的 OCI 运行时列表。每个条目包含name运行时处理器名、path运行时可执行文件绝对路径、typeoci或vm、root运行时状态根目录以及可选的allowed_annotations。这里的allowed_annotations会把io.kubernetes.cri-o.userns-mode加入对应运行时的注解白名单配置落点在crio.conf中每个运行时的[crio.runtime.runtimes.name]段渲染循环见 roles/container-engine/cri-o/templates/crio.conf.j2[crio.runtime.runtimes.runc] runtime_path /usr/bin/runc runtime_type oci runtime_root /run/runc privileged_without_host_devices false allowed_annotations [io.kubernetes.cri-o.userns-mode]crio_remap_enable: true启用后部署任务会在/etc/subuid与/etc/subgid中为containers用户写入一条映射记录见 roles/container-engine/cri-o/tasks/main.yaml例如containers:2130706432:16777216文档特别说明默认在 uid/gid 空间的末端为用户命名空间预留16M16,777,216个 uid/gid对应256 个 Pod × 65536 个 uid/gid。这些默认值在 roles/container-engine/cri-o/defaults/main.yml 中可查并可调变量默认值含义crio_remap_usercontainers写入 subuid/subgid 的用户名crio_subuid_start2130706432子 uid 起始值crio_subuid_length16777216子 uid 区间长度16Mcrio_subgid_start2130706432子 gid 起始值crio_subgid_length16777216子 gid 区间长度16M注意crio.conf模板中还存在uid_mappings/gid_mappings见 roles/container-engine/cri-o/templates/crio.conf.j2默认保持为空字符串用户命名空间的实际映射以/etc/subuid、/etc/subgid为准。默认容器能力default capabilitiescrio_default_capabilities用于定义 CRI-O 启动容器时默认授予的 Linux capabilities默认值如下同样定义在 roles/container-engine/cri-o/defaults/main.ymlcrio_default_capabilities: - CHOWN - DAC_OVERRIDE - FSETID - FOWNER - SETGID - SETUID - SETPCAP - NET_BIND_SERVICE - KILL这些能力会被渲染进crio.conf的default_capabilities数组见 roles/container-engine/cri-o/templates/crio.conf.j2。注意该列表不包含MKNOD官方文档提示如果部署 Rancher其 Rancher Agent 容器需要创建设备节点需要手动把MKNOD加入列表crio_default_capabilities: - CHOWN - DAC_OVERRIDE - FSETID - FOWNER - SETGID - SETUID - SETPCAP - NET_BIND_SERVICE - KILL - MKNOD若将该列表清空则只保留容器镜像内显式声明的能力crio.conf模板注释对此有明确说明。可选启用 NRINode Resource InterfaceNRINode Resource Interface允许 OCI 运行时与 kubelet 之外的插件如设备管理、资源调整类组件通过插件机制协同工作。CRI-O 中 NRI默认关闭如果你使用的是CRI-O v1.26.0 或更高版本可通过如下配置开启nri_enabled: true从源码看roles/container-engine/cri-o/templates/crio.conf.j2 会同时校验nri_enabled与 CRI-O 版本号由crio_version与1.26.0比较只有两者同时满足时才渲染[crio.nri] enable_nritrue一个容易踩坑的点nri_enabled在 Kubespray 中的默认值是{{ container_manager containerd }}见 roles/kubespray_defaults/defaults/main/main.yml。也就是说默认情况下它只对 containerd 生效切换到 CRI-O 后必须显式设置为true[crio.nri]段才会写入crio.conf。深入源码CRI-O 角色部署链路与高级变量部署任务流程roles/container-engine/cri-o/tasks/main.yaml 完整展示了 CRI-O 的落盘顺序按版本加载变量load_vars.yml依据crio_version选择 v1.29 / v1.31 的二进制清单检测 Fedora CoreOSostree环境并获取版本通过download角色下载 CRI-O 发布包构建运行时列表默认包含crun若kata_containers_enabled为真则追加 Kata 运行时若runc_enabled/youki_enabled为真则追加 runc / youki支持crio_runtime_switch热切换先停止 kubelet、用crictl rmp -f/crictl rmp -fa清空非 hostNetwork Pod再停止旧的crio服务创建/etc/crio、/etc/containers、/etc/systemd/system/crio.service.d等目录渲染/etc/crio/crio.confcrio.conf.j2与/etc/crio/config.jsonconfig.json.j2拷贝crio、pinns二进制到bin_dirconmon、crun、runc等到crio_libexec_dir并安装 systemdcrio.service可选写00-slice.conf当kube_reserved开启时把 crio 放入预留 cgroup slice写/etc/containers/policy.json、mounts.conf并强制将storage.conf的驱动设为overlaygraphroot/var/lib/containers/storage、runroot/var/run/containers/storage同时按内核版本自动决定是否追加metacopyon挂载选项内核 4.18/4.19 时仅nodev否则nodev,metacopyon生成/etc/containers/registries.conf.d/下的镜像仓库配置当定义了http_proxy/https_proxy时渲染http-proxy.confsystemd drop-in 为 crio 注入代理环境按crio_remap_enable维护/etc/subuid、/etc/subgid启动并 enablecrio服务仅在配置变更时重启用crio status info轮询验证守护进程就绪。值得关注的高级变量除文档明确提到的变量外roles/container-engine/cri-o/defaults/main.yml 中还有一批实用项变量默认值说明crio_default_runtimecrun默认 OCI 运行时名称CRI-O v1.31 起默认 cruncrio_cgroup_managersystemd跟随kubelet_cgroup_drivercgroup 驱动需与 kubelet 保持一致crio_root/var/lib/containers/storage容器镜像与数据根目录crio_pause_image{{ pod_infra_repo }}:{{ pod_infra_version }}infra/pause 容器镜像crio_log_levelinfo日志级别crio_enable_metricsfalse是否开启 Prometheus 指标端口crio_metrics_port9090指标监听端口crio_stream_port10010kubeletexec/attach流服务端口crio_pull_progress_timeout10s镜像拉取无进展超时crio_seccomp_profile自定义 seccomp profile 路径crio_selinux跟随preinstall_selinux_state是否启用 SELinuxcrio_criu_support_enabledfalse是否启用 CRIU检查点/恢复crio_required_version由kube_version推导校验安装的 CRI-O 主次版本其中crio_cgroup_manager直接决定conmon_cgroup的取值与cgroup_manager配置必须与 kubelet 的--cgroup-driver一致默认systemd否则会出现运行时与 kubelet 的 cgroup 归属不一致问题。Kata Containers 场景下模板还会自动把manage_ns_lifecycle置为true见 roles/container-engine/cri-o/templates/crio.conf.j2。版本差异v1.29 与 v1.31CRI-O 版本不同二进制布局不同。v1.29 中crio_conmon、crio_runtime_bin_dir指向bin_dir二进制为crio-conmon、crio-crun、crio-runc等见 roles/container-engine/cri-o/vars/v1.29.ymlv1.31 起crio_runtime_bin_dir指向/usr/libexec/crioconmon、conmonrs、crun、runc直接放入 libexec 目录见 roles/container-engine/cri-o/vars/v1.31.yml。crio_version的推导规则为从kube_version正则提取主版本.次版本crio_required_version即 CRI-O 版本与 Kubernetes 版本保持一致因此升级 Kubernetes 时会同步升级 CRI-O。运行验证与测试CRI-O 角色内置了 molecule 测试roles/container-engine/cri-o/molecule/default/verify.yml验证两点一是以unix:///var/run/crio/crio.sock作为 CRI socket 测试 CRI 接口可用二是用crun实际运行一个容器。集群部署后你可以用同样的思路手工验证# 检查 crio 服务状态 systemctl status crio # 查看 CRI-O 运行时信息等价于部署时的健康检查 crictl info # 列出节点上所有 Pod含镜像与沙箱状态 crictl pods -o json其中crictl info对应 roles/container-engine/cri-o/tasks/main.yaml 中部署末尾的轮询健康检查最多重试 5 次crictl也是 CRI-O 场景下 Kubespray 默认的镜像命令工具见 roles/kubespray_defaults/defaults/main/download.yml 中image_command_tool对container_manager crio返回crictl的逻辑。小结在 Kubespray 中启用 CRI-O 只需要三处变量联动all/all.yml关闭下载容器并指定 etcd 部署方式k8s_cluster/k8s_cluster.yml将container_manager切为crio再视需要在其基础上配置crio_registries镜像仓库镜像与阻断、crio_insecure_registries非安全仓库、crio_registry_auth私有仓库认证、crio_runtimescrio_remap_enable用户命名空间、crio_default_capabilities容器默认能力以及nri_enabledNRI 插件支持需 CRI-O ≥ v1.26.0 且显式开启。所有配置最终都会落到/etc/crio/crio.conf、/etc/containers/registries.conf.d/、/etc/crio/config.json与/etc/subuid、/etc/subgid等宿主文件上部署全程由 roles/container-engine/cri-o 角色自动化完成并通过crio status info在部署结束时完成就绪校验。按此方案配置后你的集群即可使用轻量、无 shim 层、贴合 OCI 规范的 CRI-O 运行时承载工作负载。【免费下载链接】kubesprayDeploy a Production Ready Kubernetes Cluster项目地址: https://gitcode.com/GitHub_Trending/ku/kubespray创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考