Proxy de frontend con Nginx

En esta página, se muestra cómo usar NGINX como proxy de frontend para el contenedor de tu aplicación. Esto es útil si deseas procesar solicitudes o respuestas. Puedes agregar compresión gzip o traducir HTTP/2 a HTTP/1 si los contenedores de tu aplicación solo admiten HTTP/1 y necesitas usar HTTP/2 de extremo a extremo por razones de rendimiento.

En el ejemplo proporcionado en esta página, un contenedor Nginx se ejecuta en cada instancia de Cloud Run como el contenedor de entrega principal y está configurado para reenviar solicitudes al contenedor de la aplicación, que se ejecuta. como un contenedor de sidecar, como se muestra en este diagrama:

Cloud Run: mc hello nginx 1

La forma más eficaz de realizar un proxy de frontend en Cloud Run es implementar el contenedor del servidor proxy del servidor Nginx y el contenedor de la app web como un único servicio de Cloud Run:

Cloud Run: mc hello nginx 2

Este único servicio de Cloud Run acepta solicitudes y las entrega al contenedor de entrada (entrega), que en este caso es el servidor proxy. Luego, el servidor proxy envía solicitudes a la app web a través de la interfaz de red localhost, lo que evita cualquier red externa.

La implementación como un solo servicio de Cloud Run reduce las latencias, la sobrecarga de administración de servicios y elimina la exposición a las redes externas. Cloud Run no interactúa directamente con los contenedores de sidecar, excepto cuando se inician o se detienen cada vez que se inicia o se detiene el servicio.

El contenedor de la app web y cualquier contenedor de sidecar pueden escribirse en diferentes lenguajes de programación. Para ver una muestra escrita en PHP, consulta la muestra de nginx de PHP en GitHub.

Antes de comenzar

  1. Sign in to your Google Cloud account. If you're new to Google Cloud, create an account to evaluate how our products perform in real-world scenarios. New customers also get $300 in free credits to run, test, and deploy workloads.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  3. Make sure that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Go to project selector

  5. Make sure that billing is enabled for your Google Cloud project.

  6. Enable the Cloud Run and Secret Manager APIs.

    Enable the APIs

  7. Instala e inicializa la CLI de gcloud
  8. Actualiza Google Cloud CLI: gcloud components update
  9. Configura Google Cloud CLI: gcloud init
  10. Realiza la autenticación con Google Cloud CLI: gcloud auth login

Permisos necesarios para realizar una implementación

Debes tener UNA de las siguientes funciones:

  • Los roles de administrador de Cloud Run y usuario de cuenta de servicio
  • Cualquier rol personalizado que incluya esta lista específica de permisos

Descripción general de la configuración

En estas instrucciones, se usan imágenes de contenedor compiladas previamente, por lo que lo único que se requiere para el proxy de frontend es configurar los contenedores y el servicio en sí.

Configura el contenedor de entrada de Nginx

La imagen de contenedor está nginx disponible en Docker Hub. Por lo general, está listo para usarse tal como está, excepto que debe configurarse para ejecutarse como un servicio de proxy y entregar las solicitudes de proxy al puerto en el que escucha el contenedor de sidecar en localhost. En el ejemplo de esta página, también se habilita la compresión gzip para solicitudes y respuestas.

La configuración se proporciona con un archivo de texto activado en /etc/nginx/conf.d/nginx.conf. Como no puedes editar archivos directamente en el contenedor, debes activar un volumen en /etc/nginx/conf.d/ que contenga el archivo de configuración. Una forma de activar un archivo en una ubicación específica en un contenedor que se ejecuta en Cloud Run es almacenar el contenido del archivo en un Secret de Secret Manager y activar ese Secret en la ubicación seleccionada.

Copia lo siguiente en un archivo llamado nginx.conf en el directorio actual de tu máquina local.


server {
    # Listen at port 8080
    listen 8080; 
    # Server at localhost
    server_name _;
    # Enables gzip compression to make our app faster
    gzip on;

    location / {
        # Passes initial requests to port 8080 to `hello` container at port 8888
        proxy_pass   http://127.0.0.1:8888;
    }
}

En la configuración, haz lo siguiente:

  • Asigna nginx para escuchar en el mismo puerto predeterminado de Cloud Run 8080, ubicado en localhost.
  • Aplica la compresión gzip para mejorar el rendimiento.
  • Indica a proxy_pass que entregue las solicitudes de este contenedor de entrada al contenedor de sidecar de la app web en el puerto localhost 8888.

Crea un Secret con el contenido del archivo nginx.conf.

Console

  1. Ve a la página de Secret Manager en la consola de Google Cloud:

    Ir a Secret Manager

  2. Haz clic en Crear secreto.

  3. En el campo de formulario name, ingresa nginx_config.

  4. Sube el archivo nginx.conf ubicado en multi-container/hello-nginx-sample/nginx.conf como el valor del Secret.

  5. Mantén los valores predeterminados (Google-managed encryption key, etc).

  6. Haz clic en Crear secreto.

  7. Otorga a la cuenta de servicio de procesamiento del proyecto acceso a este nuevo Secret. Para hacerlo, ve a la página de IAM en la consola de Google Cloud:

    Ir a IAM

  8. Localiza la cuenta de servicio principal con el nombre: Compute Engine default service account y haz clic en Editar principal.

  9. Haz clic en Agregar otro rol y selecciona Descriptor de acceso a secretos de Secret Manager.

  10. Haz clic en Guardar.

gcloud

  1. En una terminal, usa el siguiente comando para crear un nuevo Secret nginx_config en Secret Manager:

    gcloud secrets create nginx_config --replication-policy='automatic' --data-file='./nginx.conf'

  2. Otorga a la cuenta de servicio de procesamiento del proyecto acceso a este nuevo Secret mediante el comando

    export PROJECT_NUMBER=$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')
    gcloud secrets add-iam-policy-binding nginx_config --member=serviceAccount:$PROJECT_NUMBER-compute@developer.gserviceaccount.com --role='roles/secretmanager.secretAccessor'

  3. Ejecuta gcloud secrets list para verificar que se creó el Secret.

Acerca de la imagen de muestra del sidecar de la app web

En estas instrucciones, se usa la imagen de contenedor de muestra en us-docker.pkg.dev/cloudrun/container/hello. Debes especificar el número de puerto en el que el contenedor escuchará y localhost como el host, como se describe en Especifica la configuración del contenedor de sidecar, como se describe en las siguientes secciones.

Configura el servicio de varios contenedores

Puedes usar la consola de Google Cloud o el archivo YAML de Cloud Run para configurar un servicio de Cloud Run con más de un contenedor.

En la configuración del servicio, especifica el servidor proxy Nginx como contenedor de entrada (entrega), el puerto que escuchará, si acepta solicitudes HTTP 1 o HTTP 2 y el orden de inicio del contenedor. El contenedor de entrada (servidor proxy) depende del sidecar de la app web, por lo que primero se debe iniciar el sidecar de la app web.

Estas configuraciones se muestran en las siguientes secciones.

Agrega metadatos YAML

Console

Navega a Implementa el servicio para obtener instrucciones completas de la consola.

YAML

  1. Si creas un servicio nuevo, omite este paso. Si actualizas un servicio existente, descarga su configuración de YAML:

    gcloud run services describe SERVICE --format export > service.yaml
  2. En service.yaml, agrega lo siguiente:

    metadata:
      name: "MC_SERVICE_NAME"
      labels:
        cloud.googleapis.com/location: "REGION"
      annotations:
        # Required to use Cloud Run multi-containers (preview feature)
        run.googleapis.com/launch-stage: BETA
        run.googleapis.com/description: sample tutorial service
        # Externally available
        run.googleapis.com/ingress: all

La sección describe la revisión del servicio, que incluye propiedades que pueden variar de una revisión a otra.

Especifica el orden de inicio del contenedor

Console

Navega a Implementa el servicio para obtener instrucciones completas de la consola.

YAML

En service.yaml, agrega lo siguiente:

spec:
  template:
    metadata:
      annotations:
        # Defines container startup order within multi-container service.
        # Below requires hello container to spin up before nginx container,
        # which depends on the hello container.
        # https://cloud.google.com/run/docs/configuring/containers#container-ordering
        run.googleapis.com/container-dependencies: "{nginx: [hello]}"

Ten en cuenta la anotación container-dependencies que le indica a Cloud Run que espere a que el contenedor hello se inicie antes de iniciar el contenedor nginx. De lo contrario, si el contenedor nginx se inicia primero, podría intentar enviar una solicitud web mediante un proxy al contenedor de app web que no está listo, lo que generaría respuestas de error web.

De forma opcional, cada contenedor puede tener una propiedad de nombre definida para él, que se puede usar para hacer referencia a él en otras directivas. El contenedor de entrega ejecuta el servidor proxy, llamado nginx. Este es el contenedor al que Cloud Run entrega las solicitudes entrantes, por lo que debes especificar la versión de HTTP y el puerto del contenedor para entregarlas.

Especifica la configuración del contenedor de entrega

Console

Navega a Implementa el servicio para obtener instrucciones completas de la consola.

YAML

En el archivo service.yaml, agrega lo siguiente:

spec:
  containers:
    # A) Serving ingress container "nginx" listening at PORT 8080
    # Main entrypoint of multi-container service.
    # Source is stored in nginx_config secret in Secret Manager.
    # Any pings to this container will proxy over to hello container at PORT 8888.
    # https://cloud.google.com/run/docs/container-contract#port
    - image: nginx
      name: nginx
      ports:
        - name: http1
          containerPort: 8080
      resources:
        limits:
          cpu: 500m
          memory: 256Mi
      # Referencing declared volume below,
      # Declaring volume to mount in current ingress container's filesystem
      # https://cloud.google.com/run/docs/reference/rest/v2/Container#volumemount
      volumeMounts:
        - name: nginx-conf-secret
          readOnly: true
          mountPath: /etc/nginx/conf.d/
      startupProbe:
        timeoutSeconds: 240
        periodSeconds: 240
        failureThreshold: 1
        tcpSocket:
          port: 8080

El servidor nginx requiere un archivo de configuración en el directorio /etc/nginx/conf.d/. Para ello, activa un volumen que contenga el archivo en esa ubicación. En la sección volumeMount, se especifica un volumen llamado configuration para que se coloque allí. El volumen se define en su propia sección más adelante en el archivo.

Especifica la configuración del contenedor del sidecar

Console

Navega a Implementa el servicio para obtener instrucciones completas de la consola.

YAML

En service.yaml, agrega lo siguiente:

- image: us-docker.pkg.dev/cloudrun/container/hello
  name: hello
  env:
    - name: PORT
      value: "8888"
  resources:
    limits:
      cpu: 1000m
      memory: 512Mi
  startupProbe:
    timeoutSeconds: 240
    periodSeconds: 240
    failureThreshold: 1
    tcpSocket:
      port: 8888

La aplicación hello también necesita información de configuración. Detecta las solicitudes entrantes en el puerto que se especifica en la variable de entorno PORT. Ese nombre y valor se especifican en la sección env.

Especifica el volumen del secreto

Console

Navega a Implementa el servicio para obtener instrucciones completas de la consola.

YAML

En el archivo service.yaml, agrega lo siguiente:

volumes:
  - name: nginx-conf-secret
    secret:
      secretName: nginx_config
      items:
        - key: latest
          path: default.conf

Especifica la configuración volume activada en la sección volumeMount. Contiene un solo archivo llamado nginx.conf cuyo contenido se define como el valor del Secret llamado nginx-conf-secret.

Implemente el servicio

Console

  1. Ve a la página de Cloud Run en la consola de Google Cloud.

    Ir a Cloud Run

  2. Haz clic en Desplegar contenedor y selecciona Servicio para mostrar el formulario Crear servicio.

    1. Selecciona Implementar una revisión desde una imagen de contenedor existente y luego, ingresa nginx como URL de imagen de contenedor.
    2. En el campo Nombre del servicio, ingresa un nombre para tu servicio, por ejemplo, hello-mc.
    3. En la lista Región, selecciona una ubicación en la que deseas realizar la implementación, por ejemplo, us-west1.
    4. En Autenticación, selecciona Allow unauthenticated invocations. Si no tienes permisos (rol de administrador de Cloud Run) para seleccionar esta opción, el servicio se implementará y requerirá autenticación.
  3. Haz clic en Contenedores, volúmenes, herramientas de redes y seguridad para expandir el formulario de configuración.

    1. Haz clic en la pestaña Volúmenes.
    2. Haz clic en Agregar volumen.
    3. En la lista Tipo de volumen, selecciona Secreto.
    4. En el campo Nombre del volumen, ingresa nginx-conf-secret.
    5. En el campo Secret, ingresa nginx_config.
    6. En Rutas especificadas para las versiones de Secret, especifica default.conf como la ruta y latest como la versión.
    7. Haz clic en Crear para crear el volumen del secreto.
  4. Haz clic en la pestaña Contenedores para mostrar el formulario Editar contenedor.

    1. Haz clic en Configuración, luego en Recursos, cambia la memoria a 256MiB y CPU a 1 CPU.
    2. Haz clic en Activaciones de volúmenes.
    3. Haz clic en Volumen de activación.
    4. Selecciona nginx-conf-secret de la lista de nombres.
    5. En Ruta de activación, ingresa etc/nginx/conf.d.
    6. Haz clic en Listo para completar la configuración del primer contenedor.
  5. Haz clic en Agregar contenedor para agregar el contenedor de sidecar y mostrar el formulario Contenedor nuevo.

    1. Selecciona la URL de imagen de contenedor predeterminada us-docker.pkg.dev/cloudrun/container/hello
    2. Haz clic en la pestaña Configuración, luego en Recursos, cambia la memoria a 256MiB y CPU a 1 CPU.
    3. Haz clic en Variables y secretos.
    4. Haz clic en Agregar variable.
    5. Ingresa PORT como el nombre de la variable de entorno nueva y 8888 como el valor.
    6. Haz clic en Listo.
  6. Navega al formulario Editar contenedor del primer contenedor (nginx).

    1. Haz clic en la pestaña Configuración.
    2. En Orden de inicio del contenedor, selecciona nginx de la lista Depends on. Esto significa que el contenedor nginx se inicia sólo después de que se inicia correctamente el contenedor hello.
    3. Haz clic en Crear y espera a que se implemente el servicio.

gcloud

Para implementar el contenedor del servidor proxy y el contenedor de la app web como un solo servicio, haz lo siguiente:

gcloud run services replace service.yaml

Verifica el servicio implementado

gcloud

Para verificar que la implementación se realizó correctamente, copia la URL de Cloud Run generada y ábrela en un navegador, o usa este comando para enviar una solicitud autenticada:

curl --header "Authorization: Bearer $(gcloud auth print-identity-token)" 

Deberías recibir un proxy nginx que se haya transferido correctamente al contenedor de sidecar de hello con el estado de respuesta 200.

Pruébalo

Para continuar con este instructivo:

gcloud

  1. En una terminal, clona el repositorio de la app de ejemplo en tu máquina local:

    git clone https://github.com/GoogleCloudPlatform/cloud-run-samples

  2. Ve al directorio que contiene el código de muestra de Cloud Run:

    cd cloud-run-samples/multi-container/hello-nginx-sample/

¿Qué sigue?

Para explorar más sobre el uso de archivos adicionales en un servicio de Cloud Run: