杨梅冲
每天在想什么呢?

一、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 运行

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 端口

 

 

posted on 2022-07-28 17:41  杨梅冲  阅读(448)  评论(0编辑  收藏  举报