Proxy de front-end usando Nginx

Nesta página, mostramos como usar o NGINX como proxy de front-end para seu contêiner de aplicativos. Isso é útil se você quer processar solicitações ou respostas. É possível adicionar compactação gzip ou converter HTTP/2 para HTTP/1 se os contêineres de seu aplicativo forem compatíveis apenas com HTTP/1 e você precisar usar o HTTP/2 de ponta a ponta para melhorar o desempenho.

No exemplo fornecido nesta página, um contêiner do Nginx é executado em todas as instâncias do Cloud Run como o contêiner de exibição principal e é configurado para encaminhar solicitações ao contêiner do aplicativo, que é executado como um contêiner de arquivo secundário, conforme mostrado neste diagrama:

Cloud Run mc hello nginx 1

A maneira mais eficaz de fazer o proxy da Internet no Cloud Run é implantar o contêiner do servidor proxy do servidor Nginx e o contêiner do app da Web como um único serviço do Cloud Run:

Cloud Run mc hello nginx 2

Esse único serviço do Cloud Run aceita solicitações e as entrega ao contêiner de entrada (exibição), que, nesse caso, é o servidor proxy. Em seguida, o servidor proxy envia solicitações para o app da Web pela interface de rede localhost, o que evita qualquer rede externa.

A implantação como um único serviço do Cloud Run reduz as latências, a sobrecarga de gerenciamento de serviços e elimina a exposição a redes externas. O Cloud Run não interage diretamente com os contêineres de arquivo secundário, exceto para iniciá-los ou interrompê-los sempre que o serviço for iniciado ou interrompido.

O contêiner do app da Web e os contêineres de arquivos secundários podem ser escritos em linguagens de programação diferentes. Para uma amostra escrita em PHP, consulte a amostra PHP nginx no GitHub.

Antes de começar

  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. Instale e inicialize a CLI gcloud.
  8. Atualize a CLI do Google Cloud: gcloud components update
  9. Configure a CLI do Google Cloud: gcloud init
  10. Autenticar com a CLI do Google Cloud: gcloud auth login

Permissões necessárias para implantar

Você precisa ter UM dos seguintes papéis:

Visão geral da configuração

Essas instruções usam imagens de contêiner pré-criadas. Portanto, o único requisito para o proxy de front-end é configurar os contêineres e o próprio serviço.

Configurar o contêiner de entrada do Nginx

A imagem do contêiner está nginx disponível no Docker Hub. O contêiner já está quase pronto para uso, mas precisa ser configurado para ser executado como um serviço de proxy, entregando as solicitações por proxy para a porta em que o contêiner do arquivo secundário está detectando em localhost. O exemplo nesta página também ativa a compactação gzip para solicitações e respostas.

A configuração é fornecida usando um arquivo de texto montado em /etc/nginx/conf.d/nginx.conf. Como não é possível editar arquivos diretamente no contêiner, é preciso ativar um volume em /etc/nginx/conf.d/ que contenha o arquivo de configuração. Uma maneira de montar um arquivo em um local específico em um contêiner em execução no Cloud Run é armazenar o conteúdo do arquivo em um secret do Secret Manager e montar esse secret no local selecionado.

Copie o seguinte em um arquivo chamado nginx.conf no diretório atual da 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;
    }
}

Na configuração, faça o seguinte:

  • Atribua nginx para detectar na mesma porta padrão 8080 do Cloud Run, localizada em localhost
  • Aplique a compactação gzip para melhorar o desempenho.
  • Instrua proxy_pass para enviar todas as solicitações para esse contêiner de entrada para o contêiner de arquivo secundário do app da Web na porta localhost 8888.

Crie um secret com o conteúdo do arquivo nginx.conf.

Console

  1. Acesse a página do Secret Manager no console do Google Cloud:

    Acessar o Secret Manager

  2. Clique em Criar secret.

  3. No campo do formulário name, insira nginx_config.

  4. Faça upload do arquivo nginx.conf localizado em multi-container/hello-nginx-sample/nginx.conf como o valor do secret.

  5. Mantenha os valores padrão (Google-managed encryption key, etc).

  6. Clique em Criar secret.

  7. Conceda à conta de serviço de computação do projeto acesso a esse novo secret. Para fazer isso, acesse a página IAM no console do Google Cloud:

    Acessar IAM

  8. Localize a conta de serviço principal com o nome: Compute Engine default service account e clique em Editar principal.

  9. Clique em Adicionar outro papel e selecione Acessador de secrets do Secret Manager.

  10. Clique em Salvar.

gcloud

  1. Em um terminal, use o seguinte comando para criar um novo secret nginx_config no Secret Manager:

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

  2. Conceda à conta de serviço de computação do projeto acesso a esse novo secret com o 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. Verifique se o secret foi criado executando gcloud secrets list.

Sobre a imagem de exemplo de arquivo secundário do app da Web

Estas instruções usam a imagem do contêiner de amostra em us-docker.pkg.dev/cloudrun/container/hello. É necessário especificar o número da porta que o contêiner vai detectar e localhost como o host, conforme descrito em Especificar a configuração do contêiner de arquivo secundário, conforme descrito nas seções a seguir.

Configurar o serviço de vários contêineres

É possível usar o console do Google Cloud ou o arquivo YAML do Cloud Run para configurar um serviço do Cloud Run com mais de um contêiner.

Na configuração do serviço, especifique o servidor proxy Nginx como contêiner de entrada (exibição), a porta na qual ele detectará, se aceita solicitações HTTP 1 ou HTTP 2 e a ordem inicial do contêiner. O contêiner de entrada (servidor proxy) depende do arquivo secundário do app da Web. Portanto, é necessário iniciar esse arquivo primeiro.

Essas configurações vão ser mostradas nas próximas seções.

Adicionar metadados YAML

Console

Navegue até Implantar o serviço para ver as instruções completas do console.

YAML

  1. Se você estiver criando um novo serviço, pule esta etapa. Se você estiver atualizando um serviço, faça o download da configuração YAML correspondente:

    gcloud run services describe SERVICE --format export > service.yaml
  2. Em service.yaml, inclua o seguinte:

    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

Esta seção descreve a revisão do serviço, incluindo propriedades que podem variar de uma revisão para outra.

Especificar a ordem de inicialização do contêiner

Console

Navegue até Implantar o serviço para ver as instruções completas do console.

YAML

Em service.yaml, anexe o seguinte:

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]}"

Observe a anotação container-dependencies que diz ao Cloud Run para aguardar a inicialização do contêiner hello antes de iniciar o contêiner nginx. Caso contrário, se o contêiner nginx começar primeiro, ele pode tentar fazer proxy de uma solicitação da Web para o contêiner do app da Web que não está pronto, o que geraria respostas de erro da Web.

Como alternativa, cada contêiner pode ter uma propriedade de nome definida, que pode ser usada para se referir a ele em outras diretivas. O contêiner de exibição executa o servidor proxy, chamado nginx. Este é o contêiner ao qual o Cloud Run envia solicitações de entrada. Portanto, você precisa especificar a versão de HTTP e a porta do contêiner para entregá-las.

Especificar a configuração do contêiner de exibição

Console

Navegue até Implantar o serviço para ver as instruções completas do console.

YAML

No arquivo service.yaml, anexe o seguinte:

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

O servidor nginx requer um arquivo de configuração no diretório /etc/nginx/conf.d/. Para fazer isso, monte um volume contendo o arquivo no local. A seção volumeMount especifica um volume chamado configuration a ser colocado lá. O próprio volume é definido em sua própria seção posteriormente no arquivo.

Especificar a configuração do contêiner de arquivo secundário

Console

Navegue até Implantar o serviço para ver as instruções completas do console.

YAML

Em service.yaml, anexe o seguinte:

- 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

O aplicativo hello também precisa de informações de configuração. Ele detecta solicitações de entrada na porta especificada na variável de ambiente PORT. O nome e o valor são especificados na seção env.

Especificar o volume do secret

Console

Navegue até Implantar o serviço para ver as instruções completas do console.

YAML

No arquivo service.yaml, anexe o seguinte:

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

Especifique a configuração volume ativada na seção volumeMount. Ela contém um único arquivo chamado nginx.conf, cujo conteúdo é definido como o valor do secret chamado nginx-conf-secret.

Implante o serviço

Console

  1. Acesse a página do Cloud Run no Console do Google Cloud.

    Acesse o Cloud Run

  2. Clique em Implantar contêiner e selecione Serviço para exibir o formulário Criar serviço.

    1. Selecione Implantar uma revisão de uma imagem de contêiner atual e insira nginx como URL da imagem do contêiner.
    2. No campo Nome do serviço, forneça um nome para o serviço, por exemplo, hello-mc.
    3. Na lista Região, selecione um local para implantar, por exemplo, us-west1.
    4. Em Autenticação, selecione Allow unauthenticated invocations. Se você não tiver permissões (função de administrador do Cloud Run) para selecionar essa opção, o serviço será implantado e exigirá autenticação.
  3. Clique em Contêiner(es), volumes, rede, segurança para expandir o formulário de configuração.

    1. Clique na guia Volumes.
    2. Clique em Adicionar volume.
    3. Na lista Tipo de volume, selecione Secret.
    4. No campo Nome do volume, digite nginx-conf-secret.
    5. No campo Secret, insira nginx_config.
    6. Em Caminhos especificados para versões de secret, especifique default.conf como o caminho e latest como a versão.
    7. Clique em Criar para criar o volume do secret.
  4. Clique na guia Contêineres para exibir o formulário Editar contêiner.

    1. Clique em Configurações e, em Recursos, altere a memória para 256MiB e a CPU para 1 CPU.
    2. Clique em Montagens de volumes.
    3. Clique em Montar volume.
    4. Selecione nginx-conf-secret na lista de nomes.
    5. Em Caminho de montagem, insira etc/nginx/conf.d.
    6. Clique em Concluído para finalizar a configuração do primeiro contêiner.
  5. Clique em Adicionar contêiner para incluir o contêiner do arquivo secundário e exibir o formulário Novo contêiner.

    1. Selecione o URL da imagem do contêiner padrão us-docker.pkg.dev/cloudrun/container/hello
    2. Clique na guia Configurações e, em Recursos, mude a memória para 256MiB e a CPU para 1 CPU.
    3. Clique em Variáveis e secrets.
    4. Clique em Adicionar variável.
    5. Digite PORT como o novo nome da variável de ambiente e 8888 como o valor.
    6. Clique em Concluído.
  6. Acesse o formulário Editar contêiner para o primeiro contêiner (nginx).

    1. Clique na guia Configurações.
    2. Em Ordem de inicialização do contêiner, selecione nginx na lista Depende de. Isso significa que o contêiner nginx é iniciado somente após a inicialização do contêiner hello.
    3. Clique em Criar e aguarde a implantação do serviço.

gcloud

Para implantar o contêiner do servidor proxy e o contêiner do app da Web como um único serviço:

gcloud run services replace service.yaml

Verificar o serviço implantado

gcloud

Para verificar a implantação, copie o URL do Cloud Run gerado e abra-o em um navegador ou use este comando para enviar uma solicitação autenticada:

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

Você verá um proxy nginx que foi transferido para o contêiner de arquivo secundário hello com status de resposta 200.

Tente fazer isso

Para acompanhar este tutorial:

gcloud

  1. Em um terminal, clone o repositório do app de exemplo na sua máquina local:

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

  2. Mude para o diretório que contém o código de amostra do Cloud Run:

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

A seguir

Para saber mais sobre o uso de arquivos secundários em um serviço do Cloud Run: