乐趣区

关于阿里云:OpenKruise-v10云原生应用自动化达到新的高峰

云原生利用自动化治理套件、CNCF Sandbox 我的项目 — OpenKruise,近期公布了 v1.0 大版本。

OpenKruise [1]  是针对 Kubernetes 的加强能力套件,聚焦于云原生利用的部署、降级、运维、稳定性防护等畛域。所有的性能都通过 CRD 等规范形式扩大,能够实用于 1.16 以上版本的任意 Kubernetes 集群。单条 helm 命令即可实现 Kruise 的一键部署,无需更多配置。

总得来看,目前 OpenKruise 提供的能力分为几个畛域:

  • 利用工作负载: 面向无状态、有状态、daemon 等多种类型利用的高级部署公布策略,例如原地降级、灰度流式公布等。
  • Sidecar 容器治理: 反对独立定义 sidecar 容器,实现动静注入、独立原地降级、热降级等性能。
  • 加强运维能力: 包含容器原地重启、镜像预拉取、容器启动程序保障等。
  • 利用分区治理: 治理利用在多个分区(可用区、不同机型等)上的部署比例、程序、优先级等。
  • 利用平安防护: 帮忙利用在 Kubernetes 之上取得更高的安全性保障与可用性防护。

版本解析

在 v1.0 大版本中,OpenKruise 带来了多种新的个性,同时也对不少已有性能做了加强与优化。

首先要说的是,从 v1.0 开始 OpenKruise 将 CRD/WehhookConfiguration 等资源配置的版本从 v1beta1 降级到 v1 ,因而能够反对 Kubernetes v1.22 及以上版本的集群,但同时也要求 Kubernetes 的版本不能低于 v1.16。

以下对 v1.0 的局部性能做简要介绍,具体的 ChangeLog 列表请查看 OpenKruise Github 上的 release 阐明以及官网文档。

反对环境变量原地降级

Author: @FillZpp [2]

OpenKruise 从晚期版本开始就反对了“原地降级”性能,次要利用于 CloneSet 与 Advanced StatefulSet 两种工作负载上。简略来说,原地降级使得利用在降级的过程中,不须要删除、新建 Pod 对象,而是通过对 Pod 中容器配置的批改来达到降级的目标。

如上图所示,原地降级过程中只批改了 Pod 中的字段,因而:

  1. 能够防止如 调度、调配 IP、调配、挂载盘 等额定的操作和代价。
  2. 更快的镜像拉取,因为开源复用已有旧镜像的大部分 layer 层,只须要拉取新镜像变动的一些 layer。
  3. 当一个容器在原地降级时,Pod 的网络、挂载盘、以及 Pod 中的其余容器不会受到影响,依然维持运行。

然而,OpenKruise 过来只能对 Pod 中 image 字段的更新做原地降级,对于其余字段依然只能采纳与 Deployment 类似的重建降级。始终以来,咱们收到很多用户反馈,心愿反对对 env 等更多字段的原地降级 — 因为受到 kube-apiserver 的限度,这是很难做到的。

通过咱们的不懈努力,OpenKruise 终于在 v1.0 版本中,反对了通过 Downward API 的形式反对了 env 环境变量的原地降级。例如对以下 CloneSet YAML,用户将配置定义在 annotation 中并关联到对应 env 中。后续在批改配置时,只须要更新 annotation value 中的值,Kruise 就会对 Pod 中所有 env 里援用了这个 annotation 的容器触发原地重建,从而失效这个新的 value 配置。

apiVersion: apps.kruise.io/v1alpha1
kind: CloneSet
metadata:
  ...
spec:
  replicas: 1
  template:
    metadata:
      annotations:
        app-config: "... the real env value ..."
    spec:
      containers:
      - name: app
        env:
        - name: APP_CONFIG
          valueFrom:
            fieldRef:
              fieldPath: metadata.annotations['app-config']
  updateStrategy:
    type: InPlaceIfPossible

与此同时,咱们在这个版本中也去除了过来对镜像原地降级的 imageID 限度,即反对雷同 imageID 的两个镜像替换降级。

具体应用形式请参考文档 [3]

配置跨命名空间散发

Author:@veophi [4]

在对 Secret、ConfigMap 等 namespace-scoped 资源进行跨 namespace 散发及同步的场景中,原生 kubernetes 目前只反对用户 one-by-one 地进行手动散发与同步,非常地不不便。

典型的案例有:

  • 当用户须要应用 SidecarSet 的 imagePullSecrets 能力时,要先反复地在相干 namespaces 中创立对应的 Secret,并且须要确保这些 Secret 配置的正确性和一致性。
  • 当用户想要采纳 ConfigMap 来配置一些 通用 的环境变量时,往往须要在多个 namespaces 做 ConfigMap 的下发,并且后续的批改往往也要求多 namespaces 之间放弃同步。

因而,面对这些须要跨 namespaces 进行资源散发和 屡次同步 的场景,咱们冀望一种更便捷的散发和同步工具来自动化地去做这件事,为此咱们设计并实现了一个新的 CRD — ResourceDistribution

ResourceDistribution 目前反对 SecretConfigMap 两类资源的散发和同步。

apiVersion: apps.kruise.io/v1alpha1
kind: ResourceDistribution
metadata:
  name: sample
spec:
  resource:
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: game-demo
    data:
      ...
  targets:
   namespaceLabelSelector:
      ...
    # or includedNamespaces, excludedNamespaces

如上述 YAML 所示,ResourceDistribution 是一类 cluster-scoped 的 CRD,其次要由 resource 和 targets 两个字段形成,其中 resource 字段用于形容用户所要散发的资源,targets 字段用于形容用户所要散发的指标命名空间。

具体应用形式请参考文档 [5]

容器启动顺序控制

Author: @Concurrensee [6]

对于 Kubernetes 的一个 Pod,其中的多个容器可能存在依赖关系,比方 容器 B 中利用过程的运行依赖于 容器 A 中的利用。因而,多个容器之间存在程序关系的需要:

  • 容器 A 先启动,启动胜利后才能够启动 容器 B
  • 容器 B 先退出,退出实现后才能够进行 容器 A

通常来说 Pod 容器的启动和退出程序是由 Kubelet 治理的。Kubernetes 已经有一个 KEP 打算在 container 中减少一个 type 字段来标识不同类型容器的启停优先级。然而因为 sig-node 思考到对现有代码架构的改变太大,目前这个 KEP 曾经被回绝了。

因而,OpenKruise 在 v1.0 中提供了名为 Container Launch Priority 的性能,用于管制一个 Pod 中多个容器的强制启动程序:

  1. 对于任意一个 Pod 对象,只须要在 annotations 中定义 apps.kruise.io/container-launch-priority: Ordered,则 Kruise 会依照 Pod 中 containers 容器列表的程序来保障其中容器的串行启动。
  2. 如果要自定义 containers 中多个容器的启动程序,则在容器 env 中增加 KRUISE_CONTAINER_PRIORITY 环境变量,value 值是范畴在 [-2147483647, 2147483647] 的整数。一个容器的 priority 值越大,会保障越先启动。

具体应用形式请参考文档 [7]

kubectl-kruise 命令行工具

Author: @hantmac [8]

过来 OpenKruise 是通过 kruise-api、client-java 等仓库提供了 Go、Java 等语言的 Kruise API 定义以及客户端封装,可供用户在本人的应用程序中引入应用。但依然有不少用户在测试环境下须要灵便地用命令行操作 workload 资源。

然而原生 kubectl 工具提供的 rollout、set image 等命令只能实用于原生的 workload 类型,如 Deployment、StatefulSet,并不能辨认 OpenKruise 中扩大的 workload 类型。

因而,OpenKruise 最新提供了 kubectl-kruise 命令行工具,它是 kubectl 的规范插件,提供了许多实用于 OpenKruise workload 的性能。

# rollout undo cloneset
$ kubectl kruise rollout undo cloneset/nginx
#  rollout status advanced statefulset
$ kubectl kruise rollout status statefulsets.apps.kruise.io/sts-demo
# set image of a cloneset
$ kubectl kruise set image cloneset/nginx busybox=busybox nginx=nginx:1.9.1

具体应用形式请参考文档 [9]

其余部分性能改良与优化

CloneSet:

  • 通过 scaleStrategy.maxUnavailable 策略反对流式扩容
  • Stable revision 判断逻辑变动,当所有 Pod 版本与 updateRevision 统一时则标记为 currentRevision

WorkloadSpread:

  • 反对接管存量 Pod 到匹配的 subset 分组中
  • 优化 webhook 在 Pod 注入时的更新与重试逻辑

Advanced DaemonSet:

  • 反对对 Daemon Pod 做原地降级
  • 引入 progressive annotation 来抉择是否按 partition 限度 Pod 创立

SidecarSet:

  • 解决 SidecarSet 过滤屏蔽 inactive Pod
  • 在 transferenv 中新增 SourceContainerNameFrom 和 EnvNames 字段,来解决 container name 不统一与大量 env 状况下的冗余问题

PodUnavailableBudget:

  • 新增“跳过爱护”标识
  • PodUnavailableBudget controller 关注 workload 工作负载的 replicas 变动

NodeImage:

  • 退出 –nodeimage-creation-delay 参数,并默认期待新增 Node ready 一段时间后同步创立 NodeImage

UnitedDeployment:

  • 解决 NodeSelectorTerms 为 nil 状况下 Pod NodeSelectorTerms 长度为 0 的问题

Other optimization:

  • kruise-daemon 采纳 protobuf 协定操作 Pod 资源
  • 裸露 cache resync 为命令行参数,并在 chart 中设置默认值为 0
  • 解决 certs 更新时的 http checker 刷新问题
  • 去除对 forked controller-tools 的依赖,改为应用原生 controller-tools 配合 markers 注解

社区参加

十分欢送你通过 Github/Slack/ 钉钉 / 微信 等形式退出咱们来参加 OpenKruise 开源社区。你是否曾经有一些心愿与咱们社区交换的内容呢?能够在咱们的社区双周会 [10] 上分享你的声音,或通过以下渠道参加探讨:

  • 退出社区 Slack channel [11] (English)
  • 退出社区钉钉群:搜寻群号 23330762 (Chinese)
  • 退出社区微信群:增加用户 openkruise 并让机器人拉你入群 (Chinese)

参考资料

[1]  OpenKruise:

 ​​https://openkruise.io​​

[2]  @FillZpp:

 ​​https://github.com/FillZpp​​

[3]  文档: 

/docs/core-concepts/inplace-update

[4]  @veophi:

 ​​https://github.com/veophi​​

[5]  文档: 

/docs/user-manuals/resourcedistribution

[6]  @Concurrensee:

 ​​https://github.com/Concurrensee​​

[7]  文档:

  /docs/user-manuals/containerlaunchpriority

[8]  @hantmac: 

​​https://github.com/hantmac​​

[9]  文档:

  /docs/cli-tool/kubectl-plugin

[10]  社区双周会: 

​​https://shimo.im/docs/gXqmeQOYBehZ4vqo​​

[11]  Slack channel:

 ​​https://kubernetes.slack.com/channels/openkruise​​

戳​​原文​​,查看 OpenKruise 我的项目官方主页与文档!

退出移动版