Implementa una app de servidor web alojada en contenedores

En este instructivo, se describe cómo subir una aplicación de contenedor en un entorno de dispositivo aislado de Google Distributed Cloud (GDC) y ejecutar esa aplicación en el entorno del dispositivo. Aprenderás a crear proyectos de Harbor, subir imágenes a Harbor y crear cargas de trabajo como parte de este instructivo. Una carga de trabajo en contenedores se ejecuta dentro de un espacio de nombres del proyecto.

El entorno de 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 instructivo, se usa una app de servidor web de muestra disponible en el Google Cloud Artifact Registry.

Objetivos

  • Enviar una imagen de contenedor al registro de Harbor administrado
  • Implementar la app de contenedor de muestra en el clúster

Antes de comenzar

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

  2. Configura el espacio de nombres del proyecto como una variable de entorno:

    export NAMESPACE=PROJECT_NAMESPACE
    
  3. Descarga y, luego, instala la CLI de gdcloud.

  4. Pídele al administrador de IAM de tu organización que te otorgue los siguientes roles:

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

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

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

  5. Accede al clúster de Kubernetes y genera su archivo kubeconfig con una identidad de usuario. Asegúrate de configurar la ruta de kubeconfig como una variable de entorno:

    export KUBECONFIG=CLUSTER_KUBECONFIG
    

Crea un proyecto de Harbor en el registro

GDC proporciona Harbor como servicio, que es un servicio completamente administrado que te permite almacenar y administrar imágenes de contenedores con Harbor.

Para usar Harbor como servicio, debes crear un proyecto de Harbor dentro de la instancia de registro tear-harbor para administrar tus imágenes de contenedores:

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

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

    El resultado es similar a harbor-1.org-1.zone1.google.gdc.test.

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

    export INSTANCE_URL=INSTANCE_URL
    

    Ingresa la URL de la instancia sin el prefijo https://.

  3. Antes de crear el proyecto, debes acceder a Harbor con la URL del paso anterior. Usa un navegador para abrir esta URL y acceder a la instancia de Harbor.

  4. Crea el proyecto de Harbor:

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

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

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

    export HARBOR_PROJECT=HARBOR_PROJECT
    

Configura el Docker

Para usar Docker en tu registro de Harbor, completa los siguientes pasos:

  1. Configura Docker para que confíe en Harbor como servicio. Para obtener más información, consulta Configura 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 Configura la autenticación de Docker en instancias de registro de Harbor.

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

    1. Pídele 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 aislado. Por lo general, el archivo se almacena en el plano de control como un secreto con el nombre trust-store-internal-only en el espacio de nombres anthos-creds.
    2. De manera similar al paso anterior, crea una carpeta con el nombre de la URL externa del clúster de Harbor y guarda el archivo .crt dentro de la carpeta.

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

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

  1. Agrega una cuenta de robot del proyecto de Harbor. Sigue los pasos de la IU 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 nuevo nombre de la cuenta del proyecto de robot, que tiene la siguiente sintaxis:

    <PREFIX><PROJECT_NAME>+<ACCOUNT_NAME>
    

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

    Para obtener más información sobre cómo encontrar el nombre de la cuenta del 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. Accede a Docker con la cuenta de robot del proyecto de Harbor y el token secreto:

    docker login ${INSTANCE_URL}
    

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

  4. Establece un nombre arbitrario para el secreto de extracción de imágenes:

    export SECRET=SECRET
    
  5. Crea el secreto que se requiere para la extracción de imágenes:

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

    Reemplaza lo siguiente:

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

Envía la imagen de contenedor al registro de Harbor administrado

Para este instructivo, descargarás y enviarás la imagen del servidor web nginx al registro de Harbor administrado y la usarás para implementar una app de servidor web nginx de muestra en un clúster de Kubernetes. La app de servidor web nginx está disponible en el público Google Cloud Artifact Registry.

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

    docker pull gcr.io/cloud-marketplace/google/nginx:1.25
    
  2. Establece 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 administrado:

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

Implementa la app de contenedor de muestra

Ahora tienes todo listo para implementar la imagen de contenedor nginx en el clúster del dispositivo.

Kubernetes representa las aplicaciones como recursos Pod, que son unidades escalables que contienen uno o más contenedores. Un pod es la unidad más pequeña que se puede implementar en Kubernetes. Por lo general, implementas los pods como un conjunto de réplicas que se pueden escalar y distribuir juntas en el clúster. Una forma de implementar un conjunto de réplicas es mediante una Deployment de Kubernetes.

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

Implementa 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 si la implementación creó los pods:

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

    El resultado es similar a este:

    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
    

¿Qué sigue?

  • Lee la documentación de contenedores para obtener información sobre cómo administrar contenedores.