Kubernetes 1.22 – 新增功能

2021-07-30 05:12:33

Kubernetes 1.22 即将发布,新鲜出炉!我们从哪里开始?此版本带来了 56 项增强功能,比 Kubernetes 1.21 中的 50 项和 Kubernetes 1.20 中的 43 项有所增加。在这 56 项增强功能中,13 项已升级为稳定版,多达 24 项是不断改进的现有功能,还有 16 项是全新的。很高兴看到这么多专注于安全性的新功能,例如替换 Pod 安全策略、无根模式以及默认启用 Seccomp。有很多要谈的,所以让我们开始了解 Kubernetes 1.22 中的新功能。在 Kubernetes 1.21 中被弃用后,我们知道 Pod 安全策略的替代品即将推出,但我们不知道它会是什么样子。现在,我们很高兴得知它将成为一个准入控制器,重用现有基础设施的一部分。不以 root 身份运行容器是排名第一的容器安全最佳实践。令人欣慰的是,这项措施正在发挥到极致,让我们能够在用户空间中运行整个 Kubernetes 堆栈。这真的会让 Kubernetes 更加安全。如果在此 Kubernetes 版本之后有一件事情很清楚,那就是向安全性的转变。默认情况下添加这一额外的安全层将使许多潜在的漏洞利用变得毫无意义。像这样的步骤绝对会改变人们对 Kubernetes 的看法。我们希望在每个 Kubernetes 版本中看到的那些小细节之一,它不会成为头条新闻,但会让生活变得更轻松。 Swap 是每个开发人员都应该拥有的。通过支持,在使用 Kubernetes 时可以少担心一件事。

与交换一样,很高兴看到对更多原生 Linux 功能的支持。在这种情况下,Cgroupsv2 为内存 QoS 启用了更多选项,这(在 Kubernetes 1.22 中)将有助于避免在 Kubernetes 中运行的工作负载的性能限制。正如 Kat Cosgrove 警告我们的那样,Kubernetes 1.22 中删除了一些测试版 API 和功能,包括: 未弃用,但已删除。这意味着您将无法使用功能标志重新启用它们。如果您正在使用它们,则必须迁移到它们的稳定版本。在 Kubernetes 博客中查看完整的移除和迁移步骤列表。并保留已弃用的 API 迁移指南以备将来使用。 StreamingProxyRedirects 功能最初是为了减轻由容器运行时接口的实现驱动的请求开销而开发的。理由是绕过 kubelet,性能不会受到太大影响。然而,由于所有请求都集中在 apiserver 中,这些理论上的改进并不那么重要。此外,一些安全问题需要实现 ValidateProxyRedirects 功能。在 1.20 中最初被弃用后,功能门在 1.22 中已被禁用。在 Kubernetes 1.24 中,这些功能将被删除,配置容器流的唯一方法是使用带有 Kubelet 代理方法的本地重定向。检查 KEP 中的完整详细信息。

正如我们在上一个版本中提到的,#2433 Topology Aware Hints 增强将取代 Kubernetes 1.17 中引入的 ServiceTopology 功能门。自 Kubernetes 1.11 开始测试后,Kubernetes 团队决定弃用 DynamicKubeletConfig 而不是继续其开发。此功能旨在将逻辑从 kubectl apply 移到 apiserver,修复当前的大部分工作流程陷阱,并使操作可直接从 API 访问(例如使用 curl),而无需严格要求 kubectl 或 Golang 实现。从现在开始,API 服务器将包含一个带有弃用信息的警告标头。这包括何时引入 API、何时弃用以及何时删除。所有命名空间都添加了一个新的不可变标签 kubernetes.io/metadata.name,其值为命名空间名称。这个标签可以与任何命名空间选择器一起使用,就像前面提到的 NetworkPolicy 对象一样。 APIPriorityAndFairness 功能门在 API 服务器中启用了新的 max-in-flight 请求处理程序。通过使用 FlowSchema 对象定义不同类型的请求并使用 RequestPriority 对象为其分配资源,您可以确保 Kubernetes API 服务器能够在高负载期间响应管理和维护任务。通过此增强功能,作业将能够更早地删除已完成的 pod,从而释放集群中的资源。

当前的 Job 控制器通过在完成后将 Pod 保持在延迟状态来跟踪已完成的 Job。只有当 Job 完成时才会移除 Pod,并释放资源。使用新方法,作业控制器将跟踪已完成的作业,同时允许删除已完成的 Pod。此增强为 StatefulSets 带来了可选的 minReadySeconds 字段,该字段已在 Deployments、DaemonSets、ReplicasSets 和 Replication Controllers 上可用。如果声明,新创建的 Pod 将不会被视为可用,直到它们的容器在指定的秒数内保持就绪状态而不会崩溃。在 Kubernetes 1.4 和 1.8 之后的测试版中引入,CronJobs 终于走上了稳定的道路。使用此 API,您可以为 Pod 定义 minAvailable 副本数。如果您尝试以违反 minAvailable 值的方式自愿中断 Pod,它将不会被删除。在 Kubernetes 1.21 中,我们看到了 PodDisruptionBudget 升级到 GA,而在 Kubernetes 1.22 中,我们看到了 Eviction 子资源的升级:

在执行滚动更新时,此增强功能允许指定将创建多少个新 Pod 来替换旧 Pod。这是通过可选的 spec.strategy.rollingUpdate.maxSurge 字段完成的。通过分配一个绝对数量,您可以告诉在所需的 Pod 数量上可以创建的最大 Pod 数量。该值也可以是所需 Pod 的百分比。与之前的行为相匹配的默认值为 25%。当启用 LogarithmicScaleDown 功能门时,将使用半随机选择的 Pod 来根据 Pod 时间戳的对数分桶缩小 ReplicaSet。您现在可以使用 controller.kubernetes.io/pod-deletion-cost=10 注释 Pod,其中 0 是默认值。在缩小规模时,将尽最大努力以较低的删除成本删除 Pod。 Kubernetes 1.21 中引入了索引作业,以便更轻松地调度高度并行化的作业。此增强功能将完成索引添加到具有固定完成计数的作业的 Pod 中,以支持运行令人尴尬的并行程序。这样,就可以通过环境变量将作业索引传递给 Pod,甚至可以创建索引作业,其中 Pod 可以通过从索引构建的主机名相互寻址:

[...] 规范:子域:my-job-svc 容器:-名称:任务图像:registry.example.com/processing-image 命令:[“./process”、“--index”、“$JOB_COMPLETION_INDEX” , "--hosts-pattern", "my-job-{{.id}}.my-job-svc"] 从 Kubernetes 1.21 开始,可以通过将作业的 .spec.suspend 字段设置为 true 来临时暂停作业,稍后通过将其设置回 false 来恢复。这个新的准入控制器将能够按命名空间实施 Pod 安全标准。可以在三个级别执行强制执行: 审计:策略违规将触发添加审计注释,但在其他情况下是允许的。 apiVersion: apiserver.config.k8s.io/v1 kind: AdmissionConfiguration plugins: - name: PodSecurity configuration: defaults: # 未设置模式标签时应用的默认值。强制:<默认强制策略级别>强制版本:<默认强制策略版本>审计:<默认审计策略级别>审计版本:<默认审计策略版本>警告:<默认警告策略级别>警告版本:<默认值警告策略版本> 豁免:用户名:[ <要豁免的经过身份验证的用户名数组> ] runtimeClassNames:[ <要豁免的运行时类名数组> ] 命名空间:[ <要豁免的命名空间数组> ] 要了解更多关于这背后的基本原理增强和可能的新发展,请检查 KEP。此增强功能允许 Go 客户端使用外部凭据提供程序进行身份验证,例如密钥管理系统 (KMS)、可信平台模块 (TPM) 或硬件安全模块 (HSM)。

这些设备已经用于针对其他服务进行身份验证,更容易轮换并且更安全,因为它们不作为磁盘上的文件存在。该特性最初是在 Kubernetes 1.10 上引入的,它总结了 1.20 和 1.21 中完成的工作。工作负载用于针对 API 进行身份验证的当前 JSON Web 令牌 (JWT) 存在一些安全问题。此增强包括为 JWT 创建更安全的 API 的工作。到目前为止,Certificates API 的客户端无法为已颁发的证书请求特定的持续时间。对于每个新证书,此持续时间默认为一年,对于某些用例来说可能太长了。 CertificateSigningRequestSpec 中添加了一个新的 ExpirationSeconds 字段,该字段接受的最小值为 600 秒(10 分钟)。此增强接近边缘情况,如果端点数量更改为 0,则具有 externalTrafficPolicy=Local 的服务将丢弃来自负载均衡器的所有流量。此行为使此类服务不可能实现零停机滚动更新。

实施的解决方案是将受影响节点上的所有外部流量发送到就绪和未就绪终止端点(首选就绪端点)。通过此增强功能,Kubernetes 允许更多 DNS 搜索路径和更长的 DNS 搜索路径列表,以跟上最近的 DNS 解析器。新的 EndpointSlice API 将端点拆分为多个 Endpoint Slice 资源。这解决了当前 API 中与大型 Endpoints 对象相关的许多问题。这个新 API 还旨在支持其他未来功能,例如每个 pod 多个 IP。在 Kubernetes 1.22 中值得注意的是,如果一个 Endpoints 资源有超过 1000 个端点,集群会用 endpoints.kubernetes.io/over-capacity: truncated 对它们进行注释,之前用 endpoints.kubernetes.io/over-capacity: warning 注释。 . LoadBalancer API 的一些实现不使用 Kubernetes 自动分配的节点端口,如 MetalLB 或 kube-router。但是,API 需要定义和分配一个端口,即使它没有被使用。当Service.Spec中的allocateLoadBalancerNodePort字段设置为false时,将停止分配新的节点端口。此增强功能将允许您将 NetworkPolicy 中的所有端口定义为一个范围:

您现在可以在 Service 对象上设置 spec.trafficPolicy 字段以优化集群流量:通过此增强功能,您现在可以为具有命名空间范围的 IngressClass 指定参数。通过此增强功能,Kubernetes 更进了一步,允许您以非 root 用户身份运行整个 Kubernetes 堆栈。这样,如果您的集群遭到入侵,攻击者将很难访问您的基础设施的其余部分。您可以通过启用 KubeletInUserNamespace 功能门并按照以下说明在无根模式下运行 Kubernetes。但是,请记住,您必须解决很多注意事项。 Cgroups 是 Linux 内核功能,它限制、说明和隔离进程集合的资源使用(CPU、内存、磁盘 I/O、网络等)。两年多前,它的 v2 API 被宣布为稳定版本,并且许多 Linux 发行版已经在默认情况下使用它。此增强功能涵盖了使 Kubernetes 与 Cgroups v2 兼容所做的工作,从配置文件开始。

检查新的配置值,因为值的范围会有一些变化。例如 cpu.weight 值将从 [2-262144] 更改为 [1-10000]。此增强功能不包括启用 v2 中 v1 中不可用的新功能。它也不包括 v1 的弃用。 Swap(Linux 中的磁盘内存)并不是最快的。但是,有多种工作负载(例如 Java 和 Node 应用程序)可以从中受益。此增强功能使 Kubernetes 工作负载能够使用交换。目前,该配置是整个节点的全局配置,不能针对每个工作负载进行配置。使用方法:Kubernetes 目前允许您提高容器的安全性,使用 Seccomp 配置文件执行它们。此增强功能将默认启用此选项,有助于防止 CVE 和零日漏洞。您可以使用 SeccompDefault 启用此行为,这会将现有的 RuntimeDefault 配置文件转换为任何容器的默认配置。 memory.low:尽力而为的内存保护,一种“软保证”,即如果 cgroup 及其所有后代都低于此阈值,则不会回收 cgroup 的内存,除非无法从任何未受保护的 cgroup 中回收内存。暂时还没考虑。

memory.high:如果 cgroup 的内存使用超过了此处指定的上限,则 cgroup 的进程将受到限制并承受沉重的回收压力。此增强功能允许 CPU 管理器将独占工作负载分配给特定的 CPU 内核。隔离每个 CPU 内核的工作负载可避免上下文和缓存切换,这对于延迟敏感的应用程序至关重要。 CPU 管理器上提供了一个新的 --cpu-manager-policy-options 选项。当设置为 full-pcups-only=true 时,节点将隔离每个物理 CPU 内核的工作负载。请注意,它只会接受使用整个 CPU 的工作负载。其次,HugePages 的容器隔离已经到位,以解决一个问题,即 pod 可能使用比请求更多的内存,最终导致资源匮乏。现在,可以将 pod 的主机名设置为其完全限定域名 (FQDN),从而提高 Kubernetes 与遗留应用程序的互操作性。设置 hostnameFQDN: true 后,在 Pod 内运行 uname -n 会返回 foo.test.bar.svc.cluster.local 而不仅仅是 foo。该特性是在 Kubernetes 1.19 上引入的,更多细节可以在增强提案中阅读。

临时容器是调试正在运行的 Pod 的好方法。尽管您无法在创建后将常规容器添加到 pod,但您可以使用 kubectl debug 运行临时容器。 kubelet 中提供了一个新的内存管理器组件,以保证为 pod 分配内存和大页面。它只会作用于有保证的 QoS 类中的 Pod。当 Pod 定义了一个内存支持的空目录卷(例如,tmpfs)时,并非所有主机都将该卷的大小相同。例如,Linux 主机将其大小调整为主机内存的 50%。这种新的增强功能不仅会考虑节点可分配内存,还会考虑 pod 可分配内存和 emptyDir.sizeLimit 字段来调整卷大小。这个增强在 livenessProbe 对象中引入了第二个 terminateGracePeriodSeconds 字段,以区分两种情况:在正常情况下 Kubernetes 应该等待多长时间来杀死容器,以及由于 livenessProbe 失败而何时终止? ComponentConfig 正在不断努力,使组件配置更加动态且可通过 Kubernetes API 直接访问。此功能允许您使用 Pod 内的 .status.nominatedNodeName 字段定义首选节点,以加快大型集群中的调度过程。通过在部署中定义节点亲和性,您可以限制您的 pod 将被安排在哪些节点上。例如,在已经运行 Pod 的节点上部署示例标签的标签值。

此增强功能添加了 namespaceSelector 字段,因此您可以通过标签而不是名称来指定名称空间。使用此字段,您可以动态定义命名空间集。默认调度器的三个分数插件(NodeResourcesLeastAllocated、NodeResourcesMostAllocated 和 RequestedToCapacityRatio)实现了首选资源分配的互斥策略。此增强功能通过弃用这些插件并将它们组合到单个 NodeResourcesFit 插件下,使用可设置为 LeastAllocated(默认值)、MostAllocated 和 RequestedToCapacityRatio 的 ScoringStrategy 属性来简化调度程序。在容器内绑定挂载 CSI 卷之前,Kubernetes 通过 fsGroup 修改卷所有权。对于大多数卷插件,kubelet 通过递归 chowning 和 chmoding 卷内的文件和目录来实现。但是,chown 和 chmod 是 unix 原语,因此它们不可用于某些 CSI 驱动程序,例如 AzureFile。此增强建议为 CSI 驱动程序提供 pod 的 fsgroup 作为显式字段,因此它可以是 CSI 驱动程序在挂载时本机应用它。对于支持 VOLUME_MOUNT_GROUP NodeServiceCapability 的驱动程序,可以使用 DelegateFSGroupToCSIDriver 功能门启用此行为。 fsGroup 应该在 securityContext 中指定。通过此增强功能,可以以 ReadWriteOncePod 模式访问 PersistenVolumes,从而限制对单个节点上的单个 Pod 的访问。

虽然现有的 ReadWriteOnce 访问模式限制对单个节点的访问,但允许从该节点上的多个 Pod 同时访问。通过此增强功能,CSI 驱动程序将能够从 Kubelet 向 NodePublishVolume 函数请求服务帐户令牌。 Kubelet 还将能够限制哪些令牌可供哪个驱动程序使用。最后,驱动程序将能够通过将 RequiresRepublish 设置为 true 来重新执行 NodePublishVolume 以重新安装卷。当安装的卷可能过期并需要重新登录时,最后一个功能将派上用场。例如,秘密保险库。此增强功能在 Kubernetes 1.18 中引入,为用户创建预填充卷奠定了基础。例如,使用操作系统映像为虚拟机预填充磁盘,或启用数据备份和还原。为此,将取消对持久卷的 DataSource 字段的当前验证,允许将任意对象设置为值。关于如何填充卷的实现细节委托给专门构建的控制器。特权容器可以访问主机,就好像它们直接在主机上运行一样。尽管不建议将它们用于大多数工作负载,但它们对于管理、安全和监视目的非常有用。如果您的集群启用了 WindowsHostProcessContainers 功能,您可以通过在 pod 规范的安全上下文中设置 windowsOptions.hostProcess 标志来创建 Windows HostProcess pod。这些 Pod 中的所有容器都必须作为 Windows HostProcess 容器运行。

容器存储接口插件的创建是为了允许第三方存储卷系统的开发。从 Kubernetes 1.16 开始,Windows 节点可以使用现有的 CSI 插件。现在这个功能是稳定的。此增强功能改进了 API 服务器,以允许使用 OpenTelemetry 库和 OpenTelemetry 格式跟踪请求。您可以通过 APIServerTracing 功能门启用跟踪,并使用 --tracing-config-file=<path-to-config> 启动 apiserver,其中配置文件如下所示:与#2033 Rootless 模式容器相关,这个 enh ......