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
相关推荐
爱勇宝2 小时前
第 1 章:别把“需求文档”当成真正的需求
前端·后端·程序员
IT_陈寒7 小时前
闭包陷阱让我加了两天班,JavaScript你真行
前端·人工智能·后端
易协同低代码8 小时前
通达OA核心类库TD类深度解析
后端
Gopher_HBo8 小时前
Go语言学习笔记(十八)Gin处理Session
后端
谭光志9 小时前
工具塞满上下文窗口怎么办?深度拆解 AI Agent Tool Search 按需加载实现原理
前端·后端·ai编程
她说..9 小时前
Java 默认值设置方式
java·开发语言·后端·springboot
foggyprojects9 小时前
从0开始,一句话启动AI DataAgent
后端·数据分析·ai编程
郡杰9 小时前
一些基础和问题解决
后端
陈随易9 小时前
前端项目部署只要30秒
前端·后端·程序员
YIAN9 小时前
从零手写文件读取 MCP 服务:一文吃透 Model Context Protocol 全链路通信原理
前端·后端·mcp