Saltar al contingut

La forma de garantir la disponibilitat és mantenir un conjunt estable de rèpliques de Pods executant-se en tot moment

Replicació

Un clúster kubernetes es compon de diverses màquines virtuals o màquines físiques independents.

Assegura’t de canviar la configuració de cpus i memory en funció del nombre de nodes simulats que utilitzis!

Terminal window
$ minikube start --nodes 4 -p multi
...

Obtén la llista dels nodes:

Terminal window
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
multi Ready control-plane 5m27s v1.32.0
multi-m02 Ready <none> 4m58s v1.32.0
multi-m03 Ready <none> 4m29s v1.32.0
multi-m04 Ready <none> 4m v1.32.0

També pots comprovar l’estat dels teus nodes:

Terminal window
$ minikube status -p multi
multi
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured
multi-m02
type: Worker
host: Running
kubelet: Running
...

Un ReplicationSet és un recurs que garanteix que un grup de Pods sempre s’estan executant.

Un Pod pot desaparèixer per qualsevol raó, per exemple que el node on s’executa el Pod desapareix del clúster o que el Pod ha estat desallotjat del node.

Un ReplicaSet monitoritza constantment mitjançant un “label selector” una llista de Pods que s’estan executant, i s’assegura que el nombre de Pods en execució sigui igual al nombre desitjat mitjançant la creació o eliminació de Pods a partir d’una plantilla de Pod.

notificación recibida

faltan

ok

sobran

Comenzar

Encontrar Pods que hacen match en un 'label selector'

Esperar notificación de modificación de recursos

Comparar número de Pods encontrados con el número de pots deseados

Crear Pods adicionales a partir de la plantilla

Eliminar los Pods que sobran

Per tant, un ReplicaSet necessita tres elements fonamentals:

  • Un label selector, que determina quins Pods ha de controlar

  • Un replica count que especifica el nombre desitjat de Pods que haurien d’estar en execució

  • Un Pod template que s’utilitza quan es creen noves rèpliques del Pod.

En qualsevol moment pots modificar el nombre de rèpliques, però els canvis en el “label selector” i el “Pod template” no afecten els Pods que s’estan executant.

A continuació crea un fitxer nginx.yaml:

apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
ports:
- containerPort: 80

Crea el ReplicaSet:

Terminal window
$ kubectl apply -f nginx.yaml
replicaset.apps/nginx created

Pots veure que s’han creat tres Pods amb l’etiqueta nginx en tres nodes diferents:

Terminal window
$ kubectl get pods -o wide -L app
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES APP
nginx-78wzt 1/1 Running 0 11s 10.244.2.3 multi-m03 <none> <none> nginx
nginx-mxf4c 1/1 Running 0 11s 10.244.1.4 multi-m02 <none> <none> nginx
nginx-wdjsh 1/1 Running 0 11s 10.244.3.4 multi-m04 <none> <none> nginx

Kubernetes intenta desplegar els Pods en nodes diferents per “no tenir tots els ous al mateix cistell”.

Esborra un dels Pods:

Terminal window
$ kubectl delete pod nginx-78wzt
pod "nginx-78wzt" deleted

I verifica que el controlador de replicació crea un nou Pod:

Terminal window
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-lvw9l 1/1 Running 0 19s
nginx-mxf4c 1/1 Running 0 54s
nginx-wdjsh 1/1 Running 0 54s

Com hem dit al principi, un ReplicationSet és un recurs igual que un Pod.

Per tant, pots obtenir una llista de tots els ReplicaSet que s’han creat:

Terminal window
$ kubectl get rs
NAME DESIRED CURRENT READY AGE
nginx 3 3 3 96s

Així com una descripció d’un controlador de replicació determinat:

Terminal window
$ kubectl describe rs nginx
Name: nginx
Namespace: default
Selector: app=nginx
Labels: <none>
Annotations: <none>
Replicas: 3 current / 3 desired
Pods Status: 3 Running / 0 Waiting / 0 Succeeded / 0 Failed
Pod Template:
Labels: app=nginx
Containers: ...
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal SuccessfulCreate 2m9s replicaset-controller Created pod: nginx-wdjsh
Normal SuccessfulCreate 2m9s replicaset-controller Created pod: nginx-mxf4c
Normal SuccessfulCreate 2m9s replicaset-controller Created pod: nginx-78wzt
Normal SuccessfulCreate 94s replicaset-controller Created pod: nginx-lvw9l

La llista d’esdeveniments mostra les accions realitzades fins al moment pel controlador: ha creat 4 Pods.

Quan demanes a kubernetes que desplegui un Pod, el desplegament es farà en qualsevol node que estigui disponible.

El problema és que si aquest node “mor” …

Terminal window
$ minikube -p multi node stop multi-m02
Stopping node "multi-m02" ...
🛑 Apagando "multi-m02" mediante SSH...
🛑 Successfully stopped node multi-m02

El node ja no està Ready:

Terminal window
$ kubectl get nodes
NAME STATUS ROLES AGE VERSION
multi Ready control-plane 3d v1.32.0
multi-m02 NotReady <none> 3d v1.32.0
multi-m03 Ready <none> 3d v1.32.0
multi-m04 Ready <none> 3d v1.32.0

Important. El resultat no és immediat perquè el clúster primer s’ha d’assegurar que no és un problema temporal de connexió de pocs segons.

Si mires la llista de Pods, pots veure que el Pod nginx-lvw9l està Running al node multi-m02

Terminal window
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-lvw9l 1/1 Running 0 3m42s 10.244.2.4 multi-m03 <none> <none>
nginx-mxf4c 1/1 Running 0 4m17s 10.244.1.4 multi-m02 <none> <none>
nginx-wdjsh 1/1 Running 0 4m17s 10.244.3.4 multi-m04 <none> <none>

Tot i que pots verificar que el Pod ja no s’està executant:

Terminal window
$ kubectl exec nginx-lvw9l -- bash
error: Internal error occurred: error sending request: Post "https://192.168.49.3:10250/exec/default/nginx-gmkgq/nginx?command=bash&error=1&output=1": dial tcp 192.168.49.3:10250: connect: no route to host

El motiu és que Kubernetes espera una estona per assegurar-se que definitivament la falta de connexió amb el node no és per una fallada temporal a la xarxa o perquè Kubelet s’està reiniciant.

Però després d’aquest temps, Kubernetes notifica un canvi de recursos i el controlador de recursos nginx crea un nou Pod:

Terminal window
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
nginx-lvw9l 1/1 Running 0 9m36s 10.244.2.4 multi-m03 <none> <none>
nginx-mxf4c 1/1 Terminating 0 10m 10.244.1.4 multi-m02 <none> <none>
nginx-wdjsh 1/1 Running 0 10m 10.244.3.4 multi-m04 <none> <none>
nginx-zbw6q 1/1 Running 0 50s 10.244.0.4 multi <none> <none>

Torna a arrencar el node multi-m02:

Terminal window
$ minikube -p multi node start multi-m02
👍 Starting "multi-m02" worker node in "multi" cluster
🚜 Pulling base image v0.0.46 ...
🔄 Restarting existing docker container for "multi-m02" ...
🐳 Preparando Kubernetes v1.32.0 en Docker 27.4.1...
🔎 Verifying Kubernetes components...
🌟 Complementos habilitados:
😄 Successfully started node multi-m02!

Un controlador només gestiona els Pods que coincideixen amb el seu selector d’etiquetes.

Per saber a quin controlador està associat un Pod en aquest moment, pots mirar l’atribut metadata.ownerReferences:

Terminal window
$ kubectl get pods nginx-lvw9l -o=jsonpath='{.metadata.ownerReferences[0]}'
{
"apiVersion":"apps/v1",
"blockOwnerDeletion":true,
"controller":true,
"kind":"ReplicaSet",
"name":"nginx",
"uid":"bb526ba4-f15a-4517-a056-b6ef8c8cd531"
}

A un ReplicaSet no li importa si afegeixes etiquetes addicionals als Pods que gestiona:

Terminal window
$ kubectl label pod nginx-zbw6q env=prod
pod/nginx-zbw6q labeled

Pots veure que els Pods són els mateixos que abans perquè aquest canvi no afecta de cap manera al ReplicaSet:

Terminal window
$ kubectl get pods --show-labels
NAME READY STATUS RESTARTS AGE LABELS
nginx-lvw9l 1/1 Running 0 14m app=nginx
nginx-wdjsh 1/1 Running 0 15m app=nginx
nginx-zbw6q 1/1 Running 0 5m55s app=nginx,env=prod

Però si canvies el valor de l’etiqueta app com es mostra a continuació:

Terminal window
$ kubectl label pod nginx-lvw9l app=nginx-old --overwrite
pod/nginx-lvw9l labeled

El ReplicaSet només trobarà dos Pods etiquetats com app=nginx, i crearà un nou Pod amb aquesta etiqueta:

Terminal window
$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
nginx-gvt68 1/1 Running 0 83s nginx
nginx-lvw9l 1/1 Running 0 28m nginx-old
nginx-wdjsh 1/1 Running 0 29m nginx
nginx-zbw6q 1/1 Running 0 19m nginx

El flag és necessari perquè d’aquesta manera no modificaràs de manera accidental una etiqueta. --overwrite

Pots verificar que el Pod nginx-lvw9l ja no és gestionat pel controlador:

Terminal window
$ kubectl get pods nginx-lvw9l -o=jsonpath='{.metadata.ownerReferences[0]}'

Això és útil quan un Pod no funciona correctament i vols provar què està passant: el treus de l’abast del controlador, que crearà automàticament un Pod per reemplaçar-lo, i pots depurar o esbrinar què està succeint per després eliminar-lo.

Pots modificar el nombre de Pods canviant el valor de l’atribut spec.replicas.

Pots augmentar el nombre de Pods:

Terminal window
$ kubectl scale rs nginx --replicas=5
replicaset.apps/nginx scaled
$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
nginx-gvt68 1/1 Running 0 21m nginx
nginx-lvw9l 1/1 Running 0 48m nginx-old
nginx-m7b46 1/1 Running 0 39s nginx
nginx-sm7zx 1/1 Running 0 39s nginx
nginx-wdjsh 1/1 Running 0 49m nginx
nginx-zbw6q 1/1 Running 0 40m nginx

O reduir el nombre de Pods:

Terminal window
$ kubectl scale rs nginx --replicas=2
replicaset.apps/nginx scaled
$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
nginx-lvw9l 1/1 Running 0 51m nginx-old
nginx-wdjsh 1/1 Running 0 52m nginx
nginx-zbw6q 1/1 Running 0 43m nginx

Quan elimines un ReplicaSet mitjançant kubectl delete, també s’eliminen els Pods a menys que utilitzis el flag --cascade=orphan:

Terminal window
$ kubectl delete rs nginx --cascade=false
replicaset.apps "nginx" deleted
$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
nginx-lvw9l 1/1 Running 0 55m nginx-old
nginx-wdjsh 1/1 Running 0 56m nginx
nginx-zbw6q 1/1 Running 0 47m nginx

Si tornes a crear de nou el ReplicaSet, només cal crear un nou Pod per satisfer les restriccions:

Terminal window
$ kubectl apply -f nginx.yaml
replicaset.apps/nginx created
$ kubectl get pods -L app
NAME READY STATUS RESTARTS AGE APP
nginx-lnfrd 0/1 ContainerCreating 0 2s nginx
nginx-lvw9l 1/1 Running 0 57m nginx-old
nginx-wdjsh 1/1 Running 0 57m nginx
nginx-zbw6q 1/1 Running 0 48m nginx

Esborra tots els recursos:

En un ReplicaSet, Kubernetes desplega el nombre de Pods indicats en el recurs als nodes del clúster que li semblin millor.

En canvi, en un DaemonSet Kubernetes desplega un únic Pod per a cada node del clúster.

Això és útil per a Pods de sistema com pot ser un recopilador de “logs”, un monitor de recursos, el procés kube-proxy, etc.

Per exemple, Fluentd és un recopilador de dades per unificar el registre d’esdeveniments del sistema.

Crea el fitxer fluentd.yaml:

apiVersion: apps/v1
kind: DaemonSet
metadata:
name: fluentd
spec:
selector:
matchLabels:
name: fluentd
template:
metadata:
labels:
name: fluentd
spec:
nodeSelector:
fluentd-enabled: "true"
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:latest

Pots veure que en la configuració del recurs utilitzem un selector d’etiquetes per limitar els nodes en què es desplegarà el Pod.

Per exemple, etiqueta el node multi-m02 amb fluentd-enabled=true:

Terminal window
$ kubectl label node multi-m02 fluentd-enabled=true
node/multi-m02 labeled

Crea el recurs fluentd:

Terminal window
$ kubectl apply -f fluentd.yaml
daemonset.apps/fluentd created

Pots veure que només s’ha desplegat un Pod fluentd-????? al clúster:

Terminal window
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-wdh2j 1/1 Running 0 34s 10.244.1.4 multi-m02 <none> <none>

Edita el fitxer fluentd.yaml i elimina el selector:

...
spec:
containers:
- name: fluentd-elasticsearch
image: quay.io/fluentd_elasticsearch/fluentd:latest

Actualitza el recurs:

Terminal window
$ kubectl apply -f fluentd.yaml
daemonset.apps/fluentd configured

Ara es crea un Pod fluentd-????? a cada node del clúster:

Terminal window
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-gj4hs 1/1 Running 0 15s 10.244.2.3 multi-m03 <none> <none>
fluentd-gxrfv 1/1 Running 0 15s 10.244.3.3 multi-m04 <none> <none>
fluentd-rp7vz 1/1 Running 0 15s 10.244.0.4 multi <none> <none>
fluentd-xqlvp 1/1 Running 0 11s 10.244.1.5 multi-m02 <none> <none>

Torna a afegir el selector de node i verifica que s’eliminen tots els Pods excepte el de multi-m02:

Terminal window
$ nano fluentd.yaml
$ kubectl apply -f fluentd.yaml
daemonset.apps/fluentd configured
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-gxrfv 0/1 Completed 0 7m9s 10.244.3.3 multi-m04 <none> <none>
fluentd-xqlvp 1/1 Terminating 0 7m5s 10.244.1.5 multi-m02 <none> <none>

Modifica l’etiqueta del node multi-m02 a fluentd-enabled=false i verifica que el Pod fluentd-xqlvp s’elimina:

Terminal window
$ kubectl label node multi-m02 fluentd-enabled=false --overwrite
node/multi-m02 labeled
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
fluentd-mszqj 0/1 Completed 0 44s 10.244.1.6 multi-m02 <none> <none>

El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.

©2022-2025 xtec.dev