K8s学习笔记——3.Deployment
半野

1.为什么需要Deployment?

使用Pod虽然我们可以通过restartPolicy字段来保证Pod的Container在出错的时候能够自动重启,但是如果Node出现了问题,或者是人为的把Pod进行了删除,那么Pod将会在集群里彻底消失。此外,Pod资源作为K8s调度与管理的最小单元,并不能在部署到时候设置副本。因此Pod并不能对自己进行管理,不具备多实例、高可用等特点。

2.什么是Deployment?

Deployment是K8s用于管理Pod的资源对象,用来保证K8s中Pod的多实例、高可用与滚动更新、灰度部署等。可以说,Deployment是K8s中最常用最有用的一个对象,多用来发布无状态的应用。

3.创建一个Deployment

像创建Pod一样,我们可以让K8s为我们自动生成一个yaml模板:

1
`$ kubectl create deploy ngx-deploy --image=nginx:alpine --dry-run=client -o yaml apiVersion: apps/v1 kind: Deployment metadata: creationTimestamp: null labels: app: ngx-deploy name: ngx-deploy spec: replicas: 1 selector: matchLabels: app: ngx-deploy strategy: {} template: metadata: creationTimestamp: null labels: app: ngx-deploy spec: containers: - image: nginx:alpine name: nginx resources: {} status: {} `

4.关键字段

  1. spec.replicas:

副本数,用于描述我们希望创建多少个实例(Pod)。通过副本数字段,我们可以提高应用的可用性,减少因意外导致旧Pod被删除、新Pod未起引起可用性下降的问题。

此外,K8s集群会监控Deployment的中Pod的状态,如果Pod因意外被删除,导致集群中的Pod数量低于期望的replicas,K8s会自动创建Pod,以达到yaml中对replicas的期望值。

  1. spec.template

template中定义了1个Pod应该是什么样的,它其实就是Pod资源对象中的内容。K8s会根据spec.replicas字段,创建出spec.replicas个Pod,每个Pod描述样子就是spec.template所描述的。

  1. spec.selector

selector的作用是“筛选”出要被 Deployment 管理的 Pod 对象,筛选的规则是通过下属“matchLabels”的字段,定义了 Pod 对象应该携带的 label。它必须和“template”里 Pod 定义的“labels”完全相同(指name相同的label值相同,不是要具有Pod所有的labels),否则 Deployment 就会找不到要控制的 Pod 对象,apiserver 也会告诉你 yaml 格式校验错误无法创建。

为什Deployment不直接使用template定义的Pod,需要通过selector进行引用呢?答案就是解耦。

使用selector,Deployment将不会直接持有Pod对象,它只是Pod的其中一个管理者,这样我们就能够方便的进行扩展,使用其他对象对Pod进行管理,例如Service。

Deployment yaml 中的关系大致如下:

image

5.ReplicaSet

前面提到,Deployment是Pod的其中一个管理者,这其实也不准确,Deployment控制器也不直接操纵Pod。

应用存在副本、版本,如果直接Deployment控制器直接管理Pod,对于版本管理、灰度部署、滚动更新等功能就比较麻烦,因此在Deployment和Pod直接还存在一个ReplicaSet的对象,它是对对应着不同不Pod版本,是Pod直接管理者。Deployment通过操纵ReplicaSet间接的管理Pod:

image

上述这个图就描述了在 replicas=5 的设置下,灰度部署(滚动更新)2/5的时候,Deployment的状态。

我们不用直接创建ReplicaSet,在创建Deployment的时候,K8s会默认创建ReplicaSet,并由Deployment控制器进行管理。K8s也不建议人工管理ReplicaSet。

6.操作Deployment

对K8s自动生成的yaml进行下精简,并写入到ngx-deploy.yml文件中:

1
`# ngx-deploy.yml apiVersion: apps/v1 kind: Deployment metadata: labels: app: ngx-deploy name: ngx-deploy spec: replicas: 2 selector: matchLabels: app: ngx-deploy template: metadata: labels: app: ngx-deploy pdl: iot spec: containers: - image: nginx:alpine name: nginx `

6.1.C:创建Deployment

通过yaml声明式进行各种资源的创建,都仅需要kubectl apply即可。

1
`kubectl apply -f ngx-deploy.yml `

6.2.R:查看Deployment

deployments具有shortname deploy,所以可以通过以下两个命令查看Deployment的信息

1
`# 命令1 kubectl get deployments ngx-deploy # 命令2 kubectl get deploy ngx-deploy `

image

6.2.1.R:查看Pod

由于在get pods的时候,需要完全指定Pod的name,无法通过前缀匹配,因此这里使用grep进行下过滤:

1
`kubectl get pods | grep ngx-deploy `

image

可以看到Pod的Name是由三部分组成的:[Deployment Name]-[随机字符串1]-[随机字符串2](准确的说,随机字符串是Pod模板的哈希值),而且,第二段的随机字符是相同的。

其实[Deployment Name]-[随机字符串1]是该Pod所归属的 ReplicaSet 的 Name。你可以通过kubectl get rs命令,来查看所有的 ReplicaSet。

6.2.2.D:删除一个Pod

Deployment会保证Pod的数量维持在spec.replicas,如果删除一个Pod,它会自动创建一个新的Pod:

1
`kubectl delete pod ngx-deploy-79749cd4d4-kdqff `

删除Pod后,我们再查看Pod的列表,可以发现ngx-deploy-79749cd4d4-kdqff确实已经被删除,并且K8s创建了一个新的Podngx-deploy-79749cd4d4-rcml5

image

这里进行Pod筛选的时候,并没有使用grep,通过-l指令label进行的筛选。

6.3.U:更新Deployment

我们更新下spec.replicas字段,将副本数更改为3,然后再执行下kubectl apply,这时候我们再查看Pod的数量,会发现已经有三个Pod了。

image

6.4.D:删除Deployment

通过yaml声明式创建的资源,删除都一样,使用kubectl delete,并指定文件即可:

1
`kubectl delete -f ngx-deploy.yml `
由 Hexo 驱动 & 主题 Keep
总字数 105.7k 访客数 访问量