介绍

pod是k8s的最小的管理单元,在k8s中,可以按照pod的创建方式分为两类。

  • 自主式pod:由k8s直接创建的pod,这种pod删除后就没有了。也不会重建。
  • 控制器创建的pod:k8s通过控制器创建的pod,这种pod删除后还会重建,删除控制器pod也会被删除。

    什么是控制器

    pod控制器是管理pod的中间层,使用pod控制器后,只需告诉控制器想要多少个什么样的po就可以了,它会创建出满足条件的pod,如果pod出现问题,它会基于指定策略出现编排pod。
    在k8s中常见的pod控制器有以下几种:

  • ReplicationController:比较原始的控制器,已被弃用,由ReplicaSet替代。

  • ReplicaSet:保证副本数量一直维持在期望值,并支持pod数量的扩缩容,镜像版本升级。
  • Deployement:(最常用)通过控制ReplicaSet来控制pod,支持滚动更新,回退版本。
  • Horizontal Pod AutoScaler:可以根据集群负载均衡自动水平调整pod数量,实现削锋填谷。
  • DaemonSet:在集群中指定node运行且仅允许一个副本,一般用于守护进程类的任务。
  • Job:它创建出来的pod只要完成任务就立即退出,不需要重建或重启,用于执行一次任务。
  • CronJob:它创建的Pod负责周期性任务控制,不需要持续后台运行。
  • StateFulSet:管理有状态的应用。

    ReplicaSet(RS)

    ReplicaSet用于保证一定数量的Pod正常运行,它会持续监听这些pod的运行状态,一旦Pod发生故障,就会重启或重建,同时支持对pod数量的扩缩容和版本升降级。
    5.Pod控制器详解 - 图1
    ReplicaSet资源清单文件:

    1. apiVersion: apps/v1 # 版本号
    2. kind: ReplicaSet # 类型
    3. metadata: # 元数据
    4. name: # rs名称
    5. namespace: # 所属命名空间
    6. labels: #标签
    7. controller: rs
    8. spec: # 详情描述
    9. replicas: 3 # 副本数量
    10. selector: # 选择器,通过它指定该控制器管理哪些pod
    11. matchLabels: # Labels匹配规则
    12. app: nginx-pod
    13. matchExpressions: # Expressions匹配规则
    14. - {key: app, operator: In, values: [nginx-pod]}
    15. template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
    16. metadata:
    17. labels:
    18. app: nginx-pod
    19. spec:
    20. containers:
    21. - name: nginx
    22. image: nginx:1.17.1
    23. ports:
    24. - containerPort: 80

    在这里,需要了解的新配置是spec下面的几个选项。

  • replicas:指定副本数量,就是创建出来的pod个数,默认1。

  • selector:选择器,这里采用的是Label Selector,用来建立与pod之间的联系。
  • template:模板,就是创建pod所使用的模板。

示例脚本:

  1. apiVersion: apps/v1
  2. kind: ReplicaSet
  3. metadata:
  4. name: pc-replicaset
  5. namespace: dev
  6. spec:
  7. replicas: 3
  8. selector:
  9. matchLabels:
  10. app: nginx-pod
  11. template:
  12. metadata:
  13. labels:
  14. app: nginx-pod
  15. spec:
  16. containers:
  17. - name: nginx
  18. image: nginx:1.17.1
  1. # 查看当前控制器创建出来的pod
  2. # 这里发现控制器创建出来的pod的名称是在控制器名称后面拼接了-xxxxx随机码
  3. [root@k8s-master01 ~]# kubectl get pod -n dev
  4. NAME READY STATUS RESTARTS AGE
  5. pc-replicaset-6vmvt 1/1 Running 0 54s
  6. pc-replicaset-fmb8f 1/1 Running 0 54s
  7. pc-replicaset-snrk2 1/1 Running 0 54s

扩缩容:

  • 通过编辑控制器元信息实现,kubectl edit rs [rsname] -n [namespace] 改变其副本数保存即可(类似vim操作)
  • 通过纯命令kubectl scale rs [rsname] —replicas=3 -n [namespace]

    镜像升级

  • 通过编辑控制器元信息实现,kubectl edit rs [rsname] -n [namespace] 改变其镜像地址保存即可(类似vim操作)

  • 通过纯命令kubectl set image rs [rsname] [containername]=[image] -n [nsname]。例如:kubectl set image rs pc-replicaset nginx=nginx:1.17.1 -n dev

    Deployment(deploy)

    在k8s1.2版本中引入,用来管理ReplicaSet,所以在ReplicaSet的基础上增加了发布停止、继续、滚动升级、回滚。
    5.Pod控制器详解 - 图2
    Deployment主要功能有以下几点:

  • 支持ReplicaSet所有功能。

  • 支持发布停止,继续。
  • 支持滚动升级和回滚版本。

Deployment的资源清单文件:

  1. apiVersion: apps/v1 # 版本号
  2. kind: Deployment # 类型
  3. metadata: # 元数据
  4. name: # rs名称
  5. namespace: # 所属命名空间
  6. labels: #标签
  7. controller: deploy
  8. spec: # 详情描述
  9. replicas: 3 # 副本数量
  10. revisionHistoryLimit: 3 # 保留历史版本
  11. paused: false # 暂停部署,默认是false
  12. progressDeadlineSeconds: 600 # 部署超时时间(s),默认是600
  13. strategy: # 策略
  14. type: RollingUpdate # 滚动更新策略
  15. rollingUpdate: # 滚动更新
  16. maxSurge: 30% # 最大额外可以存在的副本数,可以为百分比,也可以为整数
  17. maxUnavailable: 30% # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
  18. selector: # 选择器,通过它指定该控制器管理哪些pod
  19. matchLabels: # Labels匹配规则
  20. app: nginx-pod
  21. matchExpressions: # Expressions匹配规则
  22. - {key: app, operator: In, values: [nginx-pod]}
  23. template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
  24. metadata:
  25. labels:
  26. app: nginx-pod
  27. spec:
  28. containers:
  29. - name: nginx
  30. image: nginx:1.17.1
  31. ports:
  32. - containerPort: 80

示例脚本:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: pc-deployment
  5. namespace: dev
  6. spec:
  7. replicas: 3
  8. selector:
  9. matchLabels:
  10. app: nginx-pod
  11. template:
  12. metadata:
  13. labels:
  14. app: nginx-pod
  15. spec:
  16. containers:
  17. - name: nginx
  18. image: nginx:1.17.1

镜像更新(不推荐):

deployment支持两种更新策略,重建更新和滚动更新,通过指定strategy来实现。

  1. strategy:指定新的Pod替换旧的Pod的策略, 支持两个属性:
  2. type:指定策略类型,支持两种策略
  3. Recreate:在创建出新的Pod之前会先杀掉所有已存在的Pod
  4. RollingUpdate:滚动更新,就是杀死一部分,就启动一部分,在更新过程中,存在两个版本Pod
  5. rollingUpdate:当typeRollingUpdate时生效,用于为RollingUpdate设置参数,支持两个属性:
  6. maxUnavailable:用来指定在升级过程中不可用Pod的最大数量,默认为25%。
  7. maxSurge 用来指定在升级过程中可以超过期望的Pod的最大数量,默认为25%。

重建更新

编辑示例脚本文件,在spec节点下添加更新策略

  1. spec:
  2. strategy: # 策略
  3. type: Recreate # 重建更新

滚动更新

编辑示例脚本文件,在spec节点下添加更新策略

  1. spec:
  2. strategy: # 策略
  3. type: RollingUpdate # 滚动更新策略
  4. rollingUpdate:
  5. maxSurge: 25%
  6. maxUnavailable: 25%

滚动更新图解
5.Pod控制器详解 - 图3

版本回退(不推荐)

kubectl rollout:版本升级相关功能,支持下面选项。

  • status 显示当前升级状态。
  • history 显示升级历史记录。
  • pause 暂停升级过程。
  • resume 继续暂停中的升级。
  • restart 重启版本升级。
  • undo 回滚上一级版本(可以使用 —to-revision回滚到指定版本)

示例代码

  1. # 查看当前升级版本的状态
  2. [root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n dev
  3. deployment "pc-deployment" successfully rolled out
  4. # 查看升级历史记录
  5. [root@k8s-master01 ~]# kubectl rollout history deploy pc-deployment -n dev
  6. deployment.apps/pc-deployment
  7. REVISION CHANGE-CAUSE
  8. 1 kubectl create --filename=pc-deployment.yaml --record=true
  9. 2 kubectl create --filename=pc-deployment.yaml --record=true
  10. 3 kubectl create --filename=pc-deployment.yaml --record=true
  11. # 可以发现有三次版本记录,说明完成过两次升级
  12. # 版本回滚
  13. # 这里直接使用--to-revision=1回滚到了1版本, 如果省略这个选项,就是回退到上个版本,就是2版本
  14. [root@k8s-master01 ~]# kubectl rollout undo deployment pc-deployment --to-revision=1 -n dev
  15. deployment.apps/pc-deployment rolled back
  16. # 查看发现,通过nginx镜像版本可以发现到了第一版
  17. [root@k8s-master01 ~]# kubectl get deploy -n dev -o wide
  18. NAME READY UP-TO-DATE AVAILABLE AGE CONTAINERS IMAGES
  19. pc-deployment 4/4 4 4 74m nginx nginx:1.17.1
  20. # 查看rs,发现第一个rs中有4个pod运行,后面两个版本的rs中pod为运行
  21. # 其实deployment之所以可是实现版本的回滚,就是通过记录下历史rs来实现的,
  22. # 一旦想回滚到哪个版本,只需要将当前版本pod数量降为0,然后将回滚版本的pod提升为目标数量就可以了
  23. [root@k8s-master01 ~]# kubectl get rs -n dev
  24. NAME DESIRED CURRENT READY AGE
  25. pc-deployment-6696798b78 4 4 4 78m
  26. pc-deployment-966bf7f44 0 0 0 37m
  27. pc-deployment-c848d767 0 0 0 71m

金丝雀发布

就是升级版本同时暂停,这样就只会有一部分pod做了更新,那么就可以分流一些流量给新版本的pod,同时观察新pod的状态,如果有问题就立即回滚,没有问题在继续即可。

  1. # 更新deployment的版本,并配置暂停deployment
  2. [root@k8s-master01 ~]# kubectl set image deploy pc-deployment nginx=nginx:1.17.4 -n dev && kubectl rollout pause deployment pc-deployment -n dev
  3. deployment.apps/pc-deployment image updated
  4. deployment.apps/pc-deployment paused
  5. #观察更新状态
  6. [root@k8s-master01 ~]# kubectl rollout status deploy pc-deployment -n dev 
  7. Waiting for deployment "pc-deployment" rollout to finish: 2 out of 4 new replicas have been updated...
  8. # 监控更新的过程,可以看到已经新增了一个资源,但是并未按照预期的状态去删除一个旧的资源,就是因为使用了pause暂停命令
  9. [root@k8s-master01 ~]# kubectl get rs -n dev -o wide
  10. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
  11. pc-deployment-5d89bdfbf9 3 3 3 19m nginx nginx:1.17.1
  12. pc-deployment-675d469f8b 0 0 0 14m nginx nginx:1.17.2
  13. pc-deployment-6c9f56fcfb 2 2 2 3m16s nginx nginx:1.17.4
  14. [root@k8s-master01 ~]# kubectl get pods -n dev
  15. NAME READY STATUS RESTARTS AGE
  16. pc-deployment-5d89bdfbf9-rj8sq 1/1 Running 0 7m33s
  17. pc-deployment-5d89bdfbf9-ttwgg 1/1 Running 0 7m35s
  18. pc-deployment-5d89bdfbf9-v4wvc 1/1 Running 0 7m34s
  19. pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 3m31s
  20. pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 3m31s
  21. # 确保更新的pod没问题了,继续更新
  22. [root@k8s-master01 ~]# kubectl rollout resume deploy pc-deployment -n dev
  23. deployment.apps/pc-deployment resumed
  24. # 查看最后的更新情况
  25. [root@k8s-master01 ~]# kubectl get rs -n dev -o wide
  26. NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES
  27. pc-deployment-5d89bdfbf9 0 0 0 21m nginx nginx:1.17.1
  28. pc-deployment-675d469f8b 0 0 0 16m nginx nginx:1.17.2
  29. pc-deployment-6c9f56fcfb 4 4 4 5m11s nginx nginx:1.17.4
  30. [root@k8s-master01 ~]# kubectl get pods -n dev
  31. NAME READY STATUS RESTARTS AGE
  32. pc-deployment-6c9f56fcfb-7bfwh 1/1 Running 0 37s
  33. pc-deployment-6c9f56fcfb-996rt 1/1 Running 0 5m27s
  34. pc-deployment-6c9f56fcfb-j2gtj 1/1 Running 0 5m27s
  35. pc-deployment-6c9f56fcfb-rf84v 1/1 Running 0 37

Horizontal Pod Autoscaler(HPA)

通过监控pod的状态而自动地、智能化的实现pod的数量调整。
HPA根据pod的利用率来对比HPA定义的指标做对比,计算出需要伸缩的具体值,最后实现pod数量的调整。
5.Pod控制器详解 - 图4

安装metrics-server

metrics-server可以用来收集资源中的资源使用情况。

  1. # 安装git
  2. [root@k8s-master01 ~]# yum install git -y
  3. # 获取metrics-server, 注意使用的版本
  4. [root@k8s-master01 ~]# git clone -b v0.3.6 https://github.com/kubernetes-incubator/metrics-server
  5. # 修改deployment, 注意修改的是镜像和初始化参数
  6. [root@k8s-master01 ~]# cd /root/metrics-server/deploy/1.8+/
  7. [root@k8s-master01 1.8+]# vim metrics-server-deployment.yaml
  8. 按图中添加下面选项
  9. hostNetwork: true
  10. image: registry.cn-hangzhou.aliyuncs.com/google_containers/metrics-server-amd64:v0.3.6
  11. args:
  12. - --kubelet-insecure-tls
  13. - --kubelet-preferred-address-types=InternalIP,Hostname,InternalDNS,ExternalDNS,ExternalIP

5.Pod控制器详解 - 图5

  1. # 安装metrics-server
  2. [root@k8s-master01 1.8+]# kubectl apply -f ./
  3. # 查看pod运行情况
  4. [root@k8s-master01 1.8+]# kubectl get pod -n kube-system
  5. metrics-server-6b976979db-2xwbj 1/1 Running 0 90s
  6. # 使用kubectl top node 查看资源使用情况
  7. [root@k8s-master01 1.8+]# kubectl top node
  8. NAME CPU(cores) CPU% MEMORY(bytes) MEMORY%
  9. k8s-master01 289m 14% 1582Mi 54%
  10. k8s-node01 81m 4% 1195Mi 40%
  11. k8s-node02 72m 3% 1211Mi 41%
  12. [root@k8s-master01 1.8+]# kubectl top pod -n kube-system
  13. NAME CPU(cores) MEMORY(bytes)
  14. coredns-6955765f44-7ptsb 3m 9Mi
  15. coredns-6955765f44-vcwr5 3m 8Mi
  16. etcd-master 14m 145Mi
  17. ...
  18. # 至此,metrics-server安装完成

准备deployment和service

示例脚本:

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: nginx
  5. namespace: dev
  6. spec:
  7. strategy: # 策略
  8. type: RollingUpdate # 滚动更新策略
  9. replicas: 1
  10. selector:
  11. matchLabels:
  12. app: nginx-pod
  13. template:
  14. metadata:
  15. labels:
  16. app: nginx-pod
  17. spec:
  18. containers:
  19. - name: nginx
  20. image: nginx:1.17.1
  21. resources: # 资源配额
  22. limits: # 限制资源(上限)
  23. cpu: "1" # CPU限制,单位是core数
  24. requests: # 请求资源(下限)
  25. cpu: "100m" # CPU限制,单位是core数

也可以通过纯命令创建

  1. # 创建deployment
  2. kubectl run nginx --image=nginx:1.17.1 --requests=cpu=100m -n dev
  3. # 创建service
  4. kubectl expose deployment nginx --type=NodePort --port=80 -n dev

部署HPA

示例脚本:

  1. apiVersion: autoscaling/v1
  2. kind: HorizontalPodAutoscaler
  3. metadata:
  4. name: pc-hpa
  5. namespace: dev
  6. spec:
  7. minReplicas: 1 #最小pod数量
  8. maxReplicas: 10 #最大pod数量
  9. targetCPUUtilizationPercentage: 3 # CPU使用率指标
  10. scaleTargetRef: # 指定要控制的nginx信息
  11. apiVersion: /v1
  12. kind: Deployment
  13. name: nginx

创建hpa之后可以通过压测工具拉高pod的cpu使用率从而使其扩容。

DaemonSet(DS)

该类型控制器可以保证集群中的每一个节点(或指定节点)都运行一个副本,一般适用于日志收集,节点监控等场景。也就是说,如果一个pod提供的功能是节点级别的(每个节点都需要一个且只需要一个),那么这类pod就适合使用DaemonSet类型的控制器创建。
5.Pod控制器详解 - 图6
特点:

  • 每当向集群中添加一个节点,会自动在该节点上创建一个副本。
  • 当节点被移动,pod也会被回收。

    资源清单

    apiVersion: apps/v1 # 版本号
    kind: DaemonSet # 类型       
    metadata: # 元数据
    name: # rs名称 
    namespace: # 所属命名空间 
    labels: #标签
      controller: daemonset
    spec: # 详情描述
    revisionHistoryLimit: 3 # 保留历史版本
    updateStrategy: # 更新策略
      type: RollingUpdate # 滚动更新策略
      rollingUpdate: # 滚动更新
        maxUnavailable: 1 # 最大不可用状态的 Pod 的最大值,可以为百分比,也可以为整数
    selector: # 选择器,通过它指定该控制器管理哪些pod
      matchLabels:      # Labels匹配规则
        app: nginx-pod
      matchExpressions: # Expressions匹配规则
        - {key: app, operator: In, values: [nginx-pod]}
    template: # 模板,当副本数量不足时,会根据下面的模板创建pod副本
      metadata:
        labels:
          app: nginx-pod
      spec:
        containers:
        - name: nginx
          image: nginx:1.17.1
          ports:
          - containerPort: 80
    
    示例脚本
    apiVersion: apps/v1
    kind: DaemonSet      
    metadata:
    name: pc-daemonset
    namespace: dev
    spec: 
    selector:
      matchLabels:
        app: nginx-pod
    template:
      metadata:
        labels:
          app: nginx-pod
      spec:
        containers:
        - name: nginx
          image: nginx:1.17.1
    
    剩下job,cronjob没意义