k8s控制器Replicaset和Deployment

前面我们学习了Pod,那我们在定义pod资源时,可以直接创建一个kind:Pod类型的自主式pod,但是这存在一个问题,假如pod被删除了,那这个pod就不能自我恢复,就会彻底被删除,线上这种情况非常危险,所以今天就给大家讲解下pod的控制器,所谓控制器就是能够管理pod,监测pod运行状况,当pod发生故障,可以自动恢复pod。也就是说能够代我们去管理pod中间层,并帮助我们确保每一个pod资源始终处于我们所定义或者我们所期望的目标状态,一旦pod资源出现故障,那么控制器会尝试重启pod或者里面的容器,如果一直重启有问题的话那么它可能会基于某种策略来进行重新布派或者重新编排;如果pod副本数量低于用户所定义的目标数量,它也会自动补全;如果多余,也会自动终止pod资源。

1、Replicaset控制器

1.1 Replicaset概述

ReplicaSet是kubernetes中的一种副本控制器,简称rs,主要作用是控制由其管理的pod,使pod副本的数量始终维持在预设的个数。它的主要作用就是保证一定数量的Pod能够在集群中正常运行,它会持续监听这些Pod的运行状态,在Pod发生故障时重启pod,pod数量减少时重新运行新的 Pod副本。官方推荐不要直接使用ReplicaSet,用Deployments取而代之,Deployments是比ReplicaSet更高级的概念,它会管理ReplicaSet并提供很多其它有用的特性,最重要的是Deployments支持声明式更新,声明式更新的好处是不会丢失历史变更。所以Deployment控制器不直接管理Pod对象,而是由 Deployment 管理ReplicaSet,再由ReplicaSet负责管理Pod对象。

1.2 Replicaset 工作原理:如何管理pod?

Replicaset核心作用在于代用户创建指定数量的pod副本,并确保pod副本一直处于满足用户期望的数量, 起到多退少补的作用,并且还具有自动扩容缩容等机制。

Replicaset控制器主要由三个部分组成:

1、用户期望的pod副本数:用来定义由这个控制器管控的pod副本有几个

2、标签选择器:选定哪些pod是自己管理的,如果通过标签选择器选到的pod副本数量少于我们指定的数量,需要用到下面的组件

3、pod资源模板:如果集群中现存的pod数量不够我们定义的副本中期望的数量怎么办,需要新建pod,这就需要pod模板,新建的pod是基于模板来创建的。

1.3 Replicaset资源清单文件编写技巧

查看定义Replicaset资源需要的字段有哪些

1
2
3
4
5
6
7
8
9
10
11
12
[root@master2 ~]# kubectl explain rs
KIND: ReplicaSet
VERSION: apps/v1
DESCRIPTION:
ReplicaSet ensures that a specified number of pod replicas are running at
any given time.
FIELDS:
apiVersion <string> #当前资源使用的api版本,跟VERSION: apps/v1保持一致
kind <string> #资源类型,跟KIND: ReplicaSet保持一致
metadata <Object> #元数据,定义Replicaset名字的
spec <Object> ##定义副本数、定义标签选择器、定义Pod模板
status <Object> #状态信息,不能改

查看replicaset的spec字段如何定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
[root@master2 ~]# kubectl explain rs.spec
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Spec defines the specification of the desired behavior of the ReplicaSet.
More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
ReplicaSetSpec is the specification of a ReplicaSet.
FIELDS:
minReadySeconds <integer>
replicas <integer> #定义的pod副本数,根据我们指定的值创建对应数量的pod
selector <Object> -required- #用于匹配pod的标签选择器
template <Object> #定义Pod的模板,基于这个模板定义的所有pod是一样的

查看replicaset的spec.template字段如何定义

1
2
3
4
5
6
7
8
9
10
11
[root@master2 ~]# kubectl explain rs.spec.template
KIND: ReplicaSet
VERSION: apps/v1
RESOURCE: template <Object>
DESCRIPTION:
Template is the object that describes the pod that will be created if
insufficient replicas are detected。PodTemplateSpec describes the data a pod should have when created from a
template
FIELDS:
metadata <Object>
spec <Object>

通过上面可以看到,ReplicaSet资源中有两个spec字段。第一个spec声明的是ReplicaSet定义多少个Pod副本(默认将仅部署1个Pod)、匹配Pod标签的选择器、创建pod的模板。第二个spec是spec.template.spec:主要用于Pod里的容器属性等配置。

.spec.template里的内容是声明Pod对象时要定义的各种属性,所以这部分也叫做PodTemplate(Pod模板)。还有一个值得注意的地方是:在.spec.selector中定义的标签选择器必须能够匹配到spec.template.metadata.labels里定义的Pod标签,否则Kubernetes将不允许创建ReplicaSet。

1.4 使用replicaset部署guestbook留言板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@master1 replicaset]# cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 3
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: yecc/gcr.io-google_samples-gb-frontend:v3
imagePullPolicy: IfNotPresent


[root@master1 replicaset]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend-k5px7 1/1 Running 0 6m23s 172.16.104.29 node2 <none> <none>
frontend-tpdms 1/1 Running 0 6m23s 172.16.104.28 node2 <none> <none>
frontend-znzcp 1/1 Running 0 6m23s 172.16.104.27 node2 <none> <none>

1.5 Replicaset管理pod

Replicaset实现pod的动态扩容与缩容

ReplicaSet最核心的功能是可以动态扩容和回缩,如果我们觉得两个副本太少了,想要增加,只需要修改配置文件replicaset.yaml里的replicas的值即可,原来replicas: 3,现在变成replicaset 5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
[root@master1 replicaset]# cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 5
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: yecc/gcr.io-google_samples-gb-frontend:v3
imagePullPolicy: IfNotPresent


[root@master1 replicaset]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend-56gws 1/1 Running 0 26s 172.16.104.30 node2 <none> <none>
frontend-grvqv 1/1 Running 0 26s 172.16.166.172 node1 <none> <none>
frontend-k5px7 1/1 Running 0 7m46s 172.16.104.29 node2 <none> <none>
frontend-tpdms 1/1 Running 0 7m46s 172.16.104.28 node2 <none> <none>
frontend-znzcp 1/1 Running 0 7m46s 172.16.104.27 node2 <none> <none>

使用kubectl edit rs实现扩容,修改字段replicas为10

1
2
3
4
5
6
7
8
9
10
11
12
13
[root@master1 replicaset]# kubectl edit rs frontend 
[root@master1 replicaset]# kubectl get pods -owide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
frontend-56gws 1/1 Running 0 4m29s 172.16.104.30 node2 <none> <none>
frontend-7pxtm 1/1 Running 0 51s 172.16.166.174 node1 <none> <none>
frontend-grvqv 1/1 Running 0 4m29s 172.16.166.172 node1 <none> <none>
frontend-k5px7 1/1 Running 0 11m 172.16.104.29 node2 <none> <none>
frontend-t8dwp 1/1 Running 0 51s 172.16.104.31 node2 <none> <none>
frontend-tpdms 1/1 Running 0 11m 172.16.104.28 node2 <none> <none>
frontend-wvljx 1/1 Running 0 51s 172.16.166.175 node1 <none> <none>
frontend-xtghz 1/1 Running 0 51s 172.16.104.32 node2 <none> <none>
frontend-znzcp 1/1 Running 0 11m 172.16.104.27 node2 <none> <none>
frontend-zpbf2 1/1 Running 0 52s 172.16.166.173 node1 <none> <none>

Replicaset实现pod的升级

修改replicaset的配置文件中image字段,kubectl apply -f 应用配置文件会发现pods并没有改变,需要手动kubectl delete pods才能生效。

使用kubectl edit rs 也是一样不会实时生效,只能kubectl delete pods之后才能生效

生产环境如果升级,可以删除一个pod,观察一段时间之后没问题再删除另一个pod,但是这样需要人工干预多次;实际生产环境一般采用蓝绿发布,原来有一个rs1,再创建一个rs2(控制器),通过修改service标签,修改service可以匹配到rs2的控制器,这样才是蓝绿发布,这个也需要我们精心的部署规划,我们有一个控制器就是建立在rs之上完成的,叫做Deployment

2、Deployment控制器

2.1 Deployment概述

Deployment官方文档:

https://kubernetes.io/docs/concepts/workloads/controllers/deployment/

Deployment是kubernetes中最常用的资源对象,为ReplicaSet和Pod的创建提供了一种声明式的定义方法,在Deployment对象中描述一个期望的状态,Deployment控制器就会按照一定的控制速率把实际状态改成期望状态,通过定义一个Deployment控制器会创建一个新的ReplicaSet控制器,通过ReplicaSet创建pod,删除Deployment控制器,也会删除Deployment控制器下对应的ReplicaSet控制器和pod资源.

使用Deployment而不直接创建ReplicaSet是因为Deployment对象拥有许多ReplicaSet没有的特性,例如滚动升级和回滚。

扩展:声明式定义是指直接修改资源清单yaml文件,然后通过kubectl apply -f 资源清单yaml文件,就可以更改资源

Deployment控制器是建立在rs之上的一个控制器,可以管理多个rs,每次更新镜像版本,都会生成一个新的rs,把旧的rs替换掉,多个rs同时存在,但是只有一个rs运行。

rs v1控制三个pod,删除一个pod,在rs v2上重新建立一个,依次类推,直到全部都是由rs v2控制,如果rs v2有问题,还可以回滚,Deployment是建构在rs之上的,多个rs组成一个Deployment,但是只有一个rs处于活跃状态.

image-20220820155403393

2.2 Deployment 工作原理

Deployment可以使用声明式定义,直接在命令行通过纯命令的方式完成对应资源版本的内容的修改,也就是通过打补丁的方式进行修改;Deployment能提供滚动式自定义自控制的更新;对Deployment来讲,我们在实现更新时还可以实现控制更新节奏和更新逻辑。

什么叫做更新节奏和更新逻辑呢?

一般都是增加后pod删除原来的pod

比如说Deployment控制5个pod副本,pod的期望值是5个,但是升级的时候需要额外多几个pod,那我们控制器可以控制在5个pod副本之外还能再增加几个pod副本;比方说能多一个,但是不能少,那么升级的时候就是先增加一个,再删除一个,增加一个删除一个,始终保持pod副本数是5个;还有一种情况,最多允许多一个,最少允许少一个,也就是最多6个,最少4个,第一次加一个,删除两个,第二次加两个,删除两个,依次类推,可以自己控制更新方式,这种滚动更新需要加readinessProbe和livenessProbe探测,确保pod中容器里的应用都正常启动了才删除之前的pod。

启动第一步,刚更新第一批就暂停了也可以;假如目标是5个,允许一个也不能少,允许最多可以10个,那一次加5个即可;这就是我们可以自己控制节奏来控制更新的方法。

通过Deployment对象,你可以轻松的做到以下事情

1、创建ReplicaSet和Pod

2、滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)

3、平滑地扩容和缩容

4、暂停和继续Deployment

2.3 Deployment资源清单文件编写技巧

查看Deployment资源对象由哪几部分组成

1
2
3
4
5
6
7
8
9
10
KIND:     Deployment
VERSION: apps/v1
DESCRIPTION:
Deployment enables declarative updates for Pods and ReplicaSets.
FIELDS:
apiVersion <string> #该资源使用的api版本
kind <string> #创建的资源是什么?
metadata <Object> #元数据,包括资源的名字和名称空间
spec <Object> #定义容器的
status <Object> #状态,不可以修改

查看Deployment下的spec字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
KIND:     Deployment
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the Deployment.
DeploymentSpec is the specification of the desired behavior of the
Deployment.
FIELDS:
minReadySeconds <integer>
#Kubernetes在等待设置的时间后才进行升级,默认时间是0秒
#如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
paused <boolean> #暂停,当我们更新的时候创建pod先暂停,不是立即更新
progressDeadlineSeconds <integer>
# k8s 在升级过程中有可能由于各种原因升级卡住(这个时候还没有明确的升级失败),比如在拉取被墙的镜像,权限不够等错误。那么这个时候就需要有个 deadline ,在 deadline 之内如果还卡着,那么就上报这个情况,这个时候这个 Deployment 状态就被标记为 False,并且注明原因。但是它并不会阻止 Deployment 继续进行卡住后面的操作。完全由用户进行控制。
replicas <integer> #副本数
revisionHistoryLimit <integer> #保留的历史版本,默认是10
selector <Object> -required- #标签选择器,选择它关联的pod
strategy <Object> #更新策略
template <Object> -required #定义的pod模板

查看Deployment下的spec.strategy字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KIND:     Deployment
VERSION: apps/v1
RESOURCE: strategy <Object>
DESCRIPTION:
The deployment strategy to use to replace existing pods with new ones.
DeploymentStrategy describes how to replace existing pods with new ones.
FIELDS:
rollingUpdate <Object>
type <string>
Type of deployment. Can be "Recreate" or "RollingUpdate". Default is
RollingUpdate.
#支持两种更新,Recreate和RollingUpdate
#Recreate是重建式更新,删除一个更新一个
#RollingUpdate滚动更新,定义滚动更新方式,也就是pod能多几个,少几个

查看Deployment下的spec.strategy.rollingUpdate字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
KIND:     Deployment
VERSION: apps/v1
RESOURCE: rollingUpdate <Object>
DESCRIPTION:
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.
Spec to control the desired behavior of rolling update.
FIELDS:
maxSurge <string>
#我们更新的过程当中最多允许超出的指定的目标副本数有几个;
#它有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示原本是5个,最多可以超出20%,那就允许多一个,最多可以超过40%,那就允许多两个
maxUnavailable <string>
#最多允许几个不可用
#假设有5个副本,最多一个不可用,就表示最少有4个可用

查看Deployment下的spec.template字段

1
2
3
4
5
6
7
8
9
10
11
#template为定义Pod的模板,Deployment通过模板创建Pod
KIND: Deployment
VERSION: apps/v1
RESOURCE: template <Object>
DESCRIPTION:
Template describes the pods that will be created.
PodTemplateSpec describes the data a pod should have when created from a template
FIELDS:
metadata <Object> #定义模板的名字
spec <Object>
#deployment.spec.template为Pod定义的模板,和Pod定义不太一样,template中不包含apiVersion和Kind属性,要求必须有metadata。#deployment.spec.template.spec为容器的属性信息,其他定义内容和Pod一致。

查看Deployment下的spec.template.spec字段

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
KIND:     Deployment
VERSION: apps/v1
RESOURCE: spec <Object>
DESCRIPTION:
Specification of the desired behavior of the pod. More info:
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
PodSpec is a description of a pod.
FIELDS:
activeDeadlineSeconds <integer>
#activeDeadlineSeconds表示Pod 可以运行的最长时间,达到设置的该值后,Pod 会自动停止。
affinity <Object> #定义亲和性,跟直接创建pod时候定义亲和性类似
automountServiceAccountToken <boolean> #身份认证相关的
containers <[]Object> -required- #定义容器属性
dnsConfig <Object> #设置Pod的DNS
dnsConfig:
nameservers:
- 192.xxx.xxx.6
searches:
- xianchao.svc.cluster.local
- my.dns.search.xianchao
dnsPolicy <string> # dnsPolicy决定Pod 内预设的DNS 配置策略

None 无任何策略:使用自定义的策略
Default 默认:使用宿主机的dns配置,/etc/resolv.conf
ClusterFirst 集群DNS优先,与 Default 相反,会预先使用 kube-dns (或 CoreDNS ) 的信息当预设置参数写入到该 Pod 内的DNS配置。
ClusterFirstWithHostNet 集群 DNS 优先,并伴随着使用宿主机网络:同时使用 hostNetwork 与 kube-dns 作为 Pod 预设 DNS 配置。

enableServiceLinks <boolean>
ephemeralContainers <[]Object> #定义临时容器
临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 ContainerSpec 段进行描述,但许多字段是不相容且不允许的。
临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
Pod 资源分配是不可变的,因此 resources 配置是不允许的。

临时容器用途:
当由于容器崩溃或容器镜像不包含调试应用程序而导致 kubectl exec 无用时,临时容器对于交互式故障排查很有用。

hostAliases <[]Object> #在pod中增加域名解析的
hostAliases:
– ip: "10.1.2.2"
hostnames:
"mc.local"
"rabbitmq.local"
– ip: "10.1.2.3"
hostnames:
"redis.local"
"mq.local"
hostIPC <boolean> #使用主机IPC
hostNetwork <boolean> #是否使用宿主机的网络
hostPID <boolean> #可以设置容器里是否可以看到宿主机上的进程。True可以
hostname <string>
imagePullSecrets <[]Object>#定义harbor账号密码的
initContainers <[]Object> #定义初始化容器
nodeName <string> #定义pod调度到具体哪个节点上
nodeSelector <map[string]string> #定义节点选择器
overhead <map[string]string> #overhead是1.16引入的字段,在没有引入 Overhead 之前,只要一个节点的资源可用量大于等于 Pod 的 requests 时,这个 Pod 就可以被调度到这个节点上。引入 Overhead 之后,只有节点的资源可用量大于等于 Overhead 加上 requests 的和时才能被调度上来。也就是说起到资源限额的作用
preemptionPolicy <string>
priority <integer>
priorityClassName <string>
readinessGates <[]Object>
restartPolicy <string> #Pod重启策略
runtimeClassName <string>
schedulerName <string>
securityContext <Object> #是否开启特权模式
serviceAccount <string>
serviceAccountName <string>
setHostnameAsFQDN <boolean>
shareProcessNamespace <boolean>
subdomain <string>
terminationGracePeriodSeconds <integer>
#在真正删除容器之前,K8S会先发终止信号(kill -15 {pid})给容器,默认30s,优雅删除时间
tolerations <[]Object> #定义容忍度
topologySpreadConstraints <[]Object
volumes <[]Object> #挂载存储卷

使用HostAliases建立pod host文件的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[root@master1 replicaset]# cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 5
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: yecc/gcr.io-google_samples-gb-frontend:v3
imagePullPolicy: IfNotPresent
hostAliases:
- hostnames:
- zy1
- zy1.localhost
ip: 192.168.106.11


#进入容器查看解析是否生效
[root@master1 replicaset]# kubectl exec -it frontend-79zbk -- /bin/bash
root@frontend-79zbk:/var/www/html# cat /etc/hosts | grep 192.168.106.11
192.168.106.11 zy1 zy1.localhost

添加dnsConfig字段添加pod容器dns(dnsPolicy 需配置为none,使容器的dns全靠dnsConfig字段下的配置所控制)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
[root@master1 replicaset]# cat replicaset.yaml 
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: frontend
labels:
app: guestbook
tier: frontend
spec:
replicas: 5
selector:
matchLabels:
tier: frontend
template:
metadata:
labels:
tier: frontend
spec:
containers:
- name: php-redis
image: yecc/gcr.io-google_samples-gb-frontend:v3
imagePullPolicy: IfNotPresent
hostAliases:
- hostnames:
- zy1
- zy1.localhost
ip: 192.168.106.11
dnsPolicy: None
dnsConfig:
nameservers:
- 114.114.114.114
searches:
- baidu.com


#查看pod的配置
[root@master1 replicaset]# kubectl exec -it frontend-4fdk6 -- /bin/bash
root@frontend-4fdk6:/var/www/html# cat /etc/resolv.conf
nameserver 114.114.114.114
search baidu.com

2.4 Deployment实现pod的动态扩容与缩容

可以直接使用kubectl edit deployments.apps myapp-v1来实现动态的扩容与缩容 ;或者修改yaml文件,重新apply

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@master1 deployment]# cat deploy_demo.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 10
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
name: test
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
httpGet:
port: 80
initialDelaySeconds: 10
failureThreshold: 3

2.5 Deployment的更新与回滚

原始配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@master1 deployment]# cat deploy_demo.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 10
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
name: test
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
httpGet:
port: 80
initialDelaySeconds: 10
failureThreshold: 3

更新版本的配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
[root@master1 deployment]# cat deploy_demo.yml 
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 10
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
name: test
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v2
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
livenessProbe:
httpGet:
port: 80
initialDelaySeconds: 10
failureThreshold: 3

滚动更新deployment

apply -f 修改后的配置文件

1
2
[root@master1 deployment]# kubectl apply -f deploy_demo.yml 
deployment.apps/myapp-v1 configured

查看replicaset

1
2
3
4
[root@master1 deployment]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-v1-79bdff79d4 10 10 10 105s
myapp-v1-99c4cd79 0 0 0 6m10s

回滚操作

maxSurge和maxUnavailable用来控制滚动更新的更新策略

取值范围

数值

  1. maxUnavailable: [0, 副本数]

  2. maxSurge: [0, 副本数]

注意:两者不能同时为0。

比例

  1. maxUnavailable: [0%, 100%] 向下取整,比如10个副本,5%的话==0.5个,但计算按照0个;

  2. maxSurge: [0%, 100%] 向上取整,比如10个副本,5%的话==0.5个,但计算按照1个;

注意:两者不能同时为0。

建议配置

  1. maxUnavailable == 0

  2. maxSurge == 1

这是我们生产环境提供给用户的默认配置。即“一上一下,先上后下”最平滑原则:

1个新版本pod ready(结合readiness)后,才销毁旧版本pod。此配置适用场景是平滑更新、保证服务平稳,但也有缺点,就是“太慢”了。

总结:

maxUnavailable:和期望的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;

maxSurge:和期望的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。

自定义策略:

修改更新策略:maxUnavailable=1,maxSurge=1

[root@xianchaomaster1 ~]# kubectl patch deployment myapp-v1 -p ‘{“spec”:{“strategy”:{“rollingUpdate”: {“maxSurge”:1,”maxUnavailable”:1}}}}’ -n blue-green

查看myapp-v1这个控制器的详细信息

[root@xianchaomaster1 ~]# kubectl describe deployment myapp-v1 -n blue-green

显示如下:

RollingUpdateStrategy: 1 max unavailable, 1 max surge

上面可以看到RollingUpdateStrategy: 1 max unavailable, 1 max surge

这个rollingUpdate更新策略变成了刚才设定的,因为我们设定的pod副本数是3,1和1表示最少不能少于2个pod,最多不能超过4个pod

这个就是通过控制RollingUpdateStrategy这个字段来设置滚动更新策略的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@master2 ~]# kubectl explain deploy.spec.strategy.rollingUpdate
KIND: Deployment
VERSION: apps/v1

RESOURCE: rollingUpdate <Object>

DESCRIPTION:
Rolling update config params. Present only if DeploymentStrategyType =
RollingUpdate.

Spec to control the desired behavior of rolling update.

FIELDS:
maxSurge <string>
The maximum number of pods that can be scheduled above the desired number
of pods. Value can be an absolute number (ex: 5) or a percentage of desired
pods (ex: 10%). This can not be 0 if MaxUnavailable is 0. Absolute number
is calculated from percentage by rounding up. Defaults to 25%. Example:
when this is set to 30%, the new ReplicaSet can be scaled up immediately
when the rolling update starts, such that the total number of old and new
pods do not exceed 130% of desired pods. Once old pods have been killed,
new ReplicaSet can be scaled up further, ensuring that total number of pods
running at any time during the update is at most 130% of desired pods.

maxUnavailable <string>
The maximum number of pods that can be unavailable during the update. Value
can be an absolute number (ex: 5) or a percentage of desired pods (ex:
10%). Absolute number is calculated from percentage by rounding down. This
can not be 0 if MaxSurge is 0. Defaults to 25%. Example: when this is set
to 30%, the old ReplicaSet can be scaled down to 70% of desired pods
immediately when the rolling update starts. Once new pods are ready, old
ReplicaSet can be scaled down further, followed by scaling up the new
ReplicaSet, ensuring that the total number of pods available at all times
during the update is at least 70% of desired pods.

查看历史版本

1
2
3
4
5
[root@master1 deployment]# kubectl rollout history deployment myapp-v1 
deployment.apps/myapp-v1
REVISION CHANGE-CAUSE
1 <none>
2 <none>

回滚到1版本

1
2
[root@master1 deployment]# kubectl rollout undo deployment myapp-v1 --to-revision=1
deployment.apps/myapp-v1 rolled back

2.6 Deployment资源清单详解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: ms
spec:
replicas: 1
selector:
matchLabels:
project: ms
app: portal
template:
metadata:
labels:
project: ms
app: portal
spec:
containers:
- name: portal
image: xianchao/portal:v1
imagePullPolicy: Always
ports:
- protocol: TCP
containerPort: 8080
resources: #资源配额
limits: #资源限制,最多可用的cpu和内存
cpu: 1
memory: 1Gi
requests: #最少需要多少资源才可以运行Pod
cpu: 0.5
memory: 1Gi
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
livenessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 60
periodSeconds: 10

livenessProbe:

存活性探测

用于判断容器是否存活,即Pod是否为running状态,如果LivenessProbe探针探测到容器不健康,则kubelet将kill掉容器,并根据容器的重启策略是否重启。如果一个容器不包含LivenessProbe探针,则Kubelet认为容器的LivenessProbe探针的返回值永远成功。

tcpSocket:

port: 8080 ##检测8080端口是否存在

initialDelaySeconds: 60 ##Pod启动60s执行第一次检查

periodSeconds: 10 ##第一次检查后每隔10s检查一次

readinessProbe: ##就绪性探测

有时候应用程序可能暂时无法接受请求,比如Pod已经Running了,但是容器内应用程序尚未启动成功,在这种情况下,如果没有ReadinessProbe,则Kubernetes认为它可以处理请求了,然而此时,我们知道程序还没启动成功是不能接收用户请求的,所以不希望kubernetes把请求调度给它,则使用ReadinessProbe探针。

ReadinessProbe和livenessProbe可以使用相同探测方式,只是对Pod的处置方式不同,ReadinessProbe是将Pod IP:Port从对应的EndPoint列表中删除,而livenessProbe则Kill容器并根据Pod的重启策略来决定作出对应的措施。

ReadinessProbe探针探测容器是否已准备就绪,如果未准备就绪则kubernetes不会将流量转发给此Pod。

tcpSocket:

port: 8080

initialDelaySeconds: 60

periodSeconds: 10

在Pod运行过程中,K8S仍然会每隔10s检测8080端口


本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!