Desplegar una aplicación de servidor web en un contenedor

En este tutorial se describe cómo subir una aplicación de contenedor en un entorno de dispositivo aislado de Google Distributed Cloud (GDC) y ejecutarla en ese entorno. En este tutorial, aprenderás a crear proyectos de Harbor, subir imágenes a Harbor y crear cargas de trabajo. Una carga de trabajo contenerizada se ejecuta en un espacio de nombres de proyecto.

El entorno del dispositivo aislado de GDC incluye un registro de Harbor preconfigurado llamado tear-harbor en un proyecto de GDC llamado tear. Usarás este registro en este ejemplo.

En este tutorial se usa una aplicación de servidor web de ejemplo disponible en Google CloudArtifact Registry.

Objetivos

  • Envía una imagen de contenedor al registro de Harbor gestionado.
  • Despliega la aplicación de contenedor de ejemplo en el clúster.

Antes de empezar

  1. Asegúrate de tener un proyecto para gestionar tus implementaciones en contenedores. Crea un proyecto si no tienes ninguno.

  2. Define el espacio de nombres de tu proyecto como una variable de entorno:

    export NAMESPACE=PROJECT_NAMESPACE
    
  3. Descarga e instala la CLI de gdcloud.

  4. Pide al administrador de gestión de identidades y accesos de tu organización que te conceda los siguientes roles:

    • Rol de administrador de espacio de nombres (namespace-admin) para el espacio de nombres de tu proyecto. Este rol es necesario para desplegar cargas de trabajo de contenedores en tu proyecto.

    • Rol de lector de instancias de Harbor (harbor-instance-viewer) para el espacio de nombres de tu proyecto. Este rol es necesario para ver y seleccionar una instancia de Harbor.

    • Rol Creador de proyectos de Harbor (harbor-project-creator) para el espacio de nombres de tu proyecto. Este rol es necesario para acceder a un proyecto de Harbor y gestionarlo.

  5. Inicia sesión en el clúster de Kubernetes y genera su archivo kubeconfig con una identidad de usuario. Asegúrate de definir la ruta de kubeconfig como variable de entorno:

    export KUBECONFIG=CLUSTER_KUBECONFIG
    

Crear un proyecto de Harbor en el registro

GDC proporciona Harbor como servicio, que es un servicio totalmente gestionado que te permite almacenar y gestionar imágenes de contenedor con Harbor.

Para usar Harbor como servicio, debes crear un proyecto de Harbor en la instancia del registro tear-harbor para gestionar tus imágenes de contenedor:

  1. Necesitas la URL de tear-harbor. Lista la URL de la instancia:

    gdcloud harbor instances describe tear-harbor --project=tear
    

    La salida es similar a harbor-1.org-1.zone1.google.gdc.test.

  2. Define la URL de la instancia como una variable para usarla más adelante en el tutorial:

    export INSTANCE_URL=INSTANCE_URL
    
  3. Antes de crear el proyecto, debes iniciar sesión en Harbor con la URL del paso anterior. Usa un navegador para abrir esta URL e iniciar sesión en la instancia de Harbor.

  4. Crea el proyecto de Harbor:

    gdcloud harbor harbor-projects create HARBOR_PROJECT \
        --project=tear \
        --instance=tear-harbor
    

    Sustituye HARBOR_PROJECT por el nombre del proyecto de Harbor que quieras crear. No puedes crear el proyecto de Harbor en ningún espacio de nombres de proyecto. Debes usar el proyecto tear.

  5. Define el nombre del proyecto de Harbor como una variable para usarla más adelante en el tutorial:

    export HARBOR_PROJECT=HARBOR_PROJECT
    

Configurar Docker

Para usar Docker en tu registro de Harbor, sigue estos pasos:

  1. Configura Docker para que confíe en Harbor como servicio. Para obtener más información, consulta Configurar Docker para que confíe en la CA raíz de Harbor.

  2. Configura la autenticación de Docker en Harbor. Para obtener más información, consulta Configurar la autenticación de Docker en instancias del registro de Harbor.

  3. Como tear-harbor es un registro de Harbor preconfigurado, debes confiar en el certificado firmado por la CA interna aislada de Google Distributed Cloud:

    1. Pide a tu IO la siguiente información:

      1. la URL externa del clúster de Harbor.
      2. el archivo .crt de la CA interna de Google Distributed Cloud con air gap. El archivo se suele almacenar en el plano de control como un secreto con el nombre trust-store-internal-only en el espacio de nombres anthos-creds.
    2. Al igual que en el paso anterior, crea una carpeta con el nombre de la URL externa del clúster de Harbor y guarda el archivo .crt en ella.

Crear un secreto de extracción de imágenes de Kubernetes

Como estás usando un proyecto privado de Harbor, debes crear un secreto de extracción de imágenes de Kubernetes.

  1. Añade una cuenta de robot de proyecto de Harbor. Sigue los pasos que se indican en la interfaz de usuario de Harbor para crear la cuenta de robot y copiar el token secreto del robot: https://goharbor.io/docs/2.8.0/working-with-projects/project-configuration/create-robot-accounts/#add-a-robot-account.

  2. Anota el nombre de la nueva cuenta de proyecto de robot, que tiene la siguiente sintaxis:

    <PREFIX><PROJECT_NAME>+<ACCOUNT_NAME>
    

    Por ejemplo, el formato del nombre de la cuenta del proyecto del robot es similar a harbor@library+artifact-account.

    Para obtener más información sobre cómo encontrar el nombre de la cuenta de proyecto de robot en Harbor, consulta la documentación de Harbor: https://goharbor.io/docs/2.8.0/working-with-projects/project-configuration/create-robot-accounts/#view-project-robot-accounts.

  3. Inicia sesión en Docker con la cuenta de robot y el token secreto de tu proyecto de Harbor:

    docker login ${INSTANCE_URL}
    

    Cuando se te solicite, inserta el nombre de la cuenta de proyecto del robot para Username y el token secreto para Password.

  4. Asigna un nombre arbitrario al secreto de extracción de imágenes:

    export SECRET=SECRET
    
  5. Crea el secreto necesario para extraer la imagen:

    kubectl create secret docker-registry ${SECRET}  \
        --from-file=.dockerconfigjson=DOCKER_CONFIG \
        -n NAMESPACE
    

    Haz los cambios siguientes:

    • DOCKER_CONFIG: la ruta al archivo .docker/config.json.
    • NAMESPACE: el espacio de nombres del secreto que crees.

Enviar una imagen de contenedor a un registro de Harbor gestionado

En este tutorial, descargarás y enviarás la imagen del servidor web nginx al registro de Harbor gestionado y la usarás para desplegar una aplicación de servidor web nginx de ejemplo en un clúster de Kubernetes. La aplicación del servidor web nginx está disponible en el registro público Google Cloud Artifact Registry.

  1. Extrae la imagen nginx de Artifact Registry a tu estación de trabajo local mediante una red externa: Google Cloud

    docker pull gcr.io/cloud-marketplace/google/nginx:1.25
    
  2. Define el nombre de la imagen. El formato de un nombre de imagen completo es el siguiente:

    ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx
    
  3. Etiqueta la imagen local con el nombre del repositorio:

    docker tag gcr.io/cloud-marketplace/google/nginx:1.25 ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    
  4. Envía la imagen de contenedor nginx a tu registro de Harbor gestionado:

    docker push ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
    

Desplegar la aplicación de contenedor de ejemplo

Ahora ya puedes desplegar la imagen de contenedor nginx en el clúster del dispositivo.

Kubernetes representa las aplicaciones como Pod recursos, que son unidades escalables que contienen uno o varios contenedores. El pod es la unidad desplegable más pequeña de Kubernetes. Normalmente, los pods se implementan como un conjunto de réplicas que se pueden escalar y distribuir conjuntamente en el clúster. Una forma de desplegar un conjunto de réplicas es mediante un Deployment de Kubernetes.

En esta sección, crearás un Deployment de Kubernetes para ejecutar la aplicación de contenedor nginx en tu clúster. Este Deployment tiene réplicas o pods. Un pod Deployment contiene solo un contenedor: la imagen de contenedor nginx. También puedes crear un recurso Service que proporcione a los clientes una forma estable de enviar solicitudes a los pods de tu Deployment.

Despliega el servidor web nginx:

  1. Crea e implementa los recursos personalizados Deployment y Service de Kubernetes:

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nginx-deployment
      labels:
        app: nginx
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: nginx
      template:
        metadata:
          labels:
            app: nginx
        spec:
          containers:
          - name: nginx
            image: ${INSTANCE_URL}/${HARBOR_PROJECT}/nginx:1.25
            ports:
            - containerPort: 80
          imagePullSecrets:
          - name: ${SECRET}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nginx-service
    spec:
      selector:
        app: nginx
      ports:
        - port: 80
          protocol: TCP
      type: LoadBalancer
    EOF
    
  2. Verifica que el despliegue haya creado los pods:

    kubectl get pods -l app=nginx -n ${NAMESPACE}
    

    El resultado debería ser similar al siguiente:

    NAME                                READY     STATUS    RESTARTS   AGE
    nginx-deployment-1882529037-6p4mt   1/1       Running   0          1h
    nginx-deployment-1882529037-p29za   1/1       Running   0          1h
    nginx-deployment-1882529037-s0cmt   1/1       Running   0          1h
    
  3. Crea una política de red para permitir todo el tráfico de red al espacio de nombres:

    kubectl --kubeconfig ${KUBECONFIG} -n ${NAMESPACE} \
    create -f - <<EOF
    apiVersion: networking.k8s.io/v1
    kind: NetworkPolicy
    metadata:
      annotations:
      name: allow-all
    spec:
      ingress:
      - from:
        - ipBlock:
            cidr: 0.0.0.0/0
      podSelector: {}
      policyTypes:
      - Ingress
    EOF
    
  4. Exporta la dirección IP del servicio nginx:

      export IP=`kubectl --kubeconfig=${KUBECONFIG} get service nginx-service \
          -n ${NAMESPACE} -o jsonpath='{.status.loadBalancer.ingress[*].ip}'`
    
  5. Prueba la dirección IP del servidor nginx con curl:

      curl http://$IP
    

Siguientes pasos