Advanced DaemonSet

这个控制器基于原生 DaemonSet 上增强了发布能力,比如 灰度分批、按 Node label 选择、暂停、热升级等。

如果你对原生 DaemonSet 不是很了解,我们强烈建议你先阅读它的文档(在学习 Advanced DaemonSet 之前):

注意 Advanced DaemonSet 是一个 CRD,kind 名字也是 DaemonSet,但是 apiVersion 是 apps.kruise.io/v1alpha1。 这个 CRD 的所有默认字段、默认行为与原生 DaemonSet 完全一致,除此之外还提供了一些 optional 字段来扩展增强的策略。

因此,用户从原生 DaemonSet 迁移到 Advanced DaemonSet,只需要把 apiVersion 修改后提交即可:

-  apiVersion: apps/v1
+  apiVersion: apps.kruise.io/v1alpha1
   kind: DaemonSet
   metadata:
     name: sample-ds
   spec:
     #...

增强策略

在 RollingUpdateDaemonSet 中我们新增了以下字段:

const (
+    // StandardRollingUpdateType replace the old daemons by new ones using rolling update i.e replace them on each node one after the other.
+    // this is the default type for RollingUpdate.
+    StandardRollingUpdateType RollingUpdateType = "Standard"

+    // InplaceRollingUpdateType update container image without killing the pod if possible.
+    InplaceRollingUpdateType RollingUpdateType = "InPlaceIfPossible"
)

// Spec to control the desired behavior of daemon set rolling update.
type RollingUpdateDaemonSet struct {
+    // Type is to specify which kind of rollingUpdate.
+    Type RollingUpdateType `json:"rollingUpdateType,omitempty" protobuf:"bytes,1,opt,name=rollingUpdateType"`

    // ...
    MaxUnavailable *intstr.IntOrString `json:"maxUnavailable,omitempty" protobuf:"bytes,2,opt,name=maxUnavailable"`

    // ...
    MaxSurge *intstr.IntOrString `json:"maxSurge,omitempty" protobuf:"bytes,7,opt,name=maxSurge"`

+    // A label query over nodes that are managed by the daemon set RollingUpdate.
+    // Must match in order to be controlled.
+    // It must match the node's labels.
+    Selector *metav1.LabelSelector `json:"selector,omitempty" protobuf:"bytes,3,opt,name=selector"`

+    // The number of DaemonSet pods remained to be old version.
+    // Default value is 0.
+    // Maximum value is status.DesiredNumberScheduled, which means no pod will be updated.
+    // +optional
+    Partition *int32 `json:"partition,omitempty" protobuf:"varint,4,opt,name=partition"`

+    // Indicates that the daemon set is paused and will not be processed by the
+    // daemon set controller.
+    // +optional
+    Paused *bool `json:"paused,omitempty" protobuf:"varint,5,opt,name=paused"`
}

升级方式

Advanced DaemonSet 在 spec.updateStrategy.rollingUpdate 中有一个 rollingUpdateType 字段,标识了如何进行滚动升级:

  • Standard: 对于每个 node,控制器会先删除旧的 daemon Pod,再创建一个新 Pod,和原生 DaemonSet 行为一致。
  • Surging: 对于每个 node,控制器会先创建一个新 Pod,等它 ready 之后再删除老 Pod。
  • Standard (默认): 控制器会重建升级 Pod,与原生 DaemonSet 行为一致。你可以通过 maxUnavailablemaxSurge 来控制重建新旧 Pod 的顺序。
  • InPlaceIfPossible: 控制器会尽量采用原地升级的方式,如果不行则重建升级。请阅读该文档了解更多原地升级的细节。 注意,在这个类型下,只能使用 maxUnavailable 而不能用 maxSurge

adv-daemonset-updateStrategy-rollingUpdate-rollingUpdateType-Standard.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      rollingUpdateType: Standard
kubectl patch daemonsets.apps.kruise.io nginx --type merge -p '{"spec":{"template":{"metadata":{"annotations":{"test":"test"}}}}}' -n kruise

Selector 标签选择升级

这个策略支持用户通过配置 node 标签的 selector,来指定灰度升级某些特定类型 node 上的 Pod。

adv-daemonset-updateStrategy-rollingUpdate-selector.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      selector:
        matchLabels:
          nodeType: canary
kubectl label node 192.168.229.130 nodeType=canary

kubectl patch daemonsets.apps.kruise.io nginx --type merge -p '{"spec":{"template":{"metadata":{"annotations":{"test":"test"}}}}}' -n kruise

分批灰度升级或扩容

Partition 的语义是 保留旧版本 Pod 的数量,默认为 0。 如果在发布过程中设置了 partition,则控制器只会将 (status.DesiredNumberScheduled - partition) 数量的 Pod 更新到最新版本。

adv-daemonset-updateStrategy-rollingUpdate-partition.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      partition: 1
kubectl patch daemonsets.apps.kruise.io nginx --type merge -p '{"spec":{"template":{"metadata":{"annotations":{"test":"test"}}}}}' -n kruise

另外如果你在 Advanced DaemonSet 中定义了 daemonset.kruise.io/progressive-create-pod: "true" annotation, partition 同样会在扩容的时候控制创建出来 Pod 的数量。

暂停升级

用户可以通过设置 paused 为 true 暂停发布,不过控制器还是会做 replicas 数量管理:

adv-daemonset-updateStrategy-rollingUpdate-paused.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    rollingUpdate:
      paused: true
kubectl patch daemonsets.apps.kruise.io nginx --type merge -p '{"spec":{"template":{"metadata":{"annotations":{"test":"test"}}}}}' -n kruise

kubectl patch daemonsets.apps.kruise.io nginx --type merge -p '{"spec":{"updateStrategy":{"rollingUpdate":{"paused":false}}}}' -n kruise

升级镜像自动预热

FEATURE STATE: Kruise v1.3.0

如果你在安装或升级 Kruise 的时候启用了 PreDownloadImageForDaemonSetUpdate feature-gate, DaemonSet 控制器会自动在所有旧版本 pod 所在 node 节点上预热你正在灰度发布的新版本镜像。 这对于应用发布加速很有帮助。

默认情况下 DaemonSet 每个新镜像预热时的并发度都是 1,也就是一个个节点拉镜像。 如果需要调整,你可以通过 apps.kruise.io/image-predownload-parallelism annotation 来设置并发度。

不需要inplace

apps.kruise.io/image-predownload-min-updated-ready-pods: "3"这个注解还没实现

adv-daemonset-predownload.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  annotations:
    apps.kruise.io/image-predownload-parallelism: "10"
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine

生命周期钩子

FEATURE STATE: Kruise v1.1.0

CloneSet 提供的生命周期钩子 能力相似。

目前 Advanced DaemonSet 只支持 PreDelete hook,它允许用户在 daemon Pod 被删除前执行一些自定义的逻辑。

type LifecycleStateType string

// Lifecycle contains the hooks for Pod lifecycle.
type Lifecycle struct {
    // PreDelete is the hook before Pod to be deleted.
    PreDelete *LifecycleHook `json:"preDelete,omitempty"`
}

type LifecycleHook struct {
    LabelsHandler     map[string]string `json:"labelsHandler,omitempty"`
    FinalizersHandler []string          `json:"finalizersHandler,omitempty"`

    /**********************  FEATURE STATE: 1.2.0 ************************/
    // MarkPodNotReady = true means:
    // - Pod will be set to 'NotReady' at preparingDelete/preparingUpdate state.
    // - Pod will be restored to 'Ready' at Updated state if it was set to 'NotReady' at preparingUpdate state.
    // Default to false.
    MarkPodNotReady bool `json:"markPodNotReady,omitempty"`
    /*********************************************************************/
}

例如:

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
spec:

  # define with label
  lifecycle:
    preDelete:
      labelsHandler:
        example.io/block-deleting: "true"

当 DaemonSet 删除一个 Pod 时(包括缩容和重建升级):

  • 如果没有定义 lifecycle hook 或者 Pod 不符合 preDelete 条件,则直接删除
  • 否则,会先将 Pod 更新为 PreparingDelete 状态,并等待用户的 controller 将 Pod 中关联的 label/finalizer 去除,再执行 Pod 删除
apiVersion: v1
kind: Pod
metadata:
  labels:
    example.io/block-deleting: "true"                   # the pod is hooked by PreDelete hook label
    lifecycle.apps.kruise.io/state: PreparingDelete     # so we update it to `PreparingDelete` state and wait for user controller to do something and remove the label
删除 Pod 前将其置为 NotReady

FEATURE STATE: Kruise v1.2.0

  lifecycle:
    preDelete:
      markPodNotReady: true
      finalizersHandler:
      - example.io/unready-blocker

如果设置 preDelete.markPodNotReady=true, Kruise 将会在 Pod 进入 PreparingDelete 状态时,将 KruisePodReady 这个 Pod Condition 设置为 False, Pod 将变为 NotReady

用户可以利用这一特性,在容器真正被停止之前将 Pod 上的流量先行排除,防止流量损失。

注意: 该特性仅在 Pod 被注入 KruisePodReady 这个 ReadinessGate 时生效。

用户 controller 逻辑示例

与上述 yaml 例子类似,我们需要先将 example.io/block-deleting label 定义在 Advanced DaemonSet 的 template 和 lifecycle 中。

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
spec:
  template:
    metadata:
      labels:
        example.io/block-deleting: "true"
  # ...
  lifecycle:
    preDelete:
      labelsHandler:
        example.io/block-deleting: "true"

用户自定义 controller 的执行逻辑:

  • 当发现 Pod 进入 PreparingDelete 状态,检查它的节点是否存在,并执行一些处理逻辑(例如资源预留等),最后将 Pod 中的 example.io/block-deleting label 去掉。

实战

burstReplicas

不知道怎么用

ads-burstReplicas.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  burstReplicas: 2
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

lifecycle

inPlaceUpdate

finalizersHandler
labelsHandler
markPodNotReady

preDelete

finalizersHandler
labelsHandler
markPodNotReady

minReadySeconds

这个字段只影响 DaemonSet Status 的 NumberAvailable 字段

ads-minReadySeconds.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  minReadySeconds: 60
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise
[root@node01 adv-daemonset]# kubectl get pod -n kruise
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-kkm7z   1/1     Running   0          4m43s
nginx-2gph5                               1/1     Running   0          86s
nginx-lljxg                               1/1     Running   0          86s
nginx-qqmqv                               1/1     Running   0          86s


status:
  currentNumberScheduled: 3
  daemonSetHash: 9d7db5555
  desiredNumberScheduled: 3
  numberAvailable: 2
  numberMisscheduled: 0
  numberReady: 3
  numberUnavailable: 1
  observedGeneration: 1
  updatedNumberScheduled: 3

revisionHistoryLimit

ads-revisionHistoryLimit.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  revisionHistoryLimit: 1
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:1.14"}]' -n kruise

[root@node01 ~]# kubectl get controllerrevisions.apps -n kruise
NAME               CONTROLLER                       REVISION   AGE
nginx-7949b7b7cd   daemonset.apps.kruise.io/nginx   3          18s
nginx-9d7db5555    daemonset.apps.kruise.io/nginx   1          100s

selector

template

updateStrategy

rollingUpdate

maxSurge和maxUnavailable不能同时使用

maxSurge
数字

ads-updateStrategy-rollingUpdate-maxSurge-digital.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-kkm7z   1/1     Running   0          23m
nginx-8lw7p                               1/1     Running   0          39s
nginx-gjdwn                               1/1     Running   0          39s
nginx-tsbh5                               1/1     Running   0          39s
nginx-msdv2                               0/1     Pending   0          0s
nginx-msdv2                               0/1     Pending   0          0s
nginx-5b6kg                               0/1     Pending   0          0s
nginx-msdv2                               0/1     Pending   0          0s
nginx-5b6kg                               0/1     Pending   0          1s
nginx-5b6kg                               0/1     Pending   0          1s
nginx-msdv2                               0/1     ContainerCreating   0          1s
nginx-5b6kg                               0/1     ContainerCreating   0          1s
nginx-msdv2                               1/1     Running             0          18s
nginx-5b6kg                               1/1     Running             0          18s
nginx-gjdwn                               1/1     Terminating         0          62s
nginx-8lw7p                               1/1     Terminating         0          62s
nginx-kvf2f                               0/1     Pending             0          0s
nginx-kvf2f                               0/1     Pending             0          0s
nginx-kvf2f                               0/1     ContainerCreating   0          0s
nginx-5b6kg                               1/1     Running             0          19s
nginx-msdv2                               1/1     Running             0          19s
nginx-kvf2f                               0/1     ContainerCreating   0          0s
nginx-8lw7p                               0/1     Terminating         0          64s
nginx-gjdwn                               0/1     Terminating         0          64s
nginx-8lw7p                               0/1     Terminating         0          67s
nginx-8lw7p                               0/1     Terminating         0          67s
nginx-kvf2f                               1/1     Running             0          5s
nginx-tsbh5                               1/1     Terminating         0          68s
nginx-kvf2f                               1/1     Running             0          6s
nginx-gjdwn                               0/1     Terminating         0          70s
nginx-gjdwn                               0/1     Terminating         0          70s
百分比

ads-updateStrategy-rollingUpdate-maxSurge-percent.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 40%
      rollingUpdateType: Surging
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise


[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-kkm7z   1/1     Running   0          33m
nginx-lbx4q                               1/1     Running   0          6m18s
nginx-qpzxg                               1/1     Running   0          6m18s
nginx-xwx5p                               1/1     Running   0          6m18s
nginx-zwcm8                               0/1     Pending   0          0s
nginx-zwcm8                               0/1     Pending   0          0s
nginx-6tz6h                               0/1     Pending   0          0s
nginx-zwcm8                               0/1     Pending   0          0s
nginx-6tz6h                               0/1     Pending   0          0s
nginx-6tz6h                               0/1     Pending   0          0s
nginx-6tz6h                               0/1     ContainerCreating   0          0s
nginx-zwcm8                               0/1     ContainerCreating   0          0s
nginx-6tz6h                               1/1     Running             0          17s
nginx-xwx5p                               1/1     Terminating         0          6m39s
nginx-9z2hp                               0/1     Pending             0          0s
nginx-9z2hp                               0/1     Pending             0          0s
nginx-9z2hp                               0/1     Pending             0          0s
nginx-9z2hp                               0/1     ContainerCreating   0          0s
nginx-xwx5p                               0/1     Terminating         0          6m40s
nginx-6tz6h                               1/1     Running             0          18s
nginx-9z2hp                               1/1     Running             0          2s
nginx-qpzxg                               1/1     Terminating         0          6m41s
nginx-zwcm8                               1/1     Running             0          20s
nginx-lbx4q                               1/1     Terminating         0          6m42s
nginx-qpzxg                               0/1     Terminating         0          6m42s
nginx-9z2hp                               1/1     Running             0          3s
nginx-zwcm8                               1/1     Running             0          21s
nginx-qpzxg                               0/1     Terminating         0          6m43s
nginx-qpzxg                               0/1     Terminating         0          6m43s
maxUnavailable
数字

ads-updateStrategy-rollingUpdate-maxUnavailable-digital.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          102s
nginx-fzkl4                               1/1     Running   0          10s
nginx-gnsbv                               1/1     Running   0          10s
nginx-x66nb                               1/1     Running   0          10s
nginx-fzkl4                               1/1     Terminating   0          49s
nginx-fzkl4                               0/1     Terminating   0          50s
nginx-fzkl4                               0/1     Terminating   0          51s
nginx-fzkl4                               0/1     Terminating   0          58s
nginx-fzkl4                               0/1     Terminating   0          58s
nginx-cmvd5                               0/1     Pending       0          0s
nginx-cmvd5                               0/1     Pending       0          0s
nginx-cmvd5                               0/1     Pending       0          0s
nginx-cmvd5                               0/1     ContainerCreating   0          0s
nginx-cmvd5                               1/1     Running             0          17s
nginx-x66nb                               1/1     Terminating         0          75s
nginx-cmvd5                               1/1     Running             0          18s
nginx-x66nb                               0/1     Terminating         0          76s
nginx-x66nb                               0/1     Terminating         0          83s
nginx-x66nb                               0/1     Terminating         0          83s
nginx-wrtts                               0/1     Pending             0          0s
nginx-wrtts                               0/1     Pending             0          0s
nginx-wrtts                               0/1     Pending             0          0s
nginx-wrtts                               0/1     ContainerCreating   0          0s
nginx-wrtts                               1/1     Running             0          1s
nginx-gnsbv                               1/1     Terminating         0          84s
nginx-wrtts                               1/1     Running             0          2s
nginx-gnsbv                               0/1     Terminating         0          85s
nginx-gnsbv                               0/1     Terminating         0          93s
nginx-gnsbv                               0/1     Terminating         0          93s
nginx-ckj8z                               0/1     Pending             0          0s
nginx-ckj8z                               0/1     Pending             0          0s
nginx-ckj8z                               0/1     Pending             0          0s
nginx-ckj8z                               0/1     ContainerCreating   0          0s

ads-updateStrategy-rollingUpdate-maxUnavailable-digital-inplaceifpossible.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 1
      rollingUpdateType: InPlaceIfPossible
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          4m25s
nginx-5pcjp                               1/1     Running   0          12s
nginx-92r8n                               1/1     Running   0          12s
nginx-vh98x                               1/1     Running   0          12s
nginx-5pcjp                               1/1     Running   0          42s
nginx-5pcjp                               1/1     Running   0          42s
nginx-5pcjp                               1/1     Running   0          42s
nginx-5pcjp                               1/1     Running   1          44s
nginx-5pcjp                               1/1     Running   1          44s
nginx-5pcjp                               1/1     Running   1          45s
nginx-5pcjp                               1/1     Running   1          46s
nginx-92r8n                               1/1     Running   0          46s
nginx-92r8n                               1/1     Running   0          46s
nginx-92r8n                               1/1     Running   0          46s
nginx-92r8n                               1/1     Running   1          47s
nginx-92r8n                               1/1     Running   1          47s
nginx-92r8n                               1/1     Running   1          48s
nginx-92r8n                               1/1     Running   1          49s
nginx-vh98x                               1/1     Running   0          49s
nginx-vh98x                               1/1     Running   0          50s
nginx-vh98x                               1/1     Running   0          50s
nginx-vh98x                               1/1     Running   1          51s
nginx-vh98x                               1/1     Running   1          51s
nginx-vh98x                               1/1     Running   1          52s
nginx-vh98x                               1/1     Running   1          53s
百分比

rollingUpdateType: Surging时不能设置maxUnavailable

ads-updateStrategy-rollingUpdate-maxUnavailable-percent.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 20%
      rollingUpdateType: Surging
Error from server: error when creating "ads-updateStrategy-rollingUpdate-maxUnavailable-percent.yaml": admission webhook "vdaemonset.kb.io" denied the request: spec.updateStrategy.rollingUpdate.maxSurge: Invalid value: intstr.IntOrString{Type:0, IntVal:1, StrVal:""}: may not be set when maxUnavailable is non-zero

ads-updateStrategy-rollingUpdate-maxUnavailable-percent-standard.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 20%
      rollingUpdateType: Standard
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          12m
nginx-dmstk                               1/1     Running   0          28s
nginx-ks95s                               1/1     Running   0          28s
nginx-r5rwm                               1/1     Running   0          28s
nginx-ks95s                               1/1     Terminating   0          32s
nginx-ks95s                               0/1     Terminating   0          33s
nginx-ks95s                               0/1     Terminating   0          34s
nginx-ks95s                               0/1     Terminating   0          34s
nginx-4s7r4                               0/1     Pending       0          0s
nginx-4s7r4                               0/1     Pending       0          0s
nginx-4s7r4                               0/1     Pending       0          0s
nginx-4s7r4                               0/1     ContainerCreating   0          0s
nginx-4s7r4                               1/1     Running             0          16s
nginx-dmstk                               1/1     Terminating         0          50s
nginx-4s7r4                               1/1     Running             0          17s
nginx-dmstk                               0/1     Terminating         0          51s
nginx-dmstk                               0/1     Terminating         0          52s
nginx-dmstk                               0/1     Terminating         0          52s
nginx-mnhnv                               0/1     Pending             0          0s
nginx-mnhnv                               0/1     Pending             0          0s
nginx-mnhnv                               0/1     ContainerCreating   0          0s
nginx-mnhnv                               0/1     ContainerCreating   0          0s
nginx-mnhnv                               1/1     Running             0          2s
nginx-r5rwm                               1/1     Terminating         0          54s
nginx-mnhnv                               1/1     Running             0          3s
nginx-r5rwm                               0/1     Terminating         0          55s
nginx-r5rwm                               0/1     Terminating         0          67s
nginx-r5rwm                               0/1     Terminating         0          67s
nginx-nwrs4                               0/1     Pending             0          0s
nginx-nwrs4                               0/1     Pending             0          0s
nginx-nwrs4                               0/1     Pending             0          0s
nginx-nwrs4                               0/1     ContainerCreating   0          0s
nginx-nwrs4                               1/1     Running             0          16s
nginx-nwrs4                               1/1     Running             0          17s
partition

cloneset partition可以是数字或百分比,adv statefulset和adv daemonset只能是数字

ads-updateStrategy-rollingUpdate-partition.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        env:
        - name: test
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['test']
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 20%
      partition: 2
      rollingUpdateType: InPlaceIfPossible
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/metadata/labels/test", "value":"test2"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          44m
nginx-87kvs                               1/1     Running   0          14s
nginx-jqzjd                               1/1     Running   0          14s
nginx-s228t                               1/1     Running   0          14s
nginx-jqzjd                               1/1     Running   0          50s
nginx-jqzjd                               1/1     Running   0          50s
nginx-jqzjd                               1/1     Running   0          50s
nginx-jqzjd                               0/1     Completed   0          54s
nginx-jqzjd                               1/1     Running     1          55s
nginx-jqzjd                               1/1     Running     1          55s
nginx-jqzjd                               1/1     Running     1          55s
nginx-jqzjd                               1/1     Running     1          57s
paused

ads-updateStrategy-rollingUpdate-paused.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        env:
        - name: test
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['test']
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 20%
      partition: 2
      paused: true
      rollingUpdateType: InPlaceIfPossible
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/metadata/labels/test", "value":"test2"}]' -n kruise

kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/updateStrategy/rollingUpdate/paused", "value":false}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          48m
nginx-kk6x4                               1/1     Running   0          19s
nginx-t2275                               1/1     Running   0          19s
nginx-tj54p                               1/1     Running   0          19s
nginx-t2275                               1/1     Running   0          53s
nginx-t2275                               1/1     Running   0          53s
nginx-t2275                               1/1     Running   0          53s
nginx-t2275                               0/1     Completed   0          57s
nginx-t2275                               1/1     Running     1          58s
nginx-t2275                               1/1     Running     1          58s
nginx-t2275                               1/1     Running     1          58s
nginx-t2275                               1/1     Running     1          60s
rollingUpdateType
Standard

ads-updateStrategy-rollingUpdate-rollingUpdateType.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      selector:
        matchLabels:
          nodeType: canary
      rollingUpdateType: Standard
kubectl label node 192.168.229.128 nodeType=canary
kubectl label node 192.168.229.129 nodeType=canary

kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w -owide
NAME                                      READY   STATUS    RESTARTS   AGE   IP             NODE              NOMINATED NODE   READINESS GATES
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          60m   172.20.0.133   192.168.229.128   <none>           <none>
nginx-2hq88                               1/1     Running   0          3s    172.20.1.247   192.168.229.129   <none>           1/1
nginx-9fz76                               1/1     Running   0          3s    172.20.0.143   192.168.229.128   <none>           1/1
nginx-xr945                               1/1     Running   0          3s    172.20.2.103   192.168.229.130   <none>           1/1
nginx-2hq88                               1/1     Terminating   0          10s   172.20.1.247   192.168.229.129   <none>           1/1
nginx-2hq88                               0/1     Terminating   0          11s   172.20.1.247   192.168.229.129   <none>           1/1
nginx-2hq88                               0/1     Terminating   0          20s   172.20.1.247   192.168.229.129   <none>           1/1
nginx-2hq88                               0/1     Terminating   0          20s   172.20.1.247   192.168.229.129   <none>           1/1
nginx-r6nbx                               0/1     Pending       0          0s    <none>         <none>            <none>           0/1
nginx-r6nbx                               0/1     Pending       0          0s    <none>         <none>            <none>           1/1
nginx-r6nbx                               0/1     Pending       0          0s    <none>         192.168.229.129   <none>           1/1
nginx-r6nbx                               0/1     ContainerCreating   0          0s    <none>         192.168.229.129   <none>           1/1
nginx-r6nbx                               1/1     Running             0          16s   172.20.1.248   192.168.229.129   <none>           1/1
nginx-9fz76                               1/1     Terminating         0          36s   172.20.0.143   192.168.229.128   <none>           1/1
nginx-r6nbx                               1/1     Running             0          17s   172.20.1.248   192.168.229.129   <none>           1/1
nginx-9fz76                               0/1     Terminating         0          37s   172.20.0.143   192.168.229.128   <none>           1/1
nginx-9fz76                               0/1     Terminating         0          38s   172.20.0.143   192.168.229.128   <none>           1/1
nginx-9fz76                               0/1     Terminating         0          38s   172.20.0.143   192.168.229.128   <none>           1/1
nginx-n584w                               0/1     Pending             0          0s    <none>         <none>            <none>           0/1
nginx-n584w                               0/1     Pending             0          0s    <none>         192.168.229.128   <none>           0/1
nginx-n584w                               0/1     ContainerCreating   0          0s    <none>         192.168.229.128   <none>           0/1
nginx-n584w                               0/1     ContainerCreating   0          0s    <none>         192.168.229.128   <none>           1/1
nginx-n584w                               1/1     Running             0          16s   172.20.0.144   192.168.229.128   <none>           1/1
nginx-n584w                               1/1     Running             0          17s   172.20.0.144   192.168.229.128   <none>           1/1
Surging

ads-updateStrategy-rollingUpdate-rollingUpdateType-Surging.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 3
      partition: 2
      rollingUpdateType: Surging
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          64m
nginx-c58rv                               1/1     Running   0          6s
nginx-gdxhh                               1/1     Running   0          6s
nginx-ngwl2                               1/1     Running   0          6s
nginx-bt6j6                               0/1     Pending   0          0s
nginx-bt6j6                               0/1     Pending   0          0s
nginx-bt6j6                               0/1     Pending   0          0s
nginx-bt6j6                               0/1     ContainerCreating   0          0s
nginx-bt6j6                               1/1     Running             0          2s
nginx-gdxhh                               1/1     Terminating         0          28s
nginx-bt6j6                               1/1     Running             0          3s
nginx-gdxhh                               0/1     Terminating         0          30s
nginx-gdxhh                               0/1     Terminating         0          36s
nginx-gdxhh                               0/1     Terminating         0          36s
InPlaceIfPossible

ads-updateStrategy-rollingUpdate-rollingUpdateType-InPlaceIfPossible.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 3
      partition: 1
      rollingUpdateType: InPlaceIfPossible
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          68m
nginx-4zl4n                               1/1     Running   0          5s
nginx-qjl5s                               1/1     Running   0          5s
nginx-qzc49                               1/1     Running   0          5s
nginx-qjl5s                               1/1     Running   0          15s
nginx-qzc49                               1/1     Running   0          15s
nginx-qjl5s                               1/1     Running   0          15s
nginx-qzc49                               1/1     Running   0          15s
nginx-qzc49                               1/1     Running   0          15s
nginx-qjl5s                               1/1     Running   0          15s
nginx-qzc49                               1/1     Running   1          16s
nginx-qzc49                               1/1     Running   1          16s
nginx-qjl5s                               1/1     Running   1          17s
nginx-qjl5s                               1/1     Running   1          17s
nginx-qzc49                               1/1     Running   1          17s
nginx-qjl5s                               1/1     Running   1          18s
nginx-qzc49                               1/1     Running   1          18s
nginx-qjl5s                               1/1     Running   1          19s
selector

ads-updateStrategy-rollingUpdate-selector.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        env:
        - name: test
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['test']
  updateStrategy:
    type: RollingUpdate
    rollingUpdate:
      selector:
        matchLabels:
          nodeType: canary
      partition: 2
      maxUnavailable: 3
      rollingUpdateType: InPlaceIfPossible
kubectl label node 192.168.229.128 nodeType=canary --overwrite
kubectl label node 192.168.229.129 nodeType=canary --overwrite

kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/metadata/labels/test", "value":"test2"}]' -n kruise

[root@node01 ~]# kubectl get pod -n kruise -w 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          73m
nginx-bxkvs                               1/1     Running   0          4s
nginx-l48jb                               1/1     Running   0          4s
nginx-s4259                               1/1     Running   0          4s
nginx-s4259                               1/1     Running   0          8s
nginx-s4259                               1/1     Running   0          8s
nginx-s4259                               1/1     Running   0          8s
nginx-s4259                               0/1     Completed   0          13s
nginx-s4259                               1/1     Running     1          14s
nginx-s4259                               1/1     Running     1          14s
nginx-s4259                               1/1     Running     1          14s
nginx-s4259                               1/1     Running     1          16s

type

RollingUpdate

OnDelete

ads-updateStrategy-type-OnDelete.yaml

apiVersion: apps.kruise.io/v1alpha1
kind: DaemonSet
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
        test: test
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        env:
        - name: test
          valueFrom:
            fieldRef:
              fieldPath: metadata.labels['test']
  updateStrategy:
    type: OnDelete
kubectl patch ads nginx --type='json'  -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/image", "value":"nginx:latest"}]' -n kruise

kubectl delete pod -n kruise nginx-bj4x5

[root@node01 ~]# kubectl get pod -n kruise -w 
NAME                                      READY   STATUS    RESTARTS   AGE
nfs-client-provisioner-69557bfdb8-hzplg   1/1     Running   0          77m
nginx-89hqj                               1/1     Running   0          60s
nginx-bj4x5                               1/1     Running   0          60s
nginx-r8p7n                               1/1     Running   0          60s
nginx-bj4x5                               1/1     Terminating   0          63s
nginx-bj4x5                               0/1     Terminating   0          64s
nginx-bj4x5                               0/1     Terminating   0          65s
nginx-bj4x5                               0/1     Terminating   0          65s
nginx-q4rmt                               0/1     Pending       0          0s
nginx-q4rmt                               0/1     Pending       0          0s
nginx-q4rmt                               0/1     Pending       0          0s
nginx-q4rmt                               0/1     ContainerCreating   0          0s
nginx-q4rmt                               1/1     Running             0          16s
nginx-q4rmt                               1/1     Running             0          17s