一、Deployment控制器概念、原理解读
1.1 Deployment概述
# Deployment官方文档
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
# 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 运行
![](https://img2022.cnblogs.com/blog/1523753/202207/1523753-20220727113339105-49743468.png)
rs v1 控制三个 pod,删除一个 pod,在 rs v2 上重新建立一个,依次类推,直到全部都是由 rs v2 控制,如果 rs v2 有问题,还可以回滚,Deployment 是建构在 rs 之上的,多个 rs 组成一个 Deployment,
但是只有一个 rs 处于活跃状态
1.2 Deployment工作原理:如何管理rs和Pod?
Deployment 可以使用声明式定义,直接在命令行通过纯命令的方式完成对应资源版本的内容的修改,也就是通过打补丁的方式进行修改;Deployment 能提供滚动式自定义自控制的更新;对 Deployment来讲,
我们在实现更新时还可以实现控制更新节奏和更新逻辑
互动:什么叫做更新节奏和更新逻辑呢?
比如说 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
二、Deployment资源清单yaml编写技巧
# 查看Deployment资源对象由哪几部分组成 [root@master rs]# kubectl explain deployment 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 字段 [root@master rs]# kubectl explain deployment.spec FIELDS: minReadySeconds <integer> #Kubernetes 在等待设置的时间后才进行升级 ,如果没有设置该值,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 字段 [root@master rs]# kubectl explain deployment.spec.strategy FIELDS: rollingUpdate <Object> type <string> # 支持2中更新方式:默认RollingUpdate滚动更新;可选 Recreate重建式更新,删除一个更新一个 #RollingUpdate 滚动更新,定义滚动更新方式,也就是 pod 能多几个,少几个 [root@master rs]# kubectl explain deployment.spec.strategy.rollingUpdate FIELDS: maxSurge <string> #我们更新的过程当中最多允许超出的指定的目标副本数有几个; 它有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示原本是 5 个,最多可以超出 20%,那就允许多一个,
最多可以超过 40%,那就允许多两个 maxUnavailable <string> ##最多允许几个不可用,假设有 5 个副本,最多一个不可用,就表示最少有 4 个可用
2.1 Deployment.spec字段详细截图
#查看 Deployment 下的 spec.template 字段 #template 为定义 Pod 的模板,Deployment 通过模板创建 Pod [root@master rs]# kubectl explain deployment.spec.template Fileds: metadata <Object> #定义模板的名字 spec <Object> deployment.spec.template 为 Pod 定义的模板,和 Pod 定义不太一样,template 中不包含apiVersion 和 Kind 属性,要求必须有 metadata。deployment.spec.template.spec 为容器的属性信息,
其他定义内容和 Pod 一致。
#查看 Deployment 下的 spec.template.spec 字段 [root@master rs]# kubectl explain deployment.spec.template.spec KIND: Deployment VERSION: apps/v1 RESOURCE: template <Object> 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> #定义临时容器 1.临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 ContainerSpec 段进行描述,但许多字段是不相容且不允许的。 2.临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。 3.Pod 资源分配是不可变的,因此 resources 配置是不允许的。 临时容器用途: 当由于容器崩溃或容器镜像不包含调试应用程序而导致 kubectl exec 无用时,临时容器对于交互式故障排查很有用。 hostAliases <[]Object> # 登录到pod中,查看hosts文件可以看到增加了域名解析的, hostAliases: – ip: "10.1.2.2" hostnames: – "mc.local" – "rabbitmq.local" – ip: "10.1.2.3" hostnames: – "redis.local" – "mq.local" 例如:hosts:10.1.2.2 mc.local rabbitmq.local
hostIPC <boolean> #使用主机 IPC hostNetwork <boolean> #是否使用宿主机的网络 hostPID <boolean> #可以设置容器里是否可以看到宿主机上的进程。True 可以 hostname <string> imagePullSecrets <[]Object> 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> #挂载存储卷
2.2 pod中添加域名解析
[root@master rs]# kubectl explain rs.spec.template.spec.hostAliases
# 挑选一个yaml文件中加入
spec:
containers:
- name: php-redis
image: ikubernetes/myapp:v2
imagePullPolicy: IfNotPresent
hostAliases:
- ip: "192.168.199.131"
hostnames:
- "master"
- "master.local"
[root@master rs]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend created
[root@master rs]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
frontend-rmxdj 1/1 Running 0 12s
frontend-x6gnr 1/1 Running 0 12s
[root@master rs]# kubectl exec -it frontend-rmxdj -- /bin/sh
# cat /etc/hosts
# Entries added by HostAliases.
192.168.199.131 master master.local
2.3 Pod中dns配置--dnsConfig和dnsPolicy
[root@master rs]# kubectl explain rs.spec.template.spec.dnsPolicy
[root@master ~]# kubectl explain rs.spec.template.spec.dnsConfig
[root@master ~]# kubectl explain rs.spec.template.spec.dnsConfig.searches
hostAliases:
- ip: "192.168.199.131"
hostnames:
- "master"
- "master.local"
dnsPolicy: None
dnsConfig:
nameservers:
- 192.168.199.131
- 192.168.199.132
searches:
- master.svc.cluster.local
- my.dns.search.master
[root@master rs]# kubectl delete -f replicaset.yaml
replicaset.apps "frontend" deleted
[root@master rs]# kubectl apply -f replicaset.yaml
replicaset.apps/frontend created
[root@master rs]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
frontend-bq997 0/1 Pending 0 13s
frontend-fqjqs 0/1 Pending 0 13s
[root@master rs]# kubectl exec -n default -it frontend-bq997 -- /bin/sh
/ # cat /etc/resolv.conf
nameserver 192.168.199.131
nameserver 192.168.199.132
search master.svc.cluster.local my.dns.search.master
三、Deployment部署生产环境web项目
3.1 案例:创建一个Web站点
deployment 是一个三级结构,deployment 管理 replicaset,replicaset 管理 pod
# 例子:用 deployment 创建一个 pod
[root@master rs]# cat deploy-demo.yaml
apiVersion: apps/v1 # deployment对应的api版本
kind: Deployment # 创建的资源是deployment
metadata:
name: myapp-v1 # deployment的名字
namespace: default # 所属名称空间
spec:
replicas: 2 # 管理的pod副本数
selector: # 选择标签器
matchLabels: # matchLabels 下定义的标签需要跟 template.metadata.labels 定义的标 签一致
app: myapp
version: v1
strategy:
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
name: test
labels:
app: myapp
version: v1
spec: # 定义容器的属性
containers:
- name: myapp
image: janakiramm/myapp:v1
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80 # 容器里应用的端口
[root@master rs]# kubectl apply -f deploy-demo.yaml
deployment.apps/myapp-v1 created
# 查看deploy状态
[root@master rs]# kubectl get deployment -n default
NAME READY UP-TO-DATE AVAILABLE AGE
myapp-v1 0/2 0 0 35s
#创建的控制器名字是 myapp-v1
1.NAME :列出名称空间中 deployment 的名称。
2.READY:显示 deployment 有多少副本数。它遵循 ready/desired 的模式。
3.UP-TO-DATE: 显示已更新到所需状态的副本数。
4.AVAILABLE: 显示你的可以使用多少个应用程序副本。
5.AGE :显示应用程序已运行的时间。
[root@master rs]# kubectl get pods -n default
NAME READY STATUS RESTARTS AGE
myapp-v1-86f6b6d8c8-k8c5h 1/1 Running 0 5s
myapp-v1-86f6b6d8c8-p6scj 1/1 Running 0 5s
[root@master rs]# kubectl get rs -n default
NAME DESIRED CURRENT READY AGE
myapp-v1-86f6b6d8c8 2 2 2 2m4s
#创建 deploy 的时候也会创建一个 rs(replicaset),86f6b6d8c8这个随机数字是我们引用 pod 的模板 template 的名字的 hash 值
1.NAME: 列出名称空间中 ReplicaSet 资源
2.DESIRED:显示应用程序的所需副本数,这些副本数是在创建时定义的。这是所需的状态。
3.CURRENT: 显示当前正在运行多少个副本。
4.READY: 显示你的用户可以使用多少个应用程序副本。
5.AGE :显示应用程序已运行的时间。
请注意,ReplicaSet 的名称始终设置为[DEPLOYMENT-NAME]-[RANDOM-STRING]。RANDOMSTRING 是随机生成的
3.2 livenessProbe和readiness探测
apiVersion: apps/v1 kind: Deployment metadata: name: myapp-v1 namespace: default spec: replicas: 2 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 readinessProbe: httpGet: port: 80
kubectl describe pods -n default myapp-v1-c5549578-gv4x4
Liveness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
Readiness: http-get http://:80/ delay=0s timeout=1s period=10s #success=1 #failure=3
3.3 Deployment管理pod:扩容、缩容、滚动更新、回滚
# 1.扩容:通过deployment管理应用,实现扩容,将副本数从2变为3 (1)方法1:将deploy-demo.yaml文件中replicas: 2 改为replicas: 3,然后执行后查看 [root@master rs]# kubectl get pods -n default NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 9m2s myapp-v1-c5549578-wfd7b 1/1 Running 0 8m49s myapp-v1-c5549578-wrknz 1/1 Running 0 2m5s (2)方法2:kubectl edit deploy -n default myapp-v1 replicas: 4 [root@master rs]# kubectl get pods -n default NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 14m myapp-v1-c5549578-j2wpz 1/1 Running 0 7s myapp-v1-c5549578-wfd7b 1/1 Running 0 13m myapp-v1-c5549578-wrknz 1/1 Running 0 7m12s # 2.缩容:将deploy-demo.yaml中replicas: 4 改为replicas: 3 方法1: [root@master rs]# kubectl get pods -n default NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 16m myapp-v1-c5549578-j2wpz 0/1 Terminating 0 2m50s myapp-v1-c5549578-wfd7b 1/1 Running 0 16m myapp-v1-c5549578-wrknz 1/1 Running 0 9m55s [root@master rs]# kubectl get pods -n default NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 17m myapp-v1-c5549578-wfd7b 1/1 Running 0 16m myapp-v1-c5549578-wrknz 1/1 Running 0 10m 方法2:将replicas: 3改为2 [root@master rs]# kubectl edit deploy -n default myapp-v1 deployment.apps/myapp-v1 edited [root@master rs]# kubectl get pods -n default NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 18m myapp-v1-c5549578-wfd7b 1/1 Running 0 18m
3.通过deployment管理应用,实现滚动更新 #步骤: (1) 将新版本导入到节点:docker load -i myapp-v2.tar.gz (2)修改yaml文件将image: janakiramm/myapp:v1修改为image: janakiramm/myapp:v2, (3)然后执行kubectl apply -f deploy-demo.yaml # 查看步骤执行过程 [root@master ~]# kubectl get pods -n default -w NAME READY STATUS RESTARTS AGE myapp-v1-c5549578-gv4x4 1/1 Running 0 35m myapp-v1-c5549578-wfd7b 1/1 Running 0 35m myapp-v1-787b9bc78c-bbftz 0/1 Pending 0 0s myapp-v1-787b9bc78c-bbftz 0/1 Pending 0 0s myapp-v1-787b9bc78c-bbftz 0/1 ContainerCreating 0 0s myapp-v1-787b9bc78c-bbftz 0/1 ContainerCreating 0 1s myapp-v1-787b9bc78c-bbftz 0/1 Running 0 2s myapp-v1-787b9bc78c-bbftz 1/1 Running 0 7s myapp-v1-c5549578-wfd7b 1/1 Terminating 0 35m myapp-v1-787b9bc78c-95qjb 0/1 Pending 0 0s myapp-v1-787b9bc78c-95qjb 0/1 Pending 0 0s myapp-v1-787b9bc78c-95qjb 0/1 ContainerCreating 0 0s myapp-v1-c5549578-wfd7b 1/1 Terminating 0 35m myapp-v1-787b9bc78c-95qjb 0/1 ContainerCreating 0 1s myapp-v1-c5549578-wfd7b 0/1 Terminating 0 35m myapp-v1-787b9bc78c-95qjb 0/1 Running 0 2s myapp-v1-787b9bc78c-95qjb 1/1 Running 0 9s myapp-v1-c5549578-gv4x4 1/1 Terminating 0 35m myapp-v1-c5549578-gv4x4 1/1 Terminating 0 36m myapp-v1-c5549578-gv4x4 0/1 Terminating 0 36m myapp-v1-c5549578-wfd7b 0/1 Terminating 0 35m myapp-v1-c5549578-wfd7b 0/1 Terminating 0 35m myapp-v1-c5549578-gv4x4 0/1 Terminating 0 36m myapp-v1-c5549578-gv4x4 0/1 Terminating 0 36m pending 表示正在进行调度,ContainerCreating 表示正在创建一个 pod,running 表示运行一个 pod,running 起来一个 pod 之后再 Terminating(停掉)一个 pod,以此类推,直到所有 pod 完成滚动升级 [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 2 2 2 8m39s myapp-v1-86f6b6d8c8 0 0 0 56m #上面可以看到 rs 有两个,上面那个是升级之前的,已经被停掉,但是可以随时回滚
v1版本的时候 curl IP可以看到 background-color: blue;
v2版本的时候 curl IP可以看到 background-color: green;
# 4.回滚 [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 2 2 2 28m myapp-v1-86f6b6d8c8 0 0 0 76m [root@master rs]# kubectl rollout --help Available Commands: history 显示 rollout 历史 pause 标记提供的 resource 为中止状态 restart Restart a resource resume 继续一个停止的 resource status 显示 rollout 的状态 undo 撤销上一次的 rollout [root@master rs]# kubectl rollout undo --help Examples: # Rollback to the previous deployment kubectl rollout undo deployment/abc # Rollback to daemonset revision 3 kubectl rollout undo daemonset/abc --to-revision=3 # Rollback to the previous deployment with dry-run kubectl rollout undo --dry-run=server deployment/abc Usage: kubectl rollout undo (TYPE NAME | TYPE/NAME) [flags] [options] # 查看历史版本 [root@master rs]# kubectl rollout history --help Examples: # View the rollout history of a deployment kubectl rollout history deployment/abc # View the details of daemonset revision 3 kubectl rollout history daemonset/abc --revision=3 Usage: kubectl rollout history (TYPE NAME | TYPE/NAME) [flags] [options] # 查询历史版本 [root@master rs]# kubectl rollout history deployment/myapp-v1 -n default deployment.apps/myapp-v1 REVISION CHANGE-CAUSE 1 <none> 2 <none> 3 <none> # 回滚版本 [root@master rs]# kubectl rollout undo deployment/myapp-v1 -n default --to-revision=1 [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 2 2 2 38m myapp-v1-86f6b6d8c8 0 0 0 86m [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 0 0 0 43m myapp-v1-86f6b6d8c8 2 2 2 91m curl IP 请求可以看到改变 background-color: blue; # 回滚完成后,再次查看版本 [root@master rs]# kubectl rollout history deployment/myapp-v1 -n default deployment.apps/myapp-v1 REVISION CHANGE-CAUSE 2 <none> 3 <none> # 代表之前版本,请求背景色为绿色 4 <none> # 代表当前版本,请求背景色为蓝色 # 再次回滚 [root@master rs]# kubectl rollout undo deployment/myapp-v1 -n default --to-revision=3 deployment.apps/myapp-v1 rolled back # 回滚中 [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 1 1 0 54m myapp-v1-86f6b6d8c8 2 2 2 102m # 回滚完成 [root@master rs]# kubectl get rs -n default NAME DESIRED CURRENT READY AGE myapp-v1-787b9bc78c 2 2 2 56m myapp-v1-86f6b6d8c8 0 0 0 104m [root@master rs]# kubectl rollout history deployment/myapp-v1 -n default deployment.apps/myapp-v1 REVISION CHANGE-CAUSE 2 <none> 4 <none> 5 <none>
3.4 自定义滚动更新策略
kubectl explain deploy.spec.strategy.rollingUpdate
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@master ~]# kubectl patch deployment myapp-v1 -p '{"spec":{"strategy":{"rollingUpdate": {"maxSurge":1,"maxUnavailable":1}}}}' 查看 myapp-v1 这个控制器的详细信息 [root@master ~]# kubectl describe deployment myapp-v1 显示如下: RollingUpdateStrategy: 1 max unavailable, 1 max surge 上面可以看到 RollingUpdateStrategy: 1 max unavailable, 1 max surge 这个 rollingUpdate 更新策略变成了刚才设定的,因为我们设定的 pod 副本数是 3,1 和 1 表示最少不能少于 2 个 pod,最多不能超过 4 个 pod 这个就是通过控制 RollingUpdateStrategy 这个字段来设置滚动更新策略的
3.5 重建式更新
[root@master deploy]# kubectl explain deploy.spec.strategy.type KIND: Deployment VERSION: apps/v1 FIELD: type <string> DESCRIPTION: Type of deployment. Can be "Recreate" or "RollingUpdate". Default is RollingUpdate. Possible enum values: - `"Recreate"` Kill all existing pods before creating new ones. 重建式更新 - `"RollingUpdate"` Replace the old ReplicaSets by new one using rolling
update i.e gradually scale down the old ReplicaSets and scale up the new one. # 滚动式更新 # 重建式更新,先杀死现有需要更新的所有pod,再创建新更新副本
# 生产环境一般都不使用,风险大 spec: strategy: # 更新策略方式 type: Recreate # 重建式更新
四、Deployment资源清单详解
# 生产环境 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: XXX/portal:v1 imagePullPolicy: ALWAYS# 一般使用IfNotPresent ports: - protocol: TCP containerPort: 8080 resources: # 资源配置 limits: # 资源限制,最多可用多少cpu和内存 cpu: 1 memory: 1Gi requests: # 最少需要多少资源才可以运行pod,才会被分配,1核=1000m 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 端口