这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

Kubernetes 博客

Kubernetes 1.26:PodDisruptionBudget 守护的不健康 Pod 所用的驱逐策略

作者: Filip Křepinský (Red Hat), Morten Torkildsen (Google), Ravi Gudimetla (Apple)

译者: Michael Yao (DaoCloud)

确保对应用的干扰不影响其可用性不是一个简单的任务。 上个月发布的 Kubernetes v1.26 允许针对 PodDisruptionBudget (PDB) 指定不健康 Pod 驱逐策略,这有助于在节点执行管理操作期间保持可用性。

这解决什么问题?

API 发起的 Pod 驱逐尊重 PodDisruptionBudget (PDB) 约束。这意味着因驱逐 Pod 而请求的自愿干扰不应干扰守护的应用且 PDB 的 .status.currentHealthy 不应低于 .status.desiredHealthy。 如果正在运行的 Pod 状态为 Unhealthy, 则该 Pod 不计入 PDB 状态,只有在应用不受干扰时才可以驱逐这些 Pod。 这有助于尽可能确保受干扰或还未启动的应用的可用性,不会因驱逐造成额外的停机时间。

不幸的是,对于想要腾空节点但又不进行任何手动干预的集群管理员而言,这种机制是有问题的。 若一些应用因 Pod 处于 CrashLoopBackOff 状态(由于漏洞或配置错误)或 Pod 无法进入就绪状态而行为异常, 会使这项任务变得更加困难。当某应用的所有 Pod 均不健康时,所有驱逐请求都会因违反 PDB 而失败。 在这种情况下,腾空节点不会有任何作用。

另一方面,有些用户依赖于现有行为,以便:

  • 防止因删除守护基础资源或存储的 Pod 而造成数据丢失
  • 让应用达到最佳可用性

Kubernetes 1.26 为 PodDisruptionBudget API 引入了新的实验性字段: .spec.unhealthyPodEvictionPolicy。启用此字段后,将允许你支持上述两种需求。

工作原理

API 发起的驱逐是触发 Pod 优雅终止的一个进程。 这个进程可以通过直接调用 API 发起,也能使用 kubectl drain 或集群中的其他主体来发起。 在这个过程中,移除每个 Pod 时将与对应的 PDB 协商,确保始终有足够数量的 Pod 在集群中运行。

以下策略允许 PDB 作者进一步控制此进程如何处理不健康的 Pod。

有两个策略可供选择:IfHealthyBudgetAlwaysAllow

前者,IfHealthyBudget 采用现有行为以达到你默认可获得的最佳的可用性。 不健康的 Pod 只有在其应用中可用的 Pod 个数达到 .status.desiredHealthy 即最小可用个数时才会被干扰。

通过将 PDB 的 spec.unhealthyPodEvictionPolicy 字段设置为 AlwaysAllow, 可以表示尽可能为应用选择最佳的可用性。采用此策略时,始终能够驱逐不健康的 Pod。 这可以简化集群的维护和升级。

我们认为 AlwaysAllow 通常是一个更好的选择,但是对于某些关键工作负载, 你可能仍然倾向于防止不健康的 Pod 被从节点上腾空或其他形式的 API 发起的驱逐。

如何使用?

这是一个 Alpha 特性,意味着你必须使用命令行参数 --feature-gates=PDBUnhealthyPodEvictionPolicy=true 为 kube-apiserver 启用 PDBUnhealthyPodEvictionPolicy 特性门控

以下是一个例子。假设你已在集群中启用了此特性门控且你已定义了运行普通 Web 服务器的 Deployment。 你已为 Deployment 的 Pod 打了标签 app: nginx。 你想要限制可避免的干扰,你知道对于此应用而言尽力而为的可用性也是足够的。 你决定即使这些 Web 服务器 Pod 不健康也允许驱逐。 你创建 PDB 守护此应用,使用 AlwaysAllow 策略驱逐不健康的 Pod:

apiVersion: policy/v1
kind: PodDisruptionBudget
metadata:
  name: nginx-pdb
spec:
  selector:
    matchLabels:
      app: nginx
  maxUnavailable: 1
  unhealthyPodEvictionPolicy: AlwaysAllow

查阅更多资料

我如何参与?

如果你有任何反馈,请通过 Slack #sig-apps 频道 (如有需要,请访问 https://slack.k8s.io/ 获取邀请)或通过 SIG Apps 邮件列表 kubernetes-sig-apps@googlegroups.com 联系我们。

Kubernetes v1.26:CPUManager 正式发布

作者: Francesco Romani (Red Hat)

译者: Michael Yao (DaoCloud)

CPU 管理器是 kubelet 的一部分;kubelet 是 Kubernetes 的节点代理,能够让用户给容器分配独占 CPU。 CPU 管理器自从 Kubernetes v1.10 进阶至 Beta, 已证明了它本身的可靠性,能够充分胜任将独占 CPU 分配给容器,因此采用率稳步增长, 使其成为性能关键型和低延迟场景的基本组件。随着时间的推移,大多数变更均与错误修复或内部重构有关, 以下列出了几个值得关注、用户可见的变更:

CPU 管理器达到了“能胜任”的水平,因此在 Kubernetes v1.26 中,它进阶至正式发布(GA)状态。

CPU 管理器的自定义选项

CPU 管理器支持两种操作模式,使用其策略进行配置。 使用 none 策略,CPU 管理器将 CPU 分配给容器,除了 Pod 规约中设置的(可选)配额外,没有任何特定限制。 使用 static 策略,假设 Pod 属于 Guaranteed QoS 类,并且该 Pod 中的每个容器都请求一个整数核数的 vCPU, 则 CPU 管理器将独占分配 CPU。独占分配意味着(无论是来自同一个 Pod 还是来自不同的 Pod)其他容器都不会被调度到该 CPU 上。

这种简单的操作模型很好地服务了用户群体,但随着 CPU 管理器越来越成熟, 用户开始关注更复杂的使用场景以及如何更好地支持这些使用场景。

社区没有添加更多策略,而是意识到几乎所有新颖的用例都是 static CPU 管理器策略所赋予的一些行为变化。 因此,决定添加[调整静态策略行为的选项](https://github.com/Kubernetes/enhancements/tree/master/keps/sig-node/2625-cpumanager-policies-thread-placement #proposed-change)。 这些选项都达到了不同程度的成熟度,类似于其他的所有 Kubernetes 特性, 为了能够被接受,每个新选项在禁用时都能提供向后兼容的行为,并能在需要进行交互时记录彼此如何交互。

这使得 Kubernetes 项目能够将 CPU 管理器核心组件和核心 CPU 分配算法进阶至 GA,同时也开启了该领域新的实验时代。 在 Kubernetes v1.26 中,CPU 管理器支持三个不同的策略选项

full-pcpus-only
将 CPU 管理器核心分配算法限制为仅支持完整的物理核心,从而减少允许共享核心的硬件技术带来的嘈杂邻居问题。
distribute-cpus-across-numa
驱动 CPU 管理器跨 NUMA 节点均匀分配 CPU,以应对需要多个 NUMA 节点来满足分配的情况。
align-by-socket
更改 CPU 管理器将 CPU 分配给容器的方式:考虑 CPU 按插槽而不是 NUMA 节点边界对齐。

后续发展

在主要 CPU 管理器特性进阶后,每个现有的策略选项将遵循其进阶过程,独立于 CPU 管理器和其他选项。 添加新选项的空间虽然存在,但随着对更高灵活性的需求不断增长,CPU 管理器及其策略选项当前所提供的灵活性也有不足。

社区中正在讨论如何将 CPU 管理器和当前属于 kubelet 可执行文件的其他资源管理器拆分为可插拔的独立 kubelet 插件。 如果你对这项努力感兴趣,请加入 SIG Node 交流频道(Slack、邮件列表、每周会议)进行讨论。

进一步阅读

请查阅控制节点上的 CPU 管理策略任务页面以了解有关 CPU 管理器的更多信息及其如何适配其他节点级别资源管理器。

参与其中

此特性由 SIG Node 社区驱动。 请加入我们与社区建立联系,就上述特性和更多内容分享你的想法和反馈。我们期待你的回音!

Kubernetes 1.26:Pod 调度就绪态

作者: Wei Huang (Apple), Abdullah Gharaibeh (Google)

译者: XiaoYang Zhang (HuaWei)

Kubernetes 1.26 引入了一个新的 Pod 特性:调度门控。 在 Kubernetes 中,调度门控是通知调度器何时可以考虑 Pod 调度的关键。

它解决了什么问题?

当 Pod 被创建时,调度器会不断尝试寻找适合它的节点。这个无限循环一直持续到调度程序为 Pod 找到节点,或者 Pod 被删除。

长时间无法被调度的 Pod(例如,被某些外部事件阻塞的 Pod)会浪费调度周期。 一个调度周期可能需要约 20ms 或更长时间,这取决于 Pod 的调度约束的复杂度。 因此,大量浪费的被调度周期会严重影响调度器的性能。请参阅下面 “调度器” 框中的箭头。

graph LR; pod((新 Pod))-->queue subgraph 调度器 queue(调度器队列) sched_cycle[/调度周期/] schedulable{可调度?} queue==>|弹出|sched_cycle sched_cycle==>schedulable schedulable==>|否|queue subgraph note [循环浪费在不断重新安排 'unready' 状态的 Pod 上] end end classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef Scheduler fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; classDef note fill:#edf2ae,stroke:#fff,stroke-width:1px; class queue,sched_cycle,schedulable k8s; class pod plain; class note note; class Scheduler Scheduler;

调度门控有助于解决这个问题。它允许声明新创建的 Pod 尚未准备好进行调度。 当 Pod 上设置了调度门控时,调度程序会忽略该 Pod,从而避免不必要的调度尝试。 如果你在集群中安装了 Cluster Autoscaler,这些 Pod 也将被忽略。

清除门控是外部控制器的责任,外部控制器知道何时应考虑对 Pod 进行调度(例如,配额管理器)。

graph LR; pod((新 Pod))-->queue subgraph 调度器 queue(调度器队列) sched_cycle[/调度周期/] schedulable{可调度?} popout{弹出?} queue==>|PreEnqueue 检查|popout popout-->|是|sched_cycle popout==>|否|queue sched_cycle-->schedulable schedulable-->|否|queue subgraph note [控制 Pod 调度的开关] end end classDef plain fill:#ddd,stroke:#fff,stroke-width:1px,color:#000; classDef k8s fill:#326ce5,stroke:#fff,stroke-width:1px,color:#fff; classDef Scheduler fill:#fff,stroke:#bbb,stroke-width:2px,color:#326ce5; classDef note fill:#edf2ae,stroke:#fff,stroke-width:1px; classDef popout fill:#f96,stroke:#fff,stroke-width:1px; class queue,sched_cycle,schedulable k8s; class pod plain; class note note; class popout popout; class Scheduler Scheduler;

它是如何工作的?

总体而言,调度门控的工作方式与 Finalizer 非常相似。具有非空 spec.schedulingGates 字段的 Pod 的状态将显示为 SchedulingGated,并阻止被调度。请注意,添加多个门控是可以的,但它们都应该在创建 Pod 时添加(例如,你可以将它们作为规约的一部分或者通过变更性质的 Webhook)。

NAME       READY   STATUS            RESTARTS   AGE
test-pod   0/1     SchedulingGated   0          10s

要清除这些门控,你可以通过删除 Pod 的 schedulingGates 字段中的所有条目来更新 Pod。 不需要一次性移除所有门控,但是,只有当所有门控都移除后,调度器才会开始考虑对 Pod 进行调度。

在后台,调度门控以 PreEnqueue 调度器插件的方式实现,这是调度器框架的新扩展点,在每个调度周期开始时调用。

用例

此特性所支持的一个重要使用场景是动态配额管理。Kubernetes 支持资源配额, 但是 API Server 会在你尝试创建 Pod 时强制执行配额。例如,如果一个新的 Pod 超过了 CPU 配额,它就会被拒绝。 API Server 不会对 Pod 进行排队;因此,无论是谁创建了 Pod,都需要不断尝试重新创建它。 这意味着在资源可用和 Pod 实际运行之间会有延迟,或者意味着由于不断尝试,会增加 API Server 和 Scheduler 的负载。

调度门控允许外部配额管理器解决 ResourceQuota 的上述限制。具体来说, 管理员可以(使用变更性质的 Webhook)为集群中创建的所有 Pod 添加一个 example.com/quota-check 调度门控。当存在用于启动 Pod 的配额时,管理器将移除此门控

接下来

要使用此特性,必须在 API Server 和调度器中启用 PodScheduleingReadiness 特性门控。 非常欢迎你对其进行测试并告诉我们(SIG Scheduling)你的想法!

附加资源

Kubernetes 1.26: 支持在挂载时将 Pod fsGroup 传递给 CSI 驱动程序

作者: Fabio Bertinatto (Red Hat), Hemant Kumar (Red Hat)

译者: Xin Li (DaoCloud)

fsGroup 委托给 CSI 驱动程序管理首先在 Kubernetes 1.22 中作为 Alpha 特性引入, 并在 Kubernetes 1.25 中进阶至 Beta 状态。 对于 Kubernetes 1.26,我们很高兴地宣布此特性已进阶至正式发布(GA)状态。

在此版本中,如果你在 Pod(Linux) 的安全上下文中指定一个 fsGroup, 则该 Pod 容器中的所有进程都是该附加组的一部分。

在以前的 Kubernetes 版本中,kubelet 总是根据 Pod 的 .spec.securityContext.fsGroupChangePolicy 字段中指定的策略, 将 fsGroup 属主关系和权限的更改应用于卷中的文件。

从 Kubernetes 1.26 开始,CSI 驱动程序可以选择在卷挂载期间应用 fsGroup 设置, 这使 kubelet 无需更改这些卷中文件和目录的权限。

它是如何工作的?

支持此功能的 CSI 驱动程序应通告其 VOLUME_MOUNT_GROUP 节点能力。

kubelet 识别此信息后,在 Pod 启动期间将 fsGroup 信息传递给 CSI 驱动程序。 这个过程是通过 NodeStageVolumeRequestNodePublishVolumeRequest CSI 调用完成的。

因此,CSI 驱动程序应使用挂载选项fsGroup 应用到卷中的文件上。 例如,Azure File CSIDriver 利用 gid 挂载选项将 fsGroup 信息映射到卷中的所有文件。

应该注意的是,在上面的示例中,kubelet 避免直接将权限更改应用于该卷文件中的文件和目录。 此外,有两个策略定义不再有效:CSIDriver 对象的 .spec.fsGroupPolicy 和 Pod 的 .spec.securityContext.fsGroupChangePolicy 都不再起作用。

有关此功能内部工作原理的更多详细信息,请查看 CSI 开发人员文档中的增强建议CSI 驱动程序 fsGroup 支持

这一特性为何重要?

如果没有此功能,则无法在某些存储环境中将 fsGroup 信息应用于文件。

例如,Azure 文件不支持 POSIX 风格的文件所有权和权限概念,CSI 驱动程序只能在卷级别设置文件权限。

我该如何使用它?

此功能应该对用户基本透明。如果你维护应支持此功能的 CSI 驱动程序, 请阅读 CSI 驱动程序 fsGroup 支持 以获取有关如何在你的 CSI 驱动程序中支持此功能的更多信息。

不支持此功能的现有 CSI 驱动程序将继续照常工作:他们不会从 kubelet 收到任何 fsGroup 信息。除此之外,kubelet 将根据 CSIDriver 的 .spec.fsGroupPolicy 和相关 Pod 的 .spec.securityContext.fsGroupChangePolicy 中指定的策略,继续对这些卷中文件的属主关系和权限进行更改。

Kubernetes 1.26: 动态资源分配 Alpha API

作者: Patrick Ohly (Intel)、Kevin Klues (NVIDIA)

译者: 空桐

动态资源分配是一个用于请求资源的新 API。 它是对为通用资源所提供的持久卷 API 的泛化。它可以:

  • 在不同的 pod 和容器中访问相同的资源实例,
  • 将任意约束附加到资源请求以获取你正在寻找的确切资源,
  • 通过用户提供的参数初始化资源。

第三方资源驱动程序负责解释这些参数,并在资源请求到来时跟踪和分配资源。

动态资源分配是一个 alpha 特性,只有在启用 DynamicResourceAllocation 特性门控resource.k8s.io/v1alpha1 API 组 时才启用。 有关详细信息,参阅 --feature-gates--runtime-config kube-apiserver 参数。 kube-scheduler、kube-controller-manager 和 kubelet 也需要设置该特性门控。

kube-scheduler 的默认配置仅在启用特性门控时才启用 DynamicResources 插件。 自定义配置可能需要被修改才能启用它。

一旦启用动态资源分配,就可以安装资源驱动程序来管理某些类型的硬件。 Kubernetes 有一个用于端到端测试的测试驱动程序,但也可以手动运行。 逐步说明参见下文

API

新的 resource.k8s.io/v1alpha1 API 组提供了四种新类型:

ResourceClass
定义由哪个资源驱动程序处理哪种资源,并为其提供通用参数。 在安装资源驱动程序时,由集群管理员创建 ResourceClass。
ResourceClaim
定义工作负载所需的特定资源实例。 由用户创建(手动管理生命周期,可以在不同的 Pod 之间共享), 或者由控制平面基于 ResourceClaimTemplate 为特定 Pod 创建 (自动管理生命周期,通常仅由一个 Pod 使用)。
ResourceClaimTemplate
定义用于创建 ResourceClaim 的 spec 和一些元数据。 部署工作负载时由用户创建。
PodScheduling
供控制平面和资源驱动程序内部使用, 在需要为 Pod 分配 ResourceClaim 时协调 Pod 调度。

ResourceClass 和 ResourceClaim 的参数存储在单独的对象中, 通常使用安装资源驱动程序时创建的 CRD 所定义的类型。

启用此 Alpha 特性后,Pod 的 spec 定义 Pod 运行所需的 ResourceClaim: 此信息放入新的 resourceClaims 字段。 该列表中的条目引用 ResourceClaim 或 ResourceClaimTemplate。 当引用 ResourceClaim 时,使用此 .spec 的所有 Pod (例如 Deployment 或 StatefulSet 中的 Pod)共享相同的 ResourceClaim 实例。 引用 ResourceClaimTemplate 时,每个 Pod 都有自己的实例。

对于 Pod 中定义的容器,resources.claims 列表定义该容器可以访问的资源实例, 从而可以在同一 Pod 中的一个或多个容器之间共享资源。 例如,init 容器可以在应用程序使用资源之前设置资源。

下面是一个虚构的资源驱动程序的示例。 此 Pod 将创建两个 ResourceClaim 对象,每个容器都可以访问其中一个。

假设已安装名为 resource-driver.example.com 的资源驱动程序和以下资源类:

apiVersion: resource.k8s.io/v1alpha1
kind: ResourceClass
name: resource.example.com
driverName: resource-driver.example.com

这样,终端用户可以按如下方式分配两个类型为 resource.example.com 的特定资源:

---
apiVersion: cats.resource.example.com/v1
kind: ClaimParameters
name: large-black-cats
spec:
  color: black
  size: large
---
apiVersion: resource.k8s.io/v1alpha1
kind: ResourceClaimTemplate
metadata:
  name: large-black-cats
spec:
  spec:
    resourceClassName: resource.example.com
    parametersRef:
      apiGroup: cats.resource.example.com
      kind: ClaimParameters
      name: large-black-cats
–--
apiVersion: v1
kind: Pod
metadata:
  name: pod-with-cats
spec:
  containers: # 两个示例容器;每个容器申领一个 cat 资源
  - name: first-example
    image: ubuntu:22.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-0
  - name: second-example
    image: ubuntu:22.04
    command: ["sleep", "9999"]
    resources:
      claims:
      - name: cat-1
  resourceClaims:
  - name: cat-0
    source:
      resourceClaimTemplateName: large-black-cats
  - name: cat-1
    source:
      resourceClaimTemplateName: large-black-cats

调度

与原生资源(CPU、RAM)和扩展资源 (由设备插件管理,并由 kubelet 公布)不同,调度器不知道集群中有哪些动态资源, 也不知道如何将它们拆分以满足特定 ResourceClaim 的要求。 资源驱动程序负责这些任务。 资源驱动程序在为 ResourceClaim 保留资源后将其标记为已分配(Allocated)。 然后告诉调度器集群中可用的 ResourceClaim 的位置。

ResourceClaim 可以在创建时就进行分配(立即分配),不用考虑哪些 Pod 将使用该资源。 默认情况下采用延迟分配(等待第一个消费者), 直到依赖于 ResourceClaim 的 Pod 有资格调度时再进行分配。 这种两种分配选项的设计与 Kubernetes 处理 PersistentVolume 和 PersistentVolumeClaim 供应的存储类似。

在等待第一个消费者模式下,调度器检查 Pod 所需的所有 ResourceClaim。 如果 Pod 有 ResourceClaim,则调度器会创建一个 PodScheduling 对象(一种特殊对象,代表 Pod 请求调度详细信息)。 PodScheduling 的名称和命名空间与 Pod 相同,Pod 是它的所有者。 调度器使用 PodScheduling 通知负责这些 ResourceClaim 的资源驱动程序,告知它们调度器认为适合该 Pod 的节点。 资源驱动程序通过排除没有足够剩余资源的节点来响应调度器。

一旦调度器有了资源信息,它就会选择一个节点,并将该选择存储在 PodScheduling 对象中。 然后,资源驱动程序分配其 ResourceClaim,以便资源可用于选中的节点。 一旦完成资源分配,调度器尝试将 Pod 调度到合适的节点。这时候调度仍然可能失败; 例如,不同的 Pod 可能同时被调度到同一个节点。如果发生这种情况,已分配的 ResourceClaim 可能会被取消分配,从而让 Pod 可以被调度到不同的节点。

作为此过程的一部分,ResourceClaim 会为 Pod 保留。 目前,ResourceClaim 可以由单个 Pod 独占使用或不限数量的多个 Pod 使用。

除非 Pod 的所有资源都已分配和保留,否则 Pod 不会被调度到节点,这是一个重要特性。 这避免了 Pod 被调度到一个节点但无法在那里运行的情况, 这种情况很糟糕,因为被挂起 Pod 也会阻塞为其保留的其他资源,如 RAM 或 CPU。

限制

调度器插件必须参与调度那些使用 ResourceClaim 的 Pod。 通过设置 nodeName 字段绕过调度器会导致 kubelet 拒绝启动 Pod, 因为 ResourceClaim 没有被保留或甚至根本没有被分配。 未来可能去除此限制

编写资源驱动程序

动态资源分配驱动程序通常由两个独立但相互协调的组件组成: 一个集中控制器和一个节点本地 kubelet 插件的 DaemonSet。 集中控制器与调度器协调所需的大部分工作都可以由样板代码处理。 只有针对插件所拥有的 ResourceClass 实际分配 ResourceClaim 时所需的业务逻辑才需要自定义。 因此,Kubernetes 提供了以下软件包,其中包括用于调用此样板代码的 API, 以及可以实现自定义业务逻辑的 Driver 接口:

同样,样板代码可用于向 kubelet 注册节点本地插件, 也可以启动 gRPC 服务器来实现 kubelet 插件 API。 对于用 Go 编写的驱动程序,推荐使用以下软件包:

驱动程序开发人员决定这两个组件如何通信。 KEP 详细介绍了使用 CRD 的方法

在 SIG Node 中,我们还计划提供一个完整的示例驱动程序, 它可以当作其他驱动程序的模板。

运行测试驱动程序

下面的步骤直接使用 Kubernetes 源代码启一个本地单节点集群。 前提是,你的集群必须具有支持容器设备接口 (CDI)的容器运行时。 例如,你可以运行 CRI-O v1.23.2 或更高版本。containerd v1.7.0 发布后,我们期望你可以运行该版本或更高版本。 在下面的示例中,我们使用 CRI-O。

首先,克隆 Kubernetes 源代码。在其目录中,运行:

$ hack/install-etcd.sh
...

$ RUNTIME_CONFIG=resource.k8s.io/v1alpha1 \
  FEATURE_GATES=DynamicResourceAllocation=true \
  DNS_ADDON="coredns" \
  CGROUP_DRIVER=systemd \
  CONTAINER_RUNTIME_ENDPOINT=unix:///var/run/crio/crio.sock \
  LOG_LEVEL=6 \
  ENABLE_CSI_SNAPSHOTTER=false \
  API_SECURE_PORT=6444 \
  ALLOW_PRIVILEGED=1 \
  PATH=$(pwd)/third_party/etcd:$PATH \
  ./hack/local-up-cluster.sh -O
...
要使用集群,你可以打开另一个终端/选项卡并运行:
  export KUBECONFIG=/var/run/kubernetes/admin.kubeconfig
...

集群启动后,在另一个终端运行测试驱动程序控制器。 必须为以下所有命令设置 KUBECONFIG

$ go run ./test/e2e/dra/test-driver --feature-gates ContextualLogging=true -v=5 controller

在另一个终端中,运行 kubelet 插件:

$ sudo mkdir -p /var/run/cdi && \
  sudo chmod a+rwx /var/run/cdi /var/lib/kubelet/plugins_registry /var/lib/kubelet/plugins/
$ go run ./test/e2e/dra/test-driver --feature-gates ContextualLogging=true -v=6 kubelet-plugin

更改目录的权限,这样可以以普通用户身份运行和(使用 delve)调试 kubelet 插件, 这很方便,因为它使用已填充的 Go 缓存。 完成后,记得使用 sudo chmod go-w 还原权限。 或者,你也可以构建二进制文件并以 root 身份运行该二进制文件。

现在集群已准备好创建对象:

$ kubectl create -f test/e2e/dra/test-driver/deploy/example/resourceclass.yaml
resourceclass.resource.k8s.io/example created

$ kubectl create -f test/e2e/dra/test-driver/deploy/example/pod-inline.yaml
configmap/test-inline-claim-parameters created
resourceclaimtemplate.resource.k8s.io/test-inline-claim-template created
pod/test-inline-claim created

$ kubectl get resourceclaims
NAME                         RESOURCECLASSNAME   ALLOCATIONMODE         STATE                AGE
test-inline-claim-resource   example             WaitForFirstConsumer   allocated,reserved   8s

$ kubectl get pods
NAME                READY   STATUS      RESTARTS   AGE
test-inline-claim   0/2     Completed   0          21s

这个测试驱动程序没有做什么事情, 它只是将 ConfigMap 中定义的变量设为环境变量。 测试 pod 会转储环境变量,所以可以检查日志以验证是否正常:

$ kubectl logs test-inline-claim with-resource | grep user_a
user_a='b'

下一步

  • 了解更多该设计的信息, 参阅动态资源分配 KEP
  • 阅读 Kubernetes 官方文档的动态资源分配
  • 你可以参与 SIG NodeCNCF 容器编排设备工作组
  • 你可以查看或评论动态资源分配的项目看板
  • 为了将该功能向 beta 版本推进,我们需要来自硬件供应商的反馈, 因此,有一个行动号召:尝试这个功能, 考虑它如何有助于解决你的用户遇到的问题,并编写资源驱动程序…

Kubernetes 1.26 中的移除、弃用和主要变更

作者 :Frederico Muñoz (SAS)

变化是 Kubernetes 生命周期不可分割的一部分:随着 Kubernetes 成长和日趋成熟, 为了此项目的健康发展,某些功能特性可能会被弃用、移除或替换为优化过的功能特性。 Kubernetes v1.26 也做了若干规划:根据 v1.26 发布流程中期获得的信息, 本文将列举并描述其中一些变更,这些变更目前仍在进行中,可能会引入更多变更。

Kubernetes API 移除和弃用流程

Kubernetes 项目对功能特性有一个文档完备的弃用策略。 该策略规定,只有当较新的、稳定的相同 API 可用时,原有的稳定 API 才可以被弃用, 每个稳定级别的 API 都有一个最短的生命周期。弃用的 API 指的是已标记为将在后续发行某个 Kubernetes 版本时移除的 API;移除之前该 API 将继续发挥作用(从弃用起至少一年时间), 但使用时会显示一条警告。被移除的 API 将在当前版本中不再可用,此时你必须迁移以使用替换的 API。

  • 正式发布(GA)或稳定的 API 版本可能被标记为已弃用,但只有在 Kubernetes 大版本更新时才会被移除。
  • 测试版(Beta)或预发布 API 版本在弃用后必须在后续 3 个版本中继续支持。
  • Alpha 或实验性 API 版本可以在任何版本中被移除,不另行通知。

无论一个 API 是因为某功能特性从 Beta 进入稳定阶段而被移除,还是因为该 API 根本没有成功, 所有移除均遵从上述弃用策略。无论何时移除一个 API,文档中都会列出迁移选项。

有关移除 CRI v1alpha2 API 和 containerd 1.5 支持的说明

在 v1.24 中采用容器运行时接口 (CRI) 并[移除 dockershim] 之后,CRI 是 Kubernetes 与不同容器运行时交互所支持和记录的方式。 每个 kubelet 会协商使用哪个版本的 CRI 来配合该节点上的容器运行时。

Kubernetes 项目推荐使用 CRI v1 版本;在 Kubernetes v1.25 中,kubelet 也可以协商使用 CRI v1alpha2(在添加对稳定的 v1 接口的支持同时此项被弃用)。

Kubernetes v1.26 将不支持 CRI v1alpha2。如果容器运行时不支持 CRI v1, 则本次移除将导致 kubelet 不注册节点。 这意味着 Kubernetes 1.26 将不支持 containerd 1.5 小版本及更早的版本;如果你使用 containerd, 则需要升级到 containerd v1.6.0 或更高版本,然后才能将该节点升级到 Kubernetes v1.26。其他仅支持 v1alpha2 的容器运行时同样受到影响。如果此项移除影响到你, 你应该联系容器运行时供应商寻求建议或查阅他们的网站以获取有关如何继续使用的更多说明。

如果你既想从 v1.26 特性中获益又想保持使用较旧的容器运行时,你可以运行较旧的 kubelet。 kubelet 支持的版本偏差允许你运行 v1.25 的 kubelet,即使你将控制平面升级到了 Kubernetes 1.26 的某个次要版本,kubelet 仍然能兼容 v1alpha2 CRI。

除了容器运行时本身,还有像 stargz-snapshotter 这样的工具充当 kubelet 和容器运行时之间的代理,这些工具也可能会受到影响。

Kubernetes v1.26 中的弃用和移除

除了上述移除外,Kubernetes v1.26 还准备包含更多移除和弃用。

移除 v1beta1 流量控制 API 组

FlowSchema 和 PriorityLevelConfiguration 的 flowcontrol.apiserver.k8s.io/v1beta1 API 版本将不再在 v1.26 中提供。 用户应迁移清单和 API 客户端才能使用自 v1.23 起可用的 flowcontrol.apiserver.k8s.io/v1beta2 API 版本。

移除 v2beta2 HorizontalPodAutoscaler API

HorizontalPodAutoscaler 的 autoscaling/v2beta2 API 版本将不再在 v1.26 中提供。 用户应迁移清单和 API 客户端以使用自 v1.23 起可用的 autoscaling/v2 API 版本。

移除树内凭证管理代码

在即将发布的版本中,原来作为 Kubernetes 一部分的、特定于供应商的身份验证代码将从 client-gokubectl移除。 现有机制为两个特定云供应商提供身份验证支持:Azure 和 Google Cloud。 作为替代方案,Kubernetes 在发布 v1.26 之前已提供了供应商中立的身份验证插件机制, 你现在就可以切换身份验证机制。如果你受到影响,你可以查阅有关如何继续使用 AzureGoogle Cloud 的更多指导信息。

移除 kube-proxy userspace 模式

已弃用一年多的 userspace 代理模式不再受 Linux 或 Windows 支持, 并将在 v1.26 中被移除。Linux 用户应使用 iptablesipvs,Windows 用户应使用 kernelspace: 现在使用 --mode userspace 会失败。

移除树内 OpenStack 云驱动

针对存储集成,Kubernetes 正在从使用树内代码转向使用容器存储接口 (CSI)。 作为这个转变的一部分,Kubernetes v1.26 将移除已弃用的 OpenStack 树内存储集成(cinder 卷类型)。 你应该迁移到外部云驱动或者位于 https://github.com/kubernetes/cloud-provider-openstack 的 CSI 驱动。 有关详细信息,请访问 Cinder in-tree to CSI driver migration

移除 GlusterFS 树内驱动

树内 GlusterFS 驱动在 v1.25 中被弃用, 且从 Kubernetes v1.26 起将被移除。

弃用非包容性的 kubectl 标志

作为包容性命名倡议(Inclusive Naming Initiative)的实现工作的一部分, --prune-whitelist 标志将被弃用,并替换为 --prune-allowlist。 强烈建议使用此标志的用户在未来某个版本中最终移除该标志之前进行必要的变更。

移除动态 kubelet 配置

动态 kubelet 配置 允许通过 Kubernetes API 推出新的 kubelet 配置, 甚至能在运作中集群上完成此操作。集群操作员可以通过指定包含 kubelet 应使用的配置数据的 ConfigMap 来重新配置节点上的 kubelet。动态 kubelet 配置已在 v1.24 中从 kubelet 中移除,并将在 v1.26 版本中从 API 服务器中移除

弃用 kube-apiserver 命令行参数

--master-service-namespace 命令行参数对 kube-apiserver 没有任何效果, 并且已经被非正式地被弃用。 该命令行参数将在 v1.26 中正式标记为弃用,准备在未来某个版本中移除。 Kubernetes 项目预期不会因此项弃用和移除受到任何影响。

弃用 kubectl run 命令行参数

针对 kubectl run 子命令若干未使用的选项参数将被标记为弃用,这包括:

  • --cascade
  • --filename
  • --force
  • --grace-period
  • --kustomize
  • --recursive
  • --timeout
  • --wait

这些参数已被忽略,因此预计不会产生任何影响:显式的弃用会设置一条警告消息并准备在未来的某个版本中移除这些参数。

移除与日志相关的原有命令行参数

Kubernetes v1.26 将移除一些与日志相关的命令行参数。 这些命令行参数之前已被弃用。有关详细信息, 请参阅弃用 Kubernetes 组件中的 klog 特定标志

展望未来

Kubernetes 1.27 计划移除的 API 官方列表包括:

  • 所有 Beta 版的 CSIStorageCapacity API;特别是 storage.k8s.io/v1beta1

了解更多

Kubernetes 发行说明中宣告了弃用信息。你可以在以下版本的发行说明中看到待弃用的公告:

我们将在 Kubernetes 1.26 的 CHANGELOG 中正式宣布该版本的弃用信息。

Kueue 介绍

作者: Abdullah Gharaibeh(谷歌),Aldo Culquicondor(谷歌)

无论是在本地还是在云端,集群都面临着资源使用、配额和成本管理方面的实际限制。 无论自动扩缩容能力如何,集群的容量都是有限的。 因此,用户需要一种简单的方法来公平有效地共享资源。

在本文中,我们介绍了 Kueue, 这是一个开源作业队列控制器,旨在将批处理作业作为一个单元进行管理。 Kueue 将 Pod 级编排留给 Kubernetes 现有的稳定组件。 Kueue 原生支持 Kubernetes Job API, 并提供用于集成其他定制 API 以进行批处理作业的钩子。

为什么是 Kueue?

作业队列是在本地和云环境中大规模运行批处理工作负载的关键功能。 作业队列的主要目标是管理对多个租户共享的有限资源池的访问。 作业排队决定了哪些作业应该等待,哪些可以立即启动,以及它们可以使用哪些资源。

一些最需要的作业队列要求包括:

  • 用配额和预算来控制谁可以使用什么以及达到什么限制。 这不仅在具有静态资源(如本地)的集群中需要,而且在云环境中也需要控制稀缺资源的支出或用量。
  • 租户之间公平共享资源。 为了最大限度地利用可用资源,应允许活动租户公平共享那些分配给非活动租户的未使用配额。
  • 根据可用性,在不同资源类型之间灵活放置作业。 这在具有异构资源的云环境中很重要,例如不同的架构(GPU 或 CPU 模型)和不同的供应模式(即用与按需)。
  • 支持可按需配置资源的自动扩缩容环境。

普通的 Kubernetes 不能满足上述要求。 在正常情况下,一旦创建了 Job,Job 控制器会立即创建 Pod,并且 kube-scheduler 会不断尝试将 Pod 分配给节点。 大规模使用时,这种情况可能会使控制平面死机。 目前也没有好的办法在 Job 层面控制哪些 Job 应该先获得哪些资源,也没有办法标明顺序或公平共享。 当前的 ResourceQuota 模型不太适合这些需求,因为配额是在资源创建时强制执行的,并且没有请求排队。 ResourceQuotas 的目的是提供一种内置的可靠性机制,其中包含管理员所需的策略,以防止集群发生故障转移。

在 Kubernetes 生态系统中,Job 调度有多种解决方案。但是,我们发现这些替代方案存在以下一个或多个问题:

  • 它们取代了 Kubernetes 的现有稳定组件,例如 kube-scheduler 或 Job 控制器。 这不仅从操作的角度看是有问题的,而且重复的 Job API 也会导致生态系统的碎片化并降低可移植性。
  • 它们没有集成自动扩缩容,或者
  • 它们缺乏对资源灵活性的支持。

Kueue 的工作原理

借助 Kueue,我们决定采用不同的方法在 Kubernetes 上进行 Job 排队,该方法基于以下方面:

  • 不复制已建立的 Kubernetes 组件提供的用于 Pod 调度、自动扩缩容和 Job 生命周期管理的现有功能。
  • 确保与具有弹性和异构性的计算资源云环境兼容。

为了使这种方法可行,Kueue 需要旋钮来影响那些已建立组件的行为,以便它可以有效地管理何时何地启动一个 Job。 我们以两个特性的方式将这些旋钮添加到 Job API:

  • Suspend 字段, 它允许在 Job 启动或停止时,Kueue 向 Job 控制器发出信号。
  • 可变调度指令, 允许在启动 Job 之前更新 Job 的 .spec.template.spec.nodeSelector。 这样,Kueue 可以控制 Pod 放置,同时仍将 Pod 到节点的实际调度委托给 kube-scheduler。

请注意,任何自定义的 Job API 都可以由 Kueue 管理,只要该 API 提供上述两种能力。

资源模型

Kueue 定义了新的 API 来解决本文开头提到的需求。三个主要的 API 是:

  • ResourceFlavor:一个集群范围的 API,用于定义可供消费的资源模板,如 GPU 模型。 ResourceFlavor 的核心是一组标签,这些标签反映了提供这些资源的节点上的标签。
  • ClusterQueue: 一种集群范围的 API,通过为一个或多个 ResourceFlavor 设置配额来定义资源池。
  • LocalQueue: 用于分组和管理单租户 Jobs 的命名空间 API。 在最简单的形式中,LocalQueue 是指向集群队列的指针,租户(建模为命名空间)可以使用它来启动他们的 Jobs。

有关更多详细信息,请查看 API 概念文档。 虽然这三个 API 看起来无法抗拒,但 Kueue 的大部分操作都以 ClusterQueue 为中心; ResourceFlavor 和 LocalQueue API 主要是组织包装器。

用例样例

想象一下在云上的 Kubernetes 集群上运行批处理工作负载的以下设置:

  • 有两种类型的自动缩放节点组,它们的供应策略不同:即用和按需。 分别对应标签:instance-type=spot 或者 instance-type=ondemand。 此外,并非所有作业都可以容忍在即用节点上运行,节点可以用 spot=true:NoSchedule 污染。
  • 为了在成本和资源可用性之间取得平衡,假设你希望 Jobs 使用最多 1000 个核心按需节点,最多 2000 个核心即用节点。

作为批处理系统的管理员,你定义了两个 ResourceFlavor,它们代表两种类型的节点:

---
apiVersion: kueue.x-k8s.io/v1alpha2
kind: ResourceFlavor
metadata:
  name: ondemand
  labels:
    instance-type: ondemand 
---
apiVersion: kueue.x-k8s.io/v1alpha2
kind: ResourceFlavor
metadata:
  name: spot
  labels:
    instance-type: spot
taints:
- effect: NoSchedule
  key: spot
  value: "true"

然后通过创建 ClusterQueue 来定义配额,如下所示:

apiVersion: kueue.x-k8s.io/v1alpha2
kind: ClusterQueue
metadata:
  name: research-pool
spec:
  namespaceSelector: {}
  resources:
  - name: "cpu"
    flavors:
    - name: ondemand
      quota:
        min: 1000
    - name: spot
      quota:
        min: 2000

注意 ClusterQueue 资源中的模板顺序很重要:Kueue 将尝试根据该顺序为 Job 分配可用配额,除非这些 Job 与特定模板有明确的关联。

对于每个命名空间,定义一个指向上述 ClusterQueue 的 LocalQueue:

apiVersion: kueue.x-k8s.io/v1alpha2
kind: LocalQueue
metadata:
  name: training
  namespace: team-ml
spec:
  clusterQueue: research-pool

管理员创建一次上述配置。批处理用户可以通过在他们的命名空间中列出 LocalQueues 来找到他们被允许提交的队列。 该命令类似于:kubectl get -n my-namespace localqueues

要提交作业,需要创建一个 Job 并设置 kueue.x-k8s.io/queue-name 注解,如下所示:

apiVersion: batch/v1
kind: Job
metadata:
  generateName: sample-job-
  annotations:
    kueue.x-k8s.io/queue-name: training
spec:
  parallelism: 3
  completions: 3
  template:
    spec:
      tolerations:
      - key: spot
        operator: "Exists"
        effect: "NoSchedule"
      containers:
      - name: example-batch-workload
        image: registry.example/batch/calculate-pi:3.14
        args: ["30s"]
        resources:
          requests:
            cpu: 1
      restartPolicy: Never

Kueue 在创建 Job 后立即进行干预以暂停 Job。 一旦 Job 位于 ClusterQueue 的头部,Kueue 就会通过检查 Job 请求的资源是否符合可用配额来评估它是否可以启动。

在上面的例子中,Job 容忍了 Spot 资源。如果之前承认的 Job 消耗了所有现有的按需配额, 但不是所有 Spot 配额,则 Kueue 承认使用 Spot 配额的 Job。Kueue 通过向 Job 对象发出单个更新来做到这一点:

  • 更改 .spec.suspend 标志位为 false
  • instance-type: spot 添加到 Job 的 .spec.template.spec.nodeSelector 中, 以便在 Job 控制器创建 Pod 时,这些 Pod 只能调度到 Spot 节点上。

最后,如果有可用的空节点与节点选择器条件匹配,那么 kube-scheduler 将直接调度 Pod。 如果不是,那么 kube-scheduler 将 pod 初始化标记为不可调度,这将触发 cluster-autoscaler 配置新节点。

未来工作以及参与方式

上面的示例提供了 Kueue 的一些功能简介,包括支持配额、资源灵活性以及与集群自动缩放器的集成。 Kueue 还支持公平共享、Job 优先级和不同的排队策略。 查看 Kueue 文档以了解这些特性以及如何使用 Kueue 的更多信息。

我们计划将许多特性添加到 Kueue 中,例如分层配额、预算和对动态大小 Job 的支持。 在不久的将来,我们将专注于增加对 Job 抢占的支持。

最新的 Kueue 版本在 Github 上可用; 如果你在 Kubernetes 上运行批处理工作负载(需要 v1.22 或更高版本),可以尝试一下。 这个项目还处于早期阶段,我们正在搜集大大小小各个方面的反馈,请不要犹豫,快来联系我们吧! 无论是修复或报告错误,还是帮助添加新特性或编写文档,我们欢迎一切形式的贡献者。 你可以通过我们的仓库邮件列表或者 Slack 与我们联系。

最后是很重要的一点,感谢所有促使这个项目成为可能的贡献者们

“Kubernetes 1.25:对使用用户名字空间运行 Pod 提供 Alpha 支持”

作者: Rodrigo Campos(Microsoft)、Giuseppe Scrivano(Red Hat)

Kubernetes v1.25 引入了对用户名字空间的支持。

这是在 Kubernetes 中运行安全工作负载的一项重大改进。 每个 Pod 只能访问系统上可用 UID 和 GID 的有限子集, 因此添加了一个新的安全层来保护 Pod 免受运行在同一系统上的其他 Pod 的影响。

它是如何工作的?

在 Linux 上运行的进程最多可以使用 4294967296 个不同的 UID 和 GID。

用户名字空间是 Linux 的一项特性,它允许将容器中的一组用户映射到主机中的不同用户, 从而限制进程可以实际使用的 ID。 此外,在新用户名字空间中授予的权能不适用于主机初始名字空间。

它为什么如此重要?

用户名字空间之所以重要,主要有两个原因:

  • 提高安全性。因为它们限制了 Pod 可以使用的 ID, 因此每个 Pod 都可以在其自己的具有唯一 ID 的单独环境中运行。

  • 以更安全的方式使用 root 身份运行工作负载。

在用户名字空间中,我们可以将 Pod 内的 root 用户映射到容器外的非零 ID, 容器将认为是 root 身份在运行,而从主机的角度来看,它们是常规的非特权 ID。

该进程可以保留通常仅限于特权 Pod 的功能,并以安全的方式执行这类操作, 因为在新用户名字空间中授予的功能不适用于主机初始名字空间。

如何启用用户名字空间

目前,对用户名字空间的支持是可选的,因此你必须在 Pod 规约部分将 hostUsers 设置为 false 以启用用户名字空间:

apiVersion: v1
kind: Pod
spec:
  hostUsers: false
  containers:
  - name: nginx
    image: docker.io/nginx

该特性目前还处于 Alpha 阶段,默认是禁用的,因此在使用此新特性之前, 请确保启用了 UserNamespacesStatelessPodsSupport 特性门控。

此外,运行时也必须支持用户名字空间:

  • Containerd:计划在 1.7 版本中提供支持。 进一步了解,请参阅 Containerd issue #7063

  • CRI-O:v1.25 支持用户名字空间。

cri-dockerd 对用户名字空间的支持尚无计划

我如何参与?

你可以通过多种方式联系 SIG Node:

你也可以直接联系我们:

Kubernetes 1.25:应用滚动上线所用的两个特性进入稳定阶段

作者: Ravi Gudimetla (Apple)、Filip Křepinský (Red Hat)、Maciej Szulik (Red Hat)

这篇博客描述了两个特性,即用于 StatefulSet 的 minReadySeconds 以及用于 DaemonSet 的 maxSurge, SIG Apps 很高兴宣布这两个特性在 Kubernetes 1.25 进入稳定阶段。

.spec.updateStrategy 字段设置为 RollingUpdate 时, 你可以设置 minReadySeconds, 通过让每个 Pod 等待一段预期时间来减缓 StatefulSet 的滚动上线。

.spec.updateStrategy 字段设置为 RollingUpdate 时, maxSurge 允许 DaemonSet 工作负载在滚动上线期间在一个节点上运行同一 Pod 的多个实例。 这对于消费者而言有助于将 DaemonSet 的停机时间降到最低。

这两个特性也可用于 Deployment 和其他工作负载。此功能的提级有助于将这一功能在所有工作负载上对齐。

这两个特性能解决什么问题?

针对 StatefulSet 的 minReadySeconds

minReadySeconds 确保 StatefulSet 工作负载在给定的秒数内处于 Ready, 然后才会将该 Pod 报告为 Available。 处于 ReadyAvailable 状况的这种说法对工作负载相当重要。 例如 Prometheus 这些工作负载有多个 Alertmanager 实例, 只有 Alertmanager 的状态转换完成后才应该被视为 AvailableminReadySeconds 还有助于云驱动确定何时使用负载均衡器。 因为 Pod 应在给定的秒数内处于 Ready,所以这就提供了一段缓冲时间, 防止新 Pod 还没起来之前就在轮转过程中杀死了旧 Pod。

针对 DaemonSet 的 maxSurge

CNI、CSI 这类 Kubernetes 系统级别的组件通常以 DaemonSet 方式运行。如果这些 DaemonSet 在升级期间瞬间挂掉, 对应的组件可能会影响工作负载的可用性。此特性允许 DaemonSet Pod 临时增加数量,以此确保 DaemonSet 的停机时间为零。

请注意在 DaemonSet 中不允许同时使用 hostPortmaxSurge, 因为 DaemonSet Pod 被捆绑到了一个节点,所以两个活跃的 Pod 无法共享同一节点上的相同端口。

工作原理

针对 StatefulSet 的 minReadySeconds

StatefulSet 控制器监视 StatefulSet Pod 并统计特定的 Pod 已处于 Running 状态多长时间了, 如果这个值大于或等于 StatefulSet 的 .spec.minReadySeconds 字段中指定的时间, StatefulSet 控制器将更新 StatefulSet 的状态中的 AvailableReplicas 字段。

针对 DaemonSet 的 maxSurge

DaemonSet 控制器根据 .spec.strategy.rollingUpdate.maxSurge 中给出的值创建额外 Pod (超出 DaemonSet 规约所设定的预期数量)。 这些 Pod 将运行在旧 DaemonSet Pod 运行所在的同一节点上,直到这个旧 Pod 被杀死为止。

  • 默认值为 0。
  • MaxUnavailable 为 0 时此值不能为 0
  • 此值可以指定为一个绝对的 Pod 个数或预期 Pod 总数的百分比(向上取整)。

我如何使用它?

针对 StatefulSet 的 minReadySeconds

执行以下命令为任意 StatefulSet 指定一个 minReadySeconds 值, 通过检验 AvailableReplicas 字段查看这些 Pod 是否可用:

kubectl get statefulset/<StatefulSet 名称> -o yaml

请注意 minReadySeconds 的默认值为 0。

针对 DaemonSet 的 maxSurge

.spec.updateStrategy.rollingUpdate.maxSurge 指定一个值并将 .spec.updateStrategy.rollingUpdate.maxUnavailable 设置为 0

然后观察下一次滚动上线是不是更快,同时运行的 Pod 数量是不是更多。

kubectl rollout restart daemonset <name_of_the_daemonset>
kubectl get pods -w

我如何才能了解更多?

针对 StatefulSet 的 minReadySeconds

针对 DaemonSet 的 maxSurge

我如何参与?

请通过 Slack #sig-apps 频道或通过 SIG Apps 邮件列表 kubernetes-sig-apps@googlegroups.com 联系我们。

Kubernetes 1.25:Pod 新增 PodHasNetwork 状况

作者: Deep Debroy (Apple)

Kubernetes 1.25 引入了对 kubelet 所管理的新的 Pod 状况 PodHasNetwork 的 Alpha 支持, 该状况位于 Pod 的 status 字段中 。对于工作节点,kubelet 将使用 PodHasNetwork 状况从容器运行时 (通常与 CNI 插件协作)创建 Pod 沙箱和网络配置的角度准确地了解 Pod 的初始化状态。 在 PodHasNetwork 状况的 status 设置为 "True" 后,kubelet 开始拉取容器镜像并启动独立的容器 (包括 Init 容器)。从集群基础设施的角度报告 Pod 初始化延迟的指标采集服务 (无需知道每个容器的镜像大小或有效负载等特征)就可以利用 PodHasNetwork 状况来准确生成服务水平指标(Service Level Indicator,SLI)。 某些管理底层 Pod 的 Operator 或控制器可以利用 PodHasNetwork 状况来优化 Pod 反复出现失败时要执行的操作。

这与现在为 Pod 所报告的 Intialized 状况有何不同?

根据 Pod 中是否存在 Init 容器,kubelet 会设置在 Pod 的 status 字段中报告的 Initialized 状况的状态。

如果 Pod 指定了 Init 容器,则 Pod 状态中的 Initialized 状况的 status 将不会设置为 "True", 直到该 Pod 的所有 Init 容器都成功为止。但是,用户配置的 Init 容器可能会出现错误(有效负载崩溃、无效镜像等), 并且 Pod 中配置的 Init 容器数量可能因工作负载不同而异。 因此,关于 Pod 初始化的集群范围基础设施 SLI 不能依赖于 Pod 的 Initialized 状况。

如果 Pod 未指定 Init 容器,则在 Pod 生命周期的早期, Pod 状态中的 Initialized 状况的 status 会被设置为 "True"。 这一设置发生在 kubelet 开始创建 Pod 运行时沙箱及配置网络之前。 因此,即使容器运行时未能成功初始化 Pod 沙箱环境,没有 Init 容器的 Pod 也会将 Initialized 状况的 status 报告为 "True"

相对于上述任何一种情况,PodHasNetwork 状况会在 Pod 运行时沙箱被初始化并配置了网络时能够提供更准确的数据, 这样 kubelet 可以继续在 Pod 中启动用户配置的容器(包括 Init 容器)。

特殊场景

如果一个 Pod 指定 hostNetwork"True", 系统会根据 Pod 沙箱创建操作是否成功来决定要不要将 PodHasNetwork 状况设置为 "True", 设置此状况时会忽略 Pod 沙箱的网络配置状态。这是因为 Pod 的 hostNetwork 被设置为 "True" 时 CRI 实现通常会跳过所有 Pod 沙箱网络配置。

节点代理可以通过监视指定附加网络配置(例如 k8s.v1.cni.cncf.io/networks)的 Pod 注解变化, 来动态地为 Pod 重新配置网络接口。Pod 沙箱被 Kubelet 初始化(结合容器运行时)之后 Pod 网络配置的动态更新不反映在 PodHasNetwork 状况中。

试用 Pod 的 PodHasNetwork 状况

为了让 kubelet 在 Pod 的 status 字段中报告 PodHasNetwork 状况,需在 kubelet 上启用 PodHasNetworkCondition 特性门控。

对于已成功创建运行时沙箱并已配置网络的 Pod,在 status 设置为 "True" 后, kubelet 将报告 PodHasNetwork 状况:

$ kubectl describe pod nginx1
Name:             nginx1
Namespace:        default
...
Conditions:
  Type              Status
  PodHasNetwork     True
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

对于尚未创建运行时沙箱(也未配置网络)的 Pod,在 status 设置为 "False" 后, kubelet 将报告 PodHasNetwork 状况:

$ kubectl describe pod nginx2
Name:             nginx2
Namespace:        default
...
Conditions:
  Type              Status
  PodHasNetwork     False
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True

下一步是什么?

Kubernetes 团队根据反馈和采用情况,计划在 1.26 或 1.27 中将 PodHasNetwork 状况的报告提升到 Beta 阶段。

我如何了解更多信息?

请查阅 PodHasNetwork 状况有关的文档, 以了解有关该状况的更多信息以及它与其他 Pod 状况的关系。

如何参与?

此特性由 SIG Node 社区驱动。请加入我们与社区建立联系,并就上述特性及其他问题分享你的想法和反馈。 我们期待你的回音!

致谢

我们要感谢以下人员围绕此特性对 KEP 和 PR 进行了极具洞察力和相当有助益的评审工作: Derek Carr (@derekwaynecarr)、Mrunal Patel (@mrunalp)、Dawn Chen (@dchen1107)、 Qiutong Song (@qiutongs)、Ruiwen Zhao (@ruiwen-zhao)、Tim Bannister (@sftim)、 Danielle Lancashire (@endocrimes) 和 Agam Dua (@agamdua)。

宣布自动刷新官方 Kubernetes CVE 订阅源

作者:Pushkar Joglekar (VMware)

Kubernetes 社区有一个长时间未解决的需求,即为最终用户提供一种编程方式来跟踪 Kubernetes 安全问题(也称为 “CVE”,这来自于跟踪不同产品和供应商的公共安全问题的数据库)。 随着 Kubernetes v1.25 的发布,我们很高兴地宣布以 alpha 特性的形式推出这样的订阅源。 在这篇博客中将介绍这项新服务的背景和范围。

动机

随着关注 Kubernetes 的人越来越多,与 Kubernetes 相关的 CVE 数量也在增加。 尽管大多数直接地、间接地或传递性地影响 Kubernetes 的 CVE 都被定期修复, 但 Kubernetes 的最终用户没有一个地方能够以编程方式来订阅或拉取固定的 CVE 数据。 目前的一些数据源要么已损坏,要么不完整。

范围

能做什么

创建一个定期自动刷新的、人和机器可读的官方 Kubernetes CVE 列表。

不能做什么

  • 漏洞的分类和披露将继续由 SRC(Security Response Committee,安全响应委员会)完成。
  • 不会列出在构建时依赖项和容器镜像中发现的 CVE。
  • 只有 Kubernetes SRC 公布的官方 CVE 才会在订阅源中发布。

针对的受众

  • 最终用户使用 Kubernetes 部署他们的应用程序的个人或团队。
  • 平台提供商管理 Kubernetes 集群的个人或团队。
  • 维护人员:通过各种特别兴趣小组和委员会在 Kubernetes 社区中创建支持 Kubernetes 发布版本的个人或团队。

实现细节

发布了一个支持性的贡献者博客, 深入讲述这个 CVE 订阅源是如何实现的,如何确保该订阅源得到合理的保护以免被篡改, 如何在一个新的 CVE 被公布后自动更新这个订阅源。

下一步工作

为了完善此功能,SIG Security 正在收集使用此 Alpha 订阅源的最终用户的反馈。

因此,为了在未来的 Kubernetes 版本中改进订阅源,如果你有任何反馈,请通过添加评论至 问题追踪告诉我们, 或者在 #sig-security-tooling Kubernetes Slack 频道上告诉我们(从这里加入 Kubernetes Slack) 。

特别感谢 Neha Lohia (@nehalohia27) 和 Tim Bannister (@sftim), 感谢他们几个月来从“构思到实现”此特性的出色合作。

COSI 简介:使用 Kubernetes API 管理对象存储

作者: Sidhartha Mani (Minio, Inc)

本文介绍了容器对象存储接口 (COSI),它是在 Kubernetes 中制备和使用对象存储的一个标准。 它是 Kubernetes v1.25 中的一个 Alpha 功能。

文件和块存储通过 Container Storage Interface (CSI) 被视为 Kubernetes 生态系统中的一等公民。 使用 CSI 卷的工作负载可以享受跨供应商和跨 Kubernetes 集群的可移植性优势, 而无需更改应用程序清单。对象存储不存在等效标准。

近年来,对象存储作为文件系统和块设备的替代存储形式越来越受欢迎。 对象存储范式促进了计算和存储的分解,这是通过网络而不是本地提供数据来完成的。 分解的架构允许计算工作负载是无状态的,从而使它们更易于管理、扩展和自动化。

COSI

COSI 旨在标准化对象存储的使用,以提供以下好处:

  • Kubernetes 原生 - 使用 Kubernetes API 来制备、配置和管理 Bucket
  • 自助服务 - 明确划分管理和运营 (DevOps),为 DevOps 人员赋予自助服务能力
  • 可移植性 - 通过跨 Kubernetes 集群和跨对象存储供应商的可移植性实现供应商中立性

跨供应商的可移植性只有在两家供应商都支持通用数据路径 API 时才有可能。 例如,可以从 AWS S3 移植到 Ceph,或从 AWS S3 移植到 MinIO 以及反向操作,因为它们都使用 S3 API。 但是无法从 AWS S3 和 Google Cloud 的 GCS 移植,反之亦然。

架构

COSI 由三个部分组成:

  • COSI 控制器管理器
  • COSI 边车
  • COSI 驱动程序

COSI 控制器管理器充当处理 COSI API 对象更改的主控制器,它负责处理 Bucket 创建、更新、删除和访问管理的请求。 每个 Kubernetes 集群都需要一个控制器管理器实例。即使集群中使用了多个对象存储提供程序,也只需要一个。

COSI 边车充当 COSI API 请求和供应商特定 COSI 驱动程序之间的转换器。 该组件使用供应商驱动程序应满足的标准化 gRPC 协议。

COSI 驱动程序是供应商特定组件,它接收来自 sidecar 的请求并调用适当的供应商 API 以创建 Bucket、 管理其生命周期及对它们的访问。

接口

COSI 接口 以 Bucket 为中心,因为 Bucket 是对象存储的抽象单元。COSI 定义了三个旨在管理它们的 Kubernetes API

  • Bucket
  • BucketClass
  • BucketClaim

此外,还定义了另外两个用于管理对 Bucket 的访问的 API:

  • BucketAccess
  • BucketAccessClass

简而言之,Bucket 和 BucketClaim 可以认为分别类似于 PersistentVolume 和 PersistentVolumeClaim。 BucketClass 在文件/块设备世界中对应的是 StorageClass。

由于对象存储始终通过网络进行身份验证,因此需要访问凭证才能访问 Bucket。 BucketAccess 和 BucketAccessClass 这两个 API 用于表示访问凭证和身份验证策略。 有关这些 API 的更多信息可以在官方 COSI 提案中找到 - https://github.com/kubernetes/enhancements/tree/master/keps/sig-storage/1979-object-storage-support

自助服务

除了提供 kubernetes-API 驱动的 Bucket 管理之外,COSI 还旨在使 DevOps 人员能够自行配置和管理 Bucket, 而无需管理员干预。这进一步使开发团队能够实现更快的周转时间和更快的上市时间。

COSI 通过在两个不同的利益相关者(即管理员(admin)和集群操作员)之间划分 Bucket 配置步骤来实现这一点。 管理员将负责就如何配置 Bucket 以及如何获取 Bucket 的访问权限设置广泛的策略和限制。 集群操作员可以在管理员设置的限制内自由创建和使用 Bucket。

例如,集群操作员可以使用管理策略将最大预置容量限制为 100GB,并且允许开发人员创建 Bucket 并将数据存储到该限制。 同样对于访问凭证,管理员将能够限制谁可以访问哪些 Bucket,并且开发人员将能够访问他们可用的所有 Bucket。

可移植性

COSI 的第三个目标是实现 Bucket 管理的供应商中立性。COSI 支持两种可移植性:

  • 跨集群
  • 跨提供商

跨集群可移植性允许在一个集群中配置的 Bucket 在另一个集群中可用。这仅在对象存储后端本身可以从两个集群访问时才有效。

跨提供商可移植性是指允许组织或团队无缝地从一个对象存储提供商迁移到另一个对象存储提供商, 而无需更改应用程序定义(PodTemplates、StatefulSets、Deployment 等)。这只有在源和目标提供者使用相同的数据时才有可能。

COSI 不处理数据迁移,因为它超出了其范围。如果提供者之间的移植也需要迁移数据,则需要采取其他措施来确保数据可用性。

接下来

令人惊叹的 sig-storage-cosi 社区一直在努力将 COSI 标准带入 Alpha 状态。 我们期待很多供应商加入编写 COSI 驱动程序并与 COSI 兼容!

我们希望为 COSI Bucket 添加更多身份验证机制,我们正在设计高级存储桶共享原语、多集群存储桶管理等等。 未来有很多伟大的想法和机会!

请继续关注接下来的内容,如果你有任何问题、意见或建议分解的架构允许计算工作负载是无状态

Kubernetes 1.25: cgroup v2 升级到 GA

作者: David Porter (Google), Mrunal Patel (Red Hat)

Kubernetes 1.25 将 cgroup v2 正式发布(GA), 让 kubelet 使用最新的容器资源管理能力。

什么是 cgroup?

有效的资源管理是 Kubernetes 的一个关键方面。 这涉及管理节点中的有限资源,例如 CPU、内存和存储。

cgroups 是一种可建立资源管理功能的 Linux 内核能力, 例如为正在运行的进程限制 CPU 使用率或设置内存限制。

当你使用 Kubernetes 中的资源管理能力时,例如配置 Pod 和容器的请求和限制, Kubernetes 会使用 cgroups 来强制执行你的资源请求和限制。

Linux 内核提供了两个版本的 cgroup:cgroup v1 和 cgroup v2。

什么是 cgroup v2?

cgroup v2 是 Linux cgroup API 的最新版本, 提供了一个具有增强的资源管理能力的统一控制系统。

自 2016 年以来,cgroup v2 一直在 Linux 内核中进行开发, 近年来在整个容器生态系统中已经成熟。在 Kubernetes 1.25 中, 对 cgroup v2 的支持已升级为正式发布。

默认情况下,许多最新版本的 Linux 发行版已切换到 cgroup v2, 因此 Kubernetes 继续在这些新更新的发行版上正常运行非常重要。

cgroup v2 对 cgroup v1 进行了多项改进,例如:

  • API 中单个统一的层次结构设计
  • 为容器提供更安全的子树委派能力
  • 压力阻塞信息等新功能
  • 增强的资源分配管理和跨多个资源的隔离
    • 统一核算不同类型的内存分配(网络和内核内存等)
    • 考虑非即时资源更改,例如页面缓存回写

一些 Kubernetes 特性专门使用 cgroup v2 来增强资源管理和隔离。 例如,MemoryQoS 特性提高了内存利用率并依赖 cgroup v2 功能来启用它。kubelet 中的新资源管理特性也将利用新的 cgroup v2 特性向前发展。

如何使用 cgroup v2?

许多 Linux 发行版默认切换到 cgroup v2; 你可能会在下次更新控制平面和节点的 Linux 版本时开始使用它!

推荐使用默认使用 cgroup v2 的 Linux 发行版。 一些使用 cgroup v2 的流行 Linux 发行版包括:

  • Container-Optimized OS(从 M97 开始)
  • Ubuntu(从 21.10 开始,推荐 22.04+)
  • Debian GNU/Linux(从 Debian 11 Bullseye 开始)
  • Fedora(从 31 开始)
  • Arch Linux(从 2021 年 4 月开始)
  • RHEL 和类似 RHEL 的发行版(从 9 开始)

要检查你的发行版是否默认使用 cgroup v2, 请参阅你的发行版文档或遵循识别 Linux 节点上的 cgroup 版本

如果你使用的是托管 Kubernetes 产品,请咨询你的提供商以确定他们如何采用 cgroup v2, 以及你是否需要采取行动。

要将 cgroup v2 与 Kubernetes 一起使用,必须满足以下要求:

  • 你的 Linux 发行版在内核版本 5.8 或更高版本上启用 cgroup v2
  • 你的容器运行时支持 cgroup v2。例如:
  • kubelet 和容器运行时配置为使用 systemd cgroup 驱动程序

kubelet 和容器运行时使用 cgroup 驱动 来设置 cgroup 参数。使用 cgroup v2 时,强烈建议 kubelet 和你的容器运行时都使用 systemd cgroup 驱动程序, 以便系统上只有一个 cgroup 管理员。要配置 kubelet 和容器运行时以使用该驱动程序, 请参阅 systemd cgroup 驱动程序文档

迁移到 cgroup v2

当你使用启用 cgroup v2 的 Linux 发行版运行 Kubernetes 时,只要你满足要求, kubelet 应该会自动适应而无需任何额外的配置。

在大多数情况下,除非你的用户直接访问 cgroup 文件系统, 否则当你切换到使用 cgroup v2 时,不会感知到用户体验有什么不同。

如果你在节点上或从容器内直接访问 cgroup 文件系统的应用程序, 你必须更新应用程序以使用 cgroup v2 API 而不是 cgroup v1 API。

你可能需要更新到 cgroup v2 的场景包括:

  • 如果你运行依赖于 cgroup 文件系统的第三方监控和安全代理,请将代理更新到支持 cgroup v2 的版本。
  • 如果你将 cAdvisor 作为独立的 DaemonSet 运行以监控 Pod 和容器, 请将其更新到 v0.43.0 或更高版本。
  • 如果你使用 JDK 部署 Java 应用程序,首选使用完全支持 cgroup v2 的 JDK 11.0.16 及更高版本或 JDK 15 及更高版本。

进一步了解

参与其中

随时欢迎你的反馈!SIG Node 定期开会,可在 Kubernetes Slack#sig-node 频道中获得,或使用 SIG 邮件列表

cgroup v2 经历了漫长的旅程,是整个行业开源社区协作的一个很好的例子, 因为它需要跨堆栈的工作,从 Linux 内核到 systemd 到各种容器运行时,当然还有 Kubernetes。

致谢

我们要感谢 Giuseppe Scrivano 在 Kubernetes 中发起对 cgroup v2 的支持, 还要感谢 SIG Node 社区主席 Dawn ChenDerek Carr 所作的审查和领导工作。

我们还要感谢 Docker、containerd 和 CRI-O 等容器运行时的维护者, 以及支持多种容器运行时的 cAdvisorrunc, libcontainer 等组件的维护者。 最后,如果没有 systemd 和上游 Linux 内核维护者的支持,这将是不可能的。

Kubernetes 1.25:CSI 内联存储卷正式发布

作者: Jonathan Dobson (Red Hat)

CSI 内联存储卷是在 Kubernetes 1.15 中作为 Alpha 功能推出的,并从 1.16 开始成为 Beta 版本。 我们很高兴地宣布,这项功能在 Kubernetes 1.25 版本中正式发布(GA)。

CSI 内联存储卷与其他类型的临时卷相似,如 configMapdownwardAPIsecret。 重要的区别是,存储是由 CSI 驱动提供的,它允许使用第三方供应商提供的临时存储。 卷被定义为 Pod 规约的一部分,并遵循 Pod 的生命周期,这意味着卷随着 Pod 的调度而创建,并随着 Pod 的销毁而销毁。

1.25 版本有什么新内容?

1.25 版本修复了几个与 CSI 内联存储卷相关的漏洞, 并且 CSIInlineVolume 特性门控 已正式发布,锁定为 True。 因为没有新的 API 变化,所以除了这些错误修复外,使用该功能 Beta 版本的用户应该不会注意到任何重大变化。

何时使用此功能

CSI 内联存储卷是为简单的本地卷准备的,这种本地卷应该跟随 Pod 的生命周期。 它们对于使用 CSI 驱动为 Pod 提供 Secret、配置数据或其他特殊用途的存储可能很有用。

在以下情况下,CSI 驱动不适合内联使用:

  • 卷需要持续的时间超过 Pod 的生命周期
  • 卷快照、克隆或卷扩展是必需的
  • CSI 驱动需要 volumeAttributes 字段,此字段应该限制给管理员使用

如何使用此功能

为了使用这个功能,CSIDriver 规约必须明确将 Ephemeral 列举为 volumeLifecycleModes 的参数之一。 下面是一个来自 Secrets Store CSI Driver 的简单例子。

apiVersion: storage.k8s.io/v1
kind: CSIDriver
metadata:
  name: secrets-store.csi.k8s.io
spec:
  podInfoOnMount: true
  attachRequired: false
  volumeLifecycleModes:
  - Ephemeral

所有 Pod 规约都可以引用该 CSI 驱动来创建一个内联卷,如下例所示。

kind: Pod
apiVersion: v1
metadata:
  name: my-csi-app-inline
spec:
  containers:
    - name: my-frontend
      image: busybox
      volumeMounts:
      - name: secrets-store-inline
        mountPath: "/mnt/secrets-store"
        readOnly: true
      command: [ "sleep", "1000000" ]
  volumes:
    - name: secrets-store-inline
      csi:
        driver: secrets-store.csi.k8s.io
        readOnly: true
        volumeAttributes:
          secretProviderClass: "my-provider"

如果驱动程序支持一些卷属性,你也可以将这些属性作为 Pod spec 的一部分。

      csi:
        driver: block.csi.vendor.example
        volumeAttributes:
          foo: bar

使用案例示例

支持 Ephemeral 卷生命周期模式的两个现有 CSI 驱动是 Secrets Store CSI 驱动和 Cert-Manager CSI 驱动。

Secrets Store CSI Driver 允许用户将 Secret 作为内联卷从外部挂载到一个 Pod 中。 当密钥存储在外部管理服务或 Vault 实例中时,这可能很有用。

Cert-Manager CSI Drivercert-manager 协同工作, 无缝地请求和挂载证书密钥对到一个 Pod 中。这使得证书可以在应用 Pod 中自动更新。

安全考虑因素

应特别考虑哪些 CSI 驱动可作为内联卷使用。 volumeAttributes 通常通过 StorageClass 控制,并可能包含应限制给集群管理员的属性。 允许 CSI 驱动用于内联临时卷意味着任何有权限创建 Pod 的用户也可以通过 Pod 规约向驱动提供 volumeAttributes 字段。

集群管理员可以选择从 CSIDriver 规约中的 volumeLifecycleModes 中省略(或删除) Ephemeral, 以防止驱动被用作内联临时卷,或者使用准入 Webhook 来限制驱动的使用。

参考资料

关于此功能的更多信息,请参阅:

PodSecurityPolicy:历史背景

作者: Mahé Tardy (Quarkslab)

从 Kubernetes v1.25 开始,PodSecurityPolicy (PSP) 准入控制器已被移除。 在为 Kubernetes v1.21 发布的博文 PodSecurityPolicy 弃用:过去、现在和未来 中,已经宣布并详细说明了它的弃用情况。

本文旨在提供 PSP 诞生和演变的历史背景,解释为什么从未使该功能达到稳定状态,并说明为什么它被移除并被 Pod 安全准入控制取代。

PodSecurityPolicy 与其他专门的准入控制插件一样,作为内置的策略 API,对有关 Pod 安全设置的特定字段提供细粒度的权限。 它承认集群管理员和集群用户通常不是同一个人,并且以 Pod 形式或任何将创建 Pod 的资源的形式创建工作负载的权限不应该等同于“集群上的 root 账户”。 它还可以通过变更配置来应用更安全的默认值,并将底层 Linux 安全决策与部署过程分离来促进最佳实践。

PodSecurityPolicy 的诞生

PodSecurityPolicy 源自 OpenShift 的 SecurityContextConstraints (SCC), 它出现在 Red Hat OpenShift 容器平台的第一个版本中,甚至在 Kubernetes 1.0 之前。PSP 是 SCC 的精简版。

PodSecurityPolicy 的创建起源很难追踪,特别是因为它主要是在 Kubernetes 增强提案 (KEP) 流程之前添加的, 当时仍在使用设计提案(Design Proposal)。事实上,最终设计提案的存档仍然可以找到。 尽管如此,编号为 5 的 KEP 是在合并第一个拉取请求后创建的。

在添加创建 PSP 的第一段代码之前,两个主要的拉取请求被合并到 Kubernetes 中, SecurityContext 子资源 定义了 Pod 容器上的新字段,以及 ServiceAccount API 的第一次迭代。

Kubernetes 1.0 于 2015 年 7 月 10 日发布,除了 Alpha 阶段的 SecurityContextDeny 准入插件 (当时称为 scdeny)之外, 没有任何机制来限制安全上下文和工作负载的敏感选项。 SecurityContextDeny 插件 今天仍存在于 Kubernetes 中(作为 Alpha 特性),负责创建一个准入控制器,以防止在安全上下文中使用某些字段。

PodSecurityPolicy 的根源是早期关于安全策略的一个拉取请求, 它以 SCC(安全上下文约束)为基础,增加了新的 PSP 对象的设计方案。这是一个长达 9 个月的漫长讨论, 基于 OpenShift 的 SCC 反复讨论, 多次变动,并重命名为 PodSecurityPolicy,最终在 2016 年 2 月进入上游 Kubernetes。 现在 PSP 对象已经创建,下一步是添加一个可以执行这些政策的准入控制器。 第一步是添加不考虑用户或组 的准入控制。 2016 年 5 月,一个特定的使 PodSecurityPolicy 达到可用状态的问题被添加进来, 以跟踪进展,并在名为 PSP 准入的拉取请求中合并了准入控制器的第一个版本。 然后大约两个月后,发布了 Kubernetes 1.3。

下面是一个时间表,它以 1.0 和 1.3 版本作为参考点,回顾了 PodSecurityPolicy 及其准入控制器诞生的主要拉取请求。

Timeline of the PodSecurityPolicy creation pull requests

之后,PSP 准入控制器通过添加最初被搁置的内容进行了增强。 在 2016 年 11 月上旬合并鉴权机制, 允许管理员在集群中使用多个策略,为不同类型的用户授予不同级别的访问权限。 后来,2017 年 10 月合并的一个拉取请求 修复了 PodSecurityPolicies 在变更和字母顺序之间冲突的设计问题, 并继续构建我们所知道的 PSP 准入。之后,进行了许多改进和修复,以构建最近 Kubernetes 版本的 PodSecurityPolicy 功能。

Pod 安全准入的兴起

尽管 PodSecurityPolicy 试图解决的是一个关键问题,但它却包含一些重大缺陷:

  • 有缺陷的鉴权模式 - 如果用户针对 PSP 具有执行 use 动作的权限,而此 PSP 准许该 Pod 或者该 Pod 的服务帐户对 PSP 执行 use 操作,则用户可以创建一个 Pod。
  • 难以推广 - PSP 失败关闭。也就是说,在没有策略的情况下,所有 Pod 都会被拒绝。 这主要意味着默认情况下无法启用它,并且用户必须在启用该功能之前为所有工作负载添加 PSP, 因此没有提供审计模式来发现哪些 Pod 会不被新策略所允许。 这种采纳模式还导致测试覆盖率不足,并因跨特性不兼容而经常出现故障。 而且与 RBAC 不同的是,还不存在在项目中交付 PSP 清单的强大文化。
  • 不一致的无边界 API - API 的发展有很多不一致的地方,特别是由于许多小众场景的请求: 如标签、调度、细粒度的卷控制等。它的可组合性很差,优先级模型较弱,会导致意外的变更优先级。 这使得 PSP 与其他第三方准入控制器的结合真的很困难。
  • 需要安全知识 - 有效使用 PSP 仍然需要了解 Linux 的安全原语。 例如:MustRunAsNonRoot + AllowPrivilegeEscalation。

PodSecurityPolicy 的经验得出的结论是,大多数用户关心两个或三个策略,这导致了 Pod 安全标准的创建,它定义了三个策略:

  • Privileged(特权的) - 策略不受限制。
  • Baseline(基线的) - 策略限制很少,允许默认 Pod 配置。
  • Restricted(受限的) - 安全最佳实践策略。

作为 PSP 的替代品,新的 Pod 安全准入是 Kubernetes v1.25 的树内稳定的准入插件,用于在命名空间级别强制执行这些标准。 无需深入的安全知识,就可以更轻松地实施基本的 Pod 安全性。 对于更复杂的用例,你可能需要一个可以轻松与 Pod 安全准入结合的第三方解决方案。

下一步是什么

有关 SIG Auth 流程的更多详细信息,包括 PodSecurityPolicy 删除和 Pod 安全准入的创建, 请参阅在 KubeCon NA 2021 的 SIG auth update at KubeCon NA 2019PodSecurityPolicy Replacement: Past, Present, and Future 演示录像。

特别是在 PSP 移除方面,PodSecurityPolicy 弃用:过去、现在和未来博客文章仍然是准确的。

对于新的 Pod 安全许可,可以访问文档。 此外,博文 Kubernetes 1.23: Pod Security Graduers to Beta 以及 KubeCon EU 2022 演示文稿 the Hitchhicker’s Guide to Pod Security 提供了很好的实践教程来学习。

Kubernetes v1.25: Combiner

作者: Kubernetes 1.25 发布团队

宣布 Kubernetes v1.25 的发版!

这个版本总共包括 40 项增强功能。 其中 15 项增强功能进入 Alpha,10 项进入 Beta,13 项进入 Stable。 我们也废弃/移除了两个功能。

版本主题和徽标

Kubernetes 1.25: Combiner

Kubernetes v1.25 的主题是 Combiner,即组合器。

Kubernetes 项目本身是由特别多单独的组件组成的,这些组件组合起来就形成了你今天看到的这个项目。 同时它也是由许多个人建立和维护的,这些人拥有不同的技能、经验、历史和兴趣, 他们不仅作为发布团队成员,而且作为许多 SIG 成员,常年通力合作支持项目和社区。

通过这次发版,我们希望向协作和开源的精神致敬, 这种精神使我们从分散在世界各地的独立开发者、作者和用户变成了能够改变世界的联合力量。 Kubernetes v1.25 包含了惊人的 40 项增强功能, 如果没有我们在一起工作时拥有的强大力量,这些增强功能都不会存在。

受我们的发布负责人的儿子 Albert Song 的启发,Kubernetes v1.25 是以你们每一个人命名的, 无论你们选择如何作为 Kubernetes 的联合力量贡献自己的独有力量。

新增内容(主要主题)

移除 PodSecurityPolicy;Pod Security Admission 成长为 Stable

PodSecurityPolicy 是在 1.21 版本中被弃用,到 1.25 版本被移除。 因为提升其可用性的变更会带来破坏性的变化,所以有必要将其删除,以支持一个更友好的替代品。 这个替代品就是 Pod Security Admission,它在这个版本里成长为 Stable。 如果你最近依赖于 PodSecurityPolicy,请参考 Pod Security Admission 迁移说明

Ephemeral Containers 成长为 Stable

临时容器是在现有的 Pod 中存在有限时间的容器。 当你需要检查另一个容器,但因为该容器已经崩溃或其镜像缺乏调试工具不能使用 kubectl exec 时,它对故障排除特别有用。 临时容器在 Kubernetes v1.23 中成长为 Beta,并在这个版本中,该功能成长为 Stable。

对 cgroups v2 的支持进入 Stable 阶段

自 Linux 内核 cgroups v2 API 宣布稳定以来,已经有两年多的时间了。 随着一些发行版现在默认使用该 API,Kubernetes 必须支持它以继续在这些发行版上运行。 cgroups v2 比 cgroups v1 提供了一些改进,更多信息参见 cgroups v2 文档。 虽然 cgroups v1 将继续受到支持,但这一改进使我们能够为其最终的废弃和替代做好准备。

改善对 Windows 系统的支持

将容器注册服务从 k8s.gcr.io 迁移至 registry.k8s.io

将容器注册服务从 k8s.gcr.io 迁移至 registry.k8s.io 的 PR 已经被合并。 更多细节参考 wiki 页面, 同时公告已发送到 kubernetes 开发邮件列表。

SeccompDefault 升级为 Beta

SeccompDefault 升级为 Beta, 更多细节参考教程用 seccomp 限制一个容器的系统调用

网络策略中 endPort 升级为 Stable

网络策略中的 endPort 已经迎来 GA 正式发布。 支持 endPort 字段的网络策略提供程序现在可使用该字段来指定端口范围,应用网络策略。 在之前的版本中,每个网络策略只能指向单一端口。

请注意,网络策略提供程序 必须支持 endPort 字段。 如果提供程序不支持 endPort,又在网络策略中指定了此字段, 则会创建出仅覆盖端口字段(单端口)的网络策略。

本地临时容器存储容量隔离升级为 Stable

本地临时存储容量隔离功能已经迎来 GA 正式发布版本。 该功能在 1.8 版中作为 alpha 版本引入,在 1.10 中升级为 beta,现在终于成为了稳定功能。 它提供了对 Pod 之间本地临时存储容量隔离的支持,如 EmptyDir, 因此,如果一个 Pod 对本地临时存储容量的消耗超过该限制,就可以通过驱逐 Pod 来硬性限制其对共享资源的消耗。

核心 CSI 迁移为稳定版

CSI 迁移是 SIG Storage 在之前多个版本中做出的持续努力。 目标是将树内数据卷插件转移到树外 CSI 驱动程序并最终移除树内数据卷插件。 此次核心 CSI 迁移已迎来 GA。 同样,GCE PD 和 AWS EBS 的 CSI 迁移也进入 GA 阶段。 vSphere 的 CSI 迁移仍为 beta(但也默认启用)。 Portworx 的 CSI 迁移同样处于 beta 阶段(但默认不启用)。

CSI 临时数据卷升级为稳定版

CSI 临时数据卷 功能允许在临时使用的情况下在 Pod 里直接指定 CSI 数据卷。 因此可以直接用它们在使用挂载卷的 Pod 内注入任意状态,如配置、秘密、身份、变量或类似信息。 这个功能最初是作为 alpha 功能在 1.15 版本中引入,现在已升级为 GA 通用版。 某些 CSI 驱动程序会使用此功能,例如存储密码的 CSI 驱动程序

CRD 验证表达式语言升级为 Beta

CRD 验证表达式语言已升级为 beta 版本, 这使得声明如何使用通用表达式语言(CEL)验证自定义资源成为可能。 请参考验证规则指导。

服务器端未知字段验证升级为 Beta

ServerSideFieldValidation 特性门控已升级为 beta(默认开启)。 它允许在检测到未知字段时,有选择地触发 API 服务器上的模式验证机制。 因此这允许从 kubectl 中移除客户端验证的同时保持相同的核心功能,即对包含未知或无效字段的请求进行错误处理。

引入 KMS v2 API

引入 KMS v2 alpha1 API 以提升性能,实现轮替与可观察性改进。 此 API 使用 AES-GCM 替代了 AES-CBC,通过 DEK 实现静态数据(即 Kubernetes Secrets)加密。 过程中无需额外用户操作,而且仍然支持通过 AES-GCM 和 AES-CBC 进行读取。 更多信息参考使用 KMS provider 进行数据加密指南。

Kube-proxy 镜像当前基于无发行版镜像

在以前的版本中,kube-proxy 的容器镜像是以 Debian 作为基础镜像构建的。 从这个版本开始,其镜像现在使用 distroless 来构建。 这一改变将镜像的大小减少了近 50%,并将安装的软件包和文件的数量减少到只有 kube-proxy 工作所需的那些。

其他更新

稳定版升级

1.25 版本共包含 13 项升级至稳定版的增强功能:

弃用和移除

1.25 版本废弃/移除两个功能。

发行版说明

Kubernetes 1.25 版本的完整信息可参考发行版说明

获取

Kubernetes 1.25 版本可在 GitHub 下载获取。 开始使用 Kubernetes 请查看这些交互式教程或者使用 kind 把容器当作 “节点” 来运行本地 Kubernetes 集群。 你也可以使用 kubeadm 来简单的安装 1.25 版本。

发布团队

Kubernetes 的发展离不开其社区的支持、承诺和辛勤工作。 每个发布团队都是由专门的社区志愿者组成的,他们共同努力,建立了许多模块,这些模块结合起来,就构成了你所依赖的 Kubernetes。 从代码本身到文档和项目管理,这需要我们社区每一个人的专业技能。

重要用户

生态系统更新

  • 2022 北美 KubeCon + CloudNativeCon 将于 2022 年 10 月 24 - 28 日在密歇根州的底特律举行! 你可以在活动网站找到更多关于会议和注册的信息。
  • KubeDay 系列活动将于 12 月 7 日在日本 KubeDay 拉开帷幕! 在活动网站上注册或提交提案。
  • 2021 云原生调查中,CNCF 看见了创纪录的 Kubernetes 和容器应用。 请参考调查结果

项目进度

CNCF K8s DevStats 项目汇集了大量关于 Kubernetes 和各种子项目研发进度相关性的有趣的数据点。 其中包括从个人贡献到参与贡献的公司数量的全面信息, 并证明了为发展 Kubernetes 生态系统所做努力的深度和广度。

在 1.25 版本的发布周期中, 该周期运行了 14 周 (May 23 to August 23), 我们看到来着 1065 家公司 以及 1620 位个人所做出的贡献。

即将举行的网络发布研讨会

加入 Kubernetes 1.25 版本发布团队的成员,将于 2022 年 9 月 22 日星期四上午 10 点至 11 点(太平洋时间)了解该版本的主要功能, 以及弃用和删除的内容,以帮助制定升级计划。 欲了解更多信息和注册,请访问活动页面

参与其中

参与 Kubernetes 最简单的方法就是加入众多特殊兴趣小组(SIGs) 中你感兴趣的一个。 你有什么东西想要跟 Kubernetes 社区沟通吗? 来我们每周的社区会议分享你的想法,并参考一下渠道:

聚焦 SIG Storage

作者:Frederico Muñoz (SAS)

自 Kubernetes 诞生之初,持久数据以及如何解决有状态应用程序的需求一直是一个重要的话题。 对无状态部署的支持是很自然的、从一开始就存在的,并引起了人们的关注,变得众所周知。 从早期开始,我们也致力于更好地支持有状态应用程序,每个版本都增加了可以在 Kubernetes 上运行的范围。

消息队列、数据库、集群文件系统:这些是具有不同存储要求的解决方案的一些示例, 如今这些解决方案越来越多地部署在 Kubernetes 中。 处理来自许多不同供应商的临时和持久存储(本地或远程、文件或块),同时考虑如何提供用户期望的所需弹性和数据一致性, 所有这些都在 SIG Storage 的整体负责范围之内。

在这次 SIG Storage 采访报道中,Frederico Muñoz (SAS 的云和架构负责人)与 VMware 技术负责人兼 SIG Storage 联合主席 Xing Yang,讨论了 SIG 的组织方式、当前的挑战是什么以及如何进行参与和贡献。

关于 SIG Storage

Frederico (FSM):你好,感谢你给我这个机会了解更多关于 SIG Storage 的情况。 你能否介绍一下你自己、你的角色以及你是如何参与 SIG Storage 的。

Xing Yang (XY):我是 VMware 的技术主管,从事云原生存储方面的工作。我也是 SIG Storage 的联合主席。 我从 2017 年底开始参与 K8s SIG Storage,开始为 VolumeSnapshot 项目做贡献。 那时,VolumeSnapshot 项目仍处于实验性的 pre-alpha 阶段。它需要贡献者。所以我自愿提供帮助。 然后我与其他社区成员合作,在 2018 年的 K8s 1.12 版本中将 VolumeSnapshot 带入 Alpha, 2019 年在 K8s 1.17 版本中带入 Beta,并最终在 2020 年在 1.20 版本中带入 GA。

FSM:仅仅阅读 SIG Storage 章程 就可以看出,SIG Storage 涵盖了很多领域,你能描述一下 SIG 的组织方式吗?

XY:在 SIG Storage 中,有两位联合主席和两位技术主管。来自 Google 的 Saad Ali 和我是联合主席。 来自 Google 的 Michelle Au 和来自 Red Hat 的 Jan Šafránek 是技术主管。

我们每两周召开一次会议,讨论我们正在为每个特定版本开发的功能,获取状态,确保每个功能都有开发人员和审阅人员在处理它, 并提醒人们发布截止日期等。有关 SIG 的更多信息,请查阅社区页面。 人们还可以将需要关注的 PR、需要讨论的设计提案和其他议题添加到会议议程文档中。 我们将在项目跟踪完成后对其进行审查。

我们还举行其他的定期会议,如 CSI 实施会议,Object Bucket API 设计会议,以及在需要时针对特定议题的一次性会议。 还有一个由 SIG Storage 和 SIG Apps 赞助的 K8s 数据保护工作组。 SIG Storage 拥有或共同拥有数据保护工作组正在讨论的功能特性。

存储和 Kubernetes

FSM:存储是很多模块的基础组件,尤其是 Kubernetes:你认为 Kubernetes 在存储管理方面的具体挑战是什么?

XY:在 Kubernetes 中,卷操作涉及多个组件。例如,创建一个使用 PVC 的 Pod 涉及多个组件。 有 Attach Detach Controller 和 external-attacher 负责将 PVC 连接到 Pod。 还有 Kubelet 可以将 PVC 挂载到 Pod 上。当然,CSI 驱动程序也参与其中。 在多个组件之间进行协调时,有时可能会出现竞争状况。

另一个挑战是关于核心与 Custom Resource Definitions(CRD), 这并不是特定于存储的。CRD 是一种扩展 Kubernetes 功能的好方法,同时又不会向 Kubernetes 核心本身添加太多代码。 然而,这也意味着运行 Kubernetes 集群时需要许多外部组件。

在 SIG Storage 方面,一个最好的例子是卷快照。卷快照 API 被定义为 CRD。 API 定义和控制器是 out-of-tree。有一个通用的快照控制器和一个快照验证 Webhook 应该部署在控制平面上,类似于 kube-controller-manager 的部署方式。 虽然 Volume Snapshot 是一个 CRD,但它是 SIG Storage 的核心特性。 建议 K8s 集群发行版部署卷快照 CRD、快照控制器和快照验证 Webhook,然而,大多数时候我们没有看到发行版部署它们。 因此,这对存储供应商来说就成了一个问题:现在部署这些非驱动程序特定的通用组件成为他们的责任。 如果客户需要使用多个存储系统,且部署多个 CSI 驱动,可能会导致冲突。

FSM:不仅要考虑单个存储系统的复杂性,还要考虑它们在 Kubernetes 中如何一起使用?

XY:是的,有许多不同的存储系统可以为 Kubernetes 中的容器提供存储。它们的工作方式不同。找到适合所有人的解决方案是具有挑战性的。

FSM:Kubernetes 中的存储还涉及与外部解决方案的交互,可能比 Kubernetes 的其他部分更多。 这种与供应商和外部供应商的互动是否具有挑战性?它是否以任何方式随着时间而演变?

XY:是的,这绝对是具有挑战性的。最初 Kubernetes 存储具有 in-tree 卷插件接口。 多家存储供应商实现了 in-tree 接口,并在 Kubernetes 核心代码库中拥有卷插件。这引起了很多问题。 如果卷插件中存在错误,它会影响整个 Kubernetes 代码库。所有卷插件必须与 Kubernetes 一起发布。 如果存储供应商需要修复其插件中的错误或希望与他们自己的产品版本保持一致,这是不灵活的。

FSM:这就是 CSI 加入的原因?

XY:没错,接下来就是容器存储接口(CSI)。 这是一个试图设计通用存储接口的行业标准,以便存储供应商可以编写一个插件并让它在一系列容器编排系统(CO)中工作。 现在 Kubernetes 是主要的 CO,但是在 CSI 刚开始的时候,除了 Kubernetes 之外,还有 Docker、Mesos、Cloud Foundry。 CSI 驱动程序是 out-of-tree 的,因此可以按照自己的节奏进行错误修复和发布。

与 in-tree 卷插件相比,CSI 绝对是一个很大的改进。CSI 的 Kubernetes 实现自 1.13 版本以来就达到 GA。 它已经发展了很长时间。SIG Storage 一直致力于将 in-tree 卷插件迁移到 out-of-tree 的 CSI 驱动,已经有几个版本了。

FSM:将驱动程序从 Kubernetes 主仓移到 CSI 中是一项重要的改进。

XY: CSI 接口是对 in-tree 卷插件接口的改进,但是仍然存在挑战。有很多存储系统。 目前在 CSI 驱动程序文档中列出了 100 多个 CSI 驱动程序。 这些存储系统也非常多样化。因此,很难设计一个适用于所有人的通用 API。 我们在 CSI 驱动层面引入了功能,但当同一驱动配置的卷具有不同的行为时,我们也会面临挑战。 前几天我们刚刚开会讨论每种卷 CSI 驱动程序功能。 当同一个驱动程序同时支持块卷和文件卷时,我们在区分某些 CSI 驱动程序功能时遇到了问题。 我们将召开后续会议来讨论这个问题。

持续的挑战

FSM:具体来说,对于 1.25 版本 们可以看到管道中有一些与存储相关的 KEPs。 你是否认为这个版本对 SIG 特别重要?

XY:我不会说一个版本比其他版本更重要。在任何给定的版本中,我们都在做一些非常重要的事情。

FSM:确实如此,但你是否想指出 1.25 版本的特定特性和亮点呢?

XY:好的。对于 1.25 版本,我想强调以下几点:

  • CSI 迁移 是一项持续的工作,SIG Storage 已经工作了几个版本了。目标是将 in-tree 卷插件移动到 out-of-tree 的 CSI 驱动程序,并最终删除 in-tree 卷插件。在 1.25 版本中,有 7 个 KEP 与 CSI 迁移有关。 有一个核心 KEP 用于通用的 CSI 迁移功能。它的目标是在 1.25 版本中达到 GA。 GCE PD 和 AWS EBS 的 CSI 迁移以 GA 为目标。vSphere 的 CSI 迁移的目标是在默认情况下启用特性门控, 在 1.25 版本中达到 Beta。Ceph RBD 和 PortWorx 的目标是达到 Beta,默认关闭特性门控。 Ceph FS 的目标是达到 Alpha。
  • 我要强调的第二个是 COSI,容器对象存储接口。 这是 SIG Storage 下的一个子项目。COSI 提出对象存储 Kubernetes API 来支持 Kubernetes 工作负载的对象存储操作的编排。 它还为对象存储提供商引入了 gRPC 接口,以编写驱动程序来配置存储桶。COSI 团队已经在这个项目上工作两年多了。 COSI 功能的目标是 1.25 版本中达到 Alpha。KEP 刚刚合入。COSI 团队正在根据更新后的 KEP 更新实现。
  • 我要提到的另一个功能是 CSI 临时卷支持。 此功能允许在临时用例的 Pod 规约中直接指定 CSI 卷。它们可用于使用已安装的卷直接在 Pod 内注入任意状态, 例如配置、Secrets、身份、变量或类似信息。这最初是在 1.15 版本中作为一个 Alpha 功能引入的,现在它的目标是在 1.25 版本中达到 GA。

FSM:如果你必须单独列出一些内容,那么 SIG 正在研究的最紧迫的领域是什么?

XY:CSI 迁移绝对是 SIG 投入大量精力的领域之一,并且现在已经进行了多个版本。它还涉及来自多个云提供商和存储供应商的工作。

社区参与

FSM:Kubernetes 是一个社区驱动的项目。对任何希望参与 SIG Storage 工作的人有什么建议吗?他们应该从哪里开始?

XY:查看 SIG Storage 社区页面, 它有很多关于如何开始的信息。SIG 年度报告告诉你我们每年做了什么。 查看贡献指南。它有一些演示的链接,可以帮助你熟悉 Kubernetes 存储概念。

参加我们在星期四举行的双周会议。 了解 SIG 的运作方式以及我们为每个版本所做的工作。找到你感兴趣的项目并提供贡献。 正如我之前提到的,我通过参与 Volume Snapshot 项目开始了 SIG Storage。

FSM:你有什么要补充的结束语吗?

XY:SIG Storage 总是欢迎新的贡献者。 我们需要贡献者来帮助构建新功能、修复错误、进行代码审查、编写测试、监控测试网格的健康状况以及改进文档等。

FSM:非常感谢你抽出宝贵时间让我们深入了解 SIG Storage!

认识我们的贡献者 - 亚太地区(中国地区)

作者和受访者: Avinesh TripathiDebabrata PanigrahiJayesh SrivastavaPriyanka SagguPurneswar PrasadVedant Kakde


大家好 👋

欢迎来到亚太地区的 “认识我们的贡献者” 博文系列第三期。

这篇博文介绍了四名来自中国的优秀贡献者,他们在上游 Kubernetes 项目中扮演了不同的领导角色和社区角色。

闲话少说,让我们直接进入正文。

Andy Zhang

Andy Zhang 目前就职于微软中国上海办事处,他主要关注 Kubernetes 存储驱动。 Andy 大约在 5 年前开始为 Kubernetes 做贡献。

他说由于自己为 Azure Kubernetes Service 团队工作,所以大部分时间都在为 Kubernetes 社区项目做贡献。 现在他是很多 Kubernetes 子项目的主要贡献者,例如 Kubernetes cloud-provider 仓库的代码。

他的开源贡献主要是出于自我激励。在过去的两年里,他通过 LFX Mentorship 计划指导了一些学生为 Kubernetes 做贡献, 其中一些学生凭借 Kubernetes 项目积累的专业知识和贡献经历而找到了工作。

Andy 是 Kubernetes 中国社区的活跃成员。 他补充说,Kubernetes 社区对如何成为 Member、Code Reviewer、Approver 有完善的指导说明, 后来他发现一些开源项目还处于非常早期的阶段,他积极地为这些项目做了贡献并成为了项目维护者。

Shiming Zhang

Shiming Zhang 是一名软件工程师,供职于中国上海道客网络科技。

他主要以 Reviewer 的身份参与 SIG Node。他的主要贡献集中在当下的 KEP 的漏洞修复和功能优化,这些工作全部围绕 SIG Node 展开。

他发起的一些主要 PR 有 fixing watchForLockfileContention memory leakfixing startupProbe behaviouradding Field status.hostIPs for Pod

Paco Xu

Paco Xu 就职于上海的一家云原生公司:道客网络科技。 他与基础设施和开源团队合作,专注于基于 Kubernetes 的企业云原生平台。

他在 2017 年初开始使用 Kubernetes,他的第一个贡献是在 2018 年 3 月。 他的贡献始于自己发现的一个漏洞,但当时他的解决方案不是那么优雅,因此没有被接受。 然后他从一些 Good First Issue 开始做贡献,这在很大程度上帮助了他。 除此之外,在 2016 到 2017 年间,他还对 Docker 做出了一些小贡献。

目前,Paco 是 kubeadm(一个 SIG Cluster Lifecycle 产品)和 SIG Node 的 Reviewer。

Paco 说大家应该为自己使用的开源项目做贡献。 对他来说,开源项目就像一本要学习的书,通过与项目维护者们讨论可以获得启发。

在我看来,对我来说最好的方式是学习项目所有者如何处理项目。

Jintao Zhang

Jintao Zhang 目前受聘于 API7,他专注于 Ingress 和服务网格。

2017 年,他遇到了一个引发社区讨论的问题,并开始了对 Kubernetes 做贡献。 在为 Kubernetes 做贡献之前,Jintao 是 Docker 相关开源项目的长期贡献者。

目前 Jintao 是 ingress-nginx 项目的 Reviewer。

他建议关注开源公司的工作机会,这样你就可以找到一个可以让你全职贡献的机会。 对于新的贡献者们,Jintao 表示如果有人想为一个开源项目做重大贡献, 那么应该根据自己的兴趣选择项目,然后应该慷慨地投入时间。


如果你对我们下一步应该采访谁有任何想法/建议,请在 #sig-contribex 频道中告知我们。 我们很高兴有其他人帮助我们接触社区中更优秀的人。我们将不胜感激。

我们下期见。最后,祝大家都能快乐地为社区做贡献!👋

逐个 KEP 地增强 Kubernetes

作者: Ryler Hockenbury(Mastercard)

你是否知道 Kubernetes v1.24 有 46 个增强特性? 在为期 4 个月的发布周期内包含了大量新特性。 Kubernetes 发布团队协调发布的后勤工作,从修复测试问题到发布更新的文档。他们需要完成成吨的工作,但发布团队总是能按期交付。

发布团队由大约 30 人组成,分布在六个子团队:Bug Triage、CI Signal、Enhancements、Release Notes、Communications 和 Docs。 每个子团队负责管理发布的一个组件。这篇博文将重点介绍增强子团队的角色以及你如何能够参与其中。

增强子团队是什么?

好问题。我们稍后会讨论这个问题,但首先让我们谈谈 Kubernetes 中是如何管理功能特性的。

每个新特性都需要一个 Kubernetes 增强提案, 简称为 KEP。KEP 是一些小型结构化设计文档,提供了一种提出和协调新特性的方法。 KEP 作者描述其提案动机、设计理念(和替代方案)、风险和测试,然后社区成员会提供反馈以达成共识。

你可以通过 Kubernetes/enhancements 仓库的拉取请求(PR)工作流来提交和更新 KEP。 每个功能特性始于 Alpha 阶段,随着不断成熟,经由毕业流程进入 Beta 和 Stable 阶段。 这里有一个很酷的 KEP 例子,是关于 Windows Server 上的特权容器支持。 这个 KEP 在 Kubernetes v1.22 中作为 Alpha 引入,并在 v1.23 中进入 Beta 阶段。

现在回到上一个问题:增强子团队如何协调每个版本的 KEP 生命周期跟踪。 每个 KEP 都必须满足一组清晰具体的要求,才能被纳入一个发布版本中。 增强子团队负责验证每个 KEP 的要求并跟踪其状态。

在一个发行版本启动时,各个 Kubernetes 特别兴趣小组 (SIG) 会提交各自的增强特性以进入某版本发布。通常一个版本最初可能有 60 到 90 个增强特性。随后,许多增强特性会被过滤掉。 这是因为有些不完全符合 KEP 要求,而另一些还未完成代码的实现。最初选择加入的 KEP 中大约有 60% - 70% 将进入最终发布。

增强子团队做什么?

这是另一个很好的问题,切中了要点!增强特性的团队在每个版本中会涉及两个重要的里程碑:增强特性冻结和代码冻结。

增强特性冻结

增强特性冻结是一个 KEP 按序完成增强特性并纳入一个发布版本的最后期限。 这是一个质量门控,用于强制对齐与 KEP 维护和更新相关的事项。 最值得注意的要求是 (1) 生产就绪审查(PRR) 和 (2) 附带完整测试计划和毕业标准的 KEP 文件

增强子团队通过在 Github 上对 KEP 问题发表评论与每位 KEP 作者进行沟通。 作为第一步,子团队成员将检查 KEP 状态并确认其是否符合要求。 KEP 在满足要求后被标记为已被跟踪(Tracked);否则,它会被认为有风险。 如果在增强特性冻结生效时 KEP 仍然存在风险,该 KEP 将被从发布版本中移除。

在发布周期的这个阶段,增强子团队通常是最繁忙的,因为他们要梳理大量的 KEP,可能需要反复审查每个 KEP 才能验证某个 KEP 是否满足要求。

代码冻结

代码冻结是从代码上实现所有增强特性的最后期限。 如果某增强特性的代码需要更改或更新,则必须在这个时间节点完成所有代码实现、代码审查和代码合并工作。 版本发布的最后三个工作专注于稳定代码库:修复测试问题,解决各种回归并准备文档。而在此之前,所有代码必须就位。

增强子团队将验证某增强特性相关的所有 PR 均已合并到 Kubernetes 代码库 (k/k)。 在此期间,子团队将联系 KEP 作者以了解哪些 PR 是 KEP 的一部分,检查这些 PR 是否已合并,然后更新 KEP 的状态。 如果在代码冻结的最后期限之前这些代码还未全部合并,该增强特性将从发布版本中移除。

我如何才能参与发布团队?

很高兴你提出这个问题。 最直接的方式就是申请成为一名发布团队影子。 影子角色是一个见习职位,旨在帮助个人在发布团队中担任领导职位做好准备。许多影子角色是非技术性的,且不需要事先对 Kubernetes 代码库做出贡献。

Kubernetes 每年发布 3 个版本,每个版本大约有 25 个影子,发布团队总是需要愿意做出贡献的人。 在每个发布周期之前,发布团队都会为影子计划打开申请渠道。当申请渠道上线时, 会公布在 Kubernetes 开发邮件清单中。 你可以订阅该列表中的通知(或定期查看!),以了解申请渠道何时开通。该公告通常会在 4 月中旬、7 月中旬和 12 月中旬发布, 或者在每个版本开始前大约一个月时发布。

我怎样才能找到更多信息?

如果你对所有 Kubernetes 发布子团队的详情感到好奇, 请查阅角色手册。 这些手册记录了每个子团队的后勤工作,包括每周对子团队活动的细分任务。这是更好地了解每个团队的绝佳参考。

你还可以查看与发布相关的 Kubernetes slack 频道,特别是 #release、#sig-release 和 #sig-arch。 这些频道围绕发布的许多方面进行了讨论和更新。

Kubernetes 1.25 的移除说明和主要变更

作者:Kat Cosgrove、Frederico Muñoz、Debabrata Panigrahi

随着 Kubernetes 成长和日趋成熟,为了此项目的健康发展,某些功能特性可能会被弃用、移除或替换为优化过的功能特性。 Kubernetes v1.25 包括几个主要变更和一个主要移除。

Kubernetes API 移除和弃用流程

Kubernetes 项目对功能特性有一个文档完备的弃用策略。 该策略规定,只有当较新的、稳定的相同 API 可用时,原有的稳定 API 才可能被弃用,每个稳定级别的 API 都有一个最短的生命周期。 弃用的 API 指的是已标记为将在后续发行某个 Kubernetes 版本时移除的 API; 移除之前该 API 将继续发挥作用(从弃用起至少一年时间),但使用时会显示一条警告。 移除的 API 将在当前版本中不再可用,此时你必须迁移以使用替换的 API。

  • 正式发布(GA)或稳定的 API 版本可能被标记为已弃用,但只有在 Kubernetes 大版本更新时才会移除。
  • 测试版(Beta)或预发布 API 版本在弃用后必须支持 3 个版本。
  • Alpha 或实验性 API 版本可能会在任何版本中被移除,恕不另行通知。

无论一个 API 是因为某功能特性从 Beta 进入稳定阶段而被移除,还是因为该 API 根本没有成功, 所有移除均遵从上述弃用策略。无论何时移除一个 API,文档中都会列出迁移选项。

有关 PodSecurityPolicy 的说明

继 PodSecurityPolicy 在 v1.21 弃用后, Kubernetes v1.25 将移除 PodSecurityPolicy。PodSecurityPolicy 曾光荣地为我们服务, 但由于其复杂和经常令人困惑的使用方式,让大家觉得有必要进行修改,但很遗憾这种修改将会是破坏性的。 为此我们移除了 PodSecurityPolicy,取而代之的是 Pod Security Admission(即 PodSecurity 安全准入控制器), 后者在本次发行中也进入了稳定阶段。 如果你目前正依赖 PodSecurityPolicy,请遵循指示说明迁移到 PodSecurity 准入控制器

Kubernetes v1.25 的主要变更

Kubernetes v1.25 除了移除 PodSecurityPolicy 之外,还将包括以下几个主要变更。

CSI Migration

将树内卷插件迁移到树外 CSI 驱动的努力还在继续,核心的 CSI Migration 特性在 v1.25 进入 GA 阶段。 对于全面移除树内卷插件而言,这是重要的一步。

存储驱动的弃用和移除

若干卷插件将被弃用或移除。

GlusterFS 将在 v1.25 中被弃用。 虽然为其构建了 CSI 驱动,但未曾得到维护。 社区曾讨论迁移到一个兼容 CSI 驱动的可能性, 但最终决定开始从树内驱动中弃用 GlusterFS 插件。 本次发行还会弃用 Portworx 树内卷插件。 Flocker、Quobyte 和 StorageOS 树内卷插件将被移除。

FlockerQuobyteStorageOS 树内卷插件将作为 CSI Migration 的一部分在 v1.25 中移除。

对 vSphere 版本支持的变更

从 Kubernetes v1.25 开始,树内 vSphere 卷驱动将不支持任何早于 7.0u2 的 vSphere 版本。 查阅 v1.25 详细发行说明,了解如何处理这种状况的更多建议。

清理 IPTables 链的所有权

在 Linux 上,Kubernetes(通常)创建 iptables 链来确保这些网络数据包到达, 尽管这些链及其名称已成为内部实现的细节,但某些工具已依赖于此行为。 将仅支持内部 Kubernetes 使用场景。 从 v1.25 开始,Kubelet 将逐渐迁移为不在 nat 表中创建以下 iptables 链:

  • KUBE-MARK-DROP
  • KUBE-MARK-MASQ
  • KUBE-POSTROUTING

此项变更将通过 IPTablesCleanup 特性门控分阶段完成。 尽管这不是正式的弃用,但某些最终用户已开始依赖 kube-proxy 特定的内部行为。 Kubernetes 项目总体上希望明确表示不支持依赖这些内部细节,并且未来的实现将更改它们在此处的行为。

展望未来

Kubernetes 1.26 计划移除的 API 的正式列表为:

  • Beta 版 FlowSchema 和 PriorityLevelConfiguration API(flowcontrol.apiserver.k8s.io/v1beta1)
  • Beta 版 HorizontalPodAutoscaler API(autoscaling/v2beta2)

了解更多

Kubernetes 发行说明公布了弃用信息。你可以在以下版本的发行说明中查看待弃用特性的公告:

有关弃用和移除流程的信息,请查阅 Kubernetes 官方弃用策略文档。

聚光灯下的 SIG Docs

作者: Purneswar Prasad

简介

官方文档是所有开源项目的首选资料源。对于 Kubernetes,它是一个持续演进的特别兴趣小组 (SIG), 人们持续不断努力制作详实的项目资料,让新贡献者和用户更容易取用这些文档。 SIG Docs 在 kubernetes.io 上发布官方文档, 包括但不限于 Kubernetes 版本发布时附带的核心 API 文档、核心架构细节和 CLI 工具文档。

为了了解 SIG Docs 的工作及其在塑造社区未来方面的更多信息,我总结了自己与联合主席 Divya Mohan(下称 DM)、 Rey Lejano(下称 RL)和 Natali Vlatko(下称 NV)的谈话, 他们讲述了 SIG 的目标以及其他贡献者们如何从旁协助。

谈话汇总

你能告诉我们 SIG Docs 具体做什么吗?

SIG Docs 是 kubernetes.io 上针对 Kubernetes 项目文档的特别兴趣小组, 为 Kubernetes API、kubeadm 和 kubectl 制作参考指南,并维护官方网站的基础设施和数据分析。 他们的工作范围还包括文档发布、文档翻译、改进并向现有文档添加新功能特性、推送和审查官方 Kubernetes 博客的内容, 并在每个发布周期与发布团队合作以审查文档和博客。

Docs 下有 2 个子项目:博客和本地化。社区如何从中受益?你想强调的这些团队是否侧重于某些贡献?

博客:这个子项目侧重于介绍新的或毕业的 Kubernetes 增强特性、社区报告、SIG 更新或任何与 Kubernetes 社区相关的新闻,例如思潮引领、教程和项目更新,例如即将在 1.25 版本中移除 Dockershim 和 PodSecurityPolicy。 Tim Bannister 是 SIG Docs 技术负责人之一,他做得工作非常出色,是推动文档和博客贡献的主力人物。

本地化:通过这个子项目,Kubernetes 社区能够在用户和贡献者之间实现更大的包容性和多样性。 自几年前以来,这也帮助该项目获得了更多的贡献者,尤其是学生们。 主要亮点之一是即将到来的本地化版本:印地语和孟加拉语。印地语的本地化工作目前由印度的学生们牵头。

除此之外,还有另外两个子项目:reference-docswebsite,后者采用 Hugo 构建,是 Kubernetes 拥有的一个重要阵地。

最近有很多关于 Kubernetes 生态系统以及业界对最新 1.24 版本中移除 Dockershim 的讨论。SIG Docs 如何帮助该项目确保最终用户们平滑变更?

与 Dockershim 移除有关的文档工作是一项艰巨的任务,需要修改现有文档并就弃用工作与各种利益相关方进行沟通。 这需要社区的努力,因此在 1.24 版本发布之前,SIG Docs 与 Docs and Comms 垂直行业、来自发布团队的发布负责人以及 CNCF 建立合作关系,帮助在全网宣传。设立了每周例会和 GitHub 项目委员会,以跟踪进度、审查问题和批准 PR, 并保持更新 Kubernetes 网站。这也有助于新的贡献者们了解这次弃用,因此如果出现任何 good-first-issue, 新的贡献者也可以参与进来。开通了专用的 Slack 频道用于交流会议更新、邀请反馈或就悬而未决的问题和 PR 寻求帮助。 每周例会在 1.24 发布后也持续了一个月,以审查并修复相关问题。 非常感谢 Celeste Horgan,与他的顺畅交流贯穿了这个弃用过程的前前后后。

为什么新老贡献者都应该考虑加入这个 SIG?

Kubernetes 是一个庞大的项目,起初可能会让很多人难以找到切入点。 任何开源项目的优劣总能从文档质量略窥一二,SIG Docs 的目标是建设一个欢迎新贡献者加入并对其有帮助的地方。 希望所有人可以轻松参与该项目的文档,并能从阅读中受益。他们还可以带来自己的新视角,以制作和改进文档。 从长远来看,如果他们坚持参与 SIG Docs,就可以拾阶而上晋升成为维护者。 这将有助于使 Kubernetes 这样的大型项目更易于解析和导航。

你如何帮助新的贡献者入门?加入有什么前提条件吗?

开始为 Docs 做贡献没有这样的前提条件。但肯定有一个很棒的对文档做贡献的指南,这个指南始终尽可能保持更新和贴合实际, 希望新手们多多阅读并将其放在趁手的地方。此外,社区 Slack 频道 #sig-docs 中有很多有用的便贴和书签。 kubernetes/website 仓库中带有 good-first-issue 标签的那些 GitHub 问题是创建你的第一个 PR 的好地方。 现在,SIG Docs 在每月的第一个星期二配合第一任 New Contributor Ambassador(新贡献者大使)角色 Arsh Sharma 召开月度 New Contributor Meet and Greet(新贡献者见面会)。 这有助于在 SIG 内为新的贡献者建立一个更容易参与的联络形式。

你是否有任何真正自豪的 SIG 相关成绩?

DM & RL :鉴于来自不同国家的贡献者们做出的所有出色工作, 过去几个月本地化子项目的正式推行对 SIG Docs 来说是一个巨大的胜利。 早些时候,本地化工作还没有任何流水线的流程,过去几个月的重点是通过起草一份 KEP 为本地化正式成为一个子项目提供一个框架, 这项工作计划在第三个季度结束时完成。

DM:另一个取得很大成功的领域是 New Contributor Ambassador(新贡献者大使)角色, 这个角色有助于为新贡献者参与项目提供更便捷的联系形式。

NV:对于每个发布周期,SIG Docs 都必须在短时间内评审突出介绍发布更新的发布文档和功能特性博客。 这对于文档和博客审阅者来说,始终需要付出巨大的努力。

你是否有一些关于 SIG Docs 未来令人兴奋的举措想让社区知道?

SIG Docs 现在期望设计一个路线图,建立稳定的人员流转机制以期推动对文档的改进, 简化社区参与 Issue 评判和已提交 PR 的评审工作。 为了建立一个这样由贡献者和 Reviewer 组成的群体,我们正在设立一项辅导计划帮助当前的贡献者们成为 Reviewer。 这绝对是一项值得关注的举措!

结束语

SIG Docs 在 KubeCon + CloudNativeCon North America 2021 期间举办了一次深度访谈,涵盖了他们很棒的 SIG 主题。 他们非常欢迎想要为 Kubernetes 项目做贡献的新人,对这些新人而言 SIG Docs 已成为加入 Kubernetes 的起跳板。 欢迎加入 SIG 会议, 了解最新的研究成果、来年的计划以及如何作为贡献者参与上游 Docs 团队!

Kubernetes Gateway API 进入 Beta 阶段

作者: Shane Utt (Kong)、Rob Scott (Google)、Nick Young (VMware)、Jeff Apple (HashiCorp)

我们很高兴地宣布 Gateway API 的 v0.5.0 版本发布。 我们最重要的几个 Gateway API 资源首次进入 Beta 阶段。 此外,我们正在启动一项新的倡议,探索如何将 Gateway API 用于网格,还引入了 URL 重写等新的实验性概念。 下文涵盖了这部分内容和更多说明。

什么是 Gateway API?

Gateway API 是以 Gateway 资源(代表底层网络网关/代理服务器)为中心的资源集合, Kubernetes 服务网络的健壮性得益于众多供应商实现、得到广泛行业支持且极具表达力、可扩展和面向角色的各个接口。

Gateway API 最初被认为是知名 Ingress API 的继任者, Gateway API 的好处包括(但不限于)对许多常用网络协议的显式支持 (例如 HTTPTLSTCP UDP) 以及对传输层安全 (TLS) 的紧密集成支持。 特别是 Gateway 资源能够实现作为 Kubernetes API 来管理网络网关的生命周期。

如果你是对 Gateway API 的某些优势感兴趣的终端用户,我们邀请你加入并找到适合你的实现方式。 值此版本发布之时,对于流行的 API 网关和服务网格有十多种实现,还提供了操作指南便于快速开始探索。

入门

Gateway API 是一个类似 Ingress 的正式 Kubernetes API。Gateway API 代表了 Ingress 功能的一个父集,使得一些更高级的概念成为可能。 与 Ingress 类似,Kubernetes 中没有内置 Gateway API 的默认实现。 相反,有许多不同的实现可用,在提供一致且可移植体验的同时,还在底层技术方面提供了重要的选择。

查看 API 概念文档 并查阅一些指南以开始熟悉这些 API 及其工作方式。 当你准备好一个实用的应用程序时, 请打开实现页面并选择属于你可能已经熟悉的现有技术或集群提供商默认使用的技术(如果适用)的实现。 Gateway API 是一个基于 CRD 的 API,因此你将需要安装 CRD 到集群上才能使用该 API。

如果你对 Gateway API 做贡献特别有兴趣,我们非常欢迎你的加入! 你可以随时在仓库上提一个新的 issue,或加入讨论。 另请查阅社区页面以了解 Slack 频道和社区会议的链接。

发布亮点

进入 Beta 阶段

v0.5.0 版本特别具有历史意义,因为它标志着一些关键 API 成长至 Beta API 版本(v1beta1):

这一成就的标志是达到了以下几个进入标准:

  • API 已广泛实现
  • 合规性测试基本覆盖了所有资源且可以让多种实现通过测试。
  • 大多数 API 接口正被积极地使用。
  • Kubernetes SIG Network API 评审团队已批准其进入 Beta 阶段。

有关 Gateway API 版本控制的更多信息,请参阅官方文档。 要查看未来版本的计划,请查看下一步

发布渠道

此版本引入了 experimentalstandard 发布渠道, 这样能够更好地保持平衡,在确保稳定性的同时,还能支持实验和迭代开发。

standard 发布渠道包括:

  • 已进入 Beta 阶段的资源
  • 已进入 standard 的字段(不再被视为 experimental)

experimental 发布渠道包括 standard 发布渠道的所有内容,另外还有:

  • alpha API 资源
  • 视为 experimental 且还未进入 standard 渠道的字段

使用发布渠道能让内部实现快速流转的迭代开发,且能让外部实现者和最终用户标示功能稳定性。

本次发布新增了以下实验性的功能特性:

其他改进

有关 v0.5.0 版本中包括的完整变更清单,请参阅 v0.5.0 发布说明

适用于服务网格的 Gateway API:GAMMA 倡议

某些服务网格项目已实现对 Gateway API 的支持。 服务网格接口 (Service Mesh Interface,SMI) API 和 Gateway API 之间的显著重叠 已激发了 SMI 社区讨论可能的集成方式。

我们很高兴地宣布,来自 Cilium Service Mesh、Consul、Istio、Kuma、Linkerd、NGINX Service Mesh 和 Open Service Mesh 等服务网格社区的代表汇聚一堂组成 GAMMA 倡议小组, 这是 Gateway API 子项目内一个专门的工作流,专注于网格管理所用的 Gateway API。

这个小组将交付增强提案, 包括对网格和网格相关用例适用的 Gateway API 规约的资源、添加和修改。

这项工作已从 探索针对服务间流量使用 Gateway API 开始,并将继续增强身份验证和鉴权策略等领域。

下一步

随着我们不断完善用于生产用例的 API,以下是我们将为下一个 Gateway API 版本所做的一些重点工作:

如果你想参与此列表中的某些工作,或者你想倡导加入路线图的内容不在此列表中, 请通过 Kubernetes Slack 的 #sig-network-gateway-api 频道或我们每周的 社区电话会议加入我们。

2021 年度总结报告

作者: Paris Pittman(指导委员会)

去年,我们发布了第一期 2020 年度总结报告, 现在已经是时候发布第二期了!

2021 年度总结报告

这份总结反映了 2021 年已完成的工作以及 2022 下半年置于台面上的倡议。 请将这份总结转发给正参与上游活动、计划云原生战略和寻求帮助的那些组织和个人。 若要查阅特定社区小组的完整报告,请访问 kubernetes/community 仓库查找各小组的文件夹。例如: sig-api-machinery/annual-report-2021.md

你将看到这份总结报告本身涵盖的领域在增长。我们准备和制作这份报告大约用了 6 个月的时间。 作为一个随着长短期需求而快速发展的项目,这么长的制作周期对任何人来说可能帮助都不大, 报告的价值也有所缩水。我等苦思无良策,请诸君不吝赐教: https://github.com/kubernetes/steering/issues/242

参考: 年度报告文献

Kubernetes 1.24: StatefulSet 的最大不可用副本数

作者: Mayank Kumar (Salesforce)

Kubernetes StatefulSet, 自 1.5 版本中引入并在 1.9 版本中变得稳定以来,已被广泛用于运行有状态应用。它提供固定的 Pod 身份标识、 每个 Pod 的持久存储以及 Pod 的有序部署、扩缩容和滚动更新功能。你可以将 StatefulSet 视为运行复杂有状态应用程序的原子构建块。随着 Kubernetes 的使用增多,需要 StatefulSet 的场景也越来越多。 当 StatefulSet 的 Pod 管理策略为 OrderedReady 时,其中许多场景需要比当前所支持的一次一个 Pod 的更新更快的滚动更新。

这里有些例子:

  • 我使用 StatefulSet 来编排一个基于缓存的多实例应用程序,其中缓存的规格很大。 缓存冷启动,需要相当长的时间才能启动容器。所需要的初始启动任务有很多。在应用程序完全更新之前, 此 StatefulSet 上的 RollingUpdate 将花费大量时间。如果 StatefulSet 支持一次更新多个 Pod, 那么更新速度会快得多。
  • 我的有状态应用程序由 leader 和 follower 或者一个 writer 和多个 reader 组成。 我有多个 reader 或 follower,并且我的应用程序可以容忍多个 Pod 同时出现故障。 我想一次更新这个应用程序的多个 Pod,特别是当我的应用程序实例数量很多时,这样我就能快速推出新的更新。 注意,我的应用程序仍然需要每个 Pod 具有唯一标识。

为了支持这样的场景,Kubernetes 1.24 提供了一个新的 alpha 特性。在使用新特性之前,必须启用 MaxUnavailableStatefulSet 特性标志。一旦启用,就可以指定一个名为 maxUnavailable 的新字段, 这是 StatefulSet spec 的一部分。例如:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
  namespace: default
spec:
  podManagementPolicy: OrderedReady  # 你必须设为 OrderedReady
  replicas: 5
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: k8s.gcr.io/nginx-slim:0.8
        imagePullPolicy: IfNotPresent
        name: nginx
  updateStrategy:
    rollingUpdate:
      maxUnavailable: 2 # 这是 alpha 特性的字段,默认值是 1
      partition: 0
    type: RollingUpdate

如果你启用了新特性,但没有在 StatefulSet 中指定 maxUnavailable 的值,Kubernetes 会默认设置 maxUnavailable: 1。这与你不启用新特性时看到的行为是一致的。

我将基于该示例清单做场景演练,以演示此特性是如何工作的。我将部署一个有 5 个副本的 StatefulSet, maxUnavailable 设置为 2 并将 partition 设置为 0。

我可以通过将镜像更改为 k8s.gcr.io/nginx-slim:0.9 来触发滚动更新。一旦开始滚动更新, 就可以看到一次更新 2 个 Pod,因为 maxUnavailable 的当前值是 2。 下面的输出显示了一个时间段内的结果,但并不是完整过程。maxUnavailable 可以是绝对数值(例如 2)或所需 Pod 的百分比(例如 10%),绝对数是通过百分比计算结果进行四舍五入得出的。

kubectl get pods --watch 
NAME    READY   STATUS    RESTARTS   AGE
web-0   1/1     Running   0          85s
web-1   1/1     Running   0          2m6s
web-2   1/1     Running   0          106s
web-3   1/1     Running   0          2m47s
web-4   1/1     Running   0          2m27s
web-4   1/1     Terminating   0          5m43s ----> start terminating 4
web-3   1/1     Terminating   0          6m3s  ----> start terminating 3
web-3   0/1     Terminating   0          6m7s
web-3   0/1     Pending       0          0s
web-3   0/1     Pending       0          0s
web-4   0/1     Terminating   0          5m48s
web-4   0/1     Terminating   0          5m48s
web-3   0/1     ContainerCreating   0          2s
web-3   1/1     Running             0          2s
web-4   0/1     Pending             0          0s
web-4   0/1     Pending             0          0s
web-4   0/1     ContainerCreating   0          0s
web-4   1/1     Running             0          1s
web-2   1/1     Terminating         0          5m46s ----> start terminating 2 (only after both 4 and 3 are running)
web-1   1/1     Terminating         0          6m6s  ----> start terminating 1
web-2   0/1     Terminating         0          5m47s
web-1   0/1     Terminating         0          6m7s
web-1   0/1     Pending             0          0s
web-1   0/1     Pending             0          0s
web-1   0/1     ContainerCreating   0          1s
web-1   1/1     Running             0          2s
web-2   0/1     Pending             0          0s
web-2   0/1     Pending             0          0s
web-2   0/1     ContainerCreating   0          0s
web-2   1/1     Running             0          1s
web-0   1/1     Terminating         0          6m6s ----> start terminating 0 (only after 2 and 1 are running)
web-0   0/1     Terminating         0          6m7s
web-0   0/1     Pending             0          0s
web-0   0/1     Pending             0          0s
web-0   0/1     ContainerCreating   0          0s
web-0   1/1     Running             0          1s

注意,滚动更新一开始,4 和 3(两个最高序号的 Pod)同时开始进入 Terminating 状态。 Pod 4 和 3 会按照自身节奏进行更新。一旦 Pod 4 和 3 更新完毕后,Pod 2 和 1 会同时进入 Terminating 状态。当 Pod 2 和 1 都准备完毕处于 Running 状态时,Pod 0 开始进入 Terminating 状态

在 Kubernetes 中,StatefulSet 更新 Pod 时遵循严格的顺序。在此示例中,更新从副本 4 开始, 然后是副本 3,然后是副本 2,以此类推,一次更新一个 Pod。当一次只更新一个 Pod 时, 副本 3 不可能在副本 4 之前准备好进入 Running 状态。当 maxUnavailable 值 大于 1 时(在示例场景中我设置 maxUnavailable 值为 2),副本 3 可能在副本 4 之前准备好并运行, 这是没问题的。如果你是开发人员并且设置 maxUnavailable 值大于 1,你应该知道可能出现这种情况, 并且如果有这种情况的话,你必须确保你的应用程序能够处理发生的此类顺序问题。当你设置 maxUnavailable 值大于 1 时,更新 Pod 的批次之间会保证顺序。该保证意味着在批次 0(副本 4 和 3)中的 Pod 准备好之前,更新批次 2(副本 2 和 1)中的 Pod 无法开始更新。

尽管 Kubernetes 将这些称为副本,但你的有状态应用程序可能不这样理解,StatefulSet 的每个 Pod 可能持有与其他 Pod 完全不同的数据。重要的是,StatefulSet 的更新是分批进行的, 你现在让批次大小大于 1(作为 alpha 特性)。

还要注意,上面的行为采用的 Pod 管理策略是 podManagementPolicy: OrderedReady。 如果你的 StatefulSet 的 Pod 管理策略是 podManagementPolicy: Parallel, 那么不仅是 maxUnavailable 数量的副本同时被终止,还会导致 maxUnavailable 数量的副本同时在 ContainerCreating 阶段。这就是所谓的突发(Bursting)。

因此,现在你可能有很多关于以下方面的问题:

  • 当设置 podManagementPolicy:Parallel 时,会产生什么行为?
  • partition 设置为非 0 值时会发生什么?

自己试试看可能会更好。这是一个 alpha 特性,Kubernetes 贡献者正在寻找有关此特性的反馈。 这是否有助于你实现有状态的场景?你是否发现了一个 bug,或者你认为实现的行为不直观易懂, 或者它可能会破坏应用程序或让他们感到吃惊?请登记一个 issue 告知我们。

进一步阅读和后续步骤

Kubernetes 1.24 中的上下文日志记录

作者: Patrick Ohly (Intel)

结构化日志工作组 在 Kubernetes 1.24 中为日志基础设施添加了新功能。这篇博文解释了开发者如何利用这些功能使日志输出更有用, 以及他们如何参与改进 Kubernetes。

结构化日志记录

结构化日志 记录的目标是用具有明确定义的语法的日志条目来取代 C 风格的格式化和由此产生的不透明的日志字符串,用于分别存储消息和参数,例如,作为一个 JSON 结构。

当使用传统的 klog 文本输出格式进行结构化日志调用时,字符串最初使用 \n 转义序列打印,除非嵌入到结构中。 对于结构体,日志条目仍然可以跨越多行,没有干净的方法将日志流拆分为单独的条目:

I1112 14:06:35.783529  328441 structured_logging.go:51] "using InfoS" longData={Name:long Data:Multiple
lines
with quite a bit
of text. internal:0}
I1112 14:06:35.783549  328441 structured_logging.go:52] "using InfoS with\nthe message across multiple lines" int=1 stringData="long: Multiple\nlines\nwith quite a bit\nof text." str="another value"

现在,<> 标记以及缩进用于确保在行首的 klog 标头处拆分是可靠的,并且生成的输出是人类可读的:

I1126 10:31:50.378204  121736 structured_logging.go:59] "using InfoS" longData=<
	{Name:long Data:Multiple
	lines
	with quite a bit
	of text. internal:0}
 >
I1126 10:31:50.378228  121736 structured_logging.go:60] "using InfoS with\nthe message across multiple lines" int=1 stringData=<
	long: Multiple
	lines
	with quite a bit
	of text.
 > str="another value"

请注意,日志消息本身带有引号。它是一个用于标识日志条目的固定字符串,因此应避免使用换行符。

在 Kubernetes 1.24 之前,kube-scheduler 中的一些日志调用仍然使用 klog.Info 处理多行字符串, 以避免不可读的输出。现在所有日志调用都已更新以支持结构化日志记录。

上下文日志记录

上下文日志 基于 go-logr API。 关键的想法是,库被其调用者传递给一个记录器实例,并使用它来记录,而不是访问一个全局记录器。 二进制文件决定了日志的实现,而不是库。go-logr API 是围绕着结构化的日志记录而设计的,并支持将额外的信息附加到一个记录器上。

这使得以下用例成为可能:

  • 调用者可以将附加信息附加到记录器:

    当将此扩展记录器传递给函数并且函数使用它而不是全局记录器时,附加信息随后将包含在所有日志条目中,而无需修改生成日志条目的代码。 这在高度并行的应用程序中很有用,在这些应用程序中,由于不同操作的输出会交错,因此很难识别某个操作的所有日志条目。

  • 运行单元测试时,可以将日志输出与当前测试关联起来。当测试失败时,go test 只显示失败测试的日志输出。 默认情况下,该输出也可以更详细,因为它不会显示成功的测试。这些测试可以在不交错输出的情况下并行运行。

上下文日志记录的设计决策之一是允许将记录器作为值附加到 context.Context。 由于记录器封装了调用的预期记录的所有方面,它是上下文的部分,而不仅仅是使用它。 一个实际的优势是许多 API 已经有一个 ctx 参数,或者添加一个具有其他优势,例如能够摆脱函数内部的 context.TODO() 调用。

另一个决定是不破坏与 klog v2 的兼容性:

  • 在已设置上下文日志记录的二进制文件中使用传统 klog 日志记录调用的库将通过二进制文件选择的日志记录后端工作和记录。 但是,这样的日志输出不会包含额外的信息,并且在单元测试中不能很好地工作,因此应该修改库以支持上下文日志记录。 结构化日志记录的迁移指南 已扩展为也涵盖上下文日志记录。
  • 当一个库支持上下文日志并从其上下文中检索一个记录器时,它仍将在不初始化上下文日志的二进制文件中工作, 因为它将获得一个通过 klog 记录的记录器。

在 Kubernetes 1.24 中,上下文日志是一个新的 Alpha 特性,以 ContextualLogging 作为特性门控。 禁用时(默认),用于上下文日志记录的新 klog API 调用(见下文)变为无操作,以避免性能或功能回归。

尚未转换任何 Kubernetes 组件。 Kubernetes 存储库中的示例程序 演示了如何在一个二进制文件中启用上下文日志记录,以及输出如何取决于该二进制文件的参数:

$ cd $GOPATH/src/k8s.io/kubernetes/staging/src/k8s.io/component-base/logs/example/cmd/
$ go run . --help
...
      --feature-gates mapStringBool  A set of key=value pairs that describe feature gates for alpha/experimental features. Options are:
                                     AllAlpha=true|false (ALPHA - default=false)
                                     AllBeta=true|false (BETA - default=false)
                                     ContextualLogging=true|false (ALPHA - default=false)
$ go run . --feature-gates ContextualLogging=true
...
I0404 18:00:02.916429  451895 logger.go:94] "example/myname: runtime" foo="bar" duration="1m0s"
I0404 18:00:02.916447  451895 logger.go:95] "example: another runtime" foo="bar" duration="1m0s"

example 前缀和 foo="bar" 是由记录 runtime 消息和 duration="1m0s" 值的函数的调用者添加的。

针对 klog 的示例代码包括一个单元测试示例 以及每个测试的输出。

klog 增强功能

上下文日志 API

以下调用管理记录器的查找:

FromContext :来自 context 参数,回退到全局记录器

Background :全局后备,无意支持上下文日志记录

TODO :全局回退,但仅作为一个临时解决方案,直到该函数得到扩展能够通过其参数接受一个记录器

SetLoggerWithOptions :更改后备记录器;当使用ContextualLogger(true) 调用时, 记录器已准备好被直接调用,在这种情况下,记录将无需执行通过 klog

为了支持 Kubernetes 中的特性门控机制,klog 对相应的 go-logr 调用进行了包装调用,并使用了一个全局布尔值来控制它们的行为:

在 Kubernetes 代码中使用这些函数是通过 linter 检查强制执行的。 上下文日志的 klog 默认是启用该功能,因为它在 klog 中被认为是稳定的。 只有在 Kubernetes 二进制文件中,该默认值才会被覆盖,并且(在某些二进制文件中)通过 --feature-gate 参数进行控制。

ktesting 记录器

新的 ktesting 包使用 klog 的文本输出格式通过 testing.T 实现日志记录。它有一个 single API call 用于检测测试用例和支持命令行标志

klogr

klog/klogr 继续受支持,默认行为不变: 它使用其格式化结构化日志条目拥有自己的自定义格式并通过 klog 打印结果。

但是,不鼓励这种用法,因为这种格式既不是机器可读的(与 zapr 生成的真实 JSON 输出相比,Kubernetes 使用的 go-logr 实现)也不是人类友好的(与 klog 文本格式相比)。

相反,应该使用选择 klog 文本格式的 WithFormat(FormatKlog) 创建一个 klogr 实例。 一个更简单但结果相同的构造方法是新的 klog.NewKlogr。 这是 klog 在未配置任何其他内容时作为后备返回的记录器。

可重用输出测试

许多 go-logr 实现都有非常相似的单元测试,它们检查某些日志调用的结果。 如果开发人员不知道某些警告,例如调用时会出现恐慌的 String 函数,那么很可能缺少对此类警告的处理和单元测试。

klog.test 是一组可重用的测试用例,可应用于 go-logr 实现。

输出刷新

klog 用于在 init 期间无条件地启动一个 goroutine,它以硬编码的时间间隔刷新缓冲数据。 现在 goroutine 仅按需启动(即当写入具有缓冲的文件时)并且可以使用 StopFlushDaemonStartFlushDaemon

当 go-logr 实现缓冲数据时,可以通过使用 FlushLogger 选项注册记录器来将刷新该数据集成到 klog.Flush 中。

其他各种变化

有关所有其他增强功能的描述,请参见 发行说明

日志检查

最初设计为结构化日志调用的 linter,[logcheck] 工具已得到增强,还支持上下文日志记录和传统的 klog 日志调用。 这些增强检查已经在 Kubernetes 中发现了错误,例如使用格式字符串和参数调用 klog.Info 而不是 klog.Infof

它可以作为插件包含在 golangci-lint 调用中,这就是 Kubernetes 现在使用它的方式,或者单独调用。

我们正在 移动工具 到一个新的存储库中,因为它与 klog 没有真正的关系,并且应该正确跟踪和标记它的发布。

下一步

Structured Logging WG 一直在寻找新的贡献者。 从 C 风格的日志记录迁移现在将一步一步地针对结构化的上下文日志记录, 以减少整体代码流失和 PR 数量。 更改日志调用是对 Kubernetes 的良好贡献,也是了解各个不同领域代码的机会。

Kubernetes 1.24: 避免为 Services 分配 IP 地址时发生冲突

作者: Antonio Ojea (Red Hat)

在 Kubernetes 中,Services 是一种抽象,用来暴露运行在一组 Pod 上的应用。 Service 可以有一个集群范围的虚拟 IP 地址(使用 type: ClusterIP 的 Service)。 客户端可以使用该虚拟 IP 地址进行连接, Kubernetes 为对该 Service 的访问流量提供负载均衡,以访问不同的后端 Pod。

Service ClusterIP 是如何分配的?

Service ClusterIP 有如下分配方式:

动态 :群集的控制平面会自动从配置的 IP 范围内为 type:ClusterIP 的 Service 选择一个空闲 IP 地址。

静态 :你可以指定一个来自 Service 配置的 IP 范围内的 IP 地址。

在整个集群中,每个 Service 的 ClusterIP 必须是唯一的。 尝试创建一个已经被分配了的 ClusterIP 的 Service 将会返回错误。

为什么需要预留 Service Cluster IP?

有时,你可能希望让 Service 运行在众所周知的 IP 地址上,以便集群中的其他组件和用户可以使用它们。

最好的例子是集群的 DNS Service。一些 Kubernetes 安装程序将 Service IP 范围中的第 10 个地址分配给 DNS Service。 假设你配置集群 Service IP 范围是 10.96.0.0/16,并且希望 DNS Service IP 为 10.96.0.10, 那么你必须创建一个如下所示的 Service:

apiVersion: v1
kind: Service
metadata:
  labels:
    k8s-app: kube-dns
    kubernetes.io/cluster-service: "true"
    kubernetes.io/name: CoreDNS
  name: kube-dns
  namespace: kube-system
spec:
  clusterIP: 10.96.0.10
  ports:
  - name: dns
    port: 53
    protocol: UDP
    targetPort: 53
  - name: dns-tcp
    port: 53
    protocol: TCP
    targetPort: 53
  selector:
    k8s-app: kube-dns
  type: ClusterIP

但正如我之前解释的,IP 地址 10.96.0.10 没有被保留; 如果其他 Service 在动态分配之前创建或与动态分配并行创建,则它们有可能分配此 IP 地址, 因此,你将无法创建 DNS Service,因为它将因冲突错误而失败。

如何避免 Service ClusterIP 冲突?

在 Kubernetes 1.24 中,你可以启用一个新的特性门控 ServiceIPStaticSubrange。 启用此特性允许你为 Service 使用不同的 IP 分配策略,减少冲突的风险。

ClusterIP 范围将根据公式 min(max(16, cidrSize / 16), 256) 进行划分, 该公式可描述为 “在不小于 16 且不大于 256 之间有一个步进量(Graduated Step)”。

分配默认使用上半段地址,当上半段地址耗尽后,将使用下半段地址范围。 这将允许用户使用下半段地址中静态分配的地址并且降低冲突的风险。

举例:

Service IP CIDR 地址段: 10.96.0.0/24

地址段大小:28 - 2 = 254
地址段偏移:min(max(16, 256/16), 256) = min(16, 256) = 16
静态地址段起点:10.96.0.1
静态地址段终点:10.96.0.16
地址范围终点:10.96.0.254

pie showData title 10.96.0.0/24 "静态" : 16 "动态" : 238

Service IP CIDR 地址段: 10.96.0.0/20

地址段大小:212 - 2 = 4094
地址段偏移:min(max(16, 4096/16), 256) = min(256, 256) = 256
静态地址段起点:10.96.0.1
静态地址段终点:10.96.1.0
地址范围终点:10.96.15.254

pie showData title 10.96.0.0/20 "静态" : 256 "动态" : 3838

Service IP CIDR 地址段: 10.96.0.0/16

地址段大小:216 - 2 = 65534
地址段偏移:min(max(16, 65536/16), 256) = min(4096, 256) = 256
静态地址段起点:10.96.0.1
静态地址段终点:10.96.1.0
地址范围终点:10.96.255.254

pie showData title 10.96.0.0/16 "静态" : 256 "动态" : 65278

加入 SIG Network

当前 SIG-Network 在 GitHub 上的 KEPsissues 表明了该 SIG 的重点领域。

SIG Network 会议是一个友好、热情的场所, 你可以与社区联系并分享你的想法。期待你的回音!

Kubernetes 1.24: 节点非体面关闭特性进入 Alpha 阶段

作者:Xing Yang 和 Yassine Tijani (VMware)

Kubernetes v1.24 引入了对节点非体面关闭 (Non-Graceful Node Shutdown)的 Alpha 支持。 此特性允许有状态工作负载在原节点关闭或处于不可恢复状态(如硬件故障或操作系统损坏)后,故障转移到不同的节点。

这与节点体面关闭有何不同

你可能听说过 Kubernetes 的节点体面关闭特性, 并且想知道节点非体面关闭特性与之有何不同。节点体面关闭允许 Kubernetes 检测节点何时完全关闭,并适当地处理这种情况。 只有当 kubelet 在实际关闭之前检测到节点关闭动作时,节点关闭才是“体面(graceful)”的。 但是,在某些情况下,kubelet 可能检测不到节点关闭操作。 这可能是因为 shutdown 命令没有触发 kubelet 所依赖的 systemd 抑制锁机制, 或者是因为配置错误(ShutdownGracePeriodShutdownGracePeriodCriticalPods 配置不正确)。

节点体面关闭依赖于特定 Linux 的支持。 kubelet 不监视 Windows 节点上即将关闭的情况(这可能在未来的 Kubernetes 版本中会有所改变)。

当一个节点被关闭但 kubelet 没有检测到时,该节点上的 Pod 也会非体面地关闭。 对于无状态应用程序,这通常不是问题(一旦集群检测到受影响的节点或 Pod 出现故障,ReplicaSet 就会添加一个新的 Pod)。 对于有状态的应用程序,情况要复杂得多。如果你使用一个 StatefulSet, 并且该 StatefulSet 中的一个 Pod 在某个节点上发生了不干净故障,则该受影响的 Pod 将被标记为终止(Terminating); StatefulSet 无法创建替换 Pod,因为该 Pod 仍存在于集群中。 因此,在 StatefulSet 上运行的应用程序可能会降级甚至离线。 如果已关闭的原节点再次出现,该节点上的 kubelet 会执行报到操作,删除现有的 Pod, 并且控制平面会在不同的运行节点上为该 StatefulSet 生成一个替换 Pod。 如果原节点出现故障并且没有恢复,这些有状态的 Pod 将处于终止状态且无限期地停留在该故障节点上。

$ kubectl get pod -o wide
NAME    READY   STATUS        RESTARTS   AGE   IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running       0          100m   10.244.2.4   k8s-node-876-1639279816   <none>           <none>
web-1   1/1     Terminating   0          100m   10.244.1.3   k8s-node-433-1639279804   <none>           <none>

尝试新的非体面关闭处理

要使用节点非体面关闭处理,你必须为 kube-controller-manager 组件启用 NodeOutOfServiceVolumeDetach 特性门控

在节点关闭的情况下,你可以手动为该节点标记污点,标示其已停止服务。 在添加污点之前,你应该确保节点确实关闭了(不是在重启过程中)。 你可以在发生了节点关闭事件,且该事件没有被 kubelet 提前检测和处理的情况下,在节点关闭之后添加污点; 你可以使用该污点的另一种情况是当节点由于硬件故障或操作系统损坏而处于不可恢复状态时。 你可以为该污点设置的值是 node.kubernetes.io/out-of-service=nodeshutdown: "NoExecute"node.kubernetes.io/out-of-service=nodeshutdown: "NoSchedule"。 如果你已经启用了前面提到的特性门控,在节点上设置 out-of-service 污点意味着节点上的 Pod 将被删除, 除非 Pod 上设置有与之匹配的容忍度。原来挂接到已关闭节点的持久卷(Persistent volume)将被解除挂接, 对于 StatefulSet,系统将在不同的运行节点上成功创建替换 Pod。

$ kubectl taint nodes <node-name> node.kubernetes.io/out-of-service=nodeshutdown:NoExecute

$ kubectl get pod -o wide
NAME    READY   STATUS    RESTARTS   AGE    IP           NODE                      NOMINATED NODE   READINESS GATES
web-0   1/1     Running   0          150m   10.244.2.4   k8s-node-876-1639279816   <none>           <none>
web-1   1/1     Running   0          10m    10.244.1.7   k8s-node-433-1639279804   <none>           <none>

注意:在应用 out-of-service 污点之前,你必须确认节点是否已经处于关闭或断电状态(不是在重新启动过程中), 节点关闭的原因可能是用户有意将其关闭,也可能是节点由于硬件故障、操作系统问题等而关闭。

一旦关联到无法提供服务的节点的所有工作负载 Pod 都被移动到新的运行中的节点,并且关闭了的节点也已恢复, 你应该在节点恢复后删除受影响节点上的污点。如果你知道该节点不会恢复服务,则可以改为从集群中删除该节点。

下一步是什么?

根据反馈和采用情况,Kubernetes 团队计划在 1.25 或 1.26 版本中将节点非体面关闭实现推送到 Beta 阶段。

此功能需要用户手动向节点添加污点以触发工作负载故障转移,并要求用户在节点恢复后移除污点。 未来,我们计划寻找方法来自动检测和隔离已关闭的或已失败的节点,并自动将工作负载故障转移到另一个节点。

怎样才能了解更多?

查看节点非体面关闭相关文档

如何参与?

此功能特性由来已久。Yassine Tijani(yastij)在两年多前启动了这个 KEP。 Xing Yang(xing-yang)继续推动这项工作。 SIG-Storage、SIG-Node 和 API 评审人员们进行了多次讨论,以确定设计细节。 Ashutosh Kumar(sonasingh46) 完成了大部分实现并在 Kubernetes 1.24 版本中将其引进到 Alpha 阶段。

我们要感谢以下人员的评审:Tim Hockin(thockin)对设计的指导; 来自 SIG-Storage 的 Jing Xu(jingxu97)、 Hemant Kumar(gnufied) 和 Michelle Au(msau42)的评论; 以及 Mrunal Patel(mrunalp)、 David Porter(bobbypage)、 Derek Carr(derekwaynecarr) 和 Danielle Endocrimes(endocrimes)来自 SIG-Node 方面的评论。

在此过程中,有很多人帮助审查了设计和实现。我们要感谢所有为此做出贡献的人, 包括在过去几年中审核 KEP 和实现的大约 30 人。

此特性是 SIG-Storage 和 SIG-Node 之间的协作。 对于那些有兴趣参与 Kubernetes Storage 系统任何部分的设计和开发的人, 请加入 Kubernetes 存储特别兴趣小组(SIG-Storage)。 对于那些有兴趣参与支持 Pod 和主机资源之间受控交互的组件的设计和开发的人, 请加入 Kubernetes Node SIG

Kubernetes 1.24: 防止未经授权的卷模式转换

作者: Raunak Pradip Shah (Mirantis)

Kubernetes v1.24 引入了一个新的 alpha 级特性,可以防止未经授权的用户修改基于 Kubernetes 集群中已有的 VolumeSnapshot 创建的 PersistentVolumeClaim 的卷模式。

问题

卷模式确定卷是格式化为文件系统还是显示为原始块设备。

用户可以使用自 Kubernetes v1.20 以来就稳定的 VolumeSnapshot 功能, 基于 Kubernetes 集群中的已有的 VolumeSnapshot 创建一个 PersistentVolumeClaim (简称 PVC )。 PVC 规约包括一个 dataSource 字段,它可以指向一个已有的 VolumeSnapshot 实例。 查阅基于卷快照创建 PVC 获取更多详细信息。

当使用上述功能时,没有逻辑来验证快照所在的原始卷的模式是否与新创建的卷的模式匹配。

这引起了一个安全漏洞,允许恶意用户潜在地利用主机操作系统中的未知漏洞。

为了提高效率,许多流行的存储备份供应商在备份操作过程中转换卷模式, 这使得 Kubernetes 无法完全阻止该操作,并在区分受信任用户和恶意用户方面带来挑战。

防止未经授权的用户转换卷模式

在这种情况下,授权用户是指有权对 VolumeSnapshotContents(集群级资源)执行 UpdatePatch 操作的用户。集群管理员只能向受信任的用户或应用程序(如备份供应商)提供这些权限。

如果在 snapshot-controllersnapshot-validation-webhookexternal-provisioner启用了这个 alpha 特性,则基于 VolumeSnapshot 创建 PVC 时,将不允许未经授权的用户修改其卷模式。

如要转换卷模式,授权用户必须执行以下操作:

  1. 确定要用作给定命名空间中新创建 PVC 的数据源的 VolumeSnapshot

  2. 确定绑定到上面 VolumeSnapshotVolumeSnapshotContent

       kubectl get volumesnapshot -n <namespace>
    
  1. VolumeSnapshotContent 添加 snapshot.storage.kubernetes.io/allowVolumeModeChange 注解。
  1. 此注解可通过软件添加或由授权用户手动添加。VolumeSnapshotContent 注解必须类似于以下清单片段:

       kind: VolumeSnapshotContent
       metadata:
         annotations:
           - snapshot.storage.kubernetes.io/allowVolumeModeChange: "true"
       ...
    

注意:对于预先制备的 VolumeSnapshotContents,你必须采取额外的步骤设置 spec.sourceVolumeMode 字段为 FilesystemBlock,这取决于快照所在卷的模式。

如下为一个示例:

   apiVersion: snapshot.storage.k8s.io/v1
   kind: VolumeSnapshotContent
   metadata:
     annotations:
     - snapshot.storage.kubernetes.io/allowVolumeModeChange: "true"
     name: new-snapshot-content-test
   spec:
     deletionPolicy: Delete
     driver: hostpath.csi.k8s.io
     source:
       snapshotHandle: 7bdd0de3-aaeb-11e8-9aae-0242ac110002
     sourceVolumeMode: Filesystem
     volumeSnapshotRef:
       name: new-snapshot-test
       namespace: default

对于在备份或恢复操作期间需要转换卷模式的所有 VolumeSnapshotContents,重复步骤 1 到 3。

如果 VolumeSnapshotContent 对象上存在上面步骤 4 中显示的注解,Kubernetes 将不会阻止转换卷模式。 用户在尝试将注解添加到任何 VolumeSnapshotContent 之前,应该记住这一点。

接下来

启用此特性并让我们知道你的想法!

我们希望此功能不会中断现有工作流程,同时防止恶意用户利用集群中的安全漏洞。

若有任何问题,请在 #sig-storage slack 频道中创建一个会话, 或在 CSI 外部快照存储仓库中报告一个 issue。

Kubernetes 1.24: 卷填充器功能进入 Beta 阶段

作者: Ben Swartzlander (NetApp)

卷填充器功能现在已经经历两个发行版本并进入 Beta 阶段! 在 Kubernetes v1.24 中 AnyVolumeDataSource 特性门控默认被启用。 这意味着用户可以指定任何自定义资源作为 PVC 的数据源。

之前的一篇博客详细介绍了卷填充器功能的工作原理。 简而言之,集群管理员可以在集群中安装 CRD 和相关的填充器控制器, 任何可以创建 CR 实例的用户都可以利用填充器创建预填充卷。

出于不同的目的,可以一起安装多个填充器。存储 SIG 社区已经有了一些公开的实现,更多原型应该很快就会出现。

强烈建议集群管理人员在安装任何填充器之前安装 volume-data-source-validator 控制器和相关的 VolumePopulator CRD,以便用户可以获得有关无效 PVC 数据源的反馈。

新功能

构建填充器的 lib-volume-populator 库现在包含可帮助操作员监控和检测问题的指标。这个库现在是 beta 阶段,最新版本是 v1.0.1。

卷数据源校验器控制器也添加了指标支持, 处于 beta 阶段。VolumePopulator CRD 是 beta 阶段,最新版本是 v1.0.1。

尝试一下

要查看它是如何工作的,你可以安装 “hello” 示例填充器并尝试一下。

首先安装 volume-data-source-validator 控制器。

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/v1.0.1/client/config/crd/populator.storage.k8s.io_volumepopulators.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/v1.0.1/deploy/kubernetes/rbac-data-source-validator.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/volume-data-source-validator/v1.0.1/deploy/kubernetes/setup-data-source-validator.yaml

接下来安装 hello 示例填充器。

kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/lib-volume-populator/v1.0.1/example/hello-populator/crd.yaml
kubectl apply -f https://raw.githubusercontent.com/kubernetes-csi/lib-volume-populator/87a47467b86052819e9ad13d15036d65b9a32fbb/example/hello-populator/deploy.yaml

你的集群现在有一个新的 CustomResourceDefinition,它提供了一个名为 Hello 的测试 API。 创建一个 Hello 自定义资源的实例,内容如下:

apiVersion: hello.example.com/v1alpha1
kind: Hello
metadata:
  name: example-hello
spec:
  fileName: example.txt
  fileContents: Hello, world!

创建一个将该 CR 引用为其数据源的 PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: example-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 10Mi
  dataSourceRef:
    apiGroup: hello.example.com
    kind: Hello
    name: example-hello
  volumeMode: Filesystem

接下来,运行一个读取 PVC 中文件的 Job。

apiVersion: batch/v1
kind: Job
metadata:
  name: example-job
spec:
  template:
    spec:
      containers:
        - name: example-container
          image: busybox:latest
          command:
            - cat
            - /mnt/example.txt
          volumeMounts:
            - name: vol
              mountPath: /mnt
      restartPolicy: Never
      volumes:
        - name: vol
          persistentVolumeClaim:
            claimName: example-pvc

等待 Job 完成(包括其所有依赖项)。

kubectl wait --for=condition=Complete job/example-job

最后检查 Job 中的日志。

kubectl logs job/example-job

输出应该是:

Hello, world!

请注意,该卷已包含一个文本文件,其中包含来自 CR 的字符串内容。这只是最简单的例子。 实际填充器可以将卷设置为包含任意内容。

如何编写自己的卷填充器

鼓励有兴趣编写新的填充器的开发人员使用 lib-volume-populator 库, 只提供一个小型控制器,以及一个能够连接到卷并向卷写入适当数据的 Pod 镜像。

单个填充器非常通用,它们可以与所有类型的 PVC 一起使用, 或者如果卷是来自同一供应商的特定 CSI 驱动程序供应的, 它们可以执行供应商特定的的操作以快速用数据填充卷,例如,通过通信直接使用该卷的存储。

我怎样才能了解更多?

增强提案, 卷填充器, 包含有关此功能的历史和技术实现的许多详细信息。

卷填充器与数据源, 在有关持久卷的文档主题中,解释了如何在集群中使用此功能。

请加入 Kubernetes 的存储 SIG,帮助我们增强这一功能。这里已经有很多好的主意了,我们很高兴能有更多!

Kubernetes 1.24:gRPC 容器探针功能进入 Beta 阶段

作者:Sergey Kanzhelev (Google)

在 Kubernetes 1.24 中,gRPC 探针(probe)功能进入了 beta 阶段,默认情况下可用。 现在,你可以为 gRPC 应用程序配置启动、活跃和就绪探测,而无需公开任何 HTTP 端点, 也不需要可执行文件。Kubernetes 可以通过 gRPC 直接连接到你的工作负载并查询其状态。

一些历史

让管理你的工作负载的系统检查应用程序是否健康、启动是否正常,以及应用程序是否认为自己可以接收流量,是很有用的。 在添加 gRPC 探针支持之前,Kubernetes 已经允许你通过从容器镜像内部运行可执行文件、发出 HTTP 请求或检查 TCP 连接是否成功来检查健康状况。

对于大多数应用程序来说,这些检查就足够了。如果你的应用程序提供了用于运行状况(或准备就绪)检查的 gRPC 端点,则很容易重新调整 exec 探针的用途,将其用于 gRPC 运行状况检查。 在博文在 Kubernetes 上对 gRPC 服务器进行健康检查中, Ahmet Alp Balkan 描述了如何做到这一点 —— 这种机制至今仍在工作。

2018 年 8 月 21 日所创建的一种常用工具可以启用此功能, 工具于 2018 年 9 月 19 日首次发布。

这种 gRPC 应用健康检查的方法非常受欢迎。使用 GitHub 上的基本搜索,发现了带有 grpc_health_probe3,626 个 Dockerfile 文件6,621 个 yaml 文件(在撰写本文时)。 这很好地表明了该工具的受欢迎程度,以及对其本地支持的需求。

Kubernetes v1.23 引入了一个 alpha 质量的实现,原生支持使用 gRPC 查询工作负载状态。 因为这是一个 alpha 特性,所以在 1.23 版中默认是禁用的。

使用该功能

我们用与其他探针类似的方式构建了 gRPC 健康检查,相信如果你熟悉 Kubernetes 中的其他探针类型, 它会很容易使用。 与涉及 grpc_health_probe 可执行文件的解决办法相比,原生支持的健康探针有许多好处。

有了原生 gRPC 支持,你不需要在镜像中下载和携带 10MB 的额外可执行文件。 Exec 探针通常比 gRPC 调用慢,因为它们需要实例化一个新进程来运行可执行文件。 当 Pod 在最大资源下运行并且在实例化新进程时遇到困难时,它还使得对边界情况的检查变得不那么智能。

不过有一些限制。由于为探针配置客户端证书很难,因此不支持依赖客户端身份验证的服务。 内置探针也不检查服务器证书,并忽略相关问题。

内置检查也不能配置为忽略某些类型的错误(grpc_health_probe 针对不同的错误返回不同的退出代码), 并且不能“串接”以在单个探测中对多个服务运行健康检查。

但是所有这些限制对于 gRPC 来说都是相当标准的,并且有简单的解决方法。

自己试试

集群级设置

你现在可以尝试这个功能。要尝试原生 gRPC 探针,你可以自己启动一个启用了 GRPCContainerProbe 特性门控的 Kubernetes 集群,可用的工具有很多。

由于特性门控 GRPCContainerProbe 在 1.24 版本中是默认启用的,因此许多供应商支持此功能开箱即用。 因此,你可以在自己选择的平台上创建 1.24 版本集群。一些供应商允许在 1.23 版本集群上启用 alpha 特性。

例如,在编写本文时,你可以在 GKE 上运行测试集群来进行快速测试。 其他供应商可能也有类似的功能,尤其是当你在 Kubernetes 1.24 版本发布很久后才阅读这篇博客时。

在 GKE 上使用以下命令(注意,版本是 1.23,并且指定了 enable-kubernetes-alpha)。

gcloud container clusters create test-grpc \
    --enable-kubernetes-alpha \
    --no-enable-autorepair \
    --no-enable-autoupgrade \
    --release-channel=rapid \
    --cluster-version=1.23

你还需要配置 kubectl 来访问集群:

gcloud container clusters get-credentials test-grpc

试用该功能

让我们创建 Pod 来测试 gRPC 探针是如何工作的。对于这个测试,我们将使用 agnhost 镜像。 这是一个 k8s 维护的镜像,可用于各种工作负载测试。例如,它有一个有用的 grpc-health-checking 模块,该模块暴露了两个端口:一个是提供健康检查服务的端口,另一个是对 make-servingmake-not-serving 命令做出反应的 http 端口。

下面是一个 Pod 定义示例。它启用 grpc-health-checking 模块,暴露 5000 和 8080 端口,并配置 gRPC 就绪探针:

---
apiVersion: v1
kind: Pod
metadata:
  name: test-grpc
spec:
  containers:
  - name: agnhost
    image: k8s.gcr.io/e2e-test-images/agnhost:2.35
    command: ["/agnhost", "grpc-health-checking"]
    ports:
    - containerPort: 5000
    - containerPort: 8080
    readinessProbe:
      grpc:
        port: 5000

如果文件名为 test.yaml,你可以用以下命令创建 Pod,并检查它的状态。如输出片段所示,Pod 将处于就绪状态。

kubectl apply -f test.yaml
kubectl describe test-grpc

输出将包含如下内容:

Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

现在让我们将健康检查端点状态更改为 NOT_SERVING。为了调用 Pod 的 http 端口,让我们创建一个端口转发:

kubectl port-forward test-grpc 8080:8080

你可以用 curl 来调用这个命令。

curl http://localhost:8080/make-not-serving

几秒钟后,端口状态将切换到未就绪。

kubectl describe pod test-grpc

现在的输出将显示:

Conditions:
  Type              Status
  Initialized       True
  Ready             False
  ContainersReady   False
  PodScheduled      True

...

  Warning  Unhealthy  2s (x6 over 42s)  kubelet            Readiness probe failed: service unhealthy (responded with "NOT_SERVING")

一旦切换回来,Pod 将在大约一秒钟后恢复到就绪状态:

curl http://localhost:8080/make-serving
kubectl describe test-grpc

输出表明 Pod 恢复为 Ready

Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True

Kubernetes 上这种新的内置 gRPC 健康探测,使得通过 gRPC 实现健康检查比依赖使用额外的 exec 探测的旧方法更容易。请阅读官方 文档 了解更多信息并在该功能正式发布(GA)之前提供反馈。

总结

Kubernetes 是一个流行的工作负载编排平台,我们根据反馈和需求添加功能。 像 gRPC 探针支持这样的特性是一个小的改进,它将使许多应用程序开发人员的生活更容易,应用程序更有弹性。 在该功能 GA(正式发布)之前,现在就试试,并给出反馈。

Kubernetes 1.24 版本中存储容量跟踪特性进入 GA 阶段

作者: Patrick Ohly(Intel)

在 Kubernetes v1.24 版本中,存储容量跟踪已经成为一项正式发布的功能。

已经解决的问题

上一篇关于此功能的博文中所详细介绍的, 存储容量跟踪允许 CSI 驱动程序发布有关剩余容量的信息。当 Pod 仍然有需要配置的卷时, kube-scheduler 使用该信息为 Pod 选择合适的节点。

如果没有这些信息,Pod 可能会被卡住,而不会被调度到合适节点,这是因为 kube-scheduler 只能盲目地选择节点。由于 CSI 驱动程序管理的下层存储系统没有足够的容量, kube-scheduler 常常会选择一个无法为其配置卷的节点。

因为 CSI 驱动程序发布的这些存储容量信息在被使用的时候可能已经不是最新的信息了, 所以最终选择的节点无法正常工作的情况仍然可能会发生。 卷配置通过通知调度程序需要在其他节点上重试来恢复。

升级到 GA 版本后重新进行的负载测试证实, 集群中部署了存储容量跟踪功能的 Pod 可以使用所有的存储,而没有部署此功能的 Pod 就会被卡住。

尚未解决的问题

如果尝试恢复一个制备失败的卷,存在一个已知的限制: 如果 Pod 使用两个卷并且只能制备其中一个,那么所有将来的调度决策都受到已经制备的卷的限制。 如果该卷是节点的本地卷,并且另一个卷无法被制备,则 Pod 会卡住。 此问题早在存储容量跟踪功能之前就存在,虽然苛刻的附加条件使这种情况不太可能发生, 但是无法完全避免,当然每个 Pod 仅使用一个卷的情况除外。

KEP 草案中提出了一个解决此问题的想法: 已制备但尚未被使用的卷不能包含任何有价值的数据,因此可以在其他地方释放并且再次被制备。 SIG Storage 正在寻找对此感兴趣并且愿意继续从事此工作的开发人员。

另一个没有解决的问题是 Cluster Autoscaler 对包含卷的 Pod 的支持。 对于具有存储容量跟踪功能的 CSI 驱动程序,我们开发了一个原型并在此 PR 中进行了讨论。 此原型旨在与任意 CSI 驱动程序协同工作,但这种灵活性使其难以配置并减慢了扩展操作: 因为自动扩展程序无法模拟卷制备操作,它一次只能将集群扩展一个节点,这是此方案的不足之处。

因此,这个 PR 没有被合入,需要另一种不同的方法,在自动缩放器和 CSI 驱动程序之间实现更紧密的耦合。 为此,需要更好地了解哪些本地存储 CSI 驱动程序与集群自动缩放结合使用。如果这会引出新的 KEP, 那么用户将不得不在实践中尝试实现,然后才能迁移到 beta 版本或 GA 版本中。 如果你对此主题感兴趣,请联系 SIG Storage。

致谢

非常感谢为此功能做出贡献或提供反馈的 SIG SchedulingSIG AutoscalingSIG Storage 成员!

Kubernetes 1.24:卷扩充现在成为稳定功能

作者: Hemant Kumar (Red Hat)

卷扩充在 Kubernetes 1.8 作为 Alpha 功能引入, 在 Kubernetes 1.11 进入了 Beta 阶段。 在 Kubernetes 1.24 中,我们很高兴地宣布卷扩充正式发布(GA)。

此功能允许 Kubernetes 用户简单地编辑其 PersistentVolumeClaim 对象, 并在 PVC Spec 中指定新的大小,Kubernetes 将使用存储后端自动扩充卷, 同时也会扩充 Pod 使用的底层文件系统,使得无需任何停机时间成为可能。

如何使用卷扩充

通过编辑 PVC 的 spec 字段,指定不同的(和更大的)存储请求, 可以触发 PersistentVolume 的扩充。 例如,给定以下 PVC:

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: myclaim
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi # 在此处指定新的大小

你可以指定新的值来替代旧的 1Gi 大小来请求扩充下层 PersistentVolume。 一旦你更改了请求的大小,可以查看 PVC 的 status.conditions 字段, 确认卷大小的调整是否已完成。

当 Kubernetes 开始扩充卷时,它会给 PVC 添加 Resizing 状况。 一旦扩充结束,这个状况会被移除。通过监控与 PVC 关联的事件, 还可以获得更多关于扩充操作进度的信息:

kubectl describe pvc <pvc>

存储驱动支持

然而,并不是每种卷类型都默认支持扩充。 某些卷类型(如树内 hostpath 卷)不支持扩充。 对于 CSI 卷, CSI 驱动必须在控制器或节点服务(如果合适,二者兼备) 中具有 EXPAND_VOLUME 能力。 请参阅 CSI 驱动的文档,了解其是否支持卷扩充。

有关支持卷扩充的树内(intree)卷类型, 请参阅卷扩充文档:扩充 PVC 申领

通常,为了对可扩充的卷提供某种程度的控制, 只有在存储类将 allowVolumeExpansion 参数设置为 true 时, 动态供应的 PVC 才是可扩充的。

Kubernetes 集群管理员必须编辑相应的 StorageClass 对象, 并将 allowVolumeExpansion 字段设置为 true。例如:

apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: gp2-default
provisioner: kubernetes.io/aws-ebs
parameters:
  secretNamespace: ""
  secretName: ""
allowVolumeExpansion: true

在线扩充与离线扩充比较

默认情况下,Kubernetes 会在用户请求调整大小后立即尝试扩充卷。 如果一个或多个 Pod 正在使用该卷, Kubernetes 会尝试通过在线调整大小来扩充该卷; 因此,卷扩充通常不需要应用停机。 节点上的文件系统也可以在线扩充,因此不需要关闭任何正在使用 PVC 的 Pod。

如果要扩充的 PersistentVolume 未被使用,Kubernetes 会用离线方式调整卷大小 (而且,由于该卷未使用,所以也不会造成工作负载中断)。

但在某些情况下,如果底层存储驱动只能支持离线扩充, 则 PVC 用户必须先停止 Pod,才能让扩充成功。 请参阅存储提供商的文档,了解其支持哪种模式的卷扩充。

当卷扩充作为 Alpha 功能引入时, Kubernetes 仅支持在节点上进行离线的文件系统扩充, 因此需要用户重新启动 Pod,才能完成文件系统的大小调整。 今天,用户的行为已经被改变,无论底层 PersistentVolume 是在线还是离线, Kubernetes 都会尽最大努力满足任何调整大小的请求。 如果你的存储提供商支持在线扩充,则无需重启 Pod 即可完成卷扩充。

下一步

尽管卷扩充在最近的 v1.24 发行版中成为了稳定版本, 但 SIG Storage 团队仍然在努力让 Kubernetes 用户扩充其持久性存储变得更简单。 Kubernetes 1.23 引入了卷扩充失败后触发恢复机制的功能特性, 允许用户在大小调整失败后尝试自助修复。 更多详细信息,请参阅处理扩充卷过程中的失败

Kubernetes 贡献者社区也在讨论有状态(StatefulSet)驱动的存储扩充的潜力。 这个提议的功能特性将允许用户通过直接编辑 StatefulSet 对象, 触发为 StatefulSet 提供存储的所有底层 PV 的扩充。 更多详细信息,请参阅通过 StatefulSet 支持卷扩充的改善提议。

Dockershim:历史背景

作者: Kat Cosgrove

自 Kubernetes v1.24 起,Dockershim 已被删除,这对项目来说是一个积极的举措。 然而,背景对于充分理解某事很重要,无论是社交还是软件开发,这值得更深入的审查。 除了 Kubernetes v1.24 中的 dockershim 移除之外, 我们在社区中看到了一些混乱(有时处于恐慌级别)和对这一决定的不满, 主要是由于缺乏有关此删除背景的了解。弃用并最终从 Kubernetes 中删除 dockershim 的决定并不是迅速或轻率地做出的。 尽管如此,它已经工作了很长时间,以至于今天的许多用户都比这个决定更新, 更不用提当初为何引入 dockershim 了。

那么 dockershim 是什么,为什么它会消失呢?

在 Kubernetes 的早期,我们只支持一个容器运行时,那个运行时就是 Docker Engine。 那时,并没有太多其他选择,而 Docker 是使用容器的主要工具,所以这不是一个有争议的选择。 最终,我们开始添加更多的容器运行时,比如 rkt 和 hypernetes,很明显 Kubernetes 用户希望选择最适合他们的运行时。因此,Kubernetes 需要一种方法来允许集群操作员灵活地使用他们选择的任何运行时。

容器运行时接口 (CRI) 已发布以支持这种灵活性。 CRI 的引入对项目和用户来说都很棒,但它确实引入了一个问题:Docker Engine 作为容器运行时的使用早于 CRI,并且 Docker Engine 不兼容 CRI。 为了解决这个问题,在 kubelet 组件中引入了一个小型软件 shim (dockershim),专门用于填补 Docker Engine 和 CRI 之间的空白, 允许集群操作员继续使用 Docker Engine 作为他们的容器运行时基本上不间断。

然而,这个小软件 shim 从来没有打算成为一个永久的解决方案。 多年来,它的存在给 kubelet 本身带来了许多不必要的复杂性。由于这个 shim,Docker 的一些集成实现不一致,导致维护人员的负担增加,并且维护特定于供应商的代码不符合我们的开源理念。 为了减少这种维护负担并朝着支持开放标准的更具协作性的社区迈进, 引入了 KEP-2221, 建议移除 dockershim。随着 Kubernetes v1.20 的发布,正式弃用。

我们没有很好地传达这一点,不幸的是,弃用公告在社区内引起了一些恐慌。关于这对 Docker作为一家公司意味着什么,Docker 构建的容器镜像是否仍然可以运行,以及 Docker Engine 究竟是什么导致了社交媒体上的一场大火,人们感到困惑。 这是我们的错;我们应该更清楚地传达当时发生的事情和原因。为了解决这个问题, 我们发布了一篇博客相应的 FAQ 以减轻社区的恐惧并纠正对 Docker 是什么以及容器如何在 Kubernetes 中工作的一些误解。 由于社区的关注,Docker 和 Mirantis 共同决定继续以 cri-dockerd 的形式支持 dockershim 代码,允许你在需要时继续使用 Docker Engine 作为容器运行时。 对于想要尝试其他运行时(如 containerd 或 cri-o)的用户, 已编写迁移文档

我们后来调查了社区发现还有很多用户有疑问和顾虑。 作为回应,Kubernetes 维护人员和 CNCF 承诺通过扩展文档和其他程序来解决这些问题。 事实上,这篇博文是这个计划的一部分。随着如此多的最终用户成功迁移到其他运行时,以及改进的文档, 我们相信每个人现在都为迁移铺平了道路。

Docker 不会消失,无论是作为一种工具还是作为一家公司。它是云原生社区的重要组成部分, 也是 Kubernetes 项目的历史。没有他们,我们就不会是现在的样子。也就是说,从 kubelet 中删除 dockershim 最终对社区、生态系统、项目和整个开源都有好处。 这是我们所有人齐心协力支持开放标准的机会,我们很高兴在 Docker 和社区的帮助下这样做。

Kubernetes 1.24: 观星者

作者: Kubernetes 1.24 发布团队

我们很高兴地宣布 Kubernetes 1.24 的发布,这是 2022 年的第一个版本!

这个版本包括 46 个增强功能:14 个增强功能已经升级到稳定版,15 个增强功能正在进入 Beta 版, 13 个增强功能正在进入 Alpha 阶段。另外,有两个功能被废弃了,还有两个功能被删除了。

主要议题

从 kubelet 中删除 Dockershim

在 v1.20 版本中被废弃后,dockershim 组件已被从 Kubernetes v1.24 版本的 kubelet 中移除。 从 v1.24 开始,如果你依赖 Docker Engine 作为容器运行时, 则需要使用其他受支持的运行时之一 (如 containerd 或 CRI-O)或使用 CRI dockerd。 有关确保集群已准备好进行此删除的更多信息,请参阅本指南

默认情况下关闭 Beta API

新的 beta API 默认不会在集群中启用。 默认情况下,现有 Beta API 和及其更新版本将继续被启用。

签署发布工件

发布工件使用 cosign 签名进行签名, 并且有验证图像签名的实验性支持。 发布工件的签名和验证是提高 Kubernetes 发布过程的软件供应链安全性 的一部分。

OpenAPI v3

Kubernetes 1.24 提供了以 OpenAPI v3 格式发布其 API 的 Beta 支持。

存储容量和卷扩展普遍可用

存储容量跟踪支持通过 CSIStorageCapacity 对象公开当前可用的存储容量, 并增强使用具有后期绑定的 CSI 卷的 Pod 的调度。

卷的扩展增加了对调整现有持久性卷大小的支持。

NonPreemptingPriority 到稳定

此功能为 PriorityClasses 添加了一个新选项,可以启用或禁用 Pod 抢占。

存储插件迁移

目前正在进行迁移树内存储插件的内部组件工作, 以便在保持原有 API 的同时调用 CSI 插件。Azure DiskOpenStack Cinder 插件都已迁移。

gRPC 探针升级到 Beta

在 Kubernetes 1.24 中,gRPC 探测功能 已进入测试版,默认可用。现在,你可以在 Kubernetes 中为你的 gRPC 应用程序原生地配置启动、存活和就绪性探测, 而无需暴露 HTTP 端点或使用额外的可执行文件。

Kubelet 凭证提供者毕业至 Beta

kubelet 最初在 Kubernetes 1.20 中作为 Alpha 发布,现在它对镜像凭证提供者 的支持已升级到 Beta。这允许 kubelet 使用 exec 插件动态检索容器镜像仓库的凭据,而不是将凭据存储在节点的文件系统上。

Alpha 中的上下文日志记录

Kubernetes 1.24 引入了上下文日志 这使函数的调用者能够控制日志记录的所有方面(输出格式、详细程度、附加值和名称)。

避免 IP 分配给服务的冲突

Kubernetes 1.24 引入了一项新的选择加入功能, 允许你为服务的静态 IP 地址分配软保留范围。 通过手动启用此功能,集群将更喜欢从服务 IP 地址池中自动分配,从而降低冲突风险。

服务的 ClusterIP 可以按照以下两种方式分配:

  • 动态,这意味着集群将自动在配置的服务 IP 范围内选择一个空闲 IP。
  • 静态,这意味着用户将在配置的服务 IP 范围内设置一个 IP。

服务 ClusterIP 是唯一的;因此,尝试使用已分配的 ClusterIP 创建服务将返回错误。

从 Kubelet 中移除动态 Kubelet 配置

在 Kubernetes 1.22 中被弃用后,动态 Kubelet 配置已从 kubelet 中移除。 该功能将从 Kubernetes 1.26 的 API 服务器中移除。

CNI 版本相关的重大更改

在升级到 Kubernetes 1.24 之前,请确认你正在使用/升级到经过测试可以在此版本中正常工作的容器运行时。

例如,以下容器运行时正在为 Kubernetes 准备,或者已经准备好了。

  • containerd v1.6.4 及更高版本,v1.5.11 及更高版本
  • CRI-O 1.24 及更高版本

当 CNI 插件尚未升级和/或 CNI 配置版本未在 CNI 配置文件中声明时,在 containerd v1.6.0–v1.6.3 中存在 Pod CNI 网络设置和拆除的服务问题。containerd 团队报告说,“这些问题在 containerd v1.6.4 中得到解决。”

在 containerd v1.6.0-v1.6.3 版本中,如果你不升级 CNI 插件和/或声明 CNI 配置版本, 你可能会遇到以下 “Incompatible CNI versions” 或 “Failed to destroy network for sandbox” 的错误情况。

CSI 快照

此信息是在首次发布后添加的。

VolumeSnapshot v1beta1 CRD 已被移除。 Kubernetes 和容器存储接口 (CSI) 的卷快照和恢复功能,提供标准化的 API 设计 (CRD) 并添加了对 CSI 卷驱动程序的 PV 快照/恢复支持,在 v1.20 中升级至 GA。VolumeSnapshot v1beta1 在 v1.20 中被弃用,现在不受支持。 有关详细信息,请参阅 KEP-177: CSI 快照卷快照 GA 博客

其他更新

毕业到稳定版

在此版本中,有 14 项增强功能升级为稳定版:

主要变更

此版本有两个主要变更:

发行说明

在我们的发行说明 中查看 Kubernetes 1.24 版本的完整详细信息。

可用性

Kubernetes 1.24 可在 GitHub 上下载。 要开始使用 Kubernetes,请查看这些交互式教程或在本地运行。 使用 kind,可以将容器作为 Kubernetes 集群的 “节点”。 你还可以使用 kubeadm 轻松安装 1.24。

发布团队

如果没有 Kubernetes 1.24 发布团队每个人做出的共同努力,这个版本是不可能实现的。 该团队齐心协力交付每个 Kubernetes 版本中的所有组件,包括代码、文档、发行说明等。

特别感谢我们的发布负责人 James Laverack 指导我们完成了一个成功的发布周期, 并感谢所有发布团队成员投入时间和精力为 Kubernetes 社区提供 v1.24 版本。

发布主题和徽标

Kubernetes 1.24: 观星者

Kubernetes 1.24 的主题是观星者(Stargazer)

古代天文学家到建造 James Webb 太空望远镜的科学家,几代人都怀着敬畏和惊奇的心情仰望星空。 是这些星辰启发了我们,点燃了我们的想象力,引导我们在艰难的海上度过了漫长的夜晚。

通过此版本,我们向上凝视,当我们的社区聚集在一起时可能发生的事情。 Kubernetes 是全球数百名贡献者和数千名最终用户支持的成果, 是一款为数百万人服务的应用程序。每个人都是我们天空中的一颗星星,帮助我们规划路线。

发布标志由 Britnee Laverack 制作, 描绘了一架位于星空和昴星团的望远镜,在神话中通常被称为“七姐妹”。 数字 7 对于 Kubernetes 项目特别吉祥,是对我们最初的“项目七”名称的引用。

这个版本的 Kubernetes 为那些仰望夜空的人命名——为所有的观星者命名。 ✨

用户亮点

生态系统更新

项目速度

The CNCF K8s DevStats 项目 汇总了许多与 Kubernetes 和各种子项目的速度相关的有趣数据点。这包括从个人贡献到做出贡献的公司数量的所有内容, 并且说明了为发展这个生态系统而付出的努力的深度和广度。

运行 17 周 ( 1 月 10 日至 5 月 3 日)的 v1.24 发布周期中,我们看到 1029 家公司1179 人 的贡献。

即将发布的网络研讨会

在太平洋时间 2022 年 5 月 24 日星期二上午 9:45 至上午 11 点加入 Kubernetes 1.24 发布团队的成员, 了解此版本的主要功能以及弃用和删除,以帮助规划升级。有关更多信息和注册, 请访问 CNCF 在线计划网站上的活动页面

参与进来

参与 Kubernetes 的最简单方法是加入符合你兴趣的众多特别兴趣组(SIG)之一。 你有什么想向 Kubernetes 社区广播的内容吗? 在我们的每周的社区会议上分享你的声音,并通过以下渠道:

Frontiers, fsGroups and frogs: Kubernetes 1.23 发布采访

作者: Craig Box (Google)

举办每周一次的来自 Google 的 Kubernetes 播客 的亮点之一是与每个新 Kubernetes 版本的发布经理交谈。发布团队不断刷新。许多人从小型文档修复开始,逐步晋升为影子角色,然后最终领导发布。

在我们为下周发布的 1.24 版本做准备时,按照长期以来的传统, 很高兴带大家回顾一下 1.23 的故事。该版本由 SUSE 的现场工程师 Rey Lejano 领导。 在 12 月我与 Rey 交谈过,当时他正在等待他的第一个孩子的出生。

请确保你订阅,无论你在哪里获得你的播客, 以便你听到我们所有来自云原生社区的故事,包括下周 1.24 的故事。

为清晰起见本稿件经过了简单的编辑和浓缩。


CRAIG BOX:我想从现在每个人最关心的问题开始。让我们谈谈非洲爪蛙!

REY LEJANO:[笑]哦,你是说 Xenopus lavis,非洲爪蛙的学名?

CRAIG BOX:当然。

REY LEJANO:知道的人不多,但我曾就读于戴維斯加利福尼亚大学的微生物学专业。 我在生物化学实验室做了大约四年的生物化学研究,并且我确实发表了一篇研究论文。 它实际上是在糖蛋白上,特别是一种叫做“皮质颗粒凝集素”的东西。我们使用青蛙,因为它们会产生大量的蛋,我们可以从中提取蛋白质。 这种蛋白质可以防止多精症。当精子进入卵子时,卵子会向细胞膜释放一种糖蛋白,即皮质颗粒凝集素,并阻止任何其他精子进入卵子。

CRAIG BOX:你是否能够从我们对青蛙进行的测试中汲取任何东西并将其推广到更高阶的哺乳动物?

REY LEJANO:是的。由于哺乳动物也有皮质颗粒凝集素,我们能够分析收敛和进化模式,不仅来自多种青蛙,还包括哺乳动物。

CRAIG BOX:现在,这里有几个不同的线索需要解开。当你年轻的时候,是什么引导你进入生物学领域,可以侧重介绍技术方面的内容吗?

REY LEJANO:我认为这主要来自家庭,因为我在医学领域确实有可以追溯到几代人的家族史。所以我觉得那是进入大学的自然路径。

CRAIG BOX:现在,你正在一个更抽象的技术领域工作。是什么让你离开了微生物学?

REY LEJANO:[笑]嗯,我一直对科技很感兴趣。我年轻的时候自学了一点编程,在高中之前,做了一些网络开发的东西。 只是在实验室里有点焦头烂额了,实际上是在地下室。我有一个很好的机会加入了一家专门从事 ITIL 的咨询公司。实际上,我从应用性能管理开始,进入监控,进入运营管理和 ITIL,也就是把你的 IT 资产管理和服务管理与商业服务结合起来。实际上,我在这方面做了很多年。

CRAIG BOX:这很有趣,当人们描述他们所经历的事情以及他们所从事的技术时,你几乎可以确定他们的年龄。 现在有很多人进入科技行业,但从未听说过 ITIL。他们不知道那是什么。它基本上和 SRE 类似,只是过程更加复杂。

REY LEJANO:是的,一点没错。它不是非常云原生的。[笑]

CRAIG BOX:一点也不。

REY LEJANO:在云原生环境中,你并没有真正听说过它。毫无疑问,如果有人专门从事过 ITIL 工作或之前曾与 ITIL 合作过,你肯定可以看出他们已经在该领域工作了一段时间。

CRAIG BOX:你提到你想离开地下室。这的确是程序员常待的地方。他们只是在新的地下室里给了你一点光吗?

REY LEJANO:[笑]他们确实给了我们更好的照明。有时也能获得一些维生素 D。

CRAIG BOX:总结一下你的过往职业经历:在过去的一年里,随着全球各地的发展变化,我认为如今微生物学技能可能比你在校时更受欢迎?

REY LEJANO:哦,当然。我肯定能看到进入这个领域的人数大增。此外,阅读当前世界正在发生的事情也会带回我过去所学的所有教育。

CRAIG BOX:你和当时的同学还在保持联系吗?

REY LEJANO:只是一些亲密的朋友,但不是在微生物学领域。

CRAIG BOX:我认为,这次的全球疫情可能让人们对科学、技术、工程和数学领域重新产生兴趣。 看看这对整个社会有什么影响,将是很有趣的。

REY LEJANO:是的。我认为那会很棒。

CRAIG BOX:你提到在一家咨询公司工作,从事 IT 管理、应用程序性能监控等工作。Kubernetes 是什么时候进入你的职业生涯的?

REY LEJANO:在我工作的公司,我的一位好朋友于 2015 年年中离职。他去了一家非常热衷于 Docker 的公司。 他教了我一点东西。我在 2015 年左右,也许是 2016 年,做了我的第一次 “docker run”。 然后,我们用于 ITIL 框架的一个应用程序在 2018 年左右被容器化了,也在 Kubernetes 中。 那个时候,它是有些问题的。那是我第一次接触 Kubernetes 和容器化应用程序。

然后我离开了那家公司,实际上我加入了我在 RX-M 的朋友,这是一家云原生咨询和培训公司。 他们专门从事 Docker 和 Kubernetes 的工作。我能够让我脚踏实地。我拿到了 CKD 和 CKA 证书。 他们在鼓励我们学习更多关于 Kubernetes 的知识和参与社区活动方面真的非常棒。

CRAIG BOX:然后,你将看到人们采用 Kubernetes 和容器化的整个生命周期,通过你自己的初始旅程,然后通过帮助客户。你如何描述这段旅程从早期到今天的变化?

REY LEJANO:我认为早期有很多问题,为什么我必须容器化?为什么我不能只使用虚拟机?

CRAIG BOX:这是你的简历上的一个条目。

REY LEJANO:[笑]是的。现在,我认为人们知道使用容器的价值,以及使用 Kubernetes 编排容器的价值。我不想说“赶上潮流”,但它已经成为编排容器的事实标准。

CRAIG BOX:这不是咨询公司需要走出去向客户推销他们应该做的事情。他们只是把它当作会发生的事情,并开始在这条路上走得更远一些,也许。

REY LEJANO:当然。

CRAIG BOX:在这样的咨询公司工作,你有多少时间致力于改善流程,也许是为多个客户,然后研究如何将这项工作推向上游,而不是每次只为单个客户做有偿工作?

REY LEJANO:那时,情况会有所不同。他们帮我介绍了自己,我也了解了很多关于云原生环境和 Kubernetes 本身的情况。 他们帮助我了解如何将云原生环境及其周围的工具一起使用。我在那家公司的老板,Randy,实际上他鼓励我们开始向上游做贡献, 并鼓励我加入发布团队。他只是说,这是个很好的机会。这对我在早期就开始做贡献有很大的帮助。

CRAIG BOX:发布团队是你参与上游 Kubernetes 贡献的方式吗?

REY LEJANO:实际上,没有。我的第一个贡献是 SIG Docs。我认识了 Taylor Dolezal——他是 1.19 的发布团队负责人,但他也参与了 SIG Docs。 我在 KubeCon 2019 遇到了他,在午餐时我坐在他的桌子旁。我记得 Paris Pittman 在万豪酒店主持了这次午餐会。 Taylor 说他参与了 SIG Docs。他鼓励我加入。我开始参加会议,开始做一些路过式的 PR。 这就是我们所说的 - 驱动式 - 小错字修复。然后做更多的事情,开始发送更好或更高质量的拉取请求,并审查 PR。

CRAIG BOX:你第一次正式担任发布团队的角色是什么时候?

REY LEJANO:那是在 12月的 1.18。 当时我的老板鼓励我去申请。我申请了,很幸运地被录取了,成为发布说明的影子。然后从那里开始,我在发布说明中呆了几个周期, 然后去了文档,自然而然地领导了文档,然后去了增强版,现在我是 1.23 的发行负责人。

CRAIG BOX:我不知道很多人都会考虑到一个好的发行说明需要什么。你说什么才是呢?

REY LEJANO:[笑]你必须告诉最终用户发生了什么变化,或者他们在发行说明中可能看到什么效果。 它不必是高度技术性的。它可以只是几行字,只是说有什么变化,如果他们也必须做任何事情,他们必须做什么。

CRAIG BOX:我不知道很多人会考虑一个好的发布说明的内容。你会说什么?

REY LEJANO:当我是这个周期的发布负责人时,我说过几次。你从发布团队得到的东西和你投入的东西一样多,或者说它直接与你投入的东西相一致。 我学到了很多东西。我在进入发布团队时就有这样的心态:向角色领导学习,也向其他影子学习。 这实际上是我的第一个角色负责人告诉我的一句话。我仍然铭记于心,那是在 1.18 中。那是 Eddie,在我们第一次见面时,我仍然牢记在心。

CRAIG BOX:当然,你是 1.23 的发布负责人。首先,祝贺发布。

REY LEJANO:非常感谢。

CRAIG BOX:这个版本的主题是最后战线。 请告诉我我们是如何确定主题和标志的故事。

REY LEJANO:最后战线代表了几件事。它不仅代表了此版本的下一个增强功能,而且 Kubernetes 本身也有《星际迷航》的参考历史。 Kubernetes 的原始代号是 Project Seven,指的是最初来自《星际迷航》中的 Seven of Nine。 在 Kubernetes 的 logo 中掌舵的七根辐条也是如此。当然,还有 Kubernetes 的前身 Borg。

最后战线继续星际迷航参考。这是星际迷航宇宙中两个标题的融合。一个是星际迷航 5:最后战线,还有星际迷航:下一代。

CRAIG BOX:你对《星际迷航 5》是一部奇数电影有什么看法,而且它们通常被称为比偶数电影票房少

REY LEJANO:我不能说,因为我是一个科幻书呆子,我喜欢他们所有的人,尽管他们很糟糕。即使是《下一代》系列之后的电影,我仍然喜欢所有的电影,尽管我知道有些并不那么好。

CRAIG BOX:我记得星际迷航 5 是由 William Shatner 执导对吗?

REY LEJANO:是的,对的。

CRAIG BOX:我认为这说明了一切。

REY LEJANO:[笑]是的。

CRAIG BOX:现在,我明白了,主题来自于 SIG 发布章程

REY LEJANO:是的。SIG 发布章程中有一句话,“确保有一个一致的社区成员小组来支持不同时期的发布过程。” 在发布团队中,我们每一个发布周期都有新的影子加入。有了这个,我们与这个社区一起成长。我们正在壮大发布团队的成员。 我们正在增加 SIG 版本。我们正在发展 Kubernetes 社区本身。对于很多人来说,这是他们第一次为开源做出贡献,所以我说这是他们新的开源前沿。

CRAIG BOX:而这个标志显然是受《星际迷航》的启发。让我感到惊讶的是,花了那么长时间才有人走这条路

REY LEJANO:我也很惊讶。我不得不重新学习 Adobe Illustrator 来创建标志。

CRAIG BOX:这是你自己的作品,是吗?

REY LEJANO:这是我自己的作品。

CRAIG BOX:非常好。

REY LEJANO:谢谢。有趣的是,相对于飞船,银河系实际上花了我最长的时间。我花了几天时间才把它弄正确。 我一直在对它进行微调,所以在真正发布时可能会有最后的改变。

CRAIG BOX:没有边界是真正的终结。

REY LEJANO:是的,非常正确。

CRAIG BOX:现在从发布的主题转到实质内容,也许,1.23 中有什么新内容?

REY LEJANO:我们有 47 项增强功能。我将运行大部分稳定的,甚至全部的,一些关键的 Beta 版,以及一些 1.23 版的 Alpha 增强。

其中一个关键的改进是双堆栈 IPv4/IPv6,它在 1.23 版本中采用了 GA。

一些背景信息:双堆栈在 1.15 中作为 Alpha 引入。你可能在 KubeCon 2019 上看到了一个主题演讲。 那时,双栈的工作方式是,你需要两个服务--你需要每个IP家族的服务。你需要一个用于 IPv4 的服务和一个用于 IPv6 的服务。 它在 1.20 版本中被重构了。在 1.21 版本中,它处于测试阶段;默认情况下,集群被启用为双堆栈。

然后在 1.23 版本中,我们确实删除了 IPv6 双栈功能标志。这不是强制性的使用双栈。它实际上仍然不是 "默认"的。 Pod,服务仍然默认为单栈。要使用双栈,有一些要求。节点必须可以在 IPv4 和 IPv6 网络接口上进行路由。 你需要一个支持双栈的 CNI 插件。Pod 本身必须被配置为双栈。而服务需要 ipFamilyPolicy 字段来指定喜欢双栈或要求双栈。

CRAIG BOX:这听起来暗示仍然需要 v4。你是否看到了一个我们实际上可以转移到仅有 v6 的集群的世界??

REY LEJANO:我认为在未来很多很多年里,我们都会谈论 IPv4 和 IPv6。我记得很久以前,他们一直在说 "这将全部是 IPv6",而那是几十年前的事了。

CRAIG BOX:我想我之前可能在节目中提到过,Vint Cerf 在伦敦参加了一个会议, 他当时做了一个公开演讲说,现在是v6的时代了。那是至少 10 年前的事了。现在还不是 v6 的时代,我的电脑桌面上还没有一天拥有 Linux。

REY LEJANO:[笑]在我看来,这是 1.23 版稳定的一大关键功能。

1.23 版的另一个亮点是 Pod 安全许可进入 Beta 版。 我知道这个功能将进入 Beta 版,但我强调这一点是因为有些人可能知道,PodSecurityPolicy 在 1.21 版本中被废弃,目标是在 1.25 版本中被移除。 Pod 安全接纳取代了 Pod 安全策略。它是一个准入控制器。它根据预定义的 Pod 安全标准集对 Pod 进行评估,以接纳或拒绝 Pod 的运行。

Pod 安全标准分为三个级别。特权,这是完全开放的。基线,已知的特权升级被最小化。或者 限制级,这是强化的。而且你可以将 Pod 安全标准设置为以三种模式运行, 即强制:拒绝任何违规的 Pod;审计:允许创建 Pod,但记录违规行为;或警告:它会向用户发送警告消息,并且允许该 Pod。

CRAIG BOX:你提到 PodSecurityPolicy 将在两个版本的时间内被弃用。我们是否对这些功能进行了排列,以便届时 Pod 安全接纳将成为 GA?

REY LEJANO:是的。当然可以。我稍后也会为另一个功能谈谈这个问题。还有另一个功能也进入了 GA。这是一个归入 GA 的 API, 因此 Beta 版的 API 现在被废弃了。我稍稍讲一下这个问题。

CRAIG BOX:好吧。让我们来谈谈名单上的下一个问题。

REY LEJANO:让我们继续讨论更稳定的增强功能。一种是 TTL 控制器。 它在作业完成后清理作业和 Pod。有一个 TTL 计时器在作业或 Pod 完成后开始计时。此 TTL 控制器监视所有作业, 并且需要设置 ttlSecondsAfterFinished。该控制器将查看 ttlSecondsAfterFinished,结合最后的过渡时间,如果它大于现在。 如果是,那么它将删除该作业和该作业的 Pod。

CRAIG BOX:粗略地说,它可以称为垃圾收集器吗?

REY LEJANO:是的。用于 Pod 和作业,或作业和 Pod 的垃圾收集器。

CRAIG BOX:如果 Kubernetes 真正成为一种编程语言,它当然必须实现垃圾收集器。

REY LEJANO:是的。还有另一个,也将在 Alpha 中出现。[笑]

CRAIG BOX:告诉我。

REY LEJANO: 那个是在 Alpha 中出现的。这实际上是我最喜欢的功能之一,今天我只想强调几个。 StafeulSet 的 PVC 将被清理。 当你删除那个 StatefulSet 时,它将自动删除由 StatefulSets 创建的 PVC。

CRAIG BOX:我们的稳定功能之旅的下一步是什么?

REY LEJANO:下一个是,跳过卷所有权更改进入稳定状态。 这是来自 SIG 存储。有的时候,当你运行一个有状态的应用程序时,就像许多数据库一样,它们对下面的权限位变化很敏感。 目前,当一个卷被绑定安装在容器内时,该卷的权限将递归更改。这可能需要很长时间。 -->

现在,有一个字段,即 fsGroupChangePolicy,它允许你作为用户告诉 Kubernetes 你希望如何更改该卷的权限和所有权。 你可以将其设置为总是、始终更改权限,或者只是在不匹配的情况下,只在顶层的权限所有权变化与预期不同的情况下进行。

CRAIG BOX:确实感觉很多这些增强功能都来自一个非常特殊的用例,有人说,“嘿,这对我来说不起作用,我已经研究了一个功能,它可以完全满足我需要的东西”

REY LEJANO:当然可以。人们为这些问题创建问题,然后创建 Kubernetes 增强提案,然后被列为发布目标。

CRAIG BOX:此版本中的另一个 GA 功能--临时卷。

REY LEJANO:我们一直能够将空目录用于临时卷,但现在我们实际上可以拥有[临时内联卷] (https://github.com/kubernetes/enhancements/issues/1698), 这意味着你可以使用标准 CSI 驱动程序并能够与它一起使用临时卷。

CRAIG BOX:而且,很长一段时间,CronJobs

REY LEJANO:CronJobs 很有趣,因为它在 1.23 之前是稳定的。对于 1.23,它仍然被跟踪,但它只是清理了一些旧控制器。 使用 CronJobs,有一个 v2 控制器。1.23 中清理的只是旧的 v1 控制器。

CRAIG BOX:在这个版本中,是否有任何其他的重复或重大的清理工作值得注意?

REY LEJANO:是的。有几个你可能会在主要的主题中看到。其中一个有点棘手,围绕 FlexVolumes。这是 SIG 存储公司的努力之一。 他们正在努力将树内插件迁移到 CSI 驱动。这有点棘手,因为 FlexVolumes 实际上是在 2020 年 11 月被废弃的。我们 在 1.23 中正式宣布

CRAIG BOX:在我看来,FlexVolumes 比 CSI 这个概念还要早。所以现在是时候摆脱它们了。

REY LEJANO:是的。还有另一个弃用,只是一些 klog 特定标志,但除此之外,1.23 中没有其他大的弃用。

CRAIG BOX:上一届 KubeCon 的流行语,在某种程度上也是过去 12 个月的主题,是安全的软件供应链。Kubernetes 在这一领域做了哪些改进工作?

REY LEJANO:对于 1.23 版本,Kubernetes 现在符合 SLSA 的 1 级标准,这意味着描述发布过程中分期和发布阶段的证明文件对于 SLSA 框架来说是令人满意的。

CRAIG BOX:需要做什么才能提升到更高的水平?

REY LEJANO:级别 1 意味着一些事情——构建是脚本化的;出处是可用的,这意味着工件是经过验证,并且已从一个阶段移交到下一个阶段; 并描述了工件是如何产生的。级别 2 意味着源是受版本控制的,也就是说,源是经过身份验证的,源是服务生成的,并且存在构建服务。SLSA 的合规性分为四个级别。

CRAIG BOX:看起来这些水平在很大程度上受到了建立这样一个大型安全项目的影响。例如,似乎不需要很多额外的工作来提升到可验证的出处。 可能只需要几行脚本即可满足其中许多要求。

REY LEJANO:当然。我觉得我们就快成功了;我们会看到 1.24 版本会出现什么。我确实想对 SIG 发布和发布工程部大加赞赏, 主要是 Adolfo García Veytia,他在 GitHub 和 Slack 上又名 Puerco。 他一直在推动这一进程。

CRAIG BOX:你提到了一些 API 正在及时升级以替换其已弃用的版本。告诉我有关新 HPA API 的信息。

REY LEJANO:horizontal pod autoscaler v2 API, 现已稳定,这意味着 v2beta2 API 已弃用。众所周知,v1 API 并未被弃用。不同之处在于 v2 添加了对用于 HPA 的多个和自定义指标的支持。

CRAIG BOX:现在还可以使用表达式语言验证我的 CRD。

REY LEJANO:是的。你可以使用 通用表达式语言,或 CEL 来验证你的 CRD,因此你不再需要使用 webhook。这也使 CRD 更加自包含和声明性,因为规则现在保存在 CRD 对象定义中。

CRAIG BOX:哪些新功能(可能是 Alpha 版或 Beta 版)引起了你的兴趣?

REY LEJANO:除了 Pod 安全策略,我真的很喜欢支持 kubectl 调试的临时容器。 它启动一个临时容器和一个正在运行的 Pod,共享这些 Pod 命名空间,你只需运行 kubectl debug 即可完成所有故障排除。

CRAIG BOX:使用 kubectl 处理事件的方式也发生了一些有趣的变化。

REY LEJANO:是的。kubectl events 总是有一些问题,比如事情没有排序。 kubectl 事件得到了改进, 所以现在你可以使用 --watch,它也可以使用 --watch 选项进行排序。那是新事物。 你实际上可以组合字段和自定义列。此外,你可以在时间线中列出最后 N 分钟的事件。你还可以使用其他标准对事件进行排序。

CRAIG BOX:你是 SUSE 的一名现场工程师。有什么事情是你所处理的个别客户所要注意的吗?

REY LEJANO:更多我期待帮助客户的东西。

CRAIG BOX:好吧。

REY LEJANO:我真的很喜欢 kubectl 事件。真的很喜欢用 StatefulSets 清理的 PVC。其中大部分是出于自私的原因,它将改进故障排除工作。[笑]

CRAIG BOX:我一直希望发布团队负责人对我说:“是的,我有自私的理由。我终于得到了我想要的东西。”

REY LEJANO:[大笑]

CRAIG BOX:也许我应该竞选发布团队的负责人,这样我就可以最终让 Init 容器一劳永逸地得到修复。

REY LEJANO:哦,Init 容器,我一直在寻找它。实际上,我已经制作了 GIF 动画,介绍了 Init 容器将如何与那个 Kubernetes 增强提案一起运行,但目前已经停止了。

CRAIG BOX:有一天。

REY LEJANO:总有一天。也许我不应该停下来。

CRAIG BOX:你提到的显然是你所关注的事情。是否有任何即将推出的东西,可能是 Alpha 功能,甚至可能只是你最近看到的建议,你个人真的很期待看到它们的发展方向?

REY LEJANO:是的。Oone 是一个非常有趣的问题,它影响了整个社区,所以这不仅仅是出于个人原因。 正如你可能已经知道的,Dockershim 已经被废弃了。而且我们确实发布了一篇博客,说它将在 1.24 中被删除。

CRAIG BOX:吓坏了一群人。

REY LEJANO:吓坏了一群人。从一项调查中,我们看到很多人仍在使用 Docker 和 Dockershim。 1.23 的增强功能之一是 kubelet CRI 进入 Beta 版。 这促进了 CRI API 的发展,而这是必需的。 这必须是 Beta 版才能在 1.24 中删除 Dockershim。

**CRAIG BOX:现在,在最后一次发布团队领导访谈中,我们与 Savitha Raghunathan 进行了交谈, 她谈到了作为她的继任者她会给你什么建议。她说要关注团队成员的心理健康。你是如何采纳这个建议的?

REY LEJANO:Savitha 的建议很好。我在每次发布团队会议上都记录了一些事情。 每次发布团队会议后,我都会停止录制,因为我们确实会录制所有会议并将其发布到 YouTube 上。 我向任何想要说任何未记录的内容的人开放发言,这不会出现在议程上。此外,我告诉人们不要在周末工作。 我曾经打破过这个规则,但除此之外,我告诉人们它可以等待。只要注意你的心理健康。

CRAIG BOX:刚刚宣布来自 Jetstack 的 James Laverack 将成为 1.24 的发布团队负责人。James 和我在 San Diego 的最后一届 KubeCon 上分享了一顿有趣的墨西哥晚餐。

REY LEJANO:哦,不错。我不知道你认识 James。

CRAIG BOX:英国科技界。我们是一个非常小的世界。你对 James 的建议是什么?

REY LEJANO:对于 1.24,我要告诉 James 的是在发布团队会议中使用教学时刻。当你第一次成为影子时,这是非常令人生畏的。 这非常困难,因为你不知道存储库。你不知道发布过程。周围的每个人似乎都知道发布过程,并且非常熟悉发布过程是什么。 但作为第一次出现的影子,你并不了解社区的所有白话。我只是建议使用教学时刻。在发布团队会议上花几分钟时间,让新影子更容易上手并熟悉发布过程。

CRAIG BOX:在你参与的这段时间里,这个过程是否有重大演变?或者你认为它正在有效地做它需要做的事情?

REY LEJANO:它总是在不断发展。我记得我第一次做发布说明时,1.18,我们说我们的目标是自动化和编程,这样我们就不再有发行说明团队了。 这改变了很多[笑]。尽管 Adolfo 和 James 在发布说明过程中取得了重大进展,但他们在 krel 中创建了一个子命令来生成发行说明。

但如今,他们所有的发行说明都更加丰富了。在自动化过程中,仍然没有达到。每个发布周期,都有一点不同的东西。 对于这个发布周期,我们有一个生产就绪审查截止日期。这是一个软期限。生产就绪审查是社区中几个人的审查。 实际上从 1.21 开始就需要它,它确保增强是可观察的、可扩展的、可支持的,并且在生产中运行是安全的,也可以被禁用或回滚。 在 1.23 中,我们有一个截止日期,要求在特定日期之前完成生产就绪审查。

CRAIG BOX:你如何发现每年发布三个版本,而不是四个版本?

REY LEJANO:从一年四个版本转为三个版本,在我看来是一种进步,因为我们支持最后三个版本, 现在我们实际上可以支持在一个日历年内的最后一个版本,而不是在 12 个月中只有 9 个月。

CRAIG BOX:日历上的下一个活动是下周一开始的 Kubernetes 贡献者庆典。我们可以从活动中期待什么?

REY LEJANO:这是我们第二次举办这个虚拟活动。这是一个虚拟的庆祝活动,以表彰整个社区和我们今年的所有成就,以及贡献者。 在这周的庆典中有许多活动。它从 12 月 13 日的那一周开始。

有像 Kubernetes 贡献者奖这样的活动,SIG 对社区和贡献者的辛勤工作进行表彰和奖励。 也有一个 DevOps 聚会游戏。还有一个云原生的烘烤活动。我强烈建议人们去 kubernetes.dev/celebration 了解更多。

CRAIG BOX: 究竟如何评判一个虚拟的烘焙比赛呢?

REY LEJANO:那我不知道。[笑]

CRAIG BOX:我尝了尝我的烤饼。我认为他们是最好的。我给他们打了 10 分(满分 10 分)。

REY LEJANO:是的。这是很难做到的。我不得不说,这道菜可能是什么,它与 Kubernetes 或开源或与 CNCF 的关系有多密切。 有几个评委。我知道 Josh Berkus 和 Rin Oliver 是主持烘焙比赛的几个评委。

CRAIG BOX:是的。我们与 Josh 谈到了他对厨房的热爱,因此他似乎非常适合这个角色。

REY LEJANO:他是。

CRAIG BOX:最后,你的妻子和你自己将在一月份迎来你们的第一个孩子。你是否为此进行过生产准备审查?

REY LEJANO:我认为我们没有通过审查。[笑]

CRAIG BOX:还有时间。

REY LEJANO:我们正在努力重构。我们将在 12 月进行一些重构,然后再次使用 --apply


Rey Lejano 是 SUSE 的一名现场工程师,来自 Rancher Labs,并且是 Kubernetes 1.23 的发布团队负责人。 他现在也是 SIG Docs 的联合主席。他的儿子 Liam 现在 3 个半月大。

你可以在 Twitter 上的 @KubernetesPod 找到来自谷歌的 Kubernetes 播客, 你也可以订阅,这样你就不会错过任何一集。

在 Ingress-NGINX v1.2.0 中提高安全标准

作者: Ricardo Katz (VMware), James Strong (Chainguard)

Ingress 可能是 Kubernetes 最容易受攻击的组件之一。 Ingress 通常定义一个 HTTP 反向代理,暴露在互联网上,包含多个网站,并具有对 Kubernetes API 的一些特权访问(例如读取与 TLS 证书及其私钥相关的 Secret)。

虽然它是架构中的一个风险组件,但它仍然是正常公开服务的最流行方式。

Ingress-NGINX 一直是安全评估的重头戏,这类评估会发现我们有着很大的问题: 在将配置转换为 nginx.conf 文件之前,我们没有进行所有适当的清理,这可能会导致信息泄露风险。

虽然我们了解此风险以及解决此问题的真正需求,但这并不是一个容易的过程, 因此我们在当前(v1.2.0)版本中采取了另一种方法来减少(但不是消除!)这种风险。

了解 Ingress NGINX v1.2.0 和 chrooted NGINX 进程

主要挑战之一是 Ingress-NGINX 运行着 Web 代理服务器(NGINX),并与 Ingress 控制器一起运行 (后者是一个可以访问 Kubernetes API 并创建 nginx.conf 的组件)。

因此,NGINX 对控制器的文件系统(和 Kubernetes 服务帐户令牌,以及容器中的其他配置)具有相同的访问权限。 虽然拆分这些组件是我们的最终目标,但该项目需要快速响应;这让我们想到了使用 chroot()

让我们看一下 Ingress-NGINX 容器在此更改之前的样子:

Ingress NGINX pre chroot

正如我们所见,用来提供 HTTP Proxy 的容器(不是 Pod,是容器!)也是是监视 Ingress 对象并将数据写入容器卷的容器。

现在,见识一下新架构:

Ingress NGINX post chroot

这一切意味着什么?一个基本的总结是:我们将 NGINX 服务隔离为控制器容器内的容器。

虽然这并不完全正确,但要了解这里所做的事情,最好了解 Linux 容器(以及内核命名空间等底层机制)是如何工作的。 你可以在 Kubernetes 词汇表中阅读有关 cgroup 的信息:cgroup, 并在 NGINX 项目文章什么是命名空间和 cgroup,以及它们如何工作? 中了解有关 cgroup 与命名空间交互的更多信息。(当你阅读时,请记住 Linux 内核命名空间与 Kubernetes 命名空间不同)。

跳过谈话,我需要什么才能使用这种新方法?

虽然这增加了安全性,但我们在这个版本中把这个功能作为一个选项,这样你就可以有时间在你的环境中做出正确的调整。 此新功能仅在 Ingress-NGINX 控制器的 v1.2.0 版本中可用。

要使用这个功能,在你的部署中有两个必要的改变:

  • 将后缀 "-chroot" 添加到容器镜像名称中。例如:gcr.io/k8s-staging-ingress-nginx/controller-chroot:v1.2.0
  • 在你的 Ingress 控制器的 Pod 模板中,找到添加 NET_BIND_SERVICE 权能的位置并添加 SYS_CHROOT 权能。 编辑清单后,你将看到如下代码段:
capabilities:
  drop:
  - ALL
  add:
  - NET_BIND_SERVICE
  - SYS_CHROOT

如果你使用官方 Helm Chart 部署控制器,则在 values.yaml 中更改以下设置:

controller:
  image:
    chroot: true

Ingress 控制器通常部署在集群作用域(IngressClass API 是集群作用域的)。 如果你管理 Ingress-NGINX 控制器但你不是整个集群的操作员, 请在部署中启用它之前与集群管理员确认你是否可以使用 SYS_CHROOT 功能。

好吧,但这如何能提高我的 Ingress 控制器的安全性呢?

以下面的配置片段为例,想象一下,由于某种原因,它被添加到你的 nginx.conf 中:

location /randomthing/ {
      alias /;
      autoindex on;
}

如果你部署了这种配置,有人可以调用 http://website.example/randomthing 并获取对 Ingress 控制器的整个文件系统的一些列表(和访问权限)。

现在,你能在下面的列表中发现 chroot 处理过和未经 chroot 处理过的 Nginx 之间的区别吗?

不额外调用 chroot() 额外调用 chroot()
bin bin
dev dev
etc etc
home
lib lib
media
mnt
opt opt
proc proc
root
run run
sbin
srv
sys
tmp tmp
usr usr
var var
dbg
nginx-ingress-controller
wait-shutdown

左侧的那个没有 chroot 处理。所以 NGINX 可以完全访问文件系统。右侧的那个经过 chroot 处理, 因此创建了一个新文件系统,其中只有使 NGINX 工作所需的文件。

此版本中的其他安全改进如何?

我们知道新的 chroot() 机制有助于解决部分风险,但仍然有人可以尝试注入命令来读取,例如 nginx.conf 文件并提取敏感信息。

所以,这个版本的另一个变化(可选择取消)是 深度探测(Deep Inspector)。 我们知道某些指令或正则表达式可能对 NGINX 造成危险,因此深度探测器会检查 Ingress 对象中的所有字段 (在其协调期间,并且还使用验证准入 webhook) 验证是否有任何字段包含这些危险指令。

Ingress 控制器已经通过注解做了这个工作,我们的目标是把现有的验证转移到深度探测中,作为未来版本的一部分。

你可以在 https://github.com/kubernetes/ingress-nginx/blob/main/internal/ingress/inspector/rules.go 中查看现有规则。

由于检查和匹配相关 Ingress 对象中的所有字符串的性质,此新功能可能会消耗更多 CPU。 你可以通过使用命令行参数 --deep-inspect=false 运行 Ingress 控制器来禁用它。

下一步是什么?

这不是我们的最终目标。我们的最终目标是拆分控制平面和数据平面进程。 事实上,这样做也将帮助我们实现 Gateway API 实现, 因为一旦它“知道”要提供什么,我们可能会有不同的控制器 数据平面(我们需要一些帮助!!)

Kubernetes 中的其他一些项目已经采用了这种方法(如 KPNG, 建议替换 kube-proxy),我们计划与他们保持一致,并为 Ingress-NGINX 获得相同的体验。

延伸阅读

如果你想了解如何在 Ingress NGINX 中完成 chrooting,请查看 https://github.com/kubernetes/ingress-nginx/pull/8337。 包含所有更改的版本 v1.2.0 可以在以下位置找到 https://github.com/kubernetes/ingress-nginx/releases/tag/controller-v1.2.0

Kubernetes 1.24 中的移除和弃用

作者:Mickey Boxell (Oracle)

随着 Kubernetes 的发展,一些特性和 API 会被定期重检和移除。 新特性可能会提供替代或改进的方法,来解决现有的问题,从而激励团队移除旧的方法。

我们希望确保你了解 Kubernetes 1.24 版本的变化。该版本将 弃用 一些(测试版/beta)API, 转而支持相同 API 的稳定版本。Kubernetes 1.24 版本的主要变化是移除 Dockershim。 这将在下面讨论,并将在发布时更深入地探讨。 要提前了解 Kubernetes 1.24 中的更改,请查看正在更新中的 CHANGELOG

关于 Dockershim

可以肯定地说,随着 Kubernetes 1.24 的发布,最受关注的是移除 Dockershim。 Dockershim 在 1.20 版本中已被弃用。如 Kubernetes 1.20 变更日志中所述: "Docker support in the kubelet is now deprecated and will be removed in a future release. The kubelet uses a module called "dockershim" which implements CRI support for Docker and it has seen maintenance issues in the Kubernetes community." 随着即将发布的 Kubernetes 1.24,Dockershim 将最终被移除。

在文章别慌: Kubernetes 和 Docker 中, 作者简洁地记述了变化的影响,并鼓励用户保持冷静:

弃用 Docker 这个底层运行时,转而支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时。 Docker 构建的镜像,将在你的集群的所有运行时中继续工作,一如既往。

已经有一些文档指南,提供了关于从 dockershim 迁移到与 Kubernetes 直接兼容的容器运行时的有用信息。 你可以在 Kubernetes 文档中的从 dockershim 迁移 页面上找到它们。

有关 Kubernetes 为何不再使用 dockershim 的更多信息, 请参见:Kubernetes 即将移除 Dockershim最新的弃用 Dockershim 的常见问题

查看你的集群准备好使用 v1.24 版本了吗? 一文, 了解如何确保你的集群在从 1.23 版本升级到 1.24 版本后继续工作。

Kubernetes API 移除和弃用流程

Kubernetes 包含大量随时间演变的组件。在某些情况下,这种演变会导致 API、标志或整个特性被移除。 为了防止用户面对重大变化,Kubernetes 贡献者采用了一项特性弃用策略。 此策略确保仅当同一 API 的较新稳定版本可用并且 API 具有以下稳定性级别所指示的最短生命周期时,才可能弃用稳定版本 API:

  • 正式发布 (GA) 或稳定的 API 版本可能被标记为已弃用,但不得在 Kubernetes 的主版本中移除。
  • 测试版(beta)或预发布 API 版本在弃用后必须支持 3 个版本。
  • Alpha 或实验性 API 版本可能会在任何版本中被移除,恕不另行通知。

移除遵循相同的弃用政策,无论 API 是由于 测试版(beta)功能逐渐稳定还是因为该 API 未被证明是成功的而被移除。 Kubernetes 将继续确保在移除 API 时提供用来迁移的文档。

弃用的 API 是指那些已标记为在未来 Kubernetes 版本中移除的 API。 移除的 API 是指那些在被弃用后不再可用于当前受支持的 Kubernetes 版本的 API。 这些移除的 API 已被更新的、稳定的/普遍可用的 (GA) API 所取代。

Kubernetes 1.24 的 API 移除、弃用和其他更改

  • 动态日志清洗:实验性的动态日志清洗功能已被弃用, 将在 1.24 版本中被移除。该功能引入了一个日志过滤器,可以应用于所有 Kubernetes 系统组件的日志, 以防止各种类型的敏感信息通过日志泄漏。有关更多信息和替代方法,请参阅 KEP-1753: Kubernetes 系统组件日志清洗
  • Pod 调度的存储容量追踪:CSIStorageCapacity API 支持通过 CSIStorageCapacity 对象暴露当前可用的存储容量,并增强了使用带有延迟绑定的 CSI 卷的 Pod 的调度。 CSIStorageCapacity API 自 1.24 版本起提供稳定版本。升级到稳定版的 API 将弃用 v1beta1 CSIStorageCapacity API。 更多信息请参见 Pod 调度存储容量约束 KEP

需要做什么

移除 Dockershim

如前所述,有一些关于从 dockershim 迁移的指南。 你可以从查明节点上所使用的容器运行时开始。 如果你的节点使用 dockershim,则还有其他可能的 Docker Engine 依赖项, 例如 Pod 或执行 Docker 命令的第三方工具或 Docker 配置文件中的私有镜像库。 你可以按照检查移除 Dockershim 是否对你有影响 的指南来查看可能的 Docker 引擎依赖项。在升级到 1.24 版本之前,你决定要么继续使用 Docker Engine 并 将 Docker Engine 节点从 dockershim 迁移到 cri-dockerd, 要么迁移到与 CRI 兼容的运行时。这是将节点上的容器运行时从 Docker Engine 更改为 containerd 的指南。

kubectl convert

kubectl 的 kubectl convert 插件有助于解决弃用 API 的迁移问题。该插件方便了不同 API 版本之间清单的转换, 例如,从弃用的 API 版本到非弃用的 API 版本。 关于 API 迁移过程的更多信息可以在已弃用 API 的迁移指南中找到。 按照安装 kubectl convert 插件 文档下载并安装 kubectl-convert 二进制文件。

展望未来

计划在今年晚些时候发布的 Kubernetes 1.25 和 1.26 版本,将停止提供一些 Kubernetes API 的 Beta 版本,这些 API 当前为稳定版。1.25 版本还将移除 PodSecurityPolicy, 它已在 Kubernetes 1.21 版本中被弃用,并且不会升级到稳定版。有关详细信息,请参阅 PodSecurityPolicy 弃用:过去、现在和未来

Kubernetes 1.25 计划移除的 API 的官方列表是:

  • Beta CronJob API (batch/v1beta1)
  • Beta EndpointSlice API (discovery.k8s.io/v1beta1)
  • Beta Event API (events.k8s.io/v1beta1)
  • Beta HorizontalPodAutoscaler API (autoscaling/v2beta1)
  • Beta PodDisruptionBudget API (policy/v1beta1)
  • Beta PodSecurityPolicy API (policy/v1beta1)
  • Beta RuntimeClass API (node.k8s.io/v1beta1)

Kubernetes 1.26 计划移除的 API 的官方列表是:

  • Beta FlowSchema 和 PriorityLevelConfiguration API (flowcontrol.apiserver.k8s.io/v1beta1)
  • Beta HorizontalPodAutoscaler API (autoscaling/v2beta2)

了解更多

Kubernetes 发行说明中宣告了弃用信息。你可以在以下版本的发行说明中看到待弃用的公告:

有关弃用和移除过程的信息,请查看 Kubernetes 官方弃用策略文档。

你的集群准备好使用 v1.24 版本了吗?

作者: Kat Cosgrove

早在 2020 年 12 月,Kubernetes 就宣布弃用 Dockershim。 在 Kubernetes 中,dockershim 是一个软件 shim, 它允许你将整个 Docker 引擎用作 Kubernetes 中的容器运行时。 在即将发布的 v1.24 版本中,我们将移除 Dockershim - 在宣布弃用之后到彻底移除这段时间内,我们至少预留了一年的时间继续支持此功能, 这符合相关的项目策略。 如果你是集群操作员,则该指南包含你在此版本中需要了解的实际情况。 另外还包括你需要做些什么来确保你的集群不会崩溃!

首先,这对你有影响吗?

如果你正在管理自己的集群或不确定此删除是否会影响到你, 请保持安全状态并检查你对 Docker Engine 是否有依赖。 请注意,使用 Docker Desktop 构建应用程序容器并不算是集群对 Docker 有依赖。 Docker 创建的容器镜像符合 Open Container Initiative (OCI) 规范, 而 OCI 是 Linux 基金会的一种治理架构,负责围绕容器格式和运行时定义行业标准。 这些镜像可以在 Kubernetes 支持的任何容器运行时上正常工作。

如果你使用的是云服务提供商管理的 Kubernetes 服务, 并且你确定没有更改过容器运行时,那么你可能不需要做任何事情。 Amazon EKS、Azure AKS 和 Google GKE 现在都默认使用 containerd, 但如果你的集群中有任何自定义的节点,你要确保它们不需要被更新。 要检查节点的运行时,请参考查明节点上所使用的容器运行时

无论你是在管理自己的集群还是使用云服务提供商管理的 Kubernetes 服务, 你可能都需要迁移依赖 Docker Engine 的遥测或安全代理

我对 Docker 有依赖。现在该怎么办?

如果你的 Kubernetes 集群对 Docker Engine 有依赖, 并且你打算升级到 Kubernetes v1.24 版本(出于安全和类似原因,你最终应该这样做), 你需要将容器运行时从 Docker Engine 更改为其他方式或使用 cri-dockerd。 由于 containerd 是一个已经毕业的 CNCF 项目, 并且是 Docker 本身的运行时,因此用它作为容器运行时的替代方式是一个安全的选择。 幸运的是,Kubernetes 项目已经以 containerd 为例, 提供了更改节点容器运行时的过程文档。 切换到其它支持的运行时的操作指令与此类似。

我想升级 Kubernetes,并且我需要保持与 Docker 作为运行时的兼容性。我有哪些选择?

别担心,你不会被冷落,也不必冒着安全风险继续使用旧版本的 Kubernetes。 Mirantis 和 Docker 已经联合发布并正在维护 dockershim 的替代品。 这种替代品称为 cri-dockerd。 如果你确实需要保持与 Docker 作为运行时的兼容性,请按照项目文档中的说明安装 cri-dockerd。

这样就可以了吗?

是的。只要你深入了解此版本所做的变更和你自己集群的详细信息, 并确保与你的开发团队进行清晰的沟通,它的不确定性就会降到最低。 你可能需要对集群、应用程序代码或脚本进行一些更改,但所有这些要求都已经有说明指导。 从使用 Docker Engine 作为运行时,切换到使用其他任何一种支持的容器运行时, 这意味着移除了中间层的组件,因为 dockershim 的作用是访问 Docker 本身使用的容器运行时。 从实际角度长远来看,这种移除对你和 Kubernetes 维护者都更有好处。

如果你仍有疑问,请先查看弃用 Dockershim 的常见问题

认识我们的贡献者 - 亚太地区(澳大利亚-新西兰地区)

作者和采访者: Anubhav VardhanAtharva ShindeAvinesh TripathiBrad McCoyDebabrata PanigrahiJayesh SrivastavaKunal VermaPranshu SrivastavaPriyanka SagguPurneswar PrasadVedant Kakde


大家好👋

欢迎来到亚太地区的”认识我们的贡献者”博文系列第二期。

这篇文章将介绍来自澳大利亚和新西兰地区的四位杰出贡献者, 他们在上游 Kubernetes 项目中承担着不同子项目的领导者和社区贡献者的角色。

闲话少说,让我们直接进入主题。

Caleb Woodbine

Caleb Woodbine 目前是 ii.nz 组织的成员。

他于 2018 年作为 Kubernetes Conformance 工作组的成员开始为 Kubernetes 项目做贡献。 他积极向上,他从一位来自新西兰的贡献者 Hippie Hacker 的早期指导中受益匪浅。

他在 SIG k8s-infrak8s-conformance 工作组为 Kubernetes 项目做出了重大贡献。

Caleb 也是 CloudNative NZ 社区活动的联合组织者,该活动旨在扩大 Kubernetes 项目在整个新西兰的影响力,以鼓励科技教育和改善就业机会。

亚太地区需要更多的外联活动,教育工作者和大学必须学习 Kubernetes,因为他们非常缓慢, 而且已经落后了8年多。新西兰倾向于在海外付费,而不是教育当地人最新的云技术。

Dylan Graham

Dylan Graham 是来自澳大利亚 Adeliade 的云计算工程师。自 2018 年以来,他一直在为上游 Kubernetes 项目做出贡献。

他表示,成为如此大项目的一份子,最初压力是比较大的,但社区的友好和开放帮助他度过了难关。

开始在项目文档方面做贡献,现在主要致力于为亚太地区提供社区支持。

他相信,持续参加社区/项目会议,承担项目任务,并在需要时寻求社区指导,可以帮助有抱负的新开发人员成为有效的贡献者。

成为大社区的一份子感觉真的很特别。我遇到了一些了不起的人,甚至是在现实生活中疫情发生之前。

Hippie Hacker

Hippie 来自新西兰,曾在 CNCF.io 作为战略计划承包商工作 5 年多。他是 k8s-infra、 API 一致性测试、云提供商一致性提交以及上游 Kubernetes 和 CNCF 项目 apisnoop.cncf.io 域的积极贡献者。

他讲述了他们早期参与 Kubernetes 项目的情况,该项目始于大约 5 年前,当时他们的公司 ii.nz 演示了使用 PXE 从 Raspberry Pi 启动网络,并在集群中运行Gitlab,以便在服务器上安装 Kubernetes

他描述了自己的贡献经历:一开始,他试图独自完成所有艰巨的任务,但最终看到了团队协作贡献的好处, 分工合作减少了过度疲劳,这让人们能够凭借自己的动力继续前进。

他建议新的贡献者结对编程。

针对一个项目,多人关注和交叉交流往往比单独的评审、批准 PR 能产生更大的效果。

Nick Young

Nick Young 在 VMware 工作,是 CNCF 入口控制器 Contour 的技术负责人。 他从一开始就积极参与上游 Kubernetes 项目,最终成为 LTS 工作组的主席, 他提倡关注用户。他目前是 SIG Network Gateway API 子项目的维护者。

他的贡献之路是引人注目的,因为他很早就在 Kubernetes 项目的主要领域工作,这改变了他的轨迹。

他断言,一个新贡献者能做的最好的事情就是“开始贡献”。当然,如果与他的工作息息相关,那好极了; 然而,把非工作时间投入到贡献中去,从长远来看可以在工作上获得回报。 他认为,应该鼓励新的贡献者,特别是那些目前是 Kubernetes 用户的人,参与到更高层次的项目讨论中来。

只要积极主动,做出贡献,你就可以走很远。一旦你活跃了一段时间,你会发现你能够解答别人的问题, 这意味着会有人请教你或和你讨论,在你意识到这一点之前,你就已经是专家了。


如果你对我们接下来应该采访的人有任何意见/建议,请在 #sig-contribex 中告知我们。 非常感谢你的建议。我们很高兴有更多的人帮助我们接触到社区中更优秀的人。

我们下期再见。祝你有个愉快的贡献之旅!👋

更新:移除 Dockershim 的常见问题

本文是针对 2020 年末发布的弃用 Dockershim 的常见问题的博客更新。 本文包括 Kubernetes v1.24 版本的更新。


本文介绍了一些关于从 Kubernetes 中移除 dockershim 的常见问题。 该移除最初是作为 Kubernetes v1.20 版本的一部分宣布的。 Kubernetes 在 v1.24 版移除了 dockershim。

关于细节请参考博文 别慌: Kubernetes 和 Docker

要确定移除 dockershim 是否会对你或你的组织的影响,可以查阅: 检查弃用 Dockershim 对你的影响 这篇文章。

在 Kubernetes 1.24 发布之前的几个月和几天里,Kubernetes 贡献者努力试图让这个过渡顺利进行。

为什么会从 Kubernetes 中移除 dockershim ?

Kubernetes 的早期版本仅适用于特定的容器运行时:Docker Engine。 后来,Kubernetes 增加了对使用其他容器运行时的支持。创建 CRI 标准是为了实现编排器(如 Kubernetes)和许多不同的容器运行时之间交互操作。 Docker Engine 没有实现(CRI)接口,因此 Kubernetes 项目创建了特殊代码来帮助过渡, 并使 dockershim 代码成为 Kubernetes 的一部分。

dockershim 代码一直是一个临时解决方案(因此得名:shim)。 你可以阅读 Kubernetes 移除 Dockershim 增强方案 以了解相关的社区讨论和计划。 事实上,维护 dockershim 已经成为 Kubernetes 维护者的沉重负担。

此外,在较新的 CRI 运行时中实现了与 dockershim 不兼容的功能,例如 cgroups v2 和用户命名空间。 从 Kubernetes 中移除 dockershim 允许在这些领域进行进一步的开发。

Docker 和容器一样吗?

Docker 普及了 Linux 容器模式,并在开发底层技术方面发挥了重要作用,但是 Linux 中的容器已经存在了很长时间,容器生态系统已经发展到比 Docker 广泛得多。 OCI 和 CRI 等标准帮助许多工具在我们的生态系统中发展壮大,其中一些替代了 Docker 的某些方面,而另一些则增强了现有功能。

我现有的容器镜像是否仍然有效?

是的,从 docker build 生成的镜像将适用于所有 CRI 实现, 现有的所有镜像仍将完全相同。

私有镜像呢?

当然可以,所有 CRI 运行时都支持在 Kubernetes 中使用的相同的 pull secrets 配置,无论是通过 PodSpec 还是 ServiceAccount。

在 Kubernetes 1.23 版本中还可以使用 Docker Engine 吗?

可以使用,在 1.20 版本中唯一的改动是,如果使用 Docker Engine, 在 kubelet 启动时会打印一个警告日志。 你将在 1.23 版本及以前版本看到此警告,dockershim 已在 Kubernetes 1.24 版本中移除 。

如果你运行的是 Kubernetes v1.24 或更高版本,请参阅 我仍然可以使用 Docker Engine 作为我的容器运行时吗? (如果你使用任何支持 dockershim 的版本,可以随时切换离开;从版本 v1.24 开始,因为 Kubernetes 不再包含 dockershim,你必须切换)。

我应该用哪个 CRI 实现?

这是一个复杂的问题,依赖于许多因素。 如果你正在使用 Docker Engine,迁移到 containerd 应该是一个相对容易地转换,并将获得更好的性能和更少的开销。 然而,我们鼓励你探索 CNCF landscape 提供的所有选项,做出更适合你的选择。

我还可以使用 Docker Engine 作为我的容器运行时吗?

首先,如果你在自己的电脑上使用 Docker 用来做开发或测试容器:它将与之前没有任何变化。 无论你为 Kubernetes 集群使用什么容器运行时,你都可以在本地使用 Docker。容器使这种交互成为可能。

Mirantis 和 Docker 已承诺 为 Docker Engine 维护一个替代适配器, 并在 dockershim 从 Kubernetes 移除后维护该适配器。 替代适配器名为 cri-dockerd

你可以安装 cri-dockerd 并使用它将 kubelet 连接到 Docker Engine。 阅读将 Docker Engine 节点从 dockershim 迁移到 cri-dockerd 以了解更多信息。

现在是否有在生产系统中使用其他运行时的例子?

Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。

此外,kind 项目使用 containerd 已经有一段时间了,并且提高了其用例的稳定性。 Kind 和 containerd 每天都会被多次使用来验证对 Kubernetes 代码库的任何更改。 其他相关项目也遵循同样的模式,从而展示了其他容器运行时的稳定性和可用性。 例如,OpenShift 4.x 从 2019 年 6 月以来,就一直在生产环境中使用 CRI-O 运行时。

至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表, 这两个容器运行时是云原生基金会(CNCF)下的项目。

人们总在谈论 OCI,它是什么?

OCI 是 Open Container Initiative 的缩写, 它标准化了容器工具和底层实现之间的大量接口。 它们维护了打包容器镜像(OCI image)和运行时(OCI runtime)的标准规范。 它们还以 runc 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerdCRI-O 依赖的默认运行时。 CRI 建立在这些底层规范之上,为管理容器提供端到端的标准。

当切换 CRI 实现时,应该注意什么?

虽然 Docker 和大多数 CRI(包括 containerd)之间的底层容器化代码是相同的, 但其周边部分却存在差异。迁移时要考虑如下常见事项:

  • 日志配置
  • 运行时的资源限制
  • 调用 docker 或通过其控制套接字使用 Docker Engine 的节点配置脚本
  • 需要 docker 命令或 Docker Engine 控制套接字的 kubectl 插件
  • 需要直接访问 Docker Engine 的 Kubernetes 工具(例如:已弃用的 'kube-imagepuller' 工具)
  • 配置 registry-mirrors 和不安全的镜像仓库等功能
  • 保障 Docker Engine 可用、且运行在 Kubernetes 之外的脚本或守护进程(例如:监视或安全代理)
  • GPU 或特殊硬件,以及它们如何与你的运行时和 Kubernetes 集成

如果你只是用了 Kubernetes 资源请求/限制或基于文件的日志收集 DaemonSet,它们将继续稳定工作, 但是如果你用了自定义了 dockerd 配置,则可能需要为新的容器运行时做一些适配工作。

另外还有一个需要关注的点,那就是当创建镜像时,系统维护或嵌入容器方面的任务将无法工作。 对于前者,可以用 crictl 工具作为临时替代方案 (参阅从 docker cli 到 crictl 的映射)。 对于后者,可以用新的容器创建选项,例如 imgbuildahkanikobuildkit-cli-for-kubectl, 他们都不需要 Docker。

对于 containerd,你可查阅有关它的文档, 获取迁移时可用的配置选项。

有关如何在 Kubernetes 中使用 containerd 和 CRI-O 的说明, 请参阅 Kubernetes 相关文档

我还有其他问题怎么办?

如果你使用了供应商支持的 Kubernetes 发行版,你可以咨询供应商他们产品的升级计划。 对于最终用户的问题,请把问题发到我们的最终用户社区的论坛

你可以通过专用 GitHub 问题 讨论删除 dockershim 的决定。

你也可以看看这篇优秀的博客文章:等等,Docker 被 Kubernetes 弃用了? 对这些变化进行更深入的技术讨论。

是否有任何工具可以帮助我找到正在使用的 dockershim?

是的! Docker Socket 检测器 (DDS) 是一个 kubectl 插件, 你可以安装它用于检查你的集群。 DDS 可以检测运行中的 Kubernetes 工作负载是否将 Docker Engine 套接字 (docker.sock) 作为卷挂载。 在 DDS 项目的 README 中查找更多详细信息和使用方法。

我可以加入吗?

当然,只要你愿意,随时随地欢迎。🤗🤗🤗

SIG Node CI 子项目庆祝测试改进两周年

作者: Sergey Kanzhelev (Google), Elana Hashman (Red Hat)

保证 SIG 节点上游代码的可靠性是一项持续的工作,需要许多贡献者在幕后付出大量努力。 Kubernetes、基础操作系统、容器运行时和测试基础架构的频繁发布,导致了一个复杂的矩阵, 需要关注和稳定的投资来“保持灯火通明”。2020 年 5 月,Kubernetes Node 特殊兴趣小组 (“SIG Node”)为节点相关代码和测试组织了一个新的持续集成(CI)子项目。自成立以来,SIG Node CI 子项目每周举行一次会议,即使一整个小时通常也不足以完成对所有缺陷、测试相关的 PR 和问题的分类, 并讨论组内所有相关的正在进行的工作。

在过去两年中,我们修复了阻塞合并和阻塞发布的测试,由于减少了测试缺陷,缩短了合并 Kubernetes 贡献者的拉取请求的时间。通过我们的努力,任务通过率由开始时 42% 提高至稳定大于 90% 。我们已经解决了 144 个测试失败问题, 并在 kubernetes/kubernetes 中合并了 176 个拉取请求。 我们还帮助子项目参与者提升了 Kubernetes 贡献者的等级,新增了 3 名组织成员、6 名评审员和 2 名审批员。

Node CI 子项目是一个可入门的第一站,帮助新参与者开始使用 SIG Node。对于新贡献者来说, 解决影响较大的缺陷和测试修复的门槛很低,尽管贡献者要攀登整个贡献者阶梯还有很长的路要走: 为该团队培养了两个新的审批人花了一年多的时间。为 Kubernetes 节点及其测试基础设施提供动力的所有 不同组件的复杂性要求开发人员在很长一段时间内进行持续投资, 以深入了解整个系统,从宏观到微观。

虽然在我们的会议上有几个比较固定的贡献者;但是我们的评审员和审批员仍然很少。 我们的目标是继续增加贡献者,以确保工作的可持续分配,而不仅仅是少数关键批准者。

SIG 中的子项目如何形成、运行和工作并不总是显而易见的。每一个都是其背后的 SIG 所独有的, 并根据该小组打算支持的项目量身定制。作为一个欢迎了许多第一次 SIG Node 贡献者的团队, 我们想分享过去两年的一些细节和成就,帮助揭开我们内部工作的神秘面纱,并庆祝我们所有专注贡献者的辛勤工作!

时间线

2020 年 5 月 SIG Node CI 组于 2020 年 5 月 11 日成立,超过 30 名志愿者 注册,以改进 SIG Node CI 信号和整体可观测性。 Victor Pickard 专注于让 testgrid 可以运行 , 当时 Ning Liao 建议围绕这项工作组建一个小组,并提出 最初的小组章程文件 。 SIG Node 赞助成立以 Victor 作为子项目负责人的小组。Sergey Kanzhelev 不久后就加入 Victor,担任联合领导人。

在启动会议上,我们讨论了应该首先集中精力修复哪些测试,并讨论了阻塞合并和阻塞发布的测试, 其中许多测试由于基础设施问题或错误的测试代码而失败。

该子项目每周召开一小时的会议,讨论正在进行的工作会谈和分类。

2020 年 6 月 Morgan Bauer 、 Karan Goel 和 Jorge Alarcon Ochoa 因其贡献而被公认为 SIG Node CI 小组的评审员,为该子项目的早期阶段提供了重要帮助。 David Porter 和 Roy Yang 也加入了 SIG 检测失败的 GitHub 测试团队。

2020 年 8 月 所有的阻塞合并和阻塞发布的测试都通过了,伴有一些逻辑问题。 然而,只有 42% 的 SIG Node 测试作业是绿色的, 因为有许多逻辑错误和失败的测试。

2020 年 10 月 Amim Knabben 因对子项目的贡献成为 Kubernetes 组织成员。

2021 年 1 月 随着健全的预提交和关键定期工作的通过,子项目讨论了清理其余定期测试并确保其顺利通过的目标。

Elana Hashman 加入了这个子项目,在 Victor 离开后帮助领导该项目。

2021 年 2 月 Artyom Lukianov 因其对子项目的贡献成为 Kubernetes 组织成员。

2021 年 8 月 在 SIG Node 成功运行 bug scrub 以清理其累积的缺陷之后,会议的范围扩大到包括缺陷分类以提高整体可靠性, 在问题影响 CI 信号之前预测问题。

子项目负责人 Elana Hashman 和 Sergey Kanzhelev 都被认为是所有节点测试代码的审批人,由 SIG node 和 SIG Testing 支持。

2021 年 9 月 在 Francesco Romani 牵头的 1.22 版本系列测试取得重大进展后, 该子项目设定了一个目标,即在 1.23 发布日期之前让串行任务完全通过。

Mike Miranda 因其对子项目的贡献成为 Kubernetes 组织成员。

2021 年 11 月 在整个 2021 年, SIG Node 没有合并或发布的测试失败。 过去版本中的许多古怪测试都已从阻止发布的仪表板中删除,因为它们已被完全清理。

Danielle Lancashire 被公认为 SIG Node 子组测试代码的评审员。

最终节点系列测试已完全修复。系列测试由许多中断性和缓慢的测试组成,这些测试往往是碎片化的,很难排除故障。 到 1.23 版本冻结时,最后一次系列测试已修复,作业顺利通过。

宣布系列测试为绿色

1.23 版本在测试质量和 CI 信号方面得到了特别的关注。SIG Node CI 子项目很自豪能够为这样一个高质量的发布做出贡献, 部分原因是我们在识别和修复节点内外的碎片方面所做的努力。

Slack 大声宣布发布的版本大多是绿色的

2021 年 12 月 在 1.23 版本发布时,估计有 90% 的测试工作通过了测试(2020 年 8 月为 42%)。

Dockershim 代码已从 Kubernetes 中删除。这影响了 SIG Node 近一半的测试作业, SIG Node CI 子项目反应迅速,并重新确定了所有测试的目标。 SIG Node 是第一个完成 dockershim 外测试迁移的 SIG ,为其他受影响的 SIG 提供了示例。 绝大多数新工作在引入时都已通过,无需进一步修复。 从 Kubernetes 中将 dockershim 除名的工作 正在进行中。 随着我们发现 dockershim 对 dockershim 的依赖性越来越大,dockershim 的删除仍然存在一些问题, 但我们计划在 1.24 版本之前确保所有测试任务稳定。

统计数据

我们过去几个月的定期会议与会者和子项目参与者:

  • Aditi Sharma
  • Artyom Lukianov
  • Arnaud Meukam
  • Danielle Lancashire
  • David Porter
  • Davanum Srinivas
  • Elana Hashman
  • Francesco Romani
  • Matthias Bertschy
  • Mike Miranda
  • Paco Xu
  • Peter Hunt
  • Ruiwen Zhao
  • Ryan Phillips
  • Sergey Kanzhelev
  • Skyler Clark
  • Swati Sehgal
  • Wenjun Wu

kubernetes/test-infra 源代码存储库包含测试定义。该存储库中的节点 PR 数:

  • 2020 年 PR(自 5 月起):183
  • 2021 年 PR:264

CI 委员会上的问题和 PRs 分类(包括子组范围之外的分类):

  • 2020 年(自 5 月起):132
  • 2021 年:532

未来

只是“保持灯亮”是一项大胆的任务,我们致力于改善这种体验。 我们正在努力简化 SIG Node 的分类和审查流程。

具体来说,我们正在致力于更好的测试组织、命名和跟踪:

我们还在改进测试的可调试性和去剥落方面不断取得进展。

如果你对此感兴趣,我们很乐意您能加入我们! 在调试测试失败中有很多东西需要学习,它将帮助你熟悉 SIG Node 维护的代码。

你可以在 SIG Node 页面上找到有关该组的信息。 我们在我们的维护者轨道会议上提供组更新,例如: KubeCon + CloudNativeCon Europe 2021KubeCon + CloudNative North America 2021。 加入我们的使命,保持 kubelet 和其他 SIG Node 组件的可靠性,确保顺顺利利发布!

关注 SIG Multicluster

作者: Dewan Ahmed (Aiven) 和 Chris Short (AWS)

简介

SIG Multicluster 是专注于如何拓展 Kubernetes 的概念并将其用于集群边界之外的 SIG。 以往 Kubernetes 资源仅在 Kubernetes Resource Universe (KRU) 这个边界内进行交互,其中 KRU 不是一个实际的 Kubernetes 概念。 即使是现在,Kubernetes 集群对自身或其他集群并不真正了解。集群标识符的缺失就是一个例子。 随着多云和多集群部署日益普及,SIG Multicluster 所做的工作越来越受到关注。 在这篇博客中,来自 Google 的 Jeremy Olmsted-Thompson来自 AWS 的 Chris Short 讨论了 SIG Multicluster 正在解决的一些有趣的问题和以及大家如何参与其中。 为简洁起见,下文将使用他们两位的首字母 JOTCS

谈话总结

CS:SIG Multicluster 存在多久了?SIG 在起步阶段情况如何?你参与这个 SIG 多长时间了?

JOT:我在 SIG Multicluster 工作了将近两年。我所知道的关于初创时期的情况都来自传说,但即使在早期,也一直是为了解决相同的问题。 早期工作的例子之一是 KubeFed。 我认为仍然有一些人在使用 KubeFed,但它只是一小部分。 那时,我认为人们在部署大量 Kubernetes 集群时,还没有达到我们拥有大量实际具体用例的地步。 像 KubeFed 和 Cluster Registry 这样的项目就是在那个时候开发的,当时的需求可以与这些项目相关联。 这些项目的动机是如何解决我们认为在开始扩展到多个集群时 会遇到的问题。 老实说,在某些方面,当时它试图做得太多了。

CS:KubeFed 与 SIG Multicluster 的现状有何不同?初创期现在 有何不同?

JOT:嗯嗯,这就像总是要预防潜在问题而不是解决眼前具体的问题。我认为在 2019 年底, SIG Multicluster 工作有所放缓,我们通过最近最活跃的项目之一 SIG Multicluster services (MCS) 将其重新拾起。

现在我们向解决实际的具体问题开始转变。比如说。

我的工作负载分布在多个集群中,我需要它们相互通信。

好吧,这是非常直接的,我们也知道需要解决这个问题。 首先,让我们确保这些项目可以在一个通用的 API 上协同工作,这样你就可以获得与 Kubernetes 相同的可移植性。

目前有一些 MCS API 的实现,并且更多的实现正在开发中。但是,我们没有建立一个实现, 因为取决于你的部署方式不同,可能会有数百种实现。 只要你所需要的基本的多集群服务功能,它就可以在你想要的任何背景下工作,无论是 Submariner、GKE 还是服务网格。

我最喜欢的“过去与现在“的例子是集群 ID。几年前曾经有过定义集群 ID 的尝试。 针对这个概念,有很多非常好的想法。例如,我们如何使集群 ID 在多个集群中是唯一的。 我们如何使这个 ID 全球范围内唯一,以便它在各个通讯中发挥作用? 假设有团队被收购或合并 - 集群 ID 对于这些团队仍然是唯一的吗?

在 Multicluster 服务的相关工作中,我们发现需要一个实际的集群 ID,并且这一需求非常具体。 为了满足这一特定需求,我们不再考虑一个个 Kubernetes 集群,而是考虑 ClusterSets — 在某种范围内协同工作的集群分组。 与考虑所有时间点和所有空间位置上存在的集群相比,这一范畴要窄得多。 这一概念还让实现者具备了定义边界(ClusterSet)的灵活性,在该边界之外,该集群 ID 将不再是唯一的。

CS:你对 SIG Multicluster 的现状有何看法,你希望未来达到什么样的目标?

JOT:有一些项目正在起步,例如 Work API。 在未来,我认为围绕着如何跨集群部署应用的一些共同做法将会发展起来。

如果我的集群部署在不同的地区,那么最好的方式是什么?

答案几乎总是“视情况而定”。你为什么要这样做?是因为某种合规性使你关注位置吗?是性能问题吗?是可用性吗?

我认为,在我们有了集群 ID 之后,重新审视注册表模式可能是很自然的一步,也就是说, 你如何将这些集群真正关联在一起?也许你有一个分布式部署,你在世界各地的数据中心运行。 我想随着多集群特性的进一步开发,扩展该领域的 API 将变得很重要。 这实际上取决于社区开始使用这些工具做什么。

CS:在 Kubernetes 的早期,我们只有寥寥几个大型的 Kubernetes 集群,而现在我们面对的是大量的小型 Kubernetes 集群,就像我自己所在的开发环境中就使用了多个集群。 这种从几个大集群到许多小集群的转变对 SIG 有何影响?它是否加快了工作进度或在某种程度上使得问题变得更困难?

JOT:我认为它带来了很多需要解决的歧义。最初,你可能拥有一个 dev 集群、一个 staging 集群和一个 prod 集群。 当引入了多区域的考量时,我们开始在每个区域部署 dev/staging/prod 集群。 再后来,有时由于合规性或某些法规问题,集群确实需要更多的隔离。 因此,我们最终会有很多集群。我认为在你究竟应该有多少个集群上找到平衡是很重要的。Kubernetes 的强大之处在于能够部署由单个控制平面管理的大量事物。 因此,并不是每个被部署的工作负载都应该在自己的集群中。 但是,我认为同样很明显的是,我们不能将所有工作负载都放在一个集群中。

CS:你最喜欢 SIG 的哪些方面?

JOT:问题的复杂性、人的因素和领域的新颖性。我们还没有正确的答案,我们必须找到正确的答案。 一开始,我们甚至无法考虑多集群,因为无法跨集群连接服务。 现在我们开始着手解决这些问题,我认为这是一个非常有趣的地方,因为我预计 SIG 在未来几年会变得更加繁忙。 这是一个协作很密切的团体,我们绝对希望更多的人参与、加入我们,提出他们的问题和想法。

CS:你认为是什么让人们留在这个群体中?疫情对你有何影响?

JOT:我认为在疫情期间这个群体肯定会变得安静一些。但在大多数情况下,这是一个非常分散的小组, 因此无论你在会议室或者在家中参加我们的每周会议,都不会产生太大的影响。在疫情期间,很多人有时间专注于他们接下来的规模和增长。 我认为这就是让人们留在团队中的原因 - 我们有真正的问题需要解决,这些问题在这个领域是非常新颖的、有趣的。

结束语

CS:这就是我们今天的全部内容,感谢 Jeremy 的时间。

JOT:谢谢 Chris。我们的双周会议 欢迎所有人参加。我们希望尽可能多的人前来,并欢迎所有问题与想法。 这是一个新的领域,如果能让社区发展起来,那就太好了。

确保准入控制器的安全

作者: Rory McCune (Aqua Security)

准入控制和认证、授权都是 Kubernetes 安全性的关键部分。 Webhook 准入控制器被广泛用于以多种方式帮助提高 Kubernetes 集群的安全性, 包括限制工作负载权限和确保部署到集群的镜像满足组织安全要求。

然而,与添加到集群中的任何其他组件一样,安全风险也会随之出现。 一个安全风险示例是没有正确处理准入控制器的部署和管理。 为了帮助准入控制器用户和设计人员适当地管理这些风险, SIG Security 的安全文档小组 花费了一些时间来开发一个准入控制器威胁模型。 这种威胁模型着眼于由于不正确使用准入控制器而产生的可能的风险,可能允许绕过安全策略,甚至允许攻击者未经授权访问集群。

基于这个威胁模型,我们开发了一套安全最佳实践。 你应该采用这些实践来确保集群操作员可以获得准入控制器带来的安全优势,同时避免使用它们带来的任何风险。

准入控制器和安全的良好做法

基于这个威胁模型,围绕着如何确保准入控制器的安全性出现了几个主题。

安全的 webhook 配置

确保集群中的任何安全组件都配置良好是很重要的,在这里准入控制器也并不例外。 使用准入控制器时需要考虑几个安全最佳实践:

  • 为所有 webhook 流量正确配置了 TLS。 API 服务器和准入控制器 webhook 之间的通信应该经过身份验证和加密,以确保处于网络中查看或修改此流量的攻击者无法查看或修改。 要实现此访问,API 服务器和 webhook 必须使用来自受信任的证书颁发机构的证书,以便它们可以验证相互的身份。
  • 只允许经过身份验证的访问。 如果攻击者可以向准入控制器发送大量请求,他们可能会压垮服务导致其失败。 确保所有访问都需要强身份验证可以降低这种风险。
  • 准入控制器关闭失败。 这是一种需要权衡的安全实践,集群操作员是否要对其进行配置取决于集群的威胁模型。 如果一个准入控制器关闭失败,当 API 服务器无法从它得到响应时,所有的部署都会失败。 这可以阻止攻击者通过禁用准入控制器绕过准入控制器,但可能会破坏集群的运行。 由于集群可以有多个 webhook,因此一种折中的方法是对关键控制允许故障关闭, 并允许不太关键的控制进行故障打开。
  • 定期审查 webhook 配置。 配置错误可能导致安全问题,因此检查准入控制器 webhook 配置以确保设置正确非常重要。 这种审查可以由基础设施即代码扫描程序自动完成,也可以由管理员手动完成。

为准入控制保护集群配置

在大多数情况下,集群使用的准入控制器 webhook 将作为工作负载安装在集群中。 因此,确保正确配置了可能影响其操作的 Kubernetes 安全特性非常重要。

  • 限制 RBAC 权限。 任何有权修改 webhook 对象的配置或准入控制器使用的工作负载的用户都可以破坏其运行。 因此,确保只有集群管理员拥有这些权限非常重要。
  • 防止特权工作负载。 容器系统的一个现实是,如果工作负载被赋予某些特权, 则有可能逃逸到下层的集群节点并影响该节点上的其他容器。 如果准入控制器服务在它们所保护的集群上运行, 一定要确保对特权工作负载的所有请求都要经过仔细审查并尽可能地加以限制。
  • 严格控制外部系统访问。 作为集群中的安全服务,准入控制器系统将有权访问敏感信息,如凭证。 为了降低此信息被发送到集群外的风险, 应使用网络策略 来限制准入控制器服务对外部网络的访问。
  • 每个集群都有一个专用的 webhook。 虽然可能让准入控制器 webhook 服务于多个集群的, 但在使用该模型时存在对 webhook 服务的攻击会对共享它的地方产生更大影响的风险。 此外,在多个集群使用准入控制器的情况下,复杂性和访问要求也会增加,从而更难保护其安全。

准入控制器规则

对于用于 Kubernetes 安全的所有准入控制器而言,一个关键元素是它使用的规则库。 规则需要能够准确地满足其目标,避免假阳性和假阴性结果。

  • 定期测试和审查规则。 需要测试准入控制器规则以确保其准确性。 还需要定期审查,因为 Kubernetes API 会随着每个新版本而改变, 并且需要在每个 Kubernetes 版本中评估规则,以了解使他们保持最新版本所需要做的任何改变。

认识我们的贡献者 - 亚太地区(印度地区)

作者和采访者: Anubhav VardhanAtharva ShindeAvinesh TripathiDebabrata PanigrahiKunal VermaPranshu SrivastavaPritish SamalPurneswar PrasadVedant Kakde

编辑: Priyanka Saggu


大家好 👋

欢迎来到亚太地区的“认识我们的贡献者”博文系列第一期。

在这篇文章中,我们将向你介绍来自印度地区的五位优秀贡献者,他们一直在以各种方式积极地为上游 Kubernetes 项目做贡献,同时也是众多社区倡议的领导者和维护者。

💫 闲话少说,我们开始吧。

Arsh Sharma

Arsh 目前在 Okteto 公司中担任开发者体验工程师职务。作为一名新的贡献者,他意识到一对一的指导机会让他在开始上游项目中受益匪浅。

他目前是 Kubernetes 1.23 版本团队的 CI Signal 经理。他还致力于为 SIG Testing 和 SIG Docs 项目提供贡献,并且在 SIG Architecture 项目中负责 证书管理器 工具的开发工作。

对于新人来说,Arsh 帮助他们可持续地计划早期贡献。

我鼓励大家以可持续的方式为社区做贡献。 我的意思是,一个人很容易在早期的时候非常有热情,并且承担了很多超出个人实际能力的事情。 这通常会导致后期的倦怠。迭代地处理事情会让大家对社区的贡献变得可持续。

Kunal Kushwaha

Kunal Kushwaha 是 Kubernetes 营销委员会的核心成员。他同时也是 CNCF 学生计划 的创始人之一。他还在 1.22 版本周期中担任通信经理一职。

在他的第一年结束时,Kunal 开始为 fabric8io kubernetes-client 项目做贡献。然后,他被推选从事同一项目,此项目是 Google Summer of Code 的一部分。Kunal 在 Google Summer of Code、Google Code-in 等项目中指导过很多人。

作为一名开源爱好者,他坚信,社区的多元化参与是非常有益的,因为他引入了新的观念和观点,并尊重自己的伙伴。它曾参与过各种开源项目,他在这些社区中的参与对他作为开发者的发展有很大帮助。

我相信,如果你发现自己在一个了解不多的项目当中,那是件好事, 因为现在你可以一边贡献一边学习,社区也会帮助你。 它帮助我获得了很多技能,认识了来自世界各地的人,也帮助了他们。 你可以在这个过程中学习,自己不一定必须是专家。 请重视非代码贡献,因为作为初学者这是一项技能,你可以为组织带来新的视角。

Madhav Jivarajani

Madhav Jivarajani 在 VMware 上游 Kubernetes 稳定性团队工作。他于 2021 年 1 月开始为 Kubernetes 项目做贡献,此后在 SIG Architecture、SIG API Machinery 和 SIG ContribEx(贡献者经验)等项目的几个工作领域做出了重大贡献。

在这几个重要项目中,他最近致力于设计方案的存档工作, 重构 k8s-infra 存储库下的 "组"代码库, 使其具有可模拟性和可测试性,以及改进 GitHub k8s 机器人的功能。

除了在技术方面的贡献,Madhav 还监督许多旨在帮助新贡献者的项目。 他每两周组织一次的 “KEP 阅读俱乐部” 会议,帮助新人了解添加新功能、 摒弃旧功能以及对上游项目进行其他关键更改的过程。他还致力于开发 Katacoda 场景, 以帮助新的贡献者在为 k/k 做贡献的过程更加熟练。目前除了每周与社区成员会面外, 他还组织了几个新贡献者讲习班(NCW)

一开始我对 Kubernetes 了解并不多。我加入社区是因为社区超级友好。 但让我留下来的不仅仅是人,还有项目本身。我在社区中不会感到不知所措, 这是因为我能够在感兴趣的和正在讨论的主题中获得尽可能多的背景和知识。 因此,我将继续深入探讨 Kubernetes 及其设计。 我是一个系统迷,kubernetes 对我来说绝对是一个金矿。

Rajas Kakodkar

Rajas Kakodkar 目前在 VMware 担任技术人员。自 2019 年以来,他一直多方面地从事上游 kubernetes 项目。

他现在是 Testing 特别兴趣小组的关键贡献者。他还活跃在 SIG Network 社区。最近,Rajas 为 NetworkPolicy++kpng 子项目做出了重大贡献。

他遇到的第一个挑战是,他所处的时区与上游项目的日常会议时间不同。不过,社区论坛上的异步交互逐渐解决了这个问题。

我喜欢为 kubernetes 做出贡献,不仅因为我可以从事尖端技术工作, 更重要的是,我可以和优秀的人一起工作,并帮助解决现实问题。

Rajula Vineet Reddy

Rajula Vineet Reddy,CERN 的初级工程师,是 SIG ContribEx 项目下营销委员会的成员。在 Kubernetes 1.22 和 1.23 版本周期中,他还担任 SIG Release 的版本经理。

在他的一位教授的帮助下,他开始将 kubernetes 项目作为大学项目的一部分。慢慢地,他花费了大量的时间阅读项目的文档、Slack 讨论、GitHub issues 和博客,这有助于他更好地掌握 kubernetes 项目,并激发了他对上游项目做贡献的兴趣。他的主要贡献之一是他在SIG ContribEx上游营销子项目中协助实现了自动化。

Rajas 说,参与项目会议和跟踪各种项目角色对于了解社区至关重要。

我发现社区非常有帮助,而且总是“你得到的回报和你贡献的一样多”。 你参与得越多,你就越会了解、学习和贡献新东西。

“挺身而出”的第一步是艰难的。但在那之后一切都会顺利的。勇敢地参与进来吧。


如果你对我们下一步应该采访谁有任何意见/建议,请在 #sig-contribex 中告知我们。我们很高兴有其他人帮助我们接触社区中更优秀的人。我们将不胜感激。

我们下期见。最后,祝大家都能快乐地为社区做贡献!👋

Kubernetes 即将移除 Dockershim:承诺和下一步

作者: Sergey Kanzhelev (Google), Jim Angel (Google), Davanum Srinivas (VMware), Shannon Kularathna (Google), Chris Short (AWS), Dawn Chen (Google)

Kubernetes 将在即将发布的 1.24 版本中移除 dockershim。我们很高兴能够通过支持开源容器运行时、支持更小的 kubelet 以及为使用 Kubernetes 的团队提高工程速度来重申我们的社区价值。 如果你使用 Docker Engine 作为 Kubernetes 集群的容器运行时, 请准备好在 1.24 中迁移!要检查你是否受到影响, 请参考检查移除 Dockershim 对你的影响

为什么我们要离开 dockershim

Docker 是 Kubernetes 使用的第一个容器运行时。 这也是许多 Kubernetes 用户和爱好者如此熟悉 Docker 的原因之一。 对 Docker 的支持被硬编码到 Kubernetes 中——一个被项目称为 dockershim 的组件。

随着容器化成为行业标准,Kubernetes 项目增加了对其他运行时的支持。 最终实现了容器运行时接口(CRI),让系统组件(如 kubelet)以标准化的方式与容器运行时通信。 因此,dockershim 成为了 Kubernetes 项目中的一个异常现象。

对 Docker 和 dockershim 的依赖已经渗透到 CNCF 生态系统中的各种工具和项目中,这导致了代码脆弱。

通过删除 dockershim CRI,我们拥抱了 CNCF 的第一个价值: “快比慢好”。 请继续关注未来关于这个话题的交流!

弃用时间线

我们正式宣布于 2020 年 12 月弃用 dockershim。目标是在 2022 年 4 月, Kubernetes 1.24 中完全移除 dockershim。 此时间线与我们的弃用策略一致, 即规定已弃用的行为必须在其宣布弃用后至少运行 1 年。

包括 dockershim 的 Kubernetes 1.23 版本,在 Kubernetes 项目中将再支持一年。 对于托管 Kubernetes 的供应商,供应商支持可能会持续更长时间,但这取决于公司本身。 无论如何,我们相信所有集群操作都有时间进行迁移。如果你有更多关于 dockershim 移除的问题, 请参考弃用 Dockershim 的常见问题

在这个你是否为 dockershim 的删除做好了准备的调查中, 我们询问你是否为 dockershim 的迁移做好了准备。我们收到了 600 多个回复。 感谢所有花时间填写调查问卷的人。

结果表明,在帮助你顺利迁移方面,我们还有很多工作要做。 存在其他容器运行时,并且已被广泛推广。但是,许多用户告诉我们他们仍然依赖 dockershim, 并且有时需要重新处理依赖项。其中一些依赖项超出控制范围。 根据收集到的反馈,我们采取了一些措施提供帮助。

我们的下一个步骤

根据提供的反馈:

  • CNCF 和 1.24 版本团队致力于及时交付 1.24 版本的文档。这包括像本文这样的包含更多信息的博客文章, 更新现有的代码示例、教程和任务,并为集群操作人员生成迁移指南。
  • 我们正在联系 CNCF 社区的其他成员,帮助他们为这一变化做好准备。

如果你是依赖 dockershim 的项目的一部分,或者如果你有兴趣帮助参与迁移工作,请加入我们! 无论是我们的迁移工具还是我们的文档,总是有更多贡献者的空间。 作为起步,请在 Kubernetes Slack 上的 #sig-node 频道打个招呼!

最终想法

作为一个项目,我们已经看到集群运营商在 2021 年之前越来越多地采用其他容器运行时。 我们相信迁移没有主要障碍。我们为改善迁移体验而采取的步骤将为你指明更清晰的道路。

我们知道,从 dockershim 迁移是你可能需要执行的另一项操作,以保证你的 Kubernetes 基础架构保持最新。 对于你们中的大多数人来说,这一步将是简单明了的。在某些情况下,你会遇到问题。 社区已经详细讨论了推迟 dockershim 删除是否会有所帮助。 例如,我们最近在 11 月 11 日的 SIG Node 讨论12 月 6 日 Kubernetes Steering 举行的委员会会议谈到了它。 我们已经在 2021 年推迟它一次, 因为其他运行时的采用率低于我们的预期,这也给了我们更多的时间来识别潜在的阻塞问题。

在这一点上,我们相信你(和 Kubernetes)从移除 dockershim 中获得的价值可以弥补你将要进行的迁移工作。 现在就开始计划以避免出现意外。在 Kubernetes 1.24 发布之前,我们将提供更多更新信息和指南。

Security Profiles Operator v0.4.0 中的新功能

作者: Jakub Hrozek, Juan Antonio Osorio, Paulo Gomes, Sascha Grunert


Security Profiles Operator (SPO) 是一种树外 Kubernetes 增强功能,用于更方便、更便捷地管理 seccompSELinuxAppArmor 配置文件。 我们很高兴地宣布,我们最近发布了 v0.4.0 的 Operator,其中包含了大量的新功能、缺陷修复和可用性改进。

有哪些新特性

距离上次的 v0.3.0 的发布已经有一段时间了。在过去的半年里,我们增加了新的功能,对现有的功能进行了微调, 并且在过去的半年里,我们通过 290 个提交重新编写了文档。

亮点之一是我们现在能够使用 Operator 的日志增强组件 记录 seccomp 和 SELinux 的配置文件。 这使我们能够减少配置文件记录所需的依赖事项,使得仅剩的依赖变为在节点上运行 auditdsyslog(作为一种回退机制)。 通过使用 ProfileRecording CRD 及其对应的标签选择算符, Operator 中的所有配置文件记录都以相同的方式工作。 日志增强组件本身也可用于获得有关节点上的 seccomp 和 SELinux 消息的有意义的洞察。 查看官方文档 了解更多信息。

与 seccomp 有关的改进

除了基于日志丰富器的记录之外,我们现在还使用 ebpf 作为记录 seccomp 配置文件的一种替代方法。可以通过将 enableBpfRecorder 设置为 true 来启用此可选功能。 启用之后会导致一个专用的容器被启动运行;该容器在每个节点上提供一个自定义 bpf 模块以收集容器的系统调用。 它甚至支持默认不公开 BPF 类型格式 (BTF) 的旧内核版本以及 amd64 arm64 架构。查看 我们的文档 以查看它的实际效果。顺便说一句,我们现在也将记录器主机的 seccomp 配置文件体系结构添加到记录的配置文件中。

我们还将 seccomp 配置文件 API 从 v1alpha1 升级到 v1beta1。 这符合我们随着时间的推移稳定 CRD API 的总体目标。 唯一改变的是 seccomp 配置文件类型 Architectures 现在指向 []Arch 而不是 []*Arch

SELinux 增强功能

管理 SELinux 策略(相当于使用通常在单个服务器上调用的 semodule )不是由 SPO 本身完成的, 而是由另一个名为 selinuxd 的容器完成,以提供更好的隔离。此版本将所使用的 selinuxd 容器镜像从个人仓库迁移到位于我们团队的 quay.io 仓库下的镜像。 selinuxd 仓库也已移至GitHub 组织 containers

请注意,selinuxd 动态链接到 libsemanage 并挂载节点上的 SELinux 目录, 这意味着 selinuxd 容器必须与集群节点运行相同的发行版。SPO 默认使用基于 CentOS-8 的容器, 但我们也构建基于 Fedora 的容器。如果你使用其他发行版并希望我们添加对它的支持, 请针对 selinuxd 提交 issue

配置文件记录

此版本(0.4.0)增加了记录 SELinux 配置文件的支持。记录本身是通过 ProfileRecording 自定义资源的实例管理的, 如我们仓库中的示例 所示。从用户的角度来看,它的工作原理与记录 seccomp 配置文件几乎相同。

在后台,为了知道工作负载在做什么,SPO 安装了一个名为 selinuxrecording 的、限制宽松的策略,允许执行所有操作并将所有 AVC 记录到 audit.log 中。 这些 AVC 消息由日志增强组件抓取,当所记录的工作负载退出时,该策略被创建。

SELinuxProfile CRD 毕业

我们引入了 SelinuxProfile 对象的 v1alpha2 版本。 这个版本从对象中删除了原始的通用中间语言 (CIL),并添加了一种简单的策略语言来简化编写和解析体验。

此外,我们还引入了 RawSelinuxProfile 对象。该对象包含策略的包装和原始表示。 引入此对象是为了让人们能够尽快将他们现有的策略付诸实现。但是,策略的验证是在这里完成的。

AppArmor 支持

0.4.0 版本引入了对 AppArmor 的初始支持,允许用户通过使用新的 AppArmorProfile 在集群节点中 CRD 加载或卸载 AppArmor 配置文件。

要启用 AppArmor 支持,请使用 SPO 配置的 enableAppArmor 特性门控开关。 然后使用我们的 apparmor 示例 在集群中部署你第一个配置文件。

指标

Operator 现在能够公开在我们的新指标文档中详细描述的指标。 我们决定使用 kube-rbac-proxy 来保护指标检索过程, 同时我们提供了一个额外的 spo-metrics-client 集群角色(和绑定)以从集群内检索指标。 如果你使用 OpenShift, 那么我们提供了一个开箱即用的 ServiceMonitor 来访问指标。

可调试性和稳健性

除了所有这些新功能外,我们还决定在内部重组安全配置文件操作程序的部分内容,使其更易于调试和更稳健。 例如,我们现在维护了一个内部 gRPC API,以便在 Operator 内部跨不同功能组件进行通信。 我们还提高了日志增强组件的性能,现在它可以缓存结果,以便更快地检索日志数据。 Operator 可以通过将 verbosity 设置从 0 改为 1,启用更详细的日志模式(https://github.com/kubernetes-sigs/security-profiles-operator/blob/71b3915/installation-usage.md#set-logging-verbosity)。

我们还在启动时打印所使用的 libseccomplibbpf 版本, 并通过 enableProfiling 选项 公开每个容器的 CPU 和内存性能分析端点。 Operator 守护程序内部的专用的存活态探测和启动探测现在能进一步改善 Operator 的生命周期管理。

总结

感谢你阅读这次更新。我们期待着 Operater 的未来改进,并希望得到你对最新版本的反馈。 欢迎通过 Kubernetes slack #security-profiles-operator 与我们联系,提出任何反馈或问题。

Kubernetes 1.23: StatefulSet PVC 自动删除 (alpha)

作者: Matthew Cary (谷歌)

Kubernetes v1.23 为 StatefulSets 引入了一个新的 alpha 级策略,用来控制由 StatefulSet 规约模板生成的 PersistentVolumeClaims (PVCs) 的生命周期, 用于当删除 StatefulSet 或减少 StatefulSet 中的 Pods 数量时 PVCs 应该被自动删除的场景。

它解决了什么问题?

StatefulSet 规约中可以包含 Pod 和 PVC 的模板。当副本先被创建时,如果 PVC 还不存在, Kubernetes 控制面会为该副本自动创建一个 PVC。在 Kubernetes 1.23 版本之前, 控制面不会删除 StatefulSet 创建的 PVCs——这依赖集群管理员或你需要部署一些额外的适用的自动化工具来处理。 管理 PVC 的常见模式是通过手动或使用 Helm 等工具,PVC 的具体生命周期由管理它的工具跟踪。 使用 StatefulSet 时必须自行确定 StatefulSet 创建哪些 PVC,以及它们的生命周期应该是什么。

在这个新特性之前,当一个 StatefulSet 管理的副本消失时,无论是因为 StatefulSet 减少了它的副本数, 还是因为它的 StatefulSet 被删除了,PVC 及其下层的卷仍然存在,需要手动删除。 当存储数据比较重要时,这样做是合理的,但在许多情况下,这些 PVC 中的持久化数据要么是临时的, 要么可以从另一个源端重建。在这些情况下,删除 StatefulSet 或减少副本后留下的 PVC 及其下层的卷是不必要的, 还会产生成本,需要手动清理。

新的 StatefulSet PVC 保留策略

如果你启用这个新 alpha 特性,StatefulSet 规约中就可以包含 PersistentVolumeClaim 的保留策略。 该策略用于控制是否以及何时删除基于 StatefulSet 的 volumeClaimTemplate 属性所创建的 PVCs。 保留策略的首次迭代包含两种可能删除 PVC 的情况。

第一种情况是 StatefulSet 资源被删除时(这意味着所有副本也被删除),这由 whenDeleted 策略控制的。 第二种情况是 StatefulSet 缩小时,即删除 StatefulSet 部分副本,这由 whenScaled 策略控制。 在这两种情况下,策略即可以是 Retain 不涉及相应 PVCs 的改变,也可以是 Delete 即删除对应的 PVCs。 删除是通过普通的对象删除完成的, 因此,的所有保留策略都会被遵照执行。

该策略形成包含四种情况的矩阵。我将逐一介绍,并为每一种情况给出一个例子。

  • whenDeletedwhenScaled 都是 Retain 这与 StatefulSets 的现有行为一致, 即不删除 PVCs。 这也是默认的保留策略。它适用于 StatefulSet 卷上的数据是不可替代的且只能手动删除的情况。
  • whenDeletedDeletewhenScaledRetain 在这种情况下, 只有当整个 StatefulSet 被删除时,PVCs 才会被删除。 如果减少 StatefulSet 副本,PVCs 不会删除,这意味着如果增加副本时,可以从前一个副本重新连接所有数据。 这可能用于临时的 StatefulSet,例如在 CI 实例或 ETL 管道中, StatefulSet 上的数据仅在 StatefulSet 生命周期内才需要,但在任务运行时数据不易重构。 任何保留状态对于所有先缩小后扩大的副本都是必需的。
  • whenDeletedwhenScaled 都是 Delete 当其副本不再被需要时,PVCs 会立即被删除。 注意,这并不包括 Pod 被删除且有新版本被调度的情况,例如当节点被腾空而 Pod 需要迁移到别处时。 只有当副本不再被需要时,如按比例缩小或删除 StatefulSet 时,才会删除 PVC。 此策略适用于数据生命周期短于副本生命周期的情况。即数据很容易重构, 且删除未使用的 PVC 所节省的成本比快速增加副本更重要,或者当创建一个新的副本时, 来自以前副本的任何数据都不可用,必须重新构建。
  • whenDeletedRetainwhenScaledDelete 这与前一种情况类似, 在增加副本时用保留的 PVCs 快速重构几乎没有什么益处。例如 Elasticsearch 集群就是使用的这种方式。 通常,你需要增大或缩小工作负载来满足业务诉求,同时确保最小数量的副本(例如:3)。 当减少副本时,数据将从已删除的副本迁移出去,保留这些 PVCs 没有任何用处。 但是,这对临时关闭整个 Elasticsearch 集群进行维护时是很有用的。 如果需要使 Elasticsearch 系统脱机,可以通过临时删除 StatefulSet 来实现, 然后通过重新创建 StatefulSet 来恢复 Elasticsearch 集群。 保存 Elasticsearch 数据的 PVCs 不会被删除,新的副本将自动使用它们。

查阅文档 获取更多详细信息。

下一步是什么?

启用该功能并尝试一下!在集群上启用 StatefulSetAutoDeletePVC 功能,然后使用新策略创建 StatefulSet。 测试一下,告诉我们你的体验!

我很好奇这个属主引用机制在实践中是否有效。例如,我们意识到 Kubernetes 中没有可以知道谁设置了引用的机制, 因此 StatefulSet 控制器可能会与设置自己的引用的自定义控制器发生冲突。 幸运的是,维护现有的保留行为不涉及任何新属主引用,因此默认行为是兼容的。

请用标签 sig/apps 标记你报告的任何问题,并将它们分配给 Matthew Cary (在 GitHub上 @mattcary)。

尽情体验吧!

Kubernetes 1.23:树内存储向 CSI 卷迁移工作的进展更新

作者: Jiawei Wang(谷歌)

自 Kubernetes v1.14 引入容器存储接口(Container Storage Interface, CSI)的工作达到 alpha 阶段后,自 v1.17 起,Kubernetes 树内存储插件(in-tree storage plugin)向 CSI 的迁移基础设施已步入 beta 阶段

自那时起,Kubernetes 存储特别兴趣组(special interest groups, SIG)及其他 Kubernetes 特别兴趣组就在努力确保这一功能的稳定性和兼容性,为正式发布做准备。 本文旨在介绍该功能的最新开发进展,以及 Kubernetes v1.17 到 v1.23 之间的变化。此外,我还将介绍每个存储插件的 CSI 迁移功能达到正式发布阶段的未来路线图。

快速回顾:CSI 迁移功能是什么?为什么要迁移?

容器存储接口旨在帮助 Kubernetes 取代其现有的树内存储驱动机制──特别是供应商的特定插件。自 v1.13 起,Kubernetes 对容器存储接口的支持工作已达到正式发布阶段。引入对 CSI 驱动的支持,将使得 Kubernetes 和存储后端技术之间的集成工作更易建立和维护。使用 CSI 驱动可以实现更好的可维护性(驱动作者可以决定自己的发布周期和支持生命周期)、减少出现漏洞的机会(得益于更少的树内代码,出现错误的风险会降低。另外,集群操作员可以只选择集群需要的存储驱动)。

随着更多的 CSI 驱动诞生并进入生产就绪阶段,Kubernetes 存储特别兴趣组希望所有 Kubernetes 用户都能从 CSI 模型中受益──然而,我们不应破坏与现有存储 API 类型的 API 兼容性。对此,我们给出的解决方案是 CSI 迁移:该功能实现将树内存储 API 翻译成等效的 CSI API,并把操作委托给一个替换的 CSI 驱动来完成。

CSI 迁移工作使存储后端现有的树内存储插件(如 kubernetes.io/gce-pdkubernetes.io/aws-ebs)能够被相应的 CSI 驱动 所取代。如果 CSI 迁移功能正确发挥作用,Kubernetes 终端用户应该不会注意到有什么变化。现有的 StorageClassPersistentVolumePersistentVolumeClaim 对象应继续工作。当 Kubernetes 集群管理员更新集群以启用 CSI 迁移功能时,利用到 PVCs1(由树内存储插件支持)的现有工作负载将继续像以前一样运作──不过在幕后,Kubernetes 将所有存储管理操作(以前面向树内存储驱动的)交给 CSI 驱动控制。

举个例子。假设你是 kubernetes.io/gce-pd 用户,在启用 CSI 迁移功能后,你仍然可以使用 kubernetes.io/gce-pd 来配置新卷、挂载现有的 GCE-PD 卷或删除现有卷。所有现有的 API/接口 仍将正常工作──只不过,底层功能调用都将通向 GCE PD CSI 驱动,而不是 Kubernetes 的树内存储功能。

这使得 Kubernetes 终端用户可以顺利过渡。另外,对于存储插件的开发者,我们可以减少他们维护树内存储插件的负担,并最终将这些插件从 Kubernetes 核心的二进制中移除。

改进与更新

在 Kubernetes v1.17 及更早的工作基础上,此后的发布有了以下一系列改变:

新的特性门控(feature gate)

Kubernetes v1.21 弃用了 CSIMigration{provider}Complete 特性参数(feature flag),它们不再生效。取而代之的是名为 InTreePlugin{vendor}Unregister 的新特性参数,它们保留了 CSIMigration{provider}Complete 提供的所有功能。

CSIMigration{provider}Complete 是作为 CSI 迁移功能在所有节点上启用后的补充特性门控于之前引入的。这个参数可注销参数名称中 {provider} 部分所指定的树内存储插件。

当你启用该特性门控时,你的集群不再使用树内驱动代码,而是直接选择并使用相应的 CSI 驱动。同时,集群并不检查节点上 CSI 迁移功能是否启用,以及 CSI 驱动是否实际部署。

虽然这一特性门控是一个很好的帮手,但 Kubernetes 存储特别兴趣组(以及,我相信还有很多集群操作员)同样希望有一个特性门控可以让你即使在不启用 CSI 迁移功能时,也能禁用树内存储插件。例如,你可能希望在一个 GCE 集群上禁用 EBS 存储插件,因为 EBS 卷是其他供应商的云(AWS)所专有的。

为了使这成为可能,Kubernetes v1.21 引入了一个新的特性参数集合:InTreePlugin{vendor}Unregister

InTreePlugin{vendor}Unregister 是一种特性门控,可以独立于 CSI 迁移功能来启用或禁用。当启用此种特性门控时,组件将不会把相应的树内存储插件注册到支持的列表中。如果集群操作员只启用了这种参数,终端用户将在使用该插件的 PVC1 处遇到错误,提示其找不到插件。如果集群操作员不想支持过时的树内存储 API,只支持 CSI,那么他们可能希望启用这种特性门控而不考虑 CSI 迁移功能。

可观察性

Kubernetes v1.21 引入了跟踪 CSI 迁移功能的指标。你可以使用这些指标来观察你的集群是如何使用存储服务的,以及对该存储的访问使用的是传统的树内驱动还是基于 CSI 的替代。

组件 指标 注释
Kube-Controller-Manager storage_operation_duration_seconds 一个新的标签 migrated 被添加到指标中,以表明该存储操作是否由 CSI 迁移功能操作(字符串值为 true 表示启用,false 表示未启用)。
Kubelet csi_operations_seconds 新的指标提供的标签包括 driver_namemethod_namegrpc_status_codemigrated。这些标签的含义与 csi_sidecar_operations_seconds 相同。
CSI Sidecars(provisioner, attacher, resizer) csi_sidecar_operations_seconds 一个新的标签 migrated 被添加到指标中,以表明该存储操作是否由 CSI 迁移功能操作(字符串值为 true 表示启用,false 表示未启用)。

错误修复和功能改进

籍由 beta 测试人员的帮助,我们修复了许多错误──如悬空附件、垃圾收集、拓扑标签错误等。

与 Kubernetes 云提供商特别兴趣组、集群生命周期特别兴趣组的合作

Kubernetes 存储特别兴趣组与云提供商特别兴趣组和集群生命周期特别兴趣组,正为了 CSI 迁移功能上线而密切合作。

如果你采用托管 Kubernetes 服务,请询问你的供应商是否有什么工作需要完成。在许多情况下,供应商将管理迁移,你不需要做额外的工作。

如果你使用的是 Kubernetes 的发行版,请查看其官方文档,了解对该功能的支持情况。对于已进入正式发布阶段的 CSI 迁移功能,Kubernetes 存储特别兴趣组正与Kubernetes 集群生命周期特别兴趣组合作,以便在这些功能于 Kubernetes 中可用时,使迁移机制也进入到周边工具(如 kubeadm)中。

时间计划及当前状态

各驱动的当前发布及目标发布如下表所示:

驱动 Alpha Beta(启用树内插件) Beta(默认启用) 正式发布 目标:移除“树内存储插件”
AWS EBS 1.14 1.17 1.23 1.24 (Target) 1.26 (Target)
GCE PD 1.14 1.17 1.23 1.24 (Target) 1.26 (Target)
OpenStack Cinder 1.14 1.18 1.21 1.24 (Target) 1.26 (Target)
Azure Disk 1.15 1.19 1.23 1.24 (Target) 1.26 (Target)
Azure File 1.15 1.21 1.24 (Target) 1.25 (Target) 1.27 (Target)
vSphere 1.18 1.19 1.24 (Target) 1.25 (Target) 1.27 (Target)
Ceph RBD 1.23
Portworx 1.23

以下存储驱动将不会支持 CSI 迁移功能。其中 ScaleIO 驱动已经被移除;其他驱动都被弃用,并将从 Kubernetes 核心中删除。

驱动 被弃用 代码移除
ScaleIO 1.16 1.22
Flocker 1.22 1.25 (Target)
Quobyte 1.22 1.25 (Target)
StorageOS 1.22 1.25 (Target)

下一步的计划

随着更多的 CSI 驱动进入正式发布阶段,我们希望尽快将整个 CSI 迁移功能标记为正式发布状态。我们计划在 Kubernetes v1.26 和 v1.27 之前移除云提供商树内存储插件的代码。

作为用户,我应该做什么?

请注意,Kubernetes 存储系统的所有新功能(如卷快照)将只被添加到 CSI 接口。因此,如果你正在启动一个新的集群、首次创建有状态的应用程序,或者需要这些新功能,我们建议你在本地使用 CSI 驱动(而不是树内卷插件 API)。遵循最新的 CSI 驱动用户指南并使用新的 CSI API。

然而,如果您选择沿用现有集群或继续使用传统卷 API 的规约,CSI 迁移功能将确保我们通过新 CSI 驱动继续支持这些部署。但是,如果您想利用快照等新功能,则需要进行手动迁移,将现有的树内持久卷重新导入为 CSI 持久卷。

我如何参与其中?

Kubernetes Slack 频道 #csi-migration 以及任何一个标准的 SIG Storage 通信频道都是与 Kubernetes 存储特别兴趣组和迁移工作组团队联系的绝佳媒介。

该项目,和其他所有 Kubernetes 项目一样,是许多来自不同背景的贡献者共同努力的结果。我们非常感谢在过去几个季度里挺身而出帮助推动项目发展的贡献者们:

  • Michelle Au (msau42)
  • Jan Šafránek (jsafrane)
  • Hemant Kumar (gnufied)

特别感谢以下人士对 CSI 迁移功能的精辟评论、全面考虑和宝贵贡献:

  • Andy Zhang (andyzhangz)
  • Divyen Patel (divyenpatel)
  • Deep Debroy (ddebroy)
  • Humble Devassy Chirammal (humblec)
  • Jing Xu (jingxu97)
  • Jordan Liggitt (liggitt)
  • Matthew Cary (mattcary)
  • Matthew Wong (wongma7)
  • Neha Arora (nearora-msft)
  • Oksana Naumov (trierra)
  • Saad Ali (saad-ali)
  • Tim Bannister (sftim)
  • Xing Yang (xing-yang)

有兴趣参与 CSI 或 Kubernetes 存储系统任何部分的设计和开发的人,请加入 Kubernetes 存储特别兴趣组。我们正在迅速成长,并一直欢迎新的贡献者。


  1. 持久卷申领(PersistentVolumeClaim,PVC) ↩︎ ↩︎

Kubernetes 1.23:IPv4/IPv6 双协议栈网络达到 GA

作者: Bridget Kromhout (微软)

“Kubernetes 何时支持 IPv6?” 自从 k8s v1.9 版本中首次添加对 IPv6 的 alpha 支持以来,这个问题的讨论越来越频繁。 虽然 Kubernetes 从 v1.18 版本开始就支持纯 IPv6 集群,但当时还无法支持 IPv4 迁移到 IPv6。 IPv4/IPv6 双协议栈网络 在 Kubernetes v1.23 版本中进入正式发布(GA)阶段。

让我们来看看双协议栈网络对你来说意味着什么?

更新 Service API

Services 在 1.20 版本之前是单协议栈的, 因此,使用两个 IP 协议族意味着需为每个 IP 协议族创建一个 Service。在 1.20 版本中对用户体验进行简化, 重新实现了 Service 以支持两个 IP 协议族,这意味着一个 Service 就可以处理 IPv4 和 IPv6 协议。 对于 Service 而言,任意的 IPv4 和 IPv6 协议组合都可以实现负载均衡。

Service API 现在有了支持双协议栈的新字段,取代了单一的 ipFamily 字段。

  • 你可以通过将 ipFamilyPolicy 字段设置为 SingleStackPreferDualStackRequireDualStack 来设置 IP 协议族。Service 可以在单协议栈和双协议栈之间进行转换(在某些限制内)。
  • 设置 ipFamilies 为指定的协议族列表,可用来设置使用协议族的顺序。
  • 'clusterIPs' 的能力在涵盖了之前的 'clusterIP'的情况下,还允许设置多个 IP 地址。 所以不再需要运行重复的 Service,在两个 IP 协议族中各运行一个。你可以在两个 IP 协议族中分配集群 IP 地址。

请注意,Pods 也是双协议栈的。对于一个给定的 Pod,不可能在同一协议族中设置多个 IP 地址。

默认行为仍然是单协议栈

从 1.20 版本开始,重新实现的双协议栈服务处于 Alpha 阶段,无论集群是否配置了启用双协议栈的特性标志, Kubernetes 的底层网络都已经包括了双协议栈。

Kubernetes 1.23 删除了这个特性标志,说明该特性已经稳定。 如果你想要配置双协议栈网络,这一能力总是存在的。 你可以将集群网络设置为 IPv4 单协议栈 、IPv6 单协议栈或 IPV4/IPV6 双协议栈 。

虽然 Service 是根据你的配置设置的,但 Pod 默认是由 CNI 插件设置的。 如果你的 CNI 插件分配单协议栈 IP,那么就是单协议栈,除非 ipFamilyPolicy 设置为 PreferDualStackRequireDualStack。 如果你的 CNI 插件分配双协议栈 IP,则 pod.status.PodIPs 默认为双协议栈。

尽管双协议栈是可用的,但并不强制你使用它。 在双协议栈服务配置 文档中的示例列出了可能出现的各种场景.

现在尝试双协议栈

虽然现在上游 Kubernetes 支持双协议栈网络 作为 GA 或稳定特性,但每个提供商对双协议栈 Kubernetes 的支持可能会有所不同。节点需要提供可路由的 IPv4/IPv6 网络接口。 Pod 需要是双协议栈的。网络插件 是用来为 Pod 分配 IP 地址的,所以集群需要支持双协议栈的网络插件。一些容器网络接口(CNI)插件支持双协议栈,例如 kubenet。

支持双协议栈的生态系统在不断壮大;你可以使用 kubeadm 创建双协议栈集群, 在本地尝试用 KIND 创建双协议栈集群, 还可以将双协议栈集群部署到云上(在查阅 CNI 或 kubenet 可用性的文档之后)

加入 Network SIG

SIG-Network 希望从双协议栈网络的社区体验中学习,以了解更多不断变化的需求和你的用例信息。 SIG-network 更新了来自 KubeCon 2021 北美大会的视频 总结了 SIG 最近的更新,包括双协议栈将在 1.23 版本中稳定。

当前 SIG-Network 在 GitHub 上的 KEPsissues 说明了该 SIG 的重点领域。双协议栈 API 服务器 是一个考虑贡献的方向。

SIG-Network 会议 是一个友好、热情的场所,你可以与社区联系并分享你的想法。期待你的加入!

致谢

许多 Kubernetes 贡献者为双协议栈网络做出了贡献。感谢所有贡献了代码、经验报告、文档、代码审查以及其他工作的人。 Bridget Kromhout 在 Kubernetes的双协议栈网络 中详细介绍了这项社区工作。Tim Hockin 和 Khaled (Kal) Henidak 在 2019 年的 KubeCon 大会演讲 (Kubernetes 通往 IPv4/IPv6 双协议栈的漫漫长路) 和 Lachlan Evenson 在 2021 年演讲(我们来啦,Kubernetes 双协议栈网络) 中讨论了双协议栈的发展旅程,耗时 5 年和海量代码。

公布 2021 年指导委员会选举结果

作者:Kaslin Fields

2021 年指导委员会选举现已完成。 Kubernetes 指导委员会由 7 个席位组成,其中 4 个席位将在 2021 年进行选举。 新任委员会成员任期 2 年,所有成员均由 Kubernetes 社区选举产生。

这个社区机构非常重要,因为它监督整个 Kubernetes 项目的治理。 你可以在其章程中了解更多关于指导委员会的角色。

选举结果

祝贺当选的委员会成员,他们的两年任期即刻生效(按 GitHub handle 字母排序):

他们加入永久成员:

Paris Pittman 和 Christoph Blecker 将回到指导委员会。

非常感谢

感谢并祝贺完成本轮成功选举的选举官们:

特别感谢 k8s-infra 联络员 Arnaud Meukam(@ameukam), 他在社区的基础设施上启动了我们的投票软件。

感谢荣誉退休的指导委员会成员。对你们之前对社区的贡献表示感谢:

感谢所有前来参加竞选的候选人。

参与指导委员会

与所有 Kubernetes 一样,这个管理机构对所有人开放。 你可以查看指导委员会的待办事项, 通过在他们的 repo 中提交一个 issue 或创建一个 PR 来参与讨论。 他们在每月的第一个星期一上午 9:30 举行公开会议, 并定期参加会见我们的贡献者活动。也可以通过他们的公共邮件列表 steering@kubernetes.io 联系他们。

你可以在 YouTube 播放列表 上观看之前的会议视频,了解指导委员会的会议讨论内容。


本文是由上游营销工作组撰写的。 如果你想撰写有关 Kubernetes 社区的故事,请了解更多关于我们的信息。

关注 SIG Node

Author: Dewan Ahmed, Red Hat

介绍

在 Kubernetes 中,一个 Node 是你集群中的某台机器。 SIG Node 负责这一非常重要的 Node 组件并支持各种子项目, 如 Kubelet, Container Runtime Interface (CRI) 以及其他支持 Pod 和主机资源间交互的子项目。 在这篇文章中,我们总结了和 Elana Hashman (EH) & Sergey Kanzhelev (SK) 的对话,是他们带领我们了解作为此 SIG 一份子的各个方面,并分享一些关于其他人如何参与的见解。

我们的对话总结

你能告诉我们一些关于 SIG Node 的工作吗?

SK:SIG Node 是一个垂直 SIG,负责支持 Pod 和主机资源之间受控互动的组件。我们管理被调度到节点上的 Pod 的生命周期。 这个 SIG 的重点是支持广泛的工作负载类型,包括具有硬件特性或性能敏感要求的工作负载。同时保持节点上 Pod 之间的隔离边界,以及 Pod 和主机的隔离边界。 这个 SIG 维护了相当多的组件,并有许多外部依赖(如容器运行时间或操作系统功能),这使得我们处理起来十分复杂。但我们战胜了这种复杂度,旨在不断提高节点的可靠性。

你能再解释一下 “SIG Node 是一种垂直 SIG” 的含义吗?

EH:有两种 SIG:横向和垂直。横向 SIG 关注 Kubernetes 中每个组件的特定功能:例如,SIG Security 考虑 Kubernetes 中每个组件的安全方面,或者 SIG Instrumentation 关注 Kubernetes 中每个组件的日志、度量、跟踪和事件。 这样的 SIG 并不太会拥有大量的代码。

相反,垂直 SIG 拥有一个单一的组件,并负责批准和合并该代码库的补丁。 SIG Node 拥有 "Node" 的垂直性,与 kubelet 和它的生命周期有关。这包括 kubelet 本身的代码,以及节点控制器、容器运行时接口和相关的子项目,比如节点问题检测器。

CI 子项目是如何开始的?这是专门针对 SIG Node 的吗?它对 SIG 有什么帮助?

SK:该子项目是在其中一个版本因关键测试的大量测试失败而受阻后开始跟进的。 这些测试并不是一下子就开始下降的,而是持续的缺乏关注导致了测试质量的缓慢下降。 SIG Node 一直将质量和可靠性放在首位,组建这个子项目是强调这一优先事项的一种方式。

作为 issue 和 PR 数量第三大的 SIG,你们 SIG 是如何兼顾这么多工作的?

EH:这归功于有组织性。当我在 2021 年 1 月增加对 SIG 的贡献时,我发现自己被大量的 PR 和 issue 淹没了,不知道该从哪里开始。 我们已经在 CI 子项目板上跟踪与测试有关的 issue 和 PR 请求,但这缺少了很多 bug 修复和功能工作。 因此,我开始为我们剩余的 PR 建立一个分流板,这使我能够根据状态和采取的行动对其进行分类,并为其他贡献者记录它的用途。 在过去的两个版本中,我们关闭或合并了超过 500 个 issue 和 PR。Kubernetes devstats 显示,我们的速度因此而大大提升。

6月,我们进行了第一次 bug 清除活动,以解决针对 SIG Node 的积压问题,确保它们被正确归类。 在这次 48 小时的全球活动中,我们关闭了 130 多个问题,但截至发稿时,我们仍有 333 个问题没有解决。

为什么新的和现有的贡献者应该考虑加入 Node 兴趣小组呢?

SK:作为 SIG Node 的贡献者会带给你有意义且有用的技能和认可度。 了解 Kubelet 的内部结构有助于构建更好的应用程序,调整和优化这些应用程序,并在 issue 排查上获得优势。 如果你是一个新手贡献者,SIG Node 为你提供了基础知识,这是理解其他 Kubernetes 组件的设计方式的关键。 现在的贡献者可能会受益于许多功能都需要 SIG Node 的这种或那种变化。所以成为 SIG Node 的贡献者有助于更快地建立其他 SIG 的功能。

SIG Node 维护着许多组件,其中许多组件都依赖于外部项目或操作系统功能。这使得入职过程相当冗长和苛刻。 但如果你愿意接受挑战,总有一个地方适合你,也有一群人支持你。

你是如何帮助新手贡献者开始工作的?

EH:在 SIG Node 的起步工作可能是令人生畏的,因为有太多的工作要做,我们的 SIG 会议非常大,而且很难找到一个开始的地方。

我总是鼓励新手贡献者在他们已经有一些投入的方向上更进一步。 在 SIG Node 中,这可能意味着自愿帮助修复一个只影响到你个人的 bug,或者按优先级去分流你关心的 bug。

为了尽快了解任何开源代码库,你可以采取两种策略:从深入探索一个特定的问题开始,然后根据需要扩展你的知识边缘,或者单纯地尽可能多的审查 issues 和变更请求,以了解更高层次的组件工作方式。 最终,如果你想成为一名 Node reviewer 或 approver,两件事是不可避免的。

Davanum Srinivas 和我各自举办了一次小组辅导,以帮助教导新手贡献者成为 Node reviewer 的技能,如果有兴趣,我们可以努力寻找一个导师来举办另一次会议。 我也鼓励新手贡献者参加我们的 Node CI 子项目会议:它的听众较少,而且我们不记录分流会议,所以它可以是一个比较温和的方式来开始 SIG 之旅。

有什么特别的技能者是你想招募的吗?对 SIG 可用性的贡献者可能会学到什么技能?

SK:SIG Node 在大相径庭的领域从事许多工作流。所有这些领域都是系统级的。 对于典型的代码贡献,你需要对建立和善用低级别的 API 以及编写高性能和可靠的组件有热情。 作为一个贡献者,你将学习如何调试和排除故障,剖析和监控这些组件,以及由这些组件运行的用户工作负载。 通常情况下,由于节点正在运行生产工作负载,所以对节点的访问是有限的,甚至是没有的。

另一种贡献方式是帮助记录 SIG Node 的功能。这种类型的贡献需要对功能有深刻的理解,并有能力用简单的术语解释它们。

最后,我们一直在寻找关于如何最好地运行你的工作负载的反馈。来解释一下它的具体情况,以及 SIG Node 组件中的哪些功能可能有助于更好地运行它。

你在哪些方面得到了积极的反馈,以及 SIG Node 的下一步计划是什么?

EH:在过去的一年里,SIG Node 采用了一些新的流程来帮助管理我们的功能开发和 Kubernetes 增强提议,其他 SIG 也向我们寻求在管理大型工作负载方面的灵感。 我希望这是一个我们可以继续领导并进一步迭代的领域。

现在,我们在新功能和废弃功能之间保持了很好的平衡。 废弃未使用或难以维护的功能有助于我们控制技术债务和维护负荷,例子包括 dockershim 和 DynamicKubeletConfiguration 的废弃。 新功能将在终端用户的集群中释放更多的功能,包括令人兴奋的功能,如支持 cgroups v2、交换内存、优雅的节点关闭和设备管理策略。

最后你有什么想法/资源要分享吗?

SK/EH:进入任何开源社区都需要时间和努力。一开始 SIG Node 可能会因为参与者的数量、工作量和项目范围而让你不知所措。但这是完全值得的。 请加入我们这个热情的社区! SIG Node GitHub Repo 包含许多有用的资源,包括 Slack、邮件列表和其他联系信息。

总结

SIG Node 举办了一场 KubeCon + CloudNativeCon Europe 2021 talk,对他们强大的 SIG 进行了介绍和深入探讨。 加入 SIG 的会议,了解最新的研究成果,未来一年的计划是什么,以及如何作为贡献者参与到上游的 Node 团队中!

更新 NGINX-Ingress 以使用稳定的 Ingress API

作者: James Strong, Ricardo Katz

对于所有 Kubernetes API,一旦它们被正式发布(GA),就有一个创建、维护和最终弃用它们的过程。 networking.k8s.io API 组也不例外。 即将发布的 Kubernetes 1.22 版本将移除几个与网络相关的已弃用 API:

  • IngressClassnetworking.k8s.io/v1beta1 API 版本
  • Ingress 的所有 Beta 版本: extensions/v1beta1networking.k8s.io/v1beta1

在 v1.22 Kubernetes 集群上,你能够通过稳定版本(v1)的 API 访问 Ingress 和 IngressClass 对象, 但无法通过其 Beta API 访问。

20172019 以来一直讨论关于 Kubernetes 1.16 弃用 API 的更改, 最近的讨论是在 KEP-1453:Ingress API 毕业到 GA

在社区会议中,网络特别兴趣小组决定继续支持带有 0.47.0 版本 Ingress-NGINX 的早于 1.22 版本的 Kubernetes。 在 Kubernetes 1.22 发布后,对 Ingress-NGINX 的支持将持续六个月。 团队会根据需要解决 Ingress-NGINX 的额外错误修复和 CVE 问题。

Ingress-NGINX 将拥有独立的分支和发布版本来支持这个模型,与 Kubernetes 项目流程相一致。 Ingress-NGINX 项目的未来版本将跟踪和支持最新版本的 Kubernetes。

Kubernetes 各版本支持的 Ingress NGINX 版本
Kubernetes 版本 Ingress-NGINX 版本 公告
v1.22 v1.0.0-alpha.2 新特性,以及错误修复。
v1.21 v0.47.x 仅修复安全问题或系统崩溃的错误。没有宣布终止支持日期。
v1.20 v0.47.x 仅修复安全问题或系统崩溃的错误。没有宣布终止支持日期。
v1.19 v0.47.x 仅修复安全问题或系统崩溃的错误。仅在 Kubernetes v1.22.0 发布后的 6 个月内提供修复支持。

由于 Kubernetes 1.22 中的更新,v0.47.0 将无法与 Kubernetes 1.22 一起使用。

你需要做什么

团队目前正在升级 Ingress-NGINX 以支持向 v1 的迁移, 你可以在此处跟踪进度。 在对 Ingress v1 的支持完成之前, 我们不会对功能进行改进。

同时,团队会确保没有兼容性问题:

  • 更新到最新的 Ingress-NGINX 版本, 目前是 v0.47.0
  • Kubernetes 1.22 发布后,请确保使用的是支持 Ingress 和 IngressClass 稳定 API 的最新版本的 Ingress-NGINX。
  • 使用集群版本 >= 1.19 测试 Ingress-NGINX 版本 v1.0.0-alpha.2,并将任何问题报告给项目 GitHub 页面。

欢迎社区对此工作的反馈和支持。 Ingress-NGINX 子项目定期举行社区会议, 我们会讨论这个问题以及项目面临的其他问题。 有关子项目的更多信息,请参阅 SIG Network

聚焦 SIG Usability

作者: Kunal Kushwaha、Civo

介绍

你是否有兴趣了解 SIG Usability 做什么? 你是否想知道如何参与?那你来对地方了。 SIG Usability 旨在让 Kubernetes 更易于触达新的伙伴,其主要活动是针对社区实施用户调研。 在本博客中,我们总结了与 Gaby Moreno 的对话, 他向我们介绍了成为 SIG 成员的各个方面,并分享了一些关于其他人如何参与的见解。

Gaby 是 SIG Usability 的联合负责人。 她在 IBM 担任产品设计师, 喜欢研究 Kubernetes、OpenShift、Terraform 和 Cloud Foundry 等开放式混合云技术的用户体验。

我们谈话的摘要

问:你能告诉我们一些关于 SIG Usability 的事情吗?

答:简单而言,启动 SIG Usability 的原因是那时 Kubernetes 没有专门的用户体验团队。 SIG Usability 的关注领域集中在为 Kubernetes 项目最终客户提供的易用性上。 主要活动是社区的用户调研,包括对 Kubernetes 用户宣讲。

所涉及的包括用户体验和可访问性等方面。 SIG 的目标是确保 Kubernetes 项目能够最大限度地被具有各类不同基础和能力的人使用, 例如引入文档的国际化并确保其开放性。

问:为什么新的和现有的贡献者应该考虑加入 SIG Usability?

答:新的贡献者可以在很多领域着手。例如:

  • 用户研究项目可以让人们帮助了解最终用户体验的可用性,包括错误消息、端到端任务等。
  • Kubernetes 社区组件的可访问性指南,包括:文档的国际化、色盲人群的颜色选择、 确保与屏幕阅读器技术的兼容性、核心 UI 组件的用户界面设计等等。

问:如何帮助新的贡献者入门?

答:新的贡献者们刚开始可以旁观参与其中一个用户访谈,浏览用户访谈记录,分析这些记录并设计调查过程。

SIG Usability 也对新的项目想法持开放态度。 如果你有想法,我们将尽我们所能支持它。 我们有定期的 SIG 会议,人们可以现场提问。 这些会议也会录制会议视频,方便那些可能无法参会的人。 与往常一样,你也可以在 Slack 上与我们联系。

问:调查包括什么?

答:简单来说,调查会收集人们如何使用 Kubernetes 的信息, 例如学习部署新系统的趋势、他们收到的错误消息和工作流程。

我们的目标之一是根据需要对反馈进行标准化。 最终目标是分析那些需求没有得到满足的重要用户故事的调查反馈。

问:招募贡献者时你希望他们具备什么特别的技能吗?SIG Usability 的贡献者可能要学习哪些技能?

答:虽然为 SIG Usability 做贡献没有任何先决条件, 但用户研究、定性研究的经验或之前如何进行访谈的经验将是很好的加分项。 定量研究,如调查设计和筛选,也很有帮助,也是我们希望贡献者学习的东西。

问:您在哪些方面获得了积极的反馈,以及 SIG Usability 接下来会发生什么?

答:我们一直有新成员加入并经常参加月度会议,并表现出对成为贡献者和帮助社区的兴趣。 我们也有很多人通过 Slack 与我们联系,表达他们对 SIG 的兴趣。

目前,我们正专注于完成我们演讲中提到的调研, 也是我们今年的项目。我们总是很高兴有新的贡献者加入我们。

问:在结束之前,你还有什么想法/资源要分享吗?

答:我们喜欢结识新的贡献者并帮助他们研究不同的 Kubernetes 项目领域。 我们将与其他 SIG 合作,以促进与最终用户的互动,开展调研,并帮助他们将可访问的设计实践整合到他们的开发实践中。

这里有一些资源供你入门:

总结

SIG Usability 举办了一个关于调研 Kubernetes 用户体验的 KubeCon 演讲。 演讲的重点是用户调研项目的更新,了解谁在使用 Kubernetes、他们试图实现什么、项目如何满足他们的需求、以及我们需要改进项目和客户体验的地方。 欢迎加入 SIG 的更新,了解最新的调研成果、来年的计划以及如何作为贡献者参与上游可用性团队!

卷健康监控的 Alpha 更新

作者: Xing Yang (VMware)

最初在 1.19 中引入的 CSI 卷健康监控功能在 1.21 版本中进行了大规模更新。

为什么要向 Kubernetes 添加卷健康监控?

如果没有卷健康监控,在 PVC 被 Pod 配置和使用后,Kubernetes 将不知道存储系统的底层卷的状态。 在 Kubernetes 中配置卷后,底层存储系统可能会发生很多事情。 例如,卷可能在 Kubernetes 之外被意外删除、卷所在的磁盘可能发生故障、容量不足、磁盘可能被降级而影响其性能等等。 即使卷被挂载到 Pod 上并被应用程序使用,以后也可能会出现诸如读/写 I/O 错误、文件系统损坏、在 Kubernetes 之外被意外卸载卷等问题。 当发生这样的事情时,调试和检测根本原因是非常困难的。

卷健康监控对 Kubernetes 用户非常有益。 它可以与 CSI 驱动程序通信以检索到底层存储系统检测到的错误。 用户可以收到报告上来的 PVC 事件继而采取行动。 例如,如果卷容量不足,他们可以请求卷扩展以获得更多空间。

什么是卷健康监控?

CSI 卷健康监控允许 CSI 驱动程序检测来自底层存储系统的异常卷状况,并将其作为 PVC 或 Pod 上的事件报送。

监控卷和使用卷健康信息报送事件的 Kubernetes 组件包括:

  • Kubelet 除了收集现有的卷统计信息外,还将观察该节点上 PVC 的卷健康状况。 如果 PVC 的健康状况异常,则会在使用 PVC 的 Pod 对象上报送事件。 如果多个 Pod 使用相同的 PVC,则将在使用该 PVC 的所有 Pod 上报送事件。

请注意,在 Kubernetes 1.19 版本中首次引入此功能时,节点侧卷健康监控逻辑是一个外部代理。 在 Kubernetes 1.21 中,节点侧卷健康监控逻辑从外部代理移至 Kubelet,以避免 CSI 函数重复调用。 随着 1.21 中的这一变化,为 Kubelet 中的卷健康监控逻辑引入了一个新的 alpha 特性门 CSIVolumeHealth

目前,卷健康监控功能仅供参考,因为它只报送 PVC 或 Pod 上的异常卷健康事件。 用户将需要检查这些事件并手动修复问题。 此功能可作为 Kubernetes 未来以编程方式检测和解决卷健康问题的基石。

如何在 Kubernetes 集群上使用卷健康?

要使用卷健康功能,首先确保你使用的 CSI 驱动程序支持此功能。 请参阅此 CSI 驱动程序文档以了解哪些 CSI 驱动程序支持此功能。

要从节点侧启用卷健康监控,需要启用 alpha 特性门 CSIVolumeHealth

如果 CSI 驱动程序支持控制器端的卷健康监控功能,则有关异常卷条件的事件将记录在 PVC 上。

如果 CSI 驱动程序支持控制器端的卷健康监控功能, 当部署外部健康监控控制器时 enable-node-watcher 标志设置为 true,用户还可以获得有关节点故障的事件。 当检测到节点故障事件时,会在 PVC 上报送一个事件,指示使用该 PVC 的 Pod 在故障节点上。

如果 CSI 驱动程序支持节点端的卷健康监控功能,则有关异常卷条件的事件将使用 PVC 记录在 Pod 上。

作为存储供应商,如何向 CSI 驱动程序添加对卷健康的支持?

卷健康监控包括两个部分:

  • 外部卷健康监控控制器从控制器端监控卷健康。
  • Kubelet 从节点端监控卷的健康状况。

有关详细信息,请参阅 CSI 规约Kubernetes-CSI 驱动开发者指南

CSI 主机路径驱动程序中有一个卷健康的示例实现。

控制器端卷健康监控

要了解如何部署外部卷健康监控控制器, 请参阅 CSI 文档中的 CSI external-health-monitor-controller

如果检测到异常卷条件, 外部健康监视器控制器调用 ListVolumes 或者 ControllerGetVolume CSI RPC 并报送 VolumeConditionAbnormal 事件以及 PVC 上的消息。 只有具有 LIST_VOLUMESVOLUME_CONDITION 控制器能力、 或者具有 GET_VOLUMEVOLUME_CONDITION 能力的 CSI 驱动程序才支持外部控制器中的卷健康监控。

要从控制器端实现卷健康功能,CSI 驱动程序必须添加对新控制器功能的支持。

如果 CSI 驱动程序支持 LIST_VOLUMESVOLUME_CONDITION 控制器功能,它必须实现控制器 RPC ListVolumes 并在响应中报送卷状况。

如果 CSI 驱动程序支持 GET_VOLUMEVOLUME_CONDITION 控制器功能,它必须实现控制器 PRC ControllerGetVolume 并在响应中报送卷状况。

如果 CSI 驱动程序支持 LIST_VOLUMESGET_VOLUMEVOLUME_CONDITION 控制器功能,则外部健康监视控制器将仅调用 ListVolumes CSI RPC。

节点侧卷健康监控

如果检测到异常的卷条件, Kubelet 会调用 NodeGetVolumeStats CSI RPC 并报送 VolumeConditionAbnormal 事件以及 Pod 上的信息。 只有具有 VOLUME_CONDITION 节点功能的 CSI 驱动程序才支持 Kubelet 中的卷健康监控。

要从节点端实现卷健康功能,CSI 驱动程序必须添加对新节点功能的支持。

如果 CSI 驱动程序支持 VOLUME_CONDITION 节点能力,它必须在节点 RPC NodeGetVoumeStats 中报送卷状况。

下一步是什么?

根据反馈和采纳情况,Kubernetes 团队计划在 1.22 或 1.23 中将 CSI 卷健康实施推向 beta。

我们还在探索如何在 Kubernetes 中使用卷健康信息进行编程检测和自动协调。

如何了解更多?

要了解卷健康监控的设计细节,请阅读卷健康监控增强提案。

卷健康检测控制器源代码位于: https://github.com/kubernetes-csi/external-health-monitor

容器存储接口文档中还有关于卷健康检查的更多详细信息。

如何参与?

Kubernetes Slack 频道 #csi 和任何标准 SIG Storage 通信频道都是联系 SIG Storage 和 CSI 团队的绝佳媒介。

我们非常感谢在 1.21 中帮助发布此功能的贡献者。 我们要感谢 Yuquan Ren (NickrenREN) 在外部健康监控仓库中实现了初始卷健康监控控制器和代理, 感谢 Ran Xu (fengzixu) 在 1.21 中将卷健康监控逻辑从外部代理转移到 Kubelet, 我们特别感谢以下人员的深刻评论: David Ashpole (dashpole)、 Michelle Au (msau42)、 David Eads (deads2k)、 Elana Hashman (ehashman)、 Seth Jennings (sjenning) 和 Jiawei Wang (Jiawei0227)

那些有兴趣参与 CSI 或 Kubernetes 存储系统任何部分的设计和开发的人, 请加入 Kubernetes Storage 特殊兴趣小组(SIG)。 我们正在迅速发展,并且欢迎新的贡献者。

弃用 PodSecurityPolicy:过去、现在、未来

作者:Tabitha Sable(Kubernetes SIG Security)

PodSecurityPolicy (PSP) 在 Kubernetes 1.21 中被弃用。 PSP 日后会被移除,但目前不会改变任何其他内容。在移除之前,PSP 将继续在后续多个版本中完全正常运行。 与此同时,我们正在开发 PSP 的替代品,希望可以更轻松、更可持续地覆盖关键用例。

什么是 PSP?为什么需要 PSP?为什么要弃用,未来又将如何发展? 这对你有什么影响?当我们准备告别 PSP,这些关键问题浮现在脑海中, 所以让我们一起来讨论吧。本文首先概述 Kubernetes 如何移除一些特性。

Kubernetes 中的弃用是什么意思?

每当 Kubernetes 决定弃用某项特性时,我们会遵循弃用策略。 首先将该特性标记为已弃用,然后经过足够长的时间后,最终将其移除。

Kubernetes 1.21 启动了 PodSecurityPolicy 的弃用流程。与弃用任何其他功能一样, PodSecurityPolicy 将继续在后续几个版本中完全正常运行。目前的计划是在 1.25 版本中将其移除。

在彻底移除之前,PSP 仍然是 PSP。至少在未来一年时间内,最新的 Kubernetes 版本仍将继续支持 PSP。大约两年之后,PSP 才会在所有受支持的 Kubernetes 版本中彻底消失。

什么是 PodSecurityPolicy?

PodSecurityPolicy 是一个内置的准入控制器, 允许集群管理员控制 Pod 规约中涉及安全的敏感内容。

首先,在集群中创建一个或多个 PodSecurityPolicy 资源来定义 Pod 必须满足的要求。 然后,创建 RBAC 规则来决定为特定的 Pod 应用哪个 PodSecurityPolicy。 如果 Pod 满足其 PSP 的要求,则照常被允许进入集群。 在某些情况下,PSP 还可以修改 Pod 字段,有效地为这些字段创建新的默认值。 如果 Pod 不符合 PSP 要求,则被拒绝进入集群,并且无法运行。

关于 PodSecurityPolicy,还需要了解:它与 PodSecurityContext 不同。

作为 Pod 规约的一部分,PodSecurityContext(及其每个容器对应的 SecurityContext) 是一组字段的集合,这些字段为 Pod 指定了与安全相关的许多设置。 安全上下文指示 kubelet 和容器运行时究竟应该如何运行 Pod。 相反,PodSecurityPolicy 仅约束可能在安全上下文中设置的值(或设置默认值)。

弃用 PSP 不会以任何方式影响 PodSecurityContext。

以前为什么需要 PodSecurityPolicy?

在 Kubernetes 中,我们定义了 Deployment、StatefulSet 和 Service 等资源。 这些资源代表软件应用程序的构建块。Kubernetes 集群中的各种控制器根据这些资源做出反应, 创建更多的 Kubernetes 资源或配置一些软件或硬件来实现我们的目标。

在大多数 Kubernetes 集群中,由 RBAC(基于角色的访问控制)规则 控制对这些资源的访问。 listgetcreateeditdelete 是 RBAC 关心的 API 操作类型, 但 RBAC 不考虑其所控制的资源中加入了哪些设置。例如, Pod 几乎可以是任何东西,例如简单的网络服务器,或者是特权命令提示(提供对底层服务器节点和所有数据的完全访问权限)。 这对 RBAC 来说都是一样的:Pod 就是 Pod 而已。

要控制集群中定义的资源允许哪些类型的设置,除了 RBAC 之外,还需要准入控制。 从 Kubernetes 1.3 开始,内置 PodSecurityPolicy 一直被作为 Pod 安全相关字段的准入控制机制。 使用 PodSecurityPolicy,可以防止“创建 Pod”这个能力自动变成“每个集群节点上的 root 用户”, 并且无需部署额外的外部准入控制器。

现在为什么 PodSecurityPolicy 要消失?

自从首次引入 PodSecurityPolicy 以来,我们已经意识到 PSP 存在一些严重的可用性问题, 只有做出断裂式的改变才能解决。

实践证明,PSP 应用于 Pod 的方式让几乎所有尝试使用它们的人都感到困惑。 很容易意外授予比预期更广泛的权限,并且难以查看某种特定情况下应用了哪些 PSP。 “更改 Pod 默认值”功能很方便,但仅支持某些 Pod 设置,而且无法明确知道它们何时会或不会应用于的 Pod。 如果没有“试运行”或审计模式,将 PSP 安全地改造并应用到现有集群是不切实际的,并且永远都不可能默认启用 PSP。

有关这些问题和其他 PSP 困难的更多信息,请查看 KubeCon NA 2019 的 SIG Auth 维护者频道会议记录:

如今,你不再局限于部署 PSP 或编写自己的自定义准入控制器。 有几个外部准入控制器可用,它们结合了从 PSP 中吸取的经验教训以提供更好的用户体验。 K-RailKyvernoOPA/Gatekeeper 都家喻户晓,各有粉丝。

尽管现在还有其他不错的选择,但我们认为,提供一个内置的准入控制器供用户选择,仍然是有价值的事情。 考虑到这一点,以及受 PSP 经验的启发,我们转向下一步。

下一步是什么?

Kubernetes SIG Security、SIG Auth 和其他社区成员几个月来一直在倾力合作,确保接下来的方案能令人惊叹。 我们拟定了 Kubernetes 增强提案(KEP 2579) 以及一个新功能的原型,目前称之为“PSP 替代策略”。 我们的目标是在 Kubernetes 1.22 中发布 Alpha 版本。

PSP 替代策略始于,我们认识到已经有一个强大的外部准入控制器生态系统可用, 所以,PSP 的替代品不需要满足所有人的所有需求。与外部 Webhook 相比, 部署和采用的简单性是内置准入控制器的关键优势。我们专注于如何最好地利用这一优势。

PSP 替代策略旨在尽可能简单,同时提供足够的灵活性以支撑大规模生产场景。 它具有柔性上线能力,以便于将其改装到现有集群,并且新的策略是可配置的,可以设置为默认启用。 PSP 替代策略可以被部分或全部禁用,以便在高级使用场景中与外部准入控制器共存。

这对你意味着什么?

这一切对你意味着什么取决于你当前的 PSP 情况。如果已经在使用 PSP,那么你有足够的时间来计划下一步行动。 请查看 PSP 替代策略 KEP 并考虑它是否适合你的使用场景。

如果你已经在通过众多 PSP 和复杂的绑定规则深度利用 PSP 的灵活性,你可能会发现 PSP 替代策略的简单性有太多限制。 此时,建议你在接下来的一年中评估一下生态系统中的其他准入控制器选择。有些资源可以让这种过渡更容易, 比如 Gatekeeper Policy Library

如果只是使用 PSP 的基础功能,只用几个策略并直接绑定到每个命名空间中的服务帐户, 你可能会发现 PSP 替代策略非常适合你的需求。 对比 Kubernetes Pod 安全标准 评估你的 PSP, 了解可以在哪些情形下使用限制策略、基线策略和特权策略。 欢迎关注或为 KEP 和后续发展做出贡献,并在可用时试用 PSP 替代策略的 Alpha 版本。

如果刚刚开始 PSP 之旅,你可以通过保持简单来节省时间和精力。 你可以使用 Pod 安全标准的 PSP 来获得和目前 PSP 替代策略相似的功能。 如果你将基线策略或限制策略绑定到 system:serviceaccounts 组来设置集群默认值, 然后使用 ServiceAccount 绑定 在某些命名空间下根据需要制定更宽松的策略,就可以避免许多 PSP 陷阱并轻松迁移到 PSP 替代策略。 如果你的需求比这复杂得多,那么建议将精力花在采用比上面提到的功能更全的某个外部准入控制器。

我们致力于使 Kubernetes 成为我们可以做到的最好的容器编排工具, 有时这意味着我们需要删除长期存在的功能,以便为更好的特性腾出空间。 发生这种情况时,Kubernetes 弃用策略可确保你有足够的时间来计划下一步行动。 对于 PodSecurityPolicy,有几个选项可以满足一系列需求和用例。 现在就开始为 PSP 的最终移除提前制定计划,请考虑为它的替换做出贡献!

致谢: 研发优秀的软件需要优秀的团队。感谢为 PSP 替代工作做出贡献的所有人, 尤其是(按字母顺序)Tim Allclair、Ian Coldwater 和 Jordan Liggitt。 和你们共事非常愉快。

一个编排高可用应用的 Kubernetes 自定义调度器

作者: Chris Seto (Cockroach Labs)

只要你愿意遵守规则,那么在 Kubernetes 上的部署和探索可以是相当愉快的。更多时候,事情会 "顺利进行"。 然而,如果一个人对与必须保持存活的鳄鱼一起旅行或者是对必须保持可用的数据库进行扩展有兴趣, 情况可能会变得更复杂一点。 相较于这个问题,建立自己的飞机或数据库甚至还可能更容易一些。撇开与鳄鱼的旅行不谈,扩展一个高可用的有状态系统也不是一件小事。

任何系统的扩展都有两个主要组成部分。

  1. 增加或删除系统将运行的基础架构,以及
  2. 确保系统知道如何处理自身额外实例的添加和删除。

大多数无状态系统,例如网络服务器,在创建时不需要意识到对等实例。而有状态的系统,包括像 CockroachDB 这样的数据库, 必须与它们的对等实例协调,并对数据进行 shuffle。运气好的话,CockroachDB 可以处理数据的再分布和复制。 棘手的部分是在确保数据和实例分布在许多故障域(可用性区域)的操作过程中能够容忍故障的发生。

Kubernetes 的职责之一是将 "资源"(如磁盘或容器)放入集群中,并满足其请求的约束。 例如。"我必须在可用性区域 A"(见在多个区域运行), 或者 "我不能被放置到与某个 Pod 相同的节点上" (见亲和与反亲和)。

作为对这些约束的补充,Kubernetes 提供了 StatefulSets, 为 Pod 提供身份,以及 "跟随" 这些指定 Pod 的持久化存储。 在 StatefulSet 中,身份是由 Pod 名称末尾一个呈增序的整数处理的。 值得注意的是,这个整数必须始终是连续的:在一个 StatefulSet 中, 如果 Pod 1 和 3 存在,那么 Pod 2 也必须存在。

在架构上,CockroachCloud 将 CockroachDB 的每个区域作为 StatefulSet 部署在自己的 Kubernetes 集群中 -- 参见 Orchestrate CockroachDB in a Single Kubernetes Cluster。 在这篇文章中,我将着眼于一个单独的区域,一个 StatefulSet 和一个至少分布有三个可用区的 Kubernetes 集群。

一个三节点的 CockroachCloud 集群如下所示:

3-node, multi-zone cockroachdb cluster

在向集群增加额外的资源时,我们也会将它们分布在各个区域。 为了获得最快的用户体验,我们同时添加所有 Kubernetes 节点,然后扩大 StatefulSet 的规模。

illustration of phases: adding Kubernetes nodes to the multi-zone cockroachdb cluster

请注意,无论 Pod 被分配到 Kubernetes 节点的顺序如何,都会满足反亲和性。 在这个例子中,Pod 0、1、2 分别被分配到 A、B、C 区,但 Pod 3 和 4 以不同的顺序被分配到 B 和 A 区。 反亲和性仍然得到满足,因为 Pod 仍然被放置在不同的区域。

要从集群中移除资源,我们以相反的顺序执行这些操作。

我们首先缩小 StatefulSet 的规模,然后从集群中移除任何缺少 CockroachDB Pod 的节点。

illustration of phases: scaling down pods in a multi-zone cockroachdb cluster in Kubernetes

现在,请记住,规模为 n 的 StatefulSet 中的 Pods 一定具有 [0,n) 范围内的 id。 当把一个 StatefulSet 规模缩减了 m 时,Kubernetes 会移除 m 个 Pod,从最高的序号开始,向最低的序号移动, 与它们被添加的顺序相反。 考虑一下下面的集群拓扑结构。

illustration: cockroachdb cluster: 6 nodes distributed across 3 availability zones

当从这个集群中移除 5 号到 3 号 Pod 时,这个 StatefulSet 仍然横跨三个可用区。

illustration: removing 3 nodes from a 6-node, 3-zone cockroachdb cluster

然而,Kubernetes 的调度器并不像我们一开始预期的那样 保证 上面的分布。

我们对以下内容的综合认识是导致这种误解的原因。

  • Kubernetes 自动跨区分配 Pod 的能力
  • 一个有 n 个副本的 StatefulSet,当 Pod 被部署时,它们会按照 {0...n-1} 的顺序依次创建。 更多细节见 StatefulSet

考虑以下拓扑结构:

illustration: 6-node cockroachdb cluster distributed across 3 availability zones

这些 Pod 是按顺序创建的,它们分布在集群里所有可用区。当序号 5 到 3 的 Pod 被终止时, 这个集群将从 C 区消失!

illustration: terminating 3 nodes in 6-node cluster spread across 3 availability zones, where 2/2 nodes in the same availability zone are terminated, knocking out that AZ

更糟糕的是,在这个时候,我们的自动化机制将删除节点 A-2,B-2,和 C-2。 并让 CRDB-1 处于未调度状态,因为持久性卷只在其创建时所处的区域内可用。

为了纠正后一个问题,我们现在采用了一种“狩猎和啄食”的方法来从集群中移除机器。 与其盲目地从集群中移除 Kubernetes 节点,不如只移除没有 CockroachDB Pod 的节点。 更为艰巨的任务是管理 Kubernetes 的调度器。

一场头脑风暴后我们有了 3 个选择。

1. 升级到 kubernetes 1.18 并利用 Pod 拓扑分布约束

虽然这似乎是一个完美的解决方案,但在写这篇文章的时候,Kubernetes 1.18 在公有云中两个最常见的 托管 Kubernetes 服务( EKS 和 GKE )上是不可用的。 此外,Pod 拓扑分布约束在 1.18 中仍是测试版功能, 这意味着即使在 v1.18 可用时,它也不能保证在托管集群中可用。 整个努力让人联想到在 Internet Explorer 8 还存在的时候访问 caniuse.com

2. 在每个区部署一个 StatefulSet。

与跨所有可用区部署一个 StatefulSet 相比,在每个区部署一个带有节点亲和性的 StatefulSet 可以实现手动控制分区拓扑结构。 我们的团队过去曾考虑过这个选项,我们也倾向此选项。 但最终,我们决定放弃这个方案,因为这需要对我们的代码库进行大规模的修改,而且在现有的客户集群上进行迁移也是一个同样大的工程。

3. 编写一个自定义的 Kubernetes 调度器

感谢 Kelsey Hightower 的例子和 Banzai Cloud 的博文,我们决定投入进去,编写自己的自定义 Kubernetes 调度器。 一旦我们的概念验证被部署和运行,我们很快就发现,Kubernetes 的调度器也负责将持久化卷映射到它所调度的 Pod 上。 kubectl get events 的输出让我们相信有另一个系统在发挥作用。 在我们寻找负责存储声明映射的组件的过程中,我们发现了 kube-scheduler 插件系统。 我们的下一个 POC 是一个"过滤器"插件,它通过 Pod 的序号来确定适当的可用区域,并且工作得非常完美。

我们的自定义调度器插件是开源的,并在我们所有的 CockroachCloud 集群中运行。 对 StatefulSet Pod 的调度方式有掌控力,让我们有信心扩大规模。 一旦 GKE 和 EKS 中的 Pod 拓扑分布约束可用,我们可能会考虑让我们的插件退役,但其维护的开销出乎意料地低。 更好的是:该插件的实现与我们的业务逻辑是横向的。部署它,或取消它,就像改变 StatefulSet 定义中的 "schedulerName" 字段一样简单。


Chris Seto 是 Cockroach 实验室的一名软件工程师,负责 CockroachCloud CockroachDB 的 Kubernetes 自动化。

Kubernetes 1.20:CSI 驱动程序中的 Pod 身份假扮和短时卷

作者: Shihang Zhang(谷歌)

通常,当 CSI 驱动程序挂载 诸如 Secret 和证书之类的凭据时,它必须通过存储提供者的身份认证才能访问这些凭据。 然而,对这些凭据的访问是根据 Pod 的身份而不是 CSI 驱动程序的身份来控制的。 因此,CSI 驱动程序需要某种方法来取得 Pod 的服务帐户令牌。

当前,有两种不是那么理想的方法来实现这一目的,要么通过授予 CSI 驱动程序使用 TokenRequest API 的权限,要么直接从主机文件系统中读取令牌。

两者都存在以下缺点:

  • 违反最少特权原则
  • 每个 CSI 驱动程序都需要重新实现获取 Pod 的服务帐户令牌的逻辑

第二种方式问题更多,因为:

  • 令牌的受众默认为 kube-apiserver
  • 该令牌不能保证可用(例如,AutomountServiceAccountToken=false
  • 该方法不适用于以与 Pod 不同的(非 root 用户)用户身份运行的 CSI 驱动程序。请参见 服务帐户令牌的文件许可权部分
  • 该令牌可能是旧的 Kubernetes 服务帐户令牌,如果 BoundServiceAccountTokenVolume=false,该令牌不会过期。

Kubernetes 1.20 引入了一个内测功能 CSIServiceAccountToken 以改善安全状况。这项新功能允许 CSI 驱动程序接收 Pod 的绑定服务帐户令牌

此功能还提供了一个重新发布卷的能力,以便可以刷新短时卷。

Pod 身份假扮

使用 GCP APIs

使用 Workload Identity,Kubernetes 服务帐户可以在访问 Google Cloud API 时验证为 Google 服务帐户。 如果 CSI 驱动程序要代表其为挂载卷的 Pod 访问 GCP API,则可以使用 Pod 的服务帐户令牌来 交换 GCP 令牌。启用功能 CSIServiceAccountToken 后, 可通过 NodePublishVolume RPC 调用中的卷上下文来访问 Pod 的服务帐户令牌。例如:通过 Secret 存储 CSI 驱动 访问 Google Secret Manager

使用Vault

如果用户将 Kubernetes 作为身份验证方法配置, 则 Vault 使用 TokenReview API 来验证 Kubernetes 服务帐户令牌。 对于使用 Vault 作为资源提供者的 CSI 驱动程序,它们需要将 Pod 的服务帐户提供给 Vault。 例如,Secret 存储 CSI 驱动证书管理器 CSI 驱动

短时卷

为了使诸如证书之类的短时卷保持有效,CSI 驱动程序可以在其 CSIDriver 对象中指定 RequiresRepublish=true, 以使 kubelet 定期针对已挂载的卷调用 NodePublishVolume。 这些重新发布操作使 CSI 驱动程序可以确保卷内容是最新的。

下一步

此功能是 Alpha 版,预计将在 1.21 版中移至 Beta 版。 请参阅以下 KEP 和 CSI 文档中的更多内容:

随时欢迎您提供反馈!

Kubernetes 1.20: 最新版本

作者: Kubernetes 1.20 发布团队

我们很高兴地宣布 Kubernetes 1.20 的发布,这是我们 2020 年的第三个也是最后一个版本!此版本包含 42 项增强功能:11 项增强功能已升级到稳定版,15 项增强功能正在进入测试版,16 项增强功能正在进入 Alpha 版。

1.20 发布周期在上一个延长的发布周期之后恢复到 11 周的正常节奏。这是一段时间以来功能最密集的版本之一:Kubernetes 创新周期仍呈上升趋势。此版本具有更多的 Alpha 而非稳定的增强功能,表明云原生生态系统仍有许多需要探索的地方。

主题

Volume 快照操作变得稳定

此功能提供了触发卷快照操作的标准方法,并允许用户以可移植的方式在任何 Kubernetes 环境和支持的存储提供程序上合并快照操作。

此外,这些 Kubernetes 快照原语充当基本构建块,解锁为 Kubernetes 开发高级企业级存储管理功能的能力,包括应用程序或集群级备份解决方案。

请注意,快照支持要求 Kubernetes 分销商捆绑 Snapshot 控制器、Snapshot CRD 和验证 webhook。还必须在集群上部署支持快照功能的 CSI 驱动程序。

Kubectl Debug 功能升级到 Beta

kubectl alpha debug 功能在 1.20 中升级到测试版,成为 kubectl debug. 该功能直接从 kubectl 提供对常见调试工作流的支持。此版本的 kubectl 支持的故障排除场景包括:

  • 通过创建使用不同容器映像或命令的 pod 副本,对在启动时崩溃的工作负载进行故障排除。
  • 通过在 pod 的新副本或使用临时容器中添加带有调试工具的新容器来对 distroless 容器进行故障排除。(临时容器是默认未启用的 alpha 功能。)
  • 通过创建在主机命名空间中运行并可以访问主机文件系统的容器来对节点进行故障排除。

请注意,作为新的内置命令,kubectl debug 优先于任何名为 “debug” 的 kubectl 插件。你必须重命名受影响的插件。

kubectl alpha debug 现在不推荐使用,并将在后续版本中删除。更新你的脚本以使用 kubectl debug。 有关更多信息 kubectl debug,请参阅[调试正在运行的 Pod]((https://kubernetes.io/zh-cn/docs/tasks/debug/debug-application/debug-running-pod/)。

测试版:API 优先级和公平性 {#beta-api-priority-and-fairness)

Kubernetes 1.20 由 1.18 引入,现在默认启用 API 优先级和公平性 (APF)。这允许 kube-apiserver 按优先级对传入请求进行分类。

Alpha 更新:IPV4/IPV6

基于用户和社区反馈,重新实现了 IPv4/IPv6 双栈以支持双栈服务。 这允许将 IPv4 和 IPv6 服务集群 IP 地址分配给单个服务,还允许服务从单 IP 堆栈转换为双 IP 堆栈,反之亦然。

GA:进程 PID 稳定性限制

进程 ID (pid) 是 Linux 主机上的基本资源。达到任务限制而不达到任何其他资源限制并导致主机不稳定是很可能发生的。

管理员需要机制来确保用户 pod 不会导致 pid 耗尽,从而阻止主机守护程序(运行时、kubelet 等)运行。此外,重要的是要确保 pod 之间的 pid 受到限制,以确保它们对节点上的其他工作负载的影响有限。 默认启用一年后,SIG Node 在 SupportNodePidsLimit(节点到 Pod PID 隔离)和 SupportPodPidsLimit(限制每个 Pod 的 PID 的能力)上都将 PID 限制升级为 GA。

Alpha:节点体面地关闭

用户和集群管理员希望 Pod 遵守预期的 Pod 生命周期,包括 Pod 终止。目前,当一个节点关闭时,Pod 不会遵循预期的 Pod 终止生命周期,也不会正常终止,这可能会导致某些工作负载出现问题。 该 GracefulNodeShutdown 功能现在处于 Alpha 阶段。GracefulNodeShutdown 使 kubelet 知道节点系统关闭,从而在系统关闭期间正常终止 pod。

主要变化

Dockershim 弃用

Dockershim,Docker 的容器运行时接口 (CRI) shim 已被弃用。不推荐使用对 Docker 的支持,并将在未来版本中删除。由于 Docker 映像遵循开放容器计划 (OCI) 映像规范,因此 Docker 生成的映像将继续在具有所有 CRI 兼容运行时的集群中工作。 Kubernetes 社区写了一篇关于弃用的详细博客文章,并为其提供了一个专门的常见问题解答页面

Exec 探测超时处理

一个关于 exec 探测超时的长期错误可能会影响现有的 pod 定义,已得到修复。在此修复之前,exec 探测器不考虑 timeoutSeconds 字段。相反,探测将无限期运行,甚至超过其配置的截止日期,直到返回结果。 通过此更改,如果未指定值,将应用默认值 1 second,并且如果探测时间超过一秒,现有 pod 定义可能不再足够。 新引入的 ExecProbeTimeout 特性门控所提供的修复使集群操作员能够恢复到以前的行为,但这种行为将在后续版本中锁定并删除。为了恢复到以前的行为,集群运营商应该将此特性门控设置为 false

有关更多详细信息,请查看有关配置探针的更新文档

其他更新

稳定版

值得注意的功能更新

发行说明

你可以在发行说明中查看 1.20 发行版的完整详细信息。

可用的发布

Kubernetes 1.20 可在 GitHub 上下载。有一些很棒的资源可以帮助你开始使用 Kubernetes。你可以在 Kubernetes 主站点上查看一些交互式教程,或者使用 kind 的 Docker 容器在你的机器上运行本地集群。如果你想尝试从头开始构建集群,请查看 Kelsey Hightower 的 Kubernetes the Hard Way 教程。

发布团队

这个版本是由一群非常敬业的人促成的,他们在世界上发生的许多事情的时段作为一个团队走到了一起。 非常感谢发布负责人 Jeremy Rickard 以及发布团队中的其他所有人,感谢他们相互支持,并努力为社区发布 1.20 版本。

发布 Logo

Kubernetes 1.20 Release Logo

raddest: adjective, Slang. excellent; wonderful; cool:

Kubernetes 1.20 版本是迄今为止最激动人心的版本。

2020 年对我们中的许多人来说都是充满挑战的一年,但 Kubernetes 贡献者在此版本中提供了创纪录的增强功能。这是一项了不起的成就,因此发布负责人希望以一点轻松的方式结束这一年,并向 Kubernetes 1.14 - Caturnetes 和一只名叫 Humphrey 的 “rad” 猫致敬。

Humphrey是发布负责人的猫,有一个永久的 blep. 在 1990 年代,Rad 是美国非常普遍的俚语,激光背景也是如此。Humphrey 在 1990 年代风格的学校照片中感觉像是结束这一年的有趣方式。希望 Humphrey 和它的 blep 在 2020 年底给你带来一点快乐!

发布标志由 Henry Hsu - @robotdancebattle 创建。

用户亮点

  • Apple 正在世界各地的数据中心运行数千个节点的 Kubernetes 集群。观看 Alena Prokarchyk 的 KubeCon NA 主题演讲,了解有关他们的云原生之旅的更多信息。

项目速度

CNCF K8S DevStats 项目聚集了许多有关Kubernetes和各分项目的速度有趣的数据点。这包括从个人贡献到做出贡献的公司数量的所有内容,并且清楚地说明了为发展这个生态系统所做的努力的深度和广度。

在持续 11 周(9 月 25 日至 12 月 9 日)的 v1.20 发布周期中,我们看到了来自 26 个国家/地区967 家公司1335 名个人(其中 44 人首次为 Kubernetes 做出贡献)的贡献。

生态系统更新

  • KubeCon North America 三周前刚刚结束,这是第二个虚拟的此类活动!现在所有演讲都可以点播,供任何需要赶上的人使用!
  • 6 月,Kubernetes 社区成立了一个新的工作组,作为对美国各地发生的 Black Lives Matter 抗议活动的直接回应。WG Naming 的目标是尽可能彻底地删除 Kubernetes 项目中有害和不清楚的语言,并以可移植到其他 CNCF 项目的方式进行。在 KubeCon 2020 North America 上就这项重要工作及其如何进行进行了精彩的介绍性演讲,这项工作的初步影响实际上可以在 v1.20 版本中看到
  • 此前于今年夏天宣布,在 Kubecon NA 期间发布了经认证的 Kubernetes 安全专家 (CKS) 认证 ,以便立即安排!遵循 CKA 和 CKAD 的模型,CKS 是一项基于性能的考试,侧重于以安全为主题的能力和领域。该考试面向当前的 CKA 持有者,尤其是那些想要完善其在保护云工作负载方面的基础知识的人(这是我们所有人,对吧?)。

活动更新

KubeCon + CloudNativeCon Europe 2021 将于 2021 年 5 月 4 日至 7 日举行!注册将于 1 月 11 日开放。你可以在此处找到有关会议的更多信息。 请记住,CFP 将于太平洋标准时间 12 月 13 日星期日晚上 11:59 关闭!

即将发布的网络研讨会

请继续关注今年 1 月即将举行的发布网络研讨会。

参与其中

如果你有兴趣为 Kubernetes 社区做出贡献,那么特别兴趣小组 (SIG) 是一个很好的起点。其中许多可能符合你的兴趣!如果你有什么想与社区分享的内容,你可以参加每周的社区会议,或使用以下任一渠道:

别慌: Kubernetes 和 Docker

作者: Jorge Castro, Duffie Cooley, Kat Cosgrove, Justin Garrison, Noah Kantrowitz, Bob Killen, Rey Lejano, Dan “POP” Papandrea, Jeffrey Sica, Davanum “Dims” Srinivas

更新:Kubernetes 通过 dockershim 对 Docker 的支持现已移除。 有关更多信息,请阅读移除 FAQ。 你还可以通过专门的 GitHub issue 讨论弃用。

Kubernetes 从版本 v1.20 之后,弃用 Docker 这个容器运行时。

不必慌张,这件事并没有听起来那么吓人。

弃用 Docker 这个底层运行时,转而支持符合为 Kubernetes 创建的容器运行接口 Container Runtime Interface (CRI) 的运行时。 Docker 构建的镜像,将在你的集群的所有运行时中继续工作,一如既往。

如果你是 Kubernetes 的终端用户,这对你不会有太大影响。 这事并不意味着 Docker 已死、也不意味着你不能或不该继续把 Docker 用作开发工具。 Docker 仍然是构建容器的利器,使用命令 docker build 构建的镜像在 Kubernetes 集群中仍然可以运行。

如果你正在使用 GKE、EKS、或 AKS 这类托管 Kubernetes 服务, 你需要在 Kubernetes 后续版本移除对 Docker 支持之前, 确认工作节点使用了被支持的容器运行时。 如果你的节点被定制过,你可能需要根据你自己的环境和运行时需求更新它们。 请与你的服务供应商协作,确保做出适当的升级测试和计划。

如果你正在运营你自己的集群,那还应该做些工作,以避免集群中断。 在 v1.20 版中,你仅会得到一个 Docker 的弃用警告。 当对 Docker 运行时的支持在 Kubernetes 某个后续发行版(目前的计划是 2021 年晚些时候的 1.22 版)中被移除时, 你需要切换到 containerd 或 CRI-O 等兼容的容器运行时。 只要确保你选择的运行时支持你当前使用的 Docker 守护进程配置(例如 logging)。

那为什么会有这样的困惑,为什么每个人要害怕呢?

我们在这里讨论的是两套不同的环境,这就是造成困惑的根源。 在你的 Kubernetes 集群中,有一个叫做容器运行时的东西,它负责拉取并运行容器镜像。 Docker 对于运行时来说是一个流行的选择(其他常见的选择包括 containerd 和 CRI-O), 但 Docker 并非设计用来嵌入到 Kubernetes,这就是问题所在。

你看,我们称之为 “Docker” 的物件实际上并不是一个物件——它是一个完整的技术堆栈, 它其中一个叫做 “containerd” 的部件本身,才是一个高级容器运行时。 Docker 既酷炫又实用,因为它提供了很多用户体验增强功能,而这简化了我们做开发工作时的操作, Kubernetes 用不到这些增强的用户体验,毕竟它并非人类。

因为这个用户友好的抽象层,Kubernetes 集群不得不引入一个叫做 Dockershim 的工具来访问它真正需要的 containerd。 这不是一件好事,因为这引入了额外的运维工作量,而且还可能出错。 实际上正在发生的事情就是:Dockershim 将在不早于 v1.23 版中从 kubelet 中被移除,也就取消对 Docker 容器运行时的支持。 你心里可能会想,如果 containerd 已经包含在 Docker 堆栈中,为什么 Kubernetes 需要 Dockershim。

Docker 不兼容 CRI, 容器运行时接口。 如果支持,我们就不需要这个 shim 了,也就没问题了。 但这也不是世界末日,你也不需要恐慌——你唯一要做的就是把你的容器运行时从 Docker 切换到其他受支持的容器运行时。

要注意一点:如果你依赖底层的 Docker 套接字(/var/run/docker.sock),作为你集群中工作流的一部分, 切换到不同的运行时会导致你无法使用它。 这种模式经常被称之为嵌套 Docker(Docker in Docker)。 对于这种特殊的场景,有很多选项,比如: kanikoimg、和 buildah

那么,这一改变对开发人员意味着什么?我们还要写 Dockerfile 吗?还能用 Docker 构建镜像吗?

此次改变带来了一个不同的环境,这不同于我们常用的 Docker 交互方式。 你在开发环境中用的 Docker 和你 Kubernetes 集群中的 Docker 运行时无关。 我们知道这听起来让人困惑。 对于开发人员,Docker 从所有角度来看仍然有用,就跟这次改变之前一样。 Docker 构建的镜像并不是 Docker 特有的镜像——它是一个 OCI(开放容器标准)镜像。 任一 OCI 兼容的镜像,不管它是用什么工具构建的,在 Kubernetes 的角度来看都是一样的。 containerdCRI-O 两者都知道怎么拉取并运行这些镜像。 这就是我们制定容器标准的原因。

所以,改变已经发生。 它确实带来了一些问题,但这不是一个灾难,总的说来,这还是一件好事。 根据你操作 Kubernetes 的方式的不同,这可能对你不构成任何问题,或者也只是意味着一点点的工作量。 从一个长远的角度看,它使得事情更简单。 如果你还在困惑,也没问题——这里还有很多事情; Kubernetes 有很多变化中的功能,没有人是100%的专家。 我们鼓励你提出任何问题,无论水平高低、问题难易。 我们的目标是确保所有人都能在即将到来的改变中获得足够的了解。 我们希望这已经回答了你的大部分问题,并缓解了一些焦虑!❤️

还在寻求更多答案吗?请参考我们附带的 移除 Dockershim 的常见问题 (2022年2月更新)

弃用 Dockershim 的常见问题

更新:本文有较新版本

本文回顾了自 Kubernetes v1.20 版宣布弃用 Dockershim 以来所引发的一些常见问题。 关于 Kubernetes kubelets 从容器运行时的角度弃用 Docker 的细节以及这些细节背后的含义,请参考博文 别慌: Kubernetes 和 Docker

此外,你可以阅读检查 Dockershim 移除是否影响你以检查它是否会影响你。

为什么弃用 dockershim

维护 dockershim 已经成为 Kubernetes 维护者肩头一个沉重的负担。 创建 CRI 标准就是为了减轻这个负担,同时也可以增加不同容器运行时之间平滑的互操作性。 但反观 Docker 却至今也没有实现 CRI,所以麻烦就来了。

Dockershim 向来都是一个临时解决方案(因此得名:shim)。 你可以进一步阅读 移除 Dockershim 这一 Kubernetes 增强方案 以了解相关的社区讨论和计划。

此外,与 dockershim 不兼容的一些特性,例如:控制组(cgoups)v2 和用户名字空间(user namespace),已经在新的 CRI 运行时中被实现。 移除对 dockershim 的支持将加速这些领域的发展。

在 Kubernetes 1.20 版本中,我还可以用 Docker 吗?

当然可以,在 1.20 版本中仅有的改变就是:如果使用 Docker 运行时,启动 kubelet 的过程中将打印一条警告日志。

什么时候移除 dockershim

考虑到此改变带来的影响,我们使用了一个加长的废弃时间表。 在 Kubernetes 1.22 版之前,它不会被彻底移除;换句话说,dockershim 被移除的最早版本会是 2021 年底发布的 1.23 版。 更新:dockershim 计划在 Kubernetes 1.24 版被移除, 请参阅移除 Dockershim 这一 Kubernetes 增强方案。 我们将与供应商以及其他生态团队紧密合作,确保顺利过渡,并将依据事态的发展评估后续事项。

从 Kubernetes 中移除后我还能使用 dockershim 吗?

更新:Mirantis 和 Docker 已承诺在 dockershim 从 Kubernetes 中删除后对其进行维护。

我现有的 Docker 镜像还能正常工作吗?

当然可以,docker build 创建的镜像适用于任何 CRI 实现。 所有你的现有镜像将和往常一样工作。

私有镜像呢?

当然可以。所有 CRI 运行时均支持 Kubernetes 中相同的拉取(pull)Secret 配置, 不管是通过 PodSpec 还是通过 ServiceAccount 均可。

Docker 和容器是一回事吗?

虽然 Linux 的容器技术已经存在了很久, 但 Docker 普及了 Linux 容器这种技术模式,并在开发底层技术方面发挥了重要作用。 容器的生态相比于单纯的 Docker,已经进化到了一个更宽广的领域。 像 OCI 和 CRI 这类标准帮助许多工具在我们的生态中成长和繁荣, 其中一些工具替代了 Docker 的某些部分,另一些增强了现有功能。

现在是否有在生产系统中使用其他运行时的例子?

Kubernetes 所有项目在所有版本中出产的工件(Kubernetes 二进制文件)都经过了验证。

此外,kind 项目使用 containerd 已经有年头了, 并且在这个场景中,稳定性还明显得到提升。 Kind 和 containerd 每天都会做多次协调,以验证对 Kubernetes 代码库的所有更改。 其他相关项目也遵循同样的模式,从而展示了其他容器运行时的稳定性和可用性。 例如,OpenShift 4.x 从 2019 年 6 月以来,就一直在生产环境中使用 CRI-O 运行时。

至于其他示例和参考资料,你可以查看 containerd 和 CRI-O 的使用者列表, 这两个容器运行时是云原生基金会(CNCF)下的项目。

人们总在谈论 OCI,那是什么?

OCI 代表开放容器标准, 它标准化了容器工具和底层实现(technologies)之间的大量接口。 他们维护了打包容器镜像(OCI image-spec)和运行容器(OCI runtime-spec)的标准规范。 他们还以 runc 的形式维护了一个 runtime-spec 的真实实现, 这也是 containerdCRI-O 依赖的默认运行时。 CRI 建立在这些底层规范之上,为管理容器提供端到端的标准。

我应该用哪个 CRI 实现?

这是一个复杂的问题,依赖于许多因素。 在 Docker 工作良好的情况下,迁移到 containerd 是一个相对容易的转换,并将获得更好的性能和更少的开销。 然而,我们建议你先探索 CNCF 全景图 提供的所有选项,以做出更适合你的环境的选择。

当切换 CRI 底层实现时,我应该注意什么?

Docker 和大多数 CRI(包括 containerd)的底层容器化代码是相同的,但其周边部分却存在一些不同。 迁移时一些常见的关注点是:

  • 日志配置
  • 运行时的资源限制
  • 直接访问 docker 命令或通过控制套接字调用 Docker 的节点供应脚本
  • 需要访问 docker 命令或控制套接字的 kubectl 插件
  • 需要直接访问 Docker 的 Kubernetes 工具(例如:kube-imagepuller)
  • 配置像 registry-mirrors 和不安全的镜像仓库等功能
  • 需要 Docker 保持可用、且运行在 Kubernetes 之外的,其他支持脚本或守护进程(例如:监视或安全代理)
  • GPU 或特殊硬件,以及它们如何与你的运行时和 Kubernetes 集成

如果你只是用了 Kubernetes 资源请求/限制或基于文件的日志收集 DaemonSet,它们将继续稳定工作, 但是如果你用了自定义了 dockerd 配置,则可能需要为新容器运行时做一些适配工作。

另外还有一个需要关注的点,那就是当创建镜像时,系统维护或嵌入容器方面的任务将无法工作。 对于前者,可以用 crictl 工具作为临时替代方案 (参见从 docker 命令映射到 crictl); 对于后者,可以用新的容器创建选项,比如 crimgbuildahkaniko、或 buildkit-cli-for-kubectl, 他们均不需要访问 Docker。

对于 containerd,你可以从它们的 文档 开始,看看在迁移过程中有哪些配置选项可用。

对于如何协同 Kubernetes 使用 containerd 和 CRI-O 的说明,参见 Kubernetes 文档中这部分: 容器运行时

我还有问题怎么办?

如果你使用了一个有供应商支持的 Kubernetes 发行版,你可以咨询供应商他们产品的升级计划。 对于最终用户的问题,请把问题发到我们的最终用户社区的论坛

你也可以看看这篇优秀的博文: 等等,Docker 刚刚被 Kubernetes 废掉了? 一个对此变化更深入的技术讨论。

我可以加入吗?

只要你愿意,随时随地欢迎加入!

为开发指南做贡献

一位新的贡献者描述了编写和提交对 Kubernetes 开发指南的修改的经验。

当大多数人想到为一个开源项目做贡献时,我猜想他们可能想到的是贡献代码修改、新功能和错误修复。作为一个软件工程师和一个长期的开源用户和贡献者,这也正是我的想法。 虽然我已经在不同的工作流中写了不少文档,但规模庞大的 Kubernetes 社区是一种新型 "客户"。我只是不知道当 Google 要求我和 Lion's Way 的同胞们对 Kubernetes 开发指南进行必要更新时会发生什么。

本文最初出现在 Kubernetes Contributor Community blog

与社区合作的乐趣

作为专业的写手,我们习惯了受雇于他人去书写非常具体的项目。我们专注于技术服务,产品营销,技术培训以及文档编制,范围从相对宽松的营销邮件到针对 IT 和开发人员的深层技术白皮书。 在这种专业服务下,每一个可交付的项目往往都有可衡量的投资回报。我知道在从事开源文档工作时不会出现这个指标,但我不确定它将如何改变我与项目的关系。

我们的写作和传统客户之间的关系有一个主要的特点,就是我们在一个公司里面总是有一两个主要的对接人。他们负责审查我们的文稿,并确保文稿内容符合公司的声明且对标于他们正在寻找的受众。 这随之而来的压力--正好解释了为什么我很高兴我的写作伙伴、鹰眼审稿人同时也是嗜血编辑的 Joel 处理了大部分的客户联系。

在与 Kubernetes 社区合作时,所有与客户接触的压力都消失了,这让我感到惊讶和高兴。

"我必须得多仔细?如果我搞砸了怎么办?如果我让开发商生气了怎么办?如果我树敌了怎么办?"。 当我第一次加入 Kubernetes Slack 上的 "#sig-contribex " 频道并宣布我将编写 开发指南 时,这些问题都在我脑海中奔腾,让我感觉如履薄冰。

"Kubernetes 编码准则已经生效,让我们共同勉励。" — Jorge Castro, SIG ContribEx co-chair

事实上我的担心是多虑的。很快,我就感觉到自己是被欢迎的。我倾向于认为这不仅仅是因为我正在从事一项急需的任务,而是因为 Kubernetes 社区充满了友好、热情的人们。 在每周的 SIG ContribEx 会议上,我们关于开发指南进展情况的报告会被立即纳入其中。此外,会议的领导会一直强调 Kubernetes 编码准则,我们应该像 Bill 和 Ted 一样,相互进步。

这并不意味着这一切都很简单

开发指南需要一次全面检查。当我们拿到它的时候,它已经捆绑了大量的信息和很多新开发者需要经历的步骤,但随着时间的推移和被忽视,它变得相当陈旧。 文档的确需要全局观,而不仅仅是点与点的修复。结果,最终我向这个项目提交了一个巨大的 pull 请求。社区仓库:新增 267 行,删除 88 行。

pull 请求的周期需要一定数量的 Kubernetes 组织成员审查和批准更改后才能合并。这是一个很好的做法,因为它使文档和代码都保持在相当不错的状态, 但要哄骗合适的人花时间来做这样一个赫赫有名的审查是很难的。 因此,那次大规模的 PR 从我第一次提交到最后合并,用了 26 天。 但最终,它是成功的.

由于 Kubernetes 是一个发展相当迅速的项目,而且开发人员通常对编写文档并不十分感兴趣,所以我也遇到了一个问题,那就是有时候, 描述 Kubernetes 子系统工作原理的秘密珍宝被深埋在 天才工程师的迷宫式思维 中,而不是用单纯的英文写在 Markdown 文件中。 当我要更新端到端(e2e)测试的入门文档时,就一头撞上了这个问题。

这段旅程将我带出了编写文档的领域,进入到一些未完成软件的全新用户角色。最终我花了很多心思与新的 kubetest2`框架 的开发者之一合作, 记录了最新 e2e 测试的启动和运行过程。 你可以通过查看我的 已完成的 pull request 来自己判断结果。

没有人是老板,每个人都给出反馈。

但当我暗自期待混乱的时候,为 Kubernetes 开发指南做贡献以及与神奇的 Kubernetes 社区互动的过程却非常顺利。 没有争执,我也没有树敌。每个人都非常友好和热情。这是令人愉快的

对于一个开源项目,没人是老板。Kubernetes 项目,一个近乎巨大的项目,被分割成许多不同的特殊兴趣小组(SIG)、工作组和社区。 每个小组都有自己的定期会议、职责分配和主席推选。我的工作与 SIG ContribEx(负责监督并寻求改善贡献者体验)和 SIG Testing(负责测试)的工作有交集。 事实证明,这两个 SIG 都很容易合作,他们渴望贡献,而且都是非常友好和热情的人。

在 Kubernetes 这样一个活跃的、有生命力的项目中,文档仍然需要与代码库一起进行维护、修订和测试。 开发指南将继续对 Kubernetes 代码库的新贡献者起到至关重要的作用,正如我们的努力所显示的那样,该指南必须与 Kubernetes 项目的发展保持同步。

Joel 和我非常喜欢与 Kubernetes 社区互动并为开发指南做出贡献。我真的很期待,不仅能继续做出更多贡献,还能继续与过去几个月在这个庞大的开源社区中结识的新朋友进行合作。

结构化日志介绍

作者: Marek Siarkowicz(谷歌),Nathan Beach(谷歌)

日志是可观察性的一个重要方面,也是调试的重要工具。 但是Kubernetes日志传统上是非结构化的字符串,因此很难进行自动解析,以及任何可靠的后续处理、分析或查询。

在Kubernetes 1.19中,我们添加结构化日志的支持,该日志本身支持(键,值)对和对象引用。 我们还更新了许多日志记录调用,以便现在将典型部署中超过99%的日志记录量迁移为结构化格式。

为了保持向后兼容性,结构化日志仍将作为字符串输出,其中该字符串包含这些“键” =“值”对的表示。 从1.19的Alpha版本开始,日志也可以使用--logging-format = json标志以JSON格式输出。

使用结构化日志

我们在klog库中添加了两个新方法:InfoS和ErrorS。 例如,InfoS的此调用:

klog.InfoS("Pod status updated", "pod", klog.KObj(pod), "status", status)

将得到下面的日志输出:

I1025 00:15:15.525108       1 controller_utils.go:116] "Pod status updated" pod="kube-system/kubedns" status="ready"

或者, 如果 --logging-format=json 模式被设置, 将会产生如下结果:

{
  "ts": 1580306777.04728,
  "msg": "Pod status updated",
  "pod": {
    "name": "coredns",
    "namespace": "kube-system"
  },
  "status": "ready"
}

这意味着下游日志记录工具可以轻松地获取结构化日志数据,而无需使用正则表达式来解析非结构化字符串。这也使处理日志更容易,查询日志更健壮,并且分析日志更快。

使用结构化日志,所有对Kubernetes对象的引用都以相同的方式进行结构化,因此您可以过滤输出并且仅引用特定Pod的日志条目。您还可以发现指示调度程序如何调度Pod,如何创建Pod,监测Pod的运行状况以及Pod生命周期中的所有其他更改的日志。

假设您正在调试Pod的问题。使用结构化日志,您可以只过滤查看感兴趣的Pod的日志条目,而无需扫描可能成千上万条日志行以找到相关的日志行。

结构化日志不仅在手动调试问题时更有用,而且还启用了更丰富的功能,例如日志的自动模式识别或日志和所跟踪数据的更紧密关联性(分析)。

最后,结构化日志可以帮助降低日志的存储成本,因为大多数存储系统比非结构化字符串更有效地压缩结构化键值数据。

参与其中

虽然在典型部署中,我们已按日志量更新了99%以上的日志条目,但仍有数千个日志需要更新。 选择一个您要改进的文件或目录,然后迁移现有的日志调用以使用结构化日志。这是对Kubernetes做出第一笔贡献的好方法!

警告: 有用的预警

作者: Jordan Liggitt (Google)

作为 Kubernetes 维护者,我们一直在寻找在保持兼容性的同时提高可用性的方法。 在开发功能、分类 Bug、和回答支持问题的过程中,我们积累了有助于 Kubernetes 用户了解的信息。 过去,共享这些信息仅限于发布说明、公告电子邮件、文档和博客文章等带外方法。 除非有人知道需要寻找这些信息并成功找到它们,否则他们不会从中受益。

在 Kubernetes v1.19 中,我们添加了一个功能,允许 Kubernetes API 服务器向 API 客户端发送警告。 警告信息使用标准 Warning 响应头发送, 因此它不会以任何方式更改状态代码或响应体。 这一设计使得服务能够发送任何 API 客户端都可以轻松读取的警告,同时保持与以前的客户端版本兼容。

警告在 kubectl v1.19+ 的 stderr 输出中和 k8s.io/client-go v0.19.0+ 客户端库的日志中出现。 k8s.io/client-go 行为可以在进程或客户端层面重载

弃用警告

我们第一次使用此新功能是针对已弃用的 API 调用发送警告。

Kubernetes 是一个大型、快速发展的项目。 跟上每个版本的变更可能是令人生畏的, 即使对于全职从事该项目的人来说也是如此。一种重要的变更是 API 弃用。 随着 Kubernetes 中的 API 升级到 GA 版本,预发布的 API 版本会被弃用并最终被删除。

即使有延长的弃用期, 并且在发布说明中也包含了弃用信息, 他们仍然很难被追踪。在弃用期内,预发布 API 仍然有效, 允许多个版本过渡到稳定的 API 版本。 然而,我们发现用户往往甚至没有意识到他们依赖于已弃用的 API 版本, 直到升级到不再提供相应服务的新版本。

从 v1.19 开始,系统每当收到针对已弃用的 REST API 的请求时,都会返回警告以及 API 响应。 此警告包括有关 API 将不再可用的版本以及替换 API 版本的详细信息。

因为警告源自服务器端,并在客户端层级被拦截,所以它适用于所有 kubectl 命令, 包括像 kubectl apply 这样的高级命令,以及像 kubectl get --raw 这样的低级命令:

kubectl 执行一个清单文件, 然后显示警告信息 'networking.k8s.io/v1beta1 Ingress is deprecated in v1.19+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress'。

这有助于受弃用影响的人们知道他们所请求的API已被弃用, 他们有多长时间来解决这个问题,以及他们应该使用什么 API。 这在用户应用不是由他们创建的清单文件时特别有用, 所以他们有时间联系作者要一个更新的版本。

我们还意识到使用已弃用的 API 的人通常不是负责升级集群的人, 因此,我们添加了两个面向管理员的工具来帮助跟踪已弃用的 API 的使用情况并确定何时升级安全。

度量指标

从 Kubernetes v1.19 开始,当向已弃用的 REST API 端点发出请求时, 在 kube-apiserver 进程中,apiserver_requested_deprecated_apis 度量指标会被设置为 1。 该指标具有 API groupversionresourcesubresource 的标签, 和一个 removed_release 标签,表明不再提供 API 的 Kubernetes 版本。

下面是一个使用 kubectl 的查询示例,prom2jsonjq 用来确定当前 API 服务器实例上收到了哪些对已弃用的 API 请求:

kubectl get --raw /metrics | prom2json | jq '
  .[] | select(.name=="apiserver_requested_deprecated_apis").metrics[].labels
'

输出:

{
  "group": "extensions",
  "removed_release": "1.22",
  "resource": "ingresses",
  "subresource": "",
  "version": "v1beta1"
}
{
  "group": "rbac.authorization.k8s.io",
  "removed_release": "1.22",
  "resource": "clusterroles",
  "subresource": "",
  "version": "v1beta1"
}

输出展示在此服务器上请求了已弃用的 extensions/v1beta1 Ingress 和 rbac.authorization.k8s.io/v1beta1 ClusterRole API,这两个 API 都将在 v1.22 中被删除。

我们可以将该信息与 apiserver_request_total 指标结合起来,以获取有关这些 API 请求的更多详细信息:

kubectl get --raw /metrics | prom2json | jq '
  # set $deprecated to a list of deprecated APIs
  [
    .[] | 
    select(.name=="apiserver_requested_deprecated_apis").metrics[].labels |
    {group,version,resource}
  ] as $deprecated 
  
  |
  
  # select apiserver_request_total metrics which are deprecated
  .[] | select(.name=="apiserver_request_total").metrics[] |
  select(.labels | {group,version,resource} as $key | $deprecated | index($key))
'

输出:

{
  "labels": {
    "code": "0",
    "component": "apiserver",
    "contentType": "application/vnd.kubernetes.protobuf;stream=watch",
    "dry_run": "",
    "group": "extensions",
    "resource": "ingresses",
    "scope": "cluster",
    "subresource": "",
    "verb": "WATCH",
    "version": "v1beta1"
  },
  "value": "21"
}
{
  "labels": {
    "code": "200",
    "component": "apiserver",
    "contentType": "application/vnd.kubernetes.protobuf",
    "dry_run": "",
    "group": "extensions",
    "resource": "ingresses",
    "scope": "cluster",
    "subresource": "",
    "verb": "LIST",
    "version": "v1beta1"
  },
  "value": "1"
}
{
  "labels": {
    "code": "200",
    "component": "apiserver",
    "contentType": "application/json",
    "dry_run": "",
    "group": "rbac.authorization.k8s.io",
    "resource": "clusterroles",
    "scope": "cluster",
    "subresource": "",
    "verb": "LIST",
    "version": "v1beta1"
  },
  "value": "1"
}

上面的输出展示,对这些 API 发出的都只是读请求,并且大多数请求都用来监测已弃用的 Ingress API。

你还可以通过以下 Prometheus 查询获取这一信息, 该查询返回关于已弃用的、将在 v1.22 中删除的 API 请求的信息:

apiserver_requested_deprecated_apis{removed_release="1.22"} * on(group,version,resource,subresource)
group_right() apiserver_request_total

审计注解

度量指标是检查是否正在使用已弃用的 API 以及使用率如何的快速方法, 但它们没有包含足够的信息来识别特定的客户端或 API 对象。 从 Kubernetes v1.19 开始, 对已弃用的 API 的请求进行审计时,审计事件中会包括 审计注解 "k8s.io/deprecated":"true"。 管理员可以使用这些审计事件来识别需要更新的特定客户端或对象。

自定义资源定义

除了 API 服务器对已弃用的 API 使用发出警告的能力外,从 v1.19 开始,CustomResourceDefinition 可以指示它定义的资源的特定版本已被弃用。 当对自定义资源的已弃用的版本发出 API 请求时,将返回一条警告消息,与内置 API 的行为相匹配。

CustomResourceDefinition 的作者还可以根据需要自定义每个版本的警告。 这允许他们在需要时提供指向迁移指南的信息或其他信息。

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
  name: crontabs.example.com
spec:
  versions:
  - name: v1alpha1
    # 这表示 v1alpha1 版本的自定义资源已经废弃了。
    # 对此版本的 API 请求会在服务器响应中收到警告。
    deprecated: true
    # 这会把返回给发出 v1alpha1 API 请求的客户端的默认警告覆盖。
    deprecationWarning: "example.com/v1alpha1 CronTab is deprecated; use example.com/v1 CronTab (see http://example.com/v1alpha1-v1)"
    ...

  - name: v1beta1
    # 这表示 v1beta1 版本的自定义资源已经废弃了。
    # 对此版本的 API 请求会在服务器响应中收到警告。
    # 此版本返回默认警告消息。
    deprecated: true
    ...

  - name: v1
    ...

准入 Webhook

准入 Webhook是将自定义策略或验证与 Kubernetes 集成的主要方式。 从 v1.19 开始,Admission Webhook 可以返回警告消息, 传递给发送请求的 API 客户端。警告可以与允许或拒绝的响应一起返回。

例如,允许请求但警告已知某个配置无法正常运行时,准入 Webhook 可以发送以下响应:

{
  "apiVersion": "admission.k8s.io/v1",
  "kind": "AdmissionReview",
  "response": {
    "uid": "<value from request.uid>",
    "allowed": true,
    "warnings": [
      ".spec.memory: requests >1GB do not work on Fridays"
    ]
  }
}

如果你在实现一个返回警告消息的 Webhook,这里有一些提示:

  • 不要在消息中包含 “Warning:” 前缀(由客户端在输出时添加)
  • 使用警告消息来正确描述能被发出 API 请求的客户端纠正或了解的问题
  • 保持简洁;如果可能,将警告限制为 120 个字符以内

准入 Webhook 可以通过多种方式使用这个新功能,我期待看到大家想出来的方法。 这里有一些想法可以帮助你入门:

  • 添加 “complain” 模式的 Webhook 实现,它们返回警告而不是拒绝, 允许在开始执行之前尝试策略以验证它是否按预期工作
  • “lint” 或 “vet” 风格的 Webhook,检查对象并在未遵循最佳实践时显示警告

自定义客户端处理方式

使用 k8s.io/client-go 库发出 API 请求的应用程序可以定制如何处理从服务器返回的警告。 默认情况下,收到的警告会以日志形式输出到 stderr, 但在进程层面或[客户端层面] (https://godoc.org/k8s.io/client-go/rest#Config)均可定制这一行为。

这个例子展示了如何让你的应用程序表现得像 kubectl, 在进程层面重载整个消息处理逻辑以删除重复的警告, 并在支持的情况下使用彩色输出突出显示消息:

import (
  "os"
  "k8s.io/client-go/rest"
  "k8s.io/kubectl/pkg/util/term"
  ...
)

func main() {
  rest.SetDefaultWarningHandler(
    rest.NewWarningWriter(os.Stderr, rest.WarningWriterOptions{
        // only print a given warning the first time we receive it
        Deduplicate: true,
        // highlight the output with color when the output supports it
        Color: term.AllowsColorOutput(os.Stderr),
      },
    ),
  )

  ...

下一个示例展示如何构建一个忽略警告的客户端。 这对于那些操作所有资源类型(使用发现 API 在运行时动态发现) 的元数据并且不会从已弃用的特定资源的警告中受益的客户端很有用。 对于需要使用特定 API 的客户端,不建议抑制弃用警告。

import (
  "k8s.io/client-go/rest"
  "k8s.io/client-go/kubernetes"
)

func getClientWithoutWarnings(config *rest.Config) (kubernetes.Interface, error) {
  // copy to avoid mutating the passed-in config
  config = rest.CopyConfig(config)
  // set the warning handler for this client to ignore warnings
  config.WarningHandler = rest.NoWarnings{}
  // construct and return the client
  return kubernetes.NewForConfig(config)
}

Kubectl 强制模式

如果你想确保及时注意到弃用问题并立即着手解决它们, kubectl 在 v1.19 中添加了 --warnings-as-errors 选项。使用此选项调用时, kubectl 将从服务器收到的所有警告视为错误,并以非零码退出:

kubectl 在设置 --warnings-as-errors 标记的情况下执行一个清单文件, 返回警告消息和非零退出码。

这可以在 CI 作业中用于将清单文件应用到当前服务器, 其中要求通过零退出码才能使 CI 作业成功。

未来的可能性

现在我们有了一种在上下文中向用户传达有用信息的方法, 我们已经在考虑使用其他方法来改善人们使用 Kubernetes 的体验。 我们接下来要研究的几个领域是关于已知有问题的值的警告。 出于兼容性原因,我们不能直接拒绝,而应就使用已弃用的字段或字段值 (例如使用 beta os/arch 节点标签的选择器, 在 v1.14 中已弃用) 给出警告。 我很高兴看到这方面的进展,继续让 Kubernetes 更容易使用。

Docsy 带来更好的 Docs UX

作者: Zach Corleissen,Cloud Native Computing Foundation

编者注:Zach 是 Kubernetes 文档特别兴趣小组(SIG Docs)的主席之一。

我很高兴地宣布 Kubernetes 网站现在采用了 Docsy Hugo 主题

Docsy 主题改进了网站的组织结构和导航性能,并开辟了改进 API 参考的途径。 在 4 年多的时间里,尽管对用户体验方面的改进不多,但 Docsy 针对技术内容实现了一些最佳实践。 该主题使 Kubernetes 网站更易于阅读,并使各个页面更易于导航。 它大大改进了网站所需的外在形象。

例如:添加用于在页面上导航主题的右侧栏。无需再向上滚动导航!

该主题为网站的未来改进开辟了道路。 我最兴奋的 Docsy 功能是主题的 swaggerui shortcode, 它为从 OpenAPI 规范生成 API 引用提供了本地支持。 CNCF 正在与 Google Season of Docs(GSoD)合作,希望在今年第四季度实现更好的 API 参考。 我们很有希望被选中,我们期待着谷歌在 8 月 16 日公布的项目清单。 自从我 2017 年第一次开始使用 SIG Docs 以来,更好的 API 参考一直是我的个人目标。 看到这个目标触手可及,真是令人兴奋。

作为 SIG Docs 的技术负责人之一,Karen Bradshaw 做了很多繁重的工作来解决广泛的网站兼容性问题, 包括在 2018 年我们从 Jekyll 迁移到 Hugo 时修复的最后一个遗留问题。 我们的其他技术负责人,Tim BannisterTaylor Dolezal 提出过很多意见。

还要感谢 Björn-Erik Pedersen,他提供了关于如何在 0.60.0 版本之后进行 Hugo 升级的宝贵建议。

CNCF 与不列颠哥伦比亚省维多利亚市的 Gearbox 签约,将主题应用于该网站。 感谢 Aidan、Troy 和团队其他成员的所有工作!

Kubernetes 1.18: Fit & Finish

作者: Kubernetes 1.18 发布团队

我们很高兴宣布 Kubernetes 1.18 版本的交付,这是我们 2020 年的第一版!Kubernetes 1.18 包含 38 个增强功能:15 项增强功能已转为稳定版,11 项增强功能处于 beta 阶段,12 项增强功能处于 alpha 阶段。

Kubernetes 1.18 是一个近乎 “完美” 的版本。为了改善 beta 和稳定的特性,已进行了大量工作, 以确保用户获得更好的体验。我们在增强现有功能的同时也增加了令人兴奋的新特性,这些有望进一步增强用户体验。

对 alpha、beta 和稳定版进行几乎同等程度的增强是一项伟大的成就。它展现了社区在提高 Kubernetes 的可靠性以及继续扩展其现有功能方面所做的巨大努力。

主要内容

Kubernetes 拓扑管理器(Topology Manager)进入 Beta 阶段 - 对齐!

Kubernetes 在 1.18 版中的 Beta 阶段功能拓扑管理器特性启用 CPU 和设备(例如 SR-IOV VF)的 NUMA 对齐,这将使你的工作负载在针对低延迟而优化的环境中运行。 在引入拓扑管理器之前,CPU 和设备管理器将做出彼此独立的资源分配决策。 这可能会导致在多处理器系统上非预期的资源分配结果,从而导致对延迟敏感的应用程序的性能下降。

Serverside Apply 推出 Beta 2

Serverside Apply 在1.16 中进入 Beta 阶段,但现在在 1.18 中进入了第二个 Beta 阶段。 这个新版本将跟踪和管理所有新 Kubernetes 对象的字段更改,从而使你知道什么更改了资源以及何时发生了更改。

使用 IngressClass 扩展 Ingress 并用 IngressClass 替换已弃用的注释

在 Kubernetes 1.18 中,Ingress 有两个重要的补充:一个新的 pathType 字段和一个新的 IngressClass 资源。pathType 字段允许指定路径的匹配方式。除了默认的 ImplementationSpecific 类型外,还有新的 ExactPrefix 路径类型。

IngressClass 资源用于描述 Kubernetes 集群中 Ingress 的类型。Ingress 对象可以通过在 Ingress 资源类型上使用新的 ingressClassName 字段来指定与它们关联的类。 这个新的资源和字段替换了不再建议使用的 kubernetes.io/ingress.class 注解。

SIG-CLI 引入了 kubectl alpha debug

SIG-CLI 一直在争论着调试工具的必要性。随着临时容器的发展, 我们如何使用基于 kubectl exec 的工具来支持开发人员的必要性变得越来越明显。 kubectl alpha debug 命令的增加, (由于是 alpha 阶段,非常欢迎你反馈意见),使开发人员可以轻松地在集群中调试 Pod。 我们认为这个功能的价值非常高。此命令允许创建一个临时容器,该容器在要尝试检查的 Pod 旁边运行,并且还附加到控制台以进行交互式故障排除。

为 Kubernetes 引入 Windows CSI 支持(Alpha)

用于 Windows 的 CSI 代理的 Alpha 版本随 Kubernetes 1.18 一起发布。CSI 代理通过允许 Windows 中的容器执行特权存储操作来启用 Windows 上的 CSI 驱动程序。

其它更新

毕业转为稳定版

主要变化

发布说明

在我们的发布文档中查看 Kubernetes 1.18 发行版的完整详细信息。

下载安装

Kubernetes 1.18 可以在 GitHub 上下载。要开始使用 Kubernetes,请查看这些交互教程或通过 kind 使用 Docker 容器运行本地 kubernetes 集群。你还可以使用 kubeadm 轻松安装 1.18。

发布团队

通过数百位贡献了技术和非技术内容的个人的努力,使本次发行成为可能。 特别感谢由 Searchable AI 的网站可靠性工程师 Jorge Alarcon Ochoa 领导的发布团队。 34 位发布团队成员协调了发布的各个方面,从文档到测试、验证和功能完整性。

随着 Kubernetes 社区的发展壮大,我们的发布过程很好地展示了开源软件开发中的协作。 Kubernetes 继续快速获取新用户。这种增长创造了一个积极的反馈回路, 其中有更多的贡献者提交了代码,从而创建了更加活跃的生态系统。迄今为止,Kubernetes 已有 40,000 独立贡献者和一个超过 3000 人的活跃社区。

Kubernetes 1.18 发布图标

为什么是 LHC

LHC 是世界上最大,功能最强大的粒子加速器。它是由来自世界各地成千上万科学家合作的结果, 所有这些合作都是为了促进科学的发展。以类似的方式,Kubernetes 已经成为一个聚集了来自数百个组织的数千名贡献者–所有人都朝着在各个方面改善云计算的相同目标努力的项目! 发布名称 “A Bit Quarky” 的意思是提醒我们,非常规的想法可以带来巨大的变化,对开放性保持开放态度将有助于我们进行创新。

关于设计者

Maru Lango 是目前居住在墨西哥城的设计师。她的专长是产品设计,她还喜欢使用 CSS + JS 进行品牌、插图和视觉实验,为技术和设计社区的多样性做贡献。你可能会在大多数社交媒体上以 @marulango 的身份找到她,或查看她的网站: https://marulango.com

高光用户

  • 爱立信正在使用 Kubernetes 和其他云原生技术来交付高标准的 5G 网络, 这可以在 CI/CD 上节省多达 90% 的支出。
  • Zendesk 正在使用 Kubernetes 运行其现有应用程序的约 70%。 它还正在使所构建的所有新应用都可以在 Kubernetes 上运行,从而节省时间、提高灵活性并加快其应用程序开发的速度。
  • LifeMiles 因迁移到 Kubernetes 而降低了 50% 的基础设施开支。 Kubernetes 还使他们可以将其可用资源容量增加一倍。

生态系统更新

  • CNCF 发布了年度调查的结果, 表明 Kubernetes 在生产中的使用正在飞速增长。调查发现,有 78% 的受访者在生产中使用 Kubernetes,而去年这一比例为 58%。
  • CNCF 举办的 “Kubernetes 入门” 课程有超过 100,000 人注册

项目速度

CNCF 继续完善 DevStats。这是一个雄心勃勃的项目,旨在对项目中的无数贡献数据进行可视化展示。 K8s DevStats 展示了主要公司贡献者的贡献细目, 以及一系列令人印象深刻的预定义的报告,涉及从贡献者个人的各方面到 PR 生命周期的各个方面。

在过去的一个季度中,641 家不同的公司和超过 6,409 个个人为 Kubernetes 作出贡献。 查看 DevStats 以了解有关 Kubernetes 项目和社区发展速度的信息。

活动信息

Kubecon + CloudNativeCon EU 2020 已经推迟 - 有关最新信息, 请查看新型肺炎发布页面

即将到来的发布的线上会议

在 2020 年 4 月 23 日,和 Kubernetes 1.18 版本团队一起了解此版本的主要功能, 包括 kubectl debug、拓扑管理器、Ingress 毕业为 V1 版本以及 client-go。 在此处注册: https://www.cncf.io/webinars/kubernetes-1-18/

如何参与

参与 Kubernetes 的最简单方法是加入众多与你的兴趣相关的特别兴趣小组(SIGs)之一。 你有什么想向 Kubernetes 社区发布的内容吗?参与我们的每周社区会议, 并通过以下渠道分享你的声音。感谢你一直以来的反馈和支持。

基于 MIPS 架构的 Kubernetes 方案

作者: 石光银,尹东超,展望,江燕,蔡卫卫,高传集,孙思清(浪潮)

背景

MIPS (Microprocessor without Interlocked Pipelined Stages) 是一种采取精简指令集(RISC)的处理器架构 (ISA),出现于 1981 年,由 MIPS 科技公司开发。如今 MIPS 架构被广泛应用于许多电子产品上。

Kubernetes 官方目前支持众多 CPU 架构诸如 x86, arm/arm64, ppc64le, s390x 等。然而目前还不支持 MIPS 架构,始终是一个遗憾。随着云原生技术的广泛应用,MIPS 架构下的用户始终对 Kubernetes on MIPS 有着迫切的需求。

成果

多年来,为了丰富开源社区的生态,我们一直致力于在 MIPS 架构下适配 Kubernetes。随着 MIPS CPU 的不断迭代优化和性能的提升,我们在 mips64el 平台上取得了一些突破性的进展。

多年来,我们一直积极投入 Kubernetes 社区,在 Kubernetes 技术应用和优化方面具备了丰富的经验。最近,我们在研发过程中尝试将 Kubernetes 适配到 MIPS 架构平台,并取得了阶段性成果。成功完成了 Kubernetes 以及相关组件的迁移适配,不仅搭建出稳定高可用的 MIPS 集群,同时完成了 Kubernetes v1.16.2 版本的一致性测试。

Kubernetes on MIPS

图一 Kubernetes on MIPS

K8S-MIPS 组件构建

几乎所有的 Kubernetes 相关的云原生组件都没有提供 MIPS 版本的安装包或镜像,在 MIPS 平台上部署 Kubernetes 的前提是自行编译构建出全部所需组件。这些组件主要包括:

  • golang
  • docker-ce
  • hyperkube
  • pause
  • etcd
  • calico
  • coredns
  • metrics-server

得益于 Golang 优秀的设计以及对于 MIPS 平台的良好支持,极大地简化了上述云原生组件的编译过程。首先,我们在 mips64el 平台编译出了最新稳定的 golang, 然后通过源码构建的方式编译完成了上述大部分组件。

在编译过程中,我们不可避免地遇到了很多平台兼容性的问题,比如关于 golang 系统调用 (syscall) 的兼容性问题, syscall.Stat_t 32 位 与 64 位类型转换,EpollEvent 修正位缺失等等。

构建 K8S-MIPS 组件主要使用了交叉编译技术。构建过程包括集成 QEMU 工具来实现 MIPS CPU 指令的转换。同时修改 Kubernetes 和 E2E 镜像的构建脚本,构建了 Hyperkube 和 MIPS 架构的 E2E 测试镜像。

成功构建出以上组件后,我们使用工具完成 Kubernetes 集群的搭建,比如 kubespray、kubeadm 等。

名称 版本 MIPS 镜像仓库
MIPS 版本 golang 1.12.5 -
MIPS 版本 docker-ce 18.09.8 -
MIPS 版本 CKE 构建 metrics-server 0.3.2 registry.inspurcloud.cn/library/cke/kubernetes/metrics-server-mips64el:v0.3.2
MIPS 版本 CKE 构建 etcd 3.2.26 registry.inspurcloud.cn/library/cke/etcd/etcd-mips64el:v3.2.26
MIPS 版本 CKE 构建 pause 3.1 registry.inspurcloud.cn/library/cke/kubernetes/pause-mips64el:3.1
MIPS 版本 CKE 构建 hyperkube 1.14.3 registry.inspurcloud.cn/library/cke/kubernetes/hyperkube-mips64el:v1.14.3
MIPS 版本 CKE 构建 coredns 1.6.5 registry.inspurcloud.cn/library/cke/kubernetes/coredns-mips64el:v1.6.5
MIPS 版本 CKE 构建 calico 3.8.0 registry.inspurcloud.cn/library/cke/calico/cni-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/ctl-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/node-mips64el:v3.8.0 registry.inspurcloud.cn/library/cke/calico/kube-controllers-mips64el:v3.8.0

: CKE 是浪潮推出的一款基于 Kubernetes 的容器云服务引擎

K8S-MIPS Cluster Components

图二 K8S-MIPS 集群组件

CPU Architecture

图三 CPU 架构

Cluster Node Information

图四 集群节点信息

运行 K8S 一致性测试

验证 K8S-MIP 集群稳定性和可用性最简单直接的方式是运行 Kubernetes 的 一致性测试

一致性测试是一个独立的容器,用于启动 Kubernetes 端到端的一致性测试。

当执行一致性测试时,测试程序会启动许多 Pod 进行各种端到端的行为测试,这些 Pod 使用的镜像源码大部分来自于 kubernetes/test/images 目录下,构建的镜像位于 gcr.io/kubernetes-e2e-test-images/。由于镜像仓库中目前并不存在 MIPS 架构的镜像,我们要想运行 E2E 测试,必须首先构建出测试所需的全部镜像。

构建测试所需镜像

第一步是找到测试所需的所有镜像。我们可以执行 sonobuoy images-p e2e 命令来列出所有镜像,或者我们可以在 /test/utils/image/manifest.go 中找到这些镜像。尽管 Kubernetes 官方提供了完整的 Makefile 和 shell 脚本,为构建测试映像提供了命令,但是仍然有许多与体系结构相关的问题未能解决,比如基础映像和依赖包的不兼容问题。因此,我们无法通过直接执行这些构建命令来制作 mips64el 架构镜像。

多数测试镜像都是使用 golang 编写,然后编译出二进制文件,并基于相应的 Dockerfile 制作出镜像。这些镜像对我们来说可以轻松地制作出来。但是需要注意一点:测试镜像默认使用的基础镜像大多是 alpine, 目前 Alpine 官方并不支持 mips64el 架构,我们暂时未能自己制作出 mips64el 版本的 alpine 础镜像,只能将基础镜像替换为我们目前已有的 mips64el 基础镜像,比如 debian-stretch,fedora, ubuntu 等。替换基础镜像的同时也需要替换安装依赖包的命令,甚至依赖包的版本等。

有些测试所需镜像的源码并不在 kubernetes/test/images 下,比如 gcr.io/google-samples/gb-frontend:v6 等,没有明确的文档说明这类镜像来自于何方,最终还是在 github.com/GoogleCloudPlatform/kubernetes-engine-samples 这个仓库找到了原始的镜像源代码。但是很快我们遇到了新的问题,为了制作这些镜像,还要制作它依赖的基础镜像,甚至基础镜像的基础镜像,比如 php:5-apacheredisperl 等等。

经过漫长庞杂的的镜像重制工作,我们完成了总计约 40 个镜像的制作 ,包括测试镜像以及直接和间接依赖的基础镜像。 最终我们将所有镜像在集群内准备妥当,并确保测试用例内所有 Pod 的镜像拉取策略设置为 imagePullPolicy: ifNotPresent

这是我们构建出的部分镜像列表:

  • docker.io/library/busybox:1.29
  • docker.io/library/nginx:1.14-alpine
  • docker.io/library/nginx:1.15-alpine
  • docker.io/library/perl:5.26
  • docker.io/library/httpd:2.4.38-alpine
  • docker.io/library/redis:5.0.5-alpine
  • gcr.io/google-containers/conformance:v1.16.2
  • gcr.io/google-containers/hyperkube:v1.16.2
  • gcr.io/google-samples/gb-frontend:v6
  • gcr.io/kubernetes-e2e-test-images/agnhost:2.6
  • gcr.io/kubernetes-e2e-test-images/apparmor-loader:1.0
  • gcr.io/kubernetes-e2e-test-images/dnsutils:1.1
  • gcr.io/kubernetes-e2e-test-images/echoserver:2.2
  • gcr.io/kubernetes-e2e-test-images/ipc-utils:1.0
  • gcr.io/kubernetes-e2e-test-images/jessie-dnsutils:1.0
  • gcr.io/kubernetes-e2e-test-images/kitten:1.0
  • gcr.io/kubernetes-e2e-test-images/metadata-concealment:1.2
  • gcr.io/kubernetes-e2e-test-images/mounttest-user:1.0
  • gcr.io/kubernetes-e2e-test-images/mounttest:1.0
  • gcr.io/kubernetes-e2e-test-images/nautilus:1.0
  • gcr.io/kubernetes-e2e-test-images/nonewprivs:1.0
  • gcr.io/kubernetes-e2e-test-images/nonroot:1.0
  • gcr.io/kubernetes-e2e-test-images/resource-consumer-controller:1.0
  • gcr.io/kubernetes-e2e-test-images/resource-consumer:1.5
  • gcr.io/kubernetes-e2e-test-images/sample-apiserver:1.10
  • gcr.io/kubernetes-e2e-test-images/test-webserver:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/gluster:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/iscsi:2.0
  • gcr.io/kubernetes-e2e-test-images/volume/nfs:1.0
  • gcr.io/kubernetes-e2e-test-images/volume/rbd:1.0.1
  • k8s.gcr.io/etcd:3.3.15
  • k8s.gcr.io/pause:3.1

最终我们执行一致性测试并且得到了测试报告,包括 e2e.log,显示我们通过了全部的测试用例。此外,我们将测试结果以 pull request 的形式提交给了 k8s-conformance

Pull request for conformance test results

图五 一致性测试结果的 PR

后续计划

我们手动构建了 K8S-MIPS 组件以及执行了 E2E 测试,验证了 Kubernetes on MIPS 的可行性,极大的增强了我们对于推进 Kubernetes 支持 MIPS 架构的信心。

后续,我们将积极地向社区贡献我们的工作经验以及成果,提交 PR 以及 Patch For MIPS 等, 希望能够有更多的来自社区的力量加入进来,共同推进 Kubernetes for MIPS 的进程。

后续开源贡献计划:

  • 贡献构建 E2E 测试镜像代码
  • 贡献构建 MIPS 版本 hyperkube 代码
  • 贡献构建 MIPS 版本 kubeadm 等集群部署工具

Kubernetes 1.17:稳定

作者: Kubernetes 1.17发布团队

我们高兴的宣布Kubernetes 1.17版本的交付,它是我们2019年的第四个也是最后一个发布版本。Kubernetes v1.17包含22个增强功能:有14个增强已经逐步稳定(stable),4个增强功能已经进入公开测试版(beta),4个增强功能刚刚进入内部测试版(alpha)。

主要的主题

云服务提供商标签基本可用

作为公开测试版特性添加到 v1.2 ,v1.17 中可以看到云提供商标签达到基本可用。

卷快照进入公开测试版

在 v1.17 中,Kubernetes卷快照特性是公开测试版。这个特性是在 v1.12 中以内部测试版引入的,第二个有重大变化的内部测试版是 v1.13 。

容器存储接口迁移公开测试版

在 v1.17 中,Kubernetes树内存储插件到容器存储接口(CSI)的迁移基础架构是公开测试版。容器存储接口迁移最初是在Kubernetes v1.14 中以内部测试版引入的。

云服务提供商标签基本可用

当节点和卷被创建,会基于基础云提供商的Kubernetes集群打上一系列标准标签。节点会获得一个实例类型标签。节点和卷都会得到两个描述资源在云提供商拓扑的位置标签,通常是以区域和地区的方式组织。

Kubernetes组件使用标准标签来支持一些特性。例如,调度者会保证pods和它们所声明的卷放置在相同的区域;当调度部署的pods时,调度器会优先将它们分布在不同的区域。你还可以在自己的pods标准中利用标签来配置,如节点亲和性,之类的事。标准标签使得你写的pod规范在不同的云提供商之间是可移植的。

在这个版本中,标签已经达到基本可用。Kubernetes组件都已经更新,可以填充基本可用和公开测试版标签,并对两者做出反应。然而,如果你的pod规范或自定义的控制器正在使用公开测试版标签,如节点亲和性,我们建议你可以将它们迁移到新的基本可用标签中。你可以从如下地方找到新标签的文档:

卷快照进入公开测试版

在 v1.17 中,Kubernetes卷快照是是公开测试版。最初是在 v1.12 中以内部测试版引入的,第二个有重大变化的内部测试版是 v1.13 。这篇文章总结它在公开版本中的变化。

卷快照是什么?

许多的存储系统(如谷歌云持久化磁盘,亚马逊弹性块存储和许多的内部存储系统)支持为持久卷创建快照。快照代表卷在一个时间点的复制。它可用于配置新卷(使用快照数据提前填充)或恢复卷到一个之前的状态(用快照表示)。

为什么给Kubernetes加入卷快照?

Kubernetes卷插件系统已经提供了功能强大的抽象用于自动配置、附加和挂载块文件系统。

支持所有这些特性是Kubernetes负载可移植的目标:Kubernetes旨在分布式系统应用和底层集群之间创建一个抽象层,使得应用可以不感知其运行集群的具体信息并且部署也不需特定集群的知识。

Kubernetes存储特别兴趣组(SIG)将快照操作确定为对很多有状态负载的关键功能。如数据库管理员希望在操作数据库前保存数据库卷快照。

在Kubernetes接口中提供一种标准的方式触发快照操作,Kubernetes用户可以处理这种用户场景,而不必使用Kubernetes API(并手动执行存储系统的具体操作)。

取而代之的是,Kubernetes用户现在被授权以与集群无关的方式将快照操作放进他们的工具和策略中,并且确信它将对任意的Kubernetes集群有效,而与底层存储无关。

此外,Kubernetes 快照原语作为基础构建能力解锁了为Kubernetes开发高级、企业级、存储管理特性的能力:包括应用或集群级别的备份方案。

你可以阅读更多关于发布容器存储接口卷快照公开测试版

容器存储接口迁移公测版

为什么我们迁移内建树插件到容器存储接口?

在容器存储接口之前,Kubernetes提供功能强大的卷插件系统。这些卷插件是树内的意味着它们的代码是核心Kubernetes代码的一部分并附带在核心Kubernetes二进制中。然而,为Kubernetes添加插件支持新卷是非常有挑战的。希望在Kubernetes上为自己存储系统添加支持(或修复现有卷插件的bug)的供应商被迫与Kubernetes发行进程对齐。此外,第三方存储代码在核心Kubernetes二进制中会造成可靠性和安全问题,并且这些代码对于Kubernetes的维护者来说是难以(一些场景是不可能)测试和维护的。在Kubernetes上采用容器存储接口可以解决大部分问题。

随着更多容器存储接口驱动变成生产环境可用,我们希望所有的Kubernetes用户从容器存储接口模型中获益。然而,我们不希望强制用户以破坏现有基本可用的存储接口的方式去改变负载和配置。道路很明确,我们将不得不用CSI替换树内插件接口。什么是容器存储接口迁移?

在容器存储接口迁移上所做的努力使得替换现有的树内存储插件,如kubernetes.io/gce-pdkubernetes.io/aws-ebs,为相应的容器存储接口驱动成为可能。如果容器存储接口迁移正常工作,Kubernetes终端用户不会注意到任何差别。迁移过后,Kubernetes用户可以继续使用现有接口来依赖树内存储插件的功能。

当Kubernetes集群管理者更新集群使得CSI迁移可用,现有的有状态部署和工作负载照常工作;然而,在幕后Kubernetes将存储管理操作交给了(以前是交给树内驱动)CSI驱动。

Kubernetes组非常努力地保证存储接口的稳定性和平滑升级体验的承诺。这需要细致的考虑现有特性和行为来确保后向兼容和接口稳定性。你可以想像成在加速行驶的直线上给赛车换轮胎。

你可以在这篇博客中阅读更多关于容器存储接口迁移成为公开测试版.

其它更新

稳定💯

主要变化

其它显著特性

可用性

Kubernetes 1.17 可以在GitHub下载。开始使用Kubernetes,看看这些交互教学。你可以非常容易使用kubeadm安装1.17。

发布团队

正是因为有上千人参与技术或非技术内容的贡献才使这个版本成为可能。特别感谢由Guinevere Saenger领导的发布团队。发布团队的35名成员在发布版本的多方面进行了协调,从文档到测试,校验和特性的完善。

随着Kubernetes社区的成长,我们的发布流程是在开源软件协作方面惊人的示例。Kubernetes快速并持续获得新用户。这一成长产生了良性的反馈循环,更多的贡献者贡献代码创造了更加活跃的生态。Kubernetes已经有超过39000位贡献者和一个超过66000人的活跃社区。

网络研讨会

2020年1月7号,加入Kubernetes 1.17发布团队,学习关于这次发布的主要特性。这里注册。

参与其中

最简单的参与Kubernetes的方式是加入其中一个与你兴趣相同的特别兴趣组(SIGs)。有什么想要广播到Kubernetes社区吗?通过如下的频道,在每周的社区会议分享你的声音。感谢你的贡献和支持。

使用 Java 开发一个 Kubernetes controller

作者: Min Kim (蚂蚁金服), Tony Ado (蚂蚁金服)

Kubernetes Java SDK 官方项目最近发布了他们的最新工作,为 Java Kubernetes 开发人员提供一个便捷的 Kubernetes 控制器-构建器 SDK,它有助于轻松开发高级工作负载或系统。

综述

Java 无疑是世界上最流行的编程语言之一,但由于社区中缺少库资源,一段时间以来,那些非 Golang 开发人员很难构建他们定制的 controller/operator。在 Golang 的世界里,已经有一些很好的 controller 框架了,例如,controller runtimeoperator SDK。这些现有的 Golang 框架依赖于 Kubernetes Golang SDK 提供的各种实用工具,这些工具经过多年证明是稳定的。受进一步集成到 Kubernetes 平台的需求驱动,我们不仅将 Golang SDK 中的许多基本工具移植到 kubernetes Java SDK 中,包括 informers、work-queues、leader-elections 等,也开发了一个控制器构建 SDK,它可以将所有东西连接到一个可运行的控制器中,而不会产生任何问题。

背景

为什么要使用 Java 实现 kubernetes 工具?选择 Java 的原因可能是:

  • 集成遗留的企业级 Java 系统:许多公司的遗留系统或框架都是用 Java 编写的,用以支持稳定性。我们不能轻易把所有东西搬到 Golang。

  • 更多开源社区的资源:Java 是成熟的,并且在过去几十年中累计了丰富的开源库,尽管 Golang 对于开发人员来说越来越具有吸引力,越来越流行。此外,现在开发人员能够在 SQL 存储上开发他们的聚合-apiserver,而 Java 在 SQL 上有更好的支持。

如何去使用

以 maven 项目为例,将以下依赖项添加到您的依赖中:

<dependency>
    <groupId>io.kubernetes</groupId>
    <artifactId>client-java-extended</artifactId>
    <version>6.0.1</version>
</dependency>

然后我们可以使用提供的生成器库来编写自己的控制器。例如,下面是一个简单的控制,它打印出关于监视通知的节点信息, 在此处 查看完整的例子:

...
    Reconciler reconciler = new Reconciler() {
      @Override
      public Result reconcile(Request request) {
        V1Node node = nodeLister.get(request.getName());
        System.out.println("triggered reconciling " + node.getMetadata().getName());
        return new Result(false);
      }
    };
    Controller controller =
        ControllerBuilder.defaultBuilder(informerFactory)
            .watch(
                (workQueue) -> ControllerBuilder.controllerWatchBuilder(V1Node.class, workQueue).build())
            .withReconciler(nodeReconciler) // required, set the actual reconciler
            .withName("node-printing-controller") // optional, set name for controller for logging, thread-tracing
            .withWorkerCount(4) // optional, set worker thread count
            .withReadyFunc( nodeInformer::hasSynced) // optional, only starts controller when the cache has synced up
            .build();

如果您留意,新的 Java 控制器框架很多地方借鉴于 controller-runtime 的设计,它成功地将控制器内部的复杂组件封装到几个干净的接口中。在 Java 泛型的帮助下,我们甚至更进一步,以更好的方式简化了封装。

我们可以将多个控制器封装到一个 controller-manager 或 leader-electing controller 中,这有助于在 HA 设置中进行部署。

未来计划

Kubernetes Java SDK 项目背后的社区将专注于为希望编写云原生 Java 应用程序来扩展 Kubernetes 的开发人员提供更有用的实用程序。如果您对更详细的信息感兴趣,请查看我们的仓库 kubernetes-client/java。请通过问题或 Slack 与我们分享您的反馈。

使用 Microk8s 在 Linux 上本地运行 Kubernetes

作者: Ihor Dvoretskyi,开发支持者,云原生计算基金会;Carmine Rimi

本文是关于 Linux 上的本地部署选项系列的第二篇,涵盖了 MicroK8s。Microk8s 是本地部署 Kubernetes 集群的 'click-and-run' 方案,最初由 Ubuntu 的发布者 Canonical 开发。

虽然 Minikube 通常为 Kubernetes 集群创建一个本地虚拟机(VM),但是 MicroK8s 不需要 VM。它使用snap 包,这是一种应用程序打包和隔离技术。

这种差异有其优点和缺点。在这里,我们将讨论一些有趣的区别,并且基于 VM 的方法和非 VM 方法的好处。第一个因素是跨平台的移植性。虽然 Minikube VM 可以跨操作系统移植——它不仅支持 Linux,还支持 Windows、macOS、甚至 FreeBSD,但 Microk8s 需要 Linux,而且只在那些支持 snaps 的发行版上。支持大多数流行的 Linux 发行版。

另一个考虑到的因素是资源消耗。虽然 VM 设备为您提供了更好的可移植性,但它确实意味着您将消耗更多资源来运行 VM,这主要是因为 VM 提供了一个完整的操作系统,并且运行在管理程序之上。当 VM 处于休眠时你将消耗更多的磁盘空间。当它运行时,你将会消耗更多的 RAM 和 CPU。因为 Microk8s 不需要创建虚拟机,你将会有更多的资源去运行你的工作负载和其他设备。考虑到所占用的空间更小,MicroK8s 是物联网设备的理想选择-你甚至可以在 Paspberry Pi 和设备上使用它!

最后,项目似乎遵循了不同的发布节奏和策略。Microk8s 和 snaps 通常提供渠道允许你使用测试版和发布 KUbernetes 新版本的候选版本,同样也提供先前稳定版本。Microk8s 通常几乎立刻发布 Kubernetes 上游的稳定版本。

但是等等,还有更多!Minikube 和 Microk8s 都是作为单节点集群启动的。本质上来说,它们允许你用单个工作节点创建 Kubernetes 集群。这种情况即将改变 - MicroK8s 早期的 alpha 版本包括集群。有了这个能力,你可以创建正如你希望多的工作节点的 KUbernetes 集群。对于创建集群来说,这是一个没有主见的选项 - 开发者在节点之间创建网络连接和集成了其他所需要的基础设施,比如一个外部的负载均衡。总的来说,MicroK8s 提供了一种快速简易的方法,使得少量的计算机和虚拟机变成一个多节点的 Kubernetes 集群。以后我们将撰写更多这种体系结构的文章。

免责声明

这不是 MicroK8s 官方介绍文档。你可以在它的官方网页查询运行和使用 MicroK8s 的详情信息,其中覆盖了不同的用例,操作系统,环境等。相反,这篇文章的意图是提供在 Linux 上运行 MicroK8s 清晰易懂的指南。

前提条件

一个支持 snaps 的 Linux 发行版是被需要的。这篇指南,我们将会用支持 snaps 且即开即用的 Ubuntu 18.04 LTS。如果你对运行在 Windows 或者 Mac 上的 MicroK8s 感兴趣,你应该检查多通道,安装一个快速的 Ubuntu VM,作为在你的系统上运行虚拟机 Ubuntu 的官方方式。

MicroK8s 安装

简洁的 MicroK8s 安装:

sudo snap install microk8s --classic

使用 microk8s

使用 MicrosK8s 就像和安装它一样便捷。MicroK8s 本身包括一个 kubectl 库,该库可以通过执行 microk8s.kubectl 命令去访问。例如:

microk8s.kubectl get nodes

当使用前缀 microk8s.kubectl 时,允许在没有影响的情况下并行地安装另一个系统级的 kubectl,你可以便捷地使用 snap alias 命令摆脱它:

sudo snap alias microk8s.kubectl kubectl

这将允许你以后便捷地使用 kubectl,你可以用 snap unalias命令恢复这个改变。

kubectl get nodes

MicroK8s 插件

使用 MicroK8s 其中最大的好处之一事实上是也支持各种各样的插件和扩展。更重要的是它们是开箱即用的,用户仅仅需要启动它们。通过运行 microk8s.status 命令检查出扩展的完整列表。

sudo microk8s.status

截至到写这篇文章为止,MicroK8s 已支持以下插件:

社区创建和贡献了越来越多的插件,经常检查他们是十分有帮助的。

发布渠道

sudo snap info microk8s

安装简单的应用

在这篇指南中我将会用 NGINX 作为一个示例应用程序(官方 Docker Hub 镜像)。

kubectl create deployment nginx --image=nginx

为了检查安装,让我们运行以下命令:

kubectl get deployments
kubectl get pods

我们也可以检索出 Kubernetes 集群中所有可用对象的完整输出。

kubectl get all --all-namespaces

卸载 MircroK8s

卸载您的 microk8s 集群与卸载 Snap 同样便捷。

sudo snap remove microk8s

截屏视频

asciicast

Kubernetes 文档最终用户调研

Author: Aimee Ukasick and SIG Docs

9月,SIG Docs 进行了第一次关于 Kubernetes 文档的用户调研。我们要感谢 CNCF 的 Kim McMahon 帮助我们创建调查并获取结果。

主要收获

受访者希望能在概念、任务和参考部分得到更多示例代码、更详细的内容和更多图表。

74% 的受访者希望教程部分包含高级内容。

69.70% 的受访者认为 Kubernetes 文档是他们首要寻找关于 Kubernetes 资料的地方。

调查方法和受访者

我们用英语进行了调查。由于时间限制,调查的有效期只有 4 天。 我们在 Kubernetes 邮件列表、Kubernetes Slack 频道、Twitter、Kube Weekly 上发布了我们的调查问卷。 这份调查有 23 个问题, 受访者平均用 4 分钟完成这个调查。

关于受访者的简要情况

  • 48.48% 是经验丰富的 Kubernetes 用户,26.26% 是专家,25.25% 是初学者
  • 57.58% 的人同时使用 Kubernetes 作为管理员和开发人员
  • 64.65% 的人使用 Kubernetes 文档超过 12 个月
  • 95.96% 的人阅读英文文档

问题和回答要点

人们为什么访问 Kubernetes 文档

大多数受访者表示,他们访问文档是为了了解概念。

受访者为什么访问 Kubernetes 文档

这与我们在 Google Analytics 上看到的略有不同:在今年浏览量最多的10个页面中,第一是在参考部分的 kubectl 的备忘单,其次是概念部分的页面。

对文档的满意程度

我们要求受访者从概念、任务、参考和教程部分记录他们对细节的满意度:

  • 概念:47.96% 中等满意
  • 任务:50.54% 中等满意
  • 参考:40.86% 非常满意
  • 教程:47.25% 中等满意

SIG Docs 如何改进文档的各个部分

我们询问如何改进每个部分,为受访者提供可选答案以及文本输入框。绝大多数人想要更多 示例代码、更详细的内容、更多图表和更高级的教程:

- 就个人而言,希望看到更多的类比,以帮助进一步理解。
- 如果代码的相应部分也能解释一下就好了
- 通过扩展概念把它们融合在一起 - 它们现在宛如在一桶水内朝各个方向游动的一条条鳗鱼。
- 更多的图表,更多的示例代码

受访者使用“其他”文本框记录引发阻碍的区域:

- 使概念保持最新和准确
- 保持任务主题的最新性和准确性。亲身试验。
- 彻底检查示例。很多时候显示的命令输出不是实际情况。
- 我从来都不知道如何导航或解释参考部分
- 使教程保持最新,或将其删除

SIG Docs 如何全面改进文档

我们询问受访者如何从整体上改进 Kubernetes 文档。一些人抓住这次机会告诉我们我们正在做一个很棒的 工作:

- 对我而言,这是我见过的文档最好的开源项目。
- 继续努力!
- 我觉得文档很好。
- 你们做得真好。真的。

其它受访者提供关于内容的反馈:

-  ...但既然我们谈论的是文档,多多益善。更多的高级配置示例对我来说将是最好的选择。比如每个配置主题的用例页面,
从初学者到高级示例场景。像这样的东西真的是令人惊叹......
- 更深入的例子和用例将是很好的。我经常感觉 Kubernetes 文档只是触及了一个主题的表面,这可能对新用户很好,
但是它没有让更有经验的用户获取多少关于如何实现某些东西的“官方”指导。
- 资源节(特别是 secrets)希望有更多类似于产品的示例或指向类似产品的示例的链接
- 如果能像很多其它技术项目那样有非常清晰的“快速启动” 逐步教学完成搭建就更好了。现有的快速入门内容屈指可数,
也没有统一的指南。结果是信息泛滥。

少数受访者提供的技术建议:

- 使用 ReactJS 或者 Angular component 使表的列可排序和可筛选。
- 对于大多数人来说,我认为用 Hugo - 一个静态站点生成系统 - 创建文档是不合适的。有更好的系统来记录大型软件项目。
具体来说,我希望看到 k8s 切换到 Sphinx 来获取文档。Sphinx 有一个很好的内置搜索。如果你了解 markdown,学习起来也很容易。
Sphinx 被其他项目广泛采用(例如,在 readthedocs.io、linux kernel、docs.python.org 等等)。

总体而言,受访者提供了建设性的批评,其关注点是高级用例以及更深入的示例、指南和演练。

哪里可以看到更多

调查结果摘要、图表和原始数据可在 kubernetes/community sig-docs survey 目录下。

圣迭戈贡献者峰会日程公布!

作者: Josh Berkus (Red Hat), Paris Pittman (Google), Jonas Rosland (VMware)

除了新贡献者研讨会之外,贡献者峰会还安排了许多精彩的会议,这些会议分布在当前五个贡献者内容的会议室中。由于这是一个上游贡献者峰会,并且我们不经常见面,所以作为一个全球分布的团队,这些会议大多是讨论或动手实践,而不仅仅是演示。我们希望大家互相学习,并于他们的开源代码队友玩的开心。

像去年一样,非组织会议将重新开始,会议将在周一上午进行选择。对于最新的热门话题和贡献者想要进行的特定讨论,这是理想的选择。在过去的几年中,我们涵盖了不稳定的测试,集群生命周期,KEP(Kubernetes增强建议),指导,安全性等等。

非组织会议

尽管在每个时间间隙日程安排都包含困难的决定,但我们选择了以下几点,让您体验一下您将在峰会上听到、看到和参与的内容:

  • 预见: SIG组织将分享他们对于明年和以后Kubernetes开发发展方向的认识。
  • 安全: Tim Allclair和CJ Cullen将介绍Kubernetes安全的当前情况。在另一个安全性演讲中,Vallery Lancey将主持有关使我们的平台默认情况下安全的讨论。
  • Prow: 有兴趣与Prow合作并为Test-Infra做贡献,但不确定从哪里开始? Rob Keilty将帮助您在笔记本电脑上运行Prow测试环境
  • Git: GitHub的员工将与Christoph Blecker合作,为Kubernetes贡献者分享实用的Git技巧。
  • 审阅: 蒂姆·霍金(Tim Hockin)将分享成为一名出色的代码审阅者的秘密,而乔丹·利吉特(Jordan Liggitt)将进行实时API审阅,以便您可以进行一次或至少了解一次审阅。
  • 终端用户: 应Cheryl Hung邀请,来自CNCF合作伙伴生态的数个终端用户,将回答贡献者的问题,以加强我们的反馈循环。
  • 文档: 与往常一样,SIG Docs将举办一个为时三个小时的文档撰写研讨会。

我们还将向在2019年杰出的贡献者颁发奖项,周一星期一结束时将有一个巨大的见面会,供新的贡献者找到他们的SIG(以及现有的贡献者询问他们的PR)。

希望能够在峰会上见到您,并且确保您已经提前注册

圣迭戈团队

2019 指导委员会选举结果

作者:Bob Killen (University of Michigan), Jorge Castro (VMware), Brian Grant (Google), and Ihor Dvoretskyi (CNCF)

2019 指导委员会选举 是 Kubernetes 项目的重要里程碑。最初的自助委员会正逐步退休,现在该委员会已缩减到最后分配的 7 个席位。指导委员会的所有成员现在都由 Kubernetes 社区选举产生。

接下来的选举将选出 3 到 4 名委员,任期两年。

选举结果

Kubernetes 指导委员会选举现已完成,以下候选人提前获得立即开始的两年任期 (按 GitHub handle 的字母顺序排列) :

他们加入了 Aaron Crickenberger (@spiffxp), Google;Davanum Srinivas (@dims),VMware; and Timothy St. Clair (@timothysc), VMware,使得委员会更圆满。Aaron、Davanum 和 Timothy 占据的这些席位将会在明年的这个时候进行选举。

诚挚的感谢!

  • 同样感谢其他的已退休指导委员会成员。社区对你们先前的服务表示赞赏:
  • 感谢参选的候选人。 愿在每次选举中,我们都能拥有一群像您一样推动社区向前发展的人。
  • 感谢所有投票的377位选民。
  • 最后,感谢康奈尔大学举办的 CIVS!

参与指导委员会

你可以跟进指导委员会的 代办事项,通过提出问题或者向 仓库 提交一个 pr 。他们每两周一次,在 UTC 时间周三晚上 8 点 会面,并定期与我们的贡献者见面。也可以通过他们的公共邮件列表 steering@kubernetes.io 联系他们。

指导委员会会议:

San Diego 贡献者峰会开放注册!

作者: Paris Pittman (Google), Jeffrey Sica (Red Hat), Jonas Rosland (VMware)

2019 San Diego 贡献者峰会活动页面 在创纪录的时间内,新贡献者研讨会 活动已满员!

11月17日,星期日
晚间贡献者庆典:
QuartYard
地址: 1301 Market Street, San Diego, CA 92101
时间: 下午6:00 - 下午9:00

11月18日,星期一
全天贡献者峰会:
Marriott Marquis San Diego Marina
地址: 333 W Harbor Dr, San Diego, CA 92101
时间: 上午9:00 - 下午5:00

虽然 Kubernetes 项目只有五年的历史,但是在 KubeCon + CloudNativeCon 之前,今年11月在圣迭戈时我们举办的第九届贡献者峰会了。快速增长的原因是在我们之前所做的北美活动中增加了欧洲和亚洲贡献者峰会。我们将继续在全球举办贡献者峰会,因为重要的是,我们的贡献者要以各种形式的多样性地成长。

Kubernetes 拥有一个庞大的分布式远程贡献团队,由来自世界各地的 个人和组织 组成。贡献者峰会每年为社区提供三次聚会的机会,围绕社区主题开展工作,并有互相了解的时间。即将举行的 San Diego 峰会预计将吸引 450 多名与会者,并将包含多个方向,适合所有人。重点将围绕贡献者的增长和可持续性。我们将在这里停留,为举行未来峰会做准备;我们希望这次活动为个人和项目提供价值。我们已经从峰会与会者的反馈中得知,完成工作、学习和与人们面对面交流是当务之急。通过限制参加人数并在更多地方提供贡献者聚会,将有助于我们实现这些目标。

这次峰会是独一无二的,因为我们在贡献者体验活动团队的坚持自我方面已采取了重大举措。从发行团队的手册中摘录,我们添加了其他核心团队和跟随学习角色,使其成为天然的辅导关系(包括监督和实施)。预计跟随学习者将在 2020 年的三项活动中扮演另一个角色,核心团队成员将带头完成。为这个团队做准备,我们开源了 技术手册,指南,最佳做法,并开放了 会议项目委员会。我们的团队组成了 Kubernetes 项目的许多部分,并确保所有声音都得到体现。

您是否已经在 KubeCon + CloudNativeCon 上,但无法参与会议? 在 KubeCon + CloudNativeCon 期间查看 SIG入门和深潜课程 参与问答,并听取每个特殊兴趣小组(SIG)的最新消息。活动结束后,我们还将记录所有贡献者峰会的课题,在讨论中做笔记,并与您分享。

我们希望能在 San Diego 的 Kubernetes 贡献者峰会上与大家见面,确保您直接进入并点击 立即注册! 此活动将关闭 - 特此提醒。 :笑脸:

查看往期博客有关 围绕我们的活动构建角色巴塞罗那峰会故事

2018年集体照

†=QuartYard 有一个巨大的舞台!想要在您的贡献者同行面前做点什么?加入我们吧! community@kubernetes.io

机器可以完成这项工作,一个关于 kubernetes 测试、CI 和自动化贡献者体验的故事

作者:Aaron Crickenberger(谷歌)和 Benjamin Elder(谷歌)

”大型项目有很多不那么令人兴奋,但却很辛苦的工作。比起辛苦工作,我们更重视把时间花在自动化重复性工作上,如果这项工作无法实现自动化,我们的文化就是承认并奖励所有类型的贡献。然而,英雄主义是不可持续的。“ - Kubernetes Community Values

像许多开源项目一样,Kubernetes 托管在 GitHub 上。 如果项目位于在开发人员已经工作的地方,使用的开发人员已经知道的工具和流程,那么参与的障碍将是最低的。 因此,该项目完全接受了这项服务:它是我们工作流程,问题跟踪,文档,博客平台,团队结构等的基础。

这个策略奏效了。 它运作良好,以至于该项目迅速超越了其贡献者的人类能力。 接下来是一次令人难以置信的自动化和创新之旅。 我们不仅需要在飞行途中重建我们的飞机而不会崩溃,我们需要将其转换为火箭飞船并发射到轨道。 我们需要机器来完成这项工作。

工作

最初,我们关注的事实是,我们需要支持复杂的分布式系统(如 Kubernetes)所要求的大量测试。 真实世界中的故障场景必须通过端到端(e2e)测试来执行,确保正确的功能。 不幸的是,e2e 测试容易受到薄片(随机故障)的影响,并且需要花费一个小时到一天才能完成。

进一步的经验揭示了机器可以为我们工作的其他领域:

  • Pull Request 工作流程
    • 贡献者是否签署了我们的 CLA?
    • Pull Request 通过测试吗?
    • Pull Request 可以合并吗?
    • 合并提交是否通过了测试?
  • 鉴别分类
    • 谁应该审查 Pull Request?
    • 是否有足够的信息将问题发送给合适的人?
    • 问题是否依旧存在?
  • 项目健康
    • 项目中发生了什么?
    • 我们应该注意什么?

当我们开发自动化来改善我们的情况时,我们遵循了以下几个指导原则:

  • 遵循适用于 Kubernetes 的推送/拉取控制循环模式
  • 首选无状态松散耦合服务
  • 更倾向于授权整个社区权利,而不是赋予少数核心贡献者权力
  • 做好自己的事,而不要重新造轮子

了解 Prow

这促使我们创建 Prow 作为我们自动化的核心组件。 Prow有点像 If This, Then That 用于 GitHub 事件, 内置 commandsplugins, 和实用程序。 我们在 Kubernetes 之上建立了 Prow,让我们不必担心资源管理和日程安排,并确保更愉快的运营体验。

Prow 让我们做以下事情:

  • 允许我们的社区通过评论诸如“/priority critical-urgent”,“/assign mary”或“/close”之类的命令对 issues/Pull Requests 进行分类
  • 根据用户更改的代码数量或创建的文件自动标记 Pull Requests
  • 标出长时间保持不活动状态 issues/Pull Requests
  • 自动合并符合我们PR工作流程要求的 Pull Requests
  • 运行定义为Knative Builds的 Kubernetes Pods或 Jenkins jobs的 CI 作业
  • 实施组织范围和重构 GitHub 仓库策略,如Knative BuildsGitHub labels

Prow最初由构建 Google Kubernetes Engine 的工程效率团队开发,并由 Kubernetes SIG Testing 的多个成员积极贡献。 Prow 已被其他几个开源项目采用,包括 Istio,JetStack,Knative 和 OpenShift。 Getting started with Prow需要一个 Kubernetes 集群和 kubectl apply starter.yaml(在 Kubernetes 集群上运行 pod)。

一旦我们安装了 Prow,我们就开始遇到其他的问题,因此需要额外的工具以支持 Kubernetes 所需的规模测试,包括:

  • Boskos: 管理池中的作业资源(例如 GCP 项目),检查它们是否有工作并自动清理它们 (with monitoring)
  • ghProxy: 优化用于 GitHub API 的反向代理 HTTP 缓存,以确保我们的令牌使用不会达到 API 限制 (with monitoring)
  • Greenhouse: 允许我们使用远程 bazel 缓存为 Pull requests 提供更快的构建和测试结果 (with monitoring)
  • Splice: 允许我们批量测试和合并 Pull requests,确保我们的合并速度不仅限于我们的测试速度
  • Tide: 允许我们合并通过 GitHub 查询选择的 Pull requests,而不是在队列中排序,允许显着更高合并速度与拼接一起

## 关注项目健康状况

随着工作流自动化的实施,我们将注意力转向了项目健康。我们选择使用 Google Cloud Storage (GCS)作为所有测试数据的真实来源,允许我们依赖已建立的基础设施,并允许社区贡献结果。然后,我们构建了各种工具来帮助个人和整个项目理解这些数据,包括:

  • Gubernator: 显示给定 Pull Request 的结果和测试历史
  • Kettle: 将数据从 GCS 传输到可公开访问的 bigquery 数据集
  • PR dashboard: 一个工作流程识别仪表板,允许参与者了解哪些 Pull Request 需要注意以及为什么
  • Triage: 识别所有作业和测试中发生的常见故障
  • Testgrid: 显示所有运行中给定作业的测试结果,汇总各组作业的测试结果

我们与云计算本地计算基金会(CNCF)联系,开发 DevStats,以便从我们的 GitHub 活动中收集见解,例如:

Into the Beyond

今天,Kubernetes 项目跨越了5个组织125个仓库。有31个特殊利益集团和10个工作组在项目内协调发展。在过去的一年里,该项目有 来自13800多名独立开发人员的参与

在任何给定的工作日,我们的 Prow 实例运行超过10,000个 CI 工作; 从2017年3月到2018年3月,它有430万个工作岗位。 这些工作中的大多数涉及建立整个 Kubernetes 集群,并使用真实场景来实施它。 它们使我们能够确保所有受支持的 Kubernetes 版本跨云提供商,容器引擎和网络插件工作。 他们确保最新版本的 Kubernetes 能够启用各种可选功能,安全升级,满足性能要求,并跨架构工作。

今天来自CNCF的公告 - 注意到 Google Cloud 有开始将 Kubernetes 项目的云资源的所有权和管理权转让给 CNCF 社区贡献者,我们很高兴能够开始另一个旅程。 允许项目基础设施由贡献者社区拥有和运营,遵循对项目其余部分有效的相同开放治理模型。 听起来令人兴奋。 请来 kubernetes.slack.com 上的 #sig-testing on kubernetes.slack.com 与我们联系。

想了解更多? 快来看看这些资源:

OPA Gatekeeper:Kubernetes 的策略和管理

作者: Rita Zhang (Microsoft), Max Smythe (Google), Craig Hooper (Commonwealth Bank AU), Tim Hinrichs (Styra), Lachie Evenson (Microsoft), Torin Sandall (Styra)

可以从项目 Open Policy Agent Gatekeeper 中获得帮助,在 Kubernetes 环境下实施策略并加强治理。在本文中,我们将逐步介绍该项目的目标,历史和当前状态。

以下是 Kubecon EU 2019 会议的录音,帮助我们更好地开展与 Gatekeeper 合作:

出发点

如果您所在的组织一直在使用 Kubernetes,您可能一直在寻找如何控制终端用户在集群上的行为,以及如何确保集群符合公司政策。这些策略可能需要满足管理和法律要求,或者符合最佳执行方法和组织惯例。使用 Kubernetes,如何在不牺牲开发敏捷性和运营独立性的前提下确保合规性?

例如,您可以执行以下策略:

  • 所有镜像必须来自获得批准的存储库
  • 所有入口主机名必须是全局唯一的
  • 所有 Pod 必须有资源限制
  • 所有命名空间都必须具有列出联系的标签

在接收请求被持久化为 Kubernetes 中的对象之前,Kubernetes 允许通过 admission controller webhooks 将策略决策与 API 服务器分离,从而拦截这些请求。Gatekeeper 创建的目的是使用户能够通过配置(而不是代码)自定义控制许可,并使用户了解集群的状态,而不仅仅是针对评估状态的单个对象,在这些对象准许加入的时候。Gatekeeper 是 Kubernetes 的一个可定制的许可 webhook ,它由 Open Policy Agent (OPA) 强制执行, OPA 是 Cloud Native 环境下的策略引擎,由 CNCF 主办。

发展

在深入了解 Gatekeeper 的当前情况之前,让我们看一下 Gatekeeper 项目是如何发展的。

  • Gatekeeper v1.0 - 使用 OPA 作为带有 kube-mgmt sidecar 的许可控制器,用来强制执行基于 configmap 的策略。这种方法实现了验证和转换许可控制。贡献方:Styra
  • Gatekeeper v2.0 - 使用 Kubernetes 策略控制器作为许可控制器,OPA 和 kube-mgmt sidecar 实施基于 configmap 的策略。这种方法实现了验证和转换准入控制和审核功能。贡献方:Microsoft
  • Gatekeeper v3.0 - 准入控制器与 OPA Constraint Framework 集成在一起,用来实施基于 CRD 的策略,并可以可靠地共享已完成声明配置的策略。使用 kubebuilder 进行构建,实现了验证以及最终转换(待完成)为许可控制和审核功能。这样就可以为 Rego 策略创建策略模板,将策略创建为 CRD 并存储审核结果到策略 CRD 上。该项目是 Google,Microsoft,Red Hat 和 Styra 合作完成的。

Gatekeeper v3.0 的功能

现在我们详细看一下 Gatekeeper 当前的状态,以及如何利用所有最新的功能。假设一个组织希望确保集群中的所有对象都有 department 信息,这些信息是对象标签的一部分。如何利用 Gatekeeper 完成这项需求?

验证许可控制

在集群中所有 Gatekeeper 组件都 安装 完成之后,只要集群中的资源进行创建、更新或删除,API 服务器将触发 Gatekeeper 准入 webhook 来处理准入请求。

在验证过程中,Gatekeeper 充当 API 服务器和 OPA 之间的桥梁。API 服务器将强制实施 OPA 执行的所有策略。

策略与 Constraint

结合 OPA Constraint Framework,Constraint 是一个声明,表示作者希望系统满足给定的一系列要求。Constraint 都使用 Rego 编写,Rego 是声明性查询语言,OPA 用 Rego 来枚举违背系统预期状态的数据实例。所有 Constraint 都遵循逻辑 AND。假使有一个 Constraint 不满足,那么整个请求都将被拒绝。

在定义 Constraint 之前,您需要创建一个 Constraint Template,允许大家声明新的 Constraint。每个模板都描述了强制执行 Constraint 的 Rego 逻辑和 Constraint 的模式,其中包括 CRD 的模式和传递到 enforces 中的参数,就像函数的参数一样。

例如,以下是一个 Constraint 模板 CRD,它的请求是在任意对象上显示某些标签。

apiVersion: templates.gatekeeper.sh/v1beta1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
        listKind: K8sRequiredLabelsList
        plural: k8srequiredlabels
        singular: k8srequiredlabels
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            labels:
              type: array
              items: string
  targets:
    - target: admission.k8s.gatekeeper.sh
      rego: |
        package k8srequiredlabels

        deny[{"msg": msg, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("you must provide labels: %v", [missing])
        }        

在集群中部署了 Constraint 模板后,管理员现在可以创建由 Constraint 模板定义的单个 Constraint CRD。例如,这里以下是一个 Constraint CRD,要求标签 hr 出现在所有命名空间上。

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-hr
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels: ["hr"]

类似地,可以从同一个 Constraint 模板轻松地创建另一个 Constraint CRD,该 Constraint CRD 要求所有命名空间上都有 finance 标签。

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-finance
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels: ["finance"]

如您所见,使用 Constraint framework,我们可以通过 Constraint 模板可靠地共享 rego,使用匹配字段定义执行范围,并为 Constraint 提供用户定义的参数,从而为每个 Constraint 创建自定义行为。

审核

根据集群中强制执行的 Constraint,审核功能可定期评估复制的资源,并检测先前存在的错误配置。Gatekeeper 将审核结果存储为 violations,在相关 Constraint 的 status 字段中列出。

apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-hr
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels: ["hr"]
status:
  auditTimestamp: "2019-08-06T01:46:13Z"
  byPod:
  - enforced: true
    id: gatekeeper-controller-manager-0
  violations:
  - enforcementAction: deny
    kind: Namespace
    message: 'you must provide labels: {"hr"}'
    name: default
  - enforcementAction: deny
    kind: Namespace
    message: 'you must provide labels: {"hr"}'
    name: gatekeeper-system
  - enforcementAction: deny
    kind: Namespace
    message: 'you must provide labels: {"hr"}'
    name: kube-public
  - enforcementAction: deny
    kind: Namespace
    message: 'you must provide labels: {"hr"}'
    name: kube-system

数据复制

审核要求将 Kubernetes 复制到 OPA 中,然后才能根据强制的 Constraint 对其进行评估。数据复制同样也需要 Constraint,这些 Constraint 需要访问集群中除评估对象之外的对象。例如,一个 Constraint 要强制确定入口主机名的唯一性,就必须有权访问集群中的所有其他入口。

对 Kubernetes 数据进行复制,请使用复制到 OPA 中的资源创建 sync config 资源。例如,下面的配置将所有命名空间和 Pod 资源复制到 OPA。

apiVersion: config.gatekeeper.sh/v1alpha1
kind: Config
metadata:
  name: config
  namespace: "gatekeeper-system"
spec:
  sync:
    syncOnly:
      - group: ""
        version: "v1"
        kind: "Namespace"
      - group: ""
        version: "v1"
        kind: "Pod"

未来计划

Gatekeeper 项目背后的社区将专注于提供转换许可控制,可以用来支持转换方案(例如:在创建新资源时使用 department 信息自动注释对象),支持外部数据以将集群外部环境加入到许可决策中,支持试运行以便在执行策略之前了解策略对集群中现有资源的影响,还有更多的审核功能。

如果您有兴趣了解更多有关该项目的信息,请查看 Gatekeeper 存储库。如果您有兴趣帮助确定 Gatekeeper 的方向,请加入 #kubernetes-policy OPA Slack 频道,并加入我们的 周会 一同讨论开发、任务、用例等。

欢迎参加在上海举行的贡献者峰会

Author: Josh Berkus (Red Hat)

![贡献者小组讨论掠影,摄于 2018 年上海贡献者峰会,作者 Josh Berkus, 许可证 CC-BY 4.0](/images/blog/2019- 06-11-contributor-summit-shanghai/panel.png)

连续第二年,我们将在 KubeCon China 之前举行一天的 贡献者峰会。 不管您是否已经是一名 Kubernetes 贡献者,还是想要加入社区队伍,贡献一份力量,都请考虑注册参加这次活动。 这次峰会将于六月 24 号,在上海世博中心(和 KubeCon 的举办地点相同)举行, 一天的活动将包含“现有贡献者活动”,以及“新贡献者工作坊”和“文档小组活动”。

现有贡献者活动

去年的贡献者节之后,我们的团队收到了很多反馈意见,很多亚洲和大洋洲的贡献者也想要针对当前贡献者的峰会内容。 有鉴于此,我们在今年的安排中加入了当前贡献者的主题。

尽管我们还没有一个完整的时间安排,下面是当前贡献者主题所会包含的话题:

  • 如何撰写 Kubernetes 改进议案 (KEP)
  • 代码库研习
  • 本地构建以及测试调试
  • 不写代码的贡献机会
  • SIG-Azure 面对面交流
  • SIG-Scheduling 面对面交流
  • 其他兴趣小组的面对面机会

整个计划安排将会在完全确定之后,整理放在社区页面上。

如果您的 SIG 想要在 Kubecon Shanghai 上进行面对面的交流,请联系 Josh Berkus

新贡献者工作坊

参与过去年新贡献者工作坊(NCW)的学生觉得这项活动非常的有价值, 这项活动也帮助、引导了很多亚洲和大洋洲的开发者更多地参与到 Kubernetes 社区之中。

“这次活动可以让人一次快速熟悉社区。”其中的一位参与者提到。

如果您之前从没有参与过 Kubernetes 的贡献,或者只是做过一次或两次贡献,都请考虑注册参加新贡献者工作坊。

“熟悉了从 CLA 到 PR 的整个流程,也认识结交了很多贡献者。”另一位开发者提到。

文档小组活动

文档小组的新老贡献者都会聚首一天,讨论如何提升文档质量,以及将文档翻译成更多的语言。 如果您对翻译文档,将这些知识和信息翻译成中文和其他语言感兴趣的话,请在这里注册,报名参加文档小组活动。

参与之前

不论您参与的是哪一项活动,所有人都需要在到达贡献者峰会前签署 Kubernetes CLA。 您也同时需要考虑带一个合适的笔记本电脑,帮助文档写作或是编程开发。

壮大我们的贡献者研讨会

作者: Guinevere Saenger (GitHub) 和 Paris Pittman (Google)(谷歌)

tl;dr - 与我们一起了解贡献者社区,并获得你的第一份 PR ! 我们在[巴塞罗那][欧洲]有空位(登记 在5月15号周三结束,所以抓住这次机会!)并且在[上海][中国]有即将到来的峰会。

巴塞罗那的活动将是我们迄今为止最大的一次,登记的参与者比以往任何时候都多!

你是否曾经想为 Kubernetes 做贡献,但不知道从哪里开始?你有没有曾经看过我们社区的许多代码库并认为需要改进的地方?我们为你准备了一个工作室!

KubeCon + CloudNativeCon 巴塞罗那的研讨会新贡献者研讨会将是第四个这样的研讨会,我们真的很期待!

这个研讨会去年在哥本哈根的 KubeConEU 启动,到目前为止,我们已经把它带到了上海和西雅图,现在是巴塞罗那,以及一些非 KubeConEU 的地方。

我们根据以往课程的反馈,不断更新和改进研讨会的内容。

这一次,我们将根据参与者对开源和 Kubernetes 的经验和适应程度来进行划分。

作为101课程的一部分,我们将为完全不熟悉开源和 Kubernetes 的人提供开发人员设置和项目工作流支持,并希望为每个参与者开展他们自己的第一期工作。

在201课程中,我们将为那些在开源方面有更多经验但可能不熟悉我们社区开发工具的人进行代码库演练和本地开发和测试演示。

对于这两门课程,你将有机会亲自动手并体会到其中的乐趣。因为不是每个贡献者都使用代码,也不是每项贡献都是技术性的,所以我们将在研讨会开始时学习如何构建和组织项目,以及如何进行找到合适的人,以及遇到困难时在哪里寻求帮助。

辅导机会

我们还将回归 SIG Meet-and-Greet,在这里新入门的菜鸟贡献者将有机会与当值的贡献者交流,这也许会让他们找到他们梦想的 SIG,了解他们可以帮助哪些激动人心的领域,获得导师,结交朋友。

PS - 5月23日星期四,在 KubeCon+CloudNativeCon 会议期间会有两次导师会议。[在这里注册][导师]。在西雅图活动期间,60% 的与会者会向贡献者提问。

曾经与会者的故事 - Vallery Lancy,Lyft 的工程师

在一系列采访中,我们与一些过去的参与者进行了交谈,这些采访将在今年全年公布。

在我们的前两个片段中,我们会提到 Vallery Lancy,Lyft 公司的工程师,也是我们最近西雅图版研讨会的75名与会者之一。她在社区里闲逛了一段时间,想看看能不能投身到某个领域当中。

在这里观看 Vallery 讲述她的经历:

Vallery 和那些对研讨会感兴趣的人或者参加巴塞罗那会议的人说了些什么?

想变得和 Vallery 还有数百名参与之前的新贡献者研讨会的与会者一样的话:在巴塞罗那(或者上海-或者圣地亚哥!)加入我们!你会有一个与众不同的体验,而不再是死读我们的文档!

Have the opportunity to meet with the experts and go step by step into your journey with your peers around you. We’re looking forward to seeing you there! Register here --> 你将有机会与专家见面,并与周围的同龄人一步步走上属于你的道路。我们期待着在那里与你见面! 在这里注册

如何参与 Kubernetes 文档的本地化工作

作者: Zach Corleissen(Linux 基金会)

去年我们对 Kubernetes 网站进行了优化,加入了多语言内容的支持。贡献者们踊跃响应,加入了多种新的本地化内容:截至 2019 年 4 月,Kubernetes 文档有了 9 个不同语言的未完成版本,其中有 6 个是 2019 年加入的。在每个 Kubernetes 文档页面的上方,读者都可以看到一个语言选择器,其中列出了所有可用语言。

不论是完成度最高的中文版 v1.12,还是最新加入的葡萄牙文版 v1.14,各语言的本地化内容还未完成,这是一个进行中的项目。如果读者有兴趣对现有本地化工作提供支持,请继续阅读。

什么是本地化

翻译是以词表意的问题。而本地化在此基础之上,还包含了过程和设计方面的工作。

本地化和翻译很像,但是包含更多内容。除了进行翻译之外,本地化还要为编写和发布过程的框架进行优化。例如,Kubernetes.io 多数的站点浏览功能(按钮文字)都保存在单独的文件之中。所以启动新本地化的过程中,需要包含加入对特定文件中字符串进行翻译的工作。

本地化很重要,能够有效的降低 Kubernetes 的采纳和支持门槛。如果能用母语阅读 Kubernetes 文档,就能更轻松的开始使用 Kubernetes,并对其发展作出贡献。

如何启动本地化工作

不同语言的本地化工作都是单独的功能——和其它 Kubernetes 功能一致,贡献者们在一个 SIG 中进行本地化工作,分享出来进行评审,并加入项目。

贡献者们在团队中进行内容的本地化工作。因为自己不能批准自己的 PR,所以一个本地化团队至少应该有两个人——例如意大利文的本地化团队有两个人。这个团队规模可能很大:中文团队有几十个成员。

每个团队都有自己的工作流。有些团队手工完成所有的内容翻译;有些会使用带有翻译插件的编译器,并使用评审机来提供正确性的保障。SIG Docs 专注于输出的标准;这就给了本地化团队采用适合自己工作情况的工作流。这样一来,团队可以根据最佳实践进行协作,并以 Kubernetes 的社区精神进行分享。

为本地化工作添砖加瓦

如果你有兴趣为 Kubernetes 文档加入新语种的本地化内容,Kubernetes contribution guide 中包含了这方面的相关内容。

已经启动的的本地化工作同样需要支持。如果有兴趣为现存项目做出贡献,可以加入本地化团队的 Slack 频道,去做个自我介绍。各团队的成员会帮助你开始工作。

语种 Slack 频道
中文 #kubernetes-docs-zh
英文 #sig-docs
法文 #kubernetes-docs-fr
德文 #kubernetes-docs-de
印地 #kubernetes-docs-hi
印度尼西亚文 #kubernetes-docs-id
意大利文 #kubernetes-docs-it
日文 #kubernetes-docs-ja
韩文 #kubernetes-docs-ko
葡萄牙文 #kubernetes-docs-pt
西班牙文 #kubernetes-docs-es

下一步?

最新的印地文本地化工作正在启动。为什么不加入你的语言?

身为 SIG Docs 的主席,我甚至希望本地化工作跳出文档范畴,直接为 Kubernetes 组件提供本地化支持。有什么组件是你希望支持不同语言的么?可以提交一个 Kubernetes Enhancement Proposal 来促成这一进步。

Kubernetes 1.14 稳定性改进中的进程ID限制

作者: Derek Carr

你是否见过有人拿走了比属于他们那一份更多的饼干? 一个人走过来,抓起半打新鲜烤制的大块巧克力饼干然后匆匆离去,就像饼干怪兽大喊 “Om nom nom nom”。

在一些罕见的工作负载中,Kubernetes 集群内部也发生了类似的情况。每个 Pod 和 Node 都有有限数量的可能的进程 ID(PID),供所有应用程序共享。尽管很少有进程或 Pod 能够进入并获取所有 PID,但由于这种行为,一些用户会遇到资源匮乏的情况。 因此,在 Kubernetes 1.14 中,我们引入了一项增强功能,以降低单个 Pod 垄断所有可用 PID 的风险。

你能预留一些 PIDs 吗?

在这里,我们谈论的是某些容器的贪婪性。 在理想情况之外,失控进程有时会发生,特别是在测试集群中。 因此,在这些集群中会发生一些混乱的非生产环境准备就绪的事情。

在这种情况下,可能会在节点内部发生类似于 fork 炸弹耗尽 PID 的攻击。随着资源的缓慢腐蚀,被一些不断产生子进程的僵尸般的进程所接管,其他正常的工作负载会因为这些像气球般不断膨胀的浪费的处理能力而开始受到冲击。这可能导致同一 Pod 上的其他进程缺少所需的 PID。这也可能导致有趣的副作用,因为节点可能会发生故障,并且该Pod的副本将安排到新的机器上,至此,该过程将在整个集群中重复进行。

解决问题

因此,在 Kubernetes 1.14 中,我们添加了一个特性,允许通过配置 kubelet,限制给定 Pod 可以消耗的 PID 数量。如果该机器支持 32768 个 PIDs 和 100 个 Pod,则可以为每个 Pod 提供 300 个 PIDs 的预算,以防止 PIDs 完全耗尽。如果管理员想要像 CPU 或内存那样过度使用 PIDs,那么他们也可以配置超额使用,但是这样会有一些额外风险。不管怎样,没有一个Pod能搞坏整个机器。这通常会防止简单的分叉函数炸弹接管你的集群。

此更改允许管理员保护一个 Pod 不受另一个 Pod 的影响,但不能确保计算机上的所有 Pod 都能保护节点和节点代理本身不受影响。因此,我们在这个版本中以 Alpha 的形式引入了这个一个特性,它提供了 PIDs 在节点代理( kubelet、runtime 等)与 Pod 上的最终用户工作负载的分离。管理员可以预定特定数量的 pid(类似于今天如何预定 CPU 或内存),并确保它们不会被该计算机上的 pod 消耗。一旦从 Alpha 进入到 Beta,然后在将来的 Kubernetes 版本中稳定下来,我们就可以使用这个特性防止 Linux 资源耗尽。

开始使用 Kubernetes 1.14

##参与其中

如果您对此特性有反馈或有兴趣参与其设计与开发,请加入[节点特别兴趣小组](https://github.com/kubernetes/community/tree/master/sig Node)。

###关于作者: Derek Carr 是 Red Hat 高级首席软件工程师。他也是 Kubernetes 的贡献者和 Kubernetes 社区指导委员会的成员。

Raw Block Volume 支持进入 Beta

作者: Ben Swartzlander (NetApp), Saad Ali (Google)

Kubernetes v1.13 中对原生数据块卷(Raw Block Volume)的支持进入 Beta 阶段。此功能允许将持久卷作为块设备而不是作为已挂载的文件系统暴露在容器内部。

什么是块设备?

块设备允许对固定大小的块中的数据进行随机访问。硬盘驱动器、SSD 和 CD-ROM 驱动器都是块设备的例子。

通常,持久性性存储是在通过在块设备(例如磁盘或 SSD)之上构造文件系统(例如 ext4)的分层方式实现的。这样应用程序就可以读写文件而不是操作数据块进。操作系统负责使用指定的文件系统将文件读写转换为对底层设备的数据块读写。

值得注意的是,整个磁盘都是块设备,磁盘分区也是如此,存储区域网络(SAN)设备中的 LUN 也是一样的。

为什么要将 raw block volume 添加到 kubernetes?

有些特殊的应用程序需要直接访问块设备,原因例如,文件系统层会引入不必要的开销。最常见的情况是数据库,通常会直接在底层存储上组织数据。原生的块设备(Raw Block Devices)还通常由能自己实现某种存储服务的软件(软件定义的存储系统)使用。

从程序员的角度来看,块设备是一个非常大的字节数组,具有某种最小读写粒度,通常为 512 个字节,大部分情况为 4K 或更大。

随着在 Kubernetes 中运行数据库软件和存储基础架构软件变得越来越普遍,在 Kubernetes 中支持原生块设备的需求变得越来越重要。

哪些卷插件支持 raw block?

在发布此博客时,以下 in-tree 卷类型支持原生块设备:

  • AWS EBS
  • Azure Disk
  • Cinder
  • Fibre Channel
  • GCE PD
  • iSCSI
  • Local volumes
  • RBD (Ceph)
  • Vsphere

Out-of-tree CSI 卷驱动程序 可能也支持原生数据块卷。Kubernetes CSI 对原生数据块卷的支持目前为 alpha 阶段。参考 这篇 文档。

Kubernetes raw block volume 的 API

原生数据块卷与普通存储卷有很多共同点。两者都通过创建与 PersistentVolume 对象绑定的 PersistentVolumeClaim 对象发起请求,并通过将它们加入到 PodSpec 的 volumes 数组中来连接到 Kubernetes 中的 Pod。

但是有两个重要的区别。首先,要请求原生数据块设备的 PersistentVolumeClaim 必须在 PersistentVolumeClaimSpec 中设置 volumeMode = "Block"volumeMode 为空时与传统设置方式中的指定 volumeMode = "Filesystem" 是一样的。PersistentVolumes 在其 PersistentVolumeSpec 中也有一个 volumeMode 字段,"Block" 类型的 PVC 只能绑定到 "Block" 类型的 PV 上,而"Filesystem" 类型的 PVC 只能绑定到 "Filesystem" PV 上。

其次,在 Pod 中使用原生数据块卷时,必须在 PodSpec 的 Container 部分指定一个 VolumeDevice,而不是 VolumeMountVolumeDevices 具备 devicePaths 而不是 mountPaths,在容器中,应用程序将看到位于该路径的设备,而不是挂载了的文件系统。

应用程序打开、读取和写入容器内的设备节点,就像它们在非容器化或虚拟环境中与系统上的任何块设备交互一样。

创建一个新的原生块设备 PVC

首先,请确保与您选择的存储类关联的驱动支持原生块设备。然后创建 PVC。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: my-pvc
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Block
  storageClassName: my-sc
  resources:
    requests:
    storage: 1Gi

使用原生块 PVC

在 Pod 定义中使用 PVC 时,需要选择块设备的设备路径,而不是文件系统的安装路径。

apiVersion: v1
kind: Pod
metadata:
  name: my-pod
spec:
  containers:
    - name: my-container
      image: busybox
      command:
        - sleep
        - “3600”
      volumeDevices:
        - devicePath: /dev/block
          name: my-volume
      imagePullPolicy: IfNotPresent
  volumes:
    - name: my-volume
      persistentVolumeClaim:
        claimName: my-pvc

作为存储供应商,我如何在 CSI 插件中添加对原生块设备的支持?

CSI 插件的原生块支持仍然是 alpha 版本,但是现在可以改进了。CSI 规范 详细说明了如何处理具有 BlockVolume 能力而不是 MountVolume 能力的卷的请求。CSI 插件可以支持两种类型的卷,也可以支持其中一种或另一种。更多详细信息,请查看 这个文档

问题/陷阱

由于块设备实质上还是设备,因此可以从容器内部对其进行底层操作,而文件系统的卷则无法执行这些操作。例如,实际上是块设备的 SCSI 磁盘支持使用 Linux ioctl 向设备发送 SCSI 命令。

默认情况下,Linux 不允许容器将 SCSI 命令从容器内部发送到磁盘。为此,必须向容器安全层级认证 SYS_RAWIO 功能实现这种行为。请参阅 这篇 文档。

另外,尽管 Kubernetes 保证可以将块设备交付到容器中,但不能保证它实际上是 SCSI 磁盘或任何其他类型的磁盘。用户必须确保所需的磁盘类型与 Pod 一起使用,或只部署可以处理各种块设备类型的应用程序。

如何学习更多?

在此处查看有关 snapshot 功能的其他文档:Raw Block Volume 支持

如何参与进来?

加入 Kubernetes 存储 SIG 和 CSI 社区,帮助我们添加更多出色的功能并改进现有功能,就像 raw block 存储一样!

https://github.com/kubernetes/community/tree/master/sig-storage https://github.com/container-storage-interface/community/blob/master/README.md

特别感谢所有为 Kubernetes 增加 block volume 支持的贡献者,包括:

新贡献者工作坊上海站

作者: Josh Berkus (红帽), Yang Li (The Plant), Puja Abbassi (Giant Swarm), XiangPeng Zhao (中兴通讯)

KubeCon 上海站新贡献者峰会与会者,摄影:Jerry Zhang

KubeCon 上海站新贡献者峰会与会者,摄影:Jerry Zhang

最近,在中国的首次 KubeCon 上,我们完成了在中国的首次新贡献者峰会。看到所有中国和亚洲的开发者(以及来自世界各地的一些人)有兴趣成为贡献者,这令人非常兴奋。在长达一天的课程中,他们了解了如何、为什么以及在何处为 Kubernetes 作出贡献,创建了 PR,参加了贡献者圆桌讨论,并签署了他们的 CLA。

这是我们的第二届新贡献者工作坊(NCW),它由前一次贡献者体验 SIG 成员创建和领导的哥本哈根研讨会延伸而来。根据受众情况,本次活动采用了中英文两种语言,充分利用了 CNCF 赞助的一流的同声传译服务。同样,NCW 团队由社区成员组成,既有说英语的,也有说汉语的:Yang Li、XiangPeng Zhao、Puja Abbassi、Noah Abrahams、Tim Pepper、Zach Corleissen、Sen Lu 和 Josh Berkus。除了演讲和帮助学员外,团队的双语成员还将所有幻灯片翻译成了中文。共有五十一名学员参加。

Noah Abrahams 讲解 Kubernetes 沟通渠道。摄影:Jerry Zhang

Noah Abrahams 讲解 Kubernetes 沟通渠道。摄影:Jerry Zhang

NCW 让参与者完成了为 Kubernetes 作出贡献的各个阶段,从决定在哪里作出贡献开始,接着介绍了 SIG 系统和我们的代码仓库结构。我们还有来自文档和测试基础设施领域的「客座讲者」,他们负责讲解有关的贡献。最后,我们在创建 issue、提交并批准 PR 的实践练习后,结束了工作坊。

这些实践练习使用一个名为贡献者游乐场的代码仓库,由贡献者体验 SIG 创建,让新贡献者尝试在一个 Kubernetes 仓库中执行各种操作。它修改了 Prow 和 Tide 自动化,使用与真实代码仓库类似的 Owners 文件。这可以让学员了解为我们的仓库做出贡献的有关机制,同时又不妨碍正常的开发流程。

Yang Li 讲到如何让你的 PR 通过评审。摄影:Josh Berkus

Yang Li 讲到如何让你的 PR 通过评审。摄影:Josh Berkus

「防火长城」和语言障碍都使得在中国为 Kubernetes 作出贡献变得困难。而且,中国的开源商业模式并不成熟,员工在开源项目上工作的时间有限。

中国工程师渴望参与 Kubernetes 的研发,但他们中的许多人不知道从何处开始,因为 Kubernetes 是一个如此庞大的项目。通过本次工作坊,我们希望帮助那些想要参与贡献的人,不论他们希望修复他们遇到的一些错误、改进或本地化文档,或者他们需要在工作中用到 Kubernetes。我们很高兴看到越来越多的中国贡献者在过去几年里加入社区,我们也希望将来可以看到更多。

「我已经参与了 Kubernetes 社区大约三年」,XiangPeng Zhao 说,「在社区,我注意到越来越多的中国开发者表现出对 Kubernetes 贡献的兴趣。但是,开始为这样一个项目做贡献并不容易。我尽力帮助那些我在社区遇到的人,但是,我认为可能仍有一些新的贡献者离开社区,因为他们在遇到麻烦时不知道从哪里获得帮助。幸运的是,社区在 KubeCon 哥本哈根站发起了 NCW,并在 KubeCon 上海站举办了第二届。我很高兴受到 Josh Berkus 的邀请,帮助组织这个工作坊。在工作坊期间,我当面见到了社区里的朋友,在练习中指导了与会者,等等。所有这些对我来说都是难忘的经历。作为有着多年贡献者经验的我,也学习到了很多。我希望几年前我开始为 Kubernetes 做贡献时参加过这样的工作坊」。

贡献者圆桌讨论。摄影:Jerry Zhang

贡献者圆桌讨论。摄影:Jerry Zhang

工作坊以现有贡献者圆桌讨论结束,嘉宾包括 Lucas Käldström、Janet Kuo、Da Ma、Pengfei Ni、Zefeng Wang 和 Chao Xu。这场圆桌讨论旨在让新的和现有的贡献者了解一些最活跃的贡献者和维护者的幕后日常工作,不论他们来自中国还是世界各地。嘉宾们讨论了从哪里开始贡献者的旅程,以及如何与评审者和维护者进行互动。他们进一步探讨了在中国参与贡献的主要问题,并向与会者预告了在 Kubernetes 的未来版本中可以期待的令人兴奋的功能。

工作坊结束后,XiangPeng Zhao 和一些与会者就他们的经历在微信和 Twitter 上进行了交谈。他们很高兴参加了 NCW,并就改进工作坊提出了一些建议。一位名叫 Mohammad 的与会者说:「我在工作坊上玩得很开心,学习了参与 k8s 贡献的整个过程。」另一位与会者 Jie Jia 说:「工作坊非常精彩。它系统地解释了如何为 Kubernetes 做出贡献。即使参与者之前对此一无所知,他(她)也可以理解这个过程。对于那些已经是贡献者的人,他们也可以学习到新东西。此外,我还可以在工作坊上结识来自国内外的新朋友。真是棒极了!」

贡献者体验 SIG 将继续在未来的 KubeCon 上举办新贡献者工作坊,包括西雅图站、巴塞罗那站,然后在 2019 年六月回到上海。如果你今年未能参加,请在未来的 KubeCon 上注册。并且,如果你遇到工作坊的与会者,请务必欢迎他们加入社区。

链接:

Kubernetes 文档更新,国际版

作者:Zach Corleissen (Linux 基金会)

作为文档特别兴趣小组(SIG Docs)的联合主席,我很高兴能与大家分享 Kubernetes 文档在本地化(l10n)方面所拥有的一个完全成熟的工作流。

丰富的缩写

L10n 是 localization 的缩写。

I18n 是 internationalization 的缩写。

I18n 定义了做什么 能让 l10n 更容易。而 L10n 更全面,相比翻译( t9n )具备更完善的流程。

为什么本地化很重要

SIG Docs 的目标是让 Kubernetes 更容易为尽可能多的人使用。

一年前,我们研究了是否有可能由一个独立翻译 Kubernetes 文档的中国团队来主持文档输出。经过多次交谈(包括 OpenStack l10n 的专家),多次转变,以及重新致力于更轻松的本地化,我们意识到,开源文档就像开源软件一样,是在可能的边缘不断进行实践。

整合工作流程、语言标签和团队级所有权可能看起来像是十分简单的改进,但是这些功能使 l10n 可以扩展到规模越来越大的 l10n 团队。随着 SIG Docs 不断改进,我们已经在单一工作流程中偿还了大量技术债务并简化了 l10n。这对未来和现在都很有益。

整合的工作流程

现在,本地化已整合到 kubernetes/website 存储库。我们已经配置了 Kubernetes CI/CD 系统,Prow 来处理自动语言标签分配以及团队级 PR 审查和批准。

语言标签

Prow 根据文件路径自动添加语言标签。感谢 SIG Docs 贡献者 June Yi,他让人们还可以在 pull request(PR)注释中手动分配语言标签。例如,当为 issue 或 PR 留下下述注释时,将为之分配标签 language/ko(Korean)。

/language ko

这些存储库标签允许审阅者按语言过滤 PR 和 issue。例如,您现在可以过滤 kubernetes/website 面板中具有中文内容的 PR

团队审核

L10n 团队现在可以审查和批准他们自己的 PR。例如,英语的审核和批准权限在位于用于显示英语内容的顶级子文件夹中的 OWNERS 文件中指定

OWNERS 文件添加到子目录可以让本地化团队审查和批准更改,而无需由可能并不擅长该门语言的审阅者进行批准。

下一步是什么

我们期待着上海的 doc sprint 能作为中国 l10n 团队的资源。

我们很高兴继续支持正在取得良好进展的日本和韩国 l10n 队伍。

如果您有兴趣将 Kubernetes 本地化为您自己的语言或地区,请查看我们的本地化 Kubernetes 文档指南,并联系 SIG Docs 主席团获取支持。

加入SIG Docs

如果您对 Kubernetes 文档感兴趣,请参加 SIG Docs 每周会议,或在 Kubernetes Slack 加入 #sig-docs

Kubernetes 2018 年北美贡献者峰会

作者:

Bob Killen(密歇根大学) Sahdev Zala(IBM), Ihor Dvoretskyi(CNCF)

2018 年北美 Kubernetes 贡献者峰会将在西雅图 KubeCon + CloudNativeCon 会议之前举办,这将是迄今为止规模最大的一次盛会。

这是一个将新老贡献者聚集在一起,面对面交流和分享的活动;并为现有的贡献者提供一个机会,帮助塑造社区发展的未来。它为新的社区成员提供了一个学习、探索和实践贡献工作流程的良好空间。

与之前的贡献者峰会不同,本次活动为期两天,有一个更为轻松的行程安排,一般贡献者将于 12 月 9 日(周日)下午 5 点至 8 点在距离会议中心仅几步远的 Garage Lounge and Gaming Hall 举办峰会。在那里,贡献者也可以进行台球、保龄球等娱乐活动,而且还有各种食品和饮料。

接下来的一天,也就是 10 号星期一,有三个独立的会议你可以选择参与:

新贡献者研讨会:

为期半天的研讨会旨在让新贡献者加入社区,并营造一个良好的 Kubernetes 社区工作环境。 请在开会期间保持在场,该讨论会不允许随意进出。

当前贡献者追踪:

保留给那些积极参与项目开发的贡献者;目前的贡献者追踪包括讲座、研讨会、聚会、Unconferences 会议、指导委员会会议等等! 请留意 GitHub 中的时间表,因为内容经常更新。

Docs 冲刺:

SIG-Docs 将在活动日期临近的时候列出一个需要处理的问题和挑战列表。

注册:

要注册贡献者峰会,请参阅 Git Hub 上的活动详情注册部分。请注意报名正在审核中。 如果您选择了 “当前贡献者追踪”,而您却不是一个活跃的贡献者,您将被要求参加新贡献者研讨会,或者被要求进入候补名单。 成千上万的贡献者只有 300 个位置,我们需要确保正确的人被安排席位。

如果您有任何问题或疑虑,请随时通过 community@kubernetes.io 联系贡献者峰会组织团队。

期待在那里看到每个人!

2018 年督导委员会选举结果

作者: Jorge Castro (Heptio), Ihor Dvoretskyi (CNCF), Paris Pittman (Google)

结果

Kubernetes 督导委员会选举现已完成,以下候选人获得了立即开始的两年任期:

十分感谢!

  • 督导委员会荣誉退休成员 Quinton Hoole,表扬他在过去一年为社区所作的贡献。我们期待着
  • 参加竞选的候选人。愿我们永远拥有一群强大的人,他们希望在每一次选举中都能像你们一样推动社区向前发展。
  • 共计 307 名选民参与投票。
  • 本次选举由康奈尔大学主办 CIVS

加入督导委员会

你可以关注督导委员会的任务清单,并通过向他们的代码仓库提交 issue 或 PR 的方式来参与。他们也会在UTC 时间每周三晚 8 点举行会议,并定期与我们的贡献者见面。

督导委员会会议:

与我们的贡献者会面:

Kubernetes 中的拓扑感知数据卷供应

作者: Michelle Au(谷歌)

通过提供拓扑感知动态卷供应功能,具有持久卷的多区域集群体验在 Kubernetes 1.12 中得到了改进。此功能使得 Kubernetes 在动态供应卷时能做出明智的决策,方法是从调度器获得为 Pod 提供数据卷的最佳位置。在多区域集群环境,这意味着数据卷能够在满足你的 Pod 运行需要的合适的区域被供应,从而允许你跨故障域轻松部署和扩展有状态工作负载,从而提供高可用性和容错能力。

以前的挑战

在此功能被提供之前,在多区域集群中使用区域化的持久磁盘(例如 AWS ElasticBlockStore、 Azure Disk、GCE PersistentDisk)运行有状态工作负载存在许多挑战。动态供应独立于 Pod 调度处理,这意味着只要你创建了一个 PersistentVolumeClaim(PVC),一个卷就会被供应。 这也意味着供应者不知道哪些 Pod 正在使用该卷,也不清楚任何可能影响调度的 Pod 约束。

这导致了不可调度的 Pod,因为在以下区域中配置了卷:

  • 没有足够的 CPU 或内存资源来运行 Pod
  • 与节点选择器、Pod 亲和或反亲和策略冲突
  • 由于污点(taint)不能运行 Pod

另一个常见问题是,使用多个持久卷的非有状态 Pod 可能会在不同的区域中配置每个卷,从而导致一个不可调度的 Pod。

次优的解决方法包括节点超配,或在正确的区域中手动创建卷,但这会造成难以动态部署和扩展有状态工作负载的问题。

拓扑感知动态供应功能解决了上述所有问题。

支持的卷类型

在 1.12 中,以下驱动程序支持拓扑感知动态供应:

  • AWS EBS
  • Azure Disk
  • GCE PD(包括 Regional PD)
  • CSI(alpha) - 目前只有 GCE PD CSI 驱动实现了拓扑支持

设计原则

虽然最初支持的插件集都是基于区域的,但我们设计此功能时遵循 Kubernetes 跨环境可移植性的原则。 拓扑规范是通用的,并使用类似于基于标签的规范,如 Pod nodeSelectors 和 nodeAffinity。 该机制允许你定义自己的拓扑边界,例如内部部署集群中的机架,而无需修改调度程序以了解这些自定义拓扑。

此外,拓扑信息是从 Pod 规范中抽象出来的,因此 Pod 不需要了解底层存储系统的拓扑特征。 这意味着你可以在多个集群、环境和存储系统中使用相同的 Pod 规范。

入门

要启用此功能,你需要做的就是创建一个将 volumeBindingMode 设置为 WaitForFirstConsumer 的 StorageClass:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: topology-aware-standard
provisioner: kubernetes.io/gce-pd
volumeBindingMode: WaitForFirstConsumer
parameters:
  type: pd-standard

这个新设置表明卷配置器不立即创建卷,而是等待使用关联的 PVC 的 Pod 通过调度运行。 请注意,不再需要指定以前的 StorageClass zonezones 参数,因为现在在哪个区域中配置卷由 Pod 策略决定。

接下来,使用此 StorageClass 创建一个 Pod 和 PVC。 此过程与之前相同,但在 PVC 中指定了不同的 StorageClass。 以下是一个假设示例,通过指定许多 Pod 约束和调度策略来演示新功能特性:

  • 一个 Pod 多个 PVC
  • 跨子区域的节点亲和
  • 同一区域 Pod 反亲和
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:   
  serviceName: "nginx"
  replicas: 2
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      affinity:
        nodeAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
            nodeSelectorTerms:
            - matchExpressions:
              - key: failure-domain.beta.kubernetes.io/zone
                operator: In
                values:
                - us-central1-a
                - us-central1-f
        podAntiAffinity:
          requiredDuringSchedulingIgnoredDuringExecution:
          - labelSelector:
              matchExpressions:
              - key: app
                operator: In
                values:
                - nginx
            topologyKey: failure-domain.beta.kubernetes.io/zone
      containers:
      - name: nginx
        image: gcr.io/google_containers/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
        - name: logs
          mountPath: /logs
 volumeClaimTemplates:
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: topology-aware-standard
      resources:
        requests:
          storage: 10Gi
  - metadata:
      name: logs
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: topology-aware-standard
      resources:
        requests:
          storage: 1Gi

之后,你可以看到根据 Pod 设置的策略在区域中配置卷:

$ kubectl get pv -o=jsonpath='{range .items[*]}{.spec.claimRef.name}{"\t"}{.metadata.labels.failure\-domain\.beta\.kubernetes\.io/zone}{"\n"}{end}'
www-web-0       us-central1-f
logs-web-0      us-central1-f
www-web-1       us-central1-a
logs-web-1      us-central1-a

我怎样才能了解更多?

有关拓扑感知动态供应功能的官方文档可在此处获取: https://kubernetes.io/docs/concepts/storage/storage-classes/#volume-binding-mode

有关 CSI 驱动程序的文档,请访问: https://kubernetes-csi.github.io/docs/

下一步是什么?

我们正积极致力于改进此功能以支持:

  • 更多卷类型,包括本地卷的动态供应
  • 动态容量可附加计数和每个节点的容量限制

我如何参与?

如果你对此功能有反馈意见或有兴趣参与设计和开发,请加入 Kubernetes 存储特别兴趣小组(SIG)。 我们正在快速成长,并始终欢迎新的贡献者。

特别感谢帮助推出此功能的所有贡献者,包括 Cheng Xing (verult)、 Chuqiang Li (lichuqiang)、David Zhu (davidz627)、 Deep Debroy (ddebroy)、Jan Šafránek (jsafrane)、 Jordan Liggitt (liggitt)、Michelle Au (msau42)、 Pengfei Ni (feiskyer)、Saad Ali (saad-ali)、 Tim Hockin (thockin),以及 Yecheng Fu (cofyc)。

Kubernetes v1.12: RuntimeClass 简介

作者: Tim Allclair (Google)

Kubernetes 最初是为了支持在 Linux 主机上运行本机应用程序的 Docker 容器而创建的。 从 Kubernetes 1.3 中的 rkt 开始,更多的运行时间开始涌现, 这导致了容器运行时接口(Container Runtime Interface)(CRI)的开发。 从那时起,备用运行时集合越来越大: 为了加强工作负载隔离,Kata ContainersgVisor 等项目被发起, 并且 Kubernetes 对 Windows 的支持正在稳步发展

由于存在诸多针对不同用例的运行时,集群对混合运行时的需求变得明晰起来。 但是,所有这些不同的容器运行方式都带来了一系列新问题要处理:

  • 用户如何知道哪些运行时可用,并为其工作负荷选择运行时?
  • 我们如何确保将 Pod 被调度到支持所需运行时的节点上?
  • 哪些运行时支持哪些功能,以及我们如何向用户显示不兼容性?
  • 我们如何考虑运行时的各种资源开销?

RuntimeClass 旨在解决这些问题。

Kubernetes 1.12 中的 RuntimeClass

最近,RuntimeClass 在 Kubernetes 1.12 中作为 alpha 功能引入。 最初的实现侧重于提供运行时选择 API,并为解决其他未解决的问题铺平道路。

RuntimeClass 资源代表 Kubernetes 集群中支持的容器运行时。 集群制备组件安装、配置和定义支持 RuntimeClass 的具体运行时。 在 RuntimeClassSpec 的当前形式中,只有一个字段,即 RuntimeHandler。 RuntimeHandler 由在节点上运行的 CRI 实现解释,并映射到实际的运行时配置。 同时,PodSpec 被扩展添加了一个新字段 RuntimeClassName,命名应该用于运行 Pod 的 RuntimeClass。

为什么 RuntimeClass 是 Pod 级别的概念? Kubernetes 资源模型期望 Pod 中的容器之间可以共享某些资源。 如果 Pod 由具有不同资源模型的不同容器组成,支持必要水平的资源共享变得非常具有挑战性。 例如,要跨 VM 边界支持本地回路(localhost)接口非常困难,但这是 Pod 中两个容器之间通信的通用模型。

下一步是什么?

RuntimeClass 资源是将运行时属性显示到控制平面的重要基础。 例如,要对具有支持不同运行时间的异构节点的集群实施调度程序支持,我们可以在 RuntimeClass 定义中添加 NodeAffinity 条件。 另一个需要解决的领域是管理可变资源需求以运行不同运行时的 Pod。 Pod Overhead 提案是一项较早的尝试,与 RuntimeClass 设计非常吻合,并且可能会进一步推广。

人们还提出了许多其他 RuntimeClass 扩展,随着功能的不断发展和成熟,我们会重新讨论这些提议。 正在考虑的其他扩展包括:

  • 提供运行时支持的可选功能,并更好地查看由不兼容功能导致的错误。
  • 自动运行时或功能发现,支持无需手动配置的调度决策。
  • 标准化或一致的 RuntimeClass 名称,用于定义一组具有相同名称的 RuntimeClass 的集群应支持的属性。
  • 动态注册附加的运行时,因此用户可以在不停机的情况下在现有集群上安装新的运行时。
  • 根据 Pod 的要求“匹配” RuntimeClass。 例如,指定运行时属性并使系统与适当的 RuntimeClass 匹配,而不是通过名称显式分配 RuntimeClass。

至少要到 2019 年,RuntimeClass 才会得到积极的开发,我们很高兴看到从 Kubernetes 1.12 中的 RuntimeClass alpha 开始,此功能得以形成。

学到更多

KubeDirector:在 Kubernetes 上运行复杂状态应用程序的简单方法

作者:Thomas Phelan(BlueData)

KubeDirector 是一个开源项目,旨在简化在 Kubernetes 上运行复杂的有状态扩展应用程序集群。KubeDirector 使用自定义资源定义(CRD) 框架构建,并利用了本地 Kubernetes API 扩展和设计哲学。这支持与 Kubernetes 用户/资源 管理以及现有客户端和工具的透明集成。

我们最近介绍了 KubeDirector 项目,作为我们称为 BlueK8s 的更广泛的 Kubernetes 开源项目的一部分。我很高兴地宣布 KubeDirector 的 pre-alpha 代码现在已经可用。在这篇博客文章中,我将展示它是如何工作的。

KubeDirector 提供以下功能:

  • 无需修改代码即可在 Kubernetes 上运行非云原生有状态应用程序。换句话说,不需要分解这些现有的应用程序来适应微服务设计模式。
  • 本机支持保存特定于应用程序的配置和状态。
  • 与应用程序无关的部署模式,最大限度地减少将新的有状态应用程序装载到 Kubernetes 的时间。

KubeDirector 使熟悉数据密集型分布式应用程序(如 Hadoop、Spark、Cassandra、TensorFlow、Caffe2 等)的数据科学家能够在 Kubernetes 上运行这些应用程序 -- 只需极少的学习曲线,无需编写 GO 代码。由 KubeDirector 控制的应用程序由一些基本元数据和相关的配置工件包定义。应用程序元数据称为 KubeDirectorApp 资源。

要了解 KubeDirector 的组件,请使用类似于以下的命令在 GitHub 上克隆存储库:

git clone http://<userid>@github.com/bluek8s/kubedirector.

Spark 2.2.1 应用程序的 KubeDirectorApp 定义位于文件 kubedirector/deploy/example_catalog/cr-app-spark221e2.json 中。

~> cat kubedirector/deploy/example_catalog/cr-app-spark221e2.json
{
   "apiVersion": "kubedirector.bluedata.io/v1alpha1",
   "kind": "KubeDirectorApp",
   "metadata": {
       "name" : "spark221e2"
   },
   "spec" : {
       "systemctlMounts": true,
       "config": {
           "node_services": [
               {
                   "service_ids": [
                       "ssh",
                       "spark",
                       "spark_master",
                       "spark_worker"
                   ],
…

应用程序集群的配置称为 KubeDirectorCluster 资源。示例 Spark 2.2.1 集群的 KubeDirectorCluster 定义位于文件 kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml 中。

~> cat kubedirector/deploy/example_clusters/cr-cluster-spark221.e1.yaml
apiVersion: "kubedirector.bluedata.io/v1alpha1"
kind: "KubeDirectorCluster"
metadata:
  name: "spark221e2"
spec:
  app: spark221e2
  roles:
  - name: controller
    replicas: 1
    resources:
      requests:
        memory: "4Gi"
        cpu: "2"
      limits:
        memory: "4Gi"
        cpu: "2"
  - name: worker
    replicas: 2
    resources:
      requests:
        memory: "4Gi"
        cpu: "2"
      limits:
        memory: "4Gi"
        cpu: "2"
  - name: jupyter
…

使用 KubeDirector 在 Kubernetes 上运行 Spark

使用 KubeDirector,可以轻松在 Kubernetes 上运行 Spark 集群。

首先,使用命令 kubectl version 验证 Kubernetes(版本 1.9 或更高)是否正在运行

~> kubectl version
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T18:02:47Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}
Server Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.3", GitCommit:"a4529464e4629c21224b3d52edfe0ea91b072862", GitTreeState:"clean", BuildDate:"2018-09-09T17:53:03Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"linux/amd64"}                                    

使用以下命令部署 KubeDirector 服务和示例 KubeDirectorApp 资源定义:

cd kubedirector
make deploy

这些将启动 KubeDirector pod:

~> kubectl get pods
NAME                           READY     STATUS     RESTARTS     AGE
kubedirector-58cf59869-qd9hb   1/1       Running    0            1m     

kubectl get KubeDirectorApp 列出中已安装的 KubeDirector 应用程序

~> kubectl get KubeDirectorApp
NAME           AGE
cassandra311   30m
spark211up     30m
spark221e2     30m

现在,您可以使用示例 KubeDirectorCluster 文件和 kubectl create -f deploy/example_clusters/cr-cluster-spark211up.yaml 命令 启动 Spark 2.2.1 集群。验证 Spark 集群已经启动:

~> kubectl get pods
NAME                             READY     STATUS    RESTARTS   AGE
kubedirector-58cf59869-djdwl     1/1       Running   0          19m
spark221e2-controller-zbg4d-0    1/1       Running   0          23m
spark221e2-jupyter-2km7q-0       1/1       Running   0          23m
spark221e2-worker-4gzbz-0        1/1       Running   0          23m
spark221e2-worker-4gzbz-1        1/1       Running   0          23m

现在运行的服务包括 Spark 服务:

~> kubectl get service
NAME                                TYPE         CLUSTER-IP        EXTERNAL-IP    PORT(S)                                                    AGE
kubedirector                        ClusterIP    10.98.234.194     <none>         60000/TCP                                                  1d
kubernetes                          ClusterIP    10.96.0.1         <none>         443/TCP                                                    1d
svc-spark221e2-5tg48                ClusterIP    None              <none>         8888/TCP                                                   21s
svc-spark221e2-controller-tq8d6-0   NodePort     10.104.181.123    <none>         22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP  20s
svc-spark221e2-jupyter-6989v-0      NodePort     10.105.227.249    <none>         22:30632/TCP,8888:30355/TCP                                20s
svc-spark221e2-worker-d9892-0       NodePort     10.107.131.165    <none>         22:30358/TCP,8081:32144/TCP                                20s
svc-spark221e2-worker-d9892-1       NodePort     10.110.88.221     <none>         22:30294/TCP,8081:31436/TCP                                20s

将浏览器指向端口 31533 连接到 Spark 主节点 UI:

kubedirector

就是这样! 事实上,在上面的例子中,我们还部署了一个 Jupyter notebook 和 Spark 集群。

要启动另一个应用程序(例如 Cassandra),只需指定另一个 KubeDirectorApp 文件:

kubectl create -f deploy/example_clusters/cr-cluster-cassandra311.yaml

查看正在运行的 Cassandra 集群:

~> kubectl get pods
NAME                              READY     STATUS    RESTARTS   AGE
cassandra311-seed-v24r6-0         1/1       Running   0          1m
cassandra311-seed-v24r6-1         1/1       Running   0          1m
cassandra311-worker-rqrhl-0       1/1       Running   0          1m
cassandra311-worker-rqrhl-1       1/1       Running   0          1m
kubedirector-58cf59869-djdwl      1/1       Running   0          1d
spark221e2-controller-tq8d6-0     1/1       Running   0          22m
spark221e2-jupyter-6989v-0        1/1       Running   0          22m
spark221e2-worker-d9892-0         1/1       Running   0          22m
spark221e2-worker-d9892-1         1/1       Running   0          22m

现在,您有一个 Spark 集群(带有 Jupyter notebook )和一个运行在 Kubernetes 上的 Cassandra 集群。 使用 kubectl get service 查看服务集。

~> kubectl get service
NAME                                TYPE         CLUSTER-IP       EXTERNAL-IP   PORT(S)                                                   AGE
kubedirector                        ClusterIP    10.98.234.194    <none>        60000/TCP                                                 1d
kubernetes                          ClusterIP    10.96.0.1        <none>        443/TCP                                                   1d
svc-cassandra311-seed-v24r6-0       NodePort     10.96.94.204     <none>        22:31131/TCP,9042:30739/TCP                               3m
svc-cassandra311-seed-v24r6-1       NodePort     10.106.144.52    <none>        22:30373/TCP,9042:32662/TCP                               3m
svc-cassandra311-vhh29              ClusterIP    None             <none>        8888/TCP                                                  3m
svc-cassandra311-worker-rqrhl-0     NodePort     10.109.61.194    <none>        22:31832/TCP,9042:31962/TCP                               3m
svc-cassandra311-worker-rqrhl-1     NodePort     10.97.147.131    <none>        22:31454/TCP,9042:31170/TCP                               3m
svc-spark221e2-5tg48                ClusterIP    None             <none>        8888/TCP                                                  24m
svc-spark221e2-controller-tq8d6-0   NodePort     10.104.181.123   <none>        22:30534/TCP,8080:31533/TCP,7077:32506/TCP,8081:32099/TCP 24m
svc-spark221e2-jupyter-6989v-0      NodePort     10.105.227.249   <none>        22:30632/TCP,8888:30355/TCP                               24m
svc-spark221e2-worker-d9892-0       NodePort     10.107.131.165   <none>        22:30358/TCP,8081:32144/TCP                               24m
svc-spark221e2-worker-d9892-1       NodePort     10.110.88.221    <none>        22:30294/TCP,8081:31436/TCP                               24m

参与其中

KubeDirector 是一个完全开放源码的 Apache v2 授权项目 – 在我们称为 BlueK8s 的更广泛的计划中,它是多个开放源码项目中的第一个。 KubeDirector 的 pre-alpha 代码刚刚发布,我们希望您加入到不断增长的开发人员、贡献者和使用者社区。 在 Twitter 上关注 @BlueK8s,并通过以下渠道参与:

在 Kubernetes 上对 gRPC 服务器进行健康检查

作者Ahmet Alp Balkan (Google)

更新(2021 年 12 月): “Kubernetes 从 v1.23 开始具有内置 gRPC 健康探测。 了解更多信息,请参阅配置存活探针、就绪探针和启动探针。 本文最初是为有关实现相同任务的外部工具所写。”

gRPC 将成为本地云微服务间进行通信的通用语言。如果您现在将 gRPC 应用程序部署到 Kubernetes,您可能会想要了解配置健康检查的最佳方法。在本文中,我们将介绍 grpc-health-probe,这是 Kubernetes 原生的健康检查 gRPC 应用程序的方法。

如果您不熟悉,Kubernetes的 健康检查(存活探针和就绪探针)可以使您的应用程序在睡眠时保持可用状态。当检测到没有回应的 Pod 时,会将其标记为不健康,并使这些 Pod 重新启动或重新安排。

Kubernetes 原本 不支持 gRPC 健康检查。gRPC 的开发人员在 Kubernetes 中部署时可以采用以下三种方法:

当前在 kubernetes 上进行 gRPC 健康检查的选项

  1. httpGet prob: 不能与 gRPC 一起使用。您需要重构您的应用程序,必须同时支持 gRPC 和 HTTP/1.1 协议(在不同的端口号上)。
  2. tcpSocket probe: 打开 gRPC 服务器的 Socket 是没有意义的,因为它无法读取响应主体。
  3. exec probe: 将定期调用容器生态系统中的程序。对于 gRPC,这意味着您要自己实现健康 RPC,然后使用容器编写并交付客户端工具。

我们可以做得更好吗?这是肯定的。

介绍 “grpc-health-probe”

为了使上述 "exec probe" 方法标准化,我们需要:

  • 可以在任何 gRPC 服务器中轻松实现的 标准 健康检查 "协议" 。
  • 一种 标准 健康检查 "工具" ,可以轻松查询健康协议。

幸运的是,gRPC 具有 标准的健康检查协议。可以用任何语言轻松调用它。几乎所有实现 gRPC 的语言都附带了生成的代码和用于设置健康状态的实用程序。

如果您在 gRPC 应用程序中 实现 此健康检查协议,那么可以使用标准或通用工具调用 Check() 方法来确定服务器状态。

接下来您需要的是 "标准工具" grpc-health-probe

使用此工具,您可以在所有 gRPC 应用程序中使用相同的健康检查配置。这种方法有以下要求:

  1. 用您喜欢的语言找到 gRPC 的 "健康" 模块并开始使用它(例如 Go 库)。
  2. 将二进制文件 grpc_health_probe 送到容器中。
  3. 配置 Kubernetes 的 "exec" 检查模块来调用容器中的 "grpc_health_probe" 工具。

在这种情况下,执行 "grpc_health_probe" 将通过 localhost 调用您的 gRPC 服务器,因为它们位于同一个容器中。

下一步工作

grpc-health-probe 项目仍处于初期阶段,需要您的反馈。它支持多种功能,例如与 TLS 服务器通信和配置延时连接/RPC。

如果您最近要在 Kubernetes 上运行 gRPC 服务器,请尝试使用 gRPC Health Protocol,并在您的 Deployment 中尝试 grpc-health-probe,然后 进行反馈

更多内容

使用 CSI 和 Kubernetes 实现卷的动态扩容

作者:Orain Xiong(联合创始人, WoquTech)

Kubernetes 本身有一个非常强大的存储子系统,涵盖了相当广泛的用例。而当我们计划使用 Kubernetes 构建产品级关系型数据库平台时,我们面临一个巨大的挑战:提供存储。本文介绍了如何扩展最新的 Container Storage Interface 0.2.0 和与 Kubernetes 集成,并演示了卷动态扩容的基本方面。

介绍

当我们专注于客户时,尤其是在金融领域,采用容器编排技术的情况大大增加。

他们期待着能用开源解决方案重新设计已经存在的整体应用程序,这些应用程序已经在虚拟化基础架构或裸机上运行了几年。

考虑到可扩展性和技术成熟程度,Kubernetes 和 Docker 排在我们选择列表的首位。但是将整体应用程序迁移到类似于 Kubernetes 之类的分布式容器编排平台上很具有挑战性,其中关系数据库对于迁移来说至关重要。

关于关系数据库,我们应该注意存储。Kubernetes 本身内部有一个非常强大的存储子系统。它非常有用,涵盖了相当广泛的用例。当我们计划在生产环境中使用 Kubernetes 运行关系型数据库时,我们面临一个巨大挑战:提供存储。目前,仍有一些基本功能尚未实现。特别是,卷的动态扩容。这听起来很无聊,但在除创建,删除,安装和卸载之类的操作外,它是非常必要的。

目前,扩展卷仅适用于这些存储供应商:

  • gcePersistentDisk
  • awsElasticBlockStore
  • OpenStack Cinder
  • glusterfs
  • rbd

为了启用此功能,我们应该将特性开关 ExpandPersistentVolumes 设置为 true 并打开 PersistentVolumeClaimResize 准入插件。 一旦启用了 PersistentVolumeClaimResize,则其对应的 allowVolumeExpansion 字段设置为 true 的存储类将允许调整大小。

不幸的是,即使基础存储提供者具有此功能,也无法通过容器存储接口(CSI)和 Kubernetes 动态扩展卷。

本文将给出 CSI 的简化视图,然后逐步介绍如何在现有 CSI 和 Kubernetes 上引入新的扩展卷功能。最后,本文将演示如何动态扩展卷容量。

容器存储接口(CSI)

为了更好地了解我们将要做什么,我们首先需要知道什么是容器存储接口。当前,Kubernetes 中已经存在的存储子系统仍然存在一些问题。 存储驱动程序代码在 Kubernetes 核心存储库中维护,这很难测试。 但是除此之外,Kubernetes 还需要授予存储供应商许可,以将代码签入 Kubernetes 核心存储库。 理想情况下,这些应在外部实施。

CSI 旨在定义行业标准,该标准将使支持 CSI 的存储提供商能够在支持 CSI 的容器编排系统中使用。

该图描述了一种与 CSI 集成的高级 Kubernetes 原型:

csi diagram

  • 引入了三个新的外部组件以解耦 Kubernetes 和存储提供程序逻辑
  • 蓝色箭头表示针对 API 服务器进行调用的常规方法
  • 红色箭头显示 gRPC 以针对 Volume Driver 进行调用

更多详细信息,请访问: https://github.com/container-storage-interface/spec/blob/master/spec.md

扩展 CSI 和 Kubernetes

为了实现在 Kubernetes 上扩展卷的功能,我们应该扩展几个组件,包括 CSI 规范,“in-tree” 卷插件,external-provisioner 和 external-attacher。

扩展CSI规范

最新的 CSI 0.2.0 仍未定义扩展卷的功能。应该引入新的3个 RPC,包括 RequiresFSResizeControllerResizeVolumeNodeResizeVolume

service Controller {
 rpc CreateVolume (CreateVolumeRequest)
   returns (CreateVolumeResponse) {}
……
 rpc RequiresFSResize (RequiresFSResizeRequest)
   returns (RequiresFSResizeResponse) {}
 rpc ControllerResizeVolume (ControllerResizeVolumeRequest)
   returns (ControllerResizeVolumeResponse) {}
}

service Node {
 rpc NodeStageVolume (NodeStageVolumeRequest)
   returns (NodeStageVolumeResponse) {}
……
 rpc NodeResizeVolume (NodeResizeVolumeRequest)
   returns (NodeResizeVolumeResponse) {}
}

扩展 “In-Tree” 卷插件

除了扩展的 CSI 规范之外,Kubernetes 中的 csiPlugin 接口还应该实现 expandablePlugincsiPlugin 接口将扩展代表 ExpanderControllerPersistentVolumeClaim

type ExpandableVolumePlugin interface {
VolumePlugin
ExpandVolumeDevice(spec Spec, newSize resource.Quantity, oldSize resource.Quantity) (resource.Quantity, error)
RequiresFSResize() bool
}

实现卷驱动程序

最后,为了抽象化实现的复杂性,我们应该将单独的存储提供程序管理逻辑硬编码为以下功能,这些功能在 CSI 规范中已明确定义:

  • CreateVolume
  • DeleteVolume
  • ControllerPublishVolume
  • ControllerUnpublishVolume
  • ValidateVolumeCapabilities
  • ListVolumes
  • GetCapacity
  • ControllerGetCapabilities
  • RequiresFSResize
  • ControllerResizeVolume

展示

让我们以具体的用户案例来演示此功能。

  • 为 CSI 存储供应商创建存储类
allowVolumeExpansion: true
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: csi-qcfs
parameters:
  csiProvisionerSecretName: orain-test
  csiProvisionerSecretNamespace: default
provisioner: csi-qcfsplugin
reclaimPolicy: Delete
volumeBindingMode: Immediate
  • 在 Kubernetes 集群上部署包括存储供应商 csi-qcfsplugin 在内的 CSI 卷驱动

  • 创建 PVC qcfs-pvc,它将由存储类 csi-qcfs 动态配置

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: qcfs-pvc
  namespace: default
....
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 300Gi
  storageClassName: csi-qcfs
  • 创建 MySQL 5.7 实例以使用 PVC qcfs-pvc
  • 为了反映完全相同的生产级别方案,实际上有两种不同类型的工作负载,包括:      * 批量插入使 MySQL 消耗更多的文件系统容量      * 浪涌查询请求
  • 通过编辑 pvc qcfs-pvc 配置动态扩展卷容量

Prometheus 和 Grafana 的集成使我们可以可视化相应的关键指标。

prometheus grafana

我们注意到中间的读数显示在批量插入期间 MySQL 数据文件的大小缓慢增加。 同时,底部读数显示文件系统在大约20分钟内扩展了两次,从 300 GiB 扩展到 400 GiB,然后扩展到 500 GiB。 同时,上半部分显示,扩展卷的整个过程立即完成,几乎不会影响 MySQL QPS。

结论

不管运行什么基础结构应用程序,数据库始终是关键资源。拥有更高级的存储子系统以完全支持数据库需求至关重要。这将有助于推动云原生技术的更广泛采用。

使用 Kubernetes 调整 PersistentVolume 的大小

作者: Hemant Kumar (Red Hat)

编者注:这篇博客是深度文章系列的一部分,这个系列介绍了 Kubernetes 1.11 中的新增特性

在 Kubernetes v1.11 中,持久化卷扩展功能升级为 Beta。 该功能允许用户通过编辑 PersistentVolumeClaim(PVC)对象,轻松调整已存在数据卷的大小。 用户不再需要手动与存储后端交互,或者删除再重建 PV 和 PVC 对象来增加卷的大小。缩减持久化卷暂不支持。

卷扩展是在 v1.8 版本中作为 Alpha 功能引入的, 在 v1.11 之前的版本都需要开启特性门控 ExpandPersistentVolumes 以及准入控制器 PersistentVolumeClaimResize(防止扩展底层存储供应商不支持调整大小的 PVC)。 在 Kubernetes v1.11+ 中,特性门控和准入控制器都是默认启用的。

虽然该功能默认是启用的,但集群管理员必须选择允许用户调整数据卷的大小。 Kubernetes v1.11 为以下树内卷插件提供了卷扩展支持: AWS-EBS、GCE-PD、Azure Disk、Azure File、Glusterfs、Cinder、Portworx 和 Ceph RBD。 一旦管理员确定底层供应商支持卷扩展, 就可以通过在 StorageClass 对象中设置 allowVolumeExpansion 字段为 true,让用户可以使用该功能。 只有由这个 StorageClass 创建的 PVC 才能触发卷扩展。

~> cat standard.yaml
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
  name: standard
parameters:
  type: pd-standard
provisioner: kubernetes.io/gce-pd
allowVolumeExpansion: true
reclaimPolicy: Delete

从这个 StorageClass 创建的任何 PVC 都可以被编辑(如下图所示)以请求更多的空间。 Kubernetes 会将存储字段的变化解释为对更多空间的请求,并触发卷大小的自动调整。

PVC StorageClass

文件系统扩展

如 GCE-PD、AWS-EBS、Azure Disk、Cinder 和 Ceph RBD 这类的块存储卷类型, 通常需要在扩展卷的额外空间被 Pod 使用之前进行文件系统扩展。 Kubernetes 会在引用数据卷的 Pod 重新启动时自动处理这个问题。

网络附加文件系统(如 Glusterfs 和 Azure File)可以被扩展,而不需要重新启动引用的 Pod, 因为这些系统不需要特殊的文件系统扩展。

文件系统扩展必须通过终止使用该卷的 Pod 来触发。更具体地说:

  • 编辑 PVC 以请求更多的空间。
  • 一旦底层卷被存储提供商扩展后, PersistentVolume 对象将反映更新的大小,PVC 会有 FileSystemResizePending 状态。

你可以通过运行 kubectl get pvc <pvc_name> -o yaml 来验证这一点。

~> kubectl get pvc myclaim -o yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: myclaim
  namespace: default
  uid: 02d4aa83-83cd-11e8-909d-42010af00004
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 14Gi
  storageClassName: standard
  volumeName: pvc-xxx
status:
  capacity:
    storage: 9G
  conditions:
  - lastProbeTime: null
    lastTransitionTime: 2018-07-11T14:51:10Z
    message: Waiting for user to (re-)start a pod to finish file system resize of
      volume on node.
    status: "True"
    type: FileSystemResizePending
  phase: Bound
  • 一旦 PVC 具有 FileSystemResizePending 状态 ,就可以重启使用该 PVC 的 Pod 以完成节点上的文件系统大小调整。 重新启动可以通过删除并重新创建 Pod,或者通过 Deployment 缩容后再扩容来实现。
  • 一旦文件系统的大小调整完成,PVC 将自动更新以展现新的大小。

在扩展文件系统时遇到的任何错误都应作为 Pod 的事件而存在。

在线文件系统扩展

Kubernetes v1.11 里还引入了一个名为在线文件系统扩展的 Alpha 功能。 该功能可以让一个正在被 Pod 使用的卷进行文件系统扩展。 因为这个功能是 Alpha 阶段,所以它需要启用特性门控 ExpandInUsePersistentVolumes。 树内卷插件 GCE-PD、AWS-EBS、Cinder 和 Ceph RBD 都支持该功能。 当这个功能被启用时,引用调整后的卷的 Pod 不需要被重新启动。 相反,在使用中文件系统将作为卷扩展的一部分自动调整大小。 文件系统的扩展是在一个 Pod 引用调整后的卷时才发生的,所以如果没有引用卷的 Pod 在运行,文件系统的扩展就不会发生。

更多信息

在这里查看有关这一特性的其他文档: https://kubernetes.io/zh-cn/docs/concepts/storage/persistent-volumes/

动态 Kubelet 配置

作者: Michael Taufen (Google)

编者注:在 1.22 版本弃用后,该功能已在 1.24 版本中删除。

编者注:这篇文章是一系列深度文章 的一部分,这个系列介绍了 Kubernetes 1.11 中的新增功能

为什么要进行动态 Kubelet 配置?

Kubernetes 提供了以 API 为中心的工具,可显着改善用于管理应用程序和基础架构的工作流程。 但是,在大多数的 Kubernetes 安装中,kubelet 在每个主机上作为本机进程运行,因此 未被标准 Kubernetes API 覆盖。

过去,这意味着集群管理员和服务提供商无法依靠 Kubernetes API 在活动集群中重新配置 Kubelets。 实际上,这要求操作员要 SSH 登录到计算机以执行手动重新配置,要么使用第三方配置管理自动化工具, 或创建已经安装了所需配置的新 VM,然后将工作迁移到新计算机上。 这些方法是特定于环境的,并且可能很耗时费力。

动态 Kubelet 配置使集群管理员和服务提供商能够通过 Kubernetes API 在活动集群中重新配置 Kubelet。

什么是动态 Kubelet 配置?

Kubernetes v1.10 使得可以通过 Beta 版本的配置文件 API 配置 kubelet。 Kubernetes 已经提供了用于在 API 服务器中存储任意文件数据的 ConfigMap 抽象。

动态 Kubelet 配置扩展了 Node 对象,以便 Node 可以引用包含相同类型配置文件的 ConfigMap。 当节点更新为引用新的 ConfigMap 时,关联的 Kubelet 将尝试使用新的配置。

它是如何工作的?

动态 Kubelet 配置提供以下核心功能:

  • Kubelet 尝试使用动态分配的配置。
  • Kubelet 将其配置已检查点的形式保存到本地磁盘,无需 API 服务器访问即可重新启动。
  • Kubelet 在 Node 状态中报告已指定的、活跃的和最近已知良好的配置源。
  • 当动态分配了无效的配置时,Kubelet 会自动退回到最后一次正确的配置,并在 Node 状态中报告错误。

要使用动态 Kubelet 配置功能,集群管理员或服务提供商将首先发布包含所需配置的 ConfigMap, 然后设置每个 Node.Spec.ConfigSource.ConfigMap 引用以指向新的 ConfigMap。 运营商可以以他们喜欢的速率更新这些参考,从而使他们能够执行新配置的受控部署。

每个 Kubelet 都会监视其关联的 Node 对象的更改。 更新 Node.Spec.ConfigSource.ConfigMap 引用后, Kubelet 将通过将其包含的文件通过检查点机制写入本地磁盘保存新的 ConfigMap。 然后,Kubelet 将退出,而操作系统级进程管理器将重新启动它。 请注意,如果未设置 Node.Spec.ConfigSource.ConfigMap 引用, 则 Kubelet 将使用其正在运行的计算机本地的一组标志和配置文件。

重新启动后,Kubelet 将尝试使用来自新检查点的配置。 如果新配置通过了 Kubelet 的内部验证,则 Kubelet 将更新 Node.Status.Config 用以反映它正在使用新配置。 如果新配置无效,则 Kubelet 将退回到其最后一个正确的配置,并在 Node.Status.Config 中报告错误。

请注意,默认的最后一次正确配置是 Kubelet 命令行标志与 Kubelet 的本地配置文件的组合。 与配置文件重叠的命令行标志始终优先于本地配置文件和动态配置,以实现向后兼容。

有关单个节点的配置更新的高级概述,请参见下图:

kubelet-diagram

我如何了解更多?

请参阅/docs/tasks/administer-cluster/reconfigure-kubelet/上的官方教程, 其中包含有关用户工作流,某配置如何成为“最新的正确的”配置,Kubelet 如何对配置执行“检查点”操作等, 更多详细信息,以及可能的故障模式。

用于 Kubernetes 集群 DNS 的 CoreDNS GA 正式发布

作者:John Belamaric (Infoblox)

**编者注:这篇文章是 系列深度文章 中的一篇,介绍了 Kubernetes 1.11 新增的功能

介绍

在 Kubernetes 1.11 中,CoreDNS 已经达到基于 DNS 服务发现的 General Availability (GA),可以替代 kube-dns 插件。这意味着 CoreDNS 会作为即将发布的安装工具的选项之一上线。实际上,从 Kubernetes 1.11 开始,kubeadm 团队选择将它设为默认选项。

很久以来, kube-dns 集群插件一直是 Kubernetes 的一部分,用来实现基于 DNS 的服务发现。 通常,此插件运行平稳,但对于实现的可靠性、灵活性和安全性仍存在一些疑虑。

CoreDNS 是通用的、权威的 DNS 服务器,提供与 Kubernetes 向后兼容但可扩展的集成。它解决了 kube-dns 遇到的问题,并提供了许多独特的功能,可以解决各种用例。

在本文中,您将了解 kube-dns 和 CoreDNS 的实现有何差异,以及 CoreDNS 提供的一些非常有用的扩展。

实现差异

在 kube-dns 中,一个 Pod 中使用多个 容器:kubednsdnsmasq、和 sidecarkubedns 容器监视 Kubernetes API 并根据 Kubernetes DNS 规范 提供 DNS 记录,dnsmasq 提供缓存和存根域支持,sidecar 提供指标和健康检查。

随着时间的推移,此设置会导致一些问题。一方面,以往 dnsmasq 中的安全漏洞需要通过发布 Kubernetes 的安全补丁来解决。但是,由于 dnsmasq 处理存根域,而 kubedns 处理外部服务,因此您不能在外部服务中使用存根域,导致这个功能具有局限性(请参阅 dns#131)。

在 CoreDNS 中,所有这些功能都是在一个容器中完成的,该容器运行用 Go 编写的进程。所启用的不同插件可复制(并增强)在 kube-dns 中存在的功能。

配置 CoreDNS

在 kube-dns 中,您可以 修改 ConfigMap 来更改服务发现的行为。用户可以添加诸如为存根域提供服务、修改上游名称服务器以及启用联盟之类的功能。

在 CoreDNS 中,您可以类似地修改 CoreDNS Corefile 的 ConfigMap,以更改服务发现的工作方式。这种 Corefile 配置提供了比 kube-dns 中更多的选项,因为它是 CoreDNS 用于配置所有功能的主要配置文件,即使与 Kubernetes 不相关的功能也可以操作。

使用 kubeadm 将 kube-dns 升级到 CoreDNS 时,现有的 ConfigMap 将被用来为您生成自定义的 Corefile,包括存根域、联盟和上游名称服务器的所有配置。更多详细信息,请参见 使用 CoreDNS 进行服务发现

错误修复和增强

在 CoreDNS 中解决了 kube-dn 的多个未解决问题,无论是默认配置还是某些自定义配置。

指标

CoreDNS 默认配置的功能性行为与 kube-dns 相同。但是,你需要了解的差别之一是二者发布的指标是不同的。在 kube-dns 中,您将分别获得 dnsmasqkubedns(skydns)的度量值。在 CoreDNS 中,存在一组完全不同的指标,因为它们在同一个进程中。您可以在 CoreDNS Prometheus 插件 页面上找到有关这些指标的更多详细信息。

一些特殊功能

标准的 CoreDNS Kubernetes 配置旨在与以前的 kube-dns 在行为上向后兼容。但是,通过进行一些配置更改,CoreDNS 允许您修改 DNS 服务发现在集群中的工作方式。这些功能中的许多功能仍要符合 Kubernetes DNS规范;它们在增强了功能的同时保持向后兼容。由于 CoreDNS 并非 用于 Kubernetes,而是通用的 DNS 服务器,因此您可以做很多超出该规范的事情。

Pod 验证模式

在 kube-dns 中,Pod 名称记录是 "伪造的"。也就是说,任何 "a-b-c-d.namespace.pod.cluster.local" 查询都将返回 IP 地址 "a.b.c.d"。在某些情况下,这可能会削弱 TLS 提供的身份确认。因此,CoreDNS 提供了一种 "Pod 验证" 的模式,该模式仅在指定名称空间中存在具有该 IP 地址的 Pod 时才返回 IP 地址。

基于 Pod 名称的端点名称

在 kube-dns 中,使用无头服务时,可以使用 SRV 请求获取该服务的所有端点的列表:

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 10 33 0 6234396237313665.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 10 33 0 6662363165353239.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 10 33 0 6338633437303230.headless.default.svc.cluster.local.
dnstools#

但是,端点 DNS 名称(出于实际目的)是随机的。在 CoreDNS 中,默认情况下,您所获得的端点 DNS 名称是基于端点 IP 地址生成的:

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-14.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-18.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-4.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 172-17-0-9.headless.default.svc.cluster.local.

对于某些应用程序,你会希望在这里使用 Pod 名称,而不是 Pod IP 地址(例如,参见 kubernetes#47992coredns#1190)。要在 CoreDNS 中启用此功能,请在 Corefile 中指定 "endpoint_pod_names" 选项,结果如下:

dnstools# host -t srv headless
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-qv84p.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-zc8lx.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-q7lf2.headless.default.svc.cluster.local.
headless.default.svc.cluster.local has SRV record 0 25 443 headless-65bb4c479f-566rt.headless.default.svc.cluster.local.

自动路径

CoreDNS 还具有一项特殊功能,可以改善 DNS 中外部名称请求的延迟。在 Kubernetes 中,Pod 的 DNS 搜索路径指定了一长串后缀。这一特点使得你可以针对集群中服务使用短名称 - 例如,上面的 "headless",而不是 "headless.default.svc.cluster.local"。但是,当请求一个外部名称(例如 "infoblox.com")时,客户端会进行几个无效的 DNS 查询,每次都需要从客户端到 kube-dns 往返(实际上是到 dnsmasq,然后到 kubedns),因为 禁用了负缓存

  • infoblox.com.default.svc.cluster.local -> NXDOMAIN
  • infoblox.com.svc.cluster.local -> NXDOMAIN
  • infoblox.com.cluster.local -> NXDOMAIN
  • infoblox.com.your-internal-domain.com -> NXDOMAIN
  • infoblox.com -> 返回有效记录

在 CoreDNS 中,可以启用 autopath 的可选功能,该功能使搜索路径在 服务器端 遍历。也就是说,CoreDNS 将基于源 IP 地址判断客户端 Pod 所在的命名空间,并且遍历此搜索列表,直到获得有效答案为止。由于其中的前三个是在 CoreDNS 本身内部解决的,因此它消除了客户端和服务器之间所有的来回通信,从而减少了延迟。

其他一些特定于 Kubernetes 的功能

在 CoreDNS 中,您可以使用标准 DNS 区域传输来导出整个 DNS 记录集。这对于调试服务以及将集群区导入其他 DNS 服务器很有用。

您还可以按名称空间或标签选择器进行过滤。这样,您可以运行特定的 CoreDNS 实例,该实例仅服务与过滤器匹配的记录,从而通过 DNS 公开受限的服务集。

可扩展性

除了上述功能之外,CoreDNS 还可轻松扩展,构建包含您独有的功能的自定义版本的 CoreDNS。例如,这一能力已被用于扩展 CoreDNS 来使用 unbound 插件 进行递归解析、使用 pdsql 插件 直接从数据库提供记录,以及使用 redisc 插件 与多个 CoreDNS 实例共享一个公共的 2 级缓存。

已添加的还有许多其他有趣的扩展,您可以在 CoreDNS 站点的 外部插件 页面上找到这些扩展。Kubernetes 和 Istio 用户真正感兴趣的是 kubernetai 插件,它允许单个 CoreDNS 实例连接到多个 Kubernetes 集群并在所有集群中提供服务发现 。

下一步工作

CoreDNS 是一个独立的项目,许多与 Kubernetes 不直接相关的功能正在开发中。但是,其中许多功能将在 Kubernetes 中具有对应的应用。例如,与策略引擎完成集成后,当请求无头服务时,CoreDNS 能够智能地选择返回哪个端点。这可用于将流量分流到本地 Pod 或响应更快的 Pod。更多的其他功能正在开发中,当然作为一个开源项目,我们欢迎您提出建议并贡献自己的功能特性!

上述特征和差异是几个示例。CoreDNS 还可以做更多的事情。您可以在 CoreDNS 博客 上找到更多信息。

参与 CoreDNS

CoreDNS 是一个 CNCF 孵化项目。

我们在 Slack(和 GitHub)上最活跃:

更多资源请浏览:

基于 IPVS 的集群内部负载均衡

作者: Jun Du(华为), Haibin Xie(华为), Wei Liang(华为)

注意: 这篇文章出自 系列深度文章 介绍 Kubernetes 1.11 的新特性

介绍

根据 Kubernetes 1.11 发布的博客文章, 我们宣布基于 IPVS 的集群内部服务负载均衡已达到一般可用性。 在这篇博客中,我们将带您深入了解该功能。

什么是 IPVS ?

IPVS (IP Virtual Server)是在 Netfilter 上层构建的,并作为 Linux 内核的一部分,实现传输层负载均衡。

IPVS 集成在 LVS(Linux Virtual Server,Linux 虚拟服务器)中,它在主机上运行,并在物理服务器集群前作为负载均衡器。IPVS 可以将基于 TCP 和 UDP 服务的请求定向到真实服务器,并使真实服务器的服务在单个IP地址上显示为虚拟服务。 因此,IPVS 自然支持 Kubernetes 服务。

为什么为 Kubernetes 选择 IPVS ?

随着 Kubernetes 的使用增长,其资源的可扩展性变得越来越重要。特别是,服务的可扩展性对于运行大型工作负载的开发人员/公司采用 Kubernetes 至关重要。

Kube-proxy 是服务路由的构建块,它依赖于经过强化攻击的 iptables 来实现支持核心的服务类型,如 ClusterIP 和 NodePort。 但是,iptables 难以扩展到成千上万的服务,因为它纯粹是为防火墙而设计的,并且基于内核规则列表。

尽管 Kubernetes 在版本v1.6中已经支持5000个节点,但使用 iptables 的 kube-proxy 实际上是将集群扩展到5000个节点的瓶颈。 一个例子是,在5000节点集群中使用 NodePort 服务,如果我们有2000个服务并且每个服务有10个 pod,这将在每个工作节点上至少产生20000个 iptable 记录,这可能使内核非常繁忙。

另一方面,使用基于 IPVS 的集群内服务负载均衡可以为这种情况提供很多帮助。 IPVS 专门用于负载均衡,并使用更高效的数据结构(哈希表),允许几乎无限的规模扩张。

基于 IPVS 的 Kube-proxy

参数更改

参数: --proxy-mode 除了现有的用户空间和 iptables 模式,IPVS 模式通过--proxy-mode = ipvs 进行配置。 它隐式使用 IPVS NAT 模式进行服务端口映射。

参数: --ipvs-scheduler

添加了一个新的 kube-proxy 参数来指定 IPVS 负载均衡算法,参数为 --ipvs-scheduler。 如果未配置,则默认为 round-robin 算法(rr)。

  • rr: round-robin
  • lc: least connection
  • dh: destination hashing
  • sh: source hashing
  • sed: shortest expected delay
  • nq: never queue

将来,我们可以实现特定于服务的调度程序(可能通过注释),该调度程序具有更高的优先级并覆盖该值。

参数: --cleanup-ipvs 类似于 --cleanup-iptables 参数,如果为 true,则清除在 IPVS 模式下创建的 IPVS 配置和 IPTables 规则。

参数: --ipvs-sync-period 刷新 IPVS 规则的最大间隔时间(例如'5s','1m')。 必须大于0。

参数: --ipvs-min-sync-period 刷新 IPVS 规则的最小间隔时间间隔(例如'5s','1m')。 必须大于0。

参数: --ipvs-exclude-cidrs 清除 IPVS 规则时 IPVS 代理不应触及的 CIDR 的逗号分隔列表,因为 IPVS 代理无法区分 kube-proxy 创建的 IPVS 规则和用户原始规则 IPVS 规则。 如果您在环境中使用 IPVS proxier 和您自己的 IPVS 规则,则应指定此参数,否则将清除原始规则。

设计注意事项

IPVS 服务网络拓扑

创建 ClusterIP 类型服务时,IPVS proxier 将执行以下三项操作:

  • 确保节点中存在虚拟接口,默认为 kube-ipvs0
  • 将服务 IP 地址绑定到虚拟接口
  • 分别为每个服务 IP 地址创建 IPVS 虚拟服务器

这是一个例子:

# kubectl describe svc nginx-service
Name:			nginx-service
...
Type:			ClusterIP
IP:			    10.102.128.4
Port:			http	3080/TCP
Endpoints:		10.244.0.235:8080,10.244.1.237:8080
Session Affinity:	None

# ip addr
...
73: kube-ipvs0: <BROADCAST,NOARP> mtu 1500 qdisc noop state DOWN qlen 1000
    link/ether 1a:ce:f5:5f:c1:4d brd ff:ff:ff:ff:ff:ff
    inet 10.102.128.4/32 scope global kube-ipvs0
       valid_lft forever preferred_lft forever

# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.102.128.4:3080 rr
  -> 10.244.0.235:8080            Masq    1      0          0
  -> 10.244.1.237:8080            Masq    1      0          0

请注意,Kubernetes 服务和 IPVS 虚拟服务器之间的关系是“1:N”。 例如,考虑具有多个 IP 地址的 Kubernetes 服务。 外部 IP 类型服务有两个 IP 地址 - 集群IP和外部 IP。 然后,IPVS 代理将创建2个 IPVS 虚拟服务器 - 一个用于集群 IP,另一个用于外部 IP。 Kubernetes 的 endpoint(每个IP +端口对)与 IPVS 虚拟服务器之间的关系是“1:1”。

删除 Kubernetes 服务将触发删除相应的 IPVS 虚拟服务器,IPVS 物理服务器及其绑定到虚拟接口的 IP 地址。

端口映射

IPVS 中有三种代理模式:NAT(masq),IPIP 和 DR。 只有 NAT 模式支持端口映射。 Kube-proxy 利用 NAT 模式进行端口映射。 以下示例显示 IPVS 服务端口3080到Pod端口8080的映射。

TCP  10.102.128.4:3080 rr
  -> 10.244.0.235:8080            Masq    1      0          0
  -> 10.244.1.237:8080            Masq    1      0

会话关系

IPVS 支持客户端 IP 会话关联(持久连接)。 当服务指定会话关系时,IPVS 代理将在 IPVS 虚拟服务器中设置超时值(默认为180分钟= 10800秒)。 例如:

# kubectl describe svc nginx-service
Name:			nginx-service
...
IP:			    10.102.128.4
Port:			http	3080/TCP
Session Affinity:	ClientIP

# ipvsadm -ln
IP Virtual Server version 1.2.1 (size=4096)
Prot LocalAddress:Port Scheduler Flags
  -> RemoteAddress:Port           Forward Weight ActiveConn InActConn
TCP  10.102.128.4:3080 rr persistent 10800

IPVS 代理中的 Iptables 和 Ipset

IPVS 用于负载均衡,它无法处理 kube-proxy 中的其他问题,例如 包过滤,数据包欺骗,SNAT 等

IPVS proxier 在上述场景中利用 iptables。 具体来说,ipvs proxier 将在以下4种情况下依赖于 iptables:

  • kube-proxy 以 --masquerade-all = true 开头
  • 在 kube-proxy 启动中指定集群 CIDR
  • 支持 Loadbalancer 类型服务
  • 支持 NodePort 类型的服务

但是,我们不想创建太多的 iptables 规则。 所以我们采用 ipset 来减少 iptables 规则。 以下是 IPVS proxier 维护的 ipset 集表:

设置名称 成员 用法 KUBE-CLUSTER-IP 所有服务 IP + 端口 masquerade-all=true 或 clusterCIDR 指定的情况下进行伪装 KUBE-LOOP-BACK 所有服务 IP +端口+ IP 解决数据包欺骗问题 KUBE-EXTERNAL-IP 服务外部 IP +端口 将数据包伪装成外部 IP KUBE-LOAD-BALANCER 负载均衡器入口 IP +端口 将数据包伪装成 Load Balancer 类型的服务 KUBE-LOAD-BALANCER-LOCAL 负载均衡器入口 IP +端口 以及 externalTrafficPolicy=local 接受数据包到 Load Balancer externalTrafficPolicy=local KUBE-LOAD-BALANCER-FW 负载均衡器入口 IP +端口 以及 loadBalancerSourceRanges 使用指定的 loadBalancerSourceRanges 丢弃 Load Balancer类型Service的数据包 KUBE-LOAD-BALANCER-SOURCE-CIDR 负载均衡器入口 IP +端口 + 源 CIDR 接受 Load Balancer 类型 Service 的数据包,并指定loadBalancerSourceRanges KUBE-NODE-PORT-TCP NodePort 类型服务 TCP 将数据包伪装成 NodePort(TCP) KUBE-NODE-PORT-LOCAL-TCP NodePort 类型服务 TCP 端口,带有 externalTrafficPolicy=local 接受数据包到 NodePort 服务 使用 externalTrafficPolicy=local KUBE-NODE-PORT-UDP NodePort 类型服务 UDP 端口 将数据包伪装成 NodePort(UDP) KUBE-NODE-PORT-LOCAL-UDP NodePort 类型服务 UDP 端口 使用 externalTrafficPolicy=local 接受数据包到NodePort服务 使用 externalTrafficPolicy=local

通常,对于 IPVS proxier,无论我们有多少 Service/ Pod,iptables 规则的数量都是静态的。

在 IPVS 模式下运行 kube-proxy

目前,本地脚本,GCE 脚本和 kubeadm 支持通过导出环境变量(KUBE_PROXY_MODE=ipvs)或指定标志(--proxy-mode=ipvs)来切换 IPVS 代理模式。 在运行IPVS 代理之前,请确保已安装 IPVS 所需的内核模块。

ip_vs
ip_vs_rr
ip_vs_wrr
ip_vs_sh
nf_conntrack_ipv4

最后,对于 Kubernetes v1.10,“SupportIPVSProxyMode” 默认设置为 “true”。 对于 Kubernetes v1.11 ,该选项已完全删除。 但是,您需要在v1.10之前为Kubernetes 明确启用 --feature-gates = SupportIPVSProxyMode = true。

参与其中

参与 Kubernetes 的最简单方法是加入众多特别兴趣小组 (SIG)中与您的兴趣一致的小组。 你有什么想要向 Kubernetes 社区广播的吗? 在我们的每周社区会议或通过以下渠道分享您的声音。

感谢您的持续反馈和支持。 在Stack Overflow上发布问题(或回答问题)

加入K8sPort的倡导者社区门户网站

在 Twitter 上关注我们 @Kubernetesio获取最新更新

Slack上与社区聊天

分享您的 Kubernetes 故事

Airflow 在 Kubernetes 中的使用(第一部分):一种不同的操作器

作者: Daniel Imberman (Bloomberg LP)

介绍

作为 Bloomberg 持续致力于开发 Kubernetes 生态系统的一部分, 我们很高兴能够宣布 Kubernetes Airflow Operator 的发布; Apache Airflow的一种机制,一种流行的工作流程编排框架, 使用 Kubernetes API 可以在本机启动任意的 Kubernetes Pod。

什么是 Airflow?

Apache Airflow 是“配置即代码”的 DevOps 理念的一种实现。 Airflow 允许用户使用简单的 Python 对象 DAG(有向无环图)启动多步骤流水线。 你可以在易于阅读的 UI 中定义依赖关系,以编程方式构建复杂的工作流,并监视调度的作业。

Airflow DAGs Airflow UI

为什么在 Kubernetes 上使用 Airflow?

自成立以来,Airflow 的最大优势在于其灵活性。 Airflow 提供广泛的服务集成,包括Spark和HBase,以及各种云提供商的服务。 Airflow 还通过其插件框架提供轻松的可扩展性。 但是,该项目的一个限制是 Airflow 用户仅限于执行时 Airflow 站点上存在的框架和客户端。 单个组织可以拥有各种 Airflow 工作流程,范围从数据科学流到应用程序部署。 用例中的这种差异会在依赖关系管理中产生问题,因为两个团队可能会在其工作流程使用截然不同的库。

为了解决这个问题,我们使 Kubernetes 允许用户启动任意 Kubernetes Pod 和配置。 Airflow 用户现在可以在其运行时环境,资源和机密上拥有全部权限,基本上将 Airflow 转变为“你想要的任何工作”工作流程协调器。

Kubernetes Operator

在进一步讨论之前,我们应该澄清 Airflow 中的 Operator 是一个任务定义。 当用户创建 DAG 时,他们将使用像 “SparkSubmitOperator” 或 “PythonOperator” 这样的 Operator 分别提交/监视 Spark 作业或 Python 函数。 Airflow 附带了 Apache Spark,BigQuery,Hive 和 EMR 等框架的内置运算符。 它还提供了一个插件入口点,允许DevOps工程师开发自己的连接器。

Airflow 用户一直在寻找更易于管理部署和 ETL 流的方法。 在增加监控的同时,任何解耦流程的机会都可以减少未来的停机等问题。 以下是 Airflow Kubernetes Operator 提供的好处:

  • 提高部署灵活性: Airflow 的插件 API一直为希望在其 DAG 中测试新功能的工程师提供了重要的福利。 不利的一面是,每当开发人员想要创建一个新的 Operator 时,他们就必须开发一个全新的插件。 现在,任何可以在 Docker 容器中运行的任务都可以通过完全相同的运算符访问,而无需维护额外的 Airflow 代码。
  • 配置和依赖的灵活性:

对于在静态 Airflow 工作程序中运行的 Operator,依赖关系管理可能变得非常困难。 如果开发人员想要运行一个需要 SciPy 的任务和另一个需要 NumPy 的任务, 开发人员必须维护所有 Airflow 节点中的依赖关系或将任务卸载到其他计算机(如果外部计算机以未跟踪的方式更改,则可能导致错误)。 自定义 Docker 镜像允许用户确保任务环境,配置和依赖关系完全是幂等的。

  • 使用kubernetes Secret以增加安全性: 处理敏感数据是任何开发工程师的核心职责。Airflow 用户总有机会在严格条款的基础上隔离任何API密钥,数据库密码和登录凭据。 使用 Kubernetes 运算符,用户可以利用 Kubernetes Vault 技术存储所有敏感数据。 这意味着 Airflow 工作人员将永远无法访问此信息,并且可以容易地请求仅使用他们需要的密码信息构建 Pod。

架构

Airflow Architecture

Kubernetes Operator 使用 Kubernetes Python客户端生成由 APIServer 处理的请求(1)。 然后,Kubernetes将使用你定义的需求启动你的 Pod(2)。 镜像文件中将加载环境变量,Secret 和依赖项,执行单个命令。 一旦启动作业,Operator 只需要监视跟踪日志的状况(3)。 用户可以选择将日志本地收集到调度程序或当前位于其 Kubernetes 集群中的任何分布式日志记录服务。

使用 Kubernetes Operator

一个基本的例子

以下 DAG 可能是我们可以编写的最简单的示例,以显示 Kubernetes Operator 的工作原理。 这个 DAG 在 Kubernetes 上创建了两个 Pod:一个带有 Python 的 Linux 发行版和一个没有它的基本 Ubuntu 发行版。 Python Pod 将正确运行 Python 请求,而没有 Python 的那个将向用户报告失败。 如果 Operator 正常工作,则应该完成 “passing-task” Pod,而“ falling-task” Pod 则向 Airflow 网络服务器返回失败。

from airflow import DAG
from datetime import datetime, timedelta
from airflow.contrib.operators.kubernetes_pod_operator import KubernetesPodOperator
from airflow.operators.dummy_operator import DummyOperator


default_args = {
    'owner': 'airflow',
    'depends_on_past': False,
    'start_date': datetime.utcnow(),
    'email': ['airflow@example.com'],
    'email_on_failure': False,
    'email_on_retry': False,
    'retries': 1,
    'retry_delay': timedelta(minutes=5)
}

dag = DAG(
    'kubernetes_sample', default_args=default_args, schedule_interval=timedelta(minutes=10))


start = DummyOperator(task_id='run_this_first', dag=dag)

passing = KubernetesPodOperator(namespace='default',
                          image="Python:3.6",
                          cmds=["Python","-c"],
                          arguments=["print('hello world')"],
                          labels={"foo": "bar"},
                          name="passing-test",
                          task_id="passing-task",
                          get_logs=True,
                          dag=dag
                          )

failing = KubernetesPodOperator(namespace='default',
                          image="ubuntu:1604",
                          cmds=["Python","-c"],
                          arguments=["print('hello world')"],
                          labels={"foo": "bar"},
                          name="fail",
                          task_id="failing-task",
                          get_logs=True,
                          dag=dag
                          )

passing.set_upstream(start)
failing.set_upstream(start)
Basic DAG Run

但这与我的工作流程有什么关系?

虽然这个例子只使用基本映像,但 Docker 的神奇之处在于,这个相同的 DAG 可以用于你想要的任何图像/命令配对。 以下是推荐的 CI/CD 管道,用于在 Airflow DAG 上运行生产就绪代码。

1:github 中的 PR

使用Travis或Jenkins运行单元和集成测试,请你的朋友PR你的代码,并合并到主分支以触发自动CI构建。

2:CI/CD 构建 Jenkins - > Docker 镜像

在 Jenkins 构建中生成 Docker 镜像和更新版本

3:Airflow 启动任务

最后,更新你的 DAG 以反映新版本,你应该准备好了!

production_task = KubernetesPodOperator(namespace='default',
                          # image="my-production-job:release-1.0.1", <-- old release
                          image="my-production-job:release-1.0.2",
                          cmds=["Python","-c"],
                          arguments=["print('hello world')"],
                          name="fail",
                          task_id="failing-task",
                          get_logs=True,
                          dag=dag
                          )

启动测试部署

由于 Kubernetes Operator 尚未发布,我们尚未发布官方 helm 图表或 Operator(但两者目前都在进行中)。 但是,我们在下面列出了基本部署的说明,并且正在积极寻找测试人员来尝试这一新功能。 要试用此系统,请按以下步骤操作:

步骤1:将 kubeconfig 设置为指向 kubernetes 集群

步骤2:克隆 Airflow 仓库:

运行 git clone https://github.com/apache/incubator-airflow.git 来克隆官方 Airflow 仓库。

步骤3:运行

为了运行这个基本 Deployment,我们正在选择我们目前用于 Kubernetes Executor 的集成测试脚本(将在本系列的下一篇文章中对此进行解释)。 要启动此部署,请运行以下三个命令:

sed -ie "s/KubernetesExecutor/LocalExecutor/g" scripts/ci/kubernetes/kube/configmaps.yaml
./scripts/ci/kubernetes/Docker/build.sh
./scripts/ci/kubernetes/kube/deploy.sh

在我们继续之前,让我们讨论这些命令正在做什么:

sed -ie "s/KubernetesExecutor/LocalExecutor/g" scripts/ci/kubernetes/kube/configmaps.yaml

Kubernetes Executor 是另一种 Airflow 功能,允许动态分配任务已解决幂等 Pod 的问题。 我们将其切换到 LocalExecutor 的原因只是一次引入一个功能。 如果你想尝试 Kubernetes Executor,欢迎你跳过此步骤,但我们将在以后的文章中详细介绍。

./scripts/ci/kubernetes/Docker/build.sh

此脚本将对Airflow主分支代码进行打包,以根据Airflow的发行文件构建Docker容器

./scripts/ci/kubernetes/kube/deploy.sh

最后,我们在你的集群上创建完整的Airflow部署。这包括 Airflow 配置,postgres 后端,web 服务器和调度程序以及之间的所有必要服务。 需要注意的一点是,提供的角色绑定是集群管理员,因此如果你没有该集群的权限级别,可以在 scripts/ci/kubernetes/kube/airflow.yaml 中进行修改。

步骤4:登录你的网络服务器

现在你的 Airflow 实例正在运行,让我们来看看 UI! 用户界面位于 Airflow Pod的 8080 端口,因此只需运行即可:

WEB=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}' | grep "airflow" | head -1)
kubectl port-forward $WEB 8080:8080

现在,Airflow UI 将存在于 http://localhost:8080上。 要登录,只需输入airflow/airflow,你就可以完全访问 Airflow Web UI。

步骤5:上传测试文档

要修改/添加自己的 DAG,可以使用 kubectl cp 将本地文件上传到 Airflow 调度程序的 DAG 文件夹中。 然后,Airflow 将读取新的 DAG 并自动将其上传到其系统。以下命令将任何本地文件上载到正确的目录中:

kubectl cp <local file> <namespace>/<pod>:/root/airflow/dags -c scheduler

步骤6:使用它!

那么我什么时候可以使用它?

虽然此功能仍处于早期阶段,但我们希望在未来几个月内发布该功能以进行广泛发布。

参与其中

此功能只是将 Apache Airflow 集成到 Kubernetes 中的多项主要工作的开始。 Kubernetes Operator 已合并到 Airflow 的 1.10 发布分支(实验模式中的执行模块), 以及完整的 k8s 本地调度程序称为 Kubernetes Executor(即将发布文章)。 这些功能仍处于早期采用者/贡献者可能对这些功能的未来产生巨大影响的阶段。

对于有兴趣加入这些工作的人,我建议按照以下步骤:

  • 加入 airflow-dev 邮件列表 dev@airflow.apache.org
  • Apache Airflow JIRA中提出问题
  • 周三上午 10点 太平洋标准时间加入我们的 SIG-BigData 会议。
  • 在 kubernetes.slack.com 上的 #sig-big-data 找到我们。

特别感谢 Apache Airflow 和 Kubernetes 社区,特别是 Grant Nicholas,Ben Goldberg,Anirudh Ramanathan,Fokko Dreisprong 和 Bolke de Bruin, 感谢你对这些功能的巨大帮助以及我们未来的努力。

Kubernetes 的动态 Ingress

Kubernetes 可以轻松部署由许多微服务组成的应用程序,但这种架构的关键挑战之一是动态地将流量路由到这些服务中的每一个。 一种方法是使用 Ambassador, 一个基于 Envoy Proxy 构建的 Kubernetes 原生开源 API 网关。 Ambassador 专为动态环境而设计,这类环境中的服务可能被频繁添加或删除。

Ambassador 使用 Kubernetes 注解进行配置。 注解用于配置从给定 Kubernetes 服务到特定 URL 的具体映射关系。 每个映射中可以包括多个注解,用于配置路由。 注解的例子有速率限制、协议、跨源请求共享(CORS)、流量影射和路由规则等。

一个简单的 Ambassador 示例

Ambassador 通常作为 Kubernetes Deployment 来安装,也可以作为 Helm Chart 使用。 配置 Ambassador 时,请使用 Ambassador 注解创建 Kubernetes 服务。 下面是一个例子,用来配置 Ambassador,将针对 /httpbin/ 的请求路由到公共的 httpbin.org 服务:

apiVersion: v1
kind: Service
metadata:
  name: httpbin
  annotations:
    getambassador.io/config: |
      ---
      apiVersion: ambassador/v0
      kind:  Mapping
      name:  httpbin_mapping
      prefix: /httpbin/
      service: httpbin.org:80
      host_rewrite: httpbin.org
spec:
  type: ClusterIP
  ports:
    - port: 80

例子中创建了一个 Mapping 对象,其 prefix 设置为 /httpbin/,service 名称为 httpbin.org。 其中的 host_rewrite 注解指定 HTTP 的 host 头部字段应设置为 httpbin.org。

Kubeflow

Kubeflow 提供了一种简单的方法,用于在 Kubernetes 上轻松部署机器学习基础设施。 Kubeflow 团队需要一个代理,为 Kubeflow 中所使用的各种服务提供集中化的认证和路由能力;Kubeflow 中许多服务本质上都是生命期很短的。

Kubeflow architecture, pre-Ambassador

服务配置

有了 Ambassador,Kubeflow 可以使用分布式模型进行配置。 Ambassador 不使用集中的配置文件,而是允许每个服务通过 Kubernetes 注解在 Ambassador 中配置其路由。 下面是一个简化的配置示例:

---
apiVersion: ambassador/v0
kind:  Mapping
name: tfserving-mapping-test-post
prefix: /models/test/
rewrite: /model/test/:predict
method: POST
service: test.kubeflow:8000

示例中,“test” 服务使用 Ambassador 注解来为服务动态配置路由。 所配置的路由仅在 HTTP 方法是 POST 时触发;注解中同时还给出了一条重写规则。

Kubeflow 和 Ambassador

通过 Ambassador,Kubeflow 可以使用 Kubernetes 注解轻松管理路由。 Kubeflow 配置同一个 Ingress 对象,将流量定向到 Ambassador,然后根据需要创建具有 Ambassador 注解的服务,以将流量定向到特定后端。 例如,在部署 TensorFlow 服务时,Kubeflow 会创建 Kubernetes 服务并为其添加注解, 以便用户能够在 https://<ingress主机>/models/<模型名称>/ 处访问到模型本身。 Kubeflow 还可以使用 Envoy Proxy 来进行实际的 L7 路由。 通过 Ambassador,Kubeflow 能够更充分地利用 URL 重写和基于方法的路由等额外的路由配置能力。

如果您对在 Kubeflow 中使用 Ambassador 感兴趣,标准的 Kubeflow 安装会自动安装和配置 Ambassador。

如果您有兴趣将 Ambassador 用作 API 网关或 Kubernetes 的 Ingress 解决方案, 请参阅 Ambassador 入门指南

Kubernetes 这四年

作者:Joe Beda(Heptio 首席技术官兼创始人)

2014 年 6 月 6 日,我检查了 Kubernetes 公共代码库的第一次 commit 。许多人会认为这是故事开始的地方。这难道不是一切开始的地方吗?但这的确不能把整个过程说清楚。

k8s_first_commit

第一次 commit 涉及的人员众多,自那以后 Kubernetes 的成功归功于更大的开发者阵容。

Kubernetes 建立在过去十年曾经在 Google 的 Borg 集群管理系统中验证过的思路之上。而 Borg 本身也是 Google 和其他公司早期努力的结果。

具体而言,Kubernetes 最初是从 Brendan Burns 的一些原型开始,结合我和 Craig McLuckie 正在进行的工作,以更好地将 Google 内部实践与 Google Cloud 的经验相结合。 Brendan,Craig 和我真的希望人们使用它,所以我们建议将这个原型构建为一个开源项目,将 Borg 的最佳创意带给大家。

在我们所有人同意后,就开始着手构建这个系统了。我们采用了 Brendan 的原型(Java 语言),用 Go 语言重写了它,并且以上述核心思想去构建该系统。到这个时候,团队已经成长为包括 Ville Aikas,Tim Hockin,Brian Grant,Dawn Chen 和 Daniel Smith。一旦我们有了一些工作需求,有人必须承担一些脱敏的工作,以便为公开发布做好准备。这个角色最终由我承担。当时,我不知道这件事情的重要性,我创建了一个新的仓库,把代码搬过来,然后进行了检查。所以在我第一次提交 public commit 之前,就有工作已经启动了。

那时 Kubernetes 的版本只是现在版本的简单雏形。核心概念已经有了,但非常原始。例如,Pods 被称为 Tasks,这在我们推广前一天就被替换。2014年6月10日 Eric Brewe 在第一届 DockerCon 上的演讲中正式发布了 Kubernetes。你可以在此处观看该视频:

但是,无论多么原始,这小小的一步足以激起一个开始强大而且变得更强大的社区的兴趣。在过去的四年里,Kubernetes 已经超出了我们所有人的期望。我们对 Kubernetes 社区的所有人员表示感谢。该项目所取得的成功不仅基于代码和技术,还基于一群出色的人聚集在一起所做的有意义的事情。Sarah Novotny 策划的一套 Kubernetes 价值观是以上最好的表现形式。

让我们一起期待下一个 4 年!🎉🎉🎉

向 Discuss Kubernetes 问好

作者: Jorge Castro (Heptio)

就一个超过 35,000 人的全球性社区而言,参与其中时沟通是非常关键的。 跟踪 Kubernetes 社区中的所有内容可能是一项艰巨的任务。 一方面,我们有官方资源,如 Stack Overflow,GitHub 和邮件列表,另一方面,我们有更多瞬时性的资源,如 Slack,你可以加入进去、与某人聊天然后各走各路。

Slack 非常适合随意和及时的对话,并与其他社区成员保持联系,但未来很难轻易引用通信。此外,在35,000名参与者中提问并得到回答很难。邮件列表在有问题尝试联系特定人群并且想要跟踪大家的回应时非常有用,但是对于大量人员来说可能是麻烦的。 Stack Overflow 和 GitHub 非常适合在涉及代码的项目或问题上进行协作,并且如果在将来要进行搜索也很有用,但某些主题如“你最喜欢的 CI/CD 工具是什么”或“Kubectl提示和技巧“在那里是没有意义的。

虽然我们目前的各种沟通渠道对他们自己来说都很有价值,但我们发现电子邮件和实时聊天之间仍然存在差距。在网络的其他部分,许多其他开源项目,如 Docker、Mozilla、Swift、Ghost 和 Chef,已经成功地在Discourse之上构建社区,一个开放的讨论平台。那么,如果我们可以使用这个工具将我们的讨论结合在一个平台下,使用开放的API,或许也不会让我们的大部分信息消失在网络中呢?只有一种方法可以找到:欢迎来到discuss.kubernetes.io

马上,我们有用户可以浏览的类别。检查和发布这些类别允许用户参与他们可能感兴趣的事情,而无需订阅列表。精细的通知控件允许用户只订阅他们想要的类别或标签,并允许通过电子邮件回复主题。

生态系统合作伙伴和开发人员现在有一个地方可以宣布项目,他们正在为用户工作,而不会想知道它是否会在官方列表中脱离主题。我们可以让这个地方不仅仅是关于核心 Kubernetes,而是关于我们社区正在建设的数百个精彩工具。

这个新的社区论坛为人们提供了一个可以讨论 Kubernetes 的地方,也是开发人员在 Kubernetes 周围发布事件的声音板,同时可以搜索并且更容易被更广泛的用户访问。

进来看看。我们刚刚开始,所以,您可能希望从自我介绍开始,到处浏览。也有 AndroidiOS 应用下载。

在 Kubernetes 上开发

作者Michael Hausenblas (Red Hat), Ilya Dmitrichenko (Weaveworks)

您将如何开发一个 Kubernetes 应用?也就是说,您如何编写并测试一个要在 Kubernetes 上运行的应用程序?本文将重点介绍在独自开发或者团队协作中,您可能希望了解到的为了成功编写 Kubernetes 应用程序而需面临的挑战,工具和方法。

我们假定您是一位开发人员,有您钟爱的编程语言,编辑器/IDE(集成开发环境),以及可用的测试框架。在针对 Kubernetes 开发应用时,最重要的目标是减少对当前工作流程的影响,改变越少越好,尽量做到最小。举个例子,如果您是 Node.js 开发人员,习惯于那种热重载的环境 - 也就是说您在编辑器里一做保存,正在运行的程序就会自动更新 - 那么跟容器、容器镜像或者镜像仓库打交道,又或是跟 Kubernetes 部署、triggers 以及更多头疼东西打交道,不仅会让人难以招架也真的会让开发过程完全失去乐趣。

在下文中,我们将首先讨论 Kubernetes 总体开发环境,然后回顾常用工具,最后进行三个示例性工具的实践演练。这些工具允许针对 Kubernetes 进行本地应用程序的开发和迭代。

您的集群运行在哪里?

作为开发人员,您既需要考虑所针对开发的 Kubernetes 集群运行在哪里,也需要思考开发环境如何配置。概念上,有四种开发模式:

Dev Modes

许多工具支持纯 offline 开发,包括 Minikube、Docker(Mac 版/Windows 版)、Minishift 以及下文中我们将详细讨论的几种。有时,比如说在一个微服务系统中,已经有若干微服务在运行,proxied 模式(通过转发把数据流传进传出集群)就非常合适,Telepresence 就是此类工具的一个实例。live 模式,本质上是您基于一个远程集群进行构建和部署。最后,纯 online 模式意味着您的开发环境和运行集群都是远程的,典型的例子是 Eclipse Che 或者 Cloud 9。现在让我们仔细看看离线开发的基础:在本地运行 Kubernetes。

Minikube 在更加喜欢于本地 VM 上运行 Kubernetes 的开发人员中,非常受欢迎。不久前,Docker 的 Mac 版和 Windows 版,都试验性地开始自带 Kubernetes(需要下载 “edge” 安装包)。在两者之间,以下原因也许会促使您选择 Minikube 而不是 Docker 桌面版:

  • 您已经安装了 Minikube 并且它运行良好
  • 您想等到 Docker 出稳定版本
  • 您是 Linux 桌面用户
  • 您是 Windows 用户,但是没有配有 Hyper-V 的 Windows 10 Pro

运行一个本地集群,开发人员可以离线工作,不用支付云服务。云服务收费一般不会太高,并且免费的等级也有,但是一些开发人员不喜欢为了使用云服务而必须得到经理的批准,也不愿意支付意想不到的费用,比如说忘了下线而集群在周末也在运转。

有些开发人员却更喜欢远程的 Kubernetes 集群,这样他们通常可以获得更大的计算能力和存储容量,也简化了协同工作流程。您可以更容易的拉上一个同事来帮您调试,或者在团队内共享一个应用的使用。再者,对某些开发人员来说,尽可能的让开发环境类似生产环境至关重要,尤其是您依赖外部厂商的云服务时,如:专有数据库、云对象存储、消息队列、外商的负载均衡器或者邮件投递系统。

总之,无论您选择本地或者远程集群,理由都足够多。这很大程度上取决于您所处的阶段:从早期的原型设计/单人开发到后期面对一批稳定微服务的集成。

既然您已经了解到运行环境的基本选项,那么我们就接着讨论如何迭代式的开发并部署您的应用。

常用工具

我们现在回顾既可以允许您可以在 Kubernetes 上开发应用程序又尽可能最小地改变您现有的工作流程的一些工具。我们致力于提供一份不偏不倚的描述,也会提及使用某个工具将会意味着什么。

请注意这很棘手,因为即使在成熟定型的技术中做选择,比如说在 JSON、YAML、XML、REST、gRPC 或者 SOAP 之间做选择,很大程度也取决于您的背景、喜好以及公司环境。在 Kubernetes 生态系统内比较各种工具就更加困难,因为技术发展太快,几乎每周都有新工具面市;举个例子,仅在准备这篇博客的期间,GitkubeWatchpod 相继出品。为了进一步覆盖到这些新的,以及一些相关的已推出的工具,例如 Weave Flux 和 OpenShift 的 S2I,我们计划再写一篇跟进的博客。

Draft

Draft 旨在帮助您将任何应用程序部署到 Kubernetes。它能够检测到您的应用所使用的编程语言,并且生成一份 Dockerfile 和 Helm 图表。然后它替您启动构建并且依照 Helm 图表把所生产的镜像部署到目标集群。它也可以让您很容易地设置到 localhost 的端口映射。

这意味着:

  • 用户可以任意地自定义 Helm 图表和 Dockerfile 模版,或者甚至创建一个 custom pack(使用 Dockerfile、Helm 图表以及其他)以备后用
  • 要想理解一个应用应该怎么构建并不容易,在某些情况下,用户也许需要修改 Draft 生成的 Dockerfile 和 Heml 图表
  • 如果使用 Draft version 0.12.01 或者更老版本,每一次用户想要测试一个改动,他们需要等 Draft 把代码拷贝到集群,运行构建,推送镜像并且发布更新后的图表;这些步骤可能进行得很快,但是每一次用户的改动都会产生一个镜像(无论是否提交到 git )
  • 在 Draft 0.12.0版本,构建是本地进行的
  • 用户不能选择 Helm 以外的工具进行部署
  • 它可以监控本地的改动并且触发部署,但是这个功能默认是关闭的
  • 它允许开发人员使用本地或者远程的 Kubernetes 集群
  • 如何部署到生产环境取决于用户, Draft 的作者推荐了他们的另一个项目 - Brigade
  • 可以代替 Skaffold, 并且可以和 Squash 一起使用

更多信息:

【1】:此处疑为 0.11.0,因为 0.12.0 已经支持本地构建,见下一条

Skaffold

Skaffold 让 CI 集成具有可移植性的,它允许用户采用不同的构建系统,镜像仓库和部署工具。它不同于 Draft,同时也具有一定的可比性。它具有生成系统清单的基本能力,但那不是一个重要功能。Skaffold 易于扩展,允许用户在构建和部署应用的每一步选取相应的工具。

这意味着:

  • 模块化设计
  • 不依赖于 CI,用户不需要 Docker 或者 Kubernetes 插件
  • 没有 CI 也可以工作,也就是说,可以在开发人员的电脑上工作
  • 它可以监控本地的改动并且触发部署
  • 它允许开发人员使用本地或者远程的 Kubernetes 集群
  • 它可以用于部署生产环境,用户可以精确配置,也可以为每一套目标环境提供不同的生产线
  • 可以代替 Draft,并且和其他工具一起使用

更多信息:

Squash

Squash 包含一个与 Kubernetes 全面集成的调试服务器,以及一个 IDE 插件。它允许您插入断点和所有的调试操作,就像您所习惯的使用 IDE 调试一个程序一般。它允许您将调试器应用到 Kubernetes 集群中运行的 pod 上,从而让您可以使用 IDE 调试 Kubernetes 集群。

这意味着:

  • 不依赖您选择的其它工具
  • 需要一组特权 DaemonSet
  • 可以和流行 IDE 集成
  • 支持 Go、Python、Node.js、Java 和 gdb
  • 用户必须确保容器中的应用程序使编译时使用了调试符号
  • 可与此处描述的任何其他工具结合使用
  • 它可以与本地或远程 Kubernetes 集群一起使用

更多信息:

Telepresence

Telepresence 使用双向代理将开发人员工作站上运行的容器与远程 Kubernetes 集群连接起来,并模拟集群内环境以及提供对配置映射和机密的访问。它消除了将应用部署到集群的需要,并利用本地容器抽象出网络和文件系统接口,以使其看起来应用好像就在集群中运行,从而改进容器应用程序开发的迭代时间。

这意味着:

  • 它不依赖于其它您选取的工具
  • 可以同 Squash 一起使用,但是 Squash 必须用于调试集群中的 pods,而传统/本地调试器需要用于调试通过 Telepresence 连接到集群的本地容器
  • Telepresence 会产生一些网络延迟
  • 它通过辅助进程提供连接 - sshuttle,基于SSH的一个工具
  • 还提供了使用 LD_PRELOAD/DYLD_INSERT_LIBRARIES 的更具侵入性的依赖注入模式
  • 它最常用于远程 Kubernetes 集群,但也可以与本地集群一起使用

更多信息:

Ksync

Ksync 在本地计算机和运行在 Kubernetes 中的容器之间同步应用程序代码(和配置),类似于 oc rsync 在 OpenShift 中的角色。它旨在通过消除构建和部署步骤来缩短应用程序开发的迭代时间。

这意味着:

  • 它绕过容器图像构建和修订控制
  • 使用编译语言的用户必须在 pod(TBC)内运行构建
  • 双向同步 - 远程文件会复制到本地目录
  • 每次更新远程文件系统时都会重启容器
  • 无安全功能 - 仅限开发
  • 使用 Syncthing,一个用于点对点同步的 Go 语言库
  • 需要一个在集群中运行的特权 DaemonSet
  • Node 必须使用带有 overlayfs2 的 Docker - 在写作本文时,尚不支持其他 CRI 实现

更多信息:

实践演练

我们接下来用于练习使用工具的应用是一个简单的股市模拟器,包含两个微服务:

  • stock-gen(股市数据生成器)微服务是用 Go 编写的,随机生成股票数据并通过 HTTP 端点 / stockdata 公开
  • 第二个微服务,stock-con(股市数据消费者)是一个 Node.js 应用程序,它使用来自 stock-gen 的股票数据流,并通过 HTTP 端点 /average/$SYMBOL 提供股价移动平均线,也提供一个健康检查端点 /healthz

总体上,此应用的默认配置如下图所示:

Default Setup

在下文中,我们将选取以上讨论的代表性工具进行实践演练:ksync,具有本地构建的 Minikube 以及 Skaffold。对于每个工具,我们执行以下操作:

  • 设置相应的工具,包括部署准备和 stock-con 微服务数据的本地读取
  • 执行代码更新,即更改 stock-con 微服务的 /healthz 端点的源代码并观察网页刷新

请注意,我们一直使用 Minikube 的本地 Kubernetes 集群,但是您也可以使用 ksync 和 Skaffold 的远程集群跟随练习。

实践演练:ksync

作为准备,安装 ksync,然后执行以下步骤配置开发环境:

$ mkdir -p $(pwd)/ksync
$ kubectl create namespace dok
$ ksync init -n dok

完成基本设置后,我们可以告诉 ksync 的本地客户端监控 Kubernetes 的某个命名空间,然后我们创建一个规范来定义我们想要同步的文件夹(本地的 $(pwd)/ksync 和容器中的 / app )。请注意,目标 pod 是用 selector 参数指定:

$ ksync watch -n dok
$ ksync create -n dok --selector=app=stock-con $(pwd)/ksync /app
$ ksync get -n dok

现在我们部署股价数据生成器和股价数据消费者微服务:

$ kubectl -n=dok apply \
      -f https://raw.githubusercontent.com/kubernauts/dok-example-us/master/stock-gen/app.yaml
$ kubectl -n=dok apply \
      -f https://raw.githubusercontent.com/kubernauts/dok-example-us/master/stock-con/app.yaml

一旦两个部署建好并且 pod 开始运行,我们转发 stock-con 服务以供本地读取(另开一个终端窗口):

$ kubectl get -n dok po --selector=app=stock-con  \
                     -o=custom-columns=:metadata.name --no-headers |  \
                     xargs -IPOD kubectl -n dok port-forward POD 9898:9898

这样,通过定期查询 healthz 端点,我们就应该能够从本地机器上读取 stock-con 服务,查询命令如下(在一个单独的终端窗口):

$ watch curl localhost:9898/healthz

现在,改动 ksync/stock-con 目录中的代码,例如改动 service.js 中定义的 /healthz 端点代码,在其 JSON 形式的响应中新添一个字段并观察 pod 如何更新以及 curl localhost:9898/healthz 命令的输出发生何种变化。总的来说,您最后应该看到类似的内容:

Preview

实践演练:带本地构建的 Minikube

对于以下内容,您需要启动并运行 Minikube,我们将利用 Minikube 自带的 Docker daemon 在本地构建镜像。作为准备,请执行以下操作

$ git clone https://github.com/kubernauts/dok-example-us.git && cd dok-example-us
$ eval $(minikube docker-env)
$ kubectl create namespace dok

现在我们部署股价数据生成器和股价数据消费者微服务:

$ kubectl -n=dok apply -f stock-gen/app.yaml
$ kubectl -n=dok apply -f stock-con/app.yaml

一旦两个部署建好并且 pod 开始运行,我们转发 stock-con 服务以供本地读取(另开一个终端窗口)并检查 healthz 端点的响应:

$ kubectl get -n dok po --selector=app=stock-con  \
                     -o=custom-columns=:metadata.name --no-headers |  \
                     xargs -IPOD kubectl -n dok port-forward POD 9898:9898 &
$ watch curl localhost:9898/healthz

现在,改一下 ksync/stock-con 目录中的代码,例如修改 service.js 中定义的 /healthz 端点代码,在其 JSON 形式的响应中添加一个字段。在您更新完代码后,最后一步是构建新的容器镜像并启动新部署,如下所示:

$ docker build -t stock-con:dev -f Dockerfile .
$ kubectl -n dok set image deployment/stock-con *=stock-con:dev

总的来说,您最后应该看到类似的内容:

Local Preview

实践演练:Skaffold

要进行此演练,首先需要安装 Skaffold。完成后,您可以执行以下步骤来配置开发环境:

$ git clone https://github.com/kubernauts/dok-example-us.git && cd dok-example-us
$ kubectl create namespace dok

现在我们部署股价数据生成器(但是暂不部署股价数据消费者,此服务将使用 Skaffold 完成):

$ kubectl -n=dok apply -f stock-gen/app.yaml

请注意,最初我们在执行 skaffold dev 时发生身份验证错误,为避免此错误需要安装问题322 中所述的修复。本质上,需要将 〜/.docker/config.json 的内容改为:

{
   "auths": {}
}

接下来,我们需要略微改动 stock-con/app.yaml,这样 Skaffold 才能正常使用此文件:

stock-con 部署和服务中添加一个 namespace 字段,其值为 dok

将容器规范的 image 字段更改为 quay.io/mhausenblas/stock-con,因为 Skaffold 可以即时管理容器镜像标签。

最终的 stock-con 的 app.yaml 文件看起来如下:

apiVersion: apps/v1beta1
kind: Deployment
metadata:
  labels:
    app: stock-con
  name: stock-con
  namespace: dok
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: stock-con
    spec:
      containers:
      - name: stock-con
        image: quay.io/mhausenblas/stock-con
        env:
        - name: DOK_STOCKGEN_HOSTNAME
          value: stock-gen
        - name: DOK_STOCKGEN_PORT
          value: "9999"
        ports:
        - containerPort: 9898
          protocol: TCP
        livenessProbe:
          initialDelaySeconds: 2
          periodSeconds: 5
          httpGet:
            path: /healthz
            port: 9898
        readinessProbe:
          initialDelaySeconds: 2
          periodSeconds: 5
          httpGet:
            path: /healthz
            port: 9898
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: stock-con
  name: stock-con
  namespace: dok
spec:
  type: ClusterIP
  ports:
  - name: http
    port: 80
    protocol: TCP
    targetPort: 9898
  selector:
    app: stock-con

我们能够开始开发之前的最后一步是配置 Skaffold。因此,在 stock-con/ 目录中创建文件 skaffold.yaml,其中包含以下内容:

apiVersion: skaffold/v1alpha2
kind: Config
build:
  artifacts:
  - imageName: quay.io/mhausenblas/stock-con
    workspace: .
    docker: {}
  local: {}
deploy:
  kubectl:
    manifests:
      - app.yaml

现在我们准备好开始开发了。为此,在 stock-con/ 目录中执行以下命令:

$ skaffold dev

上面的命令将触发 stock-con 图像的构建和部署。一旦 stock-con 部署的 pod 开始运行,我们再次转发 stock-con 服务以供本地读取(在单独的终端窗口中)并检查 healthz 端点的响应:

$ kubectl get -n dok po --selector=app=stock-con  \
                     -o=custom-columns=:metadata.name --no-headers |  \
                     xargs -IPOD kubectl -n dok port-forward POD 9898:9898 &
$ watch curl localhost:9898/healthz

现在,如果您修改一下 stock-con 目录中的代码,例如 service.js 中定义的 /healthz 端点代码,在其 JSON 形式的响应中添加一个字段,您应该看到 Skaffold 可以检测到代码改动并创建新图像以及部署它。您的屏幕看起来应该类似这样:

Skaffold Preview

至此,您应该对不同的工具如何帮您在 Kubernetes 上开发应用程序有了一定的概念,如果您有兴趣了解有关工具和/或方法的更多信息,请查看以下资源:

有了这些,我们这篇关于如何在 Kubernetes 上开发应用程序的博客就可以收尾了,希望您有所收获,如果您有反馈和/或想要指出您认为有用的工具,请通过 Twitter 告诉我们:IlyaMichael

Kubernetes 社区 - 2017 年开源排行榜榜首

对于 Kubernetes 来说,2017 年是丰收的一年,GitHub的最新 Octoverse 报告 说明了该项目获得了多少关注。

Kubernetes 是 用于运行应用程序容器的开源平台,它提供了一个统一的界面,使开发人员和操作团队能够自动执行部署、管理和扩展几乎任何基础架构上的各种应用程序。

Kubernetes 所做的,是通过利用广泛的专业知识和行业经验来解决这些共同的挑战,可以帮助工程师专注于在堆栈的顶部构建自己的产品,而不是不必要地进行重复工作,比如现在已经存在的 “云原生” 工具包的标准部分。

但是,通过临时的集体组织来实现这些收益是它独有的挑战,这使得支持开源,社区驱动的工作变得越来越困难。

继续阅读以了解 Kubernetes 社区如何解决这些挑战,从而在 GitHub 的 2017 Octoverse 报告中位居榜首。

GitHub 上讨论最多的

2017 年讨论最多的两个仓库都是基于 Kubernetes 的:

讨论最多

在 GitHub 的所有开源存储库中,没有比 kubernetes/kubernetes 收到更多的评论。 OpenShiftCNCF 认证的 Kubernetes 发行版 排名第二。

利用充足时间进行公开讨论来获取社区反馈和审查,有助于建立共享的基础架构并为云原生计算建立新标准。

GitHub 上审阅最多的

成功扩展开放源代码工作的通信通常会带来更好的协调和更高质量的功能交付。Kubernetes 项目的 Special Interest Group(SIG) 结构已使其成为 GitHub 审阅第二多的项目:

审阅最多

使用 SIG 对社区参与机制进行细分和标准化有助于从资格更高的社区成员中获得更频繁的审阅。

如果得到有效管理,活跃的社区讨论不仅表明代码库存在很大的争议,也可能表明项目包含大量未满足的需求。

扩展项目处理问题和社区互动的能力有助于扩大交流。同时,大型社区具有更多不同的用例和更多的支持问题需要管理。Kubernetes SIG 组织结构 帮助应对大规模复杂通信的挑战。

SIG 会议为不同学科的用户、维护者和专家提供了重点合作的机会,以共同协作来支持社区的工作。这些在组织上的投资有助于创建一个环境,在这样的环境中,可以更轻松地将架构讨论和规划的优先级排到提交速度前面,并使项目能够维持这种规模。

加入我们!

您可能已经在 Kubernetes 上成功使用管理和扩展的解决方案。例如,托管 Kubernetes 上游源代码的 GitHub.com 现在也可以在 Kubernetes 上运行

请查看 Kubernetes 贡献者指南 ,以获取有关如何开始作为贡献者的更多信息。

您也可以参加 每周 Kubernetes 的社区会议 并考虑 加入一个或两个 SIG

“基于容器的应用程序设计原理”

如今,可以将几乎所有应用程序放入容器中并运行它。 但是,创建云原生应用程序(由 Kubernetes 等云原生平台自动有效地编排的容器化应用程序)需要付出额外的努力。 云原生应用程序会预期失败; 它们可以可靠的运行和扩展,即使基础架构出现故障。 为了提供这样的功能,像 Kubernetes 这样的云原生平台对应用程序施加了一系列约定和约束。 这些合同确保运行的应用程序符合某些约束条件,并允许平台自动执行应用程序管理。

我总结了容器化应用要成为彻底的云原生应用所要遵从的七个原则

| ----- | | |

| 容器设计原则 |

这七个原则涵盖了构建时间和运行时问题。

建立时间

  • 单独关注点: 每个容器都解决了一个单独的关注点,并做到了。
  • 自包含: 容器仅依赖于Linux内核的存在。 构建容器时会添加其他库。
  • 镜像不可变性: 容器化应用程序是不可变的,并且一旦构建,就不会在不同环境之间发生变化。

运行时

  • 高度可观察性: 每个容器都必须实现所有必要的API,以帮助平台以最佳方式观察和管理应用程序。
  • 生命周期一致性: 容器必须具有读取来自平台的事件并通过对这些事件做出反应来进行一致性的方式。
  • 进程可丢弃: 容器化的应用程序必须尽可能短暂,并随时可以被另一个容器实例替换。
  • 运行时可约束 每个容器必须声明其资源需求,并根据所标明的需求限制其资源使用。 构建时间原则可确保容器具有正确的颗粒度,一致性和适当的结构。 运行时原则规定了必须执行哪些功能才能使容器化的应用程序具有云原生功能。 遵循这些原则有助于确保您的应用程序适合Kubernetes中的自动化。

白皮书可以免费下载:

要了解有关为Kubernetes设计云原生应用程序的更多信息,请翻阅我的Kubernetes 模式这本书。

Bilgin Ibryam,首席架构师,Red Hat

推特:
博客: http://www.ofbizian.com
领英:

Bilgin Ibryam(@bibryam)是 Red Hat 的首席架构师,ASF 的开源提交者,博客,作者和发言人。 他是骆驼设计模式和 Kubernetes 模式书籍的作者。 在日常工作中,Bilgin 乐于指导,培训和领导团队,以使他们在分布式系统,微服务,容器和云原生应用程序方面取得成功。

Kubernetes 1.9 对 Windows Server 容器提供 Beta 版本支持

随着 Kubernetes v1.9 的发布,我们确保所有人在任何地方都能正常运行 Kubernetes 的使命前进了一大步。我们的 Beta 版本对 Windows Server 的支持进行了升级,并且在 Kubernetes 和 Windows 平台上都提供了持续的功能改进。为了在 Kubernetes 上运行许多特定于 Windows 的应用程序和工作负载,SIG-Windows 自2016年3月以来一直在努力,大大扩展了 Kubernetes 的实现场景和企业适用范围。

各种规模的企业都在 .NET 和基于 Windows 的应用程序上进行了大量投资。如今许多企业产品组合都包含 .NET 和 Windows,Gartner 声称 80% 的企业应用都在 Windows 上运行。根据 StackOverflow Insights,40% 的专业开发人员使用 .NET 编程语言(包括 .NET Core)。

但为什么这些信息都很重要?这意味着企业既有传统的,也有新生的云(microservice)应用程序,利用了大量的编程框架。业界正在大力推动将现有/遗留应用程序现代化到容器中,使用类似于“提升和转移”的方法。同时,也能灵活地向其他 Windows 或 Linux 容器引入新功能。容器正在成为打包、部署和管理现有程序和微服务应用程序的业界标准。IT 组织正在寻找一种更简单且一致的方法来跨 Linux 和 Windows 环境进行协调和管理容器。Kubernetes v1.9 现在对 Windows Server 容器提供了 Beta 版本支持,使之成为策划任何类型容器的明确选择。

特点

Kubernetes 中对 Windows Server 容器的 Alpha 支持是非常有用的,尤其是对于概念项目和可视化 Kubernetes 中 Windows 支持的路线图。然而,Alpha 版本有明显的缺点,并且缺少许多特性,特别是在网络方面。SIG Windows、Microsoft、Cloudbase Solutions、Apprenda 和其他社区成员联合创建了一个全面的 Beta 版本,使 Kubernetes 用户能够开始评估和使用 Windows。

Kubernetes 对 Windows 服务器容器的一些关键功能改进包括:

  • 改进了对 Pod 的支持!Pod 中多个 Windows Server 容器现在可以使用 Windows Server 中的网络隔离专区共享网络命名空间。此功能中 Pod 的概念相当于基于 Linux 的容器
  • 可通过每个 Pod 使用单个网络端点来降低网络复杂性
  • 可以使用 Virtual Filtering Platform(VFP)的 Hyper-v Switch Extension(类似于 Linux iptables)达到基于内核的负载平衡
  • 具备 Container Runtime Interface(CRI)的 Pod 和 Node 级别的统计信息。可以使用从 Pod 和节点收集的性能指标配置 Windows Server 容器的 Horizontal Pod Autoscaling
  • 支持 kubeadm 命令将 Windows Server 的 Node 添加到 Kubernetes 环境。Kubeadm 简化了 Kubernetes 集群的配置,通过对 Windows Server 的支持,您可以在您的基础配置中使用单一的工具部署 Kubernetes
  • 支持 ConfigMaps, Secrets, 和 Volumes。这些是非常关键的特性,您可以将容器的配置从实施体系中分离出来,并且在大部分情况下是安全的
    然而,kubernetes 1.9 windows 支持的最大亮点是网络增强。随着 Windows 服务器 1709 的发布,微软在操作系统和 Windows Host Networking Service(HNS)中启用了关键的网络功能,这为创造大量与 Kubernetes 中的 Windows 服务器容器一起工作的 CNI 插件铺平了道路。Kubernetes 1.9 支持的第三层路由和网络覆盖插件如下所示:
  1. 上游 L3 路由 - 上游 ToR 中配置的 IP 路由
  2. Host-Gateway - 在每个主机上配置的 IP 路由
  3. 具有 Overlay 的 Open vSwitch(OVS)和 Open Virtual Network(OVN) - 支持 STT 和 Geneve 的 tunneling 类型 您可以阅读更多有关 配置、设置和运行时功能 的信息,以便在 Kubernetes 中为您的网络堆栈做出明智的选择。

如果您需要继续在 Linux 中运行 Kubernetes Control Plane 和 Master Components,现在也可以将 Windows Server 作为 Kubernetes 中的一个节点引入。对一个社区来说,这是一个巨大的里程碑和成就。现在,我们将会在 Kubernetes 中看到 .NET,.NET Core,ASP.NET,IIS,Windows 服务,Windows 可执行文件以及更多基于 Windows 的应用程序。

接下来还会有什么

这个 Beta 版本进行了大量工作,但是社区意识到在将 Windows 支持作为生产工作负载发布为 GA(General Availability)之前,我们需要更多领域的投资。2018年前两个季度的重点关注领域包括:

  1. 继续在网络领域取得更多进展。其他 CNI 插件正在开发中,并且即将完成
  • Overlay - win-Overlay(vxlan 或 IP-in-IP 使用 Flannel 封装)
  • Win-l2bridge(host-gateway)
  • 使用云网络的 OVN - 不再依赖 Overlay
  • 在 ovn-Kubernetes 中支持 Kubernetes 网络策略
  • 支持 Hyper-V Isolation
  • 支持有状态应用程序的 StatefulSet 功能
  • 生成适用于任何基础架构以及跨多公共云提供商(例如 Microsoft Azure,Google Cloud 和 Amazon AWS)的安装工具和文档
  • SIG-Windows 的 Continuous Integration/Continuous Delivery(CI/CD)基础结构
  • 可伸缩性和性能测试 尽管我们尚未承诺正式版的具体时间线,但估计 SIG-Windows 将于2018年上半年正式发布。

加入我们

随着我们在 Kubernetes 的普遍可用性方向不断取得进展,我们欢迎您参与进来,贡献代码、提供反馈,将 Windows 服务器容器部署到 Kubernetes 集群,或者干脆加入我们的社区。

谢谢大家,

Michael Michael (@michmike77)
SIG-Windows 领导人
Apprenda 产品管理高级总监

Kubernetes 中自动缩放

Kubernetes 允许开发人员根据当前的流量和负载自动调整集群大小和 pod 副本的数量。这些调整减少了未使用节点的数量,节省了资金和资源。 在这次演讲中,谷歌的 Marcin Wielgus 将带领您了解 Kubernetes 中 pod 和 node 自动调焦的当前状态:它是如何工作的,以及如何使用它,包括在生产应用程序中部署的最佳实践。

喜欢这个演讲吗? 12 月 6 日至 8 日,在 Austin 参加 KubeCon 关于扩展和自动化您的 Kubernetes 集群的更令人兴奋的会议。现在注册

一定要查看由 Ron Lipke, Gannet/USA Today Network, 平台即服务高级开发人员,在公共云中自动化和测试产品就绪的 Kubernetes 集群

Kubernetes 1.8 的五天

Kubernetes 1.8 已经推出,数百名贡献者在这个最新版本中推出了成千上万的提交。

社区已经有超过 66,000 个提交在主仓库,并在主仓库之外继续快速增长,这标志着该项目日益成熟和稳定。仅 v1.7.0 到 v1.8.0,社区就记录了所有仓库的超过 120,000 次提交和 17839 次提交。

在拥有 1400 多名贡献者,并且不断发展壮大的社区的帮助下,我们合并了 3000 多个 PR,并发布了 5000 多个提交,最后的 Kubernetes 1.8 在安全和工作负载方面添加了很多的更新。 这一切都表明稳定性的提高,这是我们整个项目关注成熟流程、形式化架构和加强 Kubernetes 的治理模型的结果。

虽然有很多改进,但我们在下面列出的这一系列深度文章中突出了一些关键特性。跟随并了解存储,安全等方面的新功能和改进功能。

第一天: Kubernetes 1.8 的五天 第二天: kubeadm v1.8 为 Kubernetes 集群引入了简单的升级 第三天: Kubernetes v1.8 回顾:提升一个 Kubernetes 需要一个 Village 第四天: 使用 RBAC,一般在 Kubernetes v1.8 中提供 第五天: 在 Kubernetes 执行网络策略

链接

  • Stack Overflow 上发布问题(或回答问题)
  • 加入 K8sPort 布道师的社区门户网站
  • 在 Twitter @Kubernetesio 关注我们以获取最新更新
  • Slack 上的社区联系
  • 参与 GitHub 上的 Kubernetes 项目

Kubernetes 社区指导委员会选举结果

自 2015 年 OSCON 发布 Kubernetes 1.0 以来,大家一直在共同努力,在 Kubernetes 社区中共同分享领导力和责任。

在 Brandon Philips、Brendan Burns、Brian Grant、Clayton Coleman、Joe Beda、Sarah Novotny 和 Tim Hockin 组成的自举治理委员会的工作下 - 代表 5 家不同公司的长期领导者,他们对 Kubernetes 生态系统进行了大量的人才投资和努力 - 编写了初始的指导委员会章程,并发起了一次社区选举,以选举 Kubernetes 指导委员会成员。

引用章程 -

_指导委员会的最初职责是实例化 Kubernetes 治理的正式过程。除定义初始治理过程外,指导委员会还坚信提供一种方法来迭代指导委员会定义的方法很重要。我们不相信我们会在第一次或以后把这些做好,也不会一口气完成治理开发工作。指导委员会的作用是成为一个积极响应的机构,可以根据需要进行重构和改造,以适应不断变化的项目和社区。

这是将我们隐式治理结构明确化的最大一步。Kubernetes 的愿景一直是成为一个包容而广泛的社区,用我们的软件带给用户容器的便利性。指导委员会将是一个强有力的引领声音,指导该项目取得成功。

Kubernetes 社区很高兴地宣布 2017 年指导委员会选举的结果。 请祝贺 Aaron Crickenberger、Derek Carr、Michelle Noorali、Phillip Wittrock、Quinton Hoole 和 Timothy St. Clair,他们将成为新成立的 Kubernetes 指导委员会的自举治理委员会成员。Derek、Michelle 和 Phillip 将任职 2 年。Aaron、Quinton、和 Timothy 将任职 1 年。

该小组将定期开会,以阐明和简化项目的结构和运行。早期的工作将包括选举 CNCF 理事会的代表,发展项目流程,完善和记录项目的愿景和范围,以及授权和委派更多主题社区团体。

请参阅完整的指导委员会待办事项列表以获取更多详细信息。

使用 Kubernetes Pet Sets 和 Datera Elastic Data Fabric 的 FlexVolume 扩展有状态的应用程序

编者注:今天的邀请帖子来自 Datera 公司的软件架构师 Shailesh Mittal 和高级产品总监 Ashok Rajagopalan,介绍在 Datera Elastic Data Fabric 上用 Kubernetes 配置状态应用程序。

简介

用户从无状态工作负载转移到运行有状态应用程序,Kubernetes 中的持久卷是基础。虽然 Kubernetes 早已支持有状态的应用程序,比如 MySQL、Kafka、Cassandra 和 Couchbase,但是 Pet Sets 的引入明显改善了情况。特别是,Pet Sets 具有持续扩展和关联的能力,在配置和启动的顺序过程中,可以自动缩放“Pets”(需要连续处理和持久放置的应用程序)。

Datera 是用于云部署的弹性块存储,可以通过 FlexVolume 框架与 Kubernetes 无缝集成。基于容器的基本原则,Datera 允许应用程序的资源配置与底层物理基础架构分离,为有状态的应用程序提供简洁的协议(也就是说,不依赖底层物理基础结构及其相关内容)、声明式格式和最后移植的能力。

Kubernetes 可以通过 yaml 配置来灵活定义底层应用程序基础架构,而 Datera 可以将该配置传递给存储基础结构以提供持久性。通过 Datera AppTemplates 声明,在 Kubernetes 环境中,有状态的应用程序可以自动扩展。

部署永久性存储

永久性存储是通过 Kubernetes 的子系统 PersistentVolume 定义的。PersistentVolumes 是卷插件,它定义的卷的生命周期和使用它的 Pod 相互独立。PersistentVolumes 由 NFS、iSCSI 或云提供商的特定存储系统实现。Datera 开发了用于 PersistentVolumes 的卷插件,可以在 Datera Data Fabric 上为 Kubernetes 的 Pod 配置 iSCSI 块存储。

Datera 卷插件从 minion nodes 上的 kubelet 调用,并通过 REST API 回传到 Datera Data Fabric。以下是带有 Datera 插件的 PersistentVolume 的部署示例:

 apiVersion: v1

 kind: PersistentVolume

 metadata:

   name: pv-datera-0

 spec:

   capacity:

     storage: 100Gi

   accessModes:

     - ReadWriteOnce

   persistentVolumeReclaimPolicy: Retain

   flexVolume:

     driver: "datera/iscsi"

     fsType: "xfs"

     options:

       volumeID: "kube-pv-datera-0"

       size: “100"

       replica: "3"

       backstoreServer: "[tlx170.tlx.daterainc.com](http://tlx170.tlx.daterainc.com/):7717”

为 Pod 申请 PersistentVolume,要按照以下清单在 Datera Data Fabric 中配置 100 GB 的 PersistentVolume。

[root@tlx241 /]# kubectl get pv

NAME          CAPACITY   ACCESSMODES   STATUS      CLAIM     REASON    AGE

pv-datera-0   100Gi        RWO         Available                       8s

pv-datera-1   100Gi        RWO         Available                       2s

pv-datera-2   100Gi        RWO         Available                       7s

pv-datera-3   100Gi        RWO         Available                       4s

配置

Datera PersistenceVolume 插件安装在所有 minion node 上。minion node 的声明是绑定到之前设置的永久性存储上的,当 Pod 进入具备有效声明的 minion node 上时,Datera 插件会转发请求,从而在 Datera Data Fabric 上创建卷。根据配置请求,PersistentVolume 清单中所有指定的选项都将发送到插件。

在 Datera Data Fabric 中配置的卷会作为 iSCSI 块设备呈现给 minion node,并且 kubelet 将该设备安装到容器(在 Pod 中)进行访问。

使用永久性存储

Kubernetes PersistentVolumes 与具备 PersistentVolume Claims 的 Pod 一起使用。定义声明后,会被绑定到与声明规范匹配的 PersistentVolume 上。上面提到的定义 PersistentVolume 的典型声明如下所示:

kind: PersistentVolumeClaim

apiVersion: v1

metadata:

 name: pv-claim-test-petset-0

spec:

 accessModes:

   - ReadWriteOnce

 resources:

   requests:

     storage: 100Gi

定义这个声明并将其绑定到 PersistentVolume 时,资源与 Pod 规范可以一起使用:

[root@tlx241 /]# kubectl get pv

NAME          CAPACITY   ACCESSMODES   STATUS      CLAIM                            REASON    AGE

pv-datera-0   100Gi      RWO           Bound       default/pv-claim-test-petset-0             6m

pv-datera-1   100Gi      RWO           Bound       default/pv-claim-test-petset-1             6m

pv-datera-2   100Gi      RWO           Available                                              7s

pv-datera-3   100Gi      RWO           Available                                              4s


[root@tlx241 /]# kubectl get pvc

NAME                     STATUS    VOLUME        CAPACITY   ACCESSMODES   AGE

pv-claim-test-petset-0   Bound     pv-datera-0   0                        3m

pv-claim-test-petset-1   Bound     pv-datera-1   0                        3m

Pod 可以使用 PersistentVolume 声明,如下所示:

apiVersion: v1

kind: Pod

metadata:

 name: kube-pv-demo

spec:

 containers:

 - name: data-pv-demo

   image: nginx

   volumeMounts:

   - name: test-kube-pv1

     mountPath: /data

   ports:

   - containerPort: 80

 volumes:

 - name: test-kube-pv1

   persistentVolumeClaim:

     claimName: pv-claim-test-petset-0

程序的结果是 Pod 将 PersistentVolume Claim 作为卷。依次将请求发送到 Datera 卷插件,然后在 Datera Data Fabric 中配置存储。

[root@tlx241 /]# kubectl describe pods kube-pv-demo

Name:       kube-pv-demo

Namespace:  default

Node:       tlx243/172.19.1.243

Start Time: Sun, 14 Aug 2016 19:17:31 -0700

Labels:     \<none\>

Status:     Running

IP:         10.40.0.3

Controllers: \<none\>

Containers:

 data-pv-demo:

   Container ID: [docker://ae2a50c25e03143d0dd721cafdcc6543fac85a301531110e938a8e0433f74447](about:blank)

   Image:   nginx

   Image ID: [docker://sha256:0d409d33b27e47423b049f7f863faa08655a8c901749c2b25b93ca67d01a470d](about:blank)

   Port:    80/TCP

   State:   Running

     Started:  Sun, 14 Aug 2016 19:17:34 -0700

   Ready:   True

   Restart Count:  0

   Environment Variables:  \<none\>

Conditions:

 Type           Status

 Initialized    True

 Ready          True

 PodScheduled   True

Volumes:

 test-kube-pv1:

   Type:  PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)

   ClaimName:   pv-claim-test-petset-0

   ReadOnly:    false

 default-token-q3eva:

   Type:        Secret (a volume populated by a Secret)

   SecretName:  default-token-q3eva

   QoS Tier:  BestEffort

Events:

 FirstSeen LastSeen Count From SubobjectPath Type Reason Message

 --------- -------- ----- ---- ------------- -------- ------ -------

 43s 43s 1 {default-scheduler } Normal Scheduled Successfully assigned kube-pv-demo to tlx243

 42s 42s 1 {kubelet tlx243} spec.containers{data-pv-demo} Normal Pulling pulling image "nginx"

 40s 40s 1 {kubelet tlx243} spec.containers{data-pv-demo} Normal Pulled Successfully pulled image "nginx"

 40s 40s 1 {kubelet tlx243} spec.containers{data-pv-demo} Normal Created Created container with docker id ae2a50c25e03

 40s 40s 1 {kubelet tlx243} spec.containers{data-pv-demo} Normal Started Started container with docker id ae2a50c25e03

永久卷在 minion node(在本例中为 tlx243)中显示为 iSCSI 设备:

[root@tlx243 ~]# lsscsi

[0:2:0:0]    disk    SMC      SMC2208          3.24  /dev/sda

[11:0:0:0]   disk    DATERA   IBLOCK           4.0   /dev/sdb


[root@tlx243 datera~iscsi]# mount  ``` grep sdb

/dev/sdb on /var/lib/kubelet/pods/6b99bd2a-628e-11e6-8463-0cc47ab41442/volumes/datera~iscsi/pv-datera-0 type xfs (rw,relatime,attr2,inode64,noquota)

在 Pod 中运行的容器按照清单中将设备安装在 /data 上:

[root@tlx241 /]# kubectl exec kube-pv-demo -c data-pv-demo -it bash

root@kube-pv-demo:/# mount  ``` grep data

/dev/sdb on /data type xfs (rw,relatime,attr2,inode64,noquota)

使用 Pet Sets

通常,Pod 被视为无状态单元,因此,如果其中之一状态异常或被取代,Kubernetes 会将其丢弃。相反,PetSet 是一组有状态的 Pod,具有更强的身份概念。PetSet 可以将标识分配给应用程序的各个实例,这些应用程序没有与底层物理结构连接,PetSet 可以消除这种依赖性。

每个 PetSet 需要{0..n-1}个 Pet。每个 Pet 都有一个确定的名字、PetSetName-Ordinal 和唯一的身份。每个 Pet 最多有一个 Pod,每个 PetSet 最多包含一个给定身份的 Pet。要确保每个 PetSet 在任何特定时间运行时,具有唯一标识的“pet”的数量都是确定的。Pet 的身份标识包括以下几点:

  • 一个稳定的主机名,可以在 DNS 中使用
  • 一个序号索引
  • 稳定的存储:链接到序号和主机名

使用 PersistentVolume Claim 定义 PetSet 的典型例子如下所示:

# A headless service to create DNS records

apiVersion: v1

kind: Service

metadata:

 name: test-service

 labels:

   app: nginx

spec:

 ports:

 - port: 80

   name: web

 clusterIP: None

 selector:

   app: nginx

---

apiVersion: apps/v1alpha1

kind: PetSet

metadata:

 name: test-petset

spec:

 serviceName: "test-service"

 replicas: 2

 template:

   metadata:

     labels:

       app: nginx

     annotations:

       [pod.alpha.kubernetes.io/initialized:](http://pod.alpha.kubernetes.io/initialized:) "true"

   spec:

     terminationGracePeriodSeconds: 0

     containers:

     - name: nginx

       image: [gcr.io/google\_containers/nginx-slim:0.8](http://gcr.io/google_containers/nginx-slim:0.8)

       ports:

       - containerPort: 80

         name: web

       volumeMounts:

       - name: pv-claim

         mountPath: /data

 volumeClaimTemplates:

 - metadata:

     name: pv-claim

     annotations:

       [volume.alpha.kubernetes.io/storage-class:](http://volume.alpha.kubernetes.io/storage-class:) anything

   spec:

     accessModes: ["ReadWriteOnce"]

     resources:

       requests:

         storage: 100Gi

我们提供以下 PersistentVolume Claim:

[root@tlx241 /]# kubectl get pvc

NAME                     STATUS    VOLUME        CAPACITY   ACCESSMODES   AGE

pv-claim-test-petset-0   Bound     pv-datera-0   0                        41m

pv-claim-test-petset-1   Bound     pv-datera-1   0                        41m

pv-claim-test-petset-2   Bound     pv-datera-2   0                        5s

pv-claim-test-petset-3   Bound     pv-datera-3   0                        2s

配置 PetSet 时,将实例化两个 Pod:

[root@tlx241 /]# kubectl get pods

NAMESPACE     NAME                        READY     STATUS    RESTARTS   AGE

default       test-petset-0               1/1       Running   0          7s

default       test-petset-1               1/1       Running   0          3s

以下是一个 PetSet:test-petset 实例化之前的样子:

[root@tlx241 /]# kubectl describe petset test-petset

Name: test-petset

Namespace: default

Image(s): [gcr.io/google\_containers/nginx-slim:0.8](http://gcr.io/google_containers/nginx-slim:0.8)

Selector: app=nginx

Labels: app=nginx

Replicas: 2 current / 2 desired

Annotations: \<none\>

CreationTimestamp: Sun, 14 Aug 2016 19:46:30 -0700

Pods Status: 2 Running / 0 Waiting / 0 Succeeded / 0 Failed

No volumes.

No events.

一旦实例化 PetSet(例如下面的 test-petset),随着副本数(从 PetSet 的初始 Pod 数量算起)的增加,实例化的 Pod 将变得更多,并且更多的 PersistentVolume Claim 会绑定到新的 Pod 上:

[root@tlx241 /]# kubectl patch petset test-petset -p'{"spec":{"replicas":"3"}}'

"test-petset” patched


[root@tlx241 /]# kubectl describe petset test-petset

Name: test-petset

Namespace: default

Image(s): [gcr.io/google\_containers/nginx-slim:0.8](http://gcr.io/google_containers/nginx-slim:0.8)

Selector: app=nginx

Labels: app=nginx

Replicas: 3 current / 3 desired

Annotations: \<none\>

CreationTimestamp: Sun, 14 Aug 2016 19:46:30 -0700

Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed

No volumes.

No events.


[root@tlx241 /]# kubectl get pods

NAME                        READY     STATUS    RESTARTS   AGE

test-petset-0               1/1       Running   0          29m

test-petset-1               1/1       Running   0          28m

test-petset-2               1/1       Running   0          9s

现在,应用修补程序后,PetSet 正在运行3个 Pod。

当上述 PetSet 定义修补完成,会产生另一个副本,PetSet 将在系统中引入另一个 pod。反之,这会导致在 Datera Data Fabric 上配置更多的卷。因此,在 PetSet 进行扩展时,要配置动态卷并将其附加到 Pod 上。

为了平衡持久性和一致性的概念,如果 Pod 从一个 Minion 转移到另一个,卷确实会附加(安装)到新的 minion node 上,并与旧的 Minion 分离(卸载),从而实现对数据的持久访问。

结论

本文展示了具备 Pet Sets 的 Kubernetes 协调有状态和无状态工作负载。当 Kubernetes 社区致力于扩展 FlexVolume 框架的功能时,我们很高兴这个解决方案使 Kubernetes 能够在数据中心广泛运行。

加入我们并作出贡献:Kubernetes Storage SIG.

SIG Apps: 为 Kubernetes 构建应用并在 Kubernetes 中进行运维

编者注:这篇文章由 Kubernetes SIG-Apps 团队撰写,分享他们如何关注在 Kubernetes 中运行应用的开发者和 devops 经验。

Kubernetes 是容器化应用程序的出色管理者。因此,众多 公司 已经 开始 在 Kubernetes 中运行应用程序。

Kubernetes 特殊兴趣小组 (SIGs) 自 1.0 版本开始就一直致力于支持开发者和运营商社区。围绕网络、存储、扩展和其他运营领域组织的人员。

随着 Kubernetes 的兴起,对工具、最佳实践以及围绕构建和运营云原生应用程序的讨论的需求也随之增加。为了满足这一需求, Kubernetes SIG Apps 应运而生。

SIG Apps 为公司和个人提供以下支持:

  • 查看和分享正在构建的、为应用操作人员赋能的工具的演示
  • 了解和讨论应用运营人员的需求
  • 组织各方努力改善体验

自从 SIG Apps 成立以来,我们已经进行了项目演示,例如 KubeFuseKPM,和 StackSmith。 我们还对那些负责 Kubernetes 中应用运维的人进行了调查。

从调查结果中,我们学到了很多东西,包括:

  • 81% 的受访者希望采用某种形式的自动扩缩
  • 为了存储秘密信息,47% 的受访者使用内置 Secret。目前这些资料并未实现静态加密。 (如果你需要关于加密的帮助,请参见问题。)
  • 响应最多的问题与第三方工具和调试有关
  • 对于管理应用程序的第三方工具,没有明确的赢家。有各种各样的做法
  • 总体上对缺乏有用文件有较多抱怨。(请在此处帮助提交文档。)
  • 数据量很大。很多回答是可选的,所以我们很惊讶所有候选人的所有问题中有 935 个都被填写了。 如果你想亲自查看数据,可以在线查看。

就应用运维而言,仍然有很多东西需要解决和共享。如果你对运行应用程序有看法或者有改善体验的工具, 或者只是想潜伏并了解状况,请加入我们。

--Matt Farina ,Hewlett Packard Enterprise 首席工程师

Kubernetes 生日快乐。哦,这是你要去的地方!

编者按,今天的嘉宾帖子来自一位独立的 kubernetes 撰稿人 Justin Santa Barbara,分享了他对项目从一开始到未来发展的思考。

亲爱的 K8s,

很难相信你是唯一的一个 - 成长这么快的。在你一岁生日的时候,我想我可以写一个小纸条,告诉你为什么我在你出生的时候那么兴奋,为什么我觉得很幸运能成为抚养你长大的一员,为什么我渴望看到你继续成长!

--Justin

你从一个优秀的基础 - 良好的声明性功能开始,它是围绕一个具有良好定义的模式和机制的坚实的 API 构建的,这样我们就可以向前发展了。果然,在你的第一年里,你增长得如此之快:autoscaling、HTTP load-balancing support (Ingress)、support for persistent workloads including clustered databases (PetSets)。你已经和更多的云交了朋友(欢迎 azure 和 openstack 加入家庭),甚至开始跨越区域和集群(Federation)。这些只是一些最明显的变化 - 在你的大脑里发生了太多的变化!

我觉得你一直保持开放的态度真是太好了 - 你好像把所有的东西都写在 github 上 - 不管是好是坏。我想我们在这方面都学到了很多,比如让工程师做缩放声明的风险,然后在没有完全相同的精确性和严谨性框架的情况下,将这些声明与索赔进行权衡。但我很自豪你选择了不降低你的标准,而是上升到挑战,只是跑得更快 - 这可能不是最现实的办法,但这是唯一的方式能移动山!

然而,不知何故,你已经设法避免了许多其他开源软件陷入的共同死胡同,特别是当那些项目越来越大,开发人员最终要做的比直接使用它更多的时候。你是怎么做到的?有一个很可能是虚构的故事,讲的是 IBM 的一名员工犯了一个巨大的错误,被传唤去见大老板,希望被解雇,却被告知“我们刚刚花了几百万美元培训你。我们为什么要解雇你?“。尽管谷歌对你进行了大量的投资(包括 redhat 和其他公司),但我有时想知道,我们正在避免的错误是否更有价值。有一个非常开放的开发过程,但也有一个“oracle”,它有时会通过告诉我们两年后如果我们做一个特定的设计决策会发生什么来纠正错误。这是你应该听的父母!

所以,尽管你只有一岁,你真的有一个旧灵魂。我只是很多人抚养你中的一员,但对我来说,能够与那些建立了这些令人难以置信的系统并拥有所有这些领域知识的人一起工作是一次极好的学习经历。然而,因为我们是白手起家(而不是采用现有的 Borg 代码),我们处于同一水平,仍然可以就如何培养你进行真正的讨论。好吧,至少和我们的水平一样接近,但值得称赞的是,他们都太好了,从来没提过!

如果我选择两个聪明人做出的明智决定:

  • 标签和选择器给我们声明性的“pointers”,所以我们可以说“为什么”我们想要东西,而不是直接列出东西。这是如何扩展到[伟大高度]的秘密(https://kubernetes.io/blog/2016/07/thousand-instances-of-cassandra-using-kubernetes-pet-set);不是命名每一步,而是说“像第一步一样多走一千步”。
  • 控制器是状态同步器:我们指定目标,您的控制器将不遗余力地工作,使系统达到该状态。它们工作在强类型 API 基础上,并且贯穿整个代码,因此 Kubernetes 比一个大的程序多一百个小程序。仅仅从技术上扩展到数千个节点是不够的;这个项目还必须扩展到数千个开发人员和特性;控制器帮助我们达到目的。

等等我们就走!我们将取代那些控制器,建立更多,API 基金会让我们构建任何我们可以用这种方式表达的东西 - 大多数东西只是标签或注释远离!但你的思想不会由语言来定义:有了第三方资源,你可以表达任何你选择的东西。现在我们可以不用在 Kubernetes 建造Kubernetes 了,创造出与其他任何东西一样感觉是 Kubernetes 的一部分的东西。最近添加的许多功能,如ingress、DNS integration、autoscaling and network policies ,都已经完成或可以通过这种方式完成。最终,在这些事情发生之前很难想象你会是怎样的一个人,但是明天的标准功能可以从今天开始,没有任何障碍或看门人,甚至对一个听众来说也是这样。

所以我期待着看到越来越多的增长发生在离 Kubernetes 核心越来越远的地方。我们必须通过这些阶段来工作;从需要在 kubernetes 内核中发生的事情开始——比如用部署替换复制控制器。现在我们开始构建不需要核心更改的东西。但我们仍然在讨论基础设施和应用程序。接下来真正有趣的是:当我们开始构建依赖于 kubernetes api 的应用程序时。我们一直有使用 kubernetes api 进行自组装的 cassandra 示例,但我们还没有真正开始更广泛地探讨这个问题。正如 S3 APIs 改变了我们构建记忆事物的方式一样,我认为 k8s APIs 也将改变我们构建思考事物的方式。

所以我很期待你的二岁生日:我可以试着预测你那时的样子,但我知道你会超越我所能想象的最大胆的东西。哦,这是你要去的地方!

-- Justin Santa Barbara, 独立的 Kubernetes 贡献者

将端到端的 Kubernetes 测试引入 Azure (第二部分)

作者标注:今天的邀请帖子是 Travis Newhouse 的 系列 中的第二部分,他是 AppFormix 的首席架构师,这篇文章介绍了他们对 Kubernetes 的贡献。

历史上,Kubernetes 测试一直由谷歌托管,在 谷歌计算引擎 (GCE) 和 谷歌容器引擎 (GKE) 上运行端到端测试。实际上,提交队列的选通检查是在这些测试平台上执行测试的子集。联合测试旨在通过使组织托管各种平台的测试作业并贡献测试结果,从而让 Kubernetes 项目受益来扩大测试范围。谷歌和 SIG-Testing 的 Kubernetes 测试小组成员已经创建了一个 Kubernetes 测试历史记录仪表板,可以发布所有联合测试作业(包括谷歌托管的作业)的全部结果。

在此博客文章中,我们介绍了扩展 Azure 的端到端测试工作,并展示了如何为 Kubernetes 项目贡献联合测试。

Azure 的端到端集成测试

成功实现 在 Azure 上自动部署 Kubernetes 的 “development distro” 脚本 之后,我们的下一个目标是运行端到端集成测试,并与 Kubernetes 社区共享结果。

通过在私有 Jenkins 服务器中定义夜间工作,我们自动化了在 Azure 上执行 Kubernetes 端到端测试的工作流程。图2显示了使用 kube-up.sh 在运行于 Azure 的 Ubuntu 虚拟机上部署 Kubernetes,然后执行端到端测试的工作流程。测试完成后,该作业将测试结果和日志上传到 Google Cloud Storage 目录中,其格式可以由 生成测试历史记录仪表板的脚本 进行处理。我们的 Jenkins 作业使用 hack/jenkins/e2e-runner.sh 和 hack/jenkins/upload-to-gcs.sh 脚本生成正确格式的结果。

| Kubernetes on Azure - Flow Chart - New Page.png | | 图 2 - 夜间测试工作流程 |

如何进行端到端测试

在创建 Azure 端到端测试工作的整个过程中,我们与 SIG-Testing 的成员进行了合作,找到了一种将结果发布到 Kubernetes 社区的方法。合作的结果是以文档和简化的流程从联合测试工作中贡献结果。贡献端到端测试结果的过程可以归纳为4个步骤。

  1. 创建一个 Google Cloud Storage 空间用来发布结果。
  2. 定义一个自动化作业来运行端到端测试,通过设置一些环境变量,使用 hack/jenkins/e2e-runner.sh 部署 Kubernetes 二进制文件并执行测试。
  3. 使用 hack/jenkins/upload-to-gcs.sh 上传结果。
  4. 通过提交对 kubernetes/test-infra 中的几个文件进行修改的请求,将结果合并到测试历史记录仪表板中。

联合测试文档更详细地描述了这些步骤。运行端到端测试并上传结果的脚本简化了贡献新联合测试作业的工作量。设置自动化测试作业的具体步骤以及在其中部署 Kubernetes 的合适环境将留给读者进行选择。对于使用 Jenkins 的组织,用于 GCE 和 GKE 测试的 jenkins-job-builder 配置可能会提供有用的示例。

回顾

Azure 上的端到端测试已经运行了几周。在此期间,我们在 Kubernetes 中发现了两个问题。Weixu Zhuang 立即发布了修补程序并已合并到 Kubernetes master 分支中。

当我们想用 Ubuntu VM 在 Azure 上用 SaltStack 打开 Kubernetes 集群时,发生了第一个问题。一个提交 (07d7cfd3) 修改了 OpenVPN 证书生成脚本,使用了一个仅由集群或者ubuntu中的脚本初始化的变量。证书生成脚本对参数是否存在进行严格检查会导致其他使用该脚本的平台失败(例如,为支持 Azure 而进行的更改)。我们提交了一个解决问题的请求 ,通过使用默认值初始化变量让证书生成脚本在所有平台类型上都更加健壮,。

第二个 清理未使用导入的请求 在 Daemonset 单元测试文件中。import 语句打破了 golang 1.4 的单元测试。我们的夜间 Jenkins 工作帮助我们找到错误并且迅速完成修复。

结论与未来工作

在 Azure 上为 Kubernetes 添加了夜间端到端测试工作,这有助于定义为 Kubernetes 项目贡献联合测试的过程。在工作过程中,当 Azure 测试工作发现兼容性问题时,我们还发现了将测试覆盖范围扩展到更多平台的直接好处。

我们要感谢 Aaron Crickenberger, Erick Fejta, Joe Finney 和 Ryan Hutchinson 的帮助,将我们的 Azure 端到端测试结果纳入了 Kubernetes 测试历史。如果您想参与测试来创建稳定的、高质量的 Kubernetes 版本,请加入我们的 Kubernetes Testing SIG (sig-testing)

--Travis Newhouse, AppFormix 首席架构师

Dashboard - Kubernetes 的全功能 Web 界面

编者按:这篇文章是一系列深入的文章 中关于Kubernetes 1.3的新内容的一部分 Kubernetes Dashboard是一个旨在为 Kubernetes 世界带来通用监控和操作 Web 界面的项目。三个月前,我们发布第一个面向生产的版本,从那时起 dashboard 已经做了大量的改进。在一个 UI 中,您可以在不离开浏览器的情况下,与 Kubernetes 集群执行大多数可能的交互。这篇博客文章分解了最新版本中引入的新功能,并概述了未来的路线图。

全功能的 Dashboard

由于社区和项目成员的大量贡献,我们能够为Kubernetes 1.3发行版提供许多新功能。我们一直在认真听取用户的反馈(参见摘要信息图表),并解决了最高优先级的请求和难点。 -->

Dashboard UI 现在处理所有工作负载资源。这意味着无论您运行什么工作负载类型,它都在 web 界面中可见,并且您可以对其进行操作更改。例如,可以使用Pet Sets修改有状态的 mysql 安装,使用部署对 web 服务器进行滚动更新,或使用守护程序安装集群监视。

除了查看资源外,还可以创建、编辑、更新和删除资源。这个特性支持许多用例。例如,您可以杀死一个失败的 pod,对部署进行滚动更新,或者只组织资源。您还可以导出和导入云应用程序的 yaml 配置文件,并将它们存储在版本控制系统中。

这个版本包括一个用于管理和操作用例的集群节点的 beta 视图。UI 列出集群中的所有节点,以便进行总体分析和快速筛选有问题的节点。details 视图显示有关该节点的所有信息以及指向在其上运行的 pod 的链接。

我们随发行版提供的还有许多小范围的新功能,即:支持命名空间资源、国际化、性能改进和许多错误修复(请参阅发行说明中的更多内容)。所有这些改进都会带来更好、更简单的产品用户体验。

Future Work

该团队对跨越多个用例的未来有着雄心勃勃的计划。我们还对所有功能请求开放,您可以在我们的问题跟踪程序上发布这些请求。

以下是我们接下来几个月的重点领域:

  • Handle more Kubernetes resources - 显示集群用户可能与之交互的所有资源。一旦完成,dashboard 就可以完全替代cli。
  • Monitoring and troubleshooting - 将资源使用统计信息/图表添加到 Dashboard 中显示的对象。这个重点领域将允许对云应用程序进行可操作的调试和故障排除。
  • Security, auth and logging in - 使仪表板可从集群外部的网络访问,并使用自定义身份验证系统。

联系我们

我们很乐意与您交谈并听取您的反馈!

Citrix + Kubernetes = 全垒打

编者按:今天的客座文章来自 Citrix Systems 的产品管理总监 Mikko Disini,他分享了他们在 Kubernetes 集成上的合作经验。 _

技术合作就像体育运动。如果你能像一个团队一样合作,你就能在最后关头取得胜利。这就是我们对谷歌云平台团队的经验。

最近,我们与 Google 云平台(GCP)联系,代表 Citrix 客户以及更广泛的企业市场,希望就工作负载的迁移进行协作。此迁移需要将 [NetScaler Docker 负载均衡器]https://www.citrix.com/blogs/2016/06/20/the-best-docker-load-balancer-at-dockercon-in-seattle-this-week/) CPX 包含到 Kubernetes 节点中,并解决将流量引入 CPX 代理的任何问题。

为什么是 NetScaler 和 Kubernetes

  1. Citrix 的客户希望他们开始使用 Kubernetes 部署他们的容器和微服务体系结构时,能够像当初迁移到云计算时一样,享有 NetScaler 所提供的第 4 层到第 7 层能力 
  2. Kubernetes 提供了一套经过验证的基础设施,可用来运行容器和虚拟机,并自动交付工作负载;
  3. NetScaler CPX 提供第 4 层到第 7 层的服务,并为日志和分析平台 NetScaler 管理和分析系统 提供高效的度量数据。

我希望我们所有与技术合作伙伴一起工作的经验都能像与 GCP 一起工作一样好。我们有一个列表,包含支持我们的用例所需要解决的问题。我们能够快速协作形成解决方案。为了解决这些问题,GCP 团队提供了深入的技术支持,与 Citrix 合作,从而使得 NetScaler CPX 能够在每台主机上作为客户端代理启动运行。

接下来,需要在 GCP 入口负载均衡器的数据路径中插入 NetScaler CPX,使 NetScaler CPX 能够将流量分散到前端 web 服务器。NetScaler 团队进行了修改,以便 NetScaler CPX 监听 API 服务器事件,并配置自己来创建 VIP、IP 表规则和服务器规则,以便跨前端应用程序接收流量和负载均衡。谷歌云平台团队提供反馈和帮助,验证为克服技术障碍所做的修改。完成了!

NetScaler CPX 用例在 Kubernetes 1.3 中提供支持。Citrix 的客户和更广泛的企业市场将有机会基于 Kubernetes 享用 NetScaler 服务,从而降低将工作负载转移到云平台的阻力。 

您可以在此处了解有关 NetScaler CPX 的更多信息。

_ -- Mikko Disini,Citrix Systems NetScaler 产品管理总监

容器中运行有状态的应用!? Kubernetes 1.3 说 “是!”

编者注: 今天的来宾帖子来自 Diamanti 产品副总裁 Mark Balch,他将分享有关他们对 Kubernetes 所做的贡献的更多信息。

祝贺 Kubernetes 社区发布了另一个有价值的版本。 专注于有状态应用程序和联邦集群是我对 1.3 如此兴奋的两个原因。 Kubernetes 对有状态应用程序(例如 Cassandra、Kafka 和 MongoDB)的支持至关重要。 重要服务依赖于数据库、键值存储、消息队列等。 此外,随着应用程序的发展为全球数百万用户提供服务,仅依靠一个数据中心或容器集群将无法正常工作。 联邦集群允许用户跨多个集群和数据中心部署应用程序,以实现规模和弹性。

您可能之前听过我说过,容器是下一个出色的应用程序平台。 Diamanti 正在加速在生产中使用有状态应用程序的容器-在这方面,性能和易于部署非常重要。

应用程序不仅仅需要牛

除了诸如Web服务器之类的无状态容器(因为它们是可互换的,因此被称为“牛”)之外,用户越来越多地使用容器来部署有状态工作负载,以从“一次构建,随处运行”中受益并提高裸机效率/利用率。 这些“宠物”(之所以称为“宠物”,是因为每个宠物都需要特殊的处理)带来了新的要求,包括更长的生命周期,配置依赖项,有状态故障转移以及性能敏感性。 容器编排必须满足这些需求,才能成功部署和扩展应用程序。

输入 Pet Set,这是 Kubernetes 1.3 中的新对象,用于改进对状态应用程序的支持。 Pet Set 在每个数据库副本的启动阶段进行排序(例如),以确保有序的主/从配置。 Pet Set 还利用普遍存在的 DNS SRV 记录简化了服务发现,DNS SRV 记录是一种广为人知且长期了解的机制。

Diamanti 对 Kubernetes 的 FlexVolume 贡献 通过为持久卷提供低延迟存储并保证性能来实现有状态工作负载,包括从容器到媒体的强制服务质量。

联邦主义者

为应用可用性作规划的用户必须应对故障迁移问题并在整个地理区域内扩展。 跨集群联邦服务允许容器化的应用程序轻松跨多个集群进行部署。 联邦服务解决了诸如管理多个容器集群以及协调跨联邦集群的服务部署和发现之类的挑战。

像严格的集中式模型一样,联邦身份验证提供了通用的应用程序部署界面。 但是,由于每个集群都具有自治权,因此联邦会增加了在网络中断和其他事件期间在本地管理集群的灵活性。 跨集群联邦服务还可以提供跨容器集群应用一致的服务命名和采用,简化 DNS 解析。

很容易想象在将来的版本中具有跨集群联邦服务的强大多集群用例。 一个示例是根据治理,安全性和性能要求调度容器。 Diamanti 的调度程序扩展是在考虑了这一概念的基础上开发的。 我们的第一个实现使 Kubernetes 调度程序意识到每个集群节点本地的网络和存储资源。 将来,类似的概念可以应用于跨集群联邦服务的更广泛的放置控件。

参与其中

随着对有状态应用的兴趣日益浓厚,人们已经开始进一步增强 Kubernetes 存储的工作。 存储特别兴趣小组正在讨论支持本地存储资源的提案。 Diamanti 期待将 FlexVolume 扩展到包括更丰富的 API,这些 API 可以启用本地存储和存储服务,包括数据保护,复制和缩减。 我们还正在研究有关通过 Kubernetes 跨集群联邦服务改善应用程序放置,迁移和跨容器集群故障转移的建议。

加入对话并做出贡献! 这里是一些入门的地方:

-- Diamanti 产品副总裁 Mark Balch。 Twitter @markbalch

CoreOS Fest 2016: CoreOS 和 Kubernetes 在柏林(和旧金山)社区见面会

CoreOS Fest 2016 将汇集容器和开源分布式系统社区,其中包括 Kubernetes 领域的许多思想领袖。 这是第二次年度 CoreOS 社区会议,于5月9日至10日在柏林首次举行。 CoreOS 相信 Kubernetes 是提供 GIFEE(适用于所有人的 Google 的基础架构)服务的合适的容器编排组件。

在今年的 CoreOS Fest 上,有专门针对 Kubernetes 的报道,您将听到有关 Kubernetes 性能和可伸缩性,持续交付以及 Kubernetes,rktnetes,stackanetes 等各种主题的信息。 此外,这里将有各种各样的讲座,涵盖从入门讲习班到深入探讨容器和相关软件的方方面面。

不要错过柏林会议上的精彩演讲:

如果您无法到达柏林,Kubernetes 还是** CoreOS Fest 旧金山 ** 卫星事件 的焦点,这是一个专门针对 CoreOS 和 Kubernetes 的一日活动。 实际上, Google 的高级工程师, Kubernetes 的创建者之一 Tim Hockin 将以专门介绍 Kubernetes 更新的主题演讲拉开序幕。

专门针对 Kubernetes 的旧金山会议包括:

  • Tim Hockin的主题演讲,Google 高级工程师
  • 当 rkt 与 Kubernetes 相遇时:Sysdig 首席执行官 Loris Degioanni 的故障排除故事
  • rktnetes: CoreOS的软件工程师Derek Gonyeo提供了容器运行时和 Kubernetes 的新功能
  • 神奇的安全性蔓延:CoreOS 和 Kubernetes 上的安全,弹性微服务,浮力技术总监 Oliver Gould

** SF 的 Kubernetes 研讨会**:Kubernetes 入门, Google 开发人员计划工程师 Carter Morgan 和 Bill Prin 于5月10日(星期二)上午9:00至1:00 pm在 Google 旧金山办公室(Spear 街345号第7层)举办会议,之后将提供午餐。 席位有限,请 此处免费提供 RSVP

获取门票 :

要了解更多信息,请访问: coreos.com/fest/  和 Twitter @CoreOSFest #CoreOSFest

-- Sarah Novotny, Kubernetes 社区管理者

SIG-ClusterOps: 提升 Kubernetes 集群的可操作性和互操作性

编者注: 本周我们将推出 Kubernetes 特殊兴趣小组;今天的帖子由 SIG-ClusterOps 团队负责,其任务是促进 Kubernetes 集群的可操作性和互操作性 -- 倾听,帮助和升级。

我们认为 Kubernetes 是大规模运行应用程序的绝佳方法! 不幸的是,存在一个引导问题:我们需要良好的方法来围绕 Kubernetes 构建安全可靠的扩展环境。 虽然平台管理的某些部分利用了平台(很酷!),这有一些基本的操作主题需要解决,还有一些问题(例如升级和一致性)需要回答。

输入 Cluster Ops SIG – 在平台下工作以保持其运行的社区成员。

我们对 Cluster Ops 的目标是首先成为一个人对人的社区,其次才是意见、文档、测试和脚本的来源。 这意味着我们将花费大量时间和精力来简单地比较有关工作内容的注释并讨论实际操作。 这些互动为我们提供了形成意见的数据。 这也意味着我们可以利用实际经验来为项目提供信息。

我们旨在成为对该项目进行运营审查和反馈的论坛。 为了使 Kubernetes 取得成功,运营商需要通过每周参与并收集调查数据在项目中拥有重要的声音。 我们并不是想对操作发表意见,但我们确实想创建一个协调的资源来收集项目的运营反馈。 作为一个公认的团体,操作员更容易获得影响力。

现实世界中的可交付成果如何?

我们也有切实成果的计划。 我们已经在努力实现具体的交付成果,例如参考架构,工具目录,社区部署说明和一致性测试。 Cluster Ops 希望成为运营资源的交换所。 我们将根据实际经验和经过战斗测试的部署来进行此操作。

联系我们。

集群运营可能会很辛苦–别一个人做。 我们在这里倾听,在我们可以帮助的时候提供帮助,而在我们不能帮助的时候向上一级反映。 在以下位置加入对话:

SIG Cluster Ops 每周四在太平洋标准时间下午 13:00 开会,您可以通过 视频环聊 加入我们并查看最新的 会议记录 了解所涉及的议程和主题。

-- RackN 首席执行官 Rob Hirschfeld

“SIG-Networking:1.3 版本引入 Kubernetes 网络策略 API”

编者注:本周我们将推出 Kubernetes 特殊兴趣小组、 Network-SIG 小组今天的帖子描述了 1.3 版中的网络策略 API-安全,隔离和多租户策略。

自去年下半年以来,Kubernetes SIG-Networking 一直在定期开会,致力于将网络策略引入 Kubernetes,我们开始看到这个努力的结果。

许多用户面临的一个问题是,Kubernetes 的开放访问网络策略不适用于需要对访问容器或服务的流量进行更精确控制的应用程序。 如今,这种应用可能是多层应用,其中仅允许来自某个相邻层的流量。 但是,随着新的云原生应用不断通过组合微服务构建出来,对服务间流动的数据进行控制的能力变得更加重要。

在大多数 IaaS 环境(公共和私有)中,通过允许 VM 加入“安全组(Security Group)”来提供这种控制, 其中“安全组”成员的流量由网络策略或访问控制列表( ACL )定义,并由网络数据包过滤器实施。

SIG-Networking 开始这项工作时的第一步是辩识需要特定网络隔离以增强安全性的 特定用例场景。 确保所定义的 API 适用于这些简单和常见的用例非常重要,因为它们为在 Kubernetes 内 实现更复杂的网络策略以支持多租户奠定了基础。

基于这些场景,团队考虑了几种可能的方法,并定义了一个最小的 策略规范 。 基本思想是,如果按命名空间启用了隔离,则特定流量类型被允许时会选择特定的 Pod。

快速支持此实验性 API 的最简单方法是对 API 服务器的 ThirdPartyResource 扩展,今天在 Kubernetes 1.2 中就可以实现。

如果您不熟悉它的工作方式,则可以通过定义 ThirdPartyResources 来扩展 Kubernetes API ,ThirdPartyResources 在指定的 URL 上创建一个新的 API 端点。

third-party-res-def.yaml

kind: ThirdPartyResource
apiVersion: extensions/v1beta1
metadata:
name: network-policy.net.alpha.kubernetes.io
description: "Network policy specification"
versions:
- name: v1alpha1
$kubectl create -f third-party-res-def.yaml

这将创建一个 API 端点(每个名称空间一个):

/net.alpha.kubernetes.io/v1alpha1/namespace/default/networkpolicys/

第三方网络控制器现在可以在这些端点上进行侦听,并在创建,修改或删除资源时根据需要做出反应。 注意:在即将发布的 Kubernetes 1.3 版本中-当网络政策 API 以 beta 形式发布时-无需创建如上所示的 ThirdPartyResource API 端点。

默认情况下,网络隔离处于关闭状态,以便所有Pod都能正常通信。 但是,重要的是要知道,启用网络隔离后,所有命名空间中所有容器的所有流量都会被阻止,这意味着启用隔离将改变容器的行为

通过在名称空间上定义 network-isolation 注解来启用网络隔离,如下所示:

net.alpha.kubernetes.io/network-isolation: [on | off]

启用网络隔离后,必须应用显式网络策略才能启用 Pod 通信。

可以将策略规范应用于命名空间,以定义策略的详细信息,如下所示:

POST /apis/net.alpha.kubernetes.io/v1alpha1/namespaces/tenant-a/networkpolicys/

{
"kind": "NetworkPolicy",
"metadata": {
"name": "pol1"
},
"spec": {
"allowIncoming": {
"from": [
{ "pods": { "segment": "frontend" } }
],
"toPorts": [
{ "port": 80, "protocol": "TCP" }
]
},
"podSelector": { "segment": "backend" }
}
}

在此示例中,‘ tenant-a ’名称空间将按照指示应用策略‘ pol1 ’。 具体而言,带有segment标签 ‘ 后端 ’ 的容器将允许接收来自带有“segment**标签‘ frontend ’的容器的端口80上的TCP流量。

现今,Romana, OpenShift, OpenContrailCalico 支持应用于名称空间和容器的网络策略。 思科和 VMware 也在努力实施。 Romana 和 Calico 最近都在 KubeCon 上使用 Kubernetes 1.2 演示了这些功能。 你可以在此处观看他们的演讲:Romana (slides), Calico (slides)。 

它是如何工作的?

每个解决方案都有其自己的特定实现细节。 今天,他们依靠某种形式的主机执行机制,但是将来的实现也可以构建为在虚拟机管理程序上,甚至直接由网络本身应用策略构建。 

外部策略控制软件(具体情况因实现而异)将监视新 API 终结点是否正在创建容器和/或正在应用新策略。 当发生需要配置策略的事件时,侦听器将识别出更改,并且控制器将通过配置接口并应用策略来做出响应。  下图显示了 API 侦听器和策略控制器,它通过主机代理在本地应用网络策略来响应更新。 主机上的网络接口由主机上的 CNI 插件配置(未显示)。

controller.jpg

如果您由于网络隔离和/或安全性问题而一直拒绝使用 Kubernetes 开发应用程序,那么这些新的网络策略将为您提供所需的控制功能大有帮助。 无需等到 Kubernetes 1.3,因为网络策略现在作为实验性 API 可用,已启用 ThirdPartyResource。

如果您对 Kubernetes 和网络感兴趣,有几种参与方式-请通过以下方式加入我们:

网络“特殊兴趣小组”,每两周一次,在太平洋时间下午 3 点(15:00)在SIG-Networking 环聊开会。 

--Pani Networks 联合创始人 Chris Marino

在 Rancher 中添加对 Kuernetes 的支持

今天的来宾帖子由 Rancher Labs(用于管理容器的开源软件平台)的首席架构师 Darren Shepherd 撰写。

在过去的一年中,我们看到希望在其软件开发和IT组织中利用容器的公司数量激增。 为了实现这一目标,组织一直在研究如何构建集中式的容器管理功能,该功能将使用户可以轻松访问容器,同时集中管理IT组织的可见性和控制力。 2014年,我们启动了开源 Rancher 项目,通过构建容器管理平台来解决此问题。

最近,我们发布了 Rancher v1.0。 在此最新版本中,用于管理容器的开源软件平台 Rancher 现在在创建环境时支持 Kubernetes 作为容器编排框架。 现在,使用 Rancher 启动 Kubernetes 环境是完全自动化的,只需 5 至 10 分钟即可交付运行正常的集群。

我们创建 Rancher 的目的是为组织提供完整的容器管理平台。 作为其中的一部分,我们始终支持使用 Docker API 和 Docker Compose 在本地部署 Docker 环境。 自成立以来, Kubernetes 的运营成熟度给我们留下了深刻的印象,而在此版本中,我们使得其可以在同一管理平台上部署各种容器编排和调度框架。

添加 Kubernetes 使用户可以访问增长最快的平台之一,用于在生产中部署和管理容器。 我们将在 Rancher 中提供一流的 Kubernetes 支持,并将继续支持本机 Docker 部署。

将 Kubernetes 带到 Rancher

Kubernetes deployment-3.PNG

我们的平台已经可以扩展为各种不同的包装格式,因此我们对拥抱 Kubernetes 感到乐观。 没错,作为开发人员,与 Kubernetes 项目一起工作是一次很棒的经历。 该项目的设计使这一操作变得异常简单,并且我们能够利用插件和扩展来构建 Kubernetes 发行版,从而利用我们的基础架构和应用程序服务。 例如,我们能够将 Rancher 的软件定义的网络,存储管理,负载平衡,DNS 和基础结构管理功能直接插入 Kubernetes,而无需更改代码库。

更好的是,我们已经能够围绕 Kubernetes 核心功能添加许多服务。 例如,我们在 Kubernetes 上实现了常用的 应用程序目录 。 过去,我们曾使用 Docker Compose 定义应用程序模板,但是在此版本中,我们现在支持 Kubernetes 服务、副本控制器和和 Pod 来部署应用程序。 使用目录,用户可以连接到 git 仓库并自动部署和升级作为 Kubernetes 服务部署的应用。 然后,用户只需单击一下按钮,即可配置和部署复杂的多节点企业应用程序。 升级也是完全自动化的,并集中向用户推出。

回馈

与 Kubernetes 一样,Rancher 是一个开源软件项目,任何人均可免费使用,并且不受任何限制地分发给社区。 您可以在 GitHub 上找到 Rancher 的所有源代码,即将发布的版本和问题。 我们很高兴加入 Kubernetes 社区,并期待与所有其他贡献者合作。 在Rancher here 中查看有关 Kubernetes 新支持的演示。 

-- Rancher Labs 首席架构师 Darren Shepherd

KubeCon EU 2016:伦敦 Kubernetes 社区

KubeCon EU 2016 是首届欧洲 Kubernetes 社区会议,紧随 2015 年 11 月召开的北美会议。KubeCon 致力于为 Kubernetes 爱好者、产品用户和周围的生态系统提供教育和社区参与。

快来加入我们在伦敦,与 Kubernetes 社区的数百人一起出去,体验各种深入的技术专家讲座和用例。

不要错过这些优质的演讲:

在这里获取您的 KubeCon EU 门票。

会场地址:CodeNode * 英国伦敦南广场 10 号
酒店住宿:酒店
网站:[kubecon.io] (https://www.kubecon.io/)
推特:[@KubeConio] (https://twitter.com/kubeconio) 谷歌是 KubeCon EU 2016 的钻石赞助商。下个月 3 月 10 - 11 号来伦敦,参观 13 号展位,了解 Kubernetes,Google Container Engine(GKE),Google Cloud Platform 的所有信息!

_KubeCon 是由 KubeAcademy、LLC 组织的,这是一个由社区驱动的开发者团体,专注于开发人员的教育和 kubernetes 的推广 -* Sarah Novotny, 谷歌的 Kubernetes 社区经理

Kubernetes 社区会议记录 - 20160218

2月18号 - kmachine 演示、SIG clusterops 成立、新的 k8s.io 网站预览、1.2 版本更新和 1.3 版本计划

Kubernetes 贡献社区会议大多在星期四的 10:00 召开,通过视频会议讨论项目现有情况。这里是最近一次会议的笔记。

  • 记录员: Rob Hirschfeld
  • 示例 (10 min): kmachine [Sebastien Goasguen]
    • 开始 :01 视频介绍
    • 为 Kubernetes 创建 Docker tools 的镜像 (例如 machine,compose 等等)
    • kmachine ( 它是 Docker Machine的一个分叉, 因此两者有相同的 endpoints)
  • 演示案例 (10 min): 开始时间 :15
  • SIG 汇报启动会
    • 周五进行 Cluster Ops 启动会 (doc). [Rob Hirschfeld]
  • 时区讨论 [:22]
    • 当前时区不适合亚洲。
    • 考虑轮转时间 - 每一个月一次
    • 大约 5 或者 6 PT
    • Rob 建议把例会时间上调一些
  • k8s.io 网站 概述 [John Mulhausen] [:27]
    • 使用 github 进行文档操作。你可以通过网站进行 fork 操作并且做一个 pull request 请求
    • Google 将会提供一个 "doc bounty","doc bounty" 是一个让你得到 GCP 积分来为你的文档使用的地方
    • 使用 Jekyll 创建网站 (例如 the ToC)
    • 100% 使用 GitHub 页面原则; 没有脚本或者插件外挂, 仅仅只有 fork/clone,edit,和 push 操作
    • 希望能在 Kubecon EU 启动
    • 主页唯一概述地址: http://kub.unitedcreations.xyz
  • 1.2 版本观看 [T.J. Goltermann] [:38]
  • 1.3 版本更新计划 [T.J. Goltermann]
  • GSoC 分享会 -- 截止日期 2月19号 [Sarah Novotny]
  • 3月10号 会议? [Sarah Novotny]

想要加入 Kubernetes 社区的人,考虑加入 [Slack channel] 3频道, 在 GitHub 上看看Kubernetes project, 或者加入Kubernetes-dev Google group

如果你对此真的充满激情,你可以做完上述所有事情并加入我们的下一次社区对话 - 在2016年2月25日。

请将您自己或您想了解的主题添加到agenda,加入this group组即可获得日历邀请。

"https://youtu.be/L5BgX2VJhlY?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ"

_-- Kubernetes 社区 _

Kubernetes 社区会议记录 - 20160204

2 月 4 日 - rkt 演示(祝贺 1.0 版本,CoreOS!),eBay 将 k8s 放在 Openstack 上并认为 Openstack 在 k8s,SIG 和片状测试激增方面取得了进展。

Kubernetes 贡献社区在每周四 10:00 PT 开会,通过视频会议讨论项目状态。以下是最近一次会议的笔记。

  • 书记员:Rob Hirschfeld
  • 演示视频(20 分钟):CoreOS rkt + Kubernetes [Shaya Potter]
    • 期待在未来几个月内看到与rkt和k8s的整合(“rkt-netes”)。 还没有集成到 v1.2 版本中。
    • Shaya 做了一个演示(8分钟的会议视频参考)
      • rkt 的 CLI 显示了旋转容器
      • [注意:音频在点数上是乱码]
      • 关于 k8s&rkt 整合的讨论
      • 下周 rkt 社区同步: https://groups.google.com/forum/#!topic/rkt-dev/FlwZVIEJGbY
      • Dawn Chen:
        • 将 rkt 与 kubernetes 集成的其余问题:1)cadivsor 2) DNS 3)与日志记录相关的错误
        • 但是需要在 e2e 测试套件上做更多的工作
  • 用例(10分钟):在 OpenStack 上的 eBay k8s 和 k8s 上的 OpenStack [Ashwin Raveendran]
    • eBay 目前正在 OpenStack 上运行 Kubernetes
    • eBay 的目标是管理带有 k8s 的 OpenStack 控制平面。目标是实现升级。
    • OpenStack Kolla 为控制平面创建容器。使用 Ansible+Docker 来管理容器。
    • 致力于 k8s 控制计划管理 - Saltstack 被证明是他们想运营的规模的管理挑战。寻找 k8s 控制平面的自动化管理。
  • SIG 报告
  • 测试更新 [Jeff, Joe, 和 Erick]
    • 努力使有助于 K8s 的工作流程更容易理解
      • pull/19714有 bot 流程图来帮助用户理解
    • 需要一种一致的方法来运行测试 w/hacking 配置脚本(你现在必须伪造一个 Jenkins 进程)
    • 想要创建必要的基础设施,使测试设置不那么薄弱
    • 想要将测试开始(单次或完整)与 Jenkins分离
    • 目标是指出你有一个可以指向任何集群的脚本
    • 演示包括 Google 内部视图 - 努力尝试获取外部视图。
    • 希望能够收集测试运行结果
    • Bob Wise 不赞同在 v1.3 版本进行测试方面的基础设施建设。
    • 关于测试实践的长期讨论…
      • 我们希望在多个平台上进行测试的共识。
      • 为测试报告提供一个全面转储会很有帮助
      • 可以使用"phone-home"收集异常
  • 1.2发布观察
  • CoC [Sarah]
  • GSoC [Sarah]

要参与 Kubernetes 社区,请考虑加入我们的 Slack 频道,查看 GitHub 上的 Kubernetes 项目,或加入 Kubernetes-dev Google 小组。 如果你真的很兴奋,你可以完成上述所有工作并加入我们的下一次社区对话 - 2016 年 2 月 11 日。 请将你自己或你想要了解的主题添加到议程并通过加入此组来获取日历邀请。

"https://youtu.be/IScpP8Cj0hw?list=PL69nYSiGNLP1pkHsbPjzAewvMgGUpkCnJ"

容器世界现状,2016 年 1 月

新年伊始,我们进行了一项调查,以评估容器世界的现状。 我们已经准备好发送 2 月版但在此之前,让我们从 119 条回复中看一下 1 月的数据(感谢您的参与!)。

关于这些数字的注释: 首先,您可能会注意到,这些数字加起来并不是 100%,在大多数情况下,选择不是唯一的,因此给出的百分比是选择特定选择的所有受访者的百分比。 其次,虽然我们尝试覆盖广泛的云社区,但调查最初是通过 Twitter 发送给@brendandburns@kelseyhightower@sarahnovotny@juliaferraioli@thagomizer_rb,因此受众覆盖可能并不完美。 我们正在努力扩大样本数量(我是否提到过2月份的调查?点击立即参加)。

言归正传,来谈谈数据:

首先,很多人正在使用容器!目前有 71% 的人正在使用容器,而其中有 24% 的人正在考虑尽快使用它们。 显然,这表明样本集有些偏颇。 在更广泛的社区中,容器使用的数量有所不同,但绝对低于 71%。 因此,对这些数字的其余部分要持怀疑态度。

那么人们在使用容器做什么呢? 超过 80% 的受访者使用容器进行开发,但只有 50% 的人在生产环境下使用容器。 但是他们有计划很快投入到生产环境之中,78% 的容器用户表示了意愿。

你们在哪里部署容器? 你的笔记本电脑显然是赢家,53% 的人使用笔记本电脑。 接下来是 44% 的人在自己的 VM 上运行(Vagrant?OpenStack?我们将在2月的调查中尝试深入研究),然后是 33% 的人在物理基础架构上运行,而 31% 的人在公共云 VM 上运行。

如何部署容器? 你们当中有 54% 的人使用 Kubernetes,虽然看起来有点受样本集的偏见(请参阅上面的注释),但真是令人惊讶,但有 45% 的人在使用 shell 脚本。 是因为 Kubernetes 存储库中正在运行大量(且很好)的 Bash 脚本吗? 继续下去,我们可以看到真相…… 数据显示,25% 使用 CAPS (Chef/Ansible/Puppet/Salt)系统,约 13% 使用 Docker Swarm、Mesos 或其他系统。

最后,我们让人们自由回答使用容器的挑战。 这儿有一些进行了分组和复制的最有趣的答案:

开发复杂性
  • “孤立的开发环境/工作流程可能是零散的,调试容器时可以轻松访问日志等工具,但有时却不太直观,需要大量知识来掌握整个基础架构堆栈和部署/ 更新 kubernetes,到底层网络等。”
  • “迁移开发者的工作流程。 那些不熟悉容器、卷等的人只是想工作。”
安全
  • “网络安全”
  • “Secrets”
不成熟
  • “缺乏全面的非专有标准(例如,非 Docker),例如 runC / OCI”
  • “仍处于早期阶段,只有很少的工具和许多缺少的功能。”
  • “糟糕的 CI 支持,很多工具仍然处于非常早期的阶段。”
  • "我们以前从未那样做过。"
复杂性
  • “网络支持, 为 kubernetes 在裸机上为每个 Pod 提供 IP”
  • “集群化还是太难了”
  • “设置 Mesos 和 Kubernetes 太复杂了!!”
数据
  • “卷缺乏灵活性(与 VM,物理硬件等相同的问题)”
  • “坚持不懈”
  • “存储”
  • “永久数据”

下载完整的调查结果 链接 (CSV 文件)。

_Up-- Brendan Burns,Google 软件工程师

Kubernetes 社区会议记录 - 20160114

1 月 14 日 - RackN 演示、测试问题和 KubeCon EU CFP。

记录者:Joe Beda

  • 演示:在 Metal,AWS 和其他平台上使用 Digital Rebar 自动化部署,来自 RackN 的 Rob Hirschfeld 和 Greg Althaus。

    • Greg Althaus。首席技术官。Digital Rebar 是产品。裸机置备工具。

    • 检测硬件,启动硬件,配置 RAID、操作系统并部署工作负载。

    • 处理 Kubernetes 的工作负载。

    • 看到始于云,然后又回到裸机的趋势。

    • 新的提供商模型可以在云和裸机上使用预配置系统。

    • UI, REST API, CLI

    • 演示:数据包--裸机即服务

      • 4个正在运行的节点归为一个“部署”

      • 每个节点选择的功能性角色/操作。

      • 分解的 kubernetes 带入可以订购和同步的单元。依赖关系树--诸如在启动 k8s master 之前等待 etcd 启动的事情。

      • 在封面下使用 Ansible。

      • 演示带来了另外5个节点--数据包将构建这些节点

      • 从 ansible 中提取基本参数。诸如网络配置,DNS 设置等内容。

      • 角色层次结构引入了其他组件--使节点成为主节点会带来一系列其他必要的角色。

      • 通过简单的配置文件将所有这些组合到命令行工具中。

    • 转发:扩展到多个云以进行测试部署。还希望在裸机和云之间创建拆分/复制。

    • 问:秘密?
      答:使用 Ansible。构建自己的证书,然后分发它们。想要将它们抽象出来并将其推入上游。

    • 问:您是否支持使用 PXE 引导从真正的裸机启动?
      答:是的--将发现裸机系统并安装操作系统,安装 ssh 密钥,建立网络等。

  • [来自 SIG-scalability]问:转到 golang 1.5 的状态如何?
    答:在 HEAD,我们是1.5,但也会支持1.4。有一些跟稳定性相关的问题,但看起来现在情况稳定了。

    • 还希望使用1.5供应商实验。不再使用 godep。但只有在基线为1.5之前,才能这样做。

    • Sarah:现在我们正在工作的事情之一就是提供做这些事的小奖品。云积分,T恤,扑克筹码,小马。

  • [来自可伸缩性兴趣小组]问:清理基于 jenkins 的提交队列的状态如何?社区可以做些什么来帮助您?
    答:最近几天一直很艰难。每个方面都应该有相关的问题。在这些问题上有一个片状标签

    • 仍在进行联盟测试。现在有更多测试资源。随着新人们的进步,事情有希望进展的更快。这对让很多人在他们的环境中进行端到端测试非常有用。

    • Erick Fjeta 是新的测试负责人

    • Brendan很乐意帮助分享有关 Jenkins 设置的详细信息,但这不是必须的。

    • 联盟可以使用 Jenkins API,但不需要 Jenkins 本身。

    • Joe 嘲笑以 Jenkins 的方式运行 e2e 测试是一件棘手的事实。布伦丹说,它应该易于运行。乔再看一眼。

    • 符合性测试? etune 做到了,但他不在。 -重新访问20150121

  • * 3月10日至11日在伦敦举行。地点将于本周宣布。
    
    • 请发送讲话!CFP 截止日期为2月5日。

    • 令人兴奋。看起来是700-800人。比SF版本大(560 人)。

    • 提前购买门票--早起的鸟儿价格将很快结束,价格将上涨到100英镑。

    • 为演讲者提供住宿吗?

    • 三星 Bob 的提问:我们可以针对以下问题获得更多警告/计划吗:

      • 答:Sarah -- 我不太早就听说过这些东西,但会尝试整理一下清单。努力使 kubernetes.io 上的事件页面更易于使用。

      • 答:JJ -- 我们将确保我们早日为下届美国会议提供更多信息。

  • 规模测试[RackN 的 Rob Hirschfeld] -- 如果您想帮助进行规模测试,我们将非常乐意为您提供帮助。

    • Bob 邀请 Rob 加入规模特别兴趣小组。

    • 还有一个大型的裸机集群,通过 CNCF(来自 Intel)也很有用。尚无确切日期。

  • 笔记/视频将发布在 k8s 博客上。(未录制20150114的视频。失败。)

要加入 Kubernetes 社区,请考虑加入我们的Slack 频道,看看GitHub上的Kubernetes 项目,或加入Kubernetes-dev Google 论坛。如果您真的对此感到兴奋,则可以完成上述所有操作,并加入我们的下一次社区对话-2016年1月27日。请将您自己或您想了解的话题添加到议程中,并获得一个加入此群组进行日历邀请。

为什么 Kubernetes 不用 libnetwork

在 1.0 版本发布之前,Kubernetes 已经有了一个非常基础的网络插件形式-大约在引入 Docker’s libnetwork 和 Container Network Model (CNM) 的时候。与 libnetwork 不同,Kubernetes 插件系统仍然保留它的 'alpha' 名称。现在 Docker 的网络插件支持已经发布并得到支持,我们发现一个明显的问题是 Kubernetes 尚未采用它。毕竟,供应商几乎肯定会为 Docker 编写插件-我们最好还是用相同的驱动程序,对吧?

在进一步说明之前,重要的是记住 Kubernetes 是一个支持多种容器运行时的系统, Docker 只是其中之一。配置网络只是每一个运行时的一个方面,所以当人们问起“ Kubernetes 会支持CNM吗?”,他们真正的意思是“ Kubernetes 会支持 Docker 运行时的 CNM 驱动吗?”如果我们能够跨运行时实现通用的网络支持会很棒,但这不是一个明确的目标。

实际上, Kubernetes 还没有为 Docker 运行时采用 CNM/libnetwork 。事实上,我们一直在研究 CoreOS 提出的替代 Container Network Interface (CNI) 模型以及 App Container (appc) 规范的一部分。为什么我们要这么做?有很多技术和非技术的原因。

首先,Docker 的网络驱动程序设计中存在一些基本假设,这些假设会给我们带来问题。

Docker 有一个“本地”和“全局”驱动程序的概念。本地驱动程序(例如 "bridge" )以机器为中心,不进行任何跨节点协调。全局驱动程序(例如 "overlay" )依赖于 libkv (一个键值存储抽象库)来协调跨机器。这个键值存储是另一个插件接口,并且是非常低级的(键和值,没有其他含义)。 要在 Kubernetes 集群中运行类似 Docker's overlay 驱动程序,我们要么需要集群管理员来运行 consul, etcdzookeeper 的整个不同实例 (see multi-host networking) 否则我们必须提供我们自己的 libkv 实现,那被 Kubernetes 支持。

后者听起来很有吸引力,并且我们尝试实现它,但 libkv 接口是非常低级的,并且架构在内部定义为 Docker 。我们必须直接暴露我们的底层键值存储,或者提供键值语义(在我们的结构化API之上,它本身是在键值系统上实现的)。对于性能,可伸缩性和安全性原因,这些都不是很有吸引力。最终结果是,当使用 Docker 网络的目标是简化事情时,整个系统将显得更加复杂。

对于愿意并且能够运行必需的基础架构以满足 Docker 全局驱动程序并自己配置 Docker 的用户, Docker 网络应该“正常工作。” Kubernetes 不会妨碍这样的设置,无论项目的方向如何,该选项都应该可用。但是对于默认安装,实际的结论是这对用户来说是一个不应有的负担,因此我们不能使用 Docker 的全局驱动程序(包括 "overlay" ),这消除了使用 Docker 插件的很多价值。

Docker 的网络模型做出了许多对 Kubernetes 无效的假设。在 docker 1.8 和 1.9 版本中,它包含一个从根本上有缺陷的“发现”实现,导致容器中的 /etc/hosts 文件损坏 (docker #17190) - 并且这不容易被关闭。在 1.10 版本中,Docker 计划 捆绑一个新的DNS服务器,目前还不清楚是否可以关闭它。容器级命名不是 Kubernetes 的正确抽象 - 我们已经有了自己的服务命名,发现和绑定概念,并且我们已经有了自己的 DNS 模式和服务器(基于完善的 SkyDNS )。捆绑的解决方案不足以满足我们的需求,但不能禁用。

与本地/全局拆分正交, Docker 具有进程内和进程外( "remote" )插件。我们调查了是否可以绕过 libnetwork (从而跳过上面的问题)并直接驱动 Docker remote 插件。不幸的是,这意味着我们无法使用任何 Docker 进程中的插件,特别是 "bridge" 和 "overlay",这再次消除了 libnetwork 的大部分功能。

另一方面, CNI 在哲学上与 Kubernetes 更加一致。它比 CNM 简单得多,不需要守护进程,并且至少有合理的跨平台( CoreOS 的 rkt 容器运行时支持它)。跨平台意味着有机会启用跨运行时(例如 Docker , Rocket , Hyper )运行相同的网络配置。 它遵循 UNIX 的理念,即做好一件事。

此外,包装 CNI 插件并生成更加个性化的 CNI 插件是微不足道的 - 它可以通过简单的 shell 脚本完成。 CNM 在这方面要复杂得多。这使得 CNI 对于快速开发和迭代是有吸引力的选择。早期的原型已经证明,可以将 kubelet 中几乎 100% 的当前硬编码网络逻辑弹出到插件中。

我们调查了为 Docker 编写 "bridge" CNM驱动程序 并运行 CNI 驱动程序。事实证明这非常复杂。首先, CNM 和 CNI 模型非常不同,因此没有一种“方法”协调一致。 我们仍然有上面讨论的全球与本地和键值问题。假设这个驱动程序会声明自己是本地的,我们必须从 Kubernetes 获取有关逻辑网络的信息。

不幸的是, Docker 驱动程序很难映射到像 Kubernetes 这样的其他控制平面。具体来说,驱动程序不会被告知连接容器的网络名称 - 只是 Docker 内部分配的 ID 。这使得驱动程序很难映射回另一个系统中存在的任何网络概念。

这个问题和其他问题已由网络供应商提出给 Docker 开发人员,并且通常关闭为“按预期工作”,(libnetwork #139, libnetwork #486, libnetwork #514, libnetwork #865, docker #18864),即使它们使非 Docker 第三方系统更难以与之集成。在整个调查过程中, Docker 明确表示他们对偏离当前路线或委托控制的想法不太欢迎。这对我们来说非常令人担忧,因为 Kubernetes 补充了 Docker 并增加了很多功能,但它存在于 Docker 之外。

出于所有这些原因,我们选择投资 CNI 作为 Kubernetes 插件模型。这会有一些不幸的副作用。它们中的大多数都相对较小(例如, docker inspect 不会显示 IP 地址),特别是由 docker run 启动的容器可能无法与 Kubernetes 启动的容器通信,如果网络集成商想要与 Kubernetes 完全集成,则必须提供 CNI 驱动程序。但另一方面, Kubernetes 将变得更简单,更灵活,早期引入的许多丑陋的(例如配置 Docker 使用我们的网桥)将会消失。

当我们沿着这条道路前进时,我们会保持开放,以便更好地整合和简化。如果您对我们如何做到这一点有所想法,我们真的希望听到它们 - 在 slack 或者 network SIG mailing-list 找到我们。

Tim Hockin, Software Engineer, Google

Kubernetes 和 Docker 简单的 leader election

概述

Kubernetes 简化了集群上运行的服务的部署和操作管理。但是,它也简化了这些服务的发展。在本文中,我们将看到如何使用 Kubernetes 在分布式应用程序中轻松地执行 leader election。分布式应用程序通常为了可靠性和可伸缩性而复制服务的任务,但通常需要指定其中一个副本作为负责所有副本之间协调的负责人。

通常在 leader election 中,会确定一组成为领导者的候选人。这些候选人都竞相宣布自己为领袖。其中一位候选人获胜并成为领袖。一旦选举获胜,领导者就会不断地“信号”以表示他们作为领导者的地位,其他候选人也会定期地做出新的尝试来成为领导者。这样可以确保在当前领导因某种原因失败时,快速确定新领导。

实现 leader election 通常需要部署 ZooKeeper、etcd 或 Consul 等软件并将其用于协商一致,或者也可以自己实现协商一致算法。我们将在下面看到,Kubernetes 使在应用程序中使用 leader election 的过程大大简化。

####在 Kubernetes 实施领导人选举

Leader election 的首要条件是确定候选人的人选。Kubernetes 已经使用 Endpoints 来表示组成服务的一组复制 pod,因此我们将重用这个相同的对象。(旁白:您可能认为我们会使用 ReplicationControllers,但它们是绑定到特定的二进制文件,而且通常您希望只有一个领导者,即使您正在执行滚动更新)

要执行 leader election,我们使用所有 Kubernetes api 对象的两个属性:

  • ResourceVersions - 每个 API 对象都有一个惟一的 ResourceVersion,您可以使用这些版本对 Kubernetes 对象执行比较和交换
  • Annotations - 每个 API 对象都可以用客户端使用的任意键/值对进行注释。

给定这些原语,使用 master election 的代码相对简单,您可以在这里找到here。我们自己来做吧。

$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example

这将创建一个包含3个副本的 leader election 集合:

$ kubectl get pods
NAME                   READY     STATUS    RESTARTS   AGE
leader-elector-inmr1   1/1       Running   0          13s
leader-elector-qkq00   1/1       Running   0          13s
leader-elector-sgwcq   1/1       Running   0          13s

要查看哪个pod被选为领导,您可以访问其中一个 pod 的日志,用您自己的一个 pod 的名称替换

${pod_name}, (e.g. leader-elector-inmr1 from the above)

$ kubectl logs -f ${name}
leader is (leader-pod-name)

…或者,可以直接检查 endpoints 对象:

_'example' 是上面 kubectl run … 命令_中候选集的名称

$ kubectl get endpoints example -o yaml

现在,要验证 leader election 是否实际有效,请在另一个终端运行:

$ kubectl delete pods (leader-pod-name)

这将删除现有领导。由于 pod 集由 replication controller 管理,因此新的 pod 将替换已删除的pod,确保复制集的大小仍为3。通过 leader election,这三个pod中的一个被选为新的领导者,您应该会看到领导者故障转移到另一个pod。因为 Kubernetes 的吊舱在终止前有一个 grace period,这可能需要30-40秒。

Leader-election container 提供了一个简单的 web 服务器,可以服务于任何地址(e.g. http://localhost:4040)。您可以通过删除现有的 leader election 组并创建一个新的 leader elector 组来测试这一点,在该组中,您还可以向 leader elector 映像传递--http=(host):(port) 规范。这将导致集合中的每个成员通过 webhook 提供有关领导者的信息。

# delete the old leader elector group
$ kubectl delete rc leader-elector

# create the new group, note the --http=localhost:4040 flag
$ kubectl run leader-elector --image=gcr.io/google_containers/leader-elector:0.4 --replicas=3 -- --election=example --http=0.0.0.0:4040

# create a proxy to your Kubernetes api server
$ kubectl proxy

然后您可以访问:

http://localhost:8001/api/v1/proxy/namespaces/default/pods/(leader-pod-name):4040/

你会看到:

{"name":"(name-of-leader-here)"}

有副手的 leader election

好吧,那太好了,你可以通过 HTTP 进行leader election 并找到 leader,但是你如何从自己的应用程序中使用它呢?这就是 sidecar 的由来。Kubernetes 中,Pods 由一个或多个容器组成。通常情况下,这意味着您将 sidecar containers 添加到主应用程序中以组成 pod。(关于这个主题的更详细的处理,请参阅我之前的博客文章)。 Leader-election container 可以作为一个 sidecar,您可以从自己的应用程序中使用。Pod 中任何对当前 master 感兴趣的容器都可以简单地访问http://localhost:4040,它们将返回一个包含当前 master 名称的简单 json 对象。由于 pod中 的所有容器共享相同的网络命名空间,因此不需要服务发现!

例如,这里有一个简单的 Node.js 应用程序,它连接到 leader election sidecar 并打印出它当前是否是 master。默认情况下,leader election sidecar 将其标识符设置为 hostname

var http = require('http');
// This will hold info about the current master
var master = {};

  // The web handler for our nodejs application
  var handleRequest = function(request, response) {
    response.writeHead(200);
    response.end("Master is " + master.name);
  };

  // A callback that is used for our outgoing client requests to the sidecar
  var cb = function(response) {
    var data = '';
    response.on('data', function(piece) { data = data + piece; });
    response.on('end', function() { master = JSON.parse(data); });
  };

  // Make an async request to the sidecar at http://localhost:4040
  var updateMaster = function() {
    var req = http.get({host: 'localhost', path: '/', port: 4040}, cb);
    req.on('error', function(e) { console.log('problem with request: ' + e.message); });
    req.end();
  };

  / / Set up regular updates
  updateMaster();
  setInterval(updateMaster, 5000);

  // set up the web server
  var www = http.createServer(handleRequest);
  www.listen(8080);

当然,您可以从任何支持 HTTP 和 JSON 的语言中使用这个 sidecar。

结论

希望我已经向您展示了使用 Kubernetes 为您的分布式应用程序构建 leader election 是多么容易。在以后的部分中,我们将向您展示 Kubernetes 如何使构建分布式系统变得更加容易。同时,转到Google Container Enginekubernetes.io开始使用Kubernetes。

使用 Puppet 管理 Kubernetes Pod、Service 和 Replication Controller

今天的嘉宾帖子是由 IT 自动化领域的领导者 Puppet Labs 的高级软件工程师 Gareth Rushgrove 撰写的。Gareth告诉我们一个新的 Puppet 模块,它帮助管理 Kubernetes 中的资源。

熟悉[Puppet]的人(https://github.com/puppetlabs/puppet)可能使用它来管理主机上的文件、包和用户。但是Puppet首先是一个配置管理工具,配置管理是一个比管理主机级资源更广泛的规程。配置管理的一个很好的定义是它旨在解决四个相关的问题:标识、控制、状态核算和验证审计。这些问题存在于任何复杂系统的操作中,并且有了新的Puppet Kubernetes module,我们开始研究如何为 Kubernetes 解决这些问题。

Puppet Kubernetes 模块

Puppet kubernetes 模块目前假设您已经有一个 kubernetes 集群 [启动并运行]](http://kubernetes.io/gettingstarted/)。它的重点是管理 Kubernetes中的资源,如 Pods、Replication Controllers 和 Services,而不是(现在)管理底层的 kubelet 或 etcd services。下面是描述 Puppet’s DSL 中一个 Pod 的简短代码片段。

kubernetes_pod { 'sample-pod':
  ensure => present,
  metadata => {
    namespace => 'default',
  },
  spec => {
    containers => [{
      name => 'container-name',
      image => 'nginx',
    }]
  },
}

如果您熟悉 YAML 文件格式,您可能会立即识别该结构。 该接口故意采取相同的格式以帮助在不同格式之间进行转换 — 事实上,为此提供支持的代码是从Kubernetes API Swagger自动生成的。 运行上面的代码,假设我们将其保存为 pod.pp,就像下面这样简单:

puppet apply pod.pp

身份验证使用标准的 kubectl 配置文件。您可以在模块的自述文件中找到完整的README

Kubernetes 有很多资源,来自 Pods、 Services、 Replication Controllers 和 Service Accounts。您可以在Puppet 中的 kubernetes 留言簿示例文章中看到管理这些资源的模块示例。这演示了如何将规范的 hello-world 示例转换为使用 Puppet代码。

然而,使用 Puppet 的一个主要优点是,您可以创建自己的更高级别和更特定于业务的接口,以连接 kubernetes 管理的应用程序。例如,对于留言簿,可以创建如下内容:

guestbook { 'myguestbook':
  redis_slave_replicas => 2,
  frontend_replicas => 3,
  redis_master_image => 'redis',
  redis_slave_image => 'gcr.io/google_samples/gb-redisslave:v1',
  frontend_image => 'gcr.io/google_samples/gb-frontend:v3',
}

您可以在Puppet博客文章在 Puppet 中为 Kubernetes 构建自己的抽象中阅读更多关于使用 Puppet 定义的类型的信息,并看到更多的代码示例。

结论

使用 Puppet 而不仅仅是使用标准的 YAML 文件和 kubectl 的优点是:

  • 能够创建自己的抽象,以减少重复和设计更高级别的用户界面,如上面的留言簿示例。
  • 使用 Puppet 的开发工具验证代码和编写单元测试。
  • 与 Puppet Server 等其他工具配合,以确保代码中的模型与集群的状态匹配,并与 PuppetDB 配合工作,以存储报告和跟踪更改。
  • 能够针对 Kubernetes API 重复运行相同的代码,以检测任何更改或修正配置。

值得注意的是,大多数大型组织都将拥有非常异构的环境,运行各种各样的软件和操作系统。拥有统一这些离散系统的单一工具链可以使采用 Kubernetes 等新技术变得更加容易。

可以肯定地说,Kubernetes提供了一组优秀的组件来构建云原生系统。使用 Puppet,您可以解决在生产中运行任何复杂系统所带来的一些操作和配置管理问题。告诉我们如果您试用了该模块,您会有什么想法,以及您希望在将来看到哪些支持。

Gareth Rushgrove,Puppet Labs 高级软件工程师

Kubernetes 1.1 性能升级,工具改进和社区不断壮大

自从 Kubernetes 1.0 在七月发布以来,我们已经看到大量公司采用建立分布式系统来管理其容器集群。 我们也对帮助 Kubernetes 社区变得更好,迅速发展的人感到钦佩。 我们已经看到诸如 CoreOS 的 Tectonic 和 RedHat Atomic Host 之类的商业产品应运而生,用以提供 Kubernetes 的部署和支持。 一个不断发展的生态系统增加了 Kubernetes 的支持,包括 Sysdig 和 Project Calico 等工具供应商。

在数百名贡献者的帮助下,我们自豪地宣布 Kubernetes 1.1 的可用性,它提供了主要的性能升级、改进的工具和新特性,使应用程序更容易构建和部署。

我们想强调的一些工作包括:

  • 实质性的性能提升 :从第一天开始,我们就设计了 Kubernetes 来处理 Google 规模的工作负载,而我们的客户已经按照自己的进度进行了调整。 在 Kubernetes 1.1 中,我们进行了进一步的投资,以确保您可以在超大规模环境中运行; 本周晚些时候,我们将分享运行数千个节点集群,并针对单个集群运行超过一百万个 QPS 的示例。
  • 网络吞吐量显着提高 : 运行 Google 规模的工作负载也需要 Google 规模的网络。 在 Kubernetes 1.1 中,我们提供了使用本机IP表的选项,可将尾部延迟减少80%,几乎完全消除了CPU开销,并提高了可靠性和系统架构,从而确保Kubernetes可以很好地处理未来的大规模吞吐量。
  • 水平 Pod 自动缩放 (测试版):许多工作负载可能会经历尖峰的使用期,从而给用户带来不均匀的体验。 Kubernetes 现在支持水平 Pod 自动缩放,这意味着您的 Pod 可以根据 CPU 使用率进行缩放。 阅读有关水平 Pod 自动缩放的更多信息。
  • HTTP 负载均衡器 (测试版):Kubernetes 现在具有基于数据包自省功能来路由 HTTP 流量的内置功能。 这意味着您可以让 ‘http://foo.com/bar’ 使用一项服务,而 ‘http://foo.com/meep’ 使用一项完全独立的服务。 阅读有关Ingress对象的更多信息。
  • Job 对象 (测试版):我们也经常需要集成的批处理 Job ,例如处理一批图像以创建缩略图,或者将特别大的数据文件分解成很多块。 Job 对象引入了一个新的 API 对象,该对象运行工作负载, 如果失败,则重新启动它,并继续尝试直到成功完成。 阅读有关Job 对象的更多信息。
  • 新功能可缩短开发人员的测试周期 :我们将继续致力于快速便捷地为 Kubernetes 开发应用程序。 加快开发人员工作流程的两项新功能包括以交互方式运行容器的功能,以及改进的架构验证功能,可在部署配置文件之前让您知道配置文件是否存在任何问题。
  • 滚动更新改进 : DevOps 运动的核心是能够发布新更新,而不会影响正在运行的服务。 滚动更新现在可确保在继续更新之前,已更新的 Pod 状况良好。
  • 还有很多。有关更新的完整列表,请参见1.1. 发布在GitHub上的笔记

今天,我们也很荣幸地庆祝首届Kubernetes会议KubeCon,约有400个社区成员以及数十个供应商参加支持 Kubernetes 项目的会议。

我们想强调几个使 Kubernetes 变得更好的众多合作伙伴中的几位:

“我们押注我们的主要产品 Tectonic-它能使任何公司都能在任何地方部署、管理和保护其容器-在 Kubernetes 上使用,因为我们认为这是数据中心的未来。 Kubernetes 1.1 的发布是另一个重要的里程碑,它将使分布式系统和容器得到更广泛的采用,并使我们走上一条必将导致新一代产品和服务的道路。” – CoreOS 首席执行官Alex Polvi

“Univa 的客户正在寻找可扩展的企业级解决方案,以简化企业中容器和非容器工作负载的管理。 我们选择Kubernetes作为我们新的 Navops 套件的基础,它将帮助 IT 和 DevOps 将容器化工作负载快速集成到他们的生产系统中,并将这些工作负载扩展到云服务中。” – Univa 首席执行官 Gary Tyreman

“我们看到通过 Kubernetes 大规模运行容器的巨大客户需求是推动 Redapt 专业服务业务增长的关键因素。 作为值得信赖的顾问,在我们的工具带中有像 Kubernetes 这样的工具能够帮助我们的客户实现他们的目标,这是非常棒的。“ – Redapt SR 云解决方案副总裁 Paul Welch

如上所述,我们希望得到您的帮助:

  • GitHub上参与 Kubernetes 项目;
  • 通过 Slack 与社区联系;
  • 关注我们的 Twitter @Kubernetesio 获取最新信息;
  • 在 Stackoverflow 上发布问题(或回答问题)
  • 开始运行,部署和使用 Kubernetes 指南

但是,最重要的是,请让我们知道您是如何使用 Kubernetes 改变您的业务的,以及我们如何可以帮助您更快地做到这一点。谢谢您的支持!

 - David Aronchick, Kubernetes 和谷歌容器引擎的高级产品经理

Kubernetes 社区每周环聊笔记——2015 年 7 月 31 日

每周,Kubernetes 贡献社区都会通过Google 环聊虚拟开会。我们希望任何有兴趣的人都知道本论坛讨论的内容。

这是今天会议的笔记:

  • 私有镜像仓库演示 - Muhammed

    • 将 docker-registry 作为 RC/Pod/Service 运行

    • 在每个节点上运行代理

    • 以 localhost:5000 访问

    • 讨论:

      • 我们应该在可能的情况下通过 GCS 或 S3 支持它吗?

      • 在每个节点上运行由 $object_store 支持的真实镜像仓库

      • DNS 代替 localhost?

        • 分解 docker 镜像字符串?

        • 更像 DNS 策略吗?

  • 运行大型集群 - Joe

    • 三星渴望看到大规模 O(1000)

      • 从 AWS 开始
    • RH 也有兴趣 - 需要测试计划

    • 计划下周:讨论工作组

    • 如果您有兴趣加入有关集群可扩展性的对话,请发送邮件至[joe@0xBEDA.com][4]

  • 资源 API 提案 - Clayton

    • 新东西需要更多资源信息

    • 关于资源 API 的提案 - 向 apiserver 询问有关pod的信息

    • 发送反馈至:#11951

    • 关于快照,时间序列和聚合的讨论

  • 容器化 kubelet - Clayton

    • 打开 pull

    • Docker挂载传播 - RH 带有补丁

    • 有关整个系统引导程序的大问题

      • 双:引导docker /系统docker
    • Kube-in-docker非常好,但可能并不关键

      • 做些小事以取得进步

      • 对 docker 施加压力

  • Web UI(preilly)

    • Web UI 放在哪里?

      • 确定将其拆分出去

      • 将其用作容器镜像

      • 作为 kube 发布过程的一部分构建映像

      • vendor回来了吗?也许吧,也许不是。

    • DNS将被拆分吗?

      • 可能更紧密地集成在一起,而不是
    • 其他潜在的衍生产品:

      • apiserver

      • clients

宣布首个Kubernetes企业培训课程

在谷歌,我们依赖 Linux 容器应用程序去运行我们的核心基础架构。所有服务,从搜索引擎到Gmail服务,都运行在容器中。事实上,我们非常喜欢容器,甚至我们的谷歌云计算引擎虚拟机也运行在容器上!由于容器对于我们的业务至关重要,我们已经与社区合作开发许多基本的容器技术(从 cgroups 到 Docker 的 LibContainer),甚至决定去构建谷歌的下一代开源容器调度技术,Kubernetes。

在 Kubernetes 项目进行一年后,在 OSCON 上发布 V1 版本的前夕,我们很高兴的宣布Kubernetes 的主要贡献者 Mesosphere 组织了有史以来第一次正规的以企业为中心的 Kubernetes 培训会议。首届会议将于 6 月 20 日在波特兰的 OSCON 举办,由来自 Mesosphere 的 Zed Shaw 和 Michael Hausenblas 演讲。Pre-registration 对于优先注册者是免费的,但名额有限,立刻行动吧!

这个为期一天的课程将包涵使用 Kubernetes 构建和部署容器化应用程序的基础知识。它将通过完整的流程引导与参会者创建一个 Kubernetes 的应用程序体系结构,创建和配置 Docker 镜像,并把它们部署到 Kubernetes 集群上。用户还将了解在我们的谷歌容器引擎和 Mesosphere 的数据中心操作系统上部署 Kubernetes 应用程序和服务的基础知识。

即将推出的 Kubernetes bootcamp 将是学习如何应用 Kubernetes 解决长期部署和应用程序管理问题的一个好途径。相对于我们所预期的,来自于广泛社区的众多培训项目而言,这只是其中一个。

幻灯片:Kubernetes 集群管理,爱丁堡大学演讲

2015年6月5日星期五,我在爱丁堡大学给普通听众做了一个演讲,题目是使用 Kubernetes 进行集群管理。这次演讲包括一个带有 Kibana 前端 UI 的音乐存储系统的例子,以及一个基于 Elasticsearch 的后端,该后端有助于生成具体的概念,如 pods、复制控制器和服务。

Kubernetes 集群管理

OpenStack 上的 Kubernetes

今天,OpenStack 基金会通过在其社区应用程序目录中包含 Kubernetes,使您更容易在 OpenStack 云上部署和管理 Docker 容器集群。 今天在温哥华 OpenStack 峰会上的主题演讲中,OpenStack 基金会的首席运营官:Mark Collier 和 Mirantis 产品线经理 Craig Peters 通过利用 OpenStack 云中已经存在的计算、存储、网络和标识系统,在几秒钟内启动了 Kubernetes 集群,展示了社区应用程序目录的工作流。

目录中的条目不仅包括启动 Kubernetes 集群的功能,还包括部署在 Kubernetes 管理的 Docker 容器中的一系列应用程序。这些应用包括:

此列表将会增长,并在此处进行策划。您可以检查(并参与)YAML 文件,该文件告诉 Murano 如何根据此处定义来安装和启动 ...apps/blob/master/Docker/Kubernetes/KubernetesCluster/package/Classes/KubernetesCluster.yaml)安装和启动 Kubernetes 集群。

Kubernetes 开源项目继续受到社区的欢迎,并且势头越来越好,GitHub 上有超过 11000 个提交和 7648 颗星。从 Red Hat 和 Intel 到 CoreOS 和 Box.net,它已经代表了从企业 IT 到前沿创业企业的一系列客户。我们鼓励您尝试一下,给我们您的反馈,并参与到我们不断增长的社区中来。

  • Martin Buhr, Kubernetes 开源项目产品经理

Kubernetes 社区每周聚会笔记- 2015年5月1日

每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。

  • 简单的滚动更新 - Brendan

    • 滚动更新 = RCs和Pods很好的例子。

    • ...pause… (Brendan 需要 Kelsey 的演示恢复技巧)

    • 滚动更新具有恢复功能:取消更新并重新启动,更新从停止的地方继续。

    • 新控制器获取旧控制器的名称,因此外观是纯粹的更新。

    • 还可以在 update 中命名版本(最后不会重命名)。

  • Rocket 演示 - CoreOS 的伙计们

    • Rocket 和 docker 之间的主要区别: Rocket 是无守护进程和以 pod 为中心。。

    • Rocket 具有原生的 AppContainer 格式,但也支持 docker 镜像格式。

    • 可以在同一个 pod 中运行 AppContainer 和 docker 容器。

    • 变更接近于合并。

  • 演示 service accounts 和 secrets 被添加到 pod - Jordan

    • 问题:很难获得与API通信的令牌。

    • 新的API对象:"ServiceAccount"

    • ServiceAccount 是命名空间,控制器确保命名空间中至少存在一个个默认 service account。

    • 键入 "ServiceAccountToken",控制器确保至少有一个默认令牌。

    • 演示

    • * 可以使用 ServiceAccountToken 创建新的 service account。控制器将为它创建令牌。
      
    • 可以创建一个带有 service account 的 pod, pod 将在 /var/run/secrets/kubernetes.io/…

  • Kubelet 在容器中运行 - Paul

    • Kubelet 成功地运行了带有 secret 的 pod。

通过 RKT 对 Kubernetes 的 AppC 支持

我们最近接受了对 Kubernetes 项目的拉取请求,以增加对 Kubernetes 社区的应用程序支持。  AppC 是由 CoreOS 发起的新的开放容器规范,并通过 CoreOS rkt 容器运行时受到支持。

对于Kubernetes项目和更广泛的容器社区而言,这是重要的一步。  它为容器语言增加了灵活性和选择余地,并为Kubernetes开发人员带来了令人信服的新安全性和性能功能。

与智能编排技术(例如 Kubernetes 和/或 Apache Mesos)配合使用时,基于容器的运行时(例如 Docker 或 rkt)对开发人员构建和运行其应用程序的方式是一种合法干扰。  尽管支持技术还处于新生阶段,但它们确实为组装,部署,更新,调试和扩展解决方案提供了一些非常强大的新方法。  我相信,世界还没有意识到容器的全部潜力,未来几年将特别令人兴奋!  考虑到这一点,有几个具有不同属性和不同目的的项目才有意义。能够根据给定应用程序的特定需求将不同的部分(无论是容器运行时还是编排工具)插入在一起也是有意义的。

Docker 在使容器技术民主化并使外界可以访问它们方面做得非常出色,我们希望 Kubernetes 能够无限期地支持 Docker。CoreOS 还开始与 rkt 进行有趣的工作,以创建一个优雅,干净,简单和开放的平台,该平台提供了一些非常有趣的属性。  这看起来蓄势待发,可以为容器提供安全,高性能的操作环境。  Kubernetes 团队已经与 CoreOS 的 appc 团队合作了一段时间,在许多方面,他们都将 Kubernetes 作为简单的可插入运行时组件来构建 rkt。  

真正的好处是,借助 Kubernetes,您现在可以根据工作负载的需求选择最适合您的容器运行时,无需替换集群环境即可更改运行时,甚至可以将在同一集群中在不同容器中运行的应用程序的不同部分混合在一起。  其他选择无济于事,但最终使最终开发人员受益。

-- Craig McLuckie Google 产品经理和 Kubernetes 联合创始人

Kubernetes 社区每周聚会笔记- 2015年4月24日

每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。

日程安排:

  • Flocker 和 Kubernetes 集成演示

笔记:

  • flocker 和 kubernetes 集成演示
    • Flocker Q/A

      • 迁移后文件是否仍存在于node1上?

      • Brendan: 有没有计划把它做成一本书?我们不需要 powerstrip?

        • Luke: 需要找出感兴趣的来决定我们是否想让它成为 kube 中的一个一流的持久性磁盘提供商。

        • Brendan: 删除对 powerstrip 的需求会使其易于使用。完全去做。

        • Tim: 将它添加到 kubernetes 应该不超过45分钟:)

* Derek: 持久卷和请求相比呢?

    * Luke: 除了基于 ZFS 的新后端之外,差别不大。使工作负载真正可移植。

    * Tim: 与基于网络的卷非常不同。有趣的是,它是唯一允许升级媒体的产品。

    * Brendan: 请求,它如何查找重复请求?Cassandra 希望在底层复制数据。向上和向下扩缩是有效的。根据负载动态地创建存储。它的步骤不仅仅是快照——通过编程使用预分配创建副本。

    * Tim: 帮助自动配置。
* Brian: flocker 是否需要其他组件?

    * Kai: Flocker 控制服务与主服务器位于同一位置。(dia 在博客上)。Powerstrip + Powerstrip Flocker。对在 etcd 中持久化状态非常有趣。它保存关于每个卷的元数据。

    * Brendan: 在未来,flocker 可以是一个插件,我们将负责持久性。发布 v1.0。

    * Brian: 有兴趣为 flocker 等服务添加通用插件。

    * Luke: 当扩展到单个节点上的许多容器时,Zfs 会变得非常有价值。
* Alex: flocker 服务可以作为 pod 运行吗?

    * Kai: 是的,唯一的要求是 flocker 控制服务应该能够与 zfs 代理对话。需要在主机上安装 zfs 代理,并且需要访问 zfs 二进制文件。

    * Brendan: 从理论上讲,所有 zfs 位都可以与设备一起放入容器中。

    * Luke: 是的,仍然在处理跨容器安装问题。

    * Tim: pmorie 正在通过它使 kubelet 在容器中工作。可能重复使用。

* Kai: Cinder 支持即将到来。几天之后。
  • Bob: 向 GKE 推送 kube 的过程是怎样的?需要更多的可见度。

Borg: Kubernetes 的前身

十多年来,谷歌一直在生产中运行容器化工作负载。 无论是像网络前端和有状态服务器之类的工作,像 BigtableSpanner一样的基础架构系统,或是像 MapReduceMillwheel一样的批处理框架, Google 的几乎一切都是以容器的方式运行的。今天,我们揭开了 Borg 的面纱,Google 传闻已久的面向容器的内部集群管理系统,并在学术计算机系统会议 Eurosys 上发布了详细信息。你可以在 此处 找到论文。

Kubernetes 直接继承自 Borg。 在 Google 的很多从事 Kubernetes 的开发人员以前都是 Borg 项目的开发人员。 我们在 Kubernetes 中结合了 Borg 的最佳创意,并试图解决用户多年来在 Borg 中发现的一些痛点。

Kubernetes 中的以下四个功能特性源于我们从 Borg 获得的经验:

  1. Pods. Pod 是 Kubernetes 中调度的单位。 它是一个或多个容器在其中运行的资源封装。 保证属于同一 Pod 的容器可以一起调度到同一台计算机上,并且可以通过本地卷共享状态。

Borg 有一个类似的抽象,称为 alloc(“资源分配”的缩写)。 Borg 中 alloc 的常见用法包括运行 Web 服务器,该服务器生成日志,一起部署一个轻量级日志收集进程, 该进程将日志发送到集群文件系统(和 fluentd 或 logstash 没什么不同 ); 运行 Web 服务器,该 Web 服务器从磁盘目录提供数据, 该磁盘目录由从集群文件系统读取数据并为 Web 服务器准备/暂存的进程填充(与内容管理系统没什么不同); 并与存储分片一起运行用户定义的处理功能。

Pod 不仅支持这些用例,而且还提供类似于在单个 VM 中运行多个进程的环境 -- Kubernetes 用户可以在 Pod 中部署多个位于同一地点的协作过程,而不必放弃一个应用程序一个容器的部署模型。

  1. 服务。 尽管 Borg 的主要角色是管理任务和计算机的生命周期,但是在 Borg 上运行的应用程序还可以从许多其它集群服务中受益,包括命名和负载均衡。 Kubernetes 使用服务抽象支持命名和负载均衡:带名字的服务,会映射到由标签选择器定义的一组动态 Pod 集(请参阅下一节)。 集群中的任何容器都可以使用服务名称链接到服务。

在幕后,Kubernetes 会自动在与标签选择器匹配到 Pod 之间对与服务的连接进行负载均衡,并跟踪 Pod 在哪里运行,由于故障,它们会随着时间的推移而重新安排。

  1. 标签。 Borg 中的容器通常是一组相同或几乎相同的容器中的一个副本,该容器对应于 Internet 服务的一层(例如 Google Maps 的前端)或批处理作业的工人(例如 MapReduce)。 该集合称为 Job ,每个副本称为任务。 尽管 Job 是一个非常有用的抽象,但它可能是有限的。 例如,用户经常希望将其整个服务(由许多 Job 组成)作为一个实体进行管理,或者统一管理其服务的几个相关实例,例如单独的 Canary 和稳定的发行版。 另一方面,用户经常希望推理和控制 Job 中的任务子集 --最常见的示例是在滚动更新期间,此时作业的不同子集需要具有不同的配置。

通过使用标签组织 Pod ,Kubernetes 比 Borg 支持更灵活的集合,标签是用户附加到 Pod(实际上是系统中的任何对象)的任意键/值对。 用户可以通过在其 Pod 上使用 “job:<jobname>” 标签来创建与 Borg Jobs 等效的分组,但是他们还可以使用其他标签来标记服务名称,服务实例(生产,登台,测试)以及一般而言,其 pod 的任何子集。 标签查询(称为“标签选择器”)用于选择操作应用于哪一组 Pod 。 结合起来,标签和复制控制器 允许非常灵活的更新语义,以及跨等效项的操作 Borg Jobs。

  1. 每个 Pod 一个 IP。在 Borg 中,计算机上的所有任务都使用该主机的 IP 地址,从而共享主机的端口空间。 虽然这意味着 Borg 可以使用普通网络,但是它给基础结构和应用程序开发人员带来了许多负担:Borg 必须将端口作为资源进行调度;任务必须预先声明它们需要多少个端口,并将要使用的端口作为启动参数;Borglet(节点代理)必须强制端口隔离;命名和 RPC 系统必须处理端口以及 IP 地址。

多亏了软件定义的覆盖网络,例如 flannel 或内置于公有云网络的出现,Kubernetes 能够为每个 Pod 提供服务并为其提供自己的 IP 地址。 这消除了管理端口的基础架构的复杂性,并允许开发人员选择他们想要的任何端口,而不需要其软件适应基础架构选择的端口。 后一点对于使现成的易于运行 Kubernetes 上的开源应用程序至关重要 -- 可以将 Pod 视为 VMs 或物理主机,可以访问整个端口空间,他们可能与其他 Pod 共享同一台物理计算机,这一事实已被忽略。

随着基于容器的微服务架构的日益普及,Google 从内部运行此类系统所汲取的经验教训已引起外部 DevOps 社区越来越多的兴趣。 通过揭示集群管理器 Borg 的一些内部工作原理,并将下一代集群管理器构建为一个开源项目(Kubernetes)和一个公开可用的托管服务(Google Container Engine),我们希望这些课程可以使 Google 之外的广大社区受益,并推动容器调度和集群管理方面的最新技术发展。

Kubernetes 社区每周聚会笔记- 2015年4月17日

每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。

议程

  • Mesos 集成
  • 高可用性(HA)
  • 向 e2e 添加性能和分析详细信息以跟踪回归
  • 客户端版本化

笔记

  • Mesos 集成

    • Mesos 集成提案:

    • 没有阻塞集成的因素。

    • 文档需要更新。

  • HA

    • 提案今天应该会提交。

    • Etcd 集群。

    • apiserver 负载均衡。

    • 控制器管理器和其他主组件的冷备用。

  • 向 e2e 添加性能和分析详细信息以跟踪回归

    • 希望红色为性能回归

    • 需要公共数据库才能发布数据

      • 查看
    • Justin 致力于多平台 e2e 仪表盘

  • 客户端版本化

*

* 客户端库当前使用内部 API 对象。

* 尽管没有人反映频繁修改 `types.go` 有多痛苦,但我们很为此担心。

* 结构化类型在客户端中很有用。版本化的结构就可以了。

* 如果从 json/yaml (kubectl) 开始,则不应转换为结构化类型。使用 swagger。
  • Security context

* 管理员可以限制谁可以运行特权容器或需要特定的 unix uid

* kubelet 将能够从 apiserver 获取证书

* 政策提案将于下周左右出台
  • 讨论用户的上游,等等进入Kubernetes,至少是可选的

  • 1.0 路线图

    • 重点是性能,稳定性,集群升级

    • TJ 一直在对roadmap.md进行一些编辑,但尚未发布PR

  • Kubernetes UI

    • 依赖关系分解为第三方

    • @lavalamp 是评论家

[*[3:27 PM]: 2015-04-17T15:27:00-07:00

Kubernetes Release: 0.15.0

Release 说明:

  • 启用 1beta3 API 并将其设置为默认 API 版本 (#6098)
  • 增加了多端口服务(#6182)
    • 新入门指南
    • 多节点本地启动指南 (#6505)
    • Google 云平台上的 Mesos (#5442)
    • Ansible 安装说明 (#6237)
  • 添加了一个控制器框架 (#5270, #5473)
  • Kubelet 现在监听一个安全的 HTTPS 端口 (#6380)
  • 使 kubectl 错误更加友好 (#6338)
  • apiserver 现在支持客户端 cert 身份验证 (#6190)
  • apiserver 现在限制了它处理的并发请求的数量 (#6207)
  • 添加速度限制删除 pod (#6355)
  • 将平衡资源分配算法作为优先级函数实现在调度程序包中 (#6150)
  • 从主服务器启用日志收集功能 (#6396)
  • 添加了一个 api 端口来从 Pod 中提取日志 (#6497)
  • 为调度程序添加了延迟指标 (#6368)
  • 为 REST 客户端添加了延迟指标 (#6409)
  • etcd 现在在 master 上的一个 pod 中运行 (#6221)
  • nginx 现在在 master上的容器中运行 (#6334)
  • 开始为主组件构建 Docker 镜像 (#6326)
  • 更新了 GCE 程序以使用 gcloud 0.9.54 (#6270)
  • 更新了 AWS 程序来修复区域与区域语义 (#6011)
  • 记录镜像 GC 失败时的事件 (#6091)
  • 为 kubernetes 客户端添加 QPS 限制器 (#6203)
  • 减少运行 make release 所需的时间 (#6196)
  • 新卷的支持
    • 添加 iscsi 卷插件 (#5506)
    • 添加 glusterfs 卷插件 (#6174)
    • AWS EBS 卷支持 (#5138)
  • 更新到 heapster 版本到 v0.10.0 (#6331)
  • 更新到 etcd 2.0.9 (#6544)
  • 更新到 Kibana 到 v1.2 (#6426)
  • 漏洞修复
    • 如果服务的公共 IP 发生变化,Kube-proxy现在会更新iptables规则 (#6123)
    • 如果初始创建失败,则重试 kube-addons 创建 (#6200)
    • 使 kube-proxy 对耗尽文件描述符更具弹性 (#6727)

要下载,请访问 https://github.com/GoogleCloudPlatform/kubernetes/releases/tag/v0.15.0

每周 Kubernetes 社区例会笔记 - 2015 年 4 月 3 日

Kubernetes: 每周 Kubernetes 社区聚会笔记

每周,Kubernetes 贡献社区几乎都会通过 Google Hangouts 开会。 我们希望任何有兴趣的人都知道本论坛讨论的内容。

议程:

  • Quinton - 集群联邦
  • Satnam - 性能基准测试更新

会议记录:

  1. Quinton - 集群联邦
  • 在旧金山见面会后,想法浮出水面
    • 请阅读、评论
  • 不是 1.0,而是将文档放在一起以显示路线图
  • 可以在 Kubernetes 之外构建
  • 用于控制多个集群中事物的 API ,包括一些逻辑
  1. Auth(n)(z)

  2. 调度策略

  3. ……

  • 集群联邦的不同原因
  1. 区域(非)可用性:对区域故障的弹性

  2. 混合云:有些在云中,有些在本地。 由于各种原因

  3. 避免锁定云提供商。 由于各种原因

  4. "Cloudbursting" - 自动溢出到云中

  • 困难的问题
  1. 位置亲和性。Pod 需要多近?

    1. 工作负载的耦合

    2. 绝对位置(例如,欧盟数据需要在欧盟内)

  2. 跨集群服务发现

    1. 服务/DNS 如何跨集群工作
  3. 跨集群工作负载迁移

    1. 如何在跨集群中逐块移动应用程序?
  4. 跨集群调度

    1. 如何充分了解集群以知道在哪里进行调度

    2. 可能使用成本函数以最小的复杂性得出亲和性

    3. 还可以使用成本来确定调度位置(使用不足的集群比过度使用的集群便宜)

  • 隐含要求
  1. 跨集群集成不应创建跨集群故障模式

    1. 在 Ubernetes 死亡的灾难情况下可以独立使用。
  2. 统一可见性

    1. 希望有统一的监控,报警,日志,内省,用户体验等。
  3. 统一的配额和身份管理

    1. 希望将用户数据库和 auth(n)/(z) 放在一个位置
  • 需要注意的是,导致软件故障的大多数原因不是基础架构
  1. 拙劣的软件升级

  2. 拙劣的配置升级

  3. 拙劣的密钥分发

  4. 过载

  5. 失败的外部依赖

  • 讨论:
  1. ”ubernetes“ 的边界确定

    1. 可能在可用区,但也可能在机架,或地区
  2. 重要的是不要鸽子洞并防止其他用户

  1. Satnam - 浸泡测试
  • 想要测量长时间运行的事务,以确保集群在一段时间内是稳定的。性能不会降低,不会发生内存泄漏等。
  • github.com/GoogleCloudPlatform/kubernetes/test/soak/…
  • 单个二进制文件,在每个节点上放置许多 Pod,并查询每个 Pod 以确保其正在运行。
  • Pod 的创建速度越来越快(即使在过去一周内),也可以使事情进展得更快。
  • Pod 运行起来后,我们通过代理点击 Pod。决定使用代理是有意的,因此我们测试了 kubernetes apiserver。
  • 代码已经签入。
  • 将 Pod 固定在每个节点上,练习每个 Pod,确保你得到每个节点的响应。
  • 单个二进制文件,永远运行。
  • Brian - v1beta3 默认启用, v1beta1 和 v1beta2 不支持,在6月关闭。仍应与升级现有集群等一起使用。

Kubernetes 社区每周聚会笔记 - 2015 年 3 月 27 日

每个星期,Kubernetes 贡献者社区几乎都会在谷歌 Hangouts 上聚会。我们希望任何对此感兴趣的人都能了解这个论坛的讨论内容。

日程安排:

- Andy - 演示远程执行和端口转发

- Quinton - 联邦集群 - 延迟

- Clayton - 围绕 Kubernetes 的 UI 代码共享和协作

从会议指出:

1. Andy 从 RedHat:

  • 演示远程执行
* kubectl exec -p $POD -- $CMD

* 作为代理与主机建立连接,找出 pod 所在的节点,代理与 kubelet 的连接,这一点很有趣。通过 nsenter。

* 使用 SPDY 通过 HTTP 进行多路复用流式传输

* 还有互动模式:

* 假设第一个容器,可以使用 -c $CONTAINER 一个特定的。

* 如果在容器中预先安装了 gdb,则可以交互地将其附加到正在运行的进程中

    * backtrace、symbol tbles、print 等。  使用gdb可以做的大多数事情。

* 也可以用精心制作的参数在上面运行 rsync 或者在容器内设置 sshd。

* 一些聊天反馈:
  • Andy 还演示了端口转发
  • nnsenter 与 docker exec
* 想要在主机的控制下注入二进制文件,类似于预启动钩子

* socat、nsenter,任何预启动钩子需要的
  • 如果能在博客上发表这方面的文章就太好了
  • wheezy 中的 nginx 版本太旧,无法支持所需的主代理功能

2. Clayton: 我们的社区组织在哪里,例如 kubernetes UI 组件?

  • google-containers-ui IRC 频道,邮件列表。
  • Tim: google-containers 前缀是历史的,应该只做 "kubernetes-ui"
  • 也希望将设计资源投入使用,并且 bower 期望自己的仓库。
  • 通用协议

3. Brian Grant:

  • 测试 v1beta3,准备进入。
  • Paul 致力于改变命令行的内容。
  • 下周初至中旬,尝试默认启用v1beta3 ?
  • 对于任何其他更改,请发出文件并抄送 thockin。

4. 一般认为30分钟比60分钟好

  • 不应该为了填满时间而人为地延长。

Kubernetes 采集视频

如果你错过了上个月在旧金山举行的 Kubernetes 大会,不要害怕!以下是在 YouTube 上组织成播放列表的晚间演示文稿中的视频。

Kubernetes Gathering

欢迎来到 Kubernetes 博客!

欢迎来到新的 Kubernetes 博客。关注此博客,了解 Kubernetes 开源项目。我们计划时不时的发布发布说明,操作方法文章,活动,甚至一些非常有趣的话题。

如果您正在使用 Kubernetes 或为该项目做出贡献并想要发帖子,请告诉我

首先,以下是 Kubernetes 最近在其他网站上发布的文章摘要:

快乐的云计算!

  • Kit Merker - Google 云平台产品经理