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
posted @ 2023-09-10 17:32  yt丶独自  阅读(29)  评论(0编辑  收藏  举报