k8s控制器--Replicaset和Deployment
一、Replicaset控制器
2.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对象。
2.2、Replicaset工作原理
Replicaset核心作用在于用户创建指定数量的pod副本,并确保pod副本一直处于满足用户期望的数量, 起到多退少补的作用,并且还具有自动扩容缩容等制。
Replicaset控制器主要由三个部分组成:
1、用户期望的pod副本数:用来定义由这个控制器管控的pod副本有几个
2、标签选择器:选定哪些pod是自己管理的,如果通过标签选择器选到的pod副本数量少于我们指定的数量,需要用到下面的组件
3、pod资源模板:如果集群中现存的pod数量不够我们定义的副本中期望的数量怎么办,需要新建pod,这就需要pod模板,新建的pod是基于模板来创建的。
2.3、Replicaset使用案例
#编写一个ReplicaSet资源清单
[root@k8s-master1 ~]# 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@k8s-master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend created
[root@k8s-master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
frontend 3 3 3 48s
[root@k8s-master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-8p5lq 1/1 Running 0 54s
frontend-9hjr8 1/1 Running 0 54s
frontend-nt6kb 1/1 Running 0 54s
2.4、Replicaset管理pod
2.4.1、实现pod的动态扩缩容
方式一:修改yaml文件的replicas值,重新apply
方式二:使用kubectl edit rs frontend
动态修改
# 方式一
[root@k8s-master1 ~]# vim replicaset.yaml
replicas: 4
[root@k8s-master1 ~]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend configured
[root@k8s-master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
frontend-8p5lq 1/1 Running 0 22m
frontend-9hjr8 1/1 Running 0 22m
frontend-nt6kb 1/1 Running 0 22m
frontend-vhz2g 1/1 Running 0 5s
# 方式二
[root@k8s-master1 ~]# kubectl edit rs frontend
2.4.2、实现pod的版本更新
修改yaml文件的image或者使用kubectl edit命令修改镜像只会影响新生成的pod,对原先的pod没有影响,只能删除原先的pod才能完成版本更新。
生产环境如果升级,可以删除一个pod,观察一段时间之后没问题再删除另一个pod,但是这样需要人工干预多次;实际生产环境一般采用蓝绿发布,原来有一个rs1,再创建一个rs2(控制器),通过修改service标签,修改service可以匹配到rs2的控制器,这样才是蓝绿发布,这个也需要我们精心的部署规划,我们有一个控制器就是建立在rs之上完成的,叫做Deployment
二、Deployment控制器
Deployment官方文档:https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
2.1、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处于活跃状态.
2.2、Deployment工作原理
Deployment可以使用声明式定义,直接在命令行通过纯命令的方式完成对应资源版本的内容的修改,也就是通过打补丁的方式进行修改;Deployment能提供滚动式自定义自控制的更新;对Deployment来讲,我们在实现更新时还可以实现控制更新节奏和更新逻辑。
更新节奏和更新逻辑:
比如说Deployment控制5个pod副本,pod的期望值是5个,但是升级的时候需要额外多几个pod,那我们控制器可以控制在5个pod副本之外还能再增加几个pod副本;比方说能多一个,但是不能少,那么升级的时候就是先增加一个,再删除一个,增加一个删除一个,始终保持pod副本数是5个;还有一种情况,最多允许多一个,最少允许少一个,也就是最多6个,最少4个,第一次加一个,删除两个,第二次加两个,删除两个,依次类推,可以自己控制更新方式,这种滚动更新需要加readinessProbe和livenessProbe探测,确保pod中容器里的应用都正常启动了才删除之前的pod。
启动第一步,刚更新第一批就暂停了也可以;假如目标是5个,允许一个也不能少,允许最多可以10个,那一次加5个即可;这就是我们可以自己控制节奏来控制更新的方法。
通过Deployment对象,你可以轻松的做到以下事情:
- 创建ReplicaSet和Pod
- 滚动升级(不停止旧服务的状态下升级)和回滚应用(将应用回滚到之前的版本)
- 平滑地扩容和缩容
- 暂停和继续Deployment
2.3、Deployment使用案例
[root@k8s-master1 ~]# cat deploy-demo.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-v1
spec:
replicas: 2
selector:
matchLabels:
app: myapp
version: v1
template:
metadata:
labels:
app: myapp
version: v1
spec:
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
[root@k8s-master1 ~]# kubectl apply -f deploy-demo.yaml
deployment.apps/myapp-v1 created
[root@k8s-master1 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-v1 2/2 2 2 5s
[root@k8s-master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-v1-67fd9fc9c8 2 2 2 10s
[root@k8s-master1 ~]# kubectl get pods
NAME READY STATUS RESTARTS AGE
myapp-v1-67fd9fc9c8-6fw6v 1/1 Running 0 16s
myapp-v1-67fd9fc9c8-pndjj 1/1 Running 0 16s
2.4、Deployment管理pod
2.4.1、实现Pod扩缩容
方式一:修改yaml文件,然后kubectl apply
方式二:使用kubectl edit deploy
修改副本数
2.4.2、实现滚动升级及回滚
滚动升级:
- 方式一:修改yaml文件,然后
kubectl apply
- 方式二:使用
kubectl edit deploy
修改镜像版本
回滚:
[root@k8s-master1 ~]# kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-v1 2/2 2 2 29m
[root@k8s-master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-v1-67fd9fc9c8 0 0 0 29m
myapp-v1-75fb478d6c 2 2 2 13s
# 查看myapp-v1这个控制器的历史版本
[root@k8s-master1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1
REVISION CHANGE-CAUSE
1 <none>
2 <none>
# 回滚
[root@k8s-master1 ~]# kubectl rollout undo deployment myapp-v1 --to-revision=1
deployment.apps/myapp-v1 rolled back
[root@k8s-master1 ~]# kubectl get rs
NAME DESIRED CURRENT READY AGE
myapp-v1-67fd9fc9c8 2 2 2 30m
myapp-v1-75fb478d6c 0 0 0 84s
[root@k8s-master1 ~]# kubectl rollout history deployment myapp-v1
deployment.apps/myapp-v1
REVISION CHANGE-CAUSE
2 <none>
3 <none>
2.4.3、自定义滚动更新策略
maxSurge
和maxUnavailable
用来控制滚动更新的更新策略
# 取值范围
数值:两者不能同时为0。
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个;
# 建议配置
1. maxUnavailable == 0
2. maxSurge == 1
这是我们生产环境提供给用户的默认配置。即“一上一下,先上后下”最平滑原则:1个新版本pod ready(结合readiness)后,才销毁旧版本pod。此配置适用场景是平滑更新、保证服务平稳,但也有缺点,就是“太慢”了。
# 总结:
maxUnavailable:和期望的副本数比,不可用副本数最大比例(或最大值),这个值越小,越能保证服务稳定,更新越平滑;
maxSurge:和期望的副本数比,超过期望副本数最大比例(或最大值),这个值调的越大,副本更新速度越快。
自定义策略示例
# 修改更新策略:maxUnavailable=1,maxSurge=1
[root@k8s-master1 ~]# kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":1}}}}' -n blue-green
# 查看myapp-v1这个控制器的详细信息
[root@k8s-master1 ~]# kubectl describe deployment myapp-v1 -n blue-green
RollingUpdateStrategy: 1 max unavailable, 1 max surge
# 这个rollingUpdate更新策略变成了刚才设定的,因为我们设定的pod副本数是3,1和1表示最少不能少于2个pod,最多不能超过4个pod ,这个就是通过控制RollingUpdateStrategy这个字段来设置滚动更新策略的
2.5、Deployment配置模板
apiVersion: apps/v1
kind: Deployment
metadata:
name: portal
namespace: test
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