kubernetes之控制器(一)
K8S核心组件之控制器
1 Pod的分类
自主式Pod:Pod退出后,此类型的Pod不会被创建
控制器管理的Pod:在控制器的生命周期里,始终要维持Pod的副本数。
2 什么是控制器?
Pod控制是用于实现管理Pod的中间层,确保Pod资源符合预期的状态;Pod的资源出现故障时,会尝试进行重启,当根据重启策略无效时,则会根据Pod模板重新新建Pod资源。
3 常见的控制器
- ReplicationController:最早期的Pod控制器,即将被废弃; - RelicaSet:副本集,负责管理一个应用(Pod)的多个副本; - Deployment:部署,它不直接管理Pod,而是借助ReplicaSet来管理Pod;是最常用的无状态应用控制器; - DaemonSet:守护进程集,用于确保在每个节点仅运行某个应用的一个Pod副本; - StatefulSet:功能类似于Deployment,但StatefulSet专用于编排有状态的应用; - Job:有终止期限的一次性作业式任务,而非一直处于运行状态的服务进程; - CronJob:有终止期限的周期性作业式任务。
3.1 RelicaSet
3.1.1 RelicaSet概述
ReplicaSet(简称RS)是Pod控制器类型的一种实现,用于确保由其管控的Pod对象副本数在任一时刻都能精确满足期望的数量。ReplicaSet控制器资源启动后会查找集群中匹配其标签选择的Pod资源对象,当前活动对象的数量与期望的数量不吻合时,多则删除,少则通过Pod模板创建以补足。
ReplicaSet的副本数量、标签选择器甚至是Pod模板都可以随时按需进行修改,不过仅改动期望的副本数量会对现存的Pod副本产生直接影响。修改标签选择器可能会使得现有的Pod副本的标签变得不在匹配,此时ReplicaSet控制器要做的不过是不再计入它们而已。另外,在创建完成后,RelicaSet也不会再关注Pod对象中点实际内容,因此Pod模板的改动也只会对后来新建的Pod副本产生影响。
ReplicaSet能够实现以下功能:
- 确保Pod资源对象的数量精确反映期望值:ReplicaSet需要确保由其控制运行的Pod副本数量精确温和配置中定义的期望值,否则就会自动补足所缺或终止所余。 - 确保Pod健康运行:探测到由其管理的Pod对象因其所在的工作节点故障而不可用时,自动请求由调度器于其他工作节点创建缺失的Pod副本。 - 弹性伸缩:业务规模因各种原因时长存在明显波动,在波峰或波谷期间,可以通过ReplicaSet控制器动态调整相关Pod资源对象的数量。此外,在必要时还可以通过HPA(HroizontalPodAutoscaler)控制器实现Pod资源规模的自动伸缩。
虽然ReplicaSet可以独立使用,但一般还是建议DeployMent来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但DeployMent支持)。
定义要素:
- 标签选择器 - 期望的副本数 - Pod模板
ReplicaSet的更新机制:
删除式更新:
1.单批次删除所有Pod,一次完成所有更新;服务会中断一段时间;
2.分批次删除,待一批次就绪之后,才删除下一批;滚动更新(灰度发布)
set image:更新应用版本,但对于replicaset来说,仅能更新API server中的定义;
部署类型:
蓝绿部署:优点是便于回滚;缺点是因为新旧版本同时存在,比较占用资源。
滚动发布:优点是节省资源
3.1.2 创建ReplicaSet
**定义格式:** apiVersion: apps/v1 kind: ReplicaSet metadata: name: namespace: spec: minReadySeconds <integer> # Pod就绪后多少秒内,Pod任一容器无crash方可视为“就绪” replicas <integer> # 期望的Pod副本数,默认为1 selector: # 标签选择器,必须匹配template字段中Pod模板中的标签; matchExpressions <[]Object> # 标签选择器表达式列表,多个列表项之间为“与”关系 matchLabels <map[string]string> # map格式的标签选择器 template: # Pod模板对象 metadata: # Pod对象元数据 labels: # 由模板创建出的Pod对象所拥有的标签,必须要能够匹配前面定义的标签选择器 spec: # Pod规范,格式同自主式Pod
范例1:
#编辑资源清单 [root@ubuntu-200 ~]# cat replicaset-demo.yaml apiVersion: apps/v1 kind: ReplicaSet metadata: name: replicaset-demo spec: minReadySeconds: 3 replicas: 3 selector: matchLabels: app: demoapp release: stable version: v1.0 template: metadata: labels: app: demoapp release: stable version: v1.0 spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0 ports: - name: http containerPort: 80 #查看 [root@ubuntu-200 ~]# kubectl get rs NAME DESIRED CURRENT READY AGE replicaset-demo 3 3 3 140m #详细查看 [root@ubuntu-200 ~]# kubectl describe replicasets replicaset-demo Name: replicaset-demo Namespace: default Selector: app=demoapp,release=stable,version=v1.0 Labels: <none> Annotations: <none> Replicas: 3 current / 3 desired Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed Pod Template: Labels: app=demoapp release=stable version=v1.0 Containers: demoapp: Image: ikubernetes/demoapp:v1.0 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Events: <none> [root@ubuntu-200 ~]# kubectl get replicaset -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset-demo 3 3 3 3h3m demoapp ikubernetes/demoapp:v1.0 app=demoapp,release=stable,version=v1.0 #replicaSet升级,使用kubectl set命令 [root@ubuntu-200 ~]# kubectl set --help Configure application resources These commands help you make changes to existing application resources. Available Commands: env Update environment variables on a pod template image Update image of a pod template resources Update resource requests/limits on objects with pod templates selector Set the selector on a resource serviceaccount Update ServiceAccount of a resource subject Update User, Group or ServiceAccount in a RoleBinding/ClusterRoleBinding Usage: kubectl set SUBCOMMAND [options] Use "kubectl <command> --help" for more information about a given command. Use "kubectl options" for a list of global command-line options (applies to all commands). [root@ubuntu-200 ~]# kubectl set image --help Update existing container image(s) of resources. Possible resources include (case insensitive): pod (po), replicationcontroller (rc), deployment (deploy), daemonset (ds), replicaset (rs) 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 Options: --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) --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]. Usage: kubectl set image (-f FILENAME | TYPE NAME) CONTAINER_NAME_1=CONTAINER_IMAGE_1 ... CONTAINER_NAME_N=CONTAINER_IMAGE_N [options] Use "kubectl options" for a list of global command-line options (applies to all commands). #修改镜像版本 [root@ubuntu-200 ~]# kubectl set image replicasets/replicaset-demo demoapp=ikubernetes/demoapp:v1.1 replicaset.apps/replicaset-demo image updated #再次查看详细信息,可看到镜像版本已更新为1.1 [root@ubuntu-200 ~]# kubectl get replicaset -o wide NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR replicaset-demo 3 3 3 3h7m demoapp ikubernetes/demoapp:v1.1 app=demoapp,release=stable,version=v1.0 #访问测试 [root@ubuntu-200 ~]# curl 10.244.1.98 iKubernetes demoapp v1.0 !! ClientIP: 10.244.0.0, ServerName: replicaset-demo-4dgjd, ServerIP: 10.244.1.98! #replicaset默认不会自动更新,而是删除更新,意思就是原有Pod已创建的情况下,需删除原有的Pod后,才会发生更新,且使用新版本 #删除Pod [root@ubuntu-200 ~]# kubectl delete pods replicaset-demo-4dgjd pod "replicaset-demo-4dgjd" deleted #再次查看,原有pod已删除,新建了一个Pod [root@ubuntu-200 ~]# kubectl get pods -l app=demoapp -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES downwardapi-01 1/1 Running 0 9h 10.244.5.147 c8-48 <none> <none> replicaset-demo-8t7b5 1/1 Running 0 3h14m 10.244.2.109 ubuntu-210 <none> <none> replicaset-demo-9996s 1/1 Running 0 3h14m 10.244.5.151 c8-48 <none> <none> replicaset-demo-sx7ck 1/1 Running 0 88s 10.244.1.99 ubuntu-220 <none> <none> #对新建的Pod进行测试访问,可以发现镜像版本已更新为1.1 [root@ubuntu-200 ~]# curl 10.244.1.99 iKubernetes demoapp v1.1 !! ClientIP: 10.244.0.0, ServerName: replicaset-demo-sx7ck, ServerIP: 10.244.1.99!
范例2:
#创建一个Service,和之前的ReplicaSet关联起来 [root@ubuntu-200 ~]# cat service-for-replicaset.yaml apiVersion: v1 kind: Service metadata: name: demoapp namespace: default spec: type: ClusterIP clusterIP: 10.97.26.1 selector: app: demoapp #匹配的标签要和replicaset中一致,但别加版本,以便新旧版本同时存在 release: stable ports: - name: http port: 80 protocol: TCP targetPort: 80 #创建service [root@ubuntu-200 ~]# kubectl apply -f service-for-replicaset.yaml service/demoapp created #查看service是否已匹配到Pod [root@ubuntu-200 ~]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE demoapp ClusterIP 10.97.26.1 <none> 80/TCP 9s kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d mysql-service NodePort 10.96.27.252 <none> 8080:30080/TCP 6d nginx-service NodePort 10.96.57.111 <none> 81:30016/TCP 3d23h [root@ubuntu-200 ~]# kubectl describe svc demoapp Name: demoapp Namespace: default Labels: <none> Annotations: <none> Selector: app=demoapp,release=stable Type: ClusterIP IP: 10.97.26.1 Port: http 80/TCP TargetPort: 80/TCP Endpoints: 10.244.1.99:80,10.244.2.109:80,10.244.5.151:80 #可看到已匹配到Pod Session Affinity: None Events: <none>
范例3: 蓝绿部署
#编写Service的资源清单(变量版) [root@ubuntu-200 /data/replicaset]# cat service-blue-green.yaml apiVersion: v1 kind: Service metadata: name: demoapp-svc namespace: default spec: type: ClusterIP selector: app: demoapp ctr: rs-${DEPLOY} version: ${VERSION} ports: - name: http port: 80 protocol: TCP targetPort: 80 #编写ReplicaSet资源清单(变量版) [root@ubuntu-200 /data/replicaset]# cat replicaset-blue-green.yaml apiVersion: apps/v1 kind: ReplicaSet name: rs-${DEPLOY} spec: minReadySeconds: 3 replicas: 2 selector: matchLabels: app: demoapp ctr: rs-${DEPLOY} version: ${VERSION} template: metadata: labels: app: demoapp ctr: rs-${DEPLOY} version: ${VERSION} spec: containers: - name: demoapp image: ikubernetes/demoapp:${VERSION} ports: - name: http containerPort: 80 #利用envsubst进行变量替换 [root@ubuntu-200 /data/replicaset]# DEPLOY=blue VERSION=v1.0 envsubst < replicaset-blue-green.yaml apiVersion: apps/v1 kind: ReplicaSet name: rs-blue spec: minReadySeconds: 3 replicas: 2 selector: matchLabels: app: demoapp ctr: rs-blue version: v1.0 template: metadata: labels: app: demoapp ctr: rs-blue version: v1.0 spec: containers: - name: demoapp image: ikubernetes/demoapp:v1.0 ports: - name: http containerPort: 80 #变量替换后使用管道传给kubectl命令创建ReplicaSet [root@ubuntu-200 ~]# DEPLOY=blue VERSION=v1.0 envsubst < /data/replicaset/service-blue-green.yaml | kubectl apply -f - #查看Pod [root@ubuntu-200 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE rs-blue-wnlp4 1/1 Running 0 6m53s rs-blue-x5zzr 1/1 Running 0 6m53s #创建service [root@ubuntu-200 ~]# DEPLOY=blue VERSION=v1.0 envsubst < /data/replicaset/service-blue-green.yaml | kubectl apply -f - service/demoapp-svc configured #查看Service [root@ubuntu-200 ~]# kubectl get svc -o wide NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR demoapp-svc ClusterIP 10.109.211.52 <none> 80/TCP 22m app=demoapp,ctr=rs-green,version=v1.1 #访问测试 [root@ubuntu-220 ~]# while true;do curl --connect-timeout 1 10.109.211.52;sleep .2;done iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: rs-blue-x5zzr, ServerIP: 10.244.2.113! iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.1, ServerName: rs-blue-wnlp4, ServerIP: 10.244.1.102! ... #更新版本 [root@ubuntu-200 /data/replicaset]# DEPLOY=green VERSION=v1.1 envsubst < /data/replicaset/replicaset-blue-green.yaml | kubectl apply -f - [root@ubuntu-200 /data/replicaset]# kubectl get pods #可看到更新后的pod已运行起来 NAME READY STATUS RESTARTS AGE rs-blue-5xvvj 1/1 Running 0 4h55m rs-blue-pfhl4 1/1 Running 0 4h55m rs-green-86l49 1/1 Running 0 6h53m rs-green-bbzt4 1/1 Running 0 4h55m #访问测试 [root@ubuntu-220 ~]# while true;do curl --connect-timeout 1 10.109.211.52;sleep .2;done iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: rs-blue-5xvvj, ServerIP: 10.244.3.8! iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: rs-blue-pfhl4, ServerIP: 10.244.3.15! .... #更新service [root@ubuntu-200 /data/replicaset]# DEPLOY=green VERSION=v1.1 envsubst < /data/replicaset/service-blue-green.yaml | kubectl apply -f - service/demoapp-svc configured #再次访问测试,可以看到版本以更新 [root@ubuntu-220 ~]# while true;do curl --connect-timeout 1 10.109.211.52;sleep .2;done iKubernetes demoapp v1.1 !! ClientIP: 10.244.1.0, ServerName: rs-green-86l49, ServerIP: 10.244.3.7! iKubernetes demoapp v1.1 !! ClientIP: 10.244.1.0, ServerName: rs-green-bbzt4, ServerIP: 10.244.3.21! #版本回滚,只需修改service即可实现 [root@ubuntu-200 /data/replicaset]# DEPLOY=blue VERSION=v1.0 envsubst < /data/replicaset/service-blue-green.yaml | kubectl apply -f - service/demoapp-svc configured #测试访问 [root@ubuntu-220 ~]# while true;do curl --connect-timeout 1 10.109.211.52;sleep .2;done iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: rs-blue-5xvvj, ServerIP: 10.244.3.8! iKubernetes demoapp v1.0 !! ClientIP: 10.244.1.0, ServerName: rs-blue-pfhl4, ServerIP: 10.244.3.15!
3.2 Deployment控制器
Deployment(简写为deploy)时Kubernetes控制器的又一种实现,它构建与ReplicaSet控制器之上,可为Pod和ReplicaSet资源提供声明式更新。相比较而言,Pod和ReplicaSet是较低级别的资源,它们很少被直接使用。
Deployment控制器的主要职责同样是为了保证Pod资源的健康运行,其大部分功能均可通过调用ReplicaSet控制器来实现,同时还增了新的特性。
- 事件和状态查看:必要时可以查看Deployment对象升级的详细进度和状态。 - 回滚:升级操作完成后发现问题时,支持使用回滚机制将应用返回到前一个或由用户指定点历史记录中的版本上。 - 版本记录:对Deployment对象的每一次操作都予以保存,以提供后续可能执行的回滚操作使用。 - 暂停和启动:对于每一次升级,都能够随时暂停和启动。 - 多种自动更新方案:一是Recreate,即重建更新机制,全面停止、删除旧有的Pod后用新版本替代;另一个是RollingUpdate,即滚动升级机制,逐步替换旧有的Pod至新的版本。
3.2.1 创建Deployment
Deployment是标准的KubernetesAPI资源,它构建与ReplicaSet资源之上,于是其spec字段中嵌套使用的字段包含了ReplicaSet控制器支持的replicas、selector、template和minReadySeconds,它也正是利用这些信息完成了其二次资源ReplicaSet对象的创建。
Deployment的配置规范:
apiVersion: apps/v1 # API群组及版本 kind: Deployment # 资源类型特有标识 metadata: name <string> # 资源名称,在作用域中要唯一 namespace <string> # 名称空间;Deployment隶属名称空间级别 spec: minReadySeconds <integer> # Pod就绪后多少秒内任一容器无crash方可视为“就绪” replicas <integer> # 期望的Pod副本数,默认为1 selector <object> # 标签选择器,必须匹配template字段中Pod模板中的标签 template <object> # Pod模板对象 revisionHistoryLimit <integer> # 滚动更新历史记录数量,默认为10 strategy <Object> # 滚动更新策略 type <string> # 滚动更新类型,可用值有Recreate和RollingUpdate; rollingUpdate <Object> # 滚动更新参数,专用于RollingUpdate类型 maxSurge <string> # 更新期间可比期望的Pod数量多出的数量或比例; maxUnavailable <string> # 更新期间可比期望的Pod数量缺少的数量或比例,10, progressDeadlineSeconds <integer> # 滚动更新故障超时时长,默认为600秒 paused <boolean> # 是否暂停部署过程
范例:
#编写资源清单文件 [root@ubuntu-200 /data/deployment]# cat deployment-01.yaml apiVersion: apps/v1 kind: Deployment metadata: name: deployment-myapp spec: replicas: 3 selector: matchLabels: app: myapp template: metadata: labels: app: myapp spec: containers: - name: myapp image: ikubernetes/myapp:v1 ports: - containerPort: 80 name: http #创建Deployment [root@ubuntu-200 /data/deployment]# kubectl apply -f deployment-01.yaml deployment.apps/deployment-myapp created #查看Deployment,UP-TO-DATE表示已经达到期望状态的Pod副本数量 [root@ubuntu-200 ~]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE deployment-myapp 3/3 3 3 10m #Deployment控制器会自动创建相关的ReplicaSet控制器资源,并以"[DEPLOYMENT-NAME]-[POD-TEMPLATE-HASH-VALUE]"格式为其命名,其中的hash值由Deployment控制器自动生成. [root@ubuntu-200 ~]# kubectl get replicasets.apps NAME DESIRED CURRENT READY AGE deployment-myapp-7ffb5fd5ff 3 3 3 17m #查看Deployment运行起来的Pod,Pod对象的名称遵循ReplicaSet控制器的命名格式,它以ReplicaSet控制器的名称为前缀,后跟5位随机字符: [root@ubuntu-200 ~]# kubectl get pods NAME READY STATUS RESTARTS AGE deployment-myapp-7ffb5fd5ff-2wqwt 1/1 Running 0 10m deployment-myapp-7ffb5fd5ff-8g64d 1/1 Running 0 10m deployment-myapp-7ffb5fd5ff-tp7jv 1/1 Running 0 10m #查看Deployment的详细信息 [root@ubuntu-200 ~]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp 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=myapp Containers: myapp: Image: ikubernetes/myapp:v1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-7ffb5fd5ff (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set deployment-myapp-7ffb5fd5ff to 3
3.2.2 Deployment的更新策略
Deployment控制器支持两种更新策略:
- 滚动更新(rolling update),默认更新策略:它在删除一部分就版本Pod资源的同时,补充创建一部分新版本的Pod对象进行应用升级,其优势是在升级期间,容器中应用提供的服务不会中断,但要求应用程序能够应对新旧版本同时工作的情形,例如新版本兼容同一个数据库方案等。不过,更新操作期间,不同客户端的得到的响应内容可能会来自不同版本的应用。
- 重新创建(recreate):类似于ReplicaSet的第一站更新方式,即首先删除现有的Pod对象,而后由控制器基于新模板创建出新版本资源对象。通常,只应该在应用新旧版本不兼容的情况下,才是会使用此更新策略。
Deployment控制器的滚动更新操作并非在同一个ReplicaSet控制器对象下删除并创建Pod资源,而是将它们分置于两个不同的控制器之下:就控制器的pod对象数量不断减少的同时,新控制器的Pod对象数量不断增加,直到旧控制器不在拥有Pod对象,而新控制器的副本数量完全符合期望值为止。
滚动更新时,应用升级期间还要确保可用的Pod对象数量不低于某阈值以确保可以持续处理客户端的服务请求,变动的方式和Pod对象的数量范围将通过spec.strategy.rollingUpdate.maxSurge和spec.strategy.rollingUpdate.maxUnavailable两个属性协同进行定义:
- **maxSurge**:指定升级期间存在的总Pod对象数量最多可超出期望值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;例如:如果期望值为3,当前的属性值为1,则表示Pod对象的总数不能超过4个。
- **maxUnavailable**:升级期间正常可用的Pod副本数(包括新旧版本)最低不能低于期望值的个数,其值可以是0或正整数,也可以是一个期望值的百分比;默认值为1,该值意味着如果期望值是3,则升级期间至少要有2个Pod对象处于正常提供服务的状态。
Deployment控制器也支持用户保留其滚动更新历史中的旧ReplicaSet对象版本,这赋予了控制器进行应用回滚的能力:用户可按需回滚到指定的历史版本。控制器可保存的历史版本数量由“spec.revisionHistoryLimit”属性进行定义。当然,也只有保存于revision历史中的ReplicaSet版本可用于回滚,因此,用户要习惯性地在更新操作时指定保留新旧版本。
注意:为了保存版本升级的历史,需要在创建Deployment对象时于命令中使用“--record”选项。
更新策略的选择:尽管滚动更新以节约资源著称,但它也存在一些劣势。直接改动现有环境,会使系统引入不确定性风险,而且升级过程中出现问题后,执行回滚操作也会较为缓慢。有鉴于此,金丝雀部署可能是较为理想的实现方式,当然,如果不考虑系统资源的可用性,那么蓝绿部署也是不错的选择。
3.2.3 升级Deployment
由于是声明式配置,因此对Deployment控制器资源的修改尤其适合使用apply和patch命令来进行;如果是修改容器镜像,则“set image”命令更为易用。
范例1:使用patch命令将minReadySeconds设置为5s
注意:修改Deployment控制器的minReadySeconds、replicas和strategy等字段的值不会触发Pod资源的更新操作,因为它们不属于模板的内嵌字段,对现存的Pod对象不产生任何影响。
#查看Deployment的详细信息 oot@ubuntu-200 ~]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp 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=myapp Containers: myapp: Image: ikubernetes/myapp:v1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-7ffb5fd5ff (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 23m deployment-controller Scaled up replica set deployment-myapp-7ffb5fd5ff to 3 #使用patch命令进行修改 [root@ubuntu-200 /data/deployment]# kubectl patch deployments.apps deployment-myapp -p '{"spec": {"minReadySeconds":5}}' deployment.apps/deployment-myapp patched #查看修改后的详细信息 [root@ubuntu-200 /data/deployment]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 5 #可看到等待时间已修改 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: myapp: Image: ikubernetes/myapp:v1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-7ffb5fd5ff (3/3 replicas created) Events: <none>
范例2:使用set image修改镜像版本
#查看详细信息中的镜像版本 [root@ubuntu-200 /data/deployment]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 1 Selector: app=myapp Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 5 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: myapp: Image: ikubernetes/myapp:v1 #可看到镜像版本为v1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-7ffb5fd5ff (3/3 replicas created) Events: <none> #修改镜像版本 [root@ubuntu-200 /data/deployment]# kubectl set image deployment/deployment-myapp myapp=ikubernetes/myapp:v2 deployment.apps/deployment-myapp image updated #查看更新过程 [root@ubuntu-200 /data/deployment]# kubectl rollout status deployment deployment-myapp Waiting for deployment "deployment-myapp" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "deployment-myapp" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "deployment-myapp" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "deployment-myapp" rollout to finish: 2 out of 3 new replicas have been updated... Waiting for deployment "deployment-myapp" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "deployment-myapp" rollout to finish: 1 old replicas are pending termination... Waiting for deployment "deployment-myapp" rollout to finish: 1 old replicas are pending termination... deployment "deployment-myapp" successfully rolled out #查看ReplicaSet,可以看到已更新完成 [root@ubuntu-200 /data/deployment]# kubectl get replicasets.apps -l app=myapp NAME DESIRED CURRENT READY AGE deployment-myapp-7ffb5fd5ff 0 0 0 78m deployment-myapp-d79f57d9d 3 3 3 2m25s #查看pod,可看到原有Pod已删除,新的ReplicaSet已重新创建Pod [root@ubuntu-200 /data/deployment]# kubectl get pods -l app=myapp -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deployment-myapp-d79f57d9d-fs6n4 1/1 Running 0 7m11s 10.244.2.133 ubuntu-210 <none> <none> deployment-myapp-d79f57d9d-psv67 1/1 Running 0 6m43s 10.244.1.118 ubuntu-220 <none> <none> deployment-myapp-d79f57d9d-rz8xw 1/1 Running 0 6m14s 10.244.3.55 ubuntu-184 <none> <none> #测试访问 [root@ubuntu-200 /data/deployment]# curl 10.244.2.133 Hello MyApp | Version: v2 | <a href="hostname.html">Pod Name</a> #查看Deployment的详细信息,可看到镜像版本已更新,也能看到事件中Pod的新建与删除 [root@ubuntu-200 /data/deployment]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 2 Selector: app=myapp Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 5 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: myapp: Image: ikubernetes/myapp:v2 #镜像版本 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-d79f57d9d (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 1 Normal ScalingReplicaSet 9m46s deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 2 Normal ScalingReplicaSet 9m46s deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 2 Normal ScalingReplicaSet 9m17s deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 1 Normal ScalingReplicaSet 9m17s deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 3 Normal ScalingReplicaSet 8m41s deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 0
3.2.4 回滚Deployment
若因各种原因导致滚动更新无法正常进行,如镜像文件获取、“金丝雀”遇险等,则应该将应用回滚到之前的版本,或者回滚到奥由用户指定的历史记录中的版本。
相关命令:
# 查看升级的历史记录 # kubectl rollout history deployment/<deployment-name> #回滚到当前版本的上一个版本 # kubectl rollout undo deployment/<deployment-name> #回滚到指定版本 # kubectl rollout undo deployment/<deployment-name> --to-revision=版本号 #停止更新(可用于金丝雀发布) # kubectl rollout pause deployment/<deployment-name> #继续更新(可用于金丝雀发布) # kubectl rollout reuse deployment/<deployment-name>
#查看升级的历史记录 [root@ubuntu-200 /data/deployment]# kubectl rollout history deployment/deployment-myapp deployment.apps/deployment-myapp REVISION CHANGE-CAUSE 1 <none> 2 <none> #回滚到上一版本 [root@ubuntu-200 /data/deployment]# kubectl rollout undo deployment deployment-myapp deployment.apps/deployment-myapp rolled back #可看到Pod回滚过程 [root@ubuntu-200 /data/deployment]# kubectl get pods NAME READY STATUS RESTARTS AGE deployment-myapp-7ffb5fd5ff-4qszl 1/1 Running 0 21s deployment-myapp-7ffb5fd5ff-56fv4 1/1 Running 0 13s deployment-myapp-7ffb5fd5ff-vc8hs 0/1 ContainerCreating 0 2s deployment-myapp-d79f57d9d-psv67 0/1 Terminating 0 21m deployment-myapp-d79f57d9d-rz8xw 1/1 Running 0 21m replicaset-demo-v1.1-d8n24 1/1 Running 2 18h replicaset-demo-v1.1-h4fxg 1/1 Running 2 20h replicaset-demo-v1.1-xn5g4 1/1 Running 2 18h rs-blue-5xvvj 1/1 Running 2 18h rs-blue-pfhl4 1/1 Running 2 18h rs-green-86l49 1/1 Running 2 20h rs-green-bbzt4 1/1 Running 2 18h #查看ReplicaSet已回滚到上一个版本 [root@ubuntu-200 /data/deployment]# kubectl get replicaset -l app=myapp NAME DESIRED CURRENT READY AGE deployment-myapp-7ffb5fd5ff 3 3 3 99m deployment-myapp-d79f57d9d 0 0 0 23m #访问测试,可看到版本已回滚 [root@ubuntu-200 /data/deployment]# kubectl get pods -l app=myapp -o wide NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES deployment-myapp-7ffb5fd5ff-4qszl 1/1 Running 0 2m19s 10.244.2.134 ubuntu-210 <none> <none> deployment-myapp-7ffb5fd5ff-56fv4 1/1 Running 0 2m11s 10.244.1.119 ubuntu-220 <none> <none> deployment-myapp-7ffb5fd5ff-vc8hs 1/1 Running 0 2m 10.244.3.56 ubuntu-184 <none> <none> [root@ubuntu-200 /data/deployment]# curl 10.244.2.134 Hello MyApp | Version: v1 | <a href="hostname.html">Pod Name</a> #查看升级版本,由于默认为1版本,所以回滚后,1版本变为3版本 [root@ubuntu-200 /data/deployment]# kubectl rollout history deployment deployment-myapp deployment.apps/deployment-myapp REVISION CHANGE-CAUSE 2 <none> 3 <none> #详细信息中,事件已更新 [root@ubuntu-200 /data/deployment]# kubectl describe deployments.apps deployment-myapp Name: deployment-myapp Namespace: default CreationTimestamp: Tue, 15 Dec 2020 01:49:34 +0000 Labels: <none> Annotations: deployment.kubernetes.io/revision: 3 Selector: app=myapp Replicas: 3 desired | 3 updated | 3 total | 3 available | 0 unavailable StrategyType: RollingUpdate MinReadySeconds: 5 RollingUpdateStrategy: 25% max unavailable, 25% max surge Pod Template: Labels: app=myapp Containers: myapp: Image: ikubernetes/myapp:v1 Port: 80/TCP Host Port: 0/TCP Environment: <none> Mounts: <none> Volumes: <none> Conditions: Type Status Reason ---- ------ ------ Available True MinimumReplicasAvailable Progressing True NewReplicaSetAvailable OldReplicaSets: <none> NewReplicaSet: deployment-myapp-7ffb5fd5ff (3/3 replicas created) Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal ScalingReplicaSet 26m deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 1 Normal ScalingReplicaSet 26m deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 2 Normal ScalingReplicaSet 26m deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 2 Normal ScalingReplicaSet 25m deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 1 Normal ScalingReplicaSet 25m deployment-controller Scaled up replica set deployment-myapp-d79f57d9d to 3 Normal ScalingReplicaSet 24m deployment-controller Scaled down replica set deployment-myapp-7ffb5fd5ff to 0 Normal ScalingReplicaSet 4m33s deployment-controller Scaled up replica set deployment-myapp-7ffb5fd5ff to 1 Normal ScalingReplicaSet 4m25s deployment-controller Scaled down replica set deployment-myapp-d79f57d9d to 2 Normal ScalingReplicaSet 4m25s deployment-controller Scaled up replica set deployment-myapp-7ffb5fd5ff to 2 Normal ScalingReplicaSet 4m14s (x2 over 102m) deployment-controller Scaled up replica set deployment-myapp-7ffb5fd5ff to 3 Normal ScalingReplicaSet 4m14s deployment-controller Scaled down replica set deployment-myapp-d79f57d9d to 1 Normal ScalingReplicaSet 4m7s deployment-controller Scaled down replica set deployment-myapp-d79f57d9d to 0
3.2.5 Deployment扩容和缩容
扩容:增加期望副本的数量
缩容:减少期望副本的数量
相关命令:
# kubectl scale deployment <deployment-name> --replicas 期望的副本数量(数字) 例子: # kubectl scale deployment nginx-deployment --replicas 10 #暂停更新 # kubectl rollout pause deployment/<deployment-name>
范例1:扩容
#使用命令扩容 [root@ubuntu-200 /data/deployment]# kubectl scale deployment --replicas=4 deployment-myapp deployment.apps/deployment-myapp scaled #查看pod [root@ubuntu-200 /data/deployment]# kubectl get pods -l app=myapp NAME READY STATUS RESTARTS AGE deployment-myapp-7ffb5fd5ff-4qszl 1/1 Running 0 9m24s deployment-myapp-7ffb5fd5ff-56fv4 1/1 Running 0 9m16s deployment-myapp-7ffb5fd5ff-pmcpn 1/1 Running 0 35s deployment-myapp-7ffb5fd5ff-vc8hs 1/1 Running 0 9m5s [root@ubuntu-200 /data/deployment]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE deployment-myapp 4/4 4 4 107m
范例2:缩容
[root@ubuntu-200 /data/deployment]# kubectl scale deployment deployment-myapp --replicas=3 deployment.apps/deployment-myapp scaled [root@ubuntu-200 /data/deployment]# kubectl get pods -l app=myapp NAME READY STATUS RESTARTS AGE deployment-myapp-7ffb5fd5ff-4qszl 1/1 Running 0 13m deployment-myapp-7ffb5fd5ff-56fv4 1/1 Running 0 13m deployment-myapp-7ffb5fd5ff-vc8hs 1/1 Running 0 13m [root@ubuntu-200 /data/deployment]# kubectl get deployments.apps NAME READY UP-TO-DATE AVAILABLE AGE deployment-myapp 3/3 3 3 111m
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· DeepSeek在M芯片Mac上本地化部署