k8s入门教程七:Pod控制器Deployment

简介

Pod控制器是用于实现管理pod的中间层,确保pod资源符合预期的状态,pod的资源出现故障时,会尝试进行重启,当根据重启策略无效,则会重新新建pod的资源。分为以下几类:

  • ReplicationController(RC)用来确保容器应用的副本数始终保持在用户定义的副本数,即如果有容器异常退出,会自动创建新的 Pod 来替代;而如果异常多出来的容器也会自动回收;
  • ReplicaSet(RS):在新版本的 Kubernetes 中建议使用 ReplicaSet 来取代 ReplicationController 。ReplicaSet 跟 ReplicationController 没有本质的不同,只是名字不一样,但 ReplicaSet 支持集合式的 selector。
  • Deployment:为 Pod 和 ReplicaSet 提供了一个声明式定义 (declarative) 方法,用来替代以前的 ReplicationController 来方便的管理应用。
  • DaemonSet:确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
  • Job:负责批处理任务,即仅执行一次的任务,它保证批处理任务的一个或多个 Pod 成功结束。
  • Cron Job:管理基于时间的 Job,即在给定时间点只运行一次以及周期性地在给定时间点运行。
  • StatefulSet:作为 Controller 为 Pod 提供唯一的标识。它可以保证部署和 scale 的顺序,StatefulSet是为了解决有状态服务的问题(对应Deployments和ReplicaSets是为无状态服务而设计)。
  • Horizontal Pod Autoscaling:Pod水平自动缩放

ReplicaSet

ReplicaSet副本集简称RS,用于实现副本数的控制,确保pod副本数量符合预期状态,并且支持滚动式自动扩容和缩容功能。ReplicaSet主要三个组件组成:

  • 用户期望的pod副本数量
  • 标签选择器,判断哪个pod归自己管理
  • 当现存的pod数量不足,会根据pod资源模板进行新建

其与Deployment的关系如下:

在创建一个Deployment时,会自动创建一个ReplicaSet,然后由ReplicaSet去创建POD。在Deployment升级时,旧的ReplicaSet会保留,但pod都会升级到新的ReplicaSet上。

虽然ReplicaSet可以独立使用,但一般还是建议使用 Deployment 来自动管理ReplicaSet,这样就无需担心跟其他机制的不兼容问题(比如ReplicaSet不支持rolling-update但Deployment支持)。

yaml定义如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
apiVersion: apps/v1  #api版本定义
kind: ReplicaSet  #定义资源类型为ReplicaSet
metadata:  #元数据定义
name: myapp
namespace: default
spec:  #ReplicaSet的规格定义
replicas: 2  #定义副本数量为2个
selector:    #标签选择器,定义匹配pod的标签
matchLabels:
app: myapp
release: canary
template:  #pod的模板定义
metadata:  #pod的元数据定义
name: myapp-pod   #自定义pod的名称 
labels:   #定义pod的标签,需要和上面定义的标签一致,也可以多出其他标签
app: myapp
release: canary
environment: qa
spec:  #pod的规格定义
containers:  #容器定义
- name: myapp-container  #容器名称
image: ikubernetes/myapp:v1  #容器镜像
ports:  #暴露端口
- name: http
containerPort: 80

创建:

1
2
3
4
5
6
7
8
9
10
#命令行查看ReplicaSet清单定义规则
kubectl explain rs
kubectl explain rs.spec
kubectl explain rs.spec.template

#创建ReplicaSet定义的pod
kubectl create -f rs-demo.yaml

kubectl get pods  #获取pod信息
kubectl describe pods myapp-***  #查看pod详细信息

Deployment

简介

Deployment为Pod和Replica Set(下一代Replication Controller)提供声明式更新

只需要在 Deployment 中描述想要的目标状态是什么,Deployment controller 就会帮您将 Pod 和ReplicaSet 的实际状态改变到您的目标状态。也可以定义一个全新的 Deployment 来创建 ReplicaSet 或者删除已有的 Deployment 并创建一个新的来替换。

典型的用例如下:

  • (1)使用Deployment来创建ReplicaSet。ReplicaSet在后台创建pod。检查启动状态,看它是成功还是失败。
  • (2)然后,通过更新Deployment的PodTemplateSpec字段来声明Pod的新状态。这会创建一个新的ReplicaSet,Deployment会按照控制的速率将pod从旧的ReplicaSet移动到新的ReplicaSet中。
  • (3)如果当前状态不稳定,回滚到之前的Deployment revision。每次回滚都会更新Deployment的revision。
  • (4)扩容Deployment以满足更高的负载。
  • (5)暂停Deployment来应用PodTemplateSpec的多个修复,然后恢复上线。
  • (6)根据Deployment 的状态判断上线是否hang住了。
  • (7)清除旧的不必要的 ReplicaSet。

Deployment定义

我们定义一个Deployment,副本数为3,Pod以模版Template的形式封装在Deployment中,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 2
selector:
matchLabels:
app: nginx
version: 1.7.9
template:
metadata:
labels:
app: nginx
version: 1.7.9
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

我们使用kubectl explain deployment.spec查看具体Deployment spec的配置选项,具体如下:

  • Replicas(副本数量):可选字段,指定期望的pod数量,默认是1。
  • Selector(选择器):可选字段,用来指定label selector,圈定Deployment管理的pod范围。如果被指定了.spec.selector就必须匹配 .spec.template.metadata.labels,否则它将被API拒绝。如果 .spec.selector 没有被指定, .spec.selector.matchLabels 默认是.spec.template.metadata.labels。同时在Pod的template跟.spec.template不同或者数量超过了.spec.replicas规定的数量的情况下,Deployment会杀掉label跟selector不同的Pod。
  • Pod Template(Pod模板):
    • .spec.template 是 .spec中唯一要求的字段。
    • .spec.template 是 pod template. 它跟 Pod有一模一样的schema,除了它是嵌套的并且不需要apiVersion 和 kind字段。
    • .spec.template.spec.restartPolicy 可以设置为 Always , 如果不指定的话这就是默认配置。
  • strategy(更新策略):指定新的Pod替换旧的Pod的策略。.spec.strategy.type可以是”Recreate”或者是 “RollingUpdate”。”RollingUpdate”是默认值

    • Recreate:重建式更新,就是删一个建一个。类似于ReplicaSet的更新方式,即首先删除现有的Pod对象,然后由控制器基于新模板重新创建新版本资源对象。
    • rollingUpdate:滚动更新,简单定义 更新期间pod最多有几个等。可以指定maxUnavailablemaxSurge 来控制 rolling update 进程。
      • maxSurge:.spec.strategy.rollingUpdate.maxSurge 是可选配置项,用来指定可以超过期望的Pod数量的最大个数。该值可以是一个绝对值(例如5)或者是期望的Pod数量的百分比(例如10%)。当MaxUnavailable为0时该值不可以为0。通过百分比计算的绝对值向上取整。默认值是1。例如,该值设置成30%,启动rolling update后新的ReplicatSet将会立即扩容,新老Pod的总数不能超过期望的Pod数量的130%。旧的Pod被杀掉后,新的ReplicaSet将继续扩容,旧的ReplicaSet会进一步缩容,确保在升级的所有时刻所有的Pod数量和不会超过期望Pod数量的130%。
      • maxUnavailable:.spec.strategy.rollingUpdate.maxUnavailable 是可选配置项,用来指定在升级过程中不可用Pod的最大数量。该值可以是一个绝对值(例如5),也可以是期望Pod数量的百分比(例如10%)。通过计算百分比的绝对值向下取整。 如果.spec.strategy.rollingUpdate.maxSurge 为0时,这个值不可以为0。默认值是1。例如,该值设置成30%,启动rolling update后旧的ReplicatSet将会立即缩容到期望的Pod数量的70%。新的Pod ready后,随着新的ReplicaSet的扩容,旧的ReplicaSet会进一步缩容确保在升级的所有时刻可以用的Pod数量至少是期望Pod数量的70%。
      • maxSurge和maxUnavailable的属性值不可同时为0,否则Pod对象的副本数量在符合用户期望的数量后无法做出合理变动以进行更新操作。
  • revisionHistoryLimit(历史版本记录):Deployment revision history存储在它控制的ReplicaSets中。默认保存记录10个。

Deployment创建

有2种,一是命令式,kubectl run nginx-deploy --image=nginx:1.14-alpine --port=80 --replicas=1 或者使用 kubectl apply -f deploy-demo.yaml 来创建上面定义的deploy。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[root@master ~]# kubectl get deployment nginx-deployment
NAME READY UP-TO-DATE AVAILABLE AGE
nginx-deployment 2/2 2 2 24d
[root@master ~]# kubectl get rs nginx-deployment-54f57cf6bf
NAME DESIRED CURRENT READY AGE
nginx-deployment-54f57cf6bf 2 2 2 24d
[root@master ~]# kubectl get pods |grep nginx-deployment-54f57cf6bf
nginx-deployment-54f57cf6bf-5zh9k 1/1 Running 0 5d6h
nginx-deployment-54f57cf6bf-sjv4l 1/1 Running 0 24d

#查看控制的关系
[root@master ~]# kubectl describe pod nginx-deployment-54f57cf6bf-5zh9k |grep 'Controlled By'
Controlled By: ReplicaSet/nginx-deployment-54f57cf6bf
[root@master ~]# kubectl describe rs nginx-deployment-54f57cf6bf |grep 'Controlled By'
Controlled By: Deployment/nginx-deployment

由上可以看到是由deploy创建了一个rs,然后由rs创建了pod。

Deployment相关操作

扩容

有三个方法进行扩容。

(1)使用以下命令扩容 Deployment:

1
[root@k8s-master ~]# kubectl scale deployment nginx-deployment --replicas 5

(2)直接修改yaml文件的方式进行扩容:

1
2
3
4
5
[root@k8s-master ~]# vim demo.yaml
修改.spec.replicas的值
spec:
replicas: 5
[root@k8s-master ~]# kubectl apply -f demo.yaml

(3)通过打补丁的方式进行扩容:

1
2
[root@k8s-master ~]# kubectl patch deployment myapp-deploy -p '{"spec":{"replicas":5}}'
[root@k8s-master ~]# kuebctl get pods

更新升级

更新升级指的是更新容器的镜像,一般有两个方法:

  • 通过set 命令直接修改image的版本进行升级:kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1,注意,其中nginx=这个ngninx表示的是container的名字。
  • 使用 kubectl edit deployment nginx-deployment 来修改image的值。

如下是通过2种方法后,看到了出现了三个RS:

1
2
3
4
5
[root@master ~]# kubectl get rs -o wide -l app=nginx
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
nginx-deployment-54f57cf6bf 1 1 1 24d nginx nginx:1.7.9 app=nginx,pod-template-hash=54f57cf6bf
nginx-deployment-56f8998dbc 0 0 0 24d nginx nginx:1.9.1 app=nginx,pod-template-hash=56f8998dbc
nginx-deployment-6654964744 2 2 1 83s nginx nginx:1.17.9 app=nginx,pod-template-hash=6654964744

版本相关操作

主要是跟 kubectl rollout有关

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# 查看版本信息,由于在创建deployment时没有增加--record参数,所以并不能看到revision的变化。
# 在创建 Deployment 的时候如果使用了--record参数可以记录命令,就可以方便的查看每次 revision 的变化。
[root@master ~]# kubectl rollout history deploy nginx-deployment
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
2 <none>
3 <none>
4 <none>

# 查看具体的信息
[root@master ~]# kubectl rollout history deploy nginx-deployment --revision=2
deployment.apps/nginx-deployment with revision #2
Pod Template:
Labels: app=nginx
pod-template-hash=56f8998dbc
Containers:
nginx:
Image: nginx:1.9.1
Port: 80/TCP
Host Port: 0/TCP
Environment: <none>
Mounts: <none>
Volumes: <none>

# 回退到第2个版本
[root@master ~]# kubectl rollout undo deploy nginx-deployment --to-revision=2
deployment.apps/nginx-deployment rolled back

# 查看回退时的具体信息
[root@master ~]# kubectl rollout status deploy nginx-deployment
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
Waiting for deployment "nginx-deployment" rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out

自动扩展

如果集群支持 horizontal pod autoscaling 的话,还可以为Deployment设置自动扩展

1
kubectl autoscale deployment nginx-deployment --min=10 --max=15 --cpu-percent=80

参考文档

  • 本文作者: wumingx
  • 本文链接: https://www.wumingx.com/k8s/kubernetes-Deployment.html
  • 本文主题: k8s入门教程七:Pod控制器Deployment
  • 版权声明: 本博客所有文章除特别声明外,转载请注明出处!如有侵权,请联系我删除。
0%