# 守护进程集（DaemonSet）
#### 守护进程集（DaemonSet）
DaemonSet（守护进程集）在集群的每个节点上运行一个Pod，且保证只有一个Pod，非常适合一些系统层面的应用，例如日志收集、资源监控等，这类应用需要每个节点都运行，且不需要太多实例，一个比较好的例子就是Kubernetes的kube-proxy。
DaemonSet与节点相关，如果节点异常，属于该节点的DaemonSet Pod也不会迁移到其他节点重新创建。
图1DaemonSet   
![](https://support.huaweicloud.com/basics-cce/zh-cn_image_0258871213.png "点击放大")
#### 创建DaemonSet
下面是一个DaemonSet的示例。
```
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: nginx-daemonset
  labels:
    app: nginx-daemonset
spec:
  selector:
    matchLabels:
      app: nginx-daemonset
  template:
    metadata:
      labels:
        app: nginx-daemonset
    spec:
      nodeSelector:                 # 节点选择，当节点拥有daemon=need时才在节点上创建Pod
        daemon: need
      containers:
      - name: nginx-daemonset
        image: nginx:alpine
        resources:
          limits:
            cpu: 250m
            memory: 512Mi
          requests:
            cpu: 250m
            memory: 512Mi
      imagePullSecrets:
      - name: default-secret
```
这里可以看出DaemonSet没有Deployment或StatefulSet中的replicas参数，因为DaemonSet会在每个目标节点上固定部署一个Pod。
Pod模板中有个nodeSelector，指定了只在有"daemon=need"的节点上才创建Pod，如下图所示，DaemonSet只在指定标签的节点上创建Pod。如果需要在每一个节点上创建Pod可以删除该标签。
图2DaemonSet在指定标签的节点上创建Pod   
![](https://support.huaweicloud.com/basics-cce/zh-cn_image_0258871204.png "点击放大")
创建DaemonSet：
```
$ kubectl create -f daemonset.yaml
daemonset.apps/nginx-daemonset created
```
查询发现nginx-daemonset没有Pod创建。
```
$ kubectl get ds
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   0         0         0       0            0           daemon=need     16s
​
$ kubectl get pods
No resources found in default namespace.
```
这是因为节点上没有daemon=need这个标签，使用如下命令可以查询节点的标签。
```
$ kubectl get node --show-labels
NAME            STATUS   ROLES    AGE   VERSION                            LABELS
192.168.0.212   Ready    <none>   83m   v1.15.6-r1-20.3.0.2.B001-15.30.2   beta.kubernetes.io/arch=amd64 ...
192.168.0.94    Ready    <none>   83m   v1.15.6-r1-20.3.0.2.B001-15.30.2   beta.kubernetes.io/arch=amd64 ...
192.168.0.97    Ready    <none>   83m   v1.15.6-r1-20.3.0.2.B001-15.30.2   beta.kubernetes.io/arch=amd64 ...
```
给192.168.0.212这个节点打上标签，然后再查询，发现已经创建了一个Pod，并且这个Pod是在192.168.0.212这个节点上。
```
$ kubectl label node 192.168.0.212 daemon=need
node/192.168.0.212 labeled
$ kubectl get ds
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   1         1         0       1            0           daemon=need     116s
$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP           NODE            
nginx-daemonset-g9b7j   1/1     Running   0          18s   172.16.3.0   192.168.0.212
```
再给192.168.0.94这个节点打上标签，发现又创建了一个Pod：
```
$ kubectl label node 192.168.0.94 daemon=need
node/192.168.0.94 labeled
$ kubectl get ds
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   2         2         1       2            1           daemon=need     2m29s
$ kubectl get pod -o wide
NAME                    READY   STATUS              RESTARTS   AGE   IP           NODE            
nginx-daemonset-6jjxz   0/1     ContainerCreating   0          8s    <none>       192.168.0.94    
nginx-daemonset-g9b7j   1/1     Running             0          42s   172.16.3.0   192.168.0.212
```
如果修改掉192.168.0.94节点的标签，可以发现DaemonSet会删除这个节点上的Pod。
```
$ kubectl label node 192.168.0.94 daemon=no --overwrite
node/192.168.0.94 labeled
$ kubectl get ds
NAME              DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
nginx-daemonset   1         1         1       1            1           daemon=need     4m5s
$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE     IP           NODE            
nginx-daemonset-g9b7j   1/1     Running   0          2m23s   172.16.3.0   192.168.0.212
```
