Deployment 无状态服务
Deployment 无状态服务
- 什么是无状态服务
#大部分服务都是无状态的
应用在部署的时候不需要保存所产生的缓存数据,所以叫无状态服务。
如果你部署的服务需要保存数据的话,那么就需要使用存储盘挂载
5.1 Deployment概念
用于部署无状态服务,这个是最常用的控制器。一般用于管理维护企业内部无状态的微服务,比如configserver、springboot。他可以管理多个副本的Pod实现无缝迁移、自动扩容缩容、自动灾难恢复、一键回滚等功能。
5.2 创建一个Deployment
手动创建:kubectl create deployment nginx --image=nginx:1.18
YAML创建:
[root@master01 ~/study]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "1"
creationTimestamp: "2020-09-19T02:41:11Z"
generation: 1
labels:
app: nginx
name: nginx
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2 #副本数
revisionHistoryLimit: 10 # 历史记录保留的个数
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.2
imagePullPolicy: IfNotPresent
name: nginx
resources: {}
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
状态解析:
NAME:Deployment名称
READY:Pod的状态已经Ready的个数
UP-TO-DATE:已经达到期望状态的被更新的副本数
AVAILABLE:已经可以用的副本数
AGE:显示应用程序运行的时间
CONTAINERS:容器名称
IMAGES:容器的镜像
SELECTOR:管理的Pod的标签
- 例2:
root@deploy-harbor:~/kubernetes/deployment# cat deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: default
spec:
replicas: 2 #副本数
selector:
matchLabels:
app: ng-deploy-80
template:
metadata:
labels:
app: ng-deploy-80
spec:
containers:
- name: ng-deploy-80
image: nginx:1.20.1
ports:
- containerPort: 80
- 输出
#他会先创建然后在删除
root@deploy-harbor:~/kubernetes/deployment# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-7ffdbfb56f-8zkmv 0/1 ContainerCreating 0 2s
nginx-deployment-7ffdbfb56f-qz2t5 1/1 Running 0 32s
nginx-deployment-ccbf969f7-94wlb 1/1 Terminating 0 4m49s
nginx-deployment-ccbf969f7-fxtrr 1/1 Running 0 4m49s
- 回退
root@deploy-harbor:~/kubernetes/deployment# kubectl rollout undo deployment/nginx-deployment
deployment.apps/nginx-deployment rolled back
#回退你会发现根它以前一样了
root@deploy-harbor:~/kubernetes/deployment# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-deployment-ccbf969f7-28l76 1/1 Running 0 36s
nginx-deployment-ccbf969f7-pcqzn 1/1 Running 0 32s
5.3 Deployment的更新
更改Deployment的镜像并记录:
kubectl set image deploy nginx nginx=nginx:1.15.3 --record
#--record
记录更改的参数,然后可以看到一些详细的信息
查看怎么更新的过程:
[root@master01 ~/study]# kubectl rollout status deployment nginx
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 1 out of 2 new replicas have been updated...
Waiting for deployment "nginx" rollout to finish: 2 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx" rollout to finish: 1 old replicas are pending termination...
#kubectl apply 每次更新应用时 Kubernetes 都会记录下当前的配置,保存为一个 revision(版次),这样就可以回滚到某个特定 revision。
#默认配置下,Kubernetes 只会保留最近的几个 revision,可以在 Deployment 配置文件中通过 revisionHistoryLimit 属性增加 revision 数量。
#使用也很简单,在更新的时候加上--record就可以了。
解释
注意:
record类似一个栈,先执行的apply会放到记录的最下端。也就是说你的上一个版本一定是2.
record记录的是apply的命令,所以如果每次执行的命令是一样的话,会覆盖掉。
或者使用describe查看:
kubectl describe deployments.apps nginx
#可以根据时间来判断那个是新的pod
滚动更新成功后,有一个是运行的,有一个是停掉的
5.4 Deployment回滚
`一般生产发版操作都是:`
kubectl set image deployment nginx nginx=nginx:1.20 --recode
这种方式去发版
回滚的方式分为两种:
1.edit:这个就是编辑YAML文件的方式找到对应的image镜像信息去直接的更改版本号
2.第二种就是需要更改YAML文件的配置应该是回滚的策略,然后再replace -f 加 .yaml 一下就可以了
- 再一次更新镜像
kubectl set image deploy nginx nginx=nginx:1.20 --record
- 查看历史更新的版本号
#这种方式优点在于你可能忘记上一次发版是什么时候了,不记得版本号了
回滚有两种:1.回到上一个版本2.回到指定版本
#查看历史版本
[root@master01 ~/study]# kubectl rollout history deployment nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
2 kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
3 kubectl set image deploy nginx nginx=nginx:1.20 --record=true
- 回到上一个版本
[root@master01 ~/study]# kubectl rollout undo deployment nginx
deployment.apps/nginx rolled back
#回滚成功就把旧的pod给删除掉了
[root@master01 ~/study]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5dfc8689c6-5kc4r 1/1 Running 0 10s
nginx-5dfc8689c6-q4pk6 1/1 Running 0 8s
nginx-7fb9867-44bzk 0/1 Terminating 0 11m
nginx-7fb9867-57fr8 0/1 Terminating 0 12m
- 回到指定版本
#先查看一下历史版本
[root@master01 ~/study]# kubectl rollout history deployment nginx
deployment.apps/nginx
REVISION CHANGE-CAUSE
1 <none>
3 kubectl set image deploy nginx nginx=nginx:1.20 --record=true
4 kubectl set image deploy nginx nginx=nginx:1.15.3 --record=true
#查看指定版本的详细信息
[root@master01 ~/study]# kubectl rollout history deployment nginx --revision=3
deployment.apps/nginx with revision #3
Pod Template:
Labels: app=nginx
pod-template-hash=7fb9867
Annotations: kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.20 --record=true
Containers:
nginx:
Image: nginx:1.20
Port: <none>
Host Port: <none>
Environment: <none>
Mounts: <none>
Volumes: <none>
#回到指定版本
[root@master01 ~/study]# kubectl rollout undo deployment nginx --to-revision=3
deployment.apps/nginx rolled back
[root@master01 ~/study]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5dfc8689c6-5kc4r 0/1 Terminating 0 24m
nginx-5dfc8689c6-q4pk6 0/1 Terminating 0 24m
nginx-7fb9867-4rbp2 1/1 Running 0 5s
nginx-7fb9867-jwvt5 1/1 Running 0 3s
5.5 Deployment扩容/缩容
#扩容有两种方式 1.edit直接更改副本数 2.命令行scale在改副本数
#扩容
[root@master01 ~/study]# kubectl scale --replicas=5 deployment nginx
deployment.apps/nginx scaled
#缩容
[root@master01 ~/study]# kubectl scale --replicas=2 deployment nginx
deployment.apps/nginx scaled
#查看
[root@master01 ~/study]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-7fb9867-4rbp2 1/1 Running 0 15m
nginx-7fb9867-jwvt5 1/1 Running 0 15m
5.6 Deployment暂停/恢复
#Deployment 暂停功能
#第一次配置变更
[root@master01 ~/study]# kubectl rollout pause deployment nginx
deployment.apps/nginx paused
[root@master01 ~/study]# kubectl set image deploy nginx nginx=nginx:1.15.3 --record
deployment.apps/nginx image updated
#第二次配置变更 添加内存CPU配置
[root@master01 ~/study]# kubectl set resources deploy nginx -c nginx --limits=cpu=200m,memory=128Mi --requests=cpu=10m,memory=16Mi
deployment.apps/nginx resource requirements updated
#Deployment 恢复功能 (就是恢复到没有更改内存CPU这些限制的时候)那也就是说恢复的操作前(上一个版本)
[root@master01 ~/study]# kubectl rollout resume deployment nginx
deployment.apps/nginx resumed
[root@master01 ~/study]# kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx-5dfc8689c6 0 0 0 120m
nginx-66bbc9fdc5 0 0 0 137m
nginx-68db656dd8 2 2 2 9s #这个就是新运行的POD
nginx-7fb9867 0 0 0 79m
#可以看出来已经POD已经创建成功了
[root@master01 ~/study]# kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-68db656dd8-94g58 1/1 Running 0 20s
nginx-68db656dd8-fp729 1/1 Running 0 22s
5.7 Deployment更新注意事项
[root@master01 ~/study]# cat nginx-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
annotations:
deployment.kubernetes.io/revision: "12"
kubernetes.io/change-cause: kubectl set image deploy nginx nginx=nginx:1.15.3
--record=true
creationTimestamp: "2020-09-19T02:41:11Z"
generation: 19
labels:
app: nginx
name: nginx
namespace: default
spec:
progressDeadlineSeconds: 600
replicas: 2
revisionHistoryLimit: 10
selector:
matchLabels:
app: nginx
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
type: RollingUpdate
template:
metadata:
creationTimestamp: null
labels:
app: nginx
spec:
containers:
- image: nginx:1.15.3
imagePullPolicy: IfNotPresent
name: nginx
resources:
limits:
cpu: 200m
memory: 128Mi
requests:
cpu: 10m
memory: 16Mi
terminationMessagePath: /dev/termination-log
terminationMessagePolicy: File
dnsPolicy: ClusterFirst
restartPolicy: Always
schedulerName: default-scheduler
securityContext: {}
terminationGracePeriodSeconds: 30
- 注意事项
#这个就是你更新时候--record所保留下的版本号
.spec.revisionHistoryLimit:设置保留RS旧的revision的个数,默认为10,设置为0的话,不保留历史数据
#用于健康检查
.spec.minReadySeconds:可选参数,指定新创建的POD在没有任何容器崩溃的情况下视为Ready最小的秒数,默认为0,即一旦被创建就视为可用
- 滚动更新的策略
#定义使用何种方式升级
.spec.strategy.type:
deployment升级方式:
默认是RolingUpdate、即滚动升级
Recreate、即先将所有旧的POD停止,然后再启动新的POD
Recreate:重建,先删除旧的POD,在创建新的POD
spec.strategy.type.rollingUpdate下参数
- maxSurge
maxSurge:指定在升级时、最大可以创建多少个POD,这个值可以是一个绝对值数字,也可以是个百分比。
#例如:
当这个值指定为30%时,也就是说,新旧POD的总量不能超过30%。简单来讲,就是滚动升级时,会先启动30%的新的POD。然后开始杀掉旧的POD,每当一个旧的POD被杀掉,一个新的POD会被启动,始终保持总量不超过30%,直至更新完成。需要说明的是,当maxUnavailable为0时,maxSurge的值不能为0
- maxUnavailable
maxUnavailable:在指定升级时,最大不可用的POD的值。可以是一个绝对值数字,也可以是个百分比。
#例如:
当这个值指定为30%时,最少可用的POD为70%,也就是说,在滚动升级的时候,会先杀掉30%旧的POD,然后开始启动新POD。当一个新的POD被创建,一个旧的POD就会被销毁。始终保持可用的POD在总量的70%,直至升级完成。需要说明的是、当maxSurge为0时,maxUnavailable的值不能为0