作者:赵明山(立衡)

云原生运用主动化办理套件、CNCF Sandbox 项目——OpenKruise,近期发布了 v1.3 版别。

OpenKruise是针对 Kubernetes 的增强才能套件,聚焦于云原生运用的布置、晋级、运维、安稳性防护等范畴。

一切的功能都经过 CRD 等规范方法扩展,能够适用于 1.16 以上版别的任意 Kubernetes 集群。单条 helm 指令即可完结 Kruise 的一键布置,无需更多装备。

版别解析

在版别 v1.3 中,OpenKruise 供给了新的 CRD 资源 PodProbeMarker,改进了大规模集群的一些功能问题,Advanced DaemonSet 支撑镜像预热,以及 CloneSet、WorkloadSpread、Advanced CronJob、SidecarSet 一些新的特性。

新增 CRD 和 Controller:PodProbeMarker

Kubernetes 供给了三种默许的 Pod 生命周期办理:

  • Readiness Probe:用来判别事务容器是否现已准备好响运用户请求,假如检查失利,会将该 Pod 从 Service Endpoints 中除掉。

  • Liveness Probe:用来判别容器的健康状况,假如检查失利,kubelet 将会重启该容器。

  • Startup Probe:用来判别容器是否发动完结,假如界说了该 Probe,那么 Readiness Probe 与 Liveness Probe 将会在它成功之后再执行。

所以 Kubernetes 中供给的 Probe 才能都现已限定了特定的语义以及相关的行为。除此之外,其实还是存在自界说 Probe 语义以及相关行为的需求,例如:

  • GameServer 界说 Idle Probe 用来判别该 Pod 当时是否存在游戏对局,假如没有,从本钱优化的视点,能够将该 Pod 缩容掉。

  • K8s Operator 界说 main-secondary Probe 来判别当时 Pod 的人物(main or secondary) ,晋级的时分,能够优先晋级 secondary,进而达到晋级过程只有一次选主的行为,降低晋级过程中服务抖动时间。

OpenKruise 供给了自界说 Probe 的才能,并将成果返回到 Pod Status 中,用户能够依据该成果决议后续的行为。

PodProbeMarker 装备如下:

apiVersion: apps.kruise.io/v1alpha1
kind: PodProbeMarker
metadata:
  name: game-server-probe
  namespace: ns
spec:
  selector:
    matchLabels:
      app: game-server
  probes:
  - name: Idle
    containerName: game-server
    probe:
      exec: /home/game/idle.sh
      initialDelaySeconds: 10
      timeoutSeconds: 3
      periodSeconds: 10
      successThreshold: 1
      failureThreshold: 3
    markerPolicy:
    - state: Succeeded
      labels:
        gameserver-idle: 'true'
      annotations:
        controller.kubernetes.io/pod-deletion-cost: '-10'
    - state: Failed
      labels:
        gameserver-idle: 'false'
      annotations:
        controller.kubernetes.io/pod-deletion-cost: '10'
        podConditionType: game.io/idle

PodProbeMarker 成果能够经过 Pod 对象检查:

apiVersion: v1
kind: Pod
metadata:
  labels:
    app: game-server
    gameserver-idle: 'true'
  annotations:
    controller.kubernetes.io/pod-deletion-cost: '-10'
  name: game-server-58cb9f5688-7sbd8
  namespace: ns
spec:
  ...
status:
  conditions:
    # podConditionType
  - type: game.io/idle
    # Probe State 'Succeeded' indicates 'True', and 'Failed' indicates 'False'
    status: "True"
    lastProbeTime: "2022-09-09T07:13:04Z"
    lastTransitionTime: "2022-09-09T07:13:04Z"
    # If the probe fails to execute, the message is stderr
    message: ""

功能优化:大规模集群功能明显提升

  • #1026 [ 1] 引入了延迟入队机制,大幅优化了在大规模运用集群下 kruise-manager 拉起时的 CloneSet 操控器工作队列堆积问题,在理想情况下初始化时间削减了 80% 以上。

  • #1027 [ 2] 优化 PodUnavailableBudget 操控器 Event Handler 逻辑,削减无关 Pod 入队数量。

  • #1011 [ 3] 经过缓存机制,优化了大规模集群下 Advanced DaemonSet 重复模拟 Pod 调度核算的 CPU、Memory 消耗。

  • #1015 [ 4] ,#1068 [ 5] 大幅降低了大规模集群下的运行时内存消耗。弥补了 v1.1 版别中 Disable DeepCopy 的一些疏漏点,削减 expressions 类型 label selector 的转化消耗。

SidecarSet 支撑注入特定的前史版别

SidecarSet 经过 ControllerRevision 记载了关于 containers、volumes、initContainers、imagePullSecrets 和 patchPodMetadata 等字段的前史版别,并允许用户在 Pod 创立时挑选特定的前史版别进行注入。

依据这一特性,用户能够躲避在 SidecarSet 灰度发布时,因 Deployment 等 Workload 扩容、晋级等操作带来的 SidecarSet 发布风险。假如不挑选注入版别,SidecarSet 将对重建 Pod 默许全都注入最新版别 Sidecar。

SidecarSet 相关 ControllerRevision 资源被放置在了与 Kruise-Manager 相同的命名空间中,用户能够运用以下指令来检查:

kubectl get controllerrvisions -n kruise-system -l kruise.io/sidecarset-name=your-sidecarset-name

此外,用户还能够经过 SidecarSet 的 status.latestRevision 字段看到当时版别对应的 ControllerRevision 名称,以便利自行记载。

1. 经过 ControllerRevision 名称指定注入的 Sidecar 版别

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
  name: sidecarset
spec:
  ...
  injectionStrategy:
    revisionName: specific-controllerRevision-name

2. 经过自界说版别标识指定注入的 Sidecar 版别

用户能够经过在发版时,一起给 SidecarSet 打上 apps.kruise.io/sidecarset-custom-version=your-version-id 来标记每一个前史版别,SidecarSet 会将这个 label 向下带入到对应的 ControllerRevision 对象,以便用户进行挑选,而且允许用户在挑选注入前史版别时,运用改 your-version-id 来进行描述。

假设用户只想灰度 10% 的 Pods 到 version-2,而且关于新创立的 Pod 期望都注入愈加安稳的 version-1 版别来操控灰度风险:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
metadata:
  name: sidecarset
  labels:
    apps.kruise.io/sidecarset-custom-version: version-2
spec:
  ...
  updateStrategy:
    partition: 90%
  injectionStrategy:
    customVersion: version-1

SidecarSet 支撑注入 Pod Annotations

SidecarSet 支撑注入 Pod Annotations,装备如下:

apiVersion: apps.kruise.io/v1alpha1
kind: SidecarSet
spec:
  containers:
  ...
  patchPodMetadata:
  - annotations:
    oom-score: '{"log-agent": 1}'
    custom.example.com/sidecar-configuration: '{"command": "/home/admin/bin/start.sh", "log-level": "3"}'
  patchPolicy: MergePatchJson
  - annotations:
    apps.kruise.io/container-launch-priority: Ordered
    patchPolicy: Overwrite | Retain

patchPolicy 为注入的战略,如下:

  • Retain:默许战略,假如 Pod 中存在 annotation[key]=value ,则保存 Pod 原有的 value。只有当 Pod 中不存在 annotation[key] 时,才注入 annotations[key]=value。

  • Overwrite:与 Retain 对应,当 Pod 中存在 annotation[key]=value,将被强制掩盖为 value2。

  • MergePatchJson:与 Overwrite 对应,annotations value为 json 字符串。假如 Pod 不存在该 annotations[key],则直接注入。假如存在,则进行 json value 合并。例如:Pod 中存在 annotations[oom-score]='{“main”: 2}’,注入后将 value json 合并为 annotations[oom-score]='{“log-agent”: 1, “main”: 2}’。

留意:patchPolicy 为 Overwrite和MergePatchJson 时,SidecarSet 原地晋级 Sidecar Container 时,能够同步更新该 annotations。但是,假如只修正 annotations 则不能生效,只能搭配 Sidecar 容器镜像一起原地晋级。

patchPolicy 为 Retain 时,SidecarSet 原地晋级 Sidecar Container 时,将不会同步更新该 annotations。

上述装备后,SidecarSet 在注入 Sidecar Container时,会注入 Pod annotations,如下:

apiVersion: v1
kind: Pod
metadata:
  annotations:
    apps.kruise.io/container-launch-priority: Ordered
    oom-score: '{"log-agent": 1, "main": 2}'
    custom.example.com/sidecar-configuration: '{"command": "/home/admin/bin/start.sh", "log-level": "3"}'
  name: test-pod
spec:
  containers:
    ...

留意:SidecarSet 从权限、安全的考虑不应该注入或修正除 Sidecar Container 之外的 Pod 字段,所以假如想要运用该才能,首先需求装备 SidecarSet_PatchPodMetadata_WhiteList 白名单或经过如下方法封闭白名单校验:

helm install kruise https://… –set featureGates=”SidecarSetPatchPodMetadataDefaultsAllowed =true”

Advanced DaemonSet 支撑镜像预热

假如你在安装或晋级 Kruise 的时分启用了 PreDownloadImageForDaemonSetUpdate feature-gate,DaemonSet 操控器会主动在一切旧版别 pod 所在 node 节点上预热你正在灰度发布的新版别镜像。这关于运用发布加速很有协助。

默许情况下 DaemonSet 每个新镜像预热时的并发度都是 1,也便是一个个节点拉镜像。

假如需求调整,你能够经过 apps.kruise.io/image-predownload-parallelism annotation 来设置并发度。

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  annotations:
    apps.kruise.io/image-predownload-parallelism: "10"

CloneSet 扩缩容与 PreparingDelete

默许情况下,CloneSet 将处于 PreparingDelete 状况的 Pod 视为正常,意味着这些 Pod 仍然被核算在 replicas 数量中。

在这种情况下:

  • 假如你将 replicas 从 N 改为 N-1,当一个要删去的 Pod 还在 PreparingDelete 状况中时,你从头将 replicas 改为 N,CloneSet 会将这个 Pod 从头置为 Normal 状况。

  • 假如你将 replicas 从 N 改为 N-1 的一起在 podsToDelete 中设置了一个 Pod,当这个 Pod 还在 PreparingDelete 状况中时,你从头将 replicas 改为 N,CloneSet 会比及这个 Pod 真正进入 terminating 之后再扩容一个 Pod 出来。

  • 假如你在不改动 replicas 的时分指定删去一个 Pod,当这个 Pod 还在 PreparingDelete 状况中时,CloneSet 会比及这个 Pod 真正进入 terminating 之后再扩容一个 Pod 出来。

从 Kruise v1.3.0 版别开始,你能够在 CloneSet 中设置一个 apps.kruise.io/cloneset-scaling-exclude-preparing-delete: “true” 标签,它标志着这个 CloneSet 不会将 PreparingDelete 状况的 Pod 核算在 replicas 数量中。

在这种情况下:

  • 假如你将 replicas 从 N 改为 N-1,当一个要删去的 Pod 还在 PreparingDelete 状况中时,你从头将 replicas 改为 N,CloneSet 会将这个 Pod 从头置为 Normal 状况。

  • 假如你将 replicas 从 N 改为 N-1 的一起在 podsToDelete 中设置了一个 Pod,当这个 Pod 还在 PreparingDelete 状况中时,你从头将 replicas 改为 N,CloneSet 会当即创立一个新 Pod。

  • 假如你在不改动 replicas 的时分指定删去一个 Pod,当这个 Pod 还在 PreparingDelete 状况中时,CloneSet 会当即创立一个新 Pod。

Advanced CronJob Time zones

默许情况下,一切 AdvancedCronJob schedule 调度时,都是依据 kruise-controller-manager 容器本地的时区所核算的。

不过,在 v1.3.0 版别中咱们引入了 spec.timeZone 字段,你能够将它设置为任意合法时区的名字。例如,设置 spec.timeZone: “Asia/Shanghai” 则 Kruise 会依据国内的时区核算 schedule 任务触发时间。

Go 规范库中内置了时区数据库,作为在容器的体系环境中没有外置数据库时的 fallback 挑选。

其他改动

你能够经过Github release [ 6] 页面,来检查更多的改动以及它们的作者与提交记载。

社区参加

十分欢迎你经过 Github/Slack/钉钉/微信 等方法参加咱们来参加 OpenKruise 开源社区。

你是否现已有一些期望与咱们社区沟通的内容呢?

能够在咱们的社区双周会上分享你的声响,或经过以下渠道参加讨论:

  • 参加社区Slack channel [ 7] (English)
  • 参加社区钉钉群:查找群号 23330762 (Chinese)
  • 参加社区微信群(新):添加用户 openkruise 并让机器人拉你入群 (Chinese)

参阅链接

[1] #1026

github.com/openkruise/…

[2] #1027

github.com/openkruise/…

[3] #1011

github.com/openkruise/…

[4] #1015

github.com/openkruise/…

[5] #1068

github.com/openkruise/…

[6] Github release:

https://github.com/openkruise /kruise/releases

[7] Slack channel:

kubernetes.slack.com/channels/op…

戳此处,检查 OpenKruise 项目官方主页与文档!