1. Introducción
DaemonSet garantiza ejecutar un Pod en cada Nodo. Si se agrega un Nodo nuevo, el Pod también se ejecutará en el Nodo recién agregado. Si se elimina el DaemonSet, el Pod creado por él se borrará. Se usa comúnmente para implementar algunas recopilaciones de registros de clúster, monitoreo y otras aplicaciones globales.
Los escenarios comunes son los siguientes:
1. Ejecutar un demonio de clúster de almacenamiento, como ceph, glusterd, etc .;
2. Ejecutar un demonio de recopilación de registros, como logstash, fluentd, etc .;
3. Ejecutar un demonio de supervisión, como Prometheus Exportador de nodo, recopilado, agente de New Relic, Ganglia gmond, etc .;
Dos, estrategia de programación
En circunstancias normales, el Pod creado por DaemonSet debe programarse para qué nodo está determinado por la política de programación de Kubernetes. Sin embargo, cuando se crea el Pod, qué nodo realmente se determina de antemano, ignorará la programación. Dispositivo. por lo tanto:
-
El controlador DaemonSet no se preocupa por el campo no programable de Nodo;
- Incluso si el programador no se inicia, el controlador DaemonSet puede crear un Pod;
Sin embargo, los siguientes métodos se pueden utilizar para hacer que el Pod se ejecute en el Nodo especificado:
-
nodeSelector: solo se envía al nodo que coincide con la etiqueta especificada;
-
nodeAffinity: selector de nodos con funciones más ricas, como soporte para operaciones de conjuntos;
- podAffinity: Programación en el Nodo donde se encuentra el Pod que cumple con las condiciones;
2.1 、 nodeSelector
Consiste en etiquetar los nodos que deben ejecutarse, por ejemplo, solo se ejecutan en nodos con discos duros ssd, luego podemos etiquetar estos nodos:
kubectl label nodes node-01 disktype=ssd
Luego defina nodeSelector como disktype = ssd en el campo de DaemonSet:
spec:
nodeSelector:
disktype: ssd
2.2 、 nodeAffinity
nodeAffinity actualmente admite dos tipos: requiredDuringSchedulingIgnoredDuringExecution y favoriteDuringSchedulingIgnoredDuringExecution, que representan las condiciones que deben cumplirse y las condiciones preferidas, respectivamente. Por ejemplo, el siguiente ejemplo representa la programación para el Nodo que contiene la etiqueta kubernetes.io/e2e-az-name y el valor es e2e-az1 o e2e-az2, y preferiblemente también tiene la etiqueta another-node-label-key = otro-nodo- Nodo de etiqueta-valor.
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
2,3 、 podAffinity
podAffinity selecciona el Nodo en función de la etiqueta del Pod y solo lo programa en el Nodo donde el Pod cumple las condiciones y es compatible con podAffinity y podAntiAffinity. Esta función es más complicada, tome el siguiente ejemplo como ejemplo:
-
Si una "Zona donde se encuentra el Nodo contiene al menos un Pod con etiqueta security = S1 y Pod en ejecución", entonces se puede programar para el Nodo
- No programado para "contener al menos un Pod en ejecución con seguridad = etiqueta S2"
apiVersion: v1
kind: Pod
metadata:
name: with-pod-affinity
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S1
topologyKey: failure-domain.beta.kubernetes.io/zone
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: security
operator: In
values:
- S2
topologyKey: kubernetes.io/hostname
containers:
- name: with-pod-affinity
image: gcr.io/google_containers/pause:2.0
Tres, actualiza
DaemonSet admite la actualización continua y su campo definido es updateStrategy, que se puede ver a través de kubectl explica ds.spec.updateStrategy.
[root@master ~]# kubectl explain ds.spec.updateStrategy
KIND: DaemonSet
VERSION: extensions/v1beta1
RESOURCE: updateStrategy <Object>
DESCRIPTION:
An update strategy to replace existing DaemonSet pods with new pods.
FIELDS:
rollingUpdate <Object>
Rolling update config params. Present only if type = "RollingUpdate".
type <string>
Type of daemon set update. Can be "RollingUpdate" or "OnDelete". Default is
OnDelete.
El campo rollingUpdate tiene solo un maxUnavailable y ningún maxSurge, porque DaemonSet solo permite que uno se ejecute en el nodo.
Hay dos estrategias de actualización para DaemonSet:
- RollingUpdate: actualización continua
- OnDelete: Actualización al eliminar Pod, la estrategia de actualización predeterminada;
Cuatro, ejemplo
Defina un DaemonSet que recopile registros, use filebeat para recopilar registros y recopile registros a través de filebeat y envíelos a redis:
# vim filebeat-ds.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: redis
namespace: default
spec:
replicas: 1
selector:
matchLabels:
app: redis
role: cachedb
template:
metadata:
labels:
app: redis
role: cachedb
spec:
containers:
- name: redis
image: redis:5.0.5-alpine
ports:
- name: redis
containerPort: 6379
---
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
type: ClusterIP
selector:
app: redis
role: cachedb
ports:
- port: 6379
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: filebeat-ds
namespace: default
spec:
selector:
matchLabels:
app: filebeat
role: logstorage
template:
metadata:
labels:
app: filebeat
role: logstorage
spec:
containers:
- name: filebeat
image: ikubernetes/filebeat:5.6.5-alpine
env:
- name: REDIS_HOST
value: redis.default.svc.cluster.local
Creamos este archivo YAML
# kubectl apply -f filebeat-ds.yaml
Luego verifique el estado de svc, pod
[root@master daemonset]# kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.68.0.1 <none> 443/TCP 4d6h
redis ClusterIP 10.68.213.73 <none> 6379/TCP 5s
[root@master daemonset]# kubectl get pods
NAME READY STATUS RESTARTS AGE
filebeat-ds-pgmzt 1/1 Running 0 2m50s
filebeat-ds-wx44z 1/1 Running 0 2m50s
filebeat-ds-zjv68 1/1 Running 0 2m50s
redis-85c7ccb675-ks4rc 1/1 Running 0 4m2s
Luego ingresamos al contenedor filebeat para obtener algunos datos de prueba:
# kubectl exec -it filebeat-ds-pgmzt -- /bin/bash
# cd /var/log/containers/
# echo "123" > a.log
Luego ingrese al contenedor de redis para ver los datos:
# kubectl exec -it redis-85c7ccb675-ks4rc -- /bin/sh
/data # redis-cli -h redis.default.svc.cluster.local -p 6379
redis.default.svc.cluster.local:6379> KEYS *
1) "filebeat"
redis.default.svc.cluster.local:6379>
De lo anterior, puede ver que Redis ha recibido la información transmitida por filebeat normalmente.
Finalizar