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. Faça login na sua conta do Google Cloud. Se você começou a usar o Google Cloud agora, crie uma conta para avaliar o desempenho de nossos produtos em situações reais. Clientes novos também recebem US$ 300 em créditos para executar, testar e implantar cargas de trabalho.
  2. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  3. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  4. No console do Google Cloud, na página do seletor de projetos, selecione ou crie um projeto do Google Cloud.

    Acessar o seletor de projetos

  5. Verifique se a cobrança está ativada para o seu projeto do Google Cloud.

  6. Ative as APIs Cloud Run and Secret Manager .

    Ative as 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:

  • Proprietário
  • Editor
  • Os papéis Administrador do Cloud Run e Usuário da conta de serviço
  • Qualquer papel personalizado que inclua esta lista específica de permissões

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 ativar 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 montá-lo no local desejado, volume, que é carregado no ambiente de execução.

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
  • Aplicar a compactação gzip para melhorar o desempenho
  • Instrua via 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 Save.

Linha de comando

  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 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.
  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.

Linha de comando

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

Linha de comando

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:

Linha de comando

  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: