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 minReadySecondsle 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.maxSurgeespecifica 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.maxUnavailabledeclara el número máximo (o porcentaje) de pods no disponibles durante la actualización. SimaxSurgeestá 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 initialDelaySecondsespecifica cuánto tiempo tiene que esperar la sonda para comenzar después de que se inicie el contenedor.periodSecondses el tiempo entre dos sondas. El valor predeterminado es 10 segundos, mientras que el valor mínimo es 1 segundo.successThresholdes 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:
requiredDuringSchedulingIgnoredDuringExecutionle dice a Kubernetes que solo ejecute pods en nodos que cumplan ciertos criterios, como un tipo de procesador específico.preferredDuringSchedulingIgnoredDuringExecutionpermite 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: