本部分包含以下有关节点的参考主题:
-
kubelet 的 Checkpoint API
你还可以从 Kubernetes 文档的其他地方阅读节点的详细参考信息,包括:
为容器生成检查点这个功能可以为一个正在运行的容器创建有状态的拷贝。 一旦容器有一个有状态的拷贝,你就可以将其移动到其他计算机进行调试或类似用途。
如果你将通过检查点操作生成的容器数据移动到能够恢复该容器的一台计算机, 所恢复的容器将从之前检查点操作执行的时间点继续运行。 你也可以检视所保存的数据,前提是你拥有这类操作的合适工具。
创建容器的检查点可能会产生安全隐患。
通常,一个检查点包含执行检查点操作时容器中所有进程的所有内存页。
这意味着以前存在于内存中的一切内容现在都在本地磁盘上获得。
这里的内容包括一切私密数据和可能用于加密的密钥。
底层 CRI 实现(该节点上的容器运行时)应创建只有 root 用户可以访问的检查点存档。
另外重要的是记住:如果检查点存档被转移到另一个系统,该检查点存档的所有者将可以读取所有内存页。
post 对指定的容器执行检查点操作 告知 kubelet 对指定 Pod 中的特定容器执行检查点操作。
查阅 Kubelet 身份验证/鉴权参考了解如何控制对 kubelet 检查点接口的访问。
Kubelet 将对底层 CRI 实现请求执行检查点操作。
在该检查点请求中,Kubelet 将检查点存档的名称设置为 checkpoint-<pod 全称>-<容器名称>-<时间戳>.tar,
还会请求将该检查点存档存储到其根目录(由 --root-dir 定义)下的 checkpoints 子目录中。
这个目录默认为 /var/lib/kubelet/checkpoints。
检查点存档的格式为 tar,可以使用 tar
的一种实现来读取。存档文件的内容取决于底层 CRI 实现(该节点的容器运行时)。
POST /checkpoint/{namespace}/{pod}/{container}
namespace (路径参数):string,必需
名字空间(Namespace)pod (路径参数):string,必需
Podcontainer (路径参数):string,必需
容器(Container)timeout (查询参数):integer
等待检查点创建完成的超时时间(单位为秒)。 如果超时值为零或未设定,将使用默认的 CRI 超时时间值。 生成检查点所需的时长直接取决于容器所用的内存。容器使用的内存越多,创建相应检查点所需的时间越长。
200: OK
401: Unauthorized
404: Not Found(如果 ContainerCheckpoint 特性门控被禁用)
404: Not Found(如果指定的 namespace、pod 或 container 无法被找到)
500: Internal Server Error(如果执行检查点操作期间 CRI 实现遇到一个错误(参阅错误消息了解更多细节))
500: Internal Server Error(如果 CRI 实现未实现检查点 CRI API(参阅错误消息了解更多细节))
许多特性依赖于特定的内核功能,并且有最低的内核版本要求。 然而,单纯依赖内核版本号可能不足以满足某些操作系统发行版, 因为像 RHEL、Ubuntu 和 SUSE 等发行版的维护者们通常会将选定的特性反向移植到较旧的内核版本(保留较旧的内核版本)。
在 Linux 中,sysctl() 系统调用在运行时配置内核参数。
你可以使用名为 sysctl 的命令行工具来配置这些参数,许多参数通过 proc 文件系统暴露。
某些 sysctl 仅可用于足够新的内核上。
以下 sysctl 具有最低的内核版本要求, 并在安全集中得到了支持:
net.ipv4.ip_local_reserved_ports(自 Kubernetes 1.27 起,需要内核 3.16+)。net.ipv4.tcp_keepalive_time(自 Kubernetes 1.29 起,需要内核 4.5+)。net.ipv4.tcp_fin_timeout(自 Kubernetes 1.29 起,需要内核 4.6+)。net.ipv4.tcp_keepalive_intvl(自 Kubernetes 1.29 起,需要内核 4.5+)。net.ipv4.tcp_keepalive_probes(自 Kubernetes 1.29 起,需要内核 4.5+)。net.ipv4.tcp_syncookies(自内核 4.6+ 添加了命名空间作用域)。net.ipv4.tcp_rmem(自 Kubernetes 1.32,需要内核 4.15+)。net.ipv4.tcp_wmem(自 Kubernetes 1.32,需要内核 4.15+)。net.ipv4.vs.conn_reuse_mode(用于 ipvs 代理模式,需要内核 4.1+)。nftables 代理模式 对于 Kubernetes 1.35,kube-proxy 的
nftables 模式要求
nft 命令行工具为 v1.0.1 或更高版本,要求内核为 v5.13 或更高版本。
出于测试/开发目的,你可以使用较旧的内核,如果你在 kube-proxy 配置中设置 nftables.skipKernelVersionCheck 选项,
最老可以回溯到 v5.4。但在生产环境中不推荐这样做,因为这可能会导致系统上其他 nftables 用户出现问题。
Kubernetes 对 CGroup v1 的支持从 v1.31 开始处于维护模式;推荐使用 CGroup v2。
在 Linux 5.8
中,为了方便使用,系统层面的 cpu.stat 文件被添加到根 CGroup。
在 runc 文档中,不推荐使用低于 5.2 的内核,因为其缺少冻结特性。
Linux 内核 v4.20 及更高版本支持压力阻塞信息, 但需要以下配置:
CONFIG_PSI=y 选项进行编译(大多数现代发行版默认启用此选项)。
你可以通过运行 zgrep CONFIG_PSI /proc/config.gz 来检查内核的配置。psi=1 参数来启用它。某些特性可能依赖于新的内核功能并具有特定的内核要求:
MOUNT_ATTR_RDONLY 属性和 AT_RECURSIVE 标志来实现的,使用的是在 Linux
内核 v5.12 中添加的 mount_setattr(2)。noswap。你可以在 kernel.org 找到活动的内核版本。
通常会提供多个长期维护内核版本,用于将 Bug 修复反向移植到较旧的内核树。 特别是对于较旧的树,只有重要的 Bug 修复才会被应用到此类内核,这些内核通常不会频繁发布新版本。 请参阅 Linux 内核网站,了解 Longterm 类别中的发布列表。
这是关于 Kubernetes 弃用和移除 dockershim 或使用兼容 CRI 的容器运行时相关的文章和其他页面的列表。
Kubernetes 博客:Dockershim 移除常见问题解答(最初发表于 2020/12/02)
Kubernetes 博客:更新:Dockershim 移除常见问题解答(更新发表于 2020/12/02)
Kubernetes 博客:Kubernetes 即将移除 Dockershim:承诺和下一步(发表于 2022/01/07)
Kubernetes 博客:移除 Dockershim 即将到来。你准备好了吗?(发表于 2021/11/12)
Kubernetes 文档:从 dockershim 迁移
Kubernetes 文档:容器运行时
Kubernetes 增强建议:KEP-2221: 从 kubelet 中移除 dockershim
Kubernetes 增强提问:从 kubelet 中移除 dockershim (k/enhancements#2221)
你可以通过 GitHub 问题 Dockershim 移除反馈和问题 提供反馈。 (k/kubernetes/#106917)
Amazon Web Services EKS 文档:Amazon EKS 将终止对 Dockershim 的支持
CNCF 会议视频:将 Kubernetes 从 Docker 迁移到 containerd 运行时的经验教训(Ana Caylin,在 KubeCon Europe 2019)
Docker.com 博客:开发人员需要了解的关于 Docker、Docker Engine 和 Kubernetes v1.20 的哪些知识(发表于 2020/12/04)
YouTube 上的 “Google Open Source” 频道:与 Google 一起学习 Kubernetes - 从 Dockershim 迁移到 Containerd
Azure 博客上的 Microsoft 应用:Dockershim 弃用和 AKS(发表于 2022/01/21)
Mirantis 博客:Dockershim 的未来是 cri-dockerd(发表于 2021/04/21)
Mirantis: Mirantis/cri-dockerd 官方文档
Tripwire:Dockershim 即将弃用如何影响你的 Kubernetes (发表于 2021/07/01)
你还可以通过 kubelet 配置或使用 Kubernetes API 在节点上设置自己的标签。
Kubernetes 在节点上设置的预设标签有:
kubernetes.io/archkubernetes.io/hostnamekubernetes.io/osnode.kubernetes.io/instance-type
(如果 kubelet 知道此信息 – Kubernetes 可能没有这些信息来设置标签)topology.kubernetes.io/region
(如果 kubelet 知道此信息 – Kubernetes 可能没有这些信息来设置标签)topology.kubernetes.io/zone
(如果 kubelet 知道此信息 – Kubernetes 可能没有这些信息来设置标签)这些标签的值是特定于云提供商的,并且不保证其可靠性。
例如,kubernetes.io/hostname 的值在某些环境中可能与节点名称相同,
而在其他环境中可能与节点名称不同。
kubelet 是一个运行在 Kubernetes 节点上的无状态进程。本文简要介绍了 kubelet 读写的文件。
本文仅供参考,而非描述保证会发生的行为或 API。 本文档列举 kubelet 所使用的资源。所给的信息属于实现细节,可能会在后续版本中发生变更。
kubelet 通常使用控制面作为需要在 Node 上运行的事物的真实来源,并使用容器运行时获取容器的当前状态。 只要你向 kubelet 提供 kubeconfig(API 客户端配置),kubelet 就会连接到你的控制面; 否则,节点将以**独立(Standalone)**模式运行。
在 Linux 节点上,kubelet 还需要读取 cgroups 和各种系统文件来收集指标。
在 Windows 节点上,kubelet 不依赖于路径,而是通过其他机制来收集指标。
kubelet 所使用的还有其他文件,包括其使用本地 Unix 域套接字进行通信的文件。 有些文件是 kubelet 要监听的套接字,而其他套接字则是 kubelet 先发现后作为客户端连接的。
本页列举的路径为 Linux 路径,若要映射到 Windows,你可以添加根磁盘 C:\ 替换 /(除非另行指定)。
例如,/var/lib/kubelet/device-plugins 映射到 C:\var\lib\kubelet\device-plugins。
你可以使用命令行参数 --config 指定 kubelet 配置文件的路径。kubelet
还支持插件(Drop-in)配置文件来增强配置。
证书和私钥通常位于 /var/lib/kubelet/pki,但你可以使用 --cert-dir kubelet 命令行参数进行配置。
证书文件的名称也是可以配置的。
静态 Pod 的清单通常位于 /etc/kubernetes/manifests。
你可以使用 staticPodPath kubelet 配置选项进行配置。
当 kubelet 作为 systemd 单元运行时,一些 kubelet 配置可以在 systemd 单元设置文件中声明。 这些配置通常包括:
所有资源管理器将 Pod 与已分配资源之间的映射保存在状态文件中。
状态文件位于 kubelet 的基础目录,也称为根目录(但与节点根目录 / 不同)之下。
你可以使用 kubelet 命令行参数 --root-dir 来配置 kubelet 的基础目录。
文件名称:
设备管理器在与套接字文件相同的目录(/var/lib/kubelet/device-plugins/)中创建检查点。
对于设备管理器,
检查点文件的名称为 kubelet_internal_checkpoint。
This is a stable feature in Kubernetes, and has been since version 1.35. It was first available in the v1.27 release.
如果某个节点已启用了 InPlacePodVerticalScaling
特性门控,
则 kubelet 存储有关 Pod 资源已分配和已应用状态的本地记录。
有关如何使用这些记录的更多细节,
请参阅调整分配给容器的 CPU 和内存资源。
文件名称如下:
allocated_pods_state:记录分配给该节点上每个 Pod 的资源。actuated_pods_state:记录运行时已接受并应用于该节点上每个 Pod 的资源。这些文件位于 kubelet 的基础目录中(在 Linux 系统中默认是 /var/lib/kubelet;
也可以通过 --root-dir 参数进行配置)。
kubelet 使用通过配置参数所配置的套接字与容器运行时进行通信:
containerRuntimeEndpoint 用于运行时操作imageServiceEndpoint 用于镜像管理操作这些端点的实际值取决于所使用的容器运行时。
kubelet 在路径 /var/lib/kubelet/device-plugins/kubelet.sock
为各个要注册的设备插件公开一个套接字。
当设备插件注册自己时,它会为提供其套接字路径供 kubelet 连接使用。
设备插件套接字应位于 kubelet 基础目录中的 device-plugins 目录内。
在典型的 Linux 节点上,这意味着 /var/lib/kubelet/device-plugins。
Pod Resources API
将在路径 /var/lib/kubelet/pod-resources 上被公开。
kubelet 会查找通过 DRA
设备管理器或存储插件所管理的设备插件所创建的套接字文件,然后尝试连接到这些套接字。
kubelet 查找的目录是 kubelet 基础目录下的 plugins_registry,
因此在典型的 Linux 节点上这意味着 /var/lib/kubelet/plugins_registry。
请注意,对于设备插件,有两种备选的注册机制。每个给定的插件只能使用其中一种注册机制。
可以将套接字文件放入该目录的插件类型包括:
(通常是 /var/lib/kubelet/plugins_registry)。
节点体面关闭将状态存储在本地目录
/var/lib/kubelet/graceful_node_shutdown_state。
kubelet 存储镜像拉取的尝试记录和成功记录,并使用这些记录来验证镜像是否曾使用相同的凭据被成功拉取过。
这些记录作为文件缓存在 kubelet 基础目录下的 image_registry 目录中。
在典型的 Linux 节点上,这个路径通常为 /var/lib/kubelet/image_manager。
image_manager 目录下包含两个子目录:
pulling:存储 kubelet 正在尝试拉取的镜像的相关记录。pulled:存储 kubelet 成功拉取的镜像记录,以及与拉取所用凭据相关的元数据。更多细节请参阅确保镜像拉取凭据验证。
被 Pod 引用的 Seccomp 配置文件应放置在 /var/lib/kubelet/seccomp。
有关细节请参见 Seccomp 参考。
kubelet 不会通过特定于 Kubernetes 的路径加载或引用 AppArmor 配置文件。 AppArmor 配置文件通过节点操作系统被加载,而不是通过其路径被引用。
kubelet 的锁文件;通常为 /var/run/kubelet.lock。
kubelet 使用此文件确保尝试运行两个不同的、彼此冲突的 kubelet。
你可以使用 --lock-file kubelet 命令行参数来配置这个锁文件的路径。
如果同一节点上的两个 kubelet 使用不同的锁文件路径值,则这两个 kubelet 在同时运行时将不会检测到冲突。
当使用 kubelet 的 --config-dir 标志来指定存放配置的目录时,不同类型的配置会有一些特定的行为。
以下是在配置合并过程中不同数据类型的一些行为示例:
在 YAML 结构中有两种结构字段:独立(标量类型)和嵌入式(此结构包含标量类型)。 配置合并过程将处理独立构造字段和嵌入式构造字段的重载,以创建最终的 kubelet 配置。
例如,你可能想要为所有节点设置一个基准 kubelet 配置,但希望自定义 address 和 authorization 字段。
这种情况下,你可以按以下方式完成:
kubelet 主配置文件内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
authorization:
mode: Webhook
webhook:
cacheAuthorizedTTL: "5m"
cacheUnauthorizedTTL: "30s"
serializeImagePulls: false
address: "192.168.0.1"
--config-dir 目录中文件的内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authorization:
mode: AlwaysAllow
webhook:
cacheAuthorizedTTL: "8m"
cacheUnauthorizedTTL: "45s"
address: "192.168.0.8"
生成的配置如下所示:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
serializeImagePulls: false
authorization:
mode: AlwaysAllow
webhook:
cacheAuthorizedTTL: "8m"
cacheUnauthorizedTTL: "45s"
address: "192.168.0.8"
你可以重载 kubelet 配置的切片/列表值。
但在合并过程中整个列表将被重载。
例如,你可以按以下方式重载 clusterDNS 列表:
kubelet 主配置文件的内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
serializeImagePulls: false
clusterDNS:
- "192.168.0.9"
- "192.168.0.8"
--config-dir 目录中文件的内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
clusterDNS:
- "192.168.0.2"
- "192.168.0.3"
- "192.168.0.5"
生成的配置如下所示:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
serializeImagePulls: false
clusterDNS:
- "192.168.0.2"
- "192.168.0.3"
- "192.168.0.5"
映射中的各个字段(无论其值类型是布尔值、字符串等)都可以被选择性地重载。
但对于 map[string][]string 类型来说,与特定字段关联的整个列表都将被重载。
让我们通过一个例子更好地理解这一点,特别是 featureGates 和 staticPodURLHeader 这类字段:
kubelet 主配置文件的内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
serializeImagePulls: false
featureGates:
AllAlpha: false
MemoryQoS: true
staticPodURLHeader:
kubelet-api-support:
- "Authorization: 234APSDFA"
- "X-Custom-Header: 123"
custom-static-pod:
- "Authorization: 223EWRWER"
- "X-Custom-Header: 456"
--config-dir 目录中文件的内容:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
featureGates:
MemoryQoS: false
KubeletTracing: true
DynamicResourceAllocation: true
staticPodURLHeader:
custom-static-pod:
- "Authorization: 223EWRWER"
- "X-Custom-Header: 345"
生成的配置如下所示:
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
port: 20250
serializeImagePulls: false
featureGates:
AllAlpha: false
MemoryQoS: false
KubeletTracing: true
DynamicResourceAllocation: true
staticPodURLHeader:
kubelet-api-support:
- "Authorization: 234APSDFA"
- "X-Custom-Header: 123"
custom-static-pod:
- "Authorization: 223EWRWER"
- "X-Custom-Header: 345"
本页详述了 Kubernetes 设备插件 API 与不同版本的 Kubernetes 本身之间的版本兼容性。
v1alpha1 |
v1beta1 |
|
|---|---|---|
| Kubernetes 1.21 | - | ✓ |
| Kubernetes 1.22 | - | ✓ |
| Kubernetes 1.23 | - | ✓ |
| Kubernetes 1.24 | - | ✓ |
| Kubernetes 1.25 | - | ✓ |
| Kubernetes 1.26 | - | ✓ |
简要说明:
✓ 设备插件 API 和 Kubernetes 版本中的特性或 API 对象完全相同。+ 设备插件 API 具有 Kubernetes 集群中可能不存在的特性或 API 对象,
不是因为设备插件 API 添加了额外的新 API 调用,就是因为服务器移除了旧的 API 调用。
但它们的共同点是(大多数其他 API)都能工作。
请注意,Alpha API 可能会在次要版本的迭代过程中消失或出现重大变更。- Kubernetes 集群具有设备插件 API 无法使用的特性,不是因为服务器添加了额外的 API 调用,
就是因为设备插件 API 移除了旧的 API 调用。但它们的共同点是(大多数 API)都能工作。在 Linux 节点上,Kubernetes 1.35 支持与
systemd 集成,以允许操作系统监视程序恢复失败的 kubelet。
这种集成默认并未被启用。它可以作为一个替代方案,通过定期请求 kubelet 的 /healthz 端点进行健康检查。
如果 kubelet 在设定的超时时限内未对看门狗做出响应,看门狗将杀死 kubelet。
systemd 看门狗的工作原理是要求服务定期向 systemd 进程发送一个保持活跃的信号。 如果 systemd 进程在指定的超时时限内未接收到某服务发出的信号,则对应的服务被视为无响应并被终止。 之后 systemd 进程可以基于配置重启该服务。
使用 systemd 看门狗需要在 kubelet 服务单元文件的 [Service] 部分配置 WatchdogSec 参数:
[Service]
WatchdogSec=30s
设置 WatchdogSec=30s 表示服务看门狗超时时限为 30 秒。
在 kubelet 内,sd_notify() 函数被调用,以 \( WatchdogSec \div 2\) 的时间间隔,
发送 WATCHDOG=1(保持活跃的消息)。如果在超时时限内看门狗未被“投喂”此信号,kubelet 将被杀死。
将 Restart 设置为 "always"、"on-failure"、"on-watchdog" 或 "on-abnormal"
将确保服务被自动重启。
systemd 配置相关的一些细节:
WatchdogSec 值设置为 0,或省略不设置,则对应的单元上不启用 systemd 看门狗。WatchdogSec 的值设置为短于 1 秒的超时时限,
但 Kubernetes 不支持任何更短的时间间隔。超时时限不必是整数的秒数。WatchdogSec 时限设置为大约 15 秒。
系统支持超过 10 分钟的时限设置,但明确不推荐这样做。[Unit]
Description=kubelet: The Kubernetes Node Agent
Documentation=https://kubernetes.io/docs/home/
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/bin/kubelet
# 配置看门狗的超时时限
WatchdogSec=30s
Restart=on-failure
StartLimitInterval=0
RestartSec=10
[Install]
WantedBy=multi-user.target
有关 systemd 配置的细节,请参阅 systemd 文档。
Seccomp 表示安全计算(Secure Computing)模式,自 2.6.12 版本以来,一直是 Linux 内核的一个特性。 它可以用来沙箱化进程的权限,限制进程从用户态到内核态的调用。 Kubernetes 能使你自动将加载到节点上的 seccomp 配置文件应用到你的 Pod 和容器。
有四种方式可以为 Pod 指定 seccomp 配置文件:
spec.securityContext.seccompProfilespec.containers[*].securityContext.seccompProfilespec.initContainers[*].securityContext.seccompProfilespec.ephemeralContainers[*].securityContext.seccompProfileapiVersion: v1
kind: Pod
metadata:
name: pod
spec:
securityContext:
seccompProfile:
type: Unconfined
ephemeralContainers:
- name: ephemeral-container
image: debian
securityContext:
seccompProfile:
type: RuntimeDefault
initContainers:
- name: init-container
image: debian
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: container
image: docker.io/library/debian:stable
securityContext:
seccompProfile:
type: Localhost
localhostProfile: my-profile.json
上面的示例中的 Pod 以 Unconfined 运行,而 ephemeral-container 和
init-container 独立设置了 RuntimeDefault。
如果临时容器或 Init 容器没有明确设置 securityContext.seccompProfile 字段,
则此值将从 Pod 继承。同样的机制也适用于运行 Localhost 配置文件 my-profile.json 的容器。
一般来说,(临时)容器的字段优先级高于 Pod 层级的值,而未设置 seccomp 字段的容器则从 Pod 继承配置。
你不可以将 seccomp 配置文件应用到在容器的 securityContext 中设置了 privileged: true 的
Pod 或容器。特权容器始终以 Unconfined 运行。
对于 seccompProfile.type,可以使用以下值:
UnconfinedRuntimeDefaultLocalhostlocalhostProfile 将被应用,这一配置必须位于节点磁盘上(在 Linux 上是 /var/lib/kubelet/seccomp)。
在创建容器时,容器运行时会验证 seccomp
配置文件的可用性。如果此配置文件不存在,则容器创建将失败,并报错 CreateContainerError。Localhost 配置文件 Seccomp 配置文件是遵循 OCI 运行时规范定义的 JSON 文件。配置文件主要根据所匹配的系统调用来定义操作,但也允许将特定值作为参数传递给系统调用。例如:
{
"defaultAction": "SCMP_ACT_ERRNO",
"defaultErrnoRet": 38,
"syscalls": [
{
"names": [
"adjtimex",
"alarm",
"bind",
"waitid",
"waitpid",
"write",
"writev"
],
"action": "SCMP_ACT_ALLOW"
}
]
}
上述配置文件中的 defaultAction 被定义为 SCMP_ACT_ERRNO,并可回退至 syscalls 中所定义的操作。
此错误通过 defaultErrnoRet 字段被定义为代码 38。
通常可以使用以下操作:
SCMP_ACT_ERRNOSCMP_ACT_ALLOWSCMP_ACT_KILL_PROCESSSCMP_ACT_KILL_THREAD 和 SCMP_ACT_KILLSCMP_ACT_TRAPSIGSYS 信号。SCMP_ACT_NOTIFY 和 SECCOMP_RET_USER_NOTIFSCMP_ACT_TRACESCMP_ACT_LOGSCMP_ACT_NOTIFY 或 SECCOMP_RET_USER_NOTIF 这类操作可能不被支持,
具体取决于所使用的容器运行时、OCI 运行时或 Linux 内核版本。也可能存在其他限制,
例如 SCMP_ACT_NOTIFY 不能用作 defaultAction 或用于某些系统调用(如 write)。
所有这些限制由 OCI 运行时
(runc、crun)
或 libseccomp 所定义。
syscalls JSON 数组包含对象列表,每个对象通过系统调用的 names 引用系统调用。
例如,SCMP_ACT_ALLOW 操作可用于创建包含如上例所示的系统调用的白名单。
也可以使用 SCMP_ACT_ERRNO 操作定义另一个列表,但会有不同的返回值(errnoRet)。
你还可以指定传递给某些系统调用的参数(args)。有关这些高级用例的细节,请参见
OCI 运行时规范
和 Seccomp Linux 内核文档。
在 Kubernetes 中,节点的状态是管理 Kubernetes 集群的一个关键方面。在本文中,我们将简要介绍如何监控和维护节点状态以确保集群的健康和稳定。
一个节点的状态包含以下信息:
你可以使用 kubectl 来查看节点状态和其他细节信息:
kubectl describe node <节点名称>
下面对输出的每个部分进行详细描述。
这些字段的用法取决于你的云服务商或者物理机配置。
--hostname-override 参数覆盖。conditions 字段描述了所有 Running 节点的状况。状况的示例包括:
| 节点状况 | 描述 |
|---|---|
Ready |
如节点是健康的并已经准备好接收 Pod 则为 True;False 表示节点不健康而且不能接收 Pod;Unknown 表示节点控制器在最近 node-monitor-grace-period 期间(默认 50 秒)没有收到节点的消息 |
DiskPressure |
True 表示节点存在磁盘空间压力,即磁盘可用量低,否则为 False |
MemoryPressure |
True 表示节点存在内存压力,即节点内存可用量低,否则为 False |
PIDPressure |
True 表示节点存在进程压力,即节点上进程过多;否则为 False |
NetworkUnavailable |
True 表示节点网络配置不正确;否则为 False |
如果使用命令行工具来打印已保护(Cordoned)节点的细节,其中的 Condition 字段可能包括
SchedulingDisabled。SchedulingDisabled 不是 Kubernetes API 中定义的
Condition,被保护起来的节点在其规约中被标记为不可调度(Unschedulable)。
在 Kubernetes API 中,节点的状况表示节点资源中 .status 的一部分。
例如,以下 JSON 结构描述了一个健康节点:
"conditions": [
{
"type": "Ready",
"status": "True",
"reason": "KubeletReady",
"message": "kubelet is posting ready status",
"lastHeartbeatTime": "2019-06-05T18:38:35Z",
"lastTransitionTime": "2019-06-05T11:41:27Z"
}
]
当节点上出现问题时,Kubernetes 控制面会自动创建与影响节点的状况对应的
污点。
例如当 Ready 状况的 status 保持 Unknown 或 False 的时间长于
kube-controller-manager 的 NodeMonitorGracePeriod(默认为 50 秒)时,
会造成 Unknown 状态下为节点添加 node.kubernetes.io/unreachable 污点或在
False 状态下为节点添加 node.kubernetes.io/not-ready 污点。
这些污点会影响悬决的 Pod,因为调度器在将 Pod 分配到节点时会考虑节点的污点。
已调度到节点的当前 Pod 可能会由于施加的 NoExecute 污点被驱逐。
Pod 还可以设置容忍度,
使得这些 Pod 仍然能够调度到且继续运行在设置了特定污点的节点上。
进一步的细节可参阅基于污点的驱逐 和根据状况为节点设置污点。
这两个值描述节点上的可用资源:CPU、内存和可以调度到节点上的 Pod 的个数上限。
capacity 块中的字段标示节点拥有的资源总量。
allocatable 块指示节点上可供普通 Pod 使用的资源量。
你可以通过学习如何在节点上预留计算资源 来进一步了解有关容量和可分配资源的信息。
Info 指的是节点的一般信息,如内核版本、Kubernetes 版本(kubelet 和 kube-proxy 版本)、
容器运行时详细信息,以及节点使用的操作系统。
kubelet 从节点收集这些信息并将其发布到 Kubernetes API。
To use this feature, you (or a cluster administrator) will need to enable the NodeDeclaredFeatures feature gate for all relevant components in your cluster.
See Enable Or Disable Feature Gates for more information.
此字段列出了通过特性门控在节点的
kubelet 上当前已启用的特定 Kubernetes 特性。
kubelet 会将这些特性以字符串列表的形式报告到 Node 对象的
.status.declaredFeatures 字段中。
此字段用于记录正在积极开发的新特性; 已完成且不再需要特性门控的功能被视为基线功能,无需在此字段中声明。 这反映的是 Kubernetes 特性的启用情况,而非节点底层操作系统或内核的特性。
有关更多详细信息,请参阅节点声明特性。
Kubernetes 节点发送的心跳帮助你的集群确定每个节点的可用性,并在检测到故障时采取行动。
对于节点,有两种形式的心跳:
与节点的 .status 更新相比,Lease 是一种轻量级资源。
使用 Lease 来表达心跳在大型集群中可以减少这些更新对性能的影响。
kubelet 负责创建和更新节点的 .status,以及更新它们对应的 Lease。
.status。
.status 更新的默认间隔为 5 分钟(比节点不可达事件的 40 秒默认超时时间长很多)。kubelet 会创建并每 10 秒(默认更新间隔时间)更新 Lease 对象。
Lease 的更新独立于节点的 .status 更新而发生。
如果 Lease 的更新操作失败,kubelet 会采用指数回退机制,从 200 毫秒开始重试,
最长重试间隔为 7 秒钟。要允许 Kubernetes 工作负载在 Linux 节点上使用交换分区,
你必须禁用 kubelet 在检测到交换分区时失败的默认行为,
并指定内存交换行为为 LimitedSwap:
可用的交换行为选项有:
NoSwapLimitedSwap要了解更多,请阅读交换内存管理。