Introducción
Las actualizaciones continuas son una parte importante del ciclo de vida de una aplicación moderna, ya que los usuarios esperan constantemente nuevas funciones y cero tiempo de inactividad. Si bien Kubernetes usó controladores de replicación para habilitar esta funcionalidad en el pasado, las versiones más nuevas recomiendan usar implementaciones.
Este tutorial le muestra cómo realizar actualizaciones progresivas mediante implementaciones de Kubernetes. Este método le permite actualizar rápidamente sus aplicaciones y lograr un tiempo de inactividad cero al tiempo que garantiza la compatibilidad con la reversión.
Requisitos previos
- Un clúster de Kubernetes
- Acceso a una ventana de terminal
- La herramienta de línea de comandos kubectl
Habilitar actualizaciones continuas
Las implementaciones de Kubernetes actúan como envoltorios de los conjuntos de réplicas, que son controladores de Kubernetes a cargo de la administración de pods. Las implementaciones brindan funcionalidad adicional a los ReplicaSets:realizan comprobaciones de estado, actualizaciones continuas y reversiones.
1. Primero, crea un yaml archivo con especificaciones de implementación mediante un editor de texto, como Nano:
nano nginx-test.yaml
El siguiente archivo de muestra contiene las declaraciones básicas necesarias para una implementación de Kubernetes:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
2. Guarde y salga del archivo.
3. Luego, cree la implementación usando kubectl create
comando y yaml archivo que acaba de crear:
kubectl create -f nginx-test.yaml
4. Verifique la implementación:
kubectl get deployment
El resultado debe confirmar que la implementación está lista:
4. A continuación, verifique los ReplicaSets ejecutando el comando:
kubectl get rs
El archivo de muestra especificó cuatro réplicas, que se muestran como listas:
5. Finalmente, verifique si las cápsulas están activas:
kubectl get pod
El resultado muestra los pods como listos y en ejecución:
Asegúrese de cero tiempo de inactividad
Para configurar actualizaciones continuas sin tiempo de inactividad, debe especificar la estrategia de actualización.
1. Agregue la siguiente declaración a la implementación yaml archivo bajo spec
categoría:
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
minReadySeconds
le dice a Kubernetes cuánto tiempo debe esperar hasta que cree el siguiente pod. Esta propiedad garantiza que todos los módulos de aplicaciones estén listos durante la actualización.maxSurge
especifica el número máximo (o porcentaje) de pods por encima del número especificado de réplicas. En el ejemplo anterior, el número máximo de pods será 5 desde 4 las réplicas se especifican en yaml archivo.maxUnavailable
declara el número máximo (o porcentaje) de pods no disponibles durante la actualización. SimaxSurge
está establecido en 0 , este campo no puede ser 0 .
Agregar la especificación anterior a la implementación yaml El archivo es suficiente para comenzar a realizar actualizaciones continuas de Kubernetes. Sin embargo, no garantiza cero tiempo de inactividad. Kubernetes no puede saber cuándo está listo un nuevo pod; elimina el antiguo tan pronto como se crea el nuevo. Este problema provoca tiempo de inactividad hasta que el nuevo pod pueda aceptar solicitudes.
Para solucionar este problema, Kubernetes incluye el concepto de sondeos de preparación. . Las sondas verifican el estado de los pods y permiten que las actualizaciones continuas continúen solo cuando todos los contenedores en un pod están listos. Los pods se consideran listos cuando la sonda de preparación tiene éxito y después del tiempo especificado en minReadySeconds
ha pasado.
2. Para configurar las sondas de preparación, agregue las siguientes líneas a spec.template.spec
categoría en el archivo de implementación:
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
initialDelaySeconds
especifica cuánto tiempo tiene que esperar la sonda para comenzar después de que se inicie el contenedor.periodSeconds
es el tiempo entre dos sondas. El valor predeterminado es 10 segundos, mientras que el valor mínimo es 1 segundo.successThreshold
es el número mínimo de sondeos exitosos consecutivos después de uno fallido para que todo el proceso se considere exitoso. Los valores predeterminado y mínimo son ambos 1 .
Todo el archivo de implementación correctamente configurado para actualizaciones continuas debería tener este aspecto:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 4
selector:
matchLabels:
app: nginx
minReadySeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.0
ports:
- containerPort: 80
readinessProbe:
httpGet:
path: /
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
successThreshold: 1
3. Guarde el archivo y salga.
4. Luego, usa kubectl apply
para aplicar los cambios:
kubectl apply -f nginx-text.yaml --record
El --record
la bandera tendrá un propósito en el proceso de reversión.
El resultado muestra que la implementación se ha configurado correctamente.
Realizar actualización continua
Hay tres formas de realizar actualizaciones continuas.
Por ejemplo, para cambiar la imagen de la aplicación:
Opción 1:puedes usar kubectl set
para realizar la acción en la línea de comando:
kubectl set image deployment nginx-deployment nginx=nginx:1.14.2 --record
Opción 2:como alternativa, modifique la versión de la imagen en spec.templates.spec.containers
sección del yaml expediente. Luego, usa kubectl replace
para realizar la actualización:
kubectl replace -f nginx-test.yaml
Opción 3:también puedes usar kubectl edit
para editar la implementación directamente:
kubectl edit deployment nginx-deployment --record
Realice los cambios necesarios en el editor que se abre:
Los cambios se aplican cuando cierras el editor.
Comprobar el estado del lanzamiento
Verifique el estado de lanzamiento de la implementación usando la siguiente sintaxis:
kubectl rollout status deployment nginx-deployment
El resultado confirma la implementación exitosa:
Pausar y reanudar la actualización progresiva
Detenga y reanude las actualizaciones continuas con el kubectl rollout
respectivo. comandos.
Para pausar la actualización, ejecute:
kubectl rollout pause deployment nginx-deployment
Para reanudar la actualización, ejecute:
kubectl rollout resume deployment nginx-deployment
Programar pods para implementación
Use propiedades de afinidad y antiafinidad para controlar en qué nodos Kubernetes programa pods específicos en su implementación.
Afinidad de grupos
Hay dos tipos de afinidad actualmente disponible en Kubernetes:
requiredDuringSchedulingIgnoredDuringExecution
le dice a Kubernetes que solo ejecute pods en nodos que cumplan ciertos criterios, como un tipo de procesador específico.preferredDuringSchedulingIgnoredDuringExecution
permite que los pods se ejecuten en otro lugar, si y solo si ningún nodo cumple con los criterios dados.
Estas propiedades se enumeran en PodSpec expediente. Por ejemplo, un pod se puede especificar de la siguiente manera:
apiVersion: v1
kind: Pod
metadata:
name: affinity-test
spec:
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/test-name
operator: In
values:
- test1
- test2
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 1
preference:
matchExpressions:
- key: example-node-label-key
operator: In
values:
- example-node-label-value
containers:
- name: affinity-test
image: k8s.gcr.io/pause:2.0
El archivo anterior le dice a Kubernetes que ejecute el pod solo en un nodo con una etiqueta cuya clave sea kubernetes.io/test-name
y cuyo valor es test1
o test2
. Además, Kubernetes preferirá los nodos cuya clave sea example-node-label-key
, con el example-node-label-value
valor.
Pod antiafinidad
Anti-afinidad de pods es útil si no desea que todos los pods se ejecuten en el mismo nodo. Funciona de manera similar a la afinidad, con los mismos dos tipos disponibles:requiredDuringSchedulingIgnoredDuringExecution
y preferredDuringSchedulingIgnoredDuringExecution
.
El siguiente ejemplo especifica una regla de antiafinidad que le dice a Kubernetes que preferiblemente evite programar los pods de aplicaciones de "prueba" en nodos que ya tienen los pods de "prueba":
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 100
podAffinityTerm:
labelSelector:
matchExpressions:
- key: app
operator: In
values:
- test
topologyKey: Kubernetes.io/hostname
Revertir cambios
Si algo sale mal con el proceso de actualización, puede revertir los cambios y volver a una versión anterior de la aplicación. Para hacerlo, utilice el siguiente kubectl rollout
comando:
kubectl rollout history deployment nginx-deployment
El resultado enumera las revisiones disponibles, creadas al agregar el --record
marcar al realizar una actualización:
Elija la revisión que desee y escriba el siguiente comando para revertir los cambios:
kubectl rollout undo deployment nginx-deployment --to-revision=1
El comando anterior retrocede a la revisión 1 y produce el siguiente resultado: