kubernetes工作负载之控制器

目录

​一、概述

二、Deployment 控制器

2.1Deployment 部署应用

2.2Deployment滚动升级

2.2.1应用部署完成

2.2.2更新镜像三种方式

2.3 Deployment 发布失败回滚

2.4Deployment 水平扩容

三、DaemonSet控制器

四、Job控制器

4.1Job一次性执行

4.2定时任务(CronJob)

五、总结


一、概述


 在Kubernetes中,Pod是最小的管理单元,是一组紧密关联的容器组合。

但是,单独的Pod并不能保障总是可用,比如我们创建一个nginx的Pod,因为某些原因,该Pod被意外删除,我们希望其能够自动新建一个同属性的Pod。很遗憾,单纯的Pod并不能满足需求。

为此,Kubernetes实现了一系列控制器来管理Pod,使Pod的期望状态和实际状态保持一致

工作负载控制器(Workload Controllers)是K8s的一个抽象概念,用于更高级层次对象,部署和管理Pod。常用工作负载控制器:

• Deployment :无状态应用部署

• StatefulSet :有状态应用部署

• DaemonSet :确保所有Node运行同一个Pod

• Job :一次性任务

• Cronjob :定时任务

控制器的作用

• 管理Pod对象

• 使用标签与Pod关联

• 控制器实现了Pod的运维,例如滚动更新、伸缩、副本管理、维护Pod状态等。

Deployment的功能:

• 管理Pod和ReplicaSet

• 具有上线部署、副本设定、滚动升级、回滚等功能

• 提供声明式更新,例如只更新一个新的Image 应用场景:网站、API、微服务


二、Deployment 控制器


2.1Deployment 部署应用

deployment部署一个应用,副本数为3

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 3  # 副本数量
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx  # Pod副本的标签
    spec:
      containers:
      - name: web
        image: nginx:1.15

pod 副本为3 , 成功调度到 node1和node2两个节点上

服务暴露出来,查询对用的服务端口

kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

三个节点的任意 IP加上 31812端口 都可以访问

2.2Deployment滚动升级

业务应用基本都是通过Deployment的方式部署在Kubernetes中的,应用的更新和回滚是常态的工作,特别是在互联网企业,快速迭代抓住用户的一个重要途径。

但是,并不是每一次的迭代都是100%正常的,如果异常,如何快速恢复也是要考虑的事情。为适应这种场景,Deployment提供滚动更新和快速回滚的能力。

Deployment默认的更新方式就是滚动更新,可以通过strategy.type来指定更新方式。

  • Recreate:先删除所有的Pod,再创建
  • RollingUpdate:先启动新的Pod,再替换老的Pod

2.2.1应用部署完成

## 部署应用
kubectl apply -f deployment.yaml

## 暴露应用服务的端口
kubectl expose deployment web --port=80 --target-port=80 --type=NodePort

2.2.2更新镜像三种方式

• kubectl apply -f xxx.yaml

• kubectl set image deployment/web nginx=nginx:1.16

• kubectl edit deployment/web

 滚动升级:K8s对Pod升级的默认策略,通过使用新版本Pod逐步更新旧版本Pod,实现零停机发布,用户无感知。

查看三个pod 服务 对应的 IP和端口

[root@k8s-master1 ~]# kubectl get ep
NAME         ENDPOINTS                                            AGE
kubernetes   192.168.2.117:6443,192.168.2.119:6443                7d2h
pod-check    <none>                                               6h
web          10.244.159.134:80,10.244.224.10:80,10.244.36.74:80   32m

nginx:1.15 镜像升级到 nginx:1.16

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: web
        image: nginx:1.16

replicas 一个一个升级创建一个新的删除旧的,具体的策略可以,自行配置

导出 web deployment, 查看完整的 Deployment 配置

kubectl get deployment   web    -o yaml >  deploy.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  annotations:
    deployment.kubernetes.io/revision: "7"
    kubectl.kubernetes.io/last-applied-configuration: |
      {"apiVersion":"apps/v1","kind":"Deployment","metadata":{"annotations":{"kubernetes.io/change-cause":"web.v1-nginx-1.17"},"name":"web","namespace":"default"},"spec":{"replicas":3,"selector":{"matchLabels":{"app":"nginx"}},"template":{"metadata":{"labels":{"app":"nginx"}},"spec":{"containers":[{"image":"nginx:1.17","name":"web"}]}}}}
    kubernetes.io/change-cause: web.v1-nginx-1.17
  creationTimestamp: "2022-11-12T09:11:15Z"
  generation: 8
  managedFields:
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          .: {}
          f:kubectl.kubernetes.io/last-applied-configuration: {}
      f:spec:
        f:progressDeadlineSeconds: {}
        f:replicas: {}
        f:revisionHistoryLimit: {}
        f:selector:
          f:matchLabels:
            .: {}
            f:app: {}
        f:strategy:
          f:rollingUpdate:
            .: {}
            f:maxSurge: {}
            f:maxUnavailable: {}
          f:type: {}
        f:template:
          f:metadata:
            f:labels:
              .: {}
              f:app: {}
          f:spec:
            f:containers:
              k:{"name":"web"}:
                .: {}
                f:imagePullPolicy: {}
                f:name: {}
                f:resources: {}
                f:terminationMessagePath: {}
                f:terminationMessagePolicy: {}
            f:dnsPolicy: {}
            f:restartPolicy: {}
            f:schedulerName: {}
            f:securityContext: {}
            f:terminationGracePeriodSeconds: {}
    manager: kubectl-client-side-apply
    operation: Update
    time: "2022-11-12T10:33:02Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:kubernetes.io/change-cause: {}
      f:spec:
        f:template:
          f:spec:
            f:containers:
              k:{"name":"web"}:
                f:image: {}
    manager: kubectl
    operation: Update
    time: "2022-11-12T10:33:12Z"
  - apiVersion: apps/v1
    fieldsType: FieldsV1
    fieldsV1:
      f:metadata:
        f:annotations:
          f:deployment.kubernetes.io/revision: {}
      f:status:
        f:availableReplicas: {}
        f:conditions:
          .: {}
          k:{"type":"Available"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
          k:{"type":"Progressing"}:
            .: {}
            f:lastTransitionTime: {}
            f:lastUpdateTime: {}
            f:message: {}
            f:reason: {}
            f:status: {}
            f:type: {}
        f:observedGeneration: {}
        f:readyReplicas: {}
        f:replicas: {}
        f:updatedReplicas: {}
    manager: kube-controller-manager
    operation: Update
    time: "2022-11-12T10:33:21Z"
  name: web
  namespace: default
  resourceVersion: "1262530"
  selfLink: /apis/apps/v1/namespaces/default/deployments/web
  uid: 7b334d04-b47e-4023-bb3f-8043fd1474e2
spec:
  progressDeadlineSeconds: 600
  replicas: 3
  revisionHistoryLimit: 10
  selector:
    matchLabels:
      app: nginx
  strategy:
    rollingUpdate:
      maxSurge: 25%            ### 
      maxUnavailable: 25%      ###
    type: RollingUpdate        ###
  template:
    metadata:
      creationTimestamp: null
      labels:
        app: nginx
    spec:
      containers:
      - image: nginx:1.17
        imagePullPolicy: IfNotPresent
        name: web
        resources: {}
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
      dnsPolicy: ClusterFirst
      restartPolicy: Always
      schedulerName: default-scheduler
      securityContext: {}
      terminationGracePeriodSeconds: 30
status:
  availableReplicas: 3      ### 
  conditions:
  - lastTransitionTime: "2022-11-12T09:23:15Z"
    lastUpdateTime: "2022-11-12T09:23:15Z"
    message: Deployment has minimum availability.
    reason: MinimumReplicasAvailable
    status: "True"
    type: Available
  - lastTransitionTime: "2022-11-12T09:11:15Z"
    lastUpdateTime: "2022-11-12T10:33:21Z"
    message: ReplicaSet "web-76f5f6d7f5" has successfully progressed.
    reason: NewReplicaSetAvailable
    status: "True"
    type: Progressing
  observedGeneration: 8
  readyReplicas: 3
  replicas: 3
  updatedReplicas: 3
  • maxSurge: 表示升级过程中最多可以比原先设置多出的pod数量,如上maxSurge=1,replicas:3 就表示kubennetes会先启动一个新的pod,然后删除掉一个旧的pod,整个升级过程中最多会有3+1pod
  • maxUnavailable: 表示升级过程中最多有多少个pod处于无法提供服务的状态,当manSurge不为0时,该值也不能为0,maxUnavailable =1 表示kubernetes整个升级过程中最多会有一个pod处于无法服务的状态
  • minReadySeconds: 表示kubernetes在等待设置时间后才进行升级,如果没有设置该值kubernete会假设容器启动起来就提供服务了,如果没有设置该值,在某些极端情况下可能会造成服务不正常运行,默认值是0
  • type:RollingUpdate表示,设置更新策略为滚动更新,可以设置为recreate和RollingUpdate两个值,recreate表示全部重新创建,默认值就是RollingUpdate

当然,这时候应在Pod中加上health check检查应用的健康状态,而不是简单的依赖容器的running状态。配置相应的健康检查可以确保服务的可靠性和延续性。

2.3 Deployment 发布失败回滚

发布失败恢复正常版本

# 查看历史发布版本
kubectl rollout history deployment/web 
# 回滚上一个版本
kubectl rollout undo deployment/web	
# 回滚历史指定版本
kubectl rollout undo deployment/web --to-revision=2

ngnix 版本可自由改动 ,尝试 升级和回滚

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web
  namespace: default
  annotations:       # 记录回滚参数
    kubernetes.io/change-cause: "web.v1-nginx-1.17"   #记录到revision中的内容,记录版本号
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: web
        image: nginx:1.17

 注:回滚是重新部署某一次部署时的状态,即当时版本所有配置

查看正在运行的服务版本,镜像是 nginx: 1.17

回滚到上个版本,镜像是 nginx: 1.16

2.4Deployment 水平扩容

ReplicaSet控制器用途:

• Pod副本数量管理,不断对比当前Pod数量与期望Pod数量

• Deployment每次发布都会创建一个RS作为记录,用于实现回滚

# 查看RS记录
kubectl get rs	
# 版本对应RS记录
kubectl rollout history deployment web

# 命令直接修改副本个数,或者 修改yaml重新应用下
kubectl scale deployment web --replicas 5 deployment.apps/web scaled

##  也可以直接修改 ep 文件
kubectl edit  ep web -o yaml

新增两个 pod


三、DaemonSet控制器


DaemonSet保证在每个Node上都运行一个Pod,如果新增一个Node,这个Pod也会运行在新增的Node上,如果删除这个DadmonSet,就会清除它所创建的Pod。常用来部署一些集群日志收集,监控等全局应用。

DaemonSet也是支持更新和回滚的,具体操作和Deployment类似。

常见的场景如下:

1、运行存储集群daemon,比如ceph,glusterd等;

2、运行一个日志收集daemon,比如logstash,fluentd等;

3、运行监控daemon,比如Prometheus Node Exporter,collectd,New Relic agent,Ganglia gmond等;

 部署一个日志采集程序,因为使用 kubeadm 安装 所以 master 节点打了污点,下面filebeat 配置污点容忍,使其在 master 节点 也可以调度成功。

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: filebeat
  template:
    metadata:
      labels:
        name: filebeat
    spec:
      tolerations:
      - effect: NoSchedule
        operator: Exists
      containers:
      - name: log
        image: elastic/filebeat:7.3.2

 三个 节点成功部署 filebeat


四、Job控制器


4.1Job一次性执行

计算圆周率

apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl # 自定义的一次性需要运行的镜像
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

4.2定时任务(CronJob)

应用场景:离线数据处理,视频解码等业务

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello kangll
          restartPolicy: OnFailure

 需要注意的是,由于cron的特殊性,有时候会存在由于上一个定时任务还没有执行完成,新的定时任务又开始了的情况,我们可以通过定义spec.concurrencyPolicy字段来定义规则,比如:

  • concurrencyPolicy=Allow:表示这些Job可以同时存在
  • concurrencyPolicy=Firbid:表示不会创建新的Job,也就是这个定时任务被跳过
  • concurrencyPolicy=Replace:表示产生的新Job会替代旧的Job

五、总结


上面介绍的是日常工作中常用的控制器,其中Deployment和DaemonSet的使用频率最高,熟练掌握这些控制器,并且学会在什么时候选择什么样的控制器,合理使用使工作效率最高。

猜你喜欢

转载自blog.csdn.net/qq_35995514/article/details/128062173