DaemonSet的使用案例介绍
一:daemonset 错误记录
Q1:no matches for kind "DaemonSet" in version "extensions/v1beta1"
DaemonSet、Deployment、StatefulSet 和 ReplicaSet 在 v1.16 中将不再从 extensions/v1beta1、apps/v1beta1 或 apps/v1beta2 提供服务
解决方法是:
将yaml配置文件内的api接口修改为 apps/v1 ,导致原因为之间使用的kubernetes 版本是1.14.x版本,1.16.x 版本放弃部分API支持
Q2:[ValidationError(DaemonSet.spec.template.metadata): unknown field "containers" in io.k8s.apimachinery.pkg.apis.meta.v1.ObjectMeta, ValidationError(DaemonSet.spec): missing required field "selector" in io.k8s.api.apps.v1.DaemonSetSpec]; if you choose to ignore these errors, turn validation off with --validate=false
selector 配置不当
二:DaemonSet场景1
在有种场景下,我们需要在所有的kubernetes节点上都运行同一个应用的一个副本,比如在后续我们会说如何收集kubernetes中的pod日志,在收集日志的时候,需要在每个k8s node节点上运行一个收集日志的进程 ,如fluentd。我们知道在通常情况下,kubernetes基于它内部的调度算法来自动分配pod运行在哪个节点上,没有办法保证在每个node上运行一个fluentd pod。这个时候,daemonsets的调度方式就派上了用场。简单来说,daemonsets就是让一个应用在所有的k8s集群节点上都运行一个副本
我们直接看下面的示例,在所有节点上都启动一个busybox:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: busybox
spec:
template:
metadata:
labels:
app: busybox
spec:
containers:
- name: busybox
image: myhub.mingyuanyun.com/library/busybox
command:
- sleep
- "3600"
我们通过kubectl get daemonset可以看到启动了6个busybox的pod,因为我们有6个kubernetes节点。而事实上,我们并没有指定复制的个数,这就是daemonsets的作用:
NAME DESIRED CURRENT READY NODE-SELECTOR AGE
busybox 6 6 6 1m
三:DaemonSet场景2
fluentd-elasticsearch 日志采集场景
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:
- key: node-role.kubernetes.io/master
effect: NoSchedule
containers:
- name: fluentd-elasticsearch
image: k8s.gcr.io/fluentd-elasticsearch:1.20
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
四:DaemonSet场景3
DaemonSet 确保全部(或者一些)Node 上运行一个 Pod 的副本。当有 Node 加入集群时,也会为他们新增一个 Pod 。当有 Node 从集群移除时,这些 Pod 也会被回收。删除 DaemonSet 将会删除它创建的所有 Pod。
使用 DaemonSet 的一些典型用法:
- 运行集群存储 daemon,例如在每个 Node 上运行 glusterd、ceph。
- 在每个 Node 上运行日志收集 daemon,例如fluentd、logstash。
- 在每个 Node 上运行监控 daemon,例如 Prometheus Node Exporter、collectd、Datadog 代理、New Relic 代理,或 Ganglia gmond
一个简单的用法是,在所有的 Node 上都存在一个 DaemonSet,将被作为每种类型的 daemon 使用。 一个稍微复杂的用法可能是,对单独的每种类型的 daemon 使用多个 DaemonSet,但具有不同的标志,和/或对不同硬件类型具有不同的内存、CPU要求。
kubernetes 自己也在使用DaemonSet 管理自己的组件
$ kubectl get ds -n kube-system
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE-SELECTOR AGE
calico-node 4 4 4 4 4 34d
案例
#启动一个redis配置一下filebeat
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: log-store
template:
metadata:
labels:
app: redis
role: log-store
spec:
containers:
- name: redis-pod
image: redis:4.0-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
app: filebeat
release: all
template:
metadata:
labels:
app: filebeat
release: all
spec:
containers:
- name: filebeat-ds-pod
image: ikubernetes/filebeat:5.6.6-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
- name: REDIS_LOG_LEVEL
value: info
暴露redis端口 供filebeat访问
$ kubectl expose deployment redis --port=6379
查看一下服务
$ kubectl get ds
NAME DESIRED CURRENT READY UP-TO-DATE AVAILABLE NODE-SELECTOR AGE
filebeat-ds 4 4 4 4 4 12m
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
filebeat-ds-8tf5v 1/1 Running 0 13m 10.42.2.78 k8s-node01
filebeat-ds-9fqfv 1/1 Running 0 13m 10.42.0.220 rancher-node
filebeat-ds-pdc8m 1/1 Running 0 13m 10.42.1.108 k8s-master
filebeat-ds-v4dct 1/1 Running 0 13m 10.42.3.214 k8s-node02
滚动更新
kubectl explain ds.spec.updateStrategy
默认是 rollingUpdate 是删除式更新
rollingUpdate 只支持 maxUnavailable ,因为ds是每个主机上启动一个pod,所以不能有多余节点的启动
$ kubectl set image ds filebeat-ds filebeat-ds-pod=ikubernetes/filebeat:5.6.7-alpine
daemonset "filebeat-ds" image updated
五:DaemonSet场景4
以 Prometheus Node Exporter 为例演示如何运行自己的 DaemonSet
Prometheus 是流行的系统监控方案,Node Exporter 是 Prometheus 的 agent,以 Daemon 的形式运行在每个被监控节点上
如果是直接在 Docker 中运行 Node Exporter 容器,命令为:
docker run -d \
-v "/proc:/host/proc" \
-v "/sys:/host/sys" \
-v "/:/rootfs" \
--net=host \
prom/node-exporter \
--path.procfs /host/proc \
--path.sysfs /host/sys \
--collector.filesystem.ignored-mount-points "^/(sys|proc|dev|host|etc)($|/)"
将其转换为 DaemonSet 的 YAML 配置文件 node_exporter.yml:
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
name: node-exporter-daemonset
spec:
template:
metadata:
labels:
app: prometheus
spec:
hostNetwork: true
containers:
- name: node-exporter
image: prom/node-exporter
imagePullPolicy: IfNotPresent
command:
- /bin/node_exporter
- --path.procfs
- /host/proc
- --path.sysfs
- /host/sys
- --collector.filesystem.ignored-mount-points
- ^/(sys|proc|dev|host|etc)($|/)
volumeMounts:
- name: proc
mountPath: /host/proc
- name: sys
mountPath: /host/sys
- name: root
mountPath: /rootfs
volumes:
- name: proc
hostPath:
path: /proc
- name: sys
hostPath:
path: /sys
- name: root
hostPath:
path: /
① 直接使用 Host 的网络。
② 设置容器启动命令。
③ 通过 Volume 将 Host 路径 /proc、/sys 和 / 映射到容器中。
执行 kubectl apply -f node_exporter.yml
DaemonSet node-exporter-daemonset 部署成功,k8s-node1 和 k8s-node2 上分别运行了一个 node exporter Pod