Kubernetes笔记(六):了解控制器 —— Deployment

2023-11-20

Pod(容器组)是 Kubernetes 中最小的调度单元,可以通过 yaml 定义文件直接创建一个 Pod。但 Pod 本身并不具备自我恢复(self-healing)功能。如果一个 Pod 所在的节点出现故障,或者调度程序自身出现问题,以及节点资源不够或节点进入维护而驱逐 Pod 时,Pod 将被删除,且不能自我恢复。

因此,Kubernetes 中我们一般不直接创建 Pod, 而是通过 Controller(控制器)来管理 Pod。

Controller

Controller 能为 Pod 提供如下特性:

  • 水平扩展,控制 Pod 运行的副本数
  • rollout,即版本更新
  • self-healing,即自我恢复。当节点出现故障时,控制器可以自动地在另一个节点调度一个配置完全一样的 Pod,以替换故障节点上的 Pod。

Kubernetes 中支持的控制器包括:

  • ReplicationController:用来维护一个数量稳定的 Pod 副本集合的控制器
  • ReplicaSet:是 ReplicationController 的升级版,比 ReplicationController 多一个特性:支持基于集合的选择器。 不支持滚动更新(RollingUpdate)
  • Deployment:包含了 ReplicaSet,可通过声明式、滚动更新的方式更新 ReplicaSet 及其 Pod。对于无状态应用,推荐使用 Deployment 部署
  • StatefulSet:用于管理有状态的应用程序
  • DaemonSet:在节点上以守护进程的方式运行一个指定的 Pod 副本,例如监控节点、收集节点上的日志时,可使用 DaemonSet
  • CronJob:按照预定的时间计划创建 Job,类似于 linux 的crontab
  • Job:使用 Job 执行任务,执行完后结束

ReplicaSet

Kubernetes 中,虽然一般使用 Deployment 来管理 Pod, 但 Deployment 中也是通过 ReplicaSet 来维护 Pod 的副本集合的,因此此处也对 ReplicaSet 进行简单介绍。

在 ReplicaSet 的定义中,包含三部分:

  1. selector: 标签选择器,用于指定哪些 Pod 归该 ReplicaSet 管理,通过 matchLabels 来与 Pod 的 label 匹配。
  2. replicas: 期望的 Pod 副本数,指定该 ReplicaSet 应该维持多少个 Pod 副本,默认为1。
  3. template: Pod 定义模板,ReplicaSet 使用该模板的定义来创建 Pod。

ReplicaSet 的示例定义文档如下所示,

apiVersion: apps/v1  # api版本
kind: ReplicaSet     # 资源类型
metadata:            # 元数据定义
  name: nginx-ds     # ReplicaSet 名称
spec:
  replicas: 2        # Pod 副本数量,默认1
  selector:          # 标签选择器
     matchLabels:
      app: nginx
  template:          # Pod 定义模板
    metadata:        # Pod 元数据定义
      labels:
        app: nginx   # Pod 标签
    spec:
      containers:    # 容器定义
      - name: nginx
        image: nginx

ReplicaSet 通过创建、删除 Pod 容器组来确保符合 selector 选择器的 Pod 数量等于 replicas 指定的数量。 ReplicaSet 创建的 Pod 中,都有一个字段 metadata.ownerReferences 用于标识该 Pod 从属于哪一个 ReplicaSet。可通过 kubectl get pod pod-name -o yaml 来查看 Pod 的 ownerReference。

ReplicaSet 通过 selector 字段的定义,识别哪些 Pod 应该由其管理, 不论该 Pod 是否由该 ReplicaSet 创建,即只要 selector 匹配, 通过外部定义创建的 Pod 也会被该 ReplicaSet 管理。因此需要注意 .spec.selector.matchLabels.spec.template.metadata.labels 的定义一致, 且避免与其他控制器的 selector 重合,造成混乱。

ReplicaSet 不支持滚动更新,所以对于无状态应用,一般使用 Deployment来部署, 而不直接使用 ReplicaSet。ReplicaSet 主要是被用作 Deployment 中负责 Pod 创建、删除、更新的一种手段。

Deployment

Deployment 对象包含 ReplicaSet 作为从属对象,并且可通过声明式、滚动更新的方式来更新 ReplicaSet 及其 Pod。ReplicaSet 现在主要是被用作 Deployment 中负责 Pod 创建、删除、更新的一种手段。使用 Deployment 时,无需关心由 Deployment 创建的 ReplicaSet,Deployment 将处理所有与之相关的细节。同时,Deployment 还能以“声明式”的方式管理 Pod 和 ReplicaSet (其本质是将一些特定场景的一系列运维步骤固化下来,以便快速准确无误的执行),并提供版本(revision)回退功能。

Deployment 定义示例,

apiVersion: apps/v1
kind: Deployment        # 对象类型,固定为 Deployment
metadata:
  name: nginx-deploy    # Deployment 名称
  namespace: default    # 命名空间,默认为 default
  labels:
    app: nginx          # 标签
spec:
  replicas: 4           # Pod 副本数,默认1
  strategy:  
    rollingUpdate:      # 升级策略为滚动升级,由于replicas为4,则整个升级过程pod个数在3-5个之间
      maxSurge: 1       # 滚动升级时超过 replicas 的最大 pod 数,也可以为百分比(replicas的百分比),默认为1
      maxUnavailable: 1 # 滚动升级时不可用的最大 pod 数,也可为百分比(replicas的百分比),默认为1
  selector:             # 标签选择器,通过标签选择该 Deployment 管理的 Pod
    matchLabels:
      app: nginx
  template:             # Pod 定义模板
    metadata:
      labels:
        app: nginx      # Pod 标签
    spec:               # 定义容器模板,可以包含多个容器
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80

可通过 kubectl explain xxx 来查看支持哪些配置选项,

# 查看 deployment 配置项
[root@kmaster ~]# kubectl explain deployment
...

# 查看 deployment.spec 模块的配置项
[root@kmaster ~]# kubectl explain deployment.spec
KIND:     Deployment
VERSION:  apps/v1

RESOURCE: spec <Object>

DESCRIPTION:
     Specification of the desired behavior of the Deployment.

     DeploymentSpec is the specification of the desired behavior of the
     Deployment.

FIELDS:
   minReadySeconds    <integer>
     Minimum number of seconds for which a newly created pod should be ready
     without any of its container crashing, for it to be considered available.
     Defaults to 0 (pod will be considered available as soon as it is ready)

   paused    <boolean>
     Indicates that the deployment is paused.

   progressDeadlineSeconds    <integer>
     The maximum time in seconds for a deployment to make progress before it is
     considered to be failed. The deployment controller will continue to process
     failed deployments and a condition with a ProgressDeadlineExceeded reason
     will be surfaced in the deployment status. Note that progress will not be
     estimated during the time a deployment is paused. Defaults to 600s.

   replicas    <integer>
     Number of desired pods. This is a pointer to distinguish between explicit
     zero and not specified. Defaults to 1.

   revisionHistoryLimit    <integer>
     The number of old ReplicaSets to retain to allow rollback. This is a
     pointer to distinguish between explicit zero and not specified. Defaults to
     10.

   selector    <Object> -required-
     Label selector for pods. Existing ReplicaSets whose pods are selected by
     this will be the ones affected by this deployment. It must match the pod
     template's labels.

   strategy    <Object>
     The deployment strategy to use to replace existing pods with new ones.

   template    <Object> -required-

其它配置项说明:

  • .spec.minReadySeconds:用来控制应用升级的速度。升级过程中,新创建的 Pod 一旦成功响应了就绪探测即被认为是可用状态,然后进行下一轮的替换。 .spec.minReadySeconds 定义了在新的 Pod 对象创建后至少需要等待多长的时间才能会被认为其就绪,在该段时间内,更新操作会被阻塞。
  • .spec.progressDeadlineSeconds:用来指定在系统报告 Deployment 失败 —— 表现为状态中的 type=Progressing、Status=False、 Reason=ProgressDeadlineExceeded 前可以等待的 Deployment 进行的秒数。Deployment controller 会继续重试该 Deployment。如果设置该参数,该值必须大于 .spec.minReadySeconds
  • .spec.revisionHistoryLimit:用来指定可以保留的旧的 ReplicaSet 或 revision(版本) 的数量。默认所有旧的 Replicaset 都会被保留。如果删除了一个旧的 RepelicaSet,则 Deployment 将无法再回退到那个 revison。如果将该值设置为0,所有具有0个 Pod 副本的 ReplicaSet 都会被删除,这时候 Deployment 将无法回退,因为 revision history 都被清理掉了。

1. 创建

[root@kmaster test]# kubectl apply -f nginx-deploy.yaml --record

--record 会将此次命令写入 Deployment 的 kubernetes.io/change-cause 注解中。可在后面查看某一个 Deployment 版本变化的原因。

2. 查看

创建 Deployment 后,Deployment 控制器将立刻创建一个 ReplicaSet,并由 ReplicaSet 创建所需要的 Pod。

# 查看 Deployment
[root@kmaster test]# kubectl get deploy
NAME           READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deploy   0/2     2            0           64s

# 查看 ReplicaSet
[root@kmaster test]# kubectl get rs
NAME                     DESIRED   CURRENT   READY   AGE
nginx-deploy-59c9f8dff   2         2         1       2m16s

# 查看 Pod,显示调度的节点,及标签
[root@kmaster test]# kubectl get pod -o wide --show-labels
NAME                           READY   STATUS      RESTARTS   AGE     IP            NODE     NOMINATED NODE   READINESS GATES   LABELS
nginx-deploy-59c9f8dff-47bgd   1/1     Running     0          5m14s   10.244.1.91   knode2   <none>           <none>            app=nginx,pod-template-hash=59c9f8dff
nginx-deploy-59c9f8dff-q4zb8   1/1     Running     0          5m14s   10.244.3.47   knode3   <none>           <none>            app=nginx,pod-template-hash=59c9f8dff

pod-template-hash 标签是 Deployment 创建 ReplicaSet 时添加到 ReplicaSet 上的,ReplicaSet 进而将此标签添加到 Pod 上。这个标签用于区分 Deployment 中哪个 ReplicaSet 创建了哪些 Pod。该标签的值是 .spec.template 的 hash 值,不要去修改这个标签。由上可看出 ReplicaSet、 Pod 的命名分别遵循 <Deployment-name>-<Pod-template-hash><Deployment-name>-<Pod-template-hash>-xxx 的格式。

3. 发布更新(rollout)

当且仅当 Deployment 的 Pod template(.spec.template)字段中的内容发生变更时(例如标签或容器的镜像被改变),Deployment 的发布更新(rollout)才会被触发。Deployment 中其他字段的变化(例如修改 .spec.replicas 字段)将不会触发 Deployment 的发布更新。

更新 Deployment 中 Pod 的定义(例如,发布新版本的容器镜像)。此时 Deployment 控制器将为该 Deployment 创建一个新的 ReplicaSet,并且逐步在新的 ReplicaSet 中创建 Pod,在旧的 ReplicaSet 中删除 Pod,以达到滚动更新的效果。

比如我们将上面 Deployment 的容器镜像进行修改,

# 方式一:直接使用 kubectl 命令设置修改 
[root@kmaster ~]# kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record
deployment.apps/nginx-deploy image updated

# 方式二:使用 kubectl edit 编辑yaml修改
[root@kmaster ~]# kubectl edit deploy nginx-deploy

查看发布更新(rollout)的状态

[root@kmaster ~]# kubectl rollout status deploy nginx-deploy
Waiting for deployment "nginx-deploy" rollout to finish: 2 out of 4 new replicas have been updated...

查看 ReplicaSet,

[root@kmaster ~]# kubectl get rs
NAME                     DESIRED   CURRENT   READY   AGE
nginx-deploy-59c9f8dff   1         1         1       3d6h
nginx-deploy-d47dbbb7c   4         4         2       3m41s

我们可以看到 Deployment 的更新是通过创建一个新的4个副本的 ReplicaSet,并同时将旧的 ReplicaSet 的副本数缩容到0个副本来达成的。

因为前面我们将 maxSurge, 与 maxUnavailable 都设置为了1, 因此在更新的过程中,任何时刻两个 ReplicaSet 的 Pod 数至多为5个(4 replicas +1 maxSurge),且可用的 Pod 数至少为3个(4 replicas - 1 maxUnavailable)。

使用 kubectl describe 命令查看 Deployment 的事件部分,如下所示

[root@kmaster ~]# kubectl describe deploy nginx-deploy
...

Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  12m    deployment-controller  Scaled up replica set nginx-deploy-d47dbbb7c to 1
  Normal  ScalingReplicaSet  12m    deployment-controller  Scaled down replica set nginx-deploy-59c9f8dff to 3
  Normal  ScalingReplicaSet  12m    deployment-controller  Scaled up replica set nginx-deploy-d47dbbb7c to 2
  Normal  ScalingReplicaSet  10m    deployment-controller  Scaled down replica set nginx-deploy-59c9f8dff to 2
  Normal  ScalingReplicaSet  10m    deployment-controller  Scaled up replica set nginx-deploy-d47dbbb7c to 3
  Normal  ScalingReplicaSet  8m56s  deployment-controller  Scaled down replica set nginx-deploy-59c9f8dff to 1
  Normal  ScalingReplicaSet  8m56s  deployment-controller  Scaled up replica set nginx-deploy-d47dbbb7c to 4
  Normal  ScalingReplicaSet  5m55s  deployment-controller  Scaled down replica set nginx-deploy-59c9f8dff to 0

当更新了 Deployment 的 Pod Template 时,Deployment Controller 会创建一个新的 ReplicaSet (nginx-deploy-d47dbbb7c) ,并将其 scale up 到 1 个副本,同时将旧的 ReplicaSet(nginx-deploy-59c9f8dff) scale down 到3个副本。接下来 Deployment Controller 继续 scale up 新的 ReplicaSet 并 scale down 旧的 ReplicaSet,直到新的 ReplicaSet 拥有 replicas 个数的 Pod, 旧的 ReplicaSet Pod 数缩放到0。这个过程称为 rollout(发布更新)。

通过 .spec.strategy 字段,可以指定更新策略,除了上述使用的 RollingUpdate(滚动更新),另一个可取的值为 Recreate(重新创建)。选择重新创建,Deployment 将先删除原有 ReplicaSet 中的所有 Pod,然后再创建新的 ReplicaSet 和新的 Pod,更新过程中将出现一段应用程序不可用的情况。因此,线上环境一般使用 RollingUpdate。

4. 回滚

默认情况下,kubernetes 将保存 Deployment 的所有更新(rollout)历史。可以通过设定 revision history limit(.spec.revisionHistoryLimit 配置项)来指定保存的历史版本数量。

当且仅当 Deployment 的 .spec.template 字段被修改时(例如修改容器的镜像),kubernetes 才为其创建一个 Deployment revision(版本)。Deployment 的其他更新(例如:修改 .spec.replicas 字段)将不会创建新的 Deployment revision(版本)。

查看 Deployment 的 revision,

[root@kmaster ~]# kubectl rollout history deploy nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=nginx-deploy.yaml --record=true
2         kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record=true

如果前面更新 Deployment 时没有添加 --record=true,则此处 CHANGE-CAUSE 将为空。

我们通过将镜像修改为一个不存在的版本来模拟一次失败的更新,并回滚到前一个版本的场景,

# 1. 修改镜像版本到一个不存在的值
[root@kmaster ~]# kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record
deployment.apps/nginx-deploy image updated

# 2. 查看 ReplicaSet
[root@kmaster ~]# kubectl  get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58f69cfc57   2         2         0       2m7s
nginx-deploy-59c9f8dff    0         0         0       3d7h
nginx-deploy-d47dbbb7c    3         3         3       81m

# 3. 查看 Pod 状态
[root@kmaster ~]# kubect get pod
NAME                            READY   STATUS              RESTARTS   AGE
nginx-deploy-58f69cfc57-5968g   0/1     ContainerCreating   0          42s
nginx-deploy-58f69cfc57-tk7c5   0/1     ErrImagePull        0          42s
nginx-deploy-d47dbbb7c-2chgx    1/1     Running             0          77m
nginx-deploy-d47dbbb7c-8fcb9    1/1     Running             0          80m
nginx-deploy-d47dbbb7c-gnwjj    1/1     Running             0          78m

# 4. 查看 Deployment 详情
[root@kmaster ~]# kubectl describe deploy nginx-deploy
...
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set nginx-deploy-58f69cfc57 to 1
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled down replica set nginx-deploy-d47dbbb7c to 3
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set nginx-deploy-58f69cfc57 to 2

# 5. 查看 Deployment 的历史版本
[root@kmaster ~]# kubectl rollout history deploy nginx-deploy
deployment.apps/nginx-deploy 
REVISION  CHANGE-CAUSE
1         kubectl apply --filename=nginx-deploy.yaml --record=true
2         kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record=true
3         kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record=true

# 6. 查看某个版本的详情
[root@kmaster ~]# kubectl rollout history deploy nginx-deploy --revision=3
deployment.apps/nginx-deploy with revision #3
Pod Template:
  Labels:    app=nginx
    pod-template-hash=58f69cfc57
  Annotations:    kubernetes.io/change-cause: kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record=true
  Containers:
   nginx:
    Image:    nginx:1.161
    Port:    80/TCP
    Host Port:    0/TCP
    Environment:    <none>
    Mounts:    <none>
  Volumes:    <none>

# 7. 回滚到前一个版本
[root@kmaster ~]# kubectl rollout undo deploy nginx-deploy
deployment.apps/nginx-deploy rolled back

# 8. 回滚到指定的版本
[root@kmaster ~]# kubectl rollout undo deploy nginx-deploy --to-revision=1
deployment.apps/nginx-deploy rolled back

# 9. 查看历史版本信息
[root@kmaster ~]# kubectl rollout history deploy nginx-deploy
deployment.apps/nginx-deploy 
REVISION  CHANGE-CAUSE
3         kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record=true
4         kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record=true
5         kubectl apply --filename=nginx-deploy.yaml --record=true

通过 kubectl rollout undo 命令可回滚到上一个版本或指定的版本,上述示例也可看出,回滚到历史版本,会将历史版本的序号设置为最新序号。如前所述,我们可以通过设置 Deployment 的 .spec.revisionHistoryLimit 来指定保留多少个旧的 ReplicaSet(或 revision),超出该数字的将在后台进行垃圾回收。如果该字段被设为 0,Kubernetes 将清理掉该 Deployment 的所有历史版本(revision),此时,将无法对该 Deployment 执行回滚操作了。

5. 伸缩

可以通过 kubectl scale 命令或 kubectl edit 修改定义的方式来对 Deployment 进行伸缩,增加或减少 Pod 的副本数,

# 将 Pod 数缩放到2个
[root@kmaster ~]# kubectl scale deploy nginx-deploy --replicas=2
deployment.apps/nginx-deploy scaled

# 查看 Pod
[root@kmaster ~]# kubectl  get pod
NAME                           READY   STATUS        RESTARTS   AGE
nginx-deploy-59c9f8dff-7bpjp   1/1     Running       0          9m48s
nginx-deploy-59c9f8dff-tpxzf   0/1     Terminating   0          8m57s
nginx-deploy-59c9f8dff-v8fgz   0/1     Terminating   0          10m
nginx-deploy-59c9f8dff-w8s9z   1/1     Running       0          10m

# 查看 ReplicaSet,DESIRED 变为2了
[root@kmaster ~]# kubectl get rs
NAME                      DESIRED   CURRENT   READY   AGE
nginx-deploy-58f69cfc57   0         0         0       22m
nginx-deploy-59c9f8dff    2         2         2       3d8h
nginx-deploy-d47dbbb7c    0         0         0       102m

6. 自动伸缩(HPA)

如果集群启用了自动伸缩(HPA —— Horizontal Pod Autoscaling),则可以基于 CPU、 内存的使用率在一个最大和最小的区间对 Deployment 实现自动伸缩,

# 创建一个 HPA
[root@kmaster ~]# kubectl autoscale deploy nginx-deploy --min=2 --max=4 --cpu-percent=80
horizontalpodautoscaler.autoscaling/nginx-deploy autoscaled

# 查看 HPA
[root@kmaster ~]# kubectl get hpa
NAME           REFERENCE                 TARGETS         MINPODS   MAXPODS   REPLICAS   AGE
nginx-deploy   Deployment/nginx-deploy   <unknown>/80%   2         4         2          16s

# 删除 HPA
[root@kmaster ~]# kubectl delete hpa nginx-deploy
horizontalpodautoscaler.autoscaling "nginx-deploy" deleted

7. 暂停与恢复

我们可以将一个 Deployment 暂停(pause),然后在它上面做一个或多个更新,此时 Deployment 并不会触发更新,只有再恢复(resume)该 Deployment,才会执行该时间段内的所有更新。这种做法可以在暂停和恢复中间对 Deployment 做多次更新,而不会触发不必要的滚动更新。

# 1. 暂停 Deployment
[root@kmaster ~]# kubectl rollout pause deploy nginx-deploy
deployment.apps/nginx-deploy paused

# 2. 更新容器镜像
[root@kmaster ~]# kubectl set image deploy nginx-deploy nginx=nginx:1.9.1 --record
deployment.apps/nginx-deploy image updated

# 3. 查看版本历史, 此时并没有触发更新
[root@kmaster ~]# kubectl rollout history deploy nginx-deploy
deployment.apps/nginx-deploy 
REVISION  CHANGE-CAUSE
3         kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record=true
4         kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record=true
5         kubectl apply --filename=nginx-deploy.yaml --record=true

# 4. 更新 Resource 限制,同样并不会触发更新
[root@kmaster ~]# kubectl set resources deploy nginx-deploy -c=nginx --limits=memory=512Mi,cpu=500m
deployment.apps/nginx-deploy resource requirements updated


# 5. 查看修改,Pod 定义已被更新
[root@kmaster ~]# kubectl describe deploy nginx-deploy
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:      nginx:1.9.1
    Port:       80/TCP
    Host Port:  0/TCP
    Limits:
      cpu:        500m
      memory:     512Mi

# 6. 恢复 Deployment
[root@kmaster ~]# kubectl rollout resume deploy nginx-deploy
deployment.apps/nginx-deploy resumed


# 7. 查看版本历史,可见两次修改只做了一次 rollout
[root@kmaster ~]# kubectl rollout history deploy nginx-deploy
deployment.apps/nginx-deploy
REVISION  CHANGE-CAUSE
3         kubectl set image deploy nginx-deploy nginx=nginx:1.161 --record=true
4         kubectl set image deploy nginx-deploy nginx=nginx:1.16.1 --record=true
5         kubectl apply --filename=nginx-deploy.yaml --record=true
6         kubectl set image deploy nginx-deploy nginx=nginx:1.9.1 --record=true

在更新容器镜像时,因为 Deployment 处于暂停状态,所以并不会生成新的版本(Revision),当 Deployment 恢复时,才将这段时间的更新生效,执行滚动更新,生成新的版本。在暂停中的 Deployment 上做的更新, 因为没有生成版本,因此也不能回滚(rollback)。也不能对处于暂停状态的 Deployment 执行回滚操作,只有在恢复(Resume)之后才能执行回滚操作。

8. 金丝雀发布

金丝雀发布也叫灰度发布。当我们需要发布新版本时,可以针对新版本新建一个 Deployment,与旧版本的 Deployment 同时挂在一个 Service 下(通过 label match), 通过 Service 的负载均衡将用户请求流量分发到新版 Deployment 的 Pod 上,观察新版运行情况,如果没有问题再将旧版 Deployment 的版本更新到新版完成滚动更新,最后删除新建的 Deployment。很明显这种金丝雀发布具有一定的局限性,无法根据用户或地域来分流,如果要更充分地实现金丝雀发布,则可能需要引入 Istio 等。

金丝雀发布名称的由来: 以前,旷工在下矿洞时面临的一个重要危险是矿井中的毒气,他们想到一个办法来辨别矿井中是否有毒气,矿工们随身携带一只金丝雀下矿井,金丝雀对毒气的抵抗能力比人类要弱,在毒气环境下会先挂掉从而起到预警的作用。它背后的原理是:用较小的代价试错,即使出现了严重的错误(出现了毒气),系统总体的损失也是可承受的或者是非常小的(失去了一只金丝雀)。

总结

Kubernetes 中最小的调度单元是 Pod, 负载创建 Pod 并控制其按一定的副本数运行的是 ReplicaSet, 而 Deployment 可以以“声明式”的方式来管理 Pod 和 ReplicaSet,并提供滚动更新与版本(revision)回退功能。所以,一般使用 Deployment 来部署应用, 而不直接操作 ReplicaSet 或 Pod。


[转载请注明出处] 作者:雨歌 欢迎关注作者公众号:半路雨歌,查看更多技术干货文章 qrcode

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Kubernetes笔记(六):了解控制器 —— Deployment 的相关文章

  • redis精选面试题2022(持续更新)

    目录 一 redis是单线程还是多线程 二 Redis 为什么用单线程 三 redis是单线程为什么还这么快 1 内存数据库 2 简单的数据结构 3 单线程 4 IO多路复用 四 redis是如何使用跳表来存储的 五 redis没有设置过期
  • [HDLBits] Exams/ece241 2014 q7a

    Design a 1 12 counter with the following inputs and outputs Reset Synchronous active high reset that forces the counter
  • Linux下Nginx编译安装后的开机自启动设置

    Linux下Nginx编译安装后的开机自启动设置 一 查看当前Nginx启动状态 二 而配置Nginx相关服务文件 三 设置nginx命令 四 设置开机启动 五 测试开机启动 一 查看当前Nginx启动状态 root node1 sbin
  • Python编程从入门到实践(六)-用户输入和while循环

    1 函数input 的工作原理 函数input 让程序暂停运行 等待用户输入一些文本 获取用户输入后 Python将其存储在一个变量中 以方便以后使用 例如 下面的程序让用户输入一些文本 再将这些文本呈现给用户 parrot py mess
  • QT5.15.2+MSVC2022编译程序记录

    问题描述及简单分析 使用MinGW在windows上编译的release版exe 然后再使用windeployqt进行打包关联库 在没有msvc环境的电脑中运行还是会出现报错和某些不确定的问题 比如调用pysttx3包的时候 无法正确加载语
  • js仿苹果风格弹出框alert插件

    下载地址 js仿苹果风格弹出框alert插件 多种调用方式 dd
  • Jenkins+Docker持续集成 流程图

    简介 在互联网时代 对于每一家公司 软件开发和发布的重要性不言而喻 目前已经形成一套标准的流程 最重要的组成部分就是持续集成 CI 及持续部署 交付 CD 本文基于Jenkins Docker Git实现一套CI自动化发布流程 传统工作流程
  • 对对对,我放出来了,对对对对对对--对对对对!

    很多同学以为我懒 天天问我怎么一直不发文 是不是懒了 胖了 堕落了 被收变了 其实主要因为我没背景 只有背影 黑屋去吧你 我刚从黑屋出来了 最近发生这么多事 我还说什么 不说了 一切都是对对对对对对对 就对了 还有很多同行的号直接祭了 最近
  • js读取jpg图片扩展信息,处理二进制数据

    js 读取图片扩展信息 将图片转为ArrayBuffer var http new XMLHttpRequest http onload function if this status 200 this status 0 console l
  • ReactNative D8 Cannot fit requested classes in a single dex file

    我现在的版本 再更新RN版本之后 发现在装包的时候出现了 D8 Cannot fit requested classes in a single dex file methods 65749 gt 65536 这个问题 百度上是说Andro
  • 正弦函数的频谱图(FFT)

    从理论上讲 正弦函数的傅里叶变换是冲击函数 它的幅值为原正弦信号幅值的1 2倍 即 若x t Acos t 则其频谱幅值最大值为A 2 如左图 但是 我们用matlab求出来的频谱图却不是左边这样的 而是右图 原因是 1 理论中的正弦信号是
  • 分布式时序相似查询初探

    时序数据 即随时间变化的数据 在人们的日常生活中无处不在 过去的近十年来 随着电子监控和智能穿戴等设备的普及 更是产生了海量的时序数据 例如 经过多年的发展 火力发电行业的数字化程度已经达到了很高的水平 以一台60万千瓦的中型火电机组为例
  • c#复习题(简答题:基础+面向对象)

    1 简答题 填写程序 要求如下 输入三角形三条边 先判断是否可以构成三角形 如果可以 则求三角形的周长和面积 否则报错 提示 输入的三个数构成三角形三边的条件 每条边长均大于0 并且任意两边之和大于第三边 代码编写 static void
  • 从zookeeper官方文档系统学习zookeeper

    从zookeeper官方文档系统学习zookeeper 1 zookeeper 2 zookeeper 文档 3 zookeeper 单机版 3 1 配置 3 2 启动 3 3 验证 4 zookeeper 集群版 4 1 配置 4 2 启
  • centos7 Jumpserver堡垒机部署以及使用详情

    一 跳板机 堡垒机的概念 1 跳板机 跳板机就是一台服务器 运维人员在使用管理服务器的时候 必须先连接上跳板机 然后才能去操控内网中的服务器 才能登录到目标设备上进行维护和操作 跳板机的缺点 仅仅实现服务器登录安全 但是没有实现对于运维人员
  • ChatGPT-Sorry, you have been blocked 解决办法

    使用无痕模式登录 已谷歌浏览器举例 右上点打开性的无痕模式 再访问地址 如下 可以继续登录了
  • Hadoop生态概述及常见报错

    Hadoop Hadoop是一个开源框架来存储和处理大型数据在分布式环境中 它包含两个模块 一个是MapReduce 另外一个是Hadoop分布式文件系统 HDFS MapReduce 它是一种并行编程模型在大型集群普通硬件可用于处理大型结
  • 亲测有效win10系统QQ音乐无法安装

    本人使用win10专业版时 因为一些原因 多次下载qq音乐都无法进入安装界面 找了很多原因都无法解决 最后在网上找到好像是因为火绒的原因 于是关闭火绒 再次尝试安装 遂成功 实在不行可以卸载火绒安全后重启电脑 再从官网重新下载QQ音乐安装包
  • 数据预处理-独热编码(One-Hot)

    1 部分特征如人的性别有男女 国家有中国 美国 法国等 并不是连续的 而是离散的 无序的 通常我们需要对其进行特征数字化 2 假如某个样本 某个人 他的特征是这样的 男 中国 乒乓球 我们可以用 0 0 4 来表示 但是这样的特征处理并不能
  • BeautifulSoup基本用法总结

    BeautifulSoup是Python的一个库 最主要的功能就是从网页爬取我们需要的数据 BeautifulSoup将html解析为对象进行处理 全部页面转变为字典或者数组 相对于正则表达式的方式 可以大大简化处理过程 0x01 安装 建

随机推荐

  • Leetcode 106. 从中序与后序遍历序列构造二叉树

    文章目录 题目 代码 9 18 首刷自解 题目 Leetcode 106 从中序与后序遍历序列构造二叉树 代码 9 18 首刷自解 class Solution public unordered map
  • UE4文字显示乱码“字字字字字字字字”的解决办法

    键盘win R 搜索fonts 2 滑到最底下右键复制 宋体常规简体字 3 复制到ue4项目的字体文件夹中 如下 注意在外部文件处复制 4 回到项目界面 此时右下角会有个弹窗提示是否确认导入 点击导入 然后会弹一个 字体样式导入选项 弹框
  • openGauss学习笔记-63 openGauss 数据库管理-资源池化架构

    文章目录 openGauss学习笔记 63 openGauss 数据库管理 资源池化架构 openGauss学习笔记 63 openGauss 数据库管理 资源池化架构 本文档主要介绍资源池化架构下的一些最佳实践和使用注意事项 用于支撑对相
  • go Cobra命令行工具入门

    简介 Github https github com spf13 cobra Star 26 5K Cobra是一个用Go语言实现的命令行工具 并且现在正在被很多项目使用 例如 Kubernetes Hugo和Github CLI等 通过使
  • Failed to set locale, defaulting to C.UTF-8解决方法

    CentOS 8Linux系统提示 Failed to set locale defaulting to C UTF 8 这是由于没有配置正确的语言环境导致的 Linux百科 使用root账户登录你的CentOS操作系统 然后执行两条命令
  • 现阶段计算机网络技术专业人才培养的发展对策

    确立具有高职特色的人才培养目标 在市场经济的条件下 人才培养首先要适应市场需求 以市场行业的需求为导 向制定人才培养目标 学校人才培养是否能满足社会需求 可以通过学生在对口行 业及相关领域的就业情况来衡量 高职教育培养高技能应用型人才 与研
  • Objective-C中的封装、继承、多态、分类

    封装 封装最好理解了 封装是面向对象的特征之一 是对象和类概念的主要特性 封装 也就是把客观事物封装成抽象的类 并且类可以把自己的数据和方法只让可信的类或者对象操作 对不可信的进行信息隐藏 继承 面向对象编程 OOP 语言的一个主要功能就是
  • 测试工具73款

    我们将本文的软件测试工具分为4类 1 Web应用测试工具 2 网站安全测试工具 3 跨浏览器测试工具 4 移动应用测试工具 注 工具排名没有任何意义 1 Web应用测试工具 我们列出了一些在Web应用程序上执行性能 负载和压力测试的关键工具
  • 开源项目MiniWord .NET Word 操作由Word模板和数据简单、快速生成文件

    MiniWord NET Word 介绍 MiniWord NET Word模板引擎 藉由Word模板和数据简单 快速生成文件 image Getting Started 安装 nuget link https www nuget org
  • ubuntu18.04命令安装ros2

    ROS2官方文档 本教程为apt get命令安装方式 官网教程有点问题 借鉴一下大佬的安装方式 文章目录 1 安装ROS2 1 1 安装秘钥相关指令 1 2 授权秘钥 1 3 添加ROS2软件源 1 4 安装 2 设置环境 可选但是推荐 2
  • vue路由器学习(个人学习笔记四)

    目录 友情提醒 第一章 路由简介 1 1 什么是路由 1 2 安装路由插件 第二章 自定义路由器 2 1 创建路由器文件index js文件 2 2 index js文件中配置路由信息 第三章 使用路由器 3 1 在main js文件中将路
  • 基于Item的协同过滤算法实践(最简单的在线电影推荐系统)

    上一篇文章 基于用户的协同过滤算法实践 中 基于用户的相似度生成推荐列表 本文将基于Item的相似度阐述 1 相似度 基于物品的协同过滤算法 简称ItemCF 给用户推荐那些和他们之前喜欢的物品相似的物品 不过ItemCF不是利用物品的内容
  • 用户权限数据转换为用户组列表(3/3) - Excel PY公式

    最近Excel圈里的大事情就是微软把PY塞进了Excel单元格 可以作为公式使用 轻松用PY做数据分析 系好安全带 老司机带你玩一把 实例需求 如下是AD用户的列表 每个用户拥有该应用程序的只读或读写权限 现在需要创建新的AD用户组 并根据
  • Source Insight4.0的安装以及配置

    安装source insight4 工具的动机 1 公司需求 2 source insight4 0工具是集开发快速以及界面美观和方便等多种优点于一个软件的编辑器 1 需要准备资料 source insight4 0的安装包 以及安装的过程
  • iOS内存详解

    堆栈 iOS内存条中有一部分是只读的 有一部分是可读可写的 我们操作的是可读可写部分 那么在这块内存当中 我们怎么划分堆和栈呢 我们可以限定死堆栈的内存空间 但是这样显然是不好的 那么可以使用相对弹性的空间 一个从上往下扩展 一个从下往上扩
  • Arthas阿里 阿尔萨斯诊断工具的学习

    以下所有内容基于Arthas的3 6 9版本 一 Arthas 基础 背景 线上诊断问题比较难复现 DEBUG等 都很痛苦 功能好处 通过JVM开放出来接口 代理功能 对JVM访问 获取JVM内存 线程 类 方法 变量等各种操作函数 并控制
  • Mysql数据库连接池的简单实现(基于C++11), 基础学完, 包教包会.

    项目技术点 C语言进行MYSQL数据库编程 无锁单例 基于STL队列加C 11新特性保证线程安全实现的生产者消费者模型 C 11多线程编程 线程间同步与互斥 基于CAS的原子整形 lambda表达式 shared ptr智能指针管理Conn
  • Pipenv:作为 Python 开发人员为什么应该使用它

    Pipenv 是一个旨在将所有打包世界中最好的东西带到 Python 世界的工具 它将 Pipfile pip 和 virtualenv 整合到一个命令中 它会自动为您的项目创建和管理虚拟环境 并在您安装 卸载包时从您的 Pipfile 添
  • 大清相国 -陈廷敬

    以前都没听说过这个人 读了读 原来是康熙时的重臣 一开始 太完美了 为民做主 不爱权 不爱财 后来 明白不能让皇帝太难堪 不能让天下百姓知道居然这么多贪官 委屈求全 最后一举将高士奇等一起干掉 狠字当头 最后 装傻退出朝廷 在家养老 一句话
  • Kubernetes笔记(六):了解控制器 —— Deployment

    Pod 容器组 是 Kubernetes 中最小的调度单元 可以通过 yaml 定义文件直接创建一个 Pod 但 Pod 本身并不具备自我恢复 self healing 功能 如果一个 Pod 所在的节点出现故障 或者调度程序自身出现问题