DaemonSet
基础
DaemonSet 确保符合规则的 k8s node 上都存在一份 pod。常用来构建节点常驻性的app. 例如监控节点的app, 或者采集节点日志的app,以及网络app等。
特点
-
调度在所有符合条件的node上。
-
当DaemonSet创建或删除, 则指定节点上的 pod 都会创建或删除。
-
当一个符合DaemonSet规则的节点添加到集群或从集群中删除, 则 pod 会自动被添加/删除。
-
当DaemonSet被删除, 则指定节点上的 pod 都会被删除.
-
pod模板中的 RestartPolicy 必须是默认值, 也就是 Always.
-
创建后.spec.selector 不可修改.
例子
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上。
与调度选择有关的知识,分三类:
- 节点污点和Pod容忍度
- 节点标签选择器
- 节点亲和性
节点污点和容忍度
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。