Introducción
Las implementaciones de Canary son útiles para presentar nuevas versiones de servicios porque ofrecen una forma de implementar nuevas funciones gradualmente. Cuando se implementa una actualización, sale en etapas para un pequeño porcentaje de usuarios. Esto permite a los desarrolladores ver cómo funciona la actualización antes de ponerla a disposición de todos.
Kubernetes está diseñado para realizar implementaciones canary de forma nativa. Sin embargo, la desventaja de este enfoque es que la limitación del tráfico a la implementación canary (cambiando las proporciones de réplica) debe hacerse manualmente. La solución para agilizar este proceso es emplear una red de servicios, como Istio de código abierto, para desacoplar la distribución del tráfico y los recuentos de réplicas.
En este tutorial, aprenderá a implementar la versión canary de una aplicación en un clúster habilitado para Istio y configurará Istio para controlar el enrutamiento del tráfico.

Requisitos previos
- Clúster de Kubernetes (minikube)
- herramienta de línea de comandos kubectl
- Istio instalado
- Cuenta de Docker Hub
- Panel de control de Grafana
Paso 1:Cree la imagen y el contenedor de Docker para Canary Build
Para comenzar a implementar la compilación canary de su aplicación, primero cree una imagen acoplable que contenga la versión que desea implementar.
- Vaya al directorio que contiene los archivos necesarios para la imagen. El ejemplo usa una aplicación llamada test-canary , almacenado en el directorio con el mismo nombre:
cd test-canary
2. Usa la docker build
Comando para construir la imagen de Docker. Siga el comando con su nombre de usuario de Docker Hub y el nombre de la imagen:
docker build -t [dockerhub-username]/test-canary .
El resultado confirma la creación exitosa de la imagen:

3. Usa las docker images
Comando para ver una lista de tus imágenes y verificar si la nueva imagen está entre ellas:
docker images

4. A continuación, utilice docker run
comando para construir un contenedor con la imagen que creó anteriormente. Asigne un nombre al contenedor y elija un puerto para acceder:
docker run --name [name] -p [port]:8080 -d [dockerhub-username]/test-canary
Si la operación es exitosa, el sistema genera el ID completo del contenedor recién creado:

5. Usa el docker ps
Comando para comprobar los contenedores en ejecución:
docker ps

6. Ahora use el puerto que asignó al contenedor para acceder a él a través de un navegador:
http://localhost:[port]
El navegador muestra el contenido de la aplicación:

7. Después de confirmar que la aplicación funciona, detenga el contenedor con docker stop
dominio. Agregue el ID del contenedor al comando, que puede copiar desde la primera columna de docker ps
salida:
docker stop [container-id]

8. Finalmente, para enviar la imagen a su cuenta de Docker Hub, inicie sesión en Docker Hub usando la línea de comando:
docker login -u [dockerhub-username]
El sistema pide la contraseña. Escriba la contraseña y presione Enter :

9. Ahora empuja la imagen con docker push
:
docker push [dockerhub-username]/test-canary

Paso 2:Modificar la implementación de la aplicación
Para agregar la implementación canary a la implementación general de su aplicación, use un editor de texto para editar el archivo que contiene las especificaciones del servicio y la implementación.
El ejemplo usa el manifiesto de la aplicación llamado app-manifest.yaml
:
nano app-manifest.yaml
El manifiesto debe ser similar al contenido a continuación:
apiVersion: v1
kind: Service
metadata:
name: nodejs
labels:
app: nodejs
spec:
selector:
app: nodejs
ports:
- name: http
port: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs
labels:
version: v1
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v1
spec:
containers:
- name: nodejs
image: markopnap/test-prod
ports:
- containerPort: 8080
El manifiesto de ejemplo anterior describe una versión de producción de una aplicación Node.js, cuyo contenedor se almacena en markopnap/test-prod
. Para incluir la versión Canary de la aplicación, comience editando la Despliegue sección del archivo y agregue -v1
al nombre de la aplicación:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v1
Ahora, agregue otra sección de Implementación al final del archivo, con especificaciones para la compilación canary:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodejs-v2
labels:
version: v2
spec:
replicas: 1
selector:
matchLabels:
app: nodejs
template:
metadata:
labels:
app: nodejs
version: v2
spec:
containers:
- name: nodejs
image: markopnap/test-canary
ports:
- containerPort: 8080
Una vez que termine de editar el archivo, guárdelo y luego actualice la configuración del sistema usando kubectl apply
:
kubectl apply -f app-manifest.yaml
Paso 3:configurar el servicio virtual de Istio
Cree un nuevo archivo yaml para almacenar la configuración de Istio. El ejemplo usa el archivo titulado istio.yaml
, pero puede darle el nombre que desee:
nano istio.yaml
Si anteriormente usó Istio para la implementación de una versión de producción, el archivo ya existe y debería tener un aspecto similar a este:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nodejs-gateway
spec:
selector:
istio: ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nodejs
spec:
hosts:
- "*"
gateways:
- nodejs-gateway
http:
- route:
- destination:
host: nodejs
El archivo tiene dos secciones que definen Puerta de enlace y Servicio Virtual objetos. Para introducir ambas versiones de la aplicación y establecer la regla de enrutamiento para la distribución a los usuarios, modifique el http
sección en la parte inferior. La sección debe contener dos destinos con diferentes subconjuntos y pesos :
http:
- route:
- destination:
host: nodejs
subset: v1
weight: 90
- destination:
host: nodejs
subset: v2
weight: 10
El peso El parámetro le dice a Istio qué porcentaje de tráfico debe enrutarse a un destino específico. En el ejemplo anterior, el 90 por ciento del tráfico se dirige a la versión de producción, mientras que el 10 por ciento se dirige a la versión Canary.
Después de editar la sección Servicio virtual, agregue las siguientes líneas al final del archivo para crear una regla de destino :
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nodejs
spec:
host: nodejs
subsets:
- name: v1
labels:
version: v1
- name: v2
labels:
version: v2
El propósito de definir la regla de destino es administrar el tráfico entrante y enviarlo a las versiones especificadas de la aplicación.
Guarde el archivo y use kubectl apply
para activarlo:
kubectl apply -f istio.yaml
Paso 4:probar la implementación de Canary
La configuración establecida en el paso anterior realiza el enrutamiento del tráfico a sus implementaciones de producción y Canary. Para probar esto, acceda a la aplicación usando la IP externa de istio-ingressgateway
, que Istio utiliza como equilibrador de carga.
Busque el istio-ingressgateway
servicio en la lista de servicios disponibles en el istio-system
espacio de nombres Usa kubectl get
para listar los servicios:
kubectl get svc -n istio-system

Copie el istio-ingressgateway
dirección IP externa en la barra de direcciones de su navegador:
http://[ingressgateway_ip]
Es probable que el navegador muestre la versión de producción de la aplicación. Presiona Actualizar botón varias veces para simular algo de tráfico:

Después de un par de veces, debería ver la versión canaria de la aplicación:

Si tiene instalado el complemento Grafana, verifique las estadísticas de solicitudes entrantes para ver el porcentaje de enrutamiento para cada implementación. En Grafana, haz clic en Inicio icono:

En los Paneles de control sección, seleccione Istio y, a continuación, haga clic en Panel de control de servicios de Istio :

En el panel, busque el Servicio y seleccione el servicio correspondiente a su aplicación. En este ejemplo, el servicio se llama nodejs.default.svc.cluster.local
. Una vez que elija el servicio, vaya a Cargas de trabajo del servicio sección:

Seleccione el gráfico titulado Solicitudes entrantes por carga de trabajo de destino y código de respuesta . El gráfico muestra el tráfico que generó al actualizar la página. En este ejemplo, es evidente que Istio sirvió el nodejs-v1
versión de la aplicación con más frecuencia que la canaria nodejs-v2
versión.
