StatefulSet de controlador de uso común de kubernetes

StatefulSet de controlador de uso común de kubernetes

1. Introducción

La relación desigual entre las instancias y las aplicaciones en las que las instancias tienen dependencias de datos externos se denominan "aplicaciones con estado".
La denominada relación desigual entre instancias significa que para las aplicaciones distribuidas, a menudo hay dependencias relativamente grandes entre cada instancia y cada aplicación. Por ejemplo, una aplicación debe iniciarse antes que otras aplicaciones, de lo contrario no se iniciarán otras aplicaciones.
La aplicación más importante que tiene una dependencia de datos externos es la aplicación de base de datos. Para las aplicaciones de base de datos, necesitamos almacenar sus datos de manera persistente. Si es una aplicación sin estado, reiniciar los datos en la base de datos y la aplicación perderá contacto, que es obviamente una violación Nuestra intención original no era ponerlo en producción.

Por lo tanto, para resolver el soporte efectivo de aplicaciones con estado en Kubernetes, Kubernetes usa StatefulSet para organizar y administrar aplicaciones con estado.
StatefulSet es similar a ReplicaSet. La diferencia es que puede controlar la secuencia de inicio de los pods y establece un identificador único para cada pod. Tiene las siguientes funciones:

  • Identificador de red único y estable

  • Almacenamiento estable y persistente

  • Despliegue y escalado ordenados y elegantes

  • Actualización continua ordenada y automática

El diseño de StatefulSet es fácil de entender y abstrae el mundo real en las dos situaciones siguientes:
(1) Estado topológico. Esto significa que existe una relación asimétrica entre las aplicaciones. Las aplicaciones deben iniciarse en un orden determinado. Incluso si la aplicación se reinicia, debe reiniciarse en el orden especificado y su identificación de red debe ser la misma que la original después del reinicio. para que se pueda garantizar el acceso original El usuario puede acceder al nuevo Pod a través del mismo método;
(2), estado de almacenamiento. Esto significa que la aplicación está vinculada a los datos almacenados, sin importar cuándo, sin importar la situación, para la aplicación, siempre que los datos en el almacenamiento no cambien, los datos leídos deben ser los mismos;

Entonces, la función principal de StatefulSet es registrar el estado del Pod de cierta manera y luego restaurar su estado de alguna manera cuando se vuelve a crear el Pod.

二 、 Servicio sin cabeza

Antes de presentar StatefulSet, primero comprendamos qué es Headless Service.
Sabemos que en Kubernetes, el servicio es una forma de proporcionar acceso externo a un grupo de pods. Por lo general, usamos el Servicio para acceder al Pod de las siguientes dos formas:
(1) A través de la IP del clúster, esta IP del clúster es equivalente a VIP. Cuando visitamos esta IP, la solicitud se reenviará al Pod de fondo;
(2) A través de DNS , de esta manera, primero debe asegurarse de que haya un servicio DNS en el clúster de Kubernetes. En este momento, siempre que accedamos a "my-service.my-namespace.svc, cluster.local", podemos acceder al Pod de backend enviado por proxy por el Servicio llamado my-service;

Para el segundo método, existen los siguientes dos métodos de procesamiento:
(1) Servicio normal, es decir, resolver el nombre de dominio y obtener la IP del clúster, y luego acceder de acuerdo con el método uno;
(2), Servicio sin cabeza, es decir , resuelve el nombre de dominio para obtener la dirección IP de un Pod en el backend, de modo que se pueda acceder a él directamente;

Para el segundo método de procesamiento, podemos ver que no hay necesidad de IP de clúster, pero la dirección IP del Pod de backend se resuelve directamente a través del nombre de dominio para el acceso.
La siguiente es una definición de archivo YAML simple de Headless Service:

apiVersion: v1

kind: Service

metadata:

  name: nginx

  labels:

    app: nginx

spec:

  ports:

  - port: 80

    name: web

  clusterIP: None

  selector:

    app: nginx

Se puede ver en el archivo YAML anterior que no hay mucha diferencia con nuestra definición de servicio normal. La única diferencia es que la IP del clúster está configurada en Ninguno, es decir, no se necesita ningún clúster. Creamos este Servicio a través de kubectl apply -f y luego verifique que la IP del clúster del servicio sea Ninguna.
StatefulSet de controlador de uso común de kubernetes

El Servicio creado de esta manera es un Servicio sin cabeza, no tiene un VIP, por lo que expondrá el Pod que envió como proxy en forma de registros DNS.

Tres, use StatefulSet

Cree el PV antes de crear StatefulSet, de la siguiente manera:

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv01

  labels:

    release: stable

spec:

  capacity:

    storage: 1Gi

  accessModes:

  - ReadWriteOnce

  persistentVolumeReclaimPolicy: Recycle

  hostPath:

    path: /tmp/data

---

apiVersion: v1

kind: PersistentVolume

metadata:

  name: pv02

  labels:

    release: stable

spec:

  capacity:

    storage: 1Gi

  accessModes:

  - ReadWriteOnce

  persistentVolumeReclaimPolicy: Recycle

  hostPath:

    path: /tmp/data

Luego ejecute kubectl apply -f para iniciar PV, de la siguiente manera:

[root@master statefulset]# kubectl apply -f pv.yaml

persistentvolume/pv01 created

persistentvolume/pv02 created

[root@master statefulset]# kubectl get pv

NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE

pv01   1Gi        RWO            Recycle          Available                                   10s

pv02   1Gi        RWO            Recycle          Available                                   9s

Puede ver que los estados de los dos PV están disponibles y luego escribir el archivo YAML del StatefulSet:

apiVersion: v1

kind: Service

metadata:

  name: nginx

spec:

  ports:

  - port: 80

    name: web

  clusterIP: None

  selector:

    app: nginx

    role: stateful

---

apiVersion: apps/v1

kind: StatefulSet

metadata:

  name: web

spec:

  serviceName: "nginx"

  replicas: 2

  selector:

    matchLabels:

      app: nginx

  template:

    metadata:

      labels:

        app: nginx

        role: stateful

    spec:

      containers:

      - name: nginx

        image: cnych/nginx-slim:0.8

        ports:

        - containerPort: 80

          name: web

        volumeMounts:

        - name: www

          mountPath: /usr/share/nginx/html

  volumeClaimTemplates:

  - metadata:

      name: www

    spec:

      accessModes: [ "ReadWriteOnce" ]

      resources:

        requests:

          storage: 1Gi

Tenga en cuenta que el archivo YAML anterior asociado con volumeMounts es un nuevo atributo: volumeClaimTemplates, este atributo declarará automáticamente un objeto pvc y un pv para la administración, y serviceName: "nginx" significa que el headless de nginx se usa cuando se ejecuta el bucle de control. Servicio para guardar la identidad resoluble del Pod.

Entonces aquí abrimos dos ventanas de terminal. En la primera terminal, use kubectl get para ver la creación de los Pods del StatefulSet.

$ kubectl get pods -w -l role=stateful

En otra terminal, use kubectl create para crear el Headless Service y StatefulSet definidos en statefulset-demo.yaml.

$ kubectl create -f statefulset-demo.yaml

service "nginx" created

statefulset.apps "web" created

Luego observamos la secuencia de inicio del Pod:

[root@master ~]# kubectl get pods -w -l role=stateful

web-0   0/1   Pending   0     0s

web-0   0/1   Pending   0     0s

web-0   0/1   ContainerCreating   0     0s

web-0   1/1   Running             0     3m12s

web-1   0/1   Pending             0     0s

web-1   0/1   Pending             0     0s

web-1   0/1   Pending             0     1s

web-1   0/1   ContainerCreating   0     1s

web-1   1/1   Running             0     5s

A través del proceso de creación anterior, podemos ver que StatefulSet numera los Pods que administra. Su regla de nomenclatura es [statefulset-name] - [index], y su índice comienza en 0, que es el mismo que cada instancia de Pod de StatefulSet. Uno correspondencia, nunca repetir. Más importante aún, el proceso de creación de pod es secuencial. Como se indicó anteriormente, web-1 entra en estado pendiente después de que web-0 entra en estado de ejecución.

Usamos el comando para ver los resultados de su creación:

[root@master statefulset]# kubectl get statefulset web

NAME   READY   AGE

web    2/2     17m

[root@master statefulset]# kubectl get pods -l role=stateful

NAME    READY   STATUS    RESTARTS   AGE

web-0   1/1     Running   0          17m

web-1   1/1     Running   0          14m

[root@master statefulset]# kubectl get svc nginx

NAME    TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE

nginx   ClusterIP   None         <none>        80/TCP    17m

Cuando ambos pods ingresan al estado de ejecución, puede ver sus respectivas identidades de red. Podemos verlos a través de kubectl exec, de la siguiente manera:

[root@master statefulset]# kubectl exec web-0 -- sh -c 'hostname'

web-0

[root@master statefulset]# kubectl exec web-1 -- sh -c 'hostname'

web-1

Puede ver que el nombre de host y el nombre de pod de los dos pods son iguales, y a todos se les asignan los números correspondientes. A continuación, usamos DNS para acceder al Servicio Headless.
Primero iniciamos un Pod con el siguiente comando:

kubectl run -i --tty --image busybox dns-test --restart=Never --rm /bin/sh

Luego, use nslookup para analizar el servicio sin cabeza correspondiente a un pod en este pod:

kubectl run -i --tty --image centos dns-test --restart=Never --rm /bin/sh

sh-4.2# yum install bind-utils -y

sh-4.2# nslookup web-0.nginx

Server:        10.68.0.2

Address:    10.68.0.2#53

Name:    web-0.nginx.default.svc.cluster.local

Address: 172.20.2.63

sh-4.2# nslookup web-1.nginx

Server:        10.68.0.2

Address:    10.68.0.2#53

Name:    web-1.nginx.default.svc.cluster.local

Address: 172.20.2.64

A partir del análisis de los resultados de nslookup, al acceder a web-0.nginx, se analiza la IP del Pod web-0, y la otra es la misma.
En este momento, si eliminamos los dos Pods, observe el proceso de reinicio del Pod:

[root@master statefulset]# kubectl delete pod -l role=stateful

pod "web-0" deleted

pod "web-1" deleted

Luego verifique la secuencia de reinicio de la siguiente manera:

[root@master ~]# kubectl get pods -w -l role=stateful

NAME    READY   STATUS    RESTARTS   AGE

web-0   0/1     ContainerCreating   0          0s

web-0   1/1     Running             0          2s

web-1   0/1     Pending             0          0s

web-1   0/1     Pending             0          0s

web-1   0/1     ContainerCreating   0          0s

web-1   1/1     Running             0          2s

Podemos ver que después de eliminar el Pod, su secuencia de reinicio aún se reinicia de acuerdo con el número original y su identificación de red sigue siendo la misma que antes.
A través de esta estricta regla de correspondencia, StatefulSet garantiza la estabilidad de la identidad de red del Pod. A través de este método, el estado topológico del Pod se puede arreglar de acuerdo con el nombre + número del Pod. Además, Kubernetes también proporciona una entrada de acceso fija y única para cada Pod, es decir, el registro DNS del Pod.

También podemos comprobar la unión de PV y PVC:

[root@master statefulset]# kubectl get pv

NAME   CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM               STORAGECLASS   REASON   AGE

pv01   1Gi        RWO            Recycle          Bound    default/www-web-0                           129m

pv02   1Gi        RWO            Recycle          Bound    default/www-web-1                           129m

[root@master statefulset]# kubectl get pvc

NAME        STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE

www-web-0   Bound    pv01     1Gi        RWO                           124m

www-web-1   Bound    pv02     1Gi        RWO                           116m

Por lo tanto, clasificamos StatefulSet de la siguiente manera:
(1), StatefulSet administra directamente Pod. Esto se debe a que las instancias de pod en StatefulSet no son exactamente las mismas que las instancias de pod en ReplicaSet. Son ligeramente diferentes. Por ejemplo, el nombre y el nombre de host de cada pod son diferentes, y la forma en que StatefulSet distingue estas instancias es para agregar el Número de Pod;
(2), Kubernetes genera un registro con el mismo número en el servidor DNS para este Pod numerado a través del Servicio Headless. Siempre que StatefulSet pueda garantizar que el número de este Pod se mantenga sin cambios, el registro DNS similar a web-0.nginx.default.svc.cluster.local en el Servicio no cambiará, y la dirección IP del Pod resuelta por este registro Se actualiza automáticamente con la recreación del Pod;
(3) StatefulSet también puede asignar y crear un PVC con el mismo número que el Pod para cada Pod. De esta manera, Kubernetes puede vincular el PV correspondiente a este PVC a través del mecanismo de volumen persistente, para garantizar que cada pod tenga un volumen independiente. En este caso, incluso si se elimina el Pod, su PVC y PV correspondientes se conservarán, por lo que cuando se vuelva a crear el Pod, Kubernetes encontrará el PVC con el mismo número y montará el volumen correspondiente al PVC. los datos anteriores del Volumen anterior;

Cuatro, resumen

Una de las funciones principales del controlador StatefulSet es numerarlos al crear pods con la plantilla de pod y completar las tareas en el orden de los números. Cuando el bucle de control del StatefulSet descubre que el estado real del pod no es coherente con el estado esperado, también operará el Pod en orden.

Por supuesto, StatefulSet también tiene otras características. En proyectos reales, rara vez volvemos e implementamos nuestros servicios con estado directamente a través de StatefulSet, a menos que usted pueda mantenerlo por completo. Para algunos servicios específicos, podemos usar más Operadores avanzados implementados, como como etcd-operator, prometheus-operator, etc. Estas aplicaciones pueden administrar muy bien los servicios con estado, en lugar de usar un StatefulSet para implementar un Pod, porque para las aplicaciones con estado, lo más importante es la recuperación de datos, la conmutación por error, etc.

Finalizar

Supongo que te gusta

Origin blog.51cto.com/15080014/2654577
Recomendado
Clasificación