在 Kubernetes 集群中,Pod 是最小的调度单元,每个 Pod 都运行在一个或多个节点上。为了使 Pod 能够正常运行,需要在每个节点上安装一个容器运行时。本教程将介绍如何在集群内每个节点上安装容器运行时,并描述与节点设置相关的任务。
Kubernetes 1.28 要求使用符合容器运行时接口(CRI)的运行时。
本页简要介绍在 Kubernetes 中几个常见的容器运行时的用法。
- containerd
- CRI-O
- Docker Engine
- Mirantis Container Runtime
一、安装配置先决条件
以下步骤将通用设置应用于 Linux 上的 Kubernetes 节点。
1、转发 IPv4 并让 iptables 看到桥接流量
执行下述指令:
cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf overlay br_netfilter EOF sudo modprobe overlay sudo modprobe br_netfilter # 设置所需的 sysctl 参数,参数在重新启动后保持不变 cat <<EOF | sudo tee /etc/sysctl.d/k8s.conf net.bridge.bridge-nf-call-iptables = 1 net.bridge.bridge-nf-call-ip6tables = 1 net.ipv4.ip_forward = 1 EOF # 应用 sysctl 参数而不重新启动 sudo sysctl --system
通过运行以下指令确认 br_netfilter 和 overlay 模块被加载:
lsmod | grep br_netfilter lsmod | grep overlay
通过运行以下指令确认 net.bridge.bridge-nf-call-iptables、net.bridge.bridge-nf-call-ip6tables 和 net.ipv4.ip_forward 系统变量在 sysctl 配置中被设置为 1:
sysctl net.bridge.bridge-nf-call-iptables net.bridge.bridge-nf-call-ip6tables net.ipv4.ip_forward
二、cgroup驱动
在 Linux 上,控制组(CGroup)用于限制分配给进程的资源。
kubelet 和底层容器运行时都需要对接控制组来强制执行 为 Pod 和容器管理资源 并为诸如 CPU、内存这类资源设置请求和限制。若要对接控制组,kubelet 和容器运行时需要使用一个 cgroup 驱动。 关键的一点是 kubelet 和容器运行时需使用相同的 cgroup 驱动并且采用相同的配置。
可用的 cgroup 驱动有两个:
- cgroupfs
- systemd
1、cgroupfs驱动
cgroupfs 驱动是 kubelet 中默认的 cgroup 驱动。 当使用 cgroupfs 驱动时, kubelet 和容器运行时将直接对接 cgroup 文件系统来配置 cgroup。
当 systemd 是初始化系统时, 不推荐使用 cgroupfs 驱动,因为 systemd 期望系统上只有一个 cgroup 管理器。 此外,如果 使用 cgroup v2, 则应用 systemd cgroup 驱动取代 cgroupfs。
2、systemd cgroup驱动
当某个 Linux 系统发行版使用 systemd 作为其初始化系统时,初始化进程会生成并使用一个 root 控制组(cgroup),并充当 cgroup 管理器。
systemd 与 cgroup 集成紧密,并将为每个 systemd 单元分配一个 cgroup。 因此,如果 systemd 用作初始化系统,同时使用 cgroupfs 驱动,则系统中会存在两个不同的 cgroup 管理器。
同时存在两个 cgroup 管理器将造成系统中针对可用的资源和使用中的资源出现两个视图。某些情况下, 将 kubelet 和容器运行时配置为使用 cgroupfs、但为剩余的进程使用 systemd 的那些节点将在资源压力增大时变得不稳定。
当 systemd 是选定的初始化系统时,缓解这个不稳定问题的方法是针对 kubelet 和容器运行时将 systemd 用作 cgroup 驱动。
要将 systemd 设置为 cgroup 驱动,需编辑 KubeletConfiguration 的 cgroupDriver 选项,并将其设置为 systemd。例如:
apiVersion: kubelet.config.k8s.io/v1beta1 kind: KubeletConfiguration ... cgroupDriver: systemd
注意:从 v1.22 开始,在使用 kubeadm 创建集群时,如果用户没有在 KubeletConfiguration 下设置 cgroupDriver 字段,kubeadm 默认使用 systemd。
在 Kubernetes v1.28 中,启用 KubeletCgroupDriverFromCRI 特性门控结合支持 RuntimeConfig CRI RPC 的容器运行时,kubelet 会自动从运行时检测适当的 Cgroup 驱动程序,并忽略 kubelet 配置中的 cgroupDriver 设置。
如果 将 systemd 配置为 kubelet 的 cgroup 驱动, 也必须将 systemd 配置为容器运行时的 cgroup 驱动。例如:
- containerd
- CRI-O
注意:
- 更改已加入集群的节点的 cgroup 驱动是一项敏感的操作。 如果 kubelet 已经使用某 cgroup 驱动的语义创建了 Pod,更改运行时以使用别的 cgroup 驱动,当为现有 Pod 重新创建 PodSandbox 时会产生错误。 重启 kubelet 也可能无法解决此类问题;
- 如果有切实可行的自动化方案,使用其他已更新配置的节点来替换该节点, 或者使用自动化方案来重新安装。
3、将kubeadm管理的集群迁移到systemd驱动
如果希望将现有的由 kubeadm 管理的集群迁移到 systemd cgroup 驱动, 请按照配置 cgroup 驱动操作。
三、CRI版本支持
容器运行时必须至少支持 v1alpha2 版本的容器运行时接口。
Kubernetes 从 1.26 版本开始仅适用于 v1 版本的容器运行时(CRI)API。早期版本默认为 v1 版本, 但是如果容器运行时不支持 v1 版本的 API, 则 kubelet 会回退到使用(已弃用的)v1alpha2 版本的 API。
四、容器运行时
1、containerd
下面概述了使用 containerd 作为 CRI 运行时的必要步骤。
要在系统上安装 containerd,请按照开始使用 containerd 的说明进行操作。创建有效的 config.toml 配置文件后返回此步骤。
Linux/Windows:
可以在路径 /etc/containerd/config.toml 下找到此文件。在 Linux 上,containerd 的默认 CRI 套接字是 /run/containerd/containerd.sock; 在 Windows 上,默认 CRI 端点是 npipe://./pipe/containerd-containerd。
2、配置systemd cgroup驱动
结合 runc 使用 systemd cgroup 驱动,在 /etc/containerd/config.toml 中设置:
[plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc] ... [plugins."io.containerd.grpc.v1.cri".containerd.runtimes.runc.options] SystemdCgroup = true
如果使用 cgroup v2,则推荐 systemd cgroup 驱动。
注意:
- 如果 从软件包(例如,RPM 或者 .deb)中安装 containerd, 可能会发现其中默认禁止了 CRI 集成插件;
- 需要启用 CRI 支持才能在 Kubernetes 集群中使用 containerd。 要确保 cri 没有出现在 /etc/containerd/config.toml 文件中 disabled_plugins 列表内。如果 更改了这个文件,也请记得要重启 containerd;
- 如果 在初次安装集群后或安装 CNI 后遇到容器崩溃循环,则随软件包提供的 containerd 配置可能包含不兼容的配置参数。考虑按照 getting-started.md 中指定的 containerd config default > /etc/containerd/config.toml 重置 containerd 配置,然后相应地设置上述配置参数。
如果应用此更改,请确保重新启动 containerd:
sudo systemctl restart containerd
当使用 kubeadm 时,请手动配置 kubelet 的 cgroup 驱动。
在 Kubernetes v1.28 中, 可以启用 Cgroup 驱动程序的自动检测的 Alpha 级别特性。 详情参阅 systemd cgroup 驱动。
3、重载沙箱(pause)镜像
在containerd 配置中,可以通过设置以下选项重载沙箱镜像:
[plugins."io.containerd.grpc.v1.cri"] sandbox_image = "registry.k8s.io/pause:3.2"
一旦更新了这个配置文件,可能就同样需要重启 containerd:systemctl restart containerd。
请注意,声明匹配的 pod-infra-container-image 是 kubelet 的最佳实践。 如果未配置,kubelet 可能会尝试对 pause 镜像进行垃圾回收。 containerd 固定 pause 镜像的工作正在进行中, 将不再需要在 kubelet 上进行此设置。
4、CRI-O
要安装 CRI-O,请按照 CRI-O 安装说明执行操作。
(1)cgroup 驱动
CRI-O 默认使用 systemd cgroup 驱动,这对 来说可能工作得很好。 要切换到 cgroupfs cgroup 驱动,请编辑 /etc/crio/crio.conf 或在 /etc/crio/crio.conf.d/02-cgroup-manager.conf 中放置一个插入式配置,例如:
[crio.runtime] conmon_cgroup = "pod" cgroup_manager = "cgroupfs"
还应该注意当使用 CRI-O 时,并且 CRI-O 的 cgroup 设置为 cgroupfs 时,必须将 conmon_cgroup 设置为值 pod。 通常需要保持 kubelet 的 cgroup 驱动配置(通常通过 kubeadm 完成)和 CRI-O 同步。
在 Kubernetes v1.28 中, 可以启用 Cgroup 驱动程序的自动检测的 Alpha 级别特性。 对于 CRI-O,CRI 套接字默认为 /var/run/crio/crio.sock。
(2)重载沙箱(pause)镜像
在CRI-O 配置中,可以设置以下配置值:
[crio.image] pause_image="registry.k8s.io/pause:3.6"
这一设置选项支持动态配置重加载来应用所做变更:systemctl reload crio。 也可以通过向 crio 进程发送 SIGHUP 信号来实现。
5、Docker Engine
以下操作假设使用 cri-dockerd 适配器来将 Docker Engine 与 Kubernetes 集成。
- 在每个节点上,遵循安装 Docker Engine 指南为 Linux 发行版安装 Docker;
- 按照源代码仓库中的说明安装 cri-dockerd。
- 对于 cri-dockerd,默认情况下,CRI 套接字是 /run/cri-dockerd.sock。
6、Mirantis 容器运行时
Mirantis Container Runtime (MCR) 是一种商用容器运行时,以前称为 Docker 企业版。 可以使用 MCR 中包含的开源 cri-dockerd 组件将 Mirantis Container Runtime 与 Kubernetes 一起使用。
检查名为 cri-docker.socket 的 systemd 单元以找出 CRI 套接字的路径。
7、重载沙箱(pause)镜像
cri-dockerd 适配器能够接受指定用作 Pod 的基础容器的容器镜像(“pause 镜像”)作为命令行参数。 要使用的命令行参数是 –pod-infra-container-image。