一、Deployment控制器:概念、原理解读

1.1、Deployment概述

文中有个单词提示是敏感词max_urge,中间的_是个字母s,以实际操作的单词为准。

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控制,如果rsv2有问题,还可以回滚,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资源清单文件编写技巧

当某个属性的数据类型为<[]*****>时(数据类型前有个方括号),就是说该属性是个列表,有多个子属性,该属性与第一个子属性需要用"-"连接,父属性与子属性之接有缩进。但是字符串列表数据类型除外,它的每个值都需用“-”连接,<map[string]string>数据类型不需要使用“-”连接,它的值为键值对

举例如下: hostAliases <[]Object> #在pod中增加域名解析的

# hostAliases 属性的数据类型为对象列表,注意数据类型中有个[],表示该属性是个列表,所以下面的子属性要用-线连接。
hostAliases	<[]Object> #在pod中增加域名解析的
# 举例如下:
hostAliases:					# 这里为对象列表数据类型
– ip: "10.1.2.2"			# ip子属性用“-”连接
    hostnames:				# 第二个子属性不需要“-”,正常缩进就可以了。
    – "mc.local"			# 由于hostnames子属性是字符串列表数据类型,所以对应的值的列表也需要用“-”连接,且每个值都是用“-”连接的
    – "rabbitmq.local"

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

帮助命令:kubectl explain deployment

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment
GROUP:      apps
KIND:       Deployment
VERSION:    v1

DESCRIPTION:
    Deployment enables declarative updates for Pods and ReplicaSets.
    
FIELDS:
  apiVersion    <string>	#该资源使用的api版本
    APIVersion defines the versioned schema of this representation of an object.
    Servers should convert recognized schemas to the latest internal value, and
    may reject unrecognized values. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

  kind  <string>	#创建的资源是什么?
    Kind is a string value representing the REST resource this object
    represents. Servers may infer this from the endpoint the client submits
    requests to. Cannot be updated. In CamelCase. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

  metadata      <ObjectMeta>	#元数据,包括资源的名字和名称空间
    Standard object's metadata. More info:
    https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata

  spec  <DeploymentSpec>	#定义容器的
    Specification of the desired behavior of the Deployment.

  status        <DeploymentStatus>	#状态,不可以修改
    Most recently observed status of the Deployment.


2.2、查看Deployment下的spec字段

帮助命令:kubectl explain deployment.spec

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment.spec |grep '<*>'
FIELD: spec <DeploymentSpec>
  minReadySeconds       <integer>	#Kubernetes在等待设置的时间后才进行升级
                                  #如果没有设置该值,Kubernetes会假设该容器启动起来后就提供服务了
  paused        <boolean>					#暂停,当我们更新的时候创建pod先暂停,不是立即更新
  progressDeadlineSeconds       <integer>	# k8s 在升级过程中有可能由于各种原因升级卡住(这个时候还没有明确的升级失败),比如在拉取被墙的镜像,权限不够等错误。那么这个时候就需要有个 deadline ,在 deadline 之内如果还卡着,那么就上报这个情况,这个时候这个 Deployment 状态就被标记为 False,并且注明原因。但是它并不会阻止 Deployment 继续进行卡住后面的操作。完全由用户进行控制。
  replicas      <integer>			#副本数
  revisionHistoryLimit  <integer>		#保留的历史版本,默认是10
  selector      <LabelSelector> -required-	#标签选择器,选择它关联的pod
  strategy      <DeploymentStrategy>	#更新策略
  template      <PodTemplateSpec> -required-	#定义的pod模板

2.3、查看Deployment下的spec.strategy字段

帮助命令:kubectl explain deployment.spec.strategy

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment.spec.strategy |grep '<*>'
FIELD: strategy <DeploymentStrategy>
  rollingUpdate <RollingUpdateDeployment>		# 滚动更新
  type  <string>	# 支持两种更新,Recreate和RollingUpdate,默认是RollingUpdate,Recreate是重建式更新,删除一个更新一个

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

帮助命令:kubectl explain deployment.spec.strategy.rollingUpdate

RollingUpdate滚动更新,定义滚动更新方式,也就是pod能多几个,少几个。

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment.spec.strategy.rollingUpdate |grep '<*>'
FIELD: rollingUpdate <RollingUpdateDeployment>
  maxurge      <IntOrString>	#我们更新的过程当中最多允许超出的指定的目标副本数有几个
  maxUnavailable        <IntOrString>	#最多允许几个不可用

注:

max_urge <string> #我们更新的过程当中最多允许超出的指定的目标副本数有几个;

它有两种取值方式,第一种直接给定数量,第二种根据百分比,百分比表示原本是5个,最多可以超出20%,那就允许多一个,最多可以超过40%,那就允许多两个

maxUnavailable <string>  #最多允许几个不可用

假设有5个副本,最多一个不可用,就表示最少有4个可用


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

template为定义Pod的模板,Deployment通过模板创建Pod。

帮助命令:kubectl explain deployment.spec.template

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment.spec.template |grep '<*>'
FIELD: template <PodTemplateSpec>
  metadata      <ObjectMeta>	#定义模板的名字
  spec  <PodSpec>		# 为容器的属性信息,其他定义内容和Pod一致

deployment.spec.template为Pod定义的模板,和Pod定义不太一样,template中不包含apiVersion和Kind属性,要求必须有metadata。deployment.spec.template.spec为容器的属性信息,其他定义内容和Pod一致。

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

帮助命令:kubectl explain deployment.spec.template.spec

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl explain deployment.spec.template.spec |grep '<*>'
FIELD: spec <PodSpec>
  activeDeadlineSeconds <integer>	# 表示Pod 可以运行的最长时间,达到设置的该值后,Pod 会自动停止。
  affinity      <Affinity>	#定义亲和性,跟直接创建pod时候定义亲和性类似
  automountServiceAccountToken  <boolean>	#身份认证相关的
  containers    <[]Container> -required-	#定义容器属性
  dnsConfig     <PodDNSConfig>	#设置Pod的DNS
  dnsPolicy     <string>	# dnsPolicy决定Pod 内预设的DNS 配置策略
  enableServiceLinks    <boolean>
  ephemeralContainers   <[]EphemeralContainer>	#定义临时容器
  hostAliases   <[]HostAlias>	#在pod中增加域名解析的
  hostIPC       <boolean>	#使用主机IPC
  hostNetwork   <boolean>	#是否使用宿主机的网络
  hostPID       <boolean>	#可以设置容器里是否可以看到宿主机上的进程。True可以
  hostUsers     <boolean>
  hostname      <string>
  imagePullSecrets      <[]LocalObjectReference>
  initContainers        <[]Container>	#定义初始化容器
  nodeName      <string>	#定义pod调度到具体哪个节点上
  nodeSelector  <map[string]string>	#定义节点选择器
  os    <PodOS>
  overhead      <map[string]Quantity>	#overhead是1.16引入的字段,在没有引入
  preemptionPolicy      <string>
  priority      <integer>
  priorityClassName     <string>
  readinessGates        <[]PodReadinessGate>
  resourceClaims        <[]PodResourceClaim>
  restartPolicy <string>	#Pod重启策略
  runtimeClassName      <string>
  schedulerName <string>
  schedulingGates       <[]PodSchedulingGate>
  securityContext       <PodSecurityContext>	#是否开启特权模式
  serviceAccount        <string>
  serviceAccountName    <string>
  setHostnameAsFQDN     <boolean>
  shareProcessNamespace <boolean>
  subdomain     <string>
  terminationGracePeriodSeconds <integer>	#在真正删除容器之前,K8S会先发终止信号(kill -15 {pid})给容器,默认30s
  tolerations   <[]Toleration>	#定义容忍度
  topologySpreadConstraints     <[]TopologySpreadConstraint>
  volumes       <[]Volume>	#挂载存储卷

注:

1、临时容器

  • 临时容器与其他容器的不同之处在于,它们缺少对资源或执行的保证,并且永远不会自动重启,因此不适用于构建应用程序。临时容器使用与常规容器相同的 ContainerSpec 段进行描述,但许多字段是不相容且不允许的。
  • 临时容器没有端口配置,因此像 ports,livenessProbe,readinessProbe 这样的字段是不允许的。
  • Pod 资源分配是不可变的,因此 resources 配置是不允许的。
  • 临时容器用途:当由于容器崩溃或容器镜像不包含调试应用程序而导致kubectl exec 无用时,临时容器对于交互式故障排查很有用。

2、DNS策略

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

三、Deployment使用案例:创建一个web站点

deployment是一个三级结构,deployment管理replicaset,replicaset管理pod。

例子:用deployment创建一个pod,容器中运行的nginx服务

1、编写Eg-Deployment.yaml文件

root@k8s-master:~/K8sStudy/Chapter2-8# cat Eg-Deployment.yaml 
apiVersion: apps/v1	#deployment对应的api版本
kind: Deployment	#创建的资源是deployment
metadata:
  name: deployment-demo	#deployment的名字
spec:
  replicas: 2	#deployment管理的pod副本数
  selector:	#标签选择器
    matchLabels:	# matchLabels下定义的标签需要跟template.metadata.labels定义的标签一致
      app: myapp
      version: v1
  template:
    metadata:
      name: web
      labels:
        app: myapp
        version: v1
    spec:
      containers:	#定义容器的属性
      - name: myapp
        image: docker.io/library/nginx:latest	#容器使用的镜像
        imagePullPolicy: IfNotPresent	#镜像拉取策略
        ports:
        - containerPort: 80	#容器里的应用的端口


2、创建Deployment,更新/应用资源清单文件:kubectl apply -f deploy-demo.yaml

kubectl apply:表示声明式的定义,既可以创建资源,也可以动态更新资源

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl apply -f Eg-Deployment.yaml
deployment.apps/deployment-demo created
root@k8s-master:~/K8sStudy/Chapter2-8#

3、查看Deployment,查看Replicaset,查看pod。

# 查看Deployment
root@k8s-master:~/K8sStudy/Chapter2-8# kubectl get deployment
NAME              READY   UP-TO-DATE   AVAILABLE   AGE
deployment-demo   2/2     2            2           46s
# 查看Replicaset
root@k8s-master:~/K8sStudy/Chapter2-8# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
deployment-demo-57885d597f   2         2         2       56s
frontend                     2         2         2       3d6h
# 查看P
root@k8s-master:~/K8sStudy/Chapter2-8# kubectl get pods -owide
NAME                               READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
deployment-demo-57885d597f-79k2p   1/1     Running   0          67s     10.244.113.168   k8s-node   <none>           <none>
deployment-demo-57885d597f-mmp2g   1/1     Running   0          67s     10.244.113.167   k8s-node   <none>           <none>
frontend-7gmln                     1/1     Running   0          2d23h   10.244.113.164   k8s-node   <none>           <none>
frontend-7mp87                     1/1     Running   0          3d6h    10.244.113.158   k8s-node   <none>           <none>
root@k8s-master:~/K8sStudy/Chapter2-8#

注:通过查看Deployment,ReplicaSet, Pods,会发现Deployment创建的ReplicaSet的名称是由Deployment的名称加上一串随机字符,而ReplicaSet创建的Pod的名称是由ReplicaSet的名称再加上一串随机字符。

Deployment注解:

K8s控制器Deployment_Deployment

ReplicaSet注解:

创建deploy的时候也会创建一个rs(replicaset),67fd9fc9c8 这个随机数字是我们引用pod的模板template的名字的hash值。


K8s控制器Deployment_Deployment_02

4、查看Pods,并请求pod的web网站。

K8s控制器Deployment_Deployment_03

K8s控制器Deployment_Deployment_04

四、Deployment管理pod:扩容、缩容、滚动更新、回滚

4.1、Deployment管理pod:扩容

通过deployment管理应用,实现扩容,直接修改replicas数量,把副本数变成3 。

K8s控制器Deployment_Deployment_05

更新清单文件 Eg-Deployment.yaml。kubectl apply -f Eg-Deployment.yaml

注意:apply不同于create,apply可以执行多次;create执行一次,再执行就会报错复。

K8s控制器Deployment_Deployment_06

查看Deployment控制器的详细信息: kubectl describe deployment deployment-demo

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl describe deployment deployment-demo
Name:                   deployment-demo
Namespace:              default
CreationTimestamp:      Tue, 14 May 2024 18:06:39 +0800
Labels:                 <none>
Annotations:            deployment.kubernetes.io/revision: 1
Selector:               app=myapp,version=v1
Replicas:               3 desired | 3 updated | 3 total | 3 available | 0 unavailable
StrategyType:           RollingUpdate
MinReadySeconds:        0
RollingUpdateStrategy:  25% max unavailable, 25% max s_urge
Pod Template:
  Labels:  app=myapp
           version=v1
  Containers:
   myapp:
    Image:        docker.io/library/nginx:latest
    Port:         80/TCP
    Host Port:    0/TCP
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Conditions:
  Type           Status  Reason
  ----           ------  ------
  Progressing    True    NewReplicaSetAvailable
  Available      True    MinimumReplicasAvailable
OldReplicaSets:  <none>
NewReplicaSet:   deployment-demo-57885d597f (3/3 replicas created)
Events:
  Type    Reason             Age    From                   Message
  ----    ------             ----   ----                   -------
  Normal  ScalingReplicaSet  36m    deployment-controller  Scaled up replica set deployment-demo-57885d597f to 2
  Normal  ScalingReplicaSet  3m57s  deployment-controller  Scaled up replica set deployment-demo-57885d597f to 3 from 2
root@k8s-master:~/K8sStudy/Chapter2-8# kubectl get rs
NAME                         DESIRED   CURRENT   READY   AGE
deployment-demo-57885d597f   3         3         3       40m
frontend                     2         2         2       3d7h


4.2、Deployment管理pod: 缩容

通过deployment管理应用,实现缩容,直接修改replicas数量,把副本数变成2。

K8s控制器Deployment_Deployment_07

更新清单文件 Eg-Deployment.yaml。kubectl apply -f Eg-Deployment.yaml

K8s控制器Deployment_Deployment_08


4.3、Deployment管理pod: 更新

通过deployment管理应用,实现滚动更新,修改yaml清单文件,将镜像文件有nginx改为tomcat,容器端口由80改为8080.

在一个Master终端窗口执行如下:kubectl get pods -l app=myapp -w,-w:实时查看pod的变化,如删除、创建、重启等变化,-l 指定拥有的标签:app=myapp


root@k8s-master:~/K8sStudy/Chapter2-8# kubectl get pods -l app=myapp -w
NAME                               READY   STATUS    RESTARTS   AGE
deployment-demo-57885d597f-6jsk7   1/1     Running   0          2m2s
deployment-demo-57885d597f-dwbxm   1/1     Running   0          2m9s
^Croot@k8s-master:~/K8sStudy/Chapter2-8#

另起一个新的Master终端窗口修改yaml清单文件,按如下操作:

将镜像文件有nginx改为tomcat,容器端口由80改为8080。

K8s控制器Deployment_Deployment_09

应用/更新yaml清单文件,使修改生效:kubectl apply -f Eg-Deployment.yaml 

再回到刚才执行监测kubectl get pods -l app=myapp -w的那个窗口,可以看到信息如下:

root@k8s-master:~# kubectl get pods -l app=myapp -w
NAME                               READY   STATUS    RESTARTS   AGE
deployment-demo-57885d597f-6jsk7   1/1     Running   0          2m2s
deployment-demo-57885d597f-dwbxm   1/1     Running   0          2m9s
deployment-demo-9cf97b995-7fpkq    0/1     Pending   0          0s
deployment-demo-9cf97b995-7fpkq    0/1     Pending   0          0s
deployment-demo-9cf97b995-7fpkq    0/1     ContainerCreating   0          0s
deployment-demo-9cf97b995-7fpkq    0/1     ContainerCreating   0          0s
deployment-demo-9cf97b995-7fpkq    1/1     Running             0          2s
deployment-demo-57885d597f-6jsk7   1/1     Terminating         0          2m31s
deployment-demo-9cf97b995-s98kv    0/1     Pending             0          0s
deployment-demo-9cf97b995-s98kv    0/1     Pending             0          0s
deployment-demo-9cf97b995-s98kv    0/1     ContainerCreating   0          0s
deployment-demo-57885d597f-6jsk7   1/1     Terminating         0          2m31s
deployment-demo-57885d597f-6jsk7   0/1     Terminating         0          2m31s
deployment-demo-57885d597f-6jsk7   0/1     Terminating         0          2m32s
deployment-demo-9cf97b995-s98kv    0/1     ContainerCreating   0          1s
deployment-demo-57885d597f-6jsk7   0/1     Terminating         0          2m32s
deployment-demo-57885d597f-6jsk7   0/1     Terminating         0          2m32s
deployment-demo-9cf97b995-s98kv    1/1     Running             0          2s
deployment-demo-57885d597f-dwbxm   1/1     Terminating         0          2m40s
deployment-demo-57885d597f-dwbxm   1/1     Terminating         0          2m40s
deployment-demo-57885d597f-dwbxm   0/1     Terminating         0          2m40s
deployment-demo-57885d597f-dwbxm   0/1     Terminating         0          2m41s
deployment-demo-57885d597f-dwbxm   0/1     Terminating         0          2m41s
deployment-demo-57885d597f-dwbxm   0/1     Terminating         0          2m41s

更新Deployment过程解析:

K8s控制器Deployment_Deployment_10

pending表示正在进行调度,ContainerCreating表示正在创建一个pod,running表示运行一个pod,running起来一个pod之后再Terminating(停掉)一个pod,以此类推,直到所有pod完成滚动升级。


验证Deployment是否已经更新到新的版本,web服务更新为Tomcat:

K8s控制器Deployment_Deployment_11

查看ReplicaSet: kubectl get rs -l app=myapp

root@k8s-master:~# kubectl get rs -l app=myapp
NAME                         DESIRED   CURRENT   READY   AGE
deployment-demo-57885d597f   0         0         0       22h			# 历史的ReplicaSet
deployment-demo-9cf97b995    2         2         2       18m			# 只有一个ReplicaSet是激活状态
root@k8s-master:~#

上面可以看到rs有两个,上面那个是升级之前的,已经被停掉,但是可以随时回滚

查看deployment-demo这个控制器的历史版本:kubectl rollout history deployment deployment-demo

root@k8s-master:~# kubectl rollout history deployment deployment-demo
deployment.apps/deployment-demo 
REVISION  CHANGE-CAUSE
3         <none>
4         <none>

可以看到2个版本,一个历史版本,一个是当前版本。这里不是1和2是因为,我之前测试更新,有了4个版本。

4.4、Deployment管理pod: 回滚

接着上面的更新步骤,实现应用回滚。

执行命令查看更新的历史版本:kubectl rollout history deployment deployment-demo

K8s控制器Deployment_Deployment_12

执行命令进行回滚:kubectl rollout undo deployment deployment-demo --to-revisinotallow=3 --to-revisinotallow=3: 回滚到历史版本3

root@k8s-master:~# kubectl rollout undo deployment deployment-demo --to-revision=3
deployment.apps/deployment-demo rolled back
root@k8s-master:~# kubectl get pods -l app=myapp -owide
NAME                               READY   STATUS    RESTARTS   AGE     IP               NODE       NOMINATED NODE   READINESS GATES
deployment-demo-57885d597f-8mnm4   1/1     Running   0          2m15s   10.244.113.176   k8s-node   <none>           <none>
deployment-demo-57885d597f-c2srd   1/1     Running   0          2m7s    10.244.113.177   k8s-node   <none>           <none>

如上结果,回滚之后,会创建两个新的Pod,依然是滚动更新的方式,先创建一个Pod,然后再删除一个旧的Pod,再创建一个新的Pod,最后删除最后一个旧的Pod。

验证Deployment是否完成回滚,web服务回滚为nginx:

K8s控制器Deployment_Deployment_13

可以看到,web服务确实回滚到了nginx。


4.5 自定义滚动更新策略

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

4.5.1、max_urge和maxUnavailable取值范围

方式1:数值

maxUnavailable:  [0, 副本数]

max_urge:  [0, 副本数]

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

方式二:比例

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

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

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

建议配置:

maxUnavailable == 0

max_urge == 1

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

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

总结:

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

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


4.5.2、自定义策略:命令行直接更新Deployment

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

执行命令:kubectl patch deployment deployment-demo -p '{"spec":{"strategy":{"rollingUpdate": {"max_urge":1,"maxUnavailable":1}}}}'

root@k8s-master:~# kubectl patch deployment deployment-demo -p '{"spec":{"strategy":{"rollingUpdate": {"max_urge":1,"maxUnavailable":1}}}}'
deployment.apps/deployment-demo patched


查看Deployment控制器deployment-demo的详细信息:

确认是否配置更新策略成功。

K8s控制器Deployment_Deployment_14

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

这个rollingUpdate更新策略变成了刚才设定的,因为我们设定的pod副本数是2,1和1表示最少不能少于1个pod,最多不能超过3个pod,这个就是通过控制RollingUpdateStrategy这个字段来设置滚动更新策略的。

4.5.3、自定义策略:yaml清单文件

在yaml清单文件Eg-Deployment.yaml中直接定义更新策略。

root@k8s-master:~/K8sStudy/Chapter2-8# cat Eg-Deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deployment-demo
spec:
  replicas: 2
  strategy:						# 定义更新策略
    rollingUpdate:		# 更新方式:滚动更新
      max_urge: 1			# 最多可以比副本数多一个
      maxUnavailable: 0	# 最多比副本数少0个
  selector:
    matchLabels:
      app: myapp
      version: v1
  template:
    metadata:
      name: web
      labels:
        app: myapp
        version: v1
    spec:
      containers:
      - name: myapp
        image: docker.io/library/tomcat:latest
        imagePullPolicy: IfNotPresent
        ports:
        - containerPort: 8080

应用/更新yaml清单文件是修改生效:kubectl apply -f Eg-Deployment.yaml

查看Deployment控制器deployment-demo的详细信息:

K8s控制器Deployment_Deployment_15

4.5.4、验证自定义更新策略

配置Deployment更新策略为:maxUnavailable=0,max_urge=1。更新Pod镜像Tomcat为nginx,分析其更新过程。

K8s控制器Deployment_Deployment_16

应用/更新清单文件使其生效:

root@k8s-master:~/K8sStudy/Chapter2-8# kubectl apply -f Eg-Deployment.yaml 
deployment.apps/deployment-demo configured
root@k8s-master:~/K8sStudy/Chapter2-8#

监测Deployment控制器管理的Pod的状态变化(执行kubectl apply前,另起一个终端执行):kubectl get pods -l app=myapp -w

K8s控制器Deployment_Deployment_17