kubernetes 官方文档整理,k8s入门教程笔记整理---7、工作负载

9 工作负载

k8s提供了几个内置的API来声明式管理工作负载及其组件,最终你的应用以容器的形式在Pods中运行,工作负载帮你接管Pod的管理,你可以使用k8s API管理工作负载对象,这些对象所表达的是比Pod更高级别的抽象概念,k8s控制平面根据你定义的工作负载对象规约自动管理Pod对象。
用于管理工作负载的内置API包括:

  • Deployment(间接包括ReplicaSet),管理无状态应用工作负载,任何pod都是可互换的,在需要时进行替换。Deployment替代Replication Controller API。
  • StatefulSet,允许创建具有不同身份标识的Pod,Pod不是可换的,管理有状态应用工作负载,最常见的是能简历Pod和持久化存储之间的关联,也就是说假如pod挂了仍然会连接到原来的存储卷上。
  • DaemonSet,在特定节点或每个节点运行的负载,例如某种驱动、日志组件、node-exporter等。
  • Job、CronJob,定义一次性任务和定时任务。

9.1 Deployments

kubectl rollout status -n=cloudbases-system deployment cb-dashboard可以查看滚动升级时的状态
Deployment为Pod和ReplicaSet提供声明式的更新能力,你负责描述deployemnt的目标状态,deployment控制器更改实际状态,使其变为期望状态。你可以定义deployment以创建新的ReplicaSet。
Deployment 典型用例

  1. 创建deployment将ReplicaSet上线。ReplicaSet后台创建Pod
  2. 更新Deployment的PodTemplateSpec。新的ReplicaSet将被创建,将Pod从旧的ReplicaSet逐步迁移到新ReplicaSet。每次偶会更新Deployment的修订版本
  3. 如果Deployment当前状态不稳定。可以回滚到较早的Deployment,但是每次回滚也会更新Deployment的修订版本
  4. 扩大Deployment副本数以创建更多负载
  5. 暂停Deployment的上线,修改后恢复
  6. 使用Deployment状态判断上线状态
  7. 清理旧的不用的ReplicaSet

9.1.1 创建deployment将ReplicaSet上线。ReplicaSet后台创建Pod

#deployment-nginx示例
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment #deploy的名称
  labels:
    app: nginx
spec:
  replicas: 3 #启动三个Pod副本
  selector: #selector字段定义了replicaSet如何查找要管理的pod
    matchLabels: 
      #matchLabels字段是kv键值对映射的,
      #等效于matchExpressions中的一个元素key为key、operator为In、values为value。
      #需要注意需要满足matchLabels或matchExpressions的所有条件才算匹配成功
      app: nginx
  template:
    metadata:
      labels:
        app: nginx #打了个app: nginx标签,这里也是为了和selector中的matchLabels对应
    spec:
      containers:
        - name: nginx #容器名称 
          image: nginx:1.14.2 #镜像名称:tag版本
          ports:
            - containerPort: 80
  • 查看deploy状态 kubectl get deploy nginx-deployment -o wide
  • 分析deploy状态 kubectl describe deploy nginx-deployment
  • 查看deploy创建出的pod kubectl get pods。 pod的标签里也有pod-template-hash标签,与replicaset中的标签值一样
  • 查看deploy创建出的rs kubectl get rs。需要注意rs的名称为 [deploymen名称]-[哈希] 哈希值和rs的pod-template-hash标签一致,并且此标签是由deployment的PodTemplate通过哈希处理而来

9.1.2 更新Deployment的PodTemplateSpec。新的ReplicaSet将被创建,将Pod从旧的ReplicaSet逐步迁移到新ReplicaSet。每次偶会更新Deployment的修订版本

例如修改 deploy的镜像kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
kubectl get rs 会看到多出来一个副本。
在更新时deployment确保一定数量的pod处于运行状态,默认75%,也就是最大不可用比例为25%
deployment还确保更新时数量只比期望pod高一部分,默认125%,也就是最大多出副本量的25%
当deployment被修改时,会创建一个新的replicaSet,旧的replicaSet将被缩容,新的replicaSet将被扩容

9.1.3 如果Deployment当前状态不稳定。可以回滚到较早的Deployment,但是每次回滚也会更新Deployment的修订版本

默认情况下,deploy所有上线记录都被保留在系统中,以便随时回滚,可以修改修订历史记录限制。
deployment被触发上线时,并且spec.template被修改时系统创建deployment新的修订版本,而仅修改副本数这样的操作不会重建rs

回滚步骤:

  1. 检查历史版本 kubectl rollout history deployment/nginx-deployment
    包含有 REVISION CHANGE-CAUSE,例如2 kubectl set image deployment/nginx-deployment nginx=nginx:1.16.1
    其中CHANGE-CAUSE是从deployment 的kubernetes.io/change-cause注解复制过来的
  2. 查看某个历史版本详细信息 kubectl rollout history deployment/nginx-deployment --revision=2
  3. 执行回滚到上一个版本 kubectl rollout undo deployment/nginx-deployment
    或者执行--to-version可以回滚到特定修订版本kubectl rollout undo deployment/nginx-deployment --to-revision=2

9.1.4 扩大Deployment副本数以创建更多负载

  • 缩放deployment, kubectl scale deployment/nginx-deployment --replicas=8将副本数设为8
  • 水平自动缩放,如果集群启用了Pod的水平自动缩放,可以设置自动缩放器HPA,kubectl autoscale deployment/nginx-deployment --min=5 --max=15 --cpu-percent=80在cpu超过80%时进行缩放,最小5最大15

9.1.5 暂停Deployment的上线,修改后恢复

当你更新deploy时,想做很多操作,而不想每次操作都会导致重启,就可以先暂停deploy新版本的上线,等全部修改完成后再恢复上线,在暂停期间,对deploy做修改都不会导致pod重启或修改

  1. 暂停kubectl rollout pause deployment/nginx-deployment
  2. 一系列修改deploy…
  3. 恢复kubectl rollout resume deployment/nginx-deployment

9.1.6 使用Deployment状态判断上线状态

deploy创建的rs可能处于Progressing(进行中)、Complete(已完成)、Failed(失败),以至于无法继续进行

  • Progressing进行中的Deployment:deploy正在创建新的rs、deploy;deploy为新的rs扩容;deploy为旧的rs缩容;pod就绪或可用
  • Complete完成的Deployment:deploy所有副本已更新;所有副本都可用;旧副本未运行
  • Failed失败的Deployment:一直处于未完成的状态。出现的原因可能有:配额不足、就绪探针失败、镜像拉取错误、权限不足、限制范围、应用运行时错误
    可以配置超时时间,在这期间来检查错误原因kubectl patch deployment/nginx-deployment -p '{"spec":{"progressDeadlineSeconds":600}}'
    一般使用describelogget -o yaml 中的status 排错

9.1.7 清理旧的不用的ReplicaSet

deployment的.spec.revisionHistoryLimit字段指定保留多少个replicaSet,多余版本的ReplicaSet会被垃圾回收
。默认值为10。如果将此值设为0,代表没有历史记录,也就是不能使用回滚的功能

9.1.8 金丝雀部署

创建两个deploy 按一定比例设置副本数,标签有公共的有能区分的,然后让service绑定到pod的公共标签,就可以实现按比例分配流量

9.1.9 编写deployment规约

首先需要.apiVersion .kind .metadata还需要.spec,.spec中必须填写.spec.template和.spec.selector

  • .spec.template是一个Pod模板,
  • .spce.selector中指定deploy的Pod标签选择算符。匹配的是.spec.template.metadata.labels。在apps/v1版本selector是不可变的
  • .spec.replicas 可选,可指定副本数,默认1
  • .spec.strategy 新pod替换旧pod的策略。type可以是Recreate(先杀pod,再建pod)、RollingUpdate(默认,滚动更新) .spec.strategy.rollingUpdate.maxUnavailable 不可用pod上限(比例或个数) .spec.strategy.rollingUpdate.maxSurge 可超出的数量或百分比。
  • .spec.progresDeadlineSeconds 进度期限秒数,默认600毫秒,代表控制器再600毫秒内持续重试
  • .spec.minReadySeconds 可选字段,用于指定新创建的pod再没任何容器崩溃情况下的最小就绪时间,也就是说超过这个时间Pod才被视为可用 默认0(也就是就绪后Pod就可用)
  • .spec.revisionHistoryLimit 可选字段,默认10,设定保留旧版本ReplicaSet的数量
  • .spec.paused 用于暂停和恢复deployment
    需要注意,如果多个控制器选择算符发生重叠,会导致控制器冲突,无法正常工作,所以不建议手动创建ReplicaSet或Pod。

9.2 ReplicaSet

9.2.1 replicaSet定义

维护一组Pod副本稳定集合,用来保证pod数量、pod相同和可用性。包括选择算符、副本数、pod模板。 pod的metadata.ownerReferences连接了replicaSet
.spec.template。是一个pod模板,当需要删除Pod时,按如下顺序剔除。首先剔除悬决(Pending)、其次按照删除开销注解(controller.kubernetes.io/pod-deletion-cost)先删数值小的,优先删除所处节点上副本个数较多的Pod、创建时间较近的
.spec.selector。标签选择算符.spec.template.metadata.labels需要和此匹配,否则配置将被API拒绝。当然直接修改pod的标签可以让pod摆脱replicaset的控制
.spec.replicas。pod副本数,
删除replicaset,垃圾收集器自动删除所有依赖的pod。如果只想删除replicaset而不删除pod那么可以使用 kubectl delete --cascade=orphan

9.2.2 pod删除开销

pod删除开销controller.kubernetes.io/pod-deletion-cost注解。数值小的先被删除,不设置默认为0,
可以通过为kube-apiserver和kube-controller-manager设置特性门控PodDeletionCost禁用此功能

9.2.3 replicaset作为hpa目标

如下例

apiVersion: autoscaling/v1
kind: HorizontalPodAutoscaler
metadata:
  name: frontend-scaler
spec:
  scaleTargetRef:
    kind: ReplicaSet
    name: frontend
  minReplicas: 3
  maxReplicas: 10
  targetCPUUtilizationPercentage: 50

9.2.4 ReplicaSet 的替代方案

使用Deployment可以自动管理replicaSet。
裸Pod
Job
DaemonSet
ReplicationController

9.3 StatefulSet

statefulset用来管理有状态应用的工作负载API对象,用来管理Pod集合的部署和扩缩,并为这些Pod提供持久存储和持久标识符
与deployment相似,statefulset管理基于相同容器规约的一组Pod,特殊的statefulset给每个Pod都提供了一个Id,比如-0 -1 -2。
在希望使用存储卷提供持久存储时,可以用statefulset,当pod故障重启时,仍然会挂载到原来的存储卷上。

优点

  • 稳定、唯一的网络标识符。例如test-nginx-0、test-nginx-1
  • 稳定、持久的存储。
  • 有序、优雅的部署和扩缩
  • 有序、自动的滚动更新

限制

  • 存储必须由PersistentVolume Provisioner基于storageclass制备,或者管理员预先制备好
  • 扩缩statefulSet不会删除与他关联的存储卷。保证了数据安全
  • statefulSet需要无头服务来负责Pod的网络标识。所以你需要创建此服务
  • 当删除StatefulSet时,不提供任何终止Pod的保证,也就是说没有体面终止的功能。
  • 在默认Pod管理策略(OrderedReady)时使用滚动更新,需要人工干预

配置

  • .spec.selctor pod选择算符,匹配.spec.template.metadata.labels
  • .spec.volumeClaimTemplates,卷申领模板,使用pv制备程序提供的pv提供稳定的存储
  • .spec.minReadySeconds,最短就绪秒数,指定pod最短经历多长时间后才被视为可用,默认为0
  • pod标识
    • pod的名称固定,包括顺序标识、网络标识、存储。例如test-nginx-0、test-nginx-1。
    • .spec.ordinals.start可以设置起始序号
    • 稳定的网络ID, $(StatefulSet 名称)-$(序号)、$(服务名称).$(名字空间).svc.cluster.local
      • 例如 在myns下有mynginx 的 statefulset,并且有同名的服务mynginx 。里边有mynginx-0、mynginx-1
      • statefulset的域名 mynginx.myns.svc.cluster.local
      • pod的域名 mynginx-0.myns.svc.cluster.local
    • 稳定的存储,定义了VolumeClaimTemplate,每个Pod都会基于sc制备一个pv,当Pod被调度或重新调度时,自动挂载pvc相关的pv,需要注意statefulset删除时,pv不会删除。需要手动删除
    • pod名称标签,创建pod时会给添加上一个标签statefulset.kubernetes.io/pod-name,用这个标签可以给特定Pod绑一个svc
  • .spec.replicas 副本数,当部署和扩缩时是依次创建顺序为0,1,2…N-1,扩缩时前面的Pod都要是Running或Ready。删除时是逆序终止,Pod终止之前继任者必须完全关闭
  • .spec.updateStrategy.type,配置和禁用掉自动滚动更新Pod的容器、标签、资源请求、限制、注解。取值为
    • OnDelete:控制器不会更新pod,用户需要手动删除Pod来让控制器重建pod
    • RollingUpdate:默认,执行自动滚动更新,自动删除或重建Pod。
      • .spec.updateStrategy.rollingUpdate.partition。可以实现分区,就是当更新statefulset时,只有大于该分区序号的pod会被更新
      • .spec.updateStrategy.rollingUpdate.maxUnavailable。配置最大不可用Pod的数量,可以为数量或百分比
  • .spec.persistentVolumeClaimRetentionPolicy,配置pvc保留,也就是删除pod时是否删除pvc。需要启用StatefulSetAutoDeletePVC特性门控。
    • whenDeleted。删除statefulset时保留卷,需要注意只有删除statefulset资源时才有效。就是如果单纯的删Pod的操作并不会删除卷。
    • whenScaled。当配置statefulset副本缩容时卷是否保留,Retain(默认)保留、Delete删除,需要注意这个配置只有对缩容操作有用。
#statefulset示例
apiVersion: v1
kind: Service
metadata:
  name: nginx # headless service来控制网络域名
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx # 必须匹配 .spec.template.metadata.labels
  serviceName: "nginx"
  replicas: 3 # 默认值是 1,运行三个副本 
  minReadySeconds: 10 # 默认值是 0
  template:
    metadata:
      labels:
        app: nginx # 必须匹配 .spec.selector.matchLabels
    spec:
      terminationGracePeriodSeconds: 10
      containers:
      - name: nginx
        image: registry.k8s.io/nginx-slim:0.8
        ports:
        - containerPort: 80
          name: web
        volumeMounts:
        - name: www
          mountPath: /usr/share/nginx/html
  volumeClaimTemplates: #存储卷声明模板,提供稳定存储
  - metadata:
      name: www
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "my-storage-class"
      resources:
        requests:
          storage: 1Gi

9.4 DaemonSet

确保每个(或者某些)节点上运行一个Pod,当然,当一个节点加入集群时,也会新增一个Pod,删除节点时也会收回一个Pod
典型用法:运行集群守护进程、运行日志收集守护进程、运行监控守护进程

  • 必需字段 apiVersion、kind、metadata、spec
  • .spec.template。pod模板。需要指定合理的标签,RestartPolicy必须为Always(默认)
  • .spec.selector表示pod选择算符,匹配.spec.template.metadata.labels匹配,并且是不可修改的。matchLabels、matchExpression,如果两种方式都定义了按"与"处理
  • .spec.template.spec.nodeSelector。选择节点,匹配的节点上创建 Pod
  • .spec.template.spec.affinity。如果指定了亲和性,则将在亲和性匹配的节点上创建pod。默认没指定将在所有节点创建
  • .spec.template.spec.schedulerName,可以为pod设置不同的调度程序

关于DaemonSet自动添加的污点和容忍度

DaemonSet控制器将自动添加一组容忍度到DaemonSet的Pod,当然你也可以自己加容忍度到DaemonSet的Pod。

  • node.kubernetes.io/not-ready。NoExecute。DemonSet的pod可以被调度不健康或还不准备接受pod的节点上且不被驱逐
  • node.kubernetes.io/unreachable。NoExecute。DaemonSet的Pod可以被调度到节点控制器不可达的节点上且不被驱逐
  • node.kubernetes.io/disk-pressure。NoSchedule。DaemonSet Pod 可以被调度到具有磁盘压力问题的节点上。
  • node.kubernetes.io/memory-pressure。NoSchedule。DaemonSet Pod 可以被调度到具有内存压力问题的节点上。
  • node.kubernetes.io/pid-pressure。NoSchedule。DaemonSet Pod 可以被调度到具有进程压力问题的节点上。
  • node.kubernetes.io/unschedulable。NoSchedule。DaemonSet Pod 可以被调度到不可调度的节点上。例如需要一个集群联网的网络插件Pod运行,只有网络插件运行了节点才能被标记为就绪,所以这时候使用daemonset能把网络插件放在节点上。
  • node.kubernetes.io/network-unavailable。NoSchedule。仅针对请求主机联网的 DaemonSet Pod 添加此容忍度,即 Pod 具有 spec.hostNetwork: true。这些 DaemonSet Pod 可以被调度到网络不可用的节点上。

和daemonSet的pod通信的几种模式

  • 推送(push):配置DaemonSet的pod,将信息发送到另一个服务,这种方式不需要客户端。例如统计数据库
  • NodeIP和已知端口:DaemonSet的Por可以使用hostPort。可以通过节点IP访问到Pod。
  • DNS:创建无头服务,使用endpoints资源或从DNS发现DaemonsSet
  • Service:创建DaemonSet Pod的服务,让服务随机访问到某个节点的pod
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: fluentd-elasticsearch
  namespace: kube-system
  labels:
    k8s-app: fluentd-logging
spec:
  selector:
    matchLabels:
      name: fluentd-elasticsearch
  template:
    metadata:
      labels:
        name: fluentd-elasticsearch
    spec:
      nodeAffinity:
        requiredDuringSchedulingIgnoredDuringExecution:
          nodeSelectorTerms:
           - matchFields:
             - key: metadata.name
               operator: In
               values:
                 - target-host-name
      tolerations:
      # 这些容忍度设置是为了让该守护进程集在控制平面节点上运行
      # 如果你不希望自己的控制平面节点运行 Pod,可以删除它们
      - key: node-role.kubernetes.io/control-plane
        operator: Exists
        effect: NoSchedule
      - key: node-role.kubernetes.io/master
        operator: Exists
        effect: NoSchedule
      containers:
      - name: fluentd-elasticsearch
        image: quay.io/fluentd_elasticsearch/fluentd:v2.5.2
        resources:
          limits:
            memory: 200Mi
          requests:
            cpu: 100m
            memory: 200Mi
        volumeMounts:
        - name: varlog
          mountPath: /var/log
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log

9.5 Job

会创建一个或多个Pod,并将执行Pod,直到指定数量的Pod成功终止,删除Job的操作会删除所有创建的Pod,挂起Pod会删除Job所有活跃的Pod

  • 基本信息,需要apiVersion、kind、metadata、spec
  • Job标签。为job-name和controller-uid加上batch.kubernetes.io/ 前缀
  • .spec.template。需要设置合适的标签、重启策略(Never、Onfailure)
  • .spec.selector。选择算符

Job并行执行

Job运行的任务主要有三种

  1. 非并行job,通常只启动一个pod,pod成功终止时,job为完成状态。
  2. 具有确定完成数的并行job。.spec.completions。当成功的pod数到达设定时才被视为完成。
  3. 带工作队列的并行job。不设置spec.completions。需要设置.spec.parallelism为非负整数。至少一个pod完成,那么job就完成
apiVersion: batch/v1
kind: Job
metadata:
  name: pi
spec:
  template:
    spec:
      containers:
      - name: pi
        image: perl:5.34.0
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never
  backoffLimit: 4

已完成 Job 的自动清理

当job结束时,TTL-after-finished控制器提供了一种TTL机制来限制已完成执行job对象的生命期。
通过.spec.ttlSecondsAfterFinished来清理已经结束的job(Complete或Failed),当TTL过期时,Job被级联删除

9.6 CronJob

定时job,可用于备份、生成报告等操作,类似于linux 的crontab。用cron格式编写,周期性创建job

  • .spec.schedule字段是必须的。*(分钟) *(小时) *(某天) *(月份) *(周的某天) 。 */2 代表每隔2个单位执行一次
  • .spec.jobTemplate 创建job模板
  • .spec.startingDeadlineSeconds 由于某种原因错过时间后,容忍多长时间内创建job。
  • .spec.concurrencyPolicy 声明cronjob创建的任务执行时发生重叠如何处理。Allow(默认),允许并发执行、Forbid不允许并发任务,优先执行老任务、Replace不允许并发,优先执行新任务
  • .spec.suspend 挂起,挂起cronjob,但是不会影响已开始的任务
  • .spec.successfulJobsHistoryLimit(默认3)和 .spec.failedJobsHistoryLimit(默认1) 。代表应保留多少已完成和失败的任务
  • .spec.timeZone 可以设置一个有效时区名称,例如"Etc/UTC"。
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "* * * * *" #每分钟打印一次
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

9.7 ReplicationControlle

已淘汰

  • 17
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

琰玥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值