Ingress Controller de Citrix ADC

Implementar la solución de implementación de Canary integrada en Citrix ADC

La versión de Canary es una técnica para reducir el riesgo de introducir una nueva versión de software en producción al implementar primero el cambio a un pequeño subconjunto de usuarios. Después de la validación del usuario, la aplicación se implementa para el conjunto más grande de usuarios.

Citrix proporciona las siguientes opciones para la implementación de Canary mediante el Citrix Ingress Controller.

En una implementación que utiliza Canary CRD, la configuración Canary se aplica mediante una CRD de Kubernetes. Citrix también admite una opción mucho más sencilla para la implementación de Canary mediante anotaciones de entrada.

Implementar Canary con la CRD de Canary

En esta sección se proporciona información sobre cómo realizar la implementación Canary con Canary CRD.

La solución Canary Deployment integrada en Citrix ADC une todos los componentes de la entrega continua (CD) y facilita la implementación de Canary para los desarrolladores de aplicaciones. Esta solución utiliza Spinnaker como plataforma de entrega continua y Kayenta como complemento Spinnaker para el análisis Canary. Kayenta es un servicio de análisis Canary de código abierto que obtiene métricas configuradas por el usuario de sus fuentes, ejecuta pruebas estadísticas y proporciona una puntuación agregada para Canary. La puntuación de las pruebas estadísticas y los contadores junto con los criterios correctos se utiliza para promover o reprobar Canary.

Citrix ADC viene con un módulo de configuración rico centrado en las aplicaciones y proporciona una visibilidad completa del tráfico de aplicaciones y el estado de las instancias de aplicaciones. Las capacidades de Citrix ADC para generar estadísticas de rendimiento precisas se pueden aprovechar para que el análisis de Canary tome mejores decisiones sobre la implementación de Canary. En esta solución, Citrix ADC se integra con la plataforma Spinnaker y sirve de fuente para proporcionar métricas precisas para analizar la implementación Canary mediante Kayenta.

Citrix ADC Metrics Exporter exporta las métricas de rendimiento de la aplicación al sistema de supervisión de código abierto Prometheus y puede configurar Kayenta para obtener las métricas para la implementación de Canary. La distribución del tráfico a la versión Canary se puede regular mediante la infraestructura de directivas de Citrix ADC. Si quiere desviar un tipo específico de tráfico de producción a línea de base y Canary, puede usar expresiones de coincidencia para redirigir el tráfico a la línea de base y Canary aprovechando la rica infraestructura de directivas de Citrix ADC.

Por ejemplo, puede desviar el tráfico de producción a Canary y de línea base mediante la expresión de coincidencia HTTP.REQ.URL.CONTAINS (“citrix india”). El tráfico que coincide con la expresión se desvía a Canary y línea de base y el tráfico restante pasa a producción.

Los componentes que forman parte de la solución de implementación de Canary integrada en Citrix y sus funcionalidades se explican a continuación:

  • GitHub: GitHub ofrece todas las funcionalidades distribuidas de control de versiones y administración de código fuente proporcionadas por Git y tiene funciones adicionales. GitHub tiene muchas utilidades disponibles para integrarse con otras herramientas que forman parte de su proceso de CI/CD, como Docker Hub y Spinnaker.

  • Docker Hub: Docker Hub es un servicio de repositorio basado en la nube proporcionado por Docker para compartir y encontrar imágenes de Docker. Puede integrar GitHub con Docker Hub para crear imágenes automáticamente a partir del código fuente en GitHub y enviar la imagen creada a Docker Hub.

  • Spinnaker: Spinnaker es una plataforma de entrega continua de código abierto y multinube para lanzar cambios de software con alta velocidad y confianza. Puede utilizar las funciones de implementación de aplicaciones de Spinnaker para construir y administrar flujos de trabajo de entrega continua. La construcción clave de la gestión de la implementación en Spinnaker se conoce como un proceso. Los procesos en Spinnaker consisten en una secuencia de acciones, conocidas como etapas. Spinnaker proporciona varias etapas para implementar una aplicación, ejecutar un script, realizar análisis Canary, eliminar la implementación, etc. Puede integrar Spinnaker con muchas herramientas de terceros para admitir muchas funcionalidades adicionales.

  • Prometheus: Prometheus es un conjunto de herramientas de supervisión y alertas de sistemas de código abierto. Prometheus es un sistema de supervisión que puede mantener una gran cantidad de datos en una base de datos de series temporales. Citrix ADC Metrics expone las métricas de rendimiento a Spinnaker a través de Prometheus.

  • Jenkins: Jenkins es un servidor de automatización de código abierto que ayuda a automatizar todo tipo de tareas relacionadas con la creación, las pruebas y la entrega o implementación de software. Jenkins también admite la ejecución de scripts personalizados como parte de su ciclo de implementación.

  • Citrix Ingress Controller Citrix proporciona un Ingress Controller para Citrix ADC MPX (hardware), Citrix ADC VPX (virtualizado) y Citrix ADC CPX (en contenedores) para implementaciones bare metal y en la nube. El Citrix Ingress Controller se basa en Kubernetes Ingress y configura automáticamente uno o más ADC de Citrix en función de la configuración de recursos Ingress.

Se requieren las siguientes versiones de software de Citrix para la solución de implementación de Canary integrada en Citrix:

  • Compilación/versión del controlador de entrada de Citrix: quay.io/citrix/citrix-k8s-ingress-controller:1.26.7.
  • Versión de Citrix ADC CPX: quay.io/citrix/citrix-k8s-cpx-ingress:13.0-83.27.
  • Versión de Citrix ADC Metrics Exporter: quay.io/citrix/netscaler-metrics-exporter:1.4.0.

Flujo de trabajo de un proceso de Spinnaker para la solución de implementación Canary integrada en Citrix ADC

El siguiente diagrama explica el flujo de trabajo de un proceso de Spinnaker para la solución de implementación de Canary integrada en Citrix ADC.

Spinnaker_pipeline

En los pasos siguientes se explica el flujo de trabajo especificado en el diagrama.

  1. Los desarrolladores mantienen el código fuente en GitHub, hacen cambios cuando sea necesario y confirman los cambios en GitHub.
  2. Se configura un webhook en GitHub para escuchar los cambios en el código fuente. Cada vez que el código fuente se registra en GitHub, se activa el webhook e informa a Docker Hub para que cree la imagen con el nuevo código fuente. Una vez que se crea la imagen de docker, un webhook independiente configurado en Docker Hub desencadena un proceso de Spinnaker.
  3. Una vez que se activa el proceso de Spinnaker, se implementan las versiones Canary y de línea base de la imagen.
  4. Una vez que se implementan las versiones Canary y baseline, cierto porcentaje del tráfico de producción se desvía a las versiones Canary y baseline. Citrix ADC recopila las estadísticas de rendimiento y las exporta a Prometheus con la ayuda de Citrix ADC Metrics Exporter. Prometheus envía estas estadísticas a Kayenta para su análisis Canary.

  5. Kayenta realiza un análisis Canary basado en las estadísticas de rendimiento y genera una puntuación. Según la puntuación, la implementación Canary se considera correcta o incorrecta y la imagen se implanta o se revierte.

Implementar la solución de implementación de Canary integrada en Citrix ADC en Google Cloud Platform

Esta sección contiene información sobre la configuración de Spinnaker, cómo crear un proceso de Spinnaker y una implementación de ejemplo de Canary.

Cómo implementar Spinnaker en Google Cloud Platform

Este tema contiene información sobre la implementación de Spinnaker y cómo integrar complementos con Spinnaker para la implementación de Canary en Google Cloud Platform (GCP).

Realice los siguientes pasos para implementar Spinnaker e integrar complementos en GCP.

  1. Configura el entorno y crea un clúster de GKE con los siguientes comandos.

    export GOOGLE_CLOUD_PROJECT=[PROJECT_ID] 
    gcloud config set project $GOOGLE_CLOUD_PROJECT 
    gcloud config set compute/zone us-central1-f
    gcloud services enable container.googleapis.com
    gcloud beta container clusters create kayenta-tutorial 
    --machine-type=n1-standard-2 --enable-stackdriver-kubernetes
    
  2. Instala el complemento para integrar Prometheus con Stackdriver con el siguiente comando.

    kubectl apply --as=admin --as-group=system:masters -f \
    https://storage.googleapis.com/stackdriver-prometheus-documentation/rbac-setup.yml
    curl -sS "https://storage.googleapis.com/stackdriver-prometheus-documentation/prometheus-service.yml" | 
    \sed "s/_stackdriver_project_id:.*/_stackdriver_project_id: $GOOGLE_CLOUD_PROJECT/" | 
    \sed "s/_kubernetes_cluster_name:.*/_kubernetes_cluster_name: kayenta-tutorial/" | 
    \sed "s/_kubernetes_location:.*/_kubernetes_location: us-central1-f/" | 
    \kubectl apply -f -
    
  3. Implemente Spinnaker en el clúster de GKE con los siguientes pasos.

    1. Descargue el archivo quick-install.yml de Spinnaker desde el sitio web de Spinnaker.
    2. Actualice el archivo quick-install.yml para integrar diferentes componentes a partir de Docker Hub. Para integrar Spinnaker con Docker Hub, actualice los valores de dirección, nombre de usuario, contraseña, correo electrónico y repositorio en ConfigMap en el archivo quick-install.yml.

      dockerRegistry:
                  enabled: true
                  accounts:
                  - name: my-docker-registry
                  requiredGroupMembership: []
                  providerVersion: V1
                  permissions: {}
                  address: https://index.docker.io
                  username: <username>
                  password: <password>
                  email: <mail-id>
                  cacheIntervalSeconds: 30
                  clientTimeoutMillis: 60000
                  cacheThreads: 1
                  paginateSize: 100
                  sortTagsByDate: false
                  trackDigests: false
                  insecureRegistry: false
                  repositories:- <repository-name>
                  primaryAccount: my-docker-registry
      
    3. (Opcional) Realice los siguientes pasos para configurar Jenkins.

      sudo apt-get update
      sudo apt-get upgrade
      sudo apt-get install openjdk-8-jdk
      wget -q -O - https://jenkins-ci.org/debian/jenkins-ci.org.key |       
      sudo apt-key add -
      sudo sh -c 'echo deb http://pkg.jenkins-ci.org/debian binary/ > /etc/apt/sources.list.d/jenkins.list'
      sudo apt-get update
      sudo apt-get install jenkins git
      sudo apt-get install software-properties-common python-software-properties apt-transport-https
      sudo add-apt-repository https://dl.bintray.com/spinnaker-releases/debians
      

      Nota:

      Si Jenkins está instalado en uno de los nodos de Kubernetes, debe actualizar las reglas de firewall de ese nodo para el acceso público.

    4. Actualice los siguientes valores en el archivo quick-install.yml para integrar Jenkins con Spinnaker.

          data:igor.yml: |
      enabled: true
      skipLifeCycleManagement: false
          ci:jenkins:
      enabled: true
        masters: 
      - name: master
            address: <endpoint>
          username: <username>
        password: <password>
      
    5. Para configurar Prometheus y Grafana, consulte la sección Integración de Prometheus y Grafana en Citrix ADC Metrics Exporter y siga los pasos.

    6. Para integrar Prometheus con Spinnaker, actualice los siguientes valores en el archivo quick-install.yml.

        data:
        config: | 
          deploymentConfigurations:
          canary:
          enabled: true
      serviceIntegrations:
            - name: prometheus
        enabled: true
      accounts:
        - name: my-prometheus
      endpoint:
            baseUrl: prometheus-endpoint
          supportedTypes:
      - METRICS_STORE
        data:
        config: |
          deploymentConfigurations:
          metricStores:
            prometheus:
            enabled: true
            add_source_metalabels: true
            stackdriver:
        enabled: true
          period: 30
          enabled: true
      
    7. Para integrar Slack para notificaciones con Spinnaker, actualiza los siguientes valores en el archivo quick-install.yml.

      data:
       config: |
        deploymentConfigurations:
         notifications:
          slack:
           enabled: true
            botName: <BotName>
            token: <token>
      
    8. Una vez que todos los componentes requeridos estén integrados, implemente Spinnaker realizando el siguiente paso.

      kubectl apply -f quick-install.yaml
      
    9. Verifique el progreso de la implementación mediante el siguiente comando. Una vez que se completa la implementación, este comando genera todos los pods como Ready x/x.

      watch kubectl -n spinnaker get pods
      
  4. Una vez que implemente Spinnaker, puede probar la implementación con los siguientes pasos:

    1. Habilita el acceso a Spinnaker reenviando un puerto local al componente de cubierta de Spinnaker con el siguiente comando:

      DECK_POD=$(kubectl -n spinnaker get pods -l \
      cluster=spin-deck,app=spin \
      -o=jsonpath='{.items[0].metadata.name}')
      kubectl -n spinnaker port-forward $DECK_POD 8080:9000 >/dev/null &
      
    2. Para acceder a Spinnaker, en Cloud Shell, haga clic en el icono Vista previa web y selecciona Vista previa en el puerto 8080.

      Nota:

      Puede acceder a Spinnaker de forma segura o a través de HTTP. Para exponer Spinnaker de forma segura, usa el archivo spin-ingress-ssl.yaml para implementar Ingress. Una vez que la aplicación Spinnaker se expone públicamente, puede usar el dominio asignado a Spinnaker o la dirección IP del Ingress para acceder a ella.

Crear un proceso de Spinnaker y configurar la implementación Canary automática

Una vez que implemente Spinnaker, cree un proceso de Spinnaker para una aplicación y configure la implementación Canary automática.

  1. Crea una aplicación en Spinnaker.
  2. Cree un proceso de Spinnaker. Puede modificar el proceso como un archivo JSON mediante el archivo de muestra que se proporciona en los archivos JSON de muestra.
  3. Cree una configuración Canary automatizada en Spinnaker para el análisis Canary automatizado. Puede utilizar la configuración proporcionada en el archivo JSON como muestra para la configuración Canary automatizada Archivos JSON de muestra.

Implemente una aplicación de muestra para Canary

En este ejemplo se muestra cómo ejecutar la implementación de Canary de una aplicación de muestra con la solución de implementación de Canary integrada en Citrix ADC. En este ejemplo, Citrix ADC CPX, MPX o VPX se implementa como un dispositivo de entrada para un clúster de GKE. Citrix ADC genera las métricas de rendimiento necesarias para el análisis de detección de fallos.

Como requisito previo, debe completar el siguiente paso antes de implementar la aplicación de muestra.

Implemente la aplicación de muestra

Realice los siguientes pasos para implementar una aplicación de muestra como una versión Canary.

  1. Cree las reglas RBAC necesarias para Citrix ADC implementando el archivo rbac.yaml.

    kubectl apply -f rbac.yaml 
    
  2. Puede implementar el Citrix Ingress Controller como un sidecar con Citrix ADC CPX o como un pod independiente que controla Citrix ADC VPX o MPX.

    Use el archivo cpx-with-cic-sidecar.yml para implementar el Citrix Ingress Controller como un sidecar con Citrix ADC CPX. También implementa Citrix ADC Metrics Exporter en el mismo pod.

    kubectl apply -f cpx-with-cic-sidecar.yml 
    

    Para implementar el Citrix Ingress Controller como un pod independiente para Citrix ADC VPX o MPX, use el archivo cic-vpx.yaml. En esta implementación, debe usar el archivo exporter.yaml para implementar Citrix ADC Metrics Exporter.

    kubectl apply -f cic-vpx.yaml
    kubectl apply -f exporter.yaml
    

    Nota:

    Según cómo vaya a implementar el Citrix Ingress Controller, debe modificar el archivo YAML para la implementación del Citrix Ingress Controller y modificar los valores de las variables de entorno tal como se proporcionan en la implementación del Citrix Ingress Controller.

  3. Implementa Ingress para exponer Spinnaker de forma segura mediante el archivo spin-ingress-ssl.yaml.

    kubectl apply -f spin-ingress-ssl.yaml 
    

    Nota:

    Para obtener más información sobre la creación de un certificado TLS para Ingress, consulte Certificados TLS en Citrix Ingress Controller.

  4. Una vez que Spinnaker esté expuesto con Citrix ADC, acceda a Spinnaker y realice los pasos en Crear un proceso de Spinnaker y configurar la implementación Canary automática si los pasos aún no se han realizado.

  5. Implemente la versión de producción de la aplicación mediante el archivo production.yaml.

    kubectl apply -f production.yaml 
    
  6. Cree la regla de recursos Ingress para exponer el tráfico desde fuera del clúster a los servicios dentro del clúster mediante el archivo ingress.yaml.

    kubectl apply -f ingress.yaml 
    
  7. Cree un servicio de Kubernetes para la aplicación que necesita una implementación Canary con el archivo service.yaml.

    kubectl apply -f service.yaml
    
  8. Implemente la CRD Canary que define la configuración Canary mediante el archivo canary-crd-class.yaml.

    kubectl apply -f canary-crd-class.yaml
    

    Nota:

    Una vez que cree la CRD, espere 10 segundos antes de aplicar el objeto CRD.

  9. Crea un objeto CRD canary-crd-object.yaml basado en la CRD Canary para personalizar la configuración Canary.

    kubectl apply -f canary-crd-object.yaml
    

    En la siguiente tabla se explican los campos del objeto CRD Canary.

    Campo Descripción
    serviceNames Lista de servicios a los que se debe aplicar este CRD
    deployment Especifica la estrategia de implementación como Kayenta.
    percentage Especifica el porcentaje de tráfico que se desviará de la producción a la línea de base y a Canary.
    matchExpression (opcional) Cualquier directiva compatible con Citrix ADC que se pueda utilizar para definir el subconjunto de usuarios que se dirigirán a las versiones Canary y de línea base. Si se configura x porcentaje de tráfico, entonces, desde dentro del subconjunto de usuarios que coincide con matchExpression, solo x porcentaje de usuarios se desvían a la línea de base y Canary. Los usuarios restantes se desvían a la producción.
    Spinnaker Especifica las configuraciones de proceso de Spinnaker que quiere aplicar a sus servicios.
    domain Dirección IP o nombre de dominio de la puerta Spinnaker.
    port Número de puerto de la puerta Spinnaker.
    applicationName El nombre de la aplicación en Spinnaker.
    pipelineName El nombre del proceso en la aplicación Spinnaker.
    serviceName Especifica el nombre del servicio al que quiere aplicar la configuración de Spinnaker.
  10. Implemente versiones Canary y de línea base de la aplicación.

    Nota:

    Si está automatizando completamente la implementación Canary, implemente versiones Canary y de línea base mediante la etapa Deploy (Manifest) en el proceso de Spinnaker y no hay necesidad de realizar este paso.

    Para implementar manualmente versiones Canary y de línea base, usa los archivos canary.yaml y baseline.yaml.

    kubectl apply -f canary.yaml
    kubectl apply -f baseline.yaml
    

Solución de problemas

Para solucionar problemas de la implementación, lleve a cabo los siguientes pasos.

  1. Compruebe los registros del pod para los componentes respectivos, como Spinnaker, Prometheus, Kayenta, Citrix ADC CPX, Citrix ADC Metrics Exporter, Citrix Ingress Controller.
  2. Compruebe los registros de pods del Citrix Ingress Controller para ver si hay errores relacionados con la configuración al configurar el proxy de Citrix.
  3. Busque la palabra clave exception/Exception en los registros del pod del Citrix Ingress Controller para reducir los problemas.
  4. Compruebe los registros que preceden a la búsqueda. Compruebe la configuración que falló y causó el problema.
  5. Compruebe el motivo de los errores durante la configuración.
  6. Si el error se produjo debido a una configuración incorrecta, corrija la configuración.

Archivos JSON de ejemplo

Este tema contiene archivos JSON de ejemplo para la configuración de proceso de Spinnaker y la configuración de Canary automatizada. Estos archivos se pueden utilizar como referencia al crear un proceso de Spinnaker y una configuración automatizada Canary.

Un archivo JSON de ejemplo para la configuración de proceso de Spinnaker**

{
  "appConfig": {},
  "description": "This pipeline deploys a canary version of the application, and a baseline (identical to production) version.\nIt compares them, and if the canary is OK, it triggers the production deployment pipeline.",
  "executionEngine": "v2",
  "expectedArtifacts": [
    {
      "defaultArtifact": {
        "kind": "custom"
      },
      "id": "ac842617-988f-48dc-a7a4-7f020d93cc42",
      "matchArtifact": {
        "kind": "docker",
        "name": "index.docker.io/sample/demo",
        "type": "docker/image"
      },
      "useDefaultArtifact": false,
      "usePriorExecution": false
    }
  ],
  "keepWaitingPipelines": false,
  "lastModifiedBy": "anonymous",
  "limitConcurrent": true,
  "parallel": true,
  "parameterConfig": [],
  "stages": [
    {
      "account": "my-kubernetes-account",
      "cloudProvider": "kubernetes",
      "kinds": [
        "Deployment",
        "ConfigMap"
      ],
      "labelSelectors": {
        "selectors": [
          {
            "key": "version",
            "kind": "EQUALS",
            "values": [
              "canary"
            ]
          }
        ]
      },
      "location": "default",
      "name": "Delete Canary",
      "options": {
        "cascading": true
      },
      "refId": "12",
      "requisiteStageRefIds": [
        "19",
        "26"
      ],
      "type": "deleteManifest"
    },
    {
      "account": "my-kubernetes-account",
      "cloudProvider": "kubernetes",
      "kinds": [
        "Deployment"
      ],
      "labelSelectors": {
        "selectors": [
          {
            "key": "version",
            "kind": "EQUALS",
            "values": [
              "baseline"
            ]
          }
        ]
      },
      "location": "default",
      "name": "Delete Baseline",
      "options": {
        "cascading": true
      },
      "refId": "13",
      "requisiteStageRefIds": [
        "19",
        "26"
      ],
      "type": "deleteManifest"
    },
    {
      "name": "Successful deployment",
      "preconditions": [],
      "refId": "14",
      "requisiteStageRefIds": [
        "12",
        "13"
      ],
      "type": "checkPreconditions"
    },
    {
      "application": "sampleapplicaion",
      "expectedArtifacts": [
        {
          "defaultArtifact": {
            "kind": "custom"
          },
          "id": "9185c756-c6cd-49bc-beee-e3f7118f3412",
          "matchArtifact": {
            "kind": "docker",
            "name": "index.docker.io/sample/demo",
            "type": "docker/image"
          },
          "useDefaultArtifact": false,
          "usePriorExecution": false
        }
      ],
      "failPipeline": true,
      "name": "Deploy to Production",
      "pipeline": "7048e5ac-2464-4557-a05a-bec8bdf868fc",
      "refId": "19",
      "requisiteStageRefIds": [
        "25"
      ],
      "stageEnabled": {
        "expression": ""${ #stage('Canary Analysis')['status'].toString() == 'SUCCEEDED'}"",
        "type": "expression"
      },
      "type": "pipeline",
      "waitForCompletion": true
    },
    {
      "account": "my-kubernetes-account",
      "cloudProvider": "kubernetes",
      "manifestArtifactAccount": "embedded-artifact",
      "manifests": [
        {
          "apiVersion": "apps/v1",
          "kind": "Deployment",
          "metadata": {
            "labels": {
              "name": "sampleapplicaion-prod",
              "version": "baseline"
            },
            "name": "sampleapplicaion-baseline-deployment",
            "namespace": "default"
          },
          "spec": {
            "replicas": 4,
            "strategy": {
              "rollingUpdate": {
                "maxSurge": 10,
                "maxUnavailable": 10
              },
              "type": "RollingUpdate"
            },
            "template": {
              "metadata": {
                "labels": {
                  "name": "sampleapplicaion-prod"
                }
              },
              "spec": {
                "containers": [
                  {
                    "image": "index.docker.io/sample/demo:v1",
                    "imagePullPolicy": "Always",
                    "name": "sampleapplicaion-prod",
                    "ports": [
                      {
                        "containerPort": 8080,
                        "name": "port-8080"
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      ],
      "moniker": {
        "app": "sampleapplicaion"
      },
      "name": "Deploy Baseline",
      "refId": "20",
      "relationships": {
        "loadBalancers": [],
        "securityGroups": []
      },
      "requisiteStageRefIds": [],
      "source": "text",
      "type": "deployManifest"
    },
    {
      "account": "my-kubernetes-account",
      "cloudProvider": "kubernetes",
      "manifestArtifactAccount": "embedded-artifact",
      "manifests": [
        {
          "apiVersion": "apps/v1",
          "kind": "Deployment",
          "metadata": {
            "labels": {
              "name": "sampleapplicaion-prod",
              "version": "canary"
            },
            "name": "sampleapplicaion-canary-deployment",
            "namespace": "default"
          },
          "spec": {
            "replicas": 4,
            "strategy": {
              "rollingUpdate": {
                "maxSurge": 10,
                "maxUnavailable": 10
              },
              "type": "RollingUpdate"
            },
            "template": {
              "metadata": {
                "labels": {
                  "name": "sampleapplicaion-prod"
                }
              },
              "spec": {
                "containers": [
                  {
                    "image": "index.docker.io/sample/demo",
                    "imagePullPolicy": "Always",
                    "name": "sampleapplicaion-prod",
                    "ports": [
                      {
                        "containerPort": 8080,
                        "name": "port-8080"
                      }
                    ]
                  }
                ]
              }
            }
          }
        }
      ],
      "moniker": {
        "app": "sampleapplicaion"
      },
      "name": "Deploy Canary",
      "refId": "21",
      "relationships": {
        "loadBalancers": [],
        "securityGroups": []
      },
      "requiredArtifactIds": [
        "ac842617-988f-48dc-a7a4-7f020d93cc42"
      ],
      "requisiteStageRefIds": [],
      "source": "text",
      "type": "deployManifest"
    },
    {
      "analysisType": "realTime",
      "canaryConfig": {
        "beginCanaryAnalysisAfterMins": "2",
        "canaryAnalysisIntervalMins": "",
        "canaryConfigId": "7bdb4ab4-f933-4a41-865f-6d3e9c786351",
        "combinedCanaryResultStrategy": "LOWEST",
        "lifetimeDuration": "PT0H5M",
        "metricsAccountName": "my-prometheus",
        "scopes": [
          {
            "controlLocation": "default",
            "controlScope": "k8s-sampleapplicaion.default.80.k8s-sampleapplicaion.default.8080.svc-baseline",
            "experimentLocation": "default",
            "experimentScope": "k8s-sampleapplicaion.default.80.k8s-sampleapplicaion.default.8080.svc-canary",
            "extendedScopeParams": {},
            "scopeName": "default"
          }
        ],
        "scoreThresholds": {
          "marginal": "0",
          "pass": "70"
        },
        "storageAccountName": "kayenta-minio"
      },
      "name": "Canary Analysis",
      "refId": "25",
      "requisiteStageRefIds": [
        "20",
        "21"
      ],
      "type": "kayentaCanary"
    },
    {
      "continuePipeline": false,
      "failPipeline": true,
      "job": "NJob",
      "master": "master",
      "name": "Auto Cleanup:  GCR Image and code revert",
      "parameters": {},
      "refId": "26",
      "requisiteStageRefIds": [
        "25"
      ],
      "stageEnabled": {
        "type": "expression"
      },
      "type": "jenkins"
    }
  ],
  "triggers": [
    {
      "account": "my-docker-registry",
      "enabled": true,
      "expectedArtifactIds": [
        "ac842617-988f-48dc-a7a4-7f020d93cc42"
      ],
      "organization": "sample",
      "payloadConstraints": {},
      "registry": "index.docker.io",
      "repository": "sample/demo",
      "source": "dockerhub",
      "type": "webhook"
    }
  ],
  "updateTs": "1553144362000"
}
<!--NeedCopy-->

Un archivo JSON de muestra para la configuración automática de Canary

A continuación se muestra un archivo JSON de ejemplo para la configuración automática de Canary.

{
  "applications": [
    "sampleapplicaion"
  ],
  "classifier": {
    "groupWeights": {
      "Group 1": 70,
      "Group 2": 30
    },
    "scoreThresholds": {
      "marginal": 75,
      "pass": 95
    }
  },
  "configVersion": "1",
  "createdTimestamp": 1552650414234,
  "createdTimestampIso": "2019-03-15T11:46:54.234Z",
  "description": "Canary Config",
  "judge": {
    "judgeConfigurations": {},
    "name": "NetflixACAJudge-v1.0"
  },
  "metrics": [
    {
      "analysisConfigurations": {
        "canary": {
          "direction": "increase"
        }
      },
      "groups": [
        "Group 1"
      ],
      "name": "Server Response Errors - 5XX",
      "query": {
        "customFilterTemplate": "tot_requests",
        "metricName": "netscaler_lb_vserver_svr_busy_err_rate",
        "serviceType": "prometheus",
        "type": "prometheus"
      },
      "scopeName": "default"
    },
    {
      "analysisConfigurations": {
        "canary": {
          "direction": "either",
          "nanStrategy": "replace"
        }
      },
      "groups": [
        "Group 2"
      ],
      "name": "Server Response Latency - TTFB",
      "query": {
        "customFilterTemplate": "ttfb",
        "metricName": "netscaler_lb_vserver_hits_total",
        "serviceType": "prometheus",
        "type": "prometheus"
      },
      "scopeName": "default"
    }
  ],
  "name": "canary-config",
  "templates": {
    "tot_requests": "lb_vserver_name = "${scope}"",
    "ttfb": "lb_vserver_name = "${scope}""
  },
  "updatedTimestamp": 1553098513495,
  "updatedTimestampIso": "2019-03-20T16:15:13.495Z"
}
<!--NeedCopy-->

Implementación Canary simplificada mediante anotaciones de entrada

En este tema se proporciona información sobre la implementación simplificada de Canary mediante anotaciones de Ingress. Si bien Citrix ofrece varias opciones para admitir la implementación de Canary, este es un tipo más simple de implementación de Canary.

Canary que utiliza anotaciones de Ingress es una implementación de Canary basada en reglas. En este enfoque, debe definir un objeto Ingress adicional con anotaciones específicas para indicar que la solicitud de la aplicación debe servirse en función de la estrategia de implementación Canary basada en reglas. En la solución Citrix, la redirección de tráfico basada en Canary en el nivel de entrada se puede lograr definiendo varios conjuntos de reglas de la siguiente manera:

  • Aplicar las reglas Canary en función del peso
  • Aplicar las reglas Canary en función del encabezado de solicitud HTTP
  • Aplicar las reglas Canary en función del valor del encabezado HTTP

El orden de precedencia de las reglas Canary es el siguiente:

Valor de encabezado de solicitud Canary by HTTP —> Canary por encabezado de solicitud HTTP -> Canary por peso

Implementación Canary basada en el peso

La implementación Canary basada en el peso es un enfoque de implementación Canary ampliamente utilizado. En este enfoque, puede establecer el peso como un intervalo de 0 a 100, que decide el porcentaje de tráfico que se dirigirá a la versión Canary y la versión de producción de una aplicación.

A continuación se presenta el flujo de trabajo para la implementación de Canary basada en peso:

  • Inicialmente, el peso se puede establecer en cero, lo que indica que el tráfico no se reenvía a la versión Canary.

  • Una vez que decida iniciar la implementación de Canary, cambie el peso al porcentaje requerido para asegurarse de que el tráfico también se dirija a la versión Canary.

  • Finalmente, cuando determine que la versión Canary está lista para ser lanzada, cambie el peso a 100 para asegurarse de que todo el tráfico se dirija a la versión Canary.

Para implementar Canary basado en peso con el Citrix Ingress Controller, cree un nuevo Ingress con una anotación Canary ingress.citrix.com/canary-weight: y especifique el porcentaje de tráfico que se dirigirá a la versión Canary.

Implementación de Canary basada en el encabezado de solicitud HTTP

Puede configurar la implementación de Canary en función del encabezado de solicitud HTTP que controlan los clientes. El encabezado de la solicitud notifica a Ingress para redirigir la solicitud al servicio especificado en el Ingress Canary. Cuando el encabezado de la solicitud contiene el valor mencionado en la anotación Ingress ingress.citrix.com/canary-by-header:, la solicitud se redirige al servicio especificado en el Ingress Canary.

Implementación de Canary basada en el valor del encabezado de solicitud HTTP

También puede configurar la implementación Canary en función de los valores del encabezado de solicitud HTTP, que es una extensión Canary por encabezado. En esta implementación, junto con la anotación ingress.citrix.com/canary-by-header:, también se especifica la anotación ingress.citrix.com/canary-by-header-value:. Cuando el valor del encabezado de la solicitud coincide con el valor especificado en la anotación Ingress ingress.citrix.com/canary-by-header-value:, la solicitud se redirige al servicio especificado en el Ingress Canary. Puede especificar varios valores de encabezado como una lista de cadenas.

A continuación se muestra una anotación de muestra para la implementación Canary basada en los valores del encabezado de la solicitud HTTP:

ingress.citrix.com/canary-by-header-value: ‘[“valor1”,”valor2”,”valor3”,”valor4”]’

Configurar la implementación de Canary mediante anotaciones de Ingress

Realice los siguientes pasos para implementar una aplicación de muestra como una versión Canary.

  1. Implemente el Citrix Ingress Controller siguiendo los pasos de implementar el Citrix Ingress Controller. Puede implementar el Citrix Ingress Controller como un sidecar con Citrix ADC CPX o como un pod independiente que controla Citrix ADC VPX o MPX.

  2. Implemente la aplicación Guestbook mediante el archivo guestbook-deploy.yaml.

    kubectl apply -f guestbook-deploy.yaml
    
  3. Implemente un servicio para exponer la aplicación Guestbook mediante el archivo guestbook-service.yaml.

    kubectl apply -f guestbook-service.yaml
    
  4. Implemente el objeto Ingress para la aplicación Guestbook mediante el archivo guestbook-ingress.yaml.

      kubectl apply -f  guestbook-ingress.yaml
    
  5. Implemente una versión Canary de la aplicación Guestbook mediante el archivo canary-deployment.yaml.

        kubectl apply –f canary-deployment.yaml
    
  6. Implemente un servicio para exponer la versión Canary de la aplicación Guestbook mediante el archivo canary-service.yaml.

        kubectl apply –f canary-service.yaml       
    
  7. Implemente un objeto Ingress con anotaciones para la versión Canary de la aplicación Guestbook mediante el archivo canary-ingress.yaml.

        kubectl apply –f canary-ingress.yaml
    
    
    
          apiVersion: networking.k8s.io/v1
          kind: Ingress
          metadata:
            annotations:
              ingress.citrix.com/canary-weight: "10"
              kubernetes.io/ingress.class: citrix
            name: canary-by-weight
          spec:
            rules:
            - host: webapp.com
              http:
                paths:
                - backend:
                    service:
                      name: guestbook-canary
                      port:
                        number: 80
                  path: /
                  pathType: Prefix
    

    Here, the annotation ingress.citrix.com/canary-weight: “10” is the annotation for the weight based canary. This annotation specifies the Citrix ingress controller to configure the Citrix ADC in such a way that 10 percent of the total requests destined to webapp.com is sent to the guestbook-canary service. This is the service for the canary version of the Guestbook application.

Para implementar el archivo Canary basado en encabezado HTTP mediante el Citrix Ingress Controller, reemplace la anotación ingress.citrix.com/canary-weight: Canary por la anotación ingress.citrix.com/canary-by-header: en el archivo canary-ingress.yaml.

Para implementar el valor de encabezado HTTP basado en Canary mediante el Citrix Ingress Controller, reemplace la anotación ingress.citrix.com/canary-weight: con ingress.citrix.com/canary-by-header-value: las anotaciones ingress.citrix.com/canary-by-header: y en el archivo canary-ingress.yaml.

Nota:

Puede ver los YAML de ejemplo de Canary para lograr Canary según el encabezado y Canary según el valor del encabezado.

Implementar la solución de implementación de Canary integrada en Citrix ADC