Directorio de artículos
1. Conocimiento teórico StatefulSet
Documento oficial de referencia chino
1. Funciones del controlador StatefulSet Pod
StatefulSet (abreviado como sts) también es un administrador de recursos de Pod en el clúster K8S. A diferencia del controlador de Pod de implementación, StatefulSet se usa para administrar programas sin estado. Las características son las siguientes:
- Identificador de red estable: los pods administrados tienen un identificador de red estable. Se puede acceder a través del identificador de red.
- Implementación y expansión ordenadas: StatefulSet implementará los Pods uno por uno en el orden especificado, y cada Pod tiene un número de serie único, que no cambiará a lo largo del ciclo de vida. Al expandirse, los Pods también se agregarán uno por uno en el orden especificado.
- Almacenamiento estable: cada pod utiliza un almacenamiento de volumen persistente independiente, como NFS.
- Servicios con estado: StatefulSet es adecuado para servicios con estado, como bases de datos, cachés, etc., que requieren identificadores de red estables y almacenamiento persistente.
En resumen, StatefulSet proporciona un método de expansión y despliegue de servicios confiable, ordenado y con estado, que es adecuado para servicios con estado que requieren identificadores de red estables y almacenamiento persistente.
2. ¿Qué son los servicios con estado y sin estado?
Los servicios sin estado se refieren a servicios que no requieren almacenamiento y estado persistentes, como servidores web, servidores API, etc. Estos servicios pueden ejecutarse en cualquier nodo porque no necesitan compartir datos entre diferentes nodos y no necesitan una recuperación rápida en caso de falla del nodo. Los servicios sin estado se pueden escalar horizontalmente para mejorar el rendimiento y la disponibilidad.
Los servicios con estado se refieren a servicios que requieren almacenamiento persistente y mantenimiento de estado, como bases de datos y cachés . Estos servicios deben mantener los datos sincronizados entre diferentes nodos y deben poder recuperarse rápidamente cuando falla un nodo.
3. La diferencia entre Deployment y StatefulSet
Deployment y StatefulSet son dos controladores de uso común en Kubernetes, cuyas principales diferencias son las siguientes:
-
Deployment es un controlador para administrar aplicaciones sin estado, mientras que StatefulSet es un controlador para administrar aplicaciones con estado.
-
La implementación puede crear múltiples copias de Pod. No existe una relación de secuencia entre estas copias de Pod, y se pueden programar y reemplazar a voluntad. Las copias de Pod creadas por StatefulSet tienen un orden fijo, y cada copia de Pod tiene un identificador único, lo que puede garantizar la persistencia y estabilidad de los datos de las aplicaciones con estado.
-
La implementación puede realizar actualizaciones continuas, es decir, mantener la disponibilidad de las aplicaciones durante el proceso de actualización. Sin embargo, el proceso de actualización de StatefulSet debe controlarse manualmente. Es necesario eliminar la copia anterior del Pod y luego crear una nueva copia del Pod. Por lo tanto, habrá una cierta cantidad de tiempo de inactividad durante el proceso de actualización.
-
La implementación puede usar la estrategia RollingUpdate para la actualización gradual, mientras que StatefulSet puede usar las estrategias OnDelete y RollingUpdate para la actualización.
En resumen, Deployment es adecuado para administrar aplicaciones sin estado, mientras que StatefulSet es adecuado para administrar aplicaciones con estado. Si la aplicación necesita garantizar la persistencia y estabilidad de los datos, se recomienda utilizar StatefulSet.
2. Caso: Demostración práctica de recursos StatefulSet
1. Crear un sitio WEB y verificar las características de StatefulSet
Paso 1: Cree sts-web-svc
un SVC llamado , que debe asociarse con un servicio al crear un recurso statefulset. El YAML es el siguiente:
cat sts-web-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: sts-web-svc
spec:
selector:
app: web-nginx
ports:
- port: 80
targetPort: 80
clusterIP: None # 设置无IP地址
Crear recurso de servicio:
kubectl apply -f sts-web-svc.yaml
Vea el recurso svc creado, como se muestra en la siguiente figura, puede ver que el svc creado no tiene asignada una dirección IP:
kubectl get svc sts-web-svc
Paso 2: Crear un recurso statefulset
cat sts-web.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: sts-web
namespace: default
spec:
serviceName: sts-web-svc # 关联SVC资源
replicas: 2 # 副本数
selector:
matchLabels: # 关联具有app=web-nginx标签的Pod
app: web-nginx
volumeClaimTemplates: # 卷申请模板
- metadata:
name: www # 卷申请模板名称
spec:
accessModes: ["ReadWriteOnce"] # 访问模式
storageClassName: nfs # 指定供应商,前提是需要存在此供应商
resources:
requests:
storage: 1Gi # 存储大小1G
template:
metadata:
labels:
app: web-nginx
spec:
containers:
- name: web-nginx
image: nginx:1.18.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: www # 指定卷申请模板名称
mountPath: /usr/share/nginx/html
startupProbe: # 启动探测
tcpSocket:
port: 80
Ejecutar YAML:
kubectl apply -f sts-web.yaml
Paso tres: prueba de características
1. Los pods tienen un número de serie único: como se muestra en la siguiente figura, los nombres de los pods están en orden
kubectl get pods -l app=web-nginx -o wide
Después de eliminar sts-web-0, el nombre del Pod creado automáticamente después del Pod no cambiará
kubectl delete pod sts-web-0
2. Almacenamiento de volumen persistente independiente de pod: ver PVC, generar automáticamente dos PVC, aislados entre sí
kubectl get pvc -l app=web-nginx
ls /data/nfs_pro|grep default-www-sts-web-*
3. Identificador de red estable: usamos busybox para ejecutar Pod y nslookup para analizar
kubectl run busybox --image docker.io/library/busybox:1.28 --rm -it busybox -- sh
2. Actualización continua de StatefulSet
Las actualizaciones continuas spec.updateStrategy
se definen mediante el campo.Actualmente, statefulset admite dos estrategias de actualización de la siguiente manera:
- RollingUpdate: actualización continua
- OnDelete: No se actualizará automáticamente, se actualizará después de eliminar manualmente el Pod
A continuación se muestra una actualización continua:
Paso 1: Crear y ejecutar recursos statefulset
cat web-svc.yaml
---
apiVersion: v1
kind: Service
metadata:
name: web
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
clusterIP: None
Cree statefulset, use nginx: 1.18 espejo
cat web.yaml
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: web
namespace: default
spec:
serviceName: web
replicas: 5
selector:
matchLabels:
app: web
updateStrategy:
rollingUpdate:
maxUnavailable: 0 # 最多不可用Pod,0表示2个Pod可用
partition: 2 # 只更新序号大于等于partition值的Pod
volumeClaimTemplates:
- metadata:
name: web
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: nfs
resources:
requests:
storage: 1Gi
template:
metadata:
labels:
app: web
spec:
containers:
- name: web
image: nginx:1.18.0 # 使用1.18.0版本镜像
imagePullPolicy: IfNotPresent
ports:
- containerPort: 80
name: web
volumeMounts:
- name: web
mountPath: /usr/share/nginx/html
Ejecutar el archivo YAML
kubectl apply -f web-svc.yaml
kubectl apply -f web.yaml
Paso 2: Actualizar usando nginx:latest
el espejo
Re-YAML un poco:
kubectl apply -f web.yaml
Verificación: Por nuestra culpa, partition: 2
no se actualizarán todos los Pods, solo los Pods con números de serie mayores a 2, incluidos 2
3. Resumen
- Los nombres de pod administrados por statefulset están ordenados y los nombres de los pods creados automáticamente no cambiarán después de que se elimine el pod especificado.
- El nombre del servidor debe especificarse cuando se crea el statefulset.Si el servidor no tiene una dirección IP, se realizará un análisis de DNS en el servidor para encontrar el nombre de dominio del Pod correspondiente.
- El statefulset tiene una plantilla de administración de volúmenes de volumeclaimtemplate, y todos los pods creados tienen volúmenes independientes y no se afectan entre sí.
- El Pod creado por statefulset tiene un nombre de dominio independiente. Cuando especificamos el acceso a los recursos del Pod, podemos usar el nombre de dominio para especificar, la IP cambiará, pero el nombre de dominio no (nombre de dominio: Pod name svc name.svc namespace .svc.cluster.local )