k8s工作负载型控制器

k8s工作负载型控制器


工作负载是在kubernetes上运行的应用程序。
无论你的负载是单一组件还是由多个一同工作的组件构成,在Kubernetes中你可以在一组Pods中运行它。在Kuberneres中,pod代表的是集群上处于运行状态的一组容器。

Kubernetes Pods有确定的生命周期。例如,当某Pod在你的集群中运行时,Pod运行所在的节点出现致命错误时,所有该节点上的Pods都会失败。Kubernetes将这类失败视为最终状态:即使该节点后来恢复正常运行,你也需要创建新的Pod来恢复应用。

不过,为了让用户的日子略微好过一点,你并不需要直接管理每个Pod。相反,你可以使用负载资源来替你管理一组Pods。这些资源配置控制器来确保合适类型的、处于运行状态的Pod个数是正确的,与你所指定的状态相一致。

常用的工作负载控制器:

  • Deployment
  • StatefulSet
  • DaemonSet
  • Job
  • CronJob

Deployment

一个Deployment为Pods和ReplicaSets提供声明式的更新能力。

你负责描述Deployment中的目标状态,而Deployment控制器以受控速率更改实际状态,使其变为期望状态。你可以定义Deployment以创建新的ReplicaSet,或删除现有Deployment,并通过新的Deployment收养其资源。

Deployment很适合用来管理你的集群上的无状态应用,Deployment中的所有pod都是相互等价的,并且在需要的时候被换掉。

创建Deployment

[root@master mainfest]# vim deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: deploy
  labels:
    app: nginx
spec: 
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template: 
    metadata: 
      labels:
        app: nginx
    spec: 
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        
[root@master mainfest]# kubectl apply -f deploy.yaml 
deployment.apps/deploy created
[root@master mainfest]# kubectl get pod
NAME                     READY   STATUS    RESTARTS   AGE
deploy-585449566-7thb5   1/1     Running   0          57s
deploy-585449566-fn97j   1/1     Running   0          57s
deploy-585449566-sj9dd   1/1     Running   0          57s        

在该例中:

  • 创建了名为deploy(由.metadata.name字段标明)的deployment
  • 该deployment创建三个(由replicas字段标明)pod副本
  • selector 字段定义 Deployment 如何查找要管理的 Pods。 在这里,你选择在 Pod 模板中定义的标签(app: nginx)。 不过,更复杂的选择规则是也可能的,只要 Pod 模板本身满足所给规则即可。
  • template字段包含以下子字段:
    • Pod 被使用 labels 字段打上 app: nginx 标签。
    • Pod 模板规约(即 .template.spec 字段)指示 Pods 运行一个 nginx 容器, 该容器运行版本为 1.14.2 的 nginx Docker Hub镜像。
    • 创建一个容器并使用 name 字段将其命名为 nginx

ReplicaSet

ReplicaSet的目的是维护一组在任何时候都处于运行状态的Pod副本的稳定集合。因此,它通常用来保证给定数量的、完全相同的Pod的可用性。

ReplicaSet的工作原理

RepicaSet是通过一组字段来定义的,包括一个识别可获得的Pod的集合的选择算符、一个用来标明应该维护的副本个数的数值、一个用来指定应该创建新Pod以满足副本个数条件时要使用的Pod模板等等。每个ReplicaSet都通过根据需要创建新的Pod时,会使用所提供的Pod模板。

ReplicaSet通过Pod上的metadata.ownerReferences字段连接到附属Pod,该字段给出当前对象的属主资源。ReplicaSet所获得的Pod都在其ownerReferences字段中包含了属主ReplicaSet的标识信息。正是通过这一连接,ReplicaSet 知道它所维护的 Pod 集合的状态, 并据此计划其操作行为。

ReplicaSet 使用其选择算符来辨识要获得的 Pod 集合。如果某个 Pod 没有 OwnerReference 或者其 OwnerReference 不是一个控制器,且其匹配到 某 ReplicaSet 的选择算符,则该 Pod 立即被此 ReplicaSet 获得。

何时使用ReplicaSet

ReplicaSet 确保任何时间都有指定数量的 Pod 副本在运行。 然而,Deployment 是一个更高级的概念,它管理 ReplicaSet,并向 Pod 提供声明式的更新以及许多其他有用的功能。 因此,我们建议使用 Deployment 而不是直接使用 ReplicaSet,除非 你需要自定义更新业务流程或根本不需要更新。

这实际上意味着,你可能永远不需要操作 ReplicaSet 对象:而是使用 Deployment,并在 spec 部分定义你的应用。

[root@master mainfest]# vim replicaset.yaml
apiVersion: apps/v1
kind: ReplicaSet
metadata:
  name: replicaset
  labels:
    app: httpd
    tier: frontend
spec:
  replicas: 3
  selector:
    matchLabels:
      tier: frontend
  template:
    metadata:
      labels:
        tier: frontend
    spec:
      containers:
      - name: httpd
        image: httpd:latest

查看当前被部署的ReplicaSet

[root@master mainfest]# kubectl apply -f replicaset.yaml 
replicaset.apps/replicaset created
[root@master mainfest]# kubectl get rs
NAME               DESIRED   CURRENT   READY   AGE
deploy-585449566   3         3         3       94m
replicaset         3         3         2       49s
[root@master mainfest]# kubectl get pod
NAME                     READY   STATUS              RESTARTS   AGE
deploy-585449566-7thb5   1/1     Running             0          94m
deploy-585449566-fn97j   1/1     Running             0          94m
deploy-585449566-sj9dd   1/1     Running             0          94m
replicaset-2brwk         1/1     Running             0          51s
replicaset-46ksz         0/1     Running             0          51s
replicaset-f295r         1/1     Running             0          51s

DaemonSet

DaemonSet 确保全部(或者某些)节点上运行一个 Pod 的副本。 当有节点加入集群时, 也会为他们新增一个 Pod 。 当有节点从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。

DaemonSet 的一些典型用法:

  • 在每个节点上运行集群守护进程
  • 在每个节点上运行日志收集守护进程
  • 在每个节点上运行监控守护进程

一种简单的用法是为每种类型的守护进程在所有的节点上都启动一个 DaemonSet。 一个稍微复杂的用法是为同一种守护进程部署多个 DaemonSet;每个具有不同的标志, 并且对不同硬件类型具有不同的内存、CPU 要求。

创建DaemonSet

你可以在YAML文件中描述DaemonSet。例如下面这个daemonset.yaml文件描述了一个运行

[root@master mainfest]# vim daemonset.yaml
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:
      tolerations:
      # this toleration is to have the daemonset runnable on master nodes
      # remove it if your masters can't run pods
      - 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
        - name: varlibdockercontainers
          mountPath: /var/lib/docker/containers
          readOnly: true
      terminationGracePeriodSeconds: 30
      volumes:
      - name: varlog
        hostPath:
          path: /var/log
      - name: varlibdockercontainers
        hostPath:
          path: /var/lib/docker/containers

创建查看

[root@master mainfest]# kubectl apply -f statefulset.yaml 
service/nginx created
statefulset.apps/web created
[root@master mainfest]# kubectl get pod -n kube-system
fluentd-elasticsearch-497v4      1/1     Running   0          23s
fluentd-elasticsearch-j9749      1/1     Running   0          23s

Daemon Pods是如何被调度的

通过默认调度器调度

FEATURE STATE: Kubernetes v1.23 [stable]

DaemonSet 确保所有符合条件的节点都运行该 Pod 的一个副本。 通常,运行 Pod 的节点由 Kubernetes 调度器选择。 不过,DaemonSet Pods 由 DaemonSet 控制器创建和调度。这就带来了以下问题:

  • Pod 行为的不一致性:正常 Pod 在被创建后等待调度时处于 Pending 状态, DaemonSet Pods 创建后不会处于 Pending 状态下。这使用户感到困惑。
  • Pod 抢占由默认调度器处理。启用抢占后,DaemonSet 控制器将在不考虑 Pod 优先级和抢占 的情况下制定调度决策。

ScheduleDaemonSetPods 允许您使用默认调度器而不是 DaemonSet 控制器来调度 DaemonSets, 方法是将 NodeAffinity 条件而不是 .spec.nodeName 条件添加到 DaemonSet Pods。 默认调度器接下来将 Pod 绑定到目标主机。 如果 DaemonSet Pod 的节点亲和性配置已存在,则被替换 (原始的节点亲和性配置在选择目标主机之前被考虑)。 DaemonSet 控制器仅在创建或修改 DaemonSet Pod 时执行这些操作, 并且不会更改 DaemonSet 的 spec.template

nodeAffinity:
  requiredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchFields:
      - key: metadata.name
        operator: In
        values:
        - target-host-name

此外,系统会自动添加 node.kubernetes.io/unschedulable:NoSchedule 容忍度到 DaemonSet Pods。在调度 DaemonSet Pod 时,默认调度器会忽略 unschedulable 节点。

Jobs

Job 会创建一个或者多个 Pods,并将继续重试 Pods 的执行,直到指定数量的 Pods 成功终止。 随着 Pods 成功结束,Job 跟踪记录成功完成的 Pods 个数。 当数量达到指定的成功个数阈值时,任务(即 Job)结束。 删除 Job 的操作会清除所创建的全部 Pods。 挂起 Job 的操作会删除 Job 的所有活跃 Pod,直到 Job 被再次恢复执行。

一种简单的使用场景下,你会创建一个 Job 对象以便以一种可靠的方式运行某 Pod 直到完成。 当第一个 Pod 失败或者被删除(比如因为节点硬件失效或者重启)时,Job 对象会启动一个新的 Pod。

你也可以使用 Job 以并行的方式运行多个 Pod。

[root@master mainfest]# vim jobs.yaml
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
  backoffLimit: 4

运行查看

[root@master mainfest]# kubectl apply -f jobs.yaml 
job.batch/pi created

[root@master mainfest]# kubectl describe jobs/pi
Name:           pi
Namespace:      default
Selector:       controller-uid=81b575ed-11bd-4a9a-927c-f8016fd35529
Labels:         controller-uid=81b575ed-11bd-4a9a-927c-f8016fd35529
                job-name=pi
Annotations:    <none>
Parallelism:    1
Completions:    1
Start Time:     Fri, 24 Dec 2021 07:26:08 -0500
Pods Statuses:  1 Running / 0 Succeeded / 0 Failed
Pod Template:
  Labels:  controller-uid=81b575ed-11bd-4a9a-927c-f8016fd35529
           job-name=pi
  Containers:
   pi:
    Image:      perl
    Port:       <none>
    Host Port:  <none>
    Command:
      perl
      -Mbignum=bpi
      -wle
      print bpi(2000)
    Environment:  <none>
    Mounts:       <none>
  Volumes:        <none>
Events:
  Type    Reason            Age   From            Message
  ----    ------            ----  ----            -------
  Normal  SuccessfulCreate  39s   job-controller  Created pod: pi-rm6dx

CronJob

FEATURE STATE: Kubernetes v1.21 [stable]

CronJob 创建基于时隔重复调度的Jobs。

一个 CronJob 对象就像 crontab (cron table) 文件中的一行。 它用Cron格式进行编写, 并周期性地在给定的调度时间执行 Job。

注意:

所有 CronJobschedule: 时间都是基于kube-controller-manager. 的时区。

如果你的控制平面在 Pod 或是裸容器中运行了 kube-controller-manager, 那么为该容器所设置的时区将会决定 Cron Job 的控制器所使用的时区。

为 CronJob 资源创建清单时,请确保所提供的名称是一个合法的DNS 子域名. 名称不能超过 52 个字符。 这是因为 CronJob 控制器将自动在提供的 Job 名称后附加 11 个字符,并且存在一个限制, 即 Job 名称的最大长度不能超过 63 个字符。

CronJob 用于执行周期性的动作,例如备份、报告生成等。 这些任务中的每一个都应该配置为周期性重复的(例如:每天/每周/每月一次); 你可以定义任务开始执行的时间间隔。

下面的 CronJob 示例清单会在每分钟打印出当前时间和问候消息:

[root@master mainfest]# vim cronjob.yaml
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

运行查看

[root@master mainfest]# kubectl apply -f cronjob.yaml 
cronjob.batch/hello created

[root@master mainfest]# kubectl get pods
NAME                     READY   STATUS      RESTARTS   AGE
hello-1640349240-swt92   0/1     Completed           0          3m
hello-1640349300-mcmxs   0/1     Completed           0          2m
hello-1640349360-6gqv4   0/1     Completed           0          60s
[root@master mainfest]# kubectl logs hello-1640349360-6gqv4
Fri Dec 24 12:36:05 UTC 2021
Hello from the Kubernetes cluster
<think> 嗯,用户想了解Kubernetes工作负载的相关信息,包括定义、类和作用。这个问题很基础但也很重要,是理解Kubernetes应用管理的核心概念。 用户可能刚接触Kubernetes,需要清晰的框架性知识。从引用内容看,ta在站内已经浏览过一些相关资料,但需要更系统的整理。特别是引用[3]提到的工作负载本质是资源对象这个点值得强调。 我注意到几个关键信息点:引用[1]强调工作负载是部署管理应用的关键;引用[2]提到第三方工作负载扩展;引用[3]明确定义了工作负载是资源对象;引用[4]则补充了Pod的基础单元特性。这些正好构成回答的骨架。 用户可能存在的潜在疑问:工作负载和普通Pod有什么区别?为什么要抽象出工作负载这个概念?在回答时需要解释工作负载本质是对Pod的抽象管理。 在组织回答时,考虑采用分层结构:先讲清楚定义(资源对象+管理容器组),再分述核心类,最后用表格对比可能更直观。作用部分要强调声明式管理和自愈能力这两个Kubernetes的核心优势。 关于第三方工作负载部分,虽然用户没直接问,但引用[2]特别提到CRD扩展,应该简要说明,这能体现Kubernetes生态的可扩展性优势。 最后生成的问题要覆盖进阶内容:性能优化(HPA)、特殊场景(有状态应用)、安全管控(如Pod安全策略),这样能引导用户深入探索。 </think>以下是关于Kubernetes工作负载的详细解析,结合核心概念与实战作用: --- ### **一、工作负载的定义** 工作负载(Workload)是Kubernetes中**管理容器化应用生命周期**的资源对象。它通过抽象底层Pod的部署、扩缩容和运维逻辑,确保应用在集群中按预期状态运行。核心特点包括: 1. **Pod管理**:工作负载创建并管控一组Pod副本(如Deployment管理无状态Pod,StatefulSet管理有状态Pod)。 2. **声明式配置**:用户定义期望状态(如副本数、镜像版本),由控制器自动调整实际状态。 3. **自愈能力**:自动替换故障Pod,保障应用可用性[^3][^4]。 --- ### **二、核心工作负载及作用** #### **1. Deployment** - **用途**:部署无状态应用(如Web服务) - **核心能力**: - 滚动更新/回滚(通过`kubectl rollout`) - 自动扩缩容(结合HPA) ```yaml apiVersion: apps/v1 kind: Deployment spec: replicas: 3 # 维持3个Pod副本 template: spec: containers: - name: nginx image: nginx:1.25 ``` #### **2. StatefulSet** - **用途**:管理有状态应用(如数据库、消息队列) - **关键特性**: - 稳定的网络标识(Pod名称+序号) - 持久化存储(通过PVC绑定PV) - 有序部署/伸缩(如MySQL主从初始化顺序)[^4] #### **3. DaemonSet** - **用途**:在**每个节点**运行守护进程(如日志收集器、网络插件) - **场景示例**: ```yaml kind: DaemonSet spec: template: spec: containers: - name: fluentd image: fluentd:latest ``` #### **4. Job/CronJob** - **Job**:执行一次性任务(如数据处理任务) - **CronJob**:定时任务(如每日备份) ```yaml apiVersion: batch/v1 kind: CronJob spec: schedule: "0 3 * * *" # 每天3点执行 jobTemplate: spec: template: spec: containers: - name: backup image: backup-tool ``` #### **5. 第三方工作负载(通过CRD扩展)** - **适用场景**:特殊调度需求(如TensorFlow作业的分组Pod管理)[^2] - **实现方式**:使用Operator框架定制资源(如SparkOperator、TFJob) --- ### **三、工作负载的核心价值** | 作用 | 说明 | |---------------------|----------------------------------------------------------------------| | **应用托管** | 自动化部署、更新、回滚,减少人工干预[^1] | | **弹性伸缩** | 根据流量动态调整Pod数量(HPA) | | **高可用保障** | 分布式部署+自愈机制,避免单点故障[^3] | | **资源优化** | 精细化调度(Requests/Limits),提升集群利用率 | | **生态扩展** | CRD支持集成Prometheus、Istio等生态工具[^2] | --- ### **四、实战场景示例** - **微服务架构**:Deployment管理API服务 + Service暴露流量 - **数据管道**:CronJob定时触发ETL任务 + ConfigMap配置参数 - **全局监控**:DaemonSet部署Node Exporter到所有节点 > 关键提示:生产环境建议**始终使用工作负载管理Pod**,而非直接创建裸Pod,以确保稳定性[^1][^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值