Kubernetes工作负载资源之Deployment

Deployment 为 Pod 和 ReplicaSet 提供了一个声明式的方法来管理应用。以下是典型的应用场景:

定义 Deployment 来创建 Pod 和 ReplicaSet:通过 Deployment 对象可以定义 Pod 的模板和所需的副本数量。Kubernetes 会根据这些配置创建相应数量的 Pod,并通过 ReplicaSet 进行管理,确保指定数量的副本在运行。`

滚动升级和回滚应用:Deployment 支持滚动升级和回滚应用的功能。你可以通过更新 Deployment 的配置来实现应用程序的升级,Kubernetes 会逐步创建新的 Pod 副本并逐步停止旧的副本,从而实现无缝的应用程序升级。如果升级出现问题,你也可以轻松地回滚到之前的版本。`

扩容和缩容:通过更新 Deployment 的副本数量,可以实现扩容和缩容。Kubernetes 会根据你指定的副本数量自动启动或停止相应数量的 Pod。`

暂停和继续 Deployment:Deployment 还支持暂停和继续操作。你可以暂停 Deployment,暂停后,Kubernetes 将停止创建新的 Pod 副本。当你需要进行维护或者排查问题时,这是非常有用的。暂停后,你也可以随时继续 Deployment,Kubernetes 会根据之前的配置继续创建新的 Pod 副本。`

比如一个简单的 nginx 应用可以定义为:

yaml 复制代码
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.14.2
        ports:
        - containerPort: 80
  • 扩容:
css 复制代码
kubectl scale deployment nginx-deployment --replicas 10
  • 如果集群支持 horizontal pod autoscaling 的话,还可以为 Deployment 设置自动扩展:
css 复制代码
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80
  • 更新镜像也比较简单:
arduino 复制代码
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
  • 回滚:
bash 复制代码
kubectl rollout undo deployment/nginx-deployment

创建 Deployment

首先,我们需要下载一个示例文件并执行一些命令。你只需要在终端输入这个命令:

ruby 复制代码
$ kubectl apply -f https://k8s.io/examples/controllers/nginx-deployment.yaml

执行完之后,你会看到一个提示,告诉你 Deployment "nginx-deployment" 已经创建成功了。

嗯,现在让我们执行一条 get 命令,看看有什么结果呢?

arduino 复制代码
$ kubectl get deployments

我们希望有 3 个 replica(也就是 Pod 的副本),但是当前还没有创建任何副本。所以它显示的 Desired 是 3,而 Current、Up-to-date 和 Available 都是 0。

但是再过几秒钟,我们再执行 get 命令看看会发生什么:

arduino 复制代码
$ kubectl get deployments

现在的结果Deployment 已经创建了 3 个 replica,Desired、Current、Up-to-date 和 Available 都变成了 3。这意味着我们成功地创建了 3 个最新版本的 Pod。

ReplicaSet 输出中包含以下字段:

  • NAME 列出名字空间中 ReplicaSet 的名称;
  • DESIRED 显示应用的期望副本个数,即在创建 Deployment 时所定义的值。 此为期望状态;
  • CURRENT 显示当前运行状态中的副本个数;
  • READY 显示应用中有多少副本可以为用户提供服务;
  • AGE 显示应用已经运行的时间长度。

注意 ReplicaSet 的名称格式始终为 [Deployment 名称]-[哈希]。 该名称将成为所创建的 Pod 的命名基础。 其中的哈希字符串与 ReplicaSet 上的 pod-template-hash 标签一致。

如果你还想了解更多信息,可以使用 kubectl get rs 命令查看 ReplicaSet 的情况,或者使用 kubectl get pods 命令查看 Pod 的情况。这样你就能看到 Replica Set 和 Pod 都已经成功创建!

要查看每个 Pod 自动生成的标签,运行 kubectl get pods --show-labels。 输出类似于:

更新 Deployment

说明:

仅当 Deployment Pod 模板(即 .spec.template)发生改变时,例如模板的标签或容器镜像被更新, 才会触发 Deployment 上线。其他更新(如对 Deployment 执行扩缩容的操作)不会触发上线动作。

可以通过以下两种方式之一来完成。

  • 方法一:使用kubectl set image命令直接更新Deployment的容器镜像。
arduino 复制代码
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.16.1

或者可以使用下面的命令:

arduino 复制代码
kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1

在上述命令中,deployment/nginx-deployment指定了要更新的Deployment的名称,nginx指定了要更新的容器,nginx:1.16.1表示新的镜像版本及其标签。

执行完上述命令后,将会输出类似于"deployment.apps/nginx-deployment image updated"的消息,表示成功更新了Deployment的容器镜像。

  • 方法二:使用kubectl edit命令编辑Deployment的配置文件执行更新操作。
bash 复制代码
kubectl edit deployment/nginx-deployment

执行上述命令后,将打开一个文本编辑器,允许您手动修改Deployment的配置。在编辑器中,将.spec.template.spec.containers[0].imagenginx:1.14.2更改为nginx:1.16.1,然后保存并退出编辑器。

获取关于已更新的 Deployment 的更多信息: 在上线成功后,可以通过运行 kubectl get deployments 来查看 Deployment: 输出类似于:

vbnet 复制代码
➜  ~ kubectl get deployments
NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           18m
➜  ~
  • 运行 kubectl get rs 以查看 Deployment 通过创建新的 ReplicaSet 并将其扩容到 3 个副本并将旧 ReplicaSet 缩容到 0 个副本完成了 Pod 的更新操作:
arduino 复制代码
kubectl get rs
sql 复制代码
   NAME                          DESIRED   CURRENT   READY   AGE
   nginx-deployment-1564180365   3         3         3       6s
   nginx-deployment-2035384211   0         0         0       36s
  • 现在运行 get pods 应仅显示新的 Pod:
arduino 复制代码
    kubectl get pods

输出类似于:

sql 复制代码
    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-1564180365-khku8   1/1       Running   0          14s
    nginx-deployment-1564180365-nacti   1/1       Running   0          14s
    nginx-deployment-1564180365-z9gth   1/1       Running   0          14s

下次要更新这些 Pod 时,只需再次更新 Deployment Pod 模板即可。

Deployment 可确保在更新时仅关闭一定数量的 Pod。默认情况下,它确保至少所需 Pod 的 75% 处于运行状态(最大不可用比例为 25%)。

Deployment 还确保仅所创建 Pod 数量只可能比期望 Pod 数高一点点。 默认情况下,它可确保启动的 Pod 个数比期望个数最多多出 125%(最大峰值 25%)。

例如,如果仔细查看上述 Deployment ,将看到它首先创建了一个新的 Pod,然后删除旧的 Pod, 并创建了新的 Pod。它不会杀死旧 Pod,直到有足够数量的新 Pod 已经出现。 在足够数量的旧 Pod 被杀死前并没有创建新 Pod。它确保至少 3 个 Pod 可用, 同时最多总共 4 个 Pod 可用。 当 Deployment 设置为 4 个副本时,Pod 的个数会介于 3 和 5 之间。

  • 获取 Deployment 的更多信息
vbnet 复制代码
kubectl describe deployments

➜  ~ kubectl describe deployments
Name:                   nginx-deployment
Namespace:              default
CreationTimestamp:      Wed, 18 Oct 2023 22:22:07 +0800
Labels:                 app=nginx
Annotations:            deployment.kubernetes.io/revision: 2
Selector:               app=nginx
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max surge
Pod Template:
  Labels:  app=nginx
  Containers:
   nginx:
    Image:        nginx:1.16.1
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable
OldReplicaSets:  nginx-deployment-cbdccf466 (0/0 replicas created)
NewReplicaSet:   nginx-deployment-74b6b979f (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  20m    deployment-controller  Scaled up replica set nginx-deployment-cbdccf466 to 3
  Normal  ScalingReplicaSet  9m20s  deployment-controller  Scaled up replica set nginx-deployment-74b6b979f to 1
  Normal  ScalingReplicaSet  9m4s   deployment-controller  Scaled down replica set nginx-deployment-cbdccf466 to 2 from 3
  Normal  ScalingReplicaSet  9m4s   deployment-controller  Scaled up replica set nginx-deployment-74b6b979f to 2 from 1
  Normal  ScalingReplicaSet  8m55s  deployment-controller  Scaled down replica set nginx-deployment-cbdccf466 to 1 from 2
  Normal  ScalingReplicaSet  8m55s  deployment-controller  Scaled up replica set nginx-deployment-74b6b979f to 3 from 2
  Normal  ScalingReplicaSet  8m41s  deployment-controller  Scaled down replica set nginx-deployment-cbdccf466 to 0 from 1

回滚 Deployment

通过回滚 Deployment 来还原到先前的状态。默认情况下,系统会保留 Deployment 的所有上线记录,以便可以随时回滚到先前的版本。

可以使用以下命令来回滚 Deployment:

bash 复制代码
kubectl rollout undo deployment/nginx-deployment

上述命令将会将 Deployment 回滚到先前的版本,即回到上一个修订版本。这将触发新的滚动过程,将 Deployment 恢复到先前的状态。执行命令后,会输出类似于 "deployment.apps/nginx-deployment rolled back" 的消息,表示回滚成功。

可以使用以下命令来查看 Deployment 的滚动历史记录:

bash 复制代码
kubectl rollout history deployment/nginx-deployment

输出类似于:

bash 复制代码
deployments "nginx-deployment"
REVISION    CHANGE-CAUSE
1           kubectl apply --filename=https://k8s.io/examples/controllers/nginx-deployment.yaml
2           kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
3           kubectl set image deployment/nginx-deployment nginx=nginx:1.161


`CHANGE-CAUSE` 的内容是从 Deployment 的 `kubernetes.io/change-cause` 注解复制过来的。 复制动作发生在修订版本创建时。你可以通过以下方式设置 `CHANGE-CAUSE` 消息:

-   使用 `kubectl annotate deployment/nginx-deployment kubernetes.io/change-cause="image updated to 1.16.1"` 为 Deployment 添加注解。
-   手动编辑资源的清单。

上述命令将显示 Deployment 的所有修订版本以及其相关信息,包括修订版本号、回滚到该版本的命令、修订的部署时间等。最新的修订版本显示在列表的顶部。

如果您想要回滚到特定的修订版本,可以使用以下命令:

ini 复制代码
kubectl rollout undo deployment/nginx-deployment --to-revision=<revision>

Deployment 状态

<revision> 替换为您想要回滚到的修订版本号。执行命令后,将触发新的滚动过程,将 Deployment 恢复到指定版本。

进行中的 Deployment

在Deployment的生命周期中,它可能会经历多种状态。当你上线一个新的ReplicaSet时,Deployment可能处于"进行中"(Progressing)状态,也可能是"已完成"(Complete)状态,甚至可能是"失败"(Failed)状态,无法继续进行下去。

首先,让我们来看看"进行中"(Progressing)状态。

当Deployment创建一个新的ReplicaSet、正在扩容最新的ReplicaSet,或者正在减少旧有的ReplicaSet时,Kubernetes会将Deployment标记为"进行中"状态。当新的Pod已经准备就绪或可用(至少经过了MinReadySeconds秒)时,进程将被标记为进行中。当部署进入"进行中"状态时,Deployment控制器会在Deployment的.status.conditions中添加一个包含以下属性的条件条目:

yaml 复制代码
type: Progressing  
status: "True"  
reason: NewReplicaSetCreated | reason: FoundNewReplicaSet | reason: ReplicaSetUpdated

如果你想监视Deployment的进度,可以使用kubectl rollout status命令。

完成的 Deployment

接下来是"已完成"(Complete)状态。当Deployment满足以下条件时,Kubernetes将其标记为"已完成"状态:

与Deployment关联的所有副本已更新到指定的最新版本,这意味着之前请求的所有更新都已完成。

与Deployment关联的所有副本都可用。

旧的副本已被删除,不再运行。

当部署进入"已完成"状态时,Deployment控制器会在Deployment的.status.conditions中添加一个包含以下属性的条件条目:

vbnet 复制代码
type: Progressing  
status: "True"  
reason: NewReplicaSetAvailable

Progressing条件的状态值将持续为"True",直到触发新的上线操作。即使副本的可用状态发生变化(从而影响到Available条件),Progressing条件的值也不会改变。

失败的 Deployment

你的 Deployment 可能会在尝试部署其最新的 ReplicaSet 受挫,一直处于未完成状态。 造成此情况一些可能因素如下:

  • 配额(Quota)不足
  • 就绪探测(Readiness Probe)失败
  • 镜像拉取错误
  • 权限不足
  • 限制范围(Limit Ranges)问题
  • 应用程序运行时的配置错误

为了及时检测并解决这种情况,我们可以在部署规约中设置一个截止时间参数,告诉控制器,在指定的时间之后如果还没有进展,就需要报告部署失败了。比如可以使用以下命令设置截止时间为10分钟:

css 复制代码
kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'

当截止时间到达后,控制器会在部署的状态中添加一个属性,告诉我们部署进展是否停滞了:

vbnet 复制代码
type: Progressing
status: "False"
reason: ProgressDeadlineExceeded
相关推荐
许野平31 分钟前
Rust: 利用 chrono 库实现日期和字符串互相转换
开发语言·后端·rust·字符串·转换·日期·chrono
齐 飞2 小时前
MongoDB笔记01-概念与安装
前端·数据库·笔记·后端·mongodb
LunarCod2 小时前
WorkFlow源码剖析——Communicator之TCPServer(中)
后端·workflow·c/c++·网络框架·源码剖析·高性能高并发
码农派大星。3 小时前
Spring Boot 配置文件
java·spring boot·后端
杜杜的man4 小时前
【go从零单排】go中的结构体struct和method
开发语言·后端·golang
幼儿园老大*4 小时前
走进 Go 语言基础语法
开发语言·后端·学习·golang·go
llllinuuu4 小时前
Go语言结构体、方法与接口
开发语言·后端·golang
cookies_s_s4 小时前
Golang--协程和管道
开发语言·后端·golang
为什么这亚子4 小时前
九、Go语言快速入门之map
运维·开发语言·后端·算法·云原生·golang·云计算
想进大厂的小王4 小时前
项目架构介绍以及Spring cloud、redis、mq 等组件的基本认识
redis·分布式·后端·spring cloud·微服务·架构