更新与回滚应用程序

KubernetesKubernetesBeginner
立即练习

💡 本教程由 AI 辅助翻译自英文原版。如需查看原文,您可以 切换至英文原版

介绍

在本实验中,你将学习如何更新和回滚部署在 Kubernetes 集群上的应用程序。你将首先使用 Minikube 设置一个本地 Kubernetes 集群,然后部署一个示例 NGINX 应用程序。接下来,你将更新应用程序的镜像并验证更新是否成功。为了模拟更新失败的情况,你将诊断问题并回滚到稳定版本。最后,你将在 Deployment YAML 文件中调整滚动更新策略。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicsGroup(["`Basics`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/BasicCommandsGroup(["`Basic Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedCommandsGroup(["`Advanced Commands`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/AdvancedDeploymentGroup(["`Advanced Deployment`"]) kubernetes(("`Kubernetes`")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["`Troubleshooting and Debugging Commands`"]) kubernetes/BasicsGroup -.-> kubernetes/initialization("`Initialization`") kubernetes/BasicCommandsGroup -.-> kubernetes/get("`Get`") kubernetes/BasicCommandsGroup -.-> kubernetes/create("`Create`") kubernetes/BasicCommandsGroup -.-> kubernetes/set("`Set`") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("`Apply`") kubernetes/AdvancedDeploymentGroup -.-> kubernetes/rollout("`Rollout`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("`Describe`") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/logs("`Logs`") subgraph Lab Skills kubernetes/initialization -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/get -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/create -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/set -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/apply -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/rollout -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/describe -.-> lab-434649{{"`更新与回滚应用程序`"}} kubernetes/logs -.-> lab-434649{{"`更新与回滚应用程序`"}} end

启动 Kubernetes 集群

在这一步中,你将学习如何使用 Minikube 启动并验证一个本地 Kubernetes 集群。这是设置 Kubernetes 开发环境的关键第一步。

首先,确保你位于项目目录中:

cd ~/project

启动 Minikube 集群:

minikube start

示例输出:

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

验证集群状态:

minikube status

示例输出:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

检查集群节点:

kubectl get nodes

示例输出:

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

本步骤的关键点:

  1. minikube start 创建一个本地单节点 Kubernetes 集群
  2. 集群默认使用 Docker 作为驱动
  3. Kubernetes v1.26.1 会自动配置
  4. minikube statuskubectl get nodes 用于确认集群的准备状态

部署示例应用程序

在这一步中,你将学习如何使用 Kubernetes Deployment 创建并部署一个简单的 Web 应用程序。我们将使用 NGINX 镜像作为示例应用程序来演示部署过程。

首先,导航到项目目录:

cd ~/project
mkdir -p k8s-manifests
cd k8s-manifests

为 Web 应用程序创建一个新的部署清单文件:

nano nginx-deployment.yaml

将以下内容添加到文件中:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.23.3-alpine
          ports:
            - containerPort: 80

保存文件并退出 nano 编辑器。

使用 kubectl 部署应用程序:

kubectl apply -f nginx-deployment.yaml

示例输出:

deployment.apps/web-app created

验证部署:

kubectl get deployments

示例输出:

NAME      READY   UP-TO-DATE   AVAILABLE   AGE
web-app   3/3     3            3           30s

检查创建的 Pod:

kubectl get pods -l app=web

示例输出:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          45s
web-app-xxx-zzz           1/1     Running   0          45s
web-app-xxx-www           1/1     Running   0          45s

本部署的关键点:

  1. 我们创建了一个包含 3 个 NGINX Web 服务器副本的 Deployment
  2. 使用了特定且稳定的 NGINX 版本(1.23.3-alpine)
  3. 暴露了容器的 80 端口
  4. 使用标签来识别和管理 Pod

在 Deployment YAML 中更新应用程序镜像

在这一步中,你将学习如何更新 Kubernetes Deployment 中的容器镜像,模拟真实世界中的应用程序升级场景。

首先,确保你位于正确的目录中:

cd ~/project/k8s-manifests

打开现有的部署清单文件:

nano nginx-deployment.yaml

将镜像从 nginx:1.23.3-alpine 更新到新版本:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.24.0-alpine
          ports:
            - containerPort: 80

应用更新后的部署:

kubectl apply -f nginx-deployment.yaml

示例输出:

deployment.apps/web-app configured

观察部署更新过程:

kubectl rollout status deployment web-app

示例输出:

Waiting for deployment "web-app" to roll out...
Waiting for deployment spec update to be applied...
Waiting for available replicas to reach desired number...
deployment "web-app" successfully rolled out

验证新镜像版本:

kubectl get pods -l app=web -o jsonpath='{.items[*].spec.containers[0].image}'

示例输出:

nginx:1.24.0-alpine nginx:1.24.0-alpine nginx:1.24.0-alpine

镜像更新的关键点:

  1. 使用 kubectl apply 来更新部署
  2. Kubernetes 默认执行滚动更新
  3. Pod 会逐步替换,以确保应用程序的可用性
  4. 更新过程确保零停机部署

验证更新是否成功

在这一步中,你将学习如何通过检查 Pod 版本、状态以及更多部署详细信息来验证 Kubernetes 部署的更新是否成功。

首先,列出 Pod 的详细信息:

kubectl get pods -l app=web -o wide

示例输出:

NAME                      READY   STATUS    RESTARTS   AGE   IP           NODE       NOMINATED NODE   READINESS GATES
web-app-xxx-yyy           1/1     Running   0          3m    10.244.0.5   minikube   <none>           <none>
web-app-xxx-zzz           1/1     Running   0          3m    10.244.0.6   minikube   <none>           <none>
web-app-xxx-www           1/1     Running   0          3m    10.244.0.7   minikube   <none>           <none>

检查 Pod 的具体镜像版本:

kubectl get pods -l app=web -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

示例输出:

web-app-xxx-yyy    nginx:1.24.0-alpine
web-app-xxx-zzz    nginx:1.24.0-alpine
web-app-xxx-www    nginx:1.24.0-alpine

描述部署以获取更多详细信息:

kubectl describe deployment web-app

示例输出:

Name:                   web-app
Namespace:              default
CreationTimestamp:      [current timestamp]
Labels:                 app=web
Annotations:            deployment.kubernetes.io/revision: 2
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=web
  Containers:
   nginx:
    Image:        nginx:1.24.0-alpine
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Available      True    MinimumReplicasAvailable
  Progressing    True    NewReplicaSetAvailable

验证滚动更新历史:

kubectl rollout history deployment web-app

示例输出:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>

验证的关键点:

  1. 所有 Pod 都在运行新的镜像版本
  2. 部署有 3 个可用的副本
  3. 滚动更新策略确保零停机更新
  4. 部署版本号已递增

模拟和诊断更新失败

在这一步中,你将学习如何通过模拟一个有问题的镜像更新并使用 Kubernetes 诊断工具来诊断潜在的部署更新失败。

首先,导航到项目目录:

cd ~/project/k8s-manifests

创建一个包含无效镜像的部署清单文件:

nano problematic-deployment.yaml

添加以下内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: troubleshoot-app
  labels:
    app: troubleshoot
spec:
  replicas: 3
  selector:
    matchLabels:
      app: troubleshoot
  template:
    metadata:
      labels:
        app: troubleshoot
    spec:
      containers:
        - name: nginx
          image: nginx:non-existent-tag
          ports:
            - containerPort: 80

应用有问题的部署:

kubectl apply -f problematic-deployment.yaml

示例输出:

deployment.apps/troubleshoot-app created

检查部署状态:

kubectl rollout status deployment troubleshoot-app

示例输出:

Waiting for deployment "troubleshoot-app" to roll out...

按下 Ctrl+C 退出滚动状态检查。

检查 Pod 事件和状态:

kubectl get pods -l app=troubleshoot

示例输出:

NAME                              READY   STATUS             RESTARTS   AGE
troubleshoot-app-6b8986c555-gcjj9   0/1     ImagePullBackOff   0          2m56s
troubleshoot-app-6b8986c555-p29dp   0/1     ImagePullBackOff   0          2m56s
troubleshoot-app-6b8986c555-vpv5q   0/1     ImagePullBackOff   0          2m56s

检查 Pod 详细信息和日志:

## 将 'xxx-yyy' 替换为实际的 Pod 名称
POD_NAME=$(kubectl get pods -l app=troubleshoot -o jsonpath='{.items[0].metadata.name}')
kubectl describe pod $POD_NAME
kubectl logs $POD_NAME

你将看到 Pod 状态和日志,指示镜像拉取失败。

Failed to pull image "nginx:non-existent-tag"

通过修正镜像来排查问题:

nano problematic-deployment.yaml

将镜像更新为有效的标签:

image: nginx:1.24.0-alpine

重新应用修正后的部署:

kubectl apply -f problematic-deployment.yaml

再次检查 Pod 状态:

kubectl get pods -l app=troubleshoot

示例输出:

NAME                                READY   STATUS    RESTARTS   AGE
troubleshoot-app-5dc9b58d57-bvqbr   1/1     Running   0          5s
troubleshoot-app-5dc9b58d57-tdksb   1/1     Running   0          8s
troubleshoot-app-5dc9b58d57-xdq5n   1/1     Running   0          6s

诊断失败的关键点:

  1. 使用 kubectl describe 查看部署和 Pod 事件
  2. 检查 Pod 状态是否为 ImagePullBackOff 或其他错误状态
  3. 检查 Pod 日志以获取详细的错误信息
  4. 验证镜像的可用性和标签的正确性

回滚到稳定版本

在这一步中,你将学习如何使用 kubectl rollout undo 命令将 Kubernetes 部署回滚到之前的稳定版本。

首先,导航到项目目录:

cd ~/project/k8s-manifests

检查 Web 应用程序的滚动更新历史:

kubectl rollout history deployment web-app

示例输出:

REVISION  CHANGE-CAUSE
1         <none>
2         <none>

验证当前部署的详细信息:

kubectl describe deployment web-app | grep Image

示例输出:

    Image:        nginx:1.24.0-alpine

执行回滚到上一个版本:

kubectl rollout undo deployment web-app

示例输出:

deployment.apps/web-app rolled back

验证回滚:

kubectl rollout status deployment web-app

示例输出:

Waiting for deployment "web-app" to roll out...
deployment "web-app" successfully rolled out

检查更新后的镜像版本:

kubectl get pods -l app=web -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[0].image}{"\n"}{end}'

示例输出:

web-app-xxx-yyy    nginx:1.23.3-alpine
web-app-xxx-zzz    nginx:1.23.3-alpine
web-app-xxx-www    nginx:1.23.3-alpine

确认滚动更新历史:

kubectl rollout history deployment web-app

示例输出:

REVISION  CHANGE-CAUSE
2         <none>
3         <none>

回滚的关键点:

  1. kubectl rollout undo 回滚到上一个部署版本
  2. Kubernetes 会维护部署更改的历史记录
  3. 回滚操作在零停机时间内完成
  4. 回滚会在历史记录中创建一个新的版本

在 Deployment YAML 中调整滚动更新策略

在这一步中,你将学习如何自定义 Kubernetes Deployment 中的滚动更新策略,以控制应用程序的更新和扩展方式。

首先,导航到项目目录:

cd ~/project/k8s-manifests

创建一个包含自定义滚动更新策略的部署清单文件:

nano custom-rollout-deployment.yaml

添加以下内容:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app-custom-rollout
  labels:
    app: web
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxUnavailable: 2
      maxSurge: 3
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: nginx
          image: nginx:1.24.0-alpine
          ports:
            - containerPort: 80

应用部署:

kubectl apply -f custom-rollout-deployment.yaml

示例输出:

deployment.apps/web-app-custom-rollout created

验证部署状态:

kubectl rollout status deployment web-app-custom-rollout

示例输出:

Waiting for deployment "web-app-custom-rollout" to roll out...
deployment "web-app-custom-rollout" successfully rolled out

描述部署以确认策略:

kubectl describe deployment web-app-custom-rollout

示例输出将包含:

StrategyType:           RollingUpdate
RollingUpdateStrategy:  2 max unavailable, 3 max surge

更新镜像以触发滚动更新:

kubectl set image deployment/web-app-custom-rollout nginx=nginx:1.25.0-alpine

监控更新过程:

kubectl rollout status deployment web-app-custom-rollout

滚动更新策略的关键点:

  1. maxUnavailable:更新期间允许不可用的 Pod 的最大数量
  2. maxSurge:允许超出期望数量的 Pod 的最大数量
  3. 帮助控制更新速度和应用程序的可用性
  4. 允许微调部署行为

总结

在本实验中,你学习了如何使用 Minikube 启动并验证一个本地 Kubernetes 集群,这是设置 Kubernetes 开发环境的关键第一步。你还学习了如何使用 Kubernetes Deployment 创建并部署一个简单的 Web 应用程序,并以 NGINX 镜像作为示例应用程序。部署过程包括创建部署清单文件并将其应用到集群中。

在部署应用程序的初始版本后,你学习了如何在部署 YAML 中更新应用程序镜像、验证更新是否成功、模拟和诊断更新失败、回滚到稳定版本,以及在部署 YAML 中调整滚动更新策略。

您可能感兴趣的其他 Kubernetes 教程