Kubernetes:更新与回滚
除了创建,Deployment 提供的另一个重要的功能就是更新应用,这是一个比创建复杂很多的过程。想象一下在日常交付中,在线升级是一个很常见的需求,同时应该尽量保证不能因为升级中断服务。这就要求我们必须使用一定的策略来决定何时创建新的 Pod,何时删除旧版本的 Pod。kubectl 支持滚动升级的方式,每次更新一个pod,而不是同时删除整个服务。
前置知识
回顾知识:
kubectl set image
命令格式:
kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N
例如:
Examples:
# Set a deployment's nginx container image to 'nginx:1.9.1', and its busybox container image to 'busybox'.
kubectl set image deployment/nginx busybox=busybox nginx=nginx:1.9.1
# Update all deployments' and rc's nginx container's image to 'nginx:1.9.1'
kubectl set image deployments,rc nginx=nginx:1.9.1 --all
# Update image of all containers of daemonset abc to 'nginx:1.9.1'
kubectl set image daemonset abc *=nginx:1.9.1
# Print result (in yaml format) of updating nginx container image from local file, without hitting the server
kubectl set image -f path/to/file.yaml nginx=nginx:1.9.1 --local -o yaml
💡Tips:支持缩写,如pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs)。
选项
--all=false: Select all resources, including uninitialized ones, in the namespace of the specified resource types
--allow-missing-template-keys=true: If true, ignore any errors in templates when a field or map key is missing in
the template. Only applies to golang and jsonpath output formats.
--dry-run='none': Must be "none", "server", or "client". If client strategy, only print the object that would be
sent, without sending it. If server strategy, submit server-side request without persisting the resource.
--field-manager='kubectl-set': Name of the manager used to track field ownership.
-f, --filename=[]: Filename, directory, or URL to files identifying the resource to get from a server.
-k, --kustomize='': Process the kustomization directory. This flag can't be used together with -f or -R.
--local=false: If true, set image will NOT contact api-server but run locally.
-o, --output='': Output format. One of:
json|yaml|name|go-template|go-template-file|template|templatefile|jsonpath|jsonpath-as-json|jsonpath-file.
--record=false: Record current kubectl command in the resource annotation. If set to false, do not record the
command. If set to true, record the command. If not set, default to updating the existing annotation value only if one
already exists.
-R, --recursive=false: Process the directory used in -f, --filename recursively. Useful when you want to manage
related manifests organized within the same directory.
-l, --selector='': Selector (label query) to filter on, not including uninitialized ones, supports '=', '==', and
'!='.(e.g. -l key1=value1,key2=value2)
--show-managed-fields=false: If true, keep the managedFields when printing objects in JSON or YAML format.
--template='': Template string or path to template file to use when -o=go-template, -o=go-template-file. The
template format is golang templates [http://golang.org/pkg/text/template/#pkg-overview].
示例
创建deployment
先创建一个deployment,ngx-deploy.yaml配置文件如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.16.0
ports:
- containerPort: 80
执行命令:
kubectl create -f ngx-deploy.yaml
使用 watch 方式来观测 deployment 的状态变化:
[root@master test]# kubectl get deploy nginx-deployment -w
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 0/2 2 0 14s
nginx-deployment 1/2 2 1 25s
nginx-deployment 2/2 2 2 38s
说明:
- NAME:deployment 的名字。
- READY:就是当前有多少个 Pod 处于运行中/期望有多少个 Pod。
- UP-TO-DATE:达到最新状态的 Pod 的数量。当 Deployment 在进行更新时,会有新老版本的 Pod 同时存在,这时候这个字段会比较有用。
- AVAILABLE:可用的 Pod。上个实验我们讲了健康检查的相关配置,Pod 运行中和可以提供服务是不同的概念。
- AGE:deployment 运行的时间。
更新镜像
接下来先更新一个nginx镜像,版本为1.18:
kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.18.0 --record
说明:
--record
:将这条命令记录到了 deployment 的 yaml 的annotations
里,可用于回滚镜像。
使用watch方式观察deployment实例变更情况:
[root@master test]# kubectl get deploy nginx-deployment -w
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 1 2 3m41s
nginx-deployment 3/2 1 3 3m58s
nginx-deployment 2/2 1 2 3m58s
nginx-deployment 2/2 2 2 3m58s
可以通过 get yaml
看到:
[root@master test]# kubectl get deploy nginx-deployment -o yaml
...
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.18.0
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
...
回滚镜像
有更新就有回滚。比如新的镜像版本有问题,或者配置不对等等,这是部署到生产环境里经常发生的事情。相对于更新,回滚镜像一般都是出现了问题,需要更快地进行处理。Deployment 的回滚机制正是为此而生。
可以通过命令查看历史版本:
[root@master test]# kubectl rollout history deployment.v1.apps/nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deployment.v1.apps/nginx-deployment nginx=nginx:1.18.0 --record=true
回滚到上一个版本:
kubectl rollout undo deployment.v1.apps/nginx-deployment
可以观察到已回到上个版本:
[root@master test]# kubectl get deploy nginx-deployment -o yaml
...
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.16.0
imagePullPolicy: IfNotPresent
name: nginx
ports:
- containerPort: 80
protocol: TCP
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
...
也可回滚到指定版本:
kubectl rollout undo deployment.v1.apps/nginx-deployment --to-revision=2
分类:
CloudNative
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?