k8s☞12-1控制器DaemonSet和Job和CronJob

阅读量: zyh 2020-09-20 20:30:04
Categories: > Tags:

DaemonSet

基础

DaemonSet 确保符合规则的 k8s node 上都存在一份 pod。常用来构建节点常驻性的app. 例如监控节点的app, 或者采集节点日志的app,以及网络app等。

特点

例子

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:
      # 添加容忍标签,允许将 Pod 调度到附加了 NoSchedule 的 master 主机
      - key: node-role.kubernetes.io/master
        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

这是一个日志采集pod. 它将k8s集群节点的 /var/log 和 /var/lib/docker/containers 挂载到 pod 中. 这样, elasticsearch 就可以获取到k8s集群所有节点的信息了.

调度

默认情况下,DaemonSets的Pod会调度到每一个Node上。

与调度选择有关的知识,分三类:

节点污点和容忍度

DaemonSet会给Pod自动附加容忍度,从而可以让Pod一直在节点上运行。 (截至到v1.19)。以下是自动附加的容忍度:

node.kubernetes.io/not-ready
node.kubernetes.io/unreachable	
node.kubernetes.io/disk-pressure	
node.kubernetes.io/memory-pressure	
node.kubernetes.io/unschedulable	
node.kubernetes.io/network-unavailable	

上述情况基本保证了DaemonSet的pod不会因各种意外情况导致pod被驱逐.

https://kubernetes.io/docs/concepts/scheduling-eviction/taint-and-toleration/

k8s通过污点来剔除某些故障节点或构建一些专属节点,防止Pod调度到存在污点的节点上。

k8s通过容忍度来确保某些pod可以忽略污点,从而调度到存在污点的节点上。

在正常情况下. 没有任何容忍度的pod不会被调度到存在污点的node上. (当出现节点故障时候, 默认会附加一个容忍度, 容忍度失效300秒)

通过节点标签(nodeSelector)实现部分调度

通过下列命令获知节点标签:

kubectl describe node k8s01
Labels:             beta.kubernetes.io/arch=amd64
                    beta.kubernetes.io/os=linux
                    kubernetes.io/arch=amd64
                    kubernetes.io/hostname=k8s01
                    kubernetes.io/os=linux
                    node-role.kubernetes.io/control-plane=
                    node-role.kubernetes.io/master=
                    node.kubernetes.io/exclude-from-external-load-balancers=

.spec.template.spec.nodeSelector可以让你仅在匹配的node上创建pod.

例如: 仅调度到拥有ssd磁盘标签的节点

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

通过节点亲和性(nodeAffinity)实现部分调度

.spec.affinity.nodeAffinity , 它有以下类型: (每一个类型由两部分意思组成)

requiredDuringSchedulingIgnoredDuringExecution
表示pod必须部署到满足条件的节点上,如果没有满足条件的节点,就不停重试。其中IgnoreDuringExecution表示pod部署后运行期间,如果节点标签发生了变化,不再满足pod指定的条件,pod也会继续运行。

preferredDuringSchedulingIgnoredDuringExecution
表示优先部署到满足条件的节点上,如果没有满足条件的节点,就忽略这些条件,按照正常逻辑部署。其中IgnoreDuringExecution表示pod部署之后运行的时候,如果节点标签发生了变化,不再满足pod指定的条件,pod也会继续运行。

apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: gcr.io/google_containers/pause:2.0

这个配置的意思是pod【必须被调度】到拥有标签【kubernetes.io/e2e-az-name=e2e-az1或kubernetes.io/e2e-az-name=e2e-az2】 的节点。与此同时, 还将在上述条件的基础上, 优先调度到额外拥有标签为another-node-label-key=another-node-label-value的节点上。

访问

你可以通过构建一个 Headless Service 并通过 endpoint 来访问各个 pod.

Job

# job-para-demo.yaml
apiVersion: batch/v1
kind: Job
metadata:
  name: job-para-test
spec:
  activeDeadlineSeconds: 100  # Job 对象运行的最长时间。超过这个时间,所有 job 创建的 pod 都会被删除。且 job 状态变成 DeadlineExceeded。
  backoffLimit: 6 # 失败后的重试次数。 Job 控制器重新创建 Pod 的间隔是呈指数增加的,即下一次重新创建 Pod 的动作会分别发生在 10s、20s、40s… 后。
  parallelism: 2  # 并行运行的 pod 数
  completions: 8  # 本次 Job 需要执行8次
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: test-job
        image: busybox
        command: ["echo", "test paralle job!"]

CronJob

# cronjob-demo.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cronjob-demo
spec:
  schedule: "*/1 * * * *"
  successfulJobsHistoryLimit: 3  # 默认保留成功的历史job数量
  failedJobsHistoryLimit: 1      # 默认保留失败的历史job数量
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: hello
            image: busybox
            args:
            - "bin/sh"
            - "-c"
            - "for i in 9 8 7 6 5 4 3 2 1; do echo $i; done"
➜  ~ kubectl delete cronjob cronjob-demo
cronjob "cronjob-demo" deleted

👙需要注意的是这将会终止正在创建的 Job,但是运行中的 Job 将不会被终止,不会删除 Job 或 它们的 Pod。