Da borda à malha: como expor aplicativos de malha de serviço por meio da Entrada do GKE

Last reviewed 2022-09-29 UTC

Neste tutorial, você verá como combinar o Anthos Service Mesh com o Cloud Load Balancing para expor aplicativos em uma malha de serviço aos clientes da Internet.

O Anthos Service Mesh é uma malha de serviço gerenciado e baseado no Istio. Ele oferece uma camada de comunicação padronizada, observável e de segurança aumentada para aplicativos. Não importa se você usa o Anthos Service Mesh, o Traffic Director ou o Istio, uma malha de serviço oferece uma plataforma de comunicação holística para os clientes que se comunicam na malha. No entanto, o desafio permanece em como conectar clientes que estão fora da malha aos aplicativos hospedados na malha.

É possível expor um aplicativo aos clientes de várias maneiras, dependendo de onde o cliente está. Neste tutorial, mostramos como expor um aplicativo aos clientes unindo o Cloud Load Balancing ao Anthos Service Mesh para integrar balanceadores de carga a uma malha de serviço. Este tutorial se destina a profissionais avançados que executam o Anthos Service Mesh. No entanto, ele também funciona para Istio no Google Kubernetes Engine.

Gateway de entrada da malha

O Istio 0.8 apresentou o gateway de entrada (em inglês) da malha que fornece um conjunto dedicado de proxies com portas que ficam expostas ao tráfego que vem de fora da malha de serviço. Esses proxies de entrada da malha permitem controlar o comportamento de exposição L4 separadamente do comportamento de roteamento de aplicativos. Os proxies também permitem aplicar o roteamento e a política ao tráfego externo da malha antes de chegar ao sidecar de um aplicativo. A entrada da malha define o tratamento de tráfego quando ele chega a um nó da malha. Antes, no entanto, os componentes externos precisam definir como o tráfego chega à malha.

Para gerenciar esse tráfego externo, você precisa de um balanceador de carga externo para a malha. Neste tutorial, o Google Cloud Load Balancing é provisionado por meio de recursos de entrada do GKE para automatizar a implantação. O exemplo canônico dessa configuração é um serviço de balanceamento de carga externo que, no caso do Google Cloud, implanta um balanceador de carga TCP/UDP público. Esse balanceador de carga aponta para os NodePorts de um cluster do GKE. Esses NodePorts expõem os pods de gateway de entrada do Istio, que roteiam o tráfego para proxies sidecar de malha downstream. O diagrama a seguir ilustra essa topologia. O balanceamento de carga do tráfego particular interno é semelhante a esta arquitetura, exceto pelo fato de que você implanta um balanceador de carga TCP/UDP interno.

Um balanceador de carga externo encaminha os clientes externos para a malha por meio de proxies de gateway de entrada.

O uso do balanceamento de carga transparente L4 com um gateway de entrada da malha oferece as seguintes vantagens:

  • Esta configuração simplifica a implantação do balanceador de carga.
  • O balanceador de carga fornece um IP virtual (VIP, na sigla em inglês) estável, uma verificação de integridade e uma distribuição de tráfego confiável quando ocorrem alterações no cluster, interrupções de nó ou de processo.
  • Todas as regras de roteamento, terminação TLS e política de tráfego são processadas em um único local no gateway de entrada da malha.

Entrada e serviços do GKE

Há várias maneiras de fornecer acesso a aplicativos àqueles clientes que estão fora do cluster. Veja na tabela a seguir os componentes primitivos do Kubernetes disponíveis para implantar balanceadores de carga no Google Cloud. O tipo de balanceador de carga que você usa para expor aplicativos aos clientes dependerá muito se eles forem externos ou internos, que tipo de suporte de protocolo é necessário e se a malha de serviço abrange vários clusters do GKE ou se estão em um único cluster.

Qualquer um dos tipos de balanceador de carga na tabela a seguir pode expor aplicativos hospedados em malha, dependendo do caso de uso.

Recurso do GKE Balanceador de carga baseado na nuvem Características
Entrada para balanceadores de carga HTTP(S) externos Balanceador de carga HTTP(S) externo

Proxies L7 em pontos de presença (PoPs, na sigla em inglês) de extremidade do Google

VIP público

Escopo global

Cluster único

Entrada para balanceadores de carga HTTP(S) internos Balanceador de carga HTTP(S) interno

Proxies L7 dentro da rede de nuvem privada virtual (VPC)

VIP particular

Escopo regional

Cluster único

Serviço LoadBalancer externo Balanceador de carga de rede

Passagem de L4 em PoPs de extremidade do Google

VIP público

Escopo regional

Cluster único

Serviço LoadBalancer interno Balanceador de carga TCP/UDP interno

Passagem de L4 na rede de roteamento da VPC

VIP particular

Escopo regional

Cluster único

Entrada de vários clusters (vários clusters, entrada externa) Balanceador de carga HTTP(S) externo

Proxies L7 em PoPs de extremidade do Google

VIP público

Escopo global

Vários clusters

Embora o balanceador de carga padrão do Anthos Service Mesh seja o TCP/UDP externo, o foco deste tutorial é o balanceador de carga HTTP(S) externo. O balanceador de carga HTTP(S) externo oferece integração com serviços de extremidade, como o Identity-Aware Proxy (IAP), o Google Cloud Armor e o Cloud CDN, bem como uma rede distribuída globalmente de proxies de extremidade. Na próxima seção, descrevemos a arquitetura e as vantagens do uso de duas camadas de balanceamento de carga HTTP.

Entrada na nuvem e entrada da malha

A implantação do balanceamento de carga L7 externo fora da malha com uma camada de entrada da malha oferece vantagens significativas, especialmente para o tráfego da Internet. Mesmo que os gateways de entrada do Anthos Service Mesh e do Istio forneçam roteamento avançado e gerenciamento de tráfego na malha, algumas funções são melhor veiculadas na extremidade da rede. Aproveitar a rede na extremidade da Internet por meio do balanceador de carga HTTP(S) externo do Google Cloud pode oferecer benefícios significativos de desempenho, confiabilidade ou segurança em relação à entrada da malha. Esses benefícios incluem:

Essa camada externa de balanceamento de carga L7 é chamada de entrada na nuvem porque ela é criada em balanceadores de carga gerenciados na nuvem, em vez de proxies auto-hospedados usados pela entrada da malha. A combinação de entrada na nuvem e entrada da malha utiliza recursos complementares da infraestrutura do Google Cloud e da malha. Veja no diagrama a seguir como combinar a entrada na nuvem e a entrada da malha para exibir na forma de duas camadas de balanceamento de carga no tráfego da Internet.

A entrada do Cloud age como o gateway do tráfego externo para a malha por meio da rede VPC.

Nessa topologia, a camada de entrada na nuvem recebe tráfego de fora da malha de serviço e direciona esse tráfego à camada de entrada da malha. Em seguida, a camada de entrada da malha direciona o tráfego para os back-ends de aplicativos hospedados na malha.

Topologia de entrada na nuvem e da malha

Nesta seção, descrevemos os papéis complementares que cada camada de entrada ocupa quando são usados em conjunto. Esses papéis não são regras concretas, mas sim diretrizes que usam as vantagens de cada camada. É provável que as variações desse padrão sejam baseadas no seu caso de uso.

  • Entrada do Cloud: quando emparelhada com a entrada da malha, a camada de entrada na nuvem é melhor usada para segurança de extremidade e balanceamento de carga global. A camada de entrada na nuvem é integrada à proteção contra DDoS, firewalls de nuvem, autenticação e produtos de criptografia na extremidade. Por isso, essa camada se destaca em executar esses serviços fora da malha. A lógica de roteamento costuma ser objetiva nessa camada, mas ela pode ser mais complexa para ambientes multirregionais e com vários clusters. Devido à função crucial dos balanceadores de carga voltados para a Internet, a camada de entrada na nuvem é provavelmente gerenciada por uma equipe de infraestrutura que tem controle exclusivo sobre como os aplicativos são expostos e protegidos na Internet. Esse controle também torna essa camada menos flexível e dinâmica do que uma infraestrutura orientada por desenvolvedores, uma consideração que pode afetar a quem e como você fornece acesso administrativo a essa camada.
  • Entrada da malha: quando pareada com a entrada na nuvem, a camada de entrada da malha fornece um roteamento flexível parecido com o do aplicativo. Devido a essa flexibilidade, a entrada da malha é melhor que a entrada na nuvem, seguindo a lógica de roteamento complexa e a visibilidade no nível do aplicativo. A separação entre camadas de entrada também facilita aos proprietários de aplicativos na hora de controlar diretamente essa camada sem afetar outras equipes. Ao expor aplicativos da malha de serviço por meio de um balanceador de carga L4 em vez de L7, recomendamos que você encerre o TLS do cliente na camada de entrada dentro da malha para ajudar a proteger aplicativos.

Verificação de integridade

Uma das complexidades do uso de duas camadas do balanceamento de carga L7 é a verificação de integridade. Você precisa configurar cada balanceador de carga para verificar a integridade da próxima camada a fim de garantir que ela possa receber tráfego. A topologia do diagrama a seguir mostra como a entrada na nuvem verifica a integridade dos proxies de entrada da malha. Em contrapartida, a malha verifica a integridade dos back-ends do aplicativo.

A entrada do Cloud verifica a integridade da entrada da malha. Por sua vez, a entrada da malha verifica a integridade dos back-ends do aplicativo.

Essa topologia tem as seguintes considerações:

  • Entrada do Cloud: neste tutorial, você configura o balanceador de carga do Google Cloud por meio da entrada para verificar a integridade dos proxies de entrada da malha nas portas expostas da verificação de integridade. Se um proxy de malha estiver inativo ou se o cluster, a malha ou a região não estiverem disponíveis, o balanceador de carga do Google Cloud detectará essa condição e não enviará tráfego ao proxy da malha.
  • Entrada da malha: no aplicativo de malha, você realiza verificações de integridade diretamente nos back-ends a fim de executar o balanceamento de carga e o gerenciamento de tráfego localmente.

Segurança

A topologia anterior envolve diversos elementos de segurança. Um dos elementos mais importantes é a forma de configurar a criptografia e implantar certificados. A Entrada para balanceador de carga HTTP(S) externo tem ampla integração com certificados gerenciados pelo Google. Essa integração provisiona automaticamente certificados públicos, anexa-os a um balanceador de carga e renova e alterna certificados por meio da interface declarativa do Entrada do GKE. Os clientes da Internet se autenticam nos certificados públicos e se conectam ao balanceador de carga externo como o primeiro salto na nuvem privada virtual (VPC).

O próximo salto, que fica entre o Google Front End (GFE) e o proxy de entrada da malha, é criptografado por padrão. A criptografia no nível da rede entre os GFEs e respectivos back-ends é aplicada automaticamente. No entanto, se os seus requisitos de segurança ditam que o proprietário da plataforma retém a propriedade das chaves de criptografia, será possível ativar o HTTP/2 com criptografia TLS entre a entrada do cluster (o GFE) e a entrada da malha (o proxy envoy). instância). Quando você ativa o HTTP/2 com criptografia TLS para esse caminho, é possível usar um certificado autoassinado ou público para criptografar o tráfego. Isso acontece porque o GFE não faz a autenticação nele. Essa camada adicional de criptografia é demonstrada neste guia. Para evitar o mau uso de certificados, não use o certificado público do balanceador de carga público em outro lugar. Em vez disso, recomendamos usar certificados diferentes na malha de serviço.

Se a malha de serviço exigir TLS, todo o tráfego será criptografado entre proxies sidecar e a entrada da malha. O diagrama a seguir ilustra a criptografia HTTPS do cliente para o balanceador de carga do Google Cloud, do balanceador de carga para o proxy de entrada da malha e do proxy de entrada para o proxy sidecar.

A segurança é implementada usando certificados gerenciados fora da malha e certificados internos dentro da malha.

Objetivos

  • Implantar um cluster do Google Kubernetes Engine (GKE) no Google Cloud.
  • Implantar o Anthos Service Mesh baseado no Istio no cluster do GKE.
  • Configurar a entrada do GKE para encerrar o tráfego HTTPS público e direcionar esse tráfego para aplicativos hospedados por malha de serviço.
  • Implantar o aplicativo Online Boutique no cluster do GKE que você expõe aos clientes na Internet.

Custos

Neste documento, você usará os seguintes componentes faturáveis do Google Cloud:

Para gerar uma estimativa de custo baseada na projeção de uso deste tutorial, use a calculadora de preços. Novos usuários do Google Cloud podem estar qualificados para uma avaliação gratuita.

Ao concluir as tarefas descritas neste documento, é possível evitar o faturamento contínuo excluindo os recursos criados. Saiba mais em Limpeza.

Antes de começar

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

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

  3. No Console do Google Cloud, ative o Cloud Shell.

    Ativar o Cloud Shell

    Todos os comandos de terminal deste tutorial são executados a partir do Cloud Shell.

  4. Faça upgrade para a versão mais recente do Google Cloud CLI:

    gcloud components update
    
  5. Defina seu projeto padrão do Google Cloud:

    export PROJECT=PROJECT
    export PROJECT_NUMBER=$(gcloud projects describe ${PROJECT} --format="value(projectNumber)")
    gcloud config set project ${PROJECT}
    

    Substitua PROJECT pelo ID do projeto que quer usar neste tutorial.

  6. Crie um diretório de trabalho:

    mkdir -p ${HOME}/edge-to-mesh
    cd ${HOME}/edge-to-mesh
    export WORKDIR=`pwd`
    

    Depois de concluir o tutorial, é possível excluir o diretório de trabalho.

Como criar clusters do GKE

Os recursos descritos neste tutorial exigem uma versão de cluster do GKE 1.16 ou mais recente.

  1. No Cloud Shell, crie um novo arquivo kubeconfig. Esta etapa garante que você não crie conflitos com seu arquivo kubeconfig (padrão) atual.

    touch edge2mesh_kubeconfig
    export KUBECONFIG=${WORKDIR}/edge2mesh_kubeconfig
    
  2. Defina as variáveis de ambiente no cluster do GKE:

    export CLUSTER_NAME=edge-to-mesh
    export CLUSTER_LOCATION=us-west1-a
    
  3. Ative a API do Google Kubernetes Engine.

    gcloud

    gcloud services enable container.googleapis.com
    

    Config Connector

    Este tutorial inclui recursos do Config Connector. É possível usar esses recursos para realizar as mesmas tarefas que você concluiu na guia gcloud. Para utilizar esses recursos, instale o Config Connector e aplique os recursos da maneira que funcionar melhor para seu ambiente.

    Use o manifesto Services a seguir:

    apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
    kind: Service
    metadata:
      annotations:
        cnrm.cloud.google.com/deletion-policy: "abandon"
        cnrm.cloud.google.com/disable-dependent-services: "false"
      name: container.googleapis.com
    spec:
      resourceID: container.googleapis.com
      projectRef:
        external: PROJECT
    
  4. Criar um cluster do GKE.

    gcloud

    gcloud container clusters create ${CLUSTER_NAME} \
        --machine-type=e2-standard-4 \
        --num-nodes=4 \
        --zone ${CLUSTER_LOCATION} \
        --enable-ip-alias \
        --workload-pool=${PROJECT}.svc.id.goog \
        --release-channel rapid \
        --addons HttpLoadBalancing \
        --labels mesh_id=proj-${PROJECT_NUMBER}
    

    Config Connector

    Use os manifestos ContainerCluster e ContainerNodePool abaixo:

    apiVersion: container.cnrm.cloud.google.com/v1beta1
    kind: ContainerNodePool
    metadata:
      annotations:
        cnrm.cloud.google.com/project-id: PROJECT
      name: edge-to-mesh
    spec:
      clusterRef:
        name: edge-to-mesh
      location: us-west1-a
      nodeConfig:
        machineType: e2-standard-4
      nodeCount: 4
    ---
    apiVersion: container.cnrm.cloud.google.com/v1beta1
    kind: ContainerCluster
    metadata:
      annotations:
        cnrm.cloud.google.com/project-id: PROJECT
        cnrm.cloud.google.com/remove-default-node-pool: "true"
      labels:
        mesh_id: proj-PROJECT_NUMBER
      name: edge-to-mesh
    spec:
      addonsConfig:
        httpLoadBalancing:
          disabled: false
      location: us-west1-a
      initialNodeCount: 1
      releaseChannel:
        channel: RAPID
      workloadIdentityConfig:
        workloadPool: PROJECT.svc.id.goog
    

    Substitua PROJECT_NUMBER pelo valor da variável de ambiente PROJECT_NUMBER recuperada anteriormente.

    Para usar uma entrada na nuvem, é preciso ativar o complemento de balanceamento de carga HTTP. Os clusters do GKE têm o balanceamento de carga HTTP ativado por padrão. Não o desative.

    Para usar o Anthos Service Mesh gerenciado, é preciso aplicar o rótulo mesh_id no cluster.

  5. Certifique-se de que o cluster está em execução:

    gcloud container clusters list
    

    A resposta será semelhante a:

    NAME          LOCATION    MASTER_VERSION    MASTER_IP      MACHINE_TYPE   NODE_VERSION      NUM_NODES  STATUS
    edge-to-mesh  us-west1-a  v1.22.6-gke.300   35.233.195.59  e2-standard-4  v1.22.6-gke.300   4          RUNNING
    
  6. Conecte-se ao cluster:

    gcloud container clusters get-credentials ${CLUSTER_NAME} \
        --zone ${CLUSTER_LOCATION} \
        --project ${PROJECT}
    

Como instalar uma malha de serviço

Nesta seção, você configurará o Anthos Service Mesh gerenciado com a API de frota.

  1. Ative as APIs necessárias:

    gcloud

    gcloud services enable mesh.googleapis.com
    

    Config Connector

    Use o manifesto Services a seguir:

    apiVersion: serviceusage.cnrm.cloud.google.com/v1beta1
    kind: Service
    metadata:
      annotations:
        cnrm.cloud.google.com/deletion-policy: "abandon"
        cnrm.cloud.google.com/disable-dependent-services: "false"
      name: mesh.googleapis.com
    spec:
      resourceID: mesh.googleapis.com
      projectRef:
        external: PROJECT
    
  2. Ative o Anthos Service Mesh na frota:

    gcloud

    gcloud container fleet mesh enable
    

    Config Connector

    Use o manifesto GKEHubFeature a seguir:

    apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
    kind: GKEHubFeature
    metadata:
      name: servicemesh
    spec:
      projectRef:
        external: PROJECT
      location: global
      resourceID: servicemesh
    
  3. Registre o cluster na frota:

    gcloud

    gcloud container fleet memberships register ${CLUSTER_NAME} \
        --gke-cluster ${CLUSTER_LOCATION}/${CLUSTER_NAME} \
        --enable-workload-identity
    

    Config Connector

    Use o manifesto GKEHubMembership a seguir:

    apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
    kind: GKEHubMembership
    metadata:
      annotations:
        cnrm.cloud.google.com/project-id: PROJECT
      name: edge-to-mesh
    spec:
      location: global
      authority:
        issuer: https://container.googleapis.com/v1/projects/PROJECT/locations/us-west1-a/clusters/edge-to-mesh
      endpoint:
        gkeCluster:
          resourceRef:
            name: edge-to-mesh
    
  4. Ative o gerenciamento automático do plano de controle e o plano de dados gerenciado:

    gcloud

    gcloud container fleet mesh update \
        --management automatic \
        --memberships ${CLUSTER_NAME}
    

    Config Connector

    Use o manifesto GKEHubFeatureMembership a seguir:

    apiVersion: gkehub.cnrm.cloud.google.com/v1beta1
    kind: GKEHubFeatureMembership
    metadata:
      name: servicemesh-membership
    spec:
      projectRef:
        external: PROJECT_ID
      location: global
      membershipRef:
        name: edge-to-mesh
      featureRef:
        name: servicemesh
      mesh:
        management: MANAGEMENT_AUTOMATIC
    
  5. Após alguns minutos, verifique se o status no plano de controle é ACTIVE:

    gcloud container fleet mesh describe
    

    A saída será assim:

    ...
    membershipSpecs:
      projects/841956571429/locations/global/memberships/edge-to-mesh:
        mesh:
          management: MANAGEMENT_AUTOMATIC
    membershipStates:
      projects/841956571429/locations/global/memberships/edge-to-mesh:
        servicemesh:
          controlPlaneManagement:
            details:
            - code: REVISION_READY
              details: 'Ready: asm-managed-rapid'
            state: ACTIVE
          dataPlaneManagement:
            details:
            - code: OK
              details: Service is running.
            state: ACTIVE
        state:
          code: OK
          description: 'Revision(s) ready for use: asm-managed-rapid.'
          updateTime: '2022-09-29T05:30:28.320896186Z'
    name: projects/your-project/locations/global/features/servicemesh
    resourceState:
      state: ACTIVE
    ...
    

Como implantar a Entrada do GKE

Nas etapas a seguir, você implantará o balanceador de carga HTTP(S) externo por meio do controlador Entrada do GKE. O recurso Entrada automatiza o provisionamento do balanceador de carga, os certificados TLS e a verificação de integridade do back-end. Além disso, use o Cloud Endpoints para provisionar automaticamente um nome DNS público ao aplicativo.

Instalar um gateway de entrada

Como prática recomendada de segurança, recomendamos que você implante o gateway de entrada em um namespace diferente do plano de controle.

  1. No Cloud Shell, crie um namespace asm-ingress dedicado:

    kubectl create namespace asm-ingress
    
  2. Adicione um rótulo ao namespace asm-ingress:

    kubectl label namespace asm-ingress istio-injection=enabled
    

    A saída será assim:

    namespace/asm-ingress labeled
    

    Rotular o namespace asm-ingress com istio-injection=enabled instrui o Anthos Service Mesh a injetar automaticamente os proxies sidecar do Envoy quando um aplicativo é implantado.

  3. Execute o seguinte comando para criar o manifesto Deployment como ingress-deployment.yaml:

    cat <<EOF > ingress-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      selector:
        matchLabels:
          asm: ingressgateway
      template:
        metadata:
          annotations:
            # This is required to tell Anthos Service Mesh to inject the gateway with the
            # required configuration.
            inject.istio.io/templates: gateway
          labels:
            asm: ingressgateway
        spec:
          securityContext:
            fsGroup: 1337
            runAsGroup: 1337
            runAsNonRoot: true
            runAsUser: 1337
          containers:
          - name: istio-proxy
            securityContext:
              allowPrivilegeEscalation: false
              capabilities:
                drop:
                - all
              privileged: false
              readOnlyRootFilesystem: true
            image: auto # The image will automatically update each time the pod starts.
            resources:
              limits:
                cpu: 2000m
                memory: 1024Mi
              requests:
                cpu: 100m
                memory: 128Mi
          serviceAccountName: asm-ingressgateway
    ---
    apiVersion: autoscaling/v2
    kind: HorizontalPodAutoscaler
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    spec:
      maxReplicas: 5
      minReplicas: 3
      metrics:
      - type: Resource
        resource:
          name: cpu
          target:
            type: Utilization
            averageUtilization: 50
      scaleTargetRef:
        apiVersion: apps/v1
        kind: Deployment
        name: asm-ingressgateway
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: Role
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    rules:
    - apiGroups: [""]
      resources: ["secrets"]
      verbs: ["get", "watch", "list"]
    ---
    apiVersion: rbac.authorization.k8s.io/v1
    kind: RoleBinding
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: Role
      name: asm-ingressgateway
    subjects:
      - kind: ServiceAccount
        name: asm-ingressgateway
    ---
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
    EOF
    

    Esse Deployment tem o próprio ServiceAccount com Role e RoleBinding associados, permitindo que o gateway acesse certificados.

  4. Implante ingress-deployment.yaml no cluster para criar o recurso Deployment:

    kubectl apply -f ingress-deployment.yaml
    

    A saída será assim:

    deployment.apps/asm-ingressgateway configured
    role.rbac.authorization.k8s.io/asm-ingressgateway configured
    rolebinding.rbac.authorization.k8s.io/asm-ingressgateway configured
    serviceaccount/asm-ingressgateway created
    

    Verifique se todas as implantações estão funcionando:

    kubectl wait --for=condition=available --timeout=600s deployment --all -n asm-ingress
    

    A saída será assim:

    deployment.apps/asm-ingressgateway condition met
    
  5. Execute o seguinte comando para criar o manifesto Service como ingress-service.yaml:

    cat <<EOF > ingress-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: asm-ingressgateway
      namespace: asm-ingress
      annotations:
        cloud.google.com/neg: '{"ingress": true}'
        cloud.google.com/backend-config: '{"default": "ingress-backendconfig"}'
        cloud.google.com/app-protocols: '{"https":"HTTP2"}' # HTTP/2 with TLS encryption
      labels:
        asm: ingressgateway
    spec:
      ports:
      # status-port exposes a /healthz/ready endpoint that can be used with GKE Ingress health checks
      - name: status-port
        port: 15021
        protocol: TCP
        targetPort: 15021
      # Any ports exposed in Gateway resources should be exposed here.
      - name: http2
        port: 80
        targetPort: 8080
      - name: https
        port: 443
        targetPort: 8443
      selector:
        asm: ingressgateway
      type: ClusterIP
    EOF
    

    Esse Service tem as seguintes anotações que definem parâmetros do balanceador de carga de Entrada quando ele é implantado:

    • cloud.google.com/backend-config refere-se ao nome de um recurso personalizado chamado BackendConfig. O controlador Entrada usa BackendConfig para definir parâmetros no recurso BackendService do Google Cloud. Use esse recurso na próxima etapa para definir parâmetros personalizados da verificação de integridade do Google Cloud.
    • cloud.google.com/neg: '{"ingress": true}' ativa os back-ends de Entrada (os proxies de entrada da malha, neste caso) para balanceamento de carga nativo de contêiner. Para um balanceamento de carga mais eficiente e estável, esses back-ends usam grupos de endpoints da rede (NEGs, na sigla em inglês) em vez de grupos de instâncias.
    • cloud.google.com/app-protocols: '{"https":"HTTP2"}' direciona o GFE para se conectar ao gateway de entrada da malha de serviço usando HTTP2 com TLS, conforme descrito em Entrada para balanceamento de carga HTTP(S) externo e HTTP(S) externo Visão geral do balanceamento de carga para uma camada extra de criptografia.
  6. Implante ingress-service.yaml no cluster para criar o recurso Service:

    kubectl apply -f ingress-service.yaml
    

    A saída será assim:

    service/asm-ingressgateway created
    

Aplicar configurações do serviço de back-end

  1. No Cloud Shell, execute o seguinte comando para criar o manifesto BackendConfig como ingress-backendconfig.yaml:

    cat <<EOF > ingress-backendconfig.yaml
    apiVersion: cloud.google.com/v1
    kind: BackendConfig
    metadata:
      name: ingress-backendconfig
      namespace: asm-ingress
    spec:
      healthCheck:
        requestPath: /healthz/ready
        port: 15021
        type: HTTP
      securityPolicy:
        name: edge-fw-policy
    EOF
    

    BackendConfig é uma definição de recurso personalizada (CRD, na sigla em inglês) que define os parâmetros de back-end do balanceamento de carga do Entrada. Para uma lista completa dos parâmetros de back-end e front-end que podem ser configurados por meio do Entrada do GKE, consulte Recursos do Entrada.

    Neste tutorial, o manifesto BackendConfig especifica verificações de integridade personalizadas para os proxies de entrada da malha. O Anthos Service Mesh e o Istio expõem as verificações de integridade do proxy sidecar na porta 15021 no caminho /healthz/ready. Os parâmetros de verificação de integridade personalizados são necessários porque a porta de exibição (443) dos proxies de entrada da malha é diferente da porta de verificação de integridade (15021). O Entrada do GKE usa os parâmetros de verificação de integridade a seguir em BackendConfig para configurar as verificações de integridade do balanceador de carga do Google Cloud. A política de segurança que ajuda a proteger o tráfego de balanceamento de carga contra diferentes tipos de ataques de rede também é referenciada.

    • healthCheck.port define a porta que recebe uma verificação de integridade pelo balanceador de carga do Google Cloud no endereço IP de cada pod.
    • healthCheck.requestPath define o caminho HTTP que recebe uma verificação de integridade na porta especificada.
    • type define o protocolo da verificação de integridade (neste caso, HTTP).
    • securityPolicy.name refere-se ao nome de uma política de segurança do Cloud Armor.
  2. Implante ingress-backendconfig.yaml no cluster para criar o recurso BackendConfig:

    kubectl apply -f ingress-backendconfig.yaml
    

    A resposta será semelhante a:

    backendconfig.cloud.google.com/ingress-backendconfig created
    

    Os parâmetros BackendConfig e as anotações do Serviço asm-ingressgateway não são aplicados a um balanceador de carga do Google Cloud até que o recurso Entrada seja implantado. A implantação do Entrada vincula todos esses recursos.

Definir políticas de segurança

O Google Cloud Armor fornece proteção contra DDoS e políticas de segurança personalizáveis que podem ser anexadas a um balanceador de carga por meio de recursos de Entrada. Nas etapas a seguir, você criará uma política de segurança que usa regras pré-configuradas para bloquear ataques de scripting em vários locais (XSS). Essa regra ajuda a bloquear o tráfego que corresponde a assinaturas de ataque conhecidas, mas permite qualquer outro tráfego. Seu ambiente pode usar regras diferentes dependendo da carga de trabalho.

gcloud

  1. No Cloud Shell, crie uma política de segurança chamada edge-fw-policy:

    gcloud compute security-policies create edge-fw-policy \
        --description "Block XSS attacks"
    
  2. Crie uma regra de política de segurança que use os filtros XSS pré-configurados:

    gcloud compute security-policies rules create 1000 \
        --security-policy edge-fw-policy \
        --expression "evaluatePreconfiguredExpr('xss-stable')" \
        --action "deny-403" \
        --description "XSS attack filtering"
    

Config Connector

Use o manifesto ComputeSecurityPolicy a seguir:

apiVersion: compute.cnrm.cloud.google.com/v1beta1
kind: ComputeSecurityPolicy
metadata:
  annotations:
    cnrm.cloud.google.com/project-id: PROJECT_ID
  name: edge-fw-policy
spec:
  rule:
  - action: allow
    description: "Default rule"
    match:
      versionedExpr: SRC_IPS_V1
      config:
        srcIpRanges:
        - "*"
    priority: 2147483647
  - action: deny-403
    description: "XSS attack filtering"
    match:
      expr:
        expression: "evaluatePreconfiguredExpr('xss-stable')"
    priority: 1000

O edge-fw-policy foi referenciado por ingress-backendconfig na seção anterior. Quando o recurso Entrada é implantado, ele vincula essa política de segurança ao balanceador de carga para ajudar a proteger os back-ends do Serviço asm-ingressgateway.

Configurar o endereçamento IP e o DNS

  1. No Cloud Shell, crie um IP estático global para o balanceador de carga do Google Cloud:

    gcloud

    gcloud compute addresses create ingress-ip --global
    

    Config Connector

    Use o manifesto ComputeAddress a seguir:

    apiVersion: compute.cnrm.cloud.google.com/v1beta1
    kind: ComputeAddress
    metadata:
      annotations:
        cnrm.cloud.google.com/project-id: PROJECT_ID
      name: ingress-ip
    spec:
      location: global
    

    Esse IP estático é usado pelo recurso Entrada e permite que o IP permaneça igual, mesmo se o balanceador de carga externo for alterado.

  2. Consiga o endereço IP estático:

    export GCLB_IP=$(gcloud compute addresses describe ingress-ip --global --format "value(address)")
    echo ${GCLB_IP}
    

    Para criar um mapeamento estável e legível para o IP de Entrada, é preciso ter um registro DNS público. Use o provedor de DNS e a automação que quiser. Neste tutorial, o Endpoints é usado em vez da criação de uma zona de DNS gerenciada. O Endpoints fornece gratuitamente um registro DNS gerenciado pelo Google para um IP público.

  3. Execute o seguinte comando para criar o arquivo de especificação YAML chamado dns-spec.yaml:

    cat <<EOF > dns-spec.yaml
    swagger: "2.0"
    info:
      description: "Cloud Endpoints DNS"
      title: "Cloud Endpoints DNS"
      version: "1.0.0"
    paths: {}
    host: "frontend.endpoints.${PROJECT}.cloud.goog"
    x-google-endpoints:
    - name: "frontend.endpoints.${PROJECT}.cloud.goog"
      target: "${GCLB_IP}"
    EOF
    

    A especificação YAML define o registro DNS público no formato frontend.endpoints.${PROJECT}.cloud.goog, em que ${PROJECT} é o número exclusivo do projeto.

  4. Implante o arquivo dns-spec.yaml no projeto do Google Cloud:

    gcloud endpoints services deploy dns-spec.yaml
    

    O resultado será assim:

    Operation finished successfully. The following command can describe the Operation details:
     gcloud endpoints operations describe operations/rollouts.frontend.endpoints.edge2mesh.cloud.goog:442b2b38-4aee-4c60-b9fc-28731657ee08
    
    Service Configuration [2021-11-14r0] uploaded for service [frontend.endpoints.edge2mesh.cloud.goog]
    

    Agora que o IP e o DNS estão configurados, é possível gerar um certificado público para proteger o front-end do Entrada. O Entrada do GKE é compatível com certificados gerenciados pelo Google como recursos do Kubernetes, o que permite que você os provisione por meios declarativos.

Provisionar um certificado TLS

  1. No Cloud Shell, execute o seguinte comando para criar o manifesto ManagedCertificate como managed-cert.yaml:

    cat <<EOF > managed-cert.yaml
    apiVersion: networking.gke.io/v1
    kind: ManagedCertificate
    metadata:
      name: gke-ingress-cert
      namespace: asm-ingress
    spec:
      domains:
        - "frontend.endpoints.${PROJECT}.cloud.goog"
    EOF
    

    Esse arquivo YAML especifica que o nome DNS criado por meio do Endpoints é usado para provisionar um certificado público. Como o Google gerencia totalmente o ciclo de vida desses certificados públicos, eles são gerados e alternados regularmente, sem intervenção direta do usuário.

  2. Implante o arquivo managed-cert.yaml no cluster do GKE:

    kubectl apply -f managed-cert.yaml
    

    A resposta será semelhante a:

    managedcertificate.networking.gke.io/gke-ingress-cert created
    
  3. Inspecione o recurso ManagedCertificate para verificar o progresso da geração do certificado:

    kubectl describe managedcertificate gke-ingress-cert -n asm-ingress
    

    A resposta será semelhante a:

    Name:         gke-ingress-cert
    Namespace:    asm-ingress
    Labels:       <none>
    Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                    {"apiVersion":"networking.gke.io/v1","kind":"ManagedCertificate","metadata":{"annotations":{},"name":"gke-ingress-cert","namespace":"...
    API Version:  networking.gke.io/v1
    Kind:         ManagedCertificate
    Metadata:
      Creation Timestamp:  2020-08-05T20:44:49Z
      Generation:          2
      Resource Version:    1389781
      Self Link:           /apis/networking.gke.io/v1/namespaces/asm-ingress/managedcertificates/gke-ingress-cert
      UID:                 d74ec346-ced9-47a8-988a-6e6e9ddc4019
    Spec:
      Domains:
        frontend.endpoints.edge2mesh.cloud.goog
    Status:
      Certificate Name:    mcrt-306c779e-8439-408a-9634-163664ca6ced
      Certificate Status:  Provisioning
      Domain Status:
        Domain:  frontend.endpoints.edge2mesh.cloud.goog
        Status:  Provisioning
    Events:
      Type    Reason  Age   From                            Message
      ----    ------  ----  ----                            -------
      Normal  Create  44s   managed-certificate-controller  Create SslCertificate mcrt-306c779e-8439-408a-9634-163664ca6ced
    

    Quando o certificado estiver pronto, o Certificate Status será Active.

Implantar o recurso Entrada

  1. No Cloud Shell, execute o seguinte comando para criar o manifesto Ingress como ingress.yaml:

    cat <<EOF > ingress.yaml
    apiVersion: networking.k8s.io/v1
    kind: Ingress
    metadata:
      name: gke-ingress
      namespace: asm-ingress
      annotations:
        kubernetes.io/ingress.allow-http: "false"
        kubernetes.io/ingress.global-static-ip-name: "ingress-ip"
        networking.gke.io/managed-certificates: "gke-ingress-cert"
        kubernetes.io/ingress.class: "gce"
    spec:
      defaultBackend:
        service:
          name: asm-ingressgateway
          port:
            number: 443
      rules:
      - http:
          paths:
          - path: /*
            pathType: ImplementationSpecific
            backend:
              service:
                name: asm-ingressgateway
                port:
                  number: 443
    EOF
    

    Esse manifesto define um recurso Entrada que une todos os recursos anteriores. O manifesto especifica os seguintes campos:

    • kubernetes.io/ingress.allow-http: "false" desativa o tráfego HTTP na porta 80 do balanceador de carga do Google Cloud. Isso impede efetivamente que os clientes se conectem com o tráfego não criptografado porque a porta 443 detecta somente HTTPS, e a porta 80 está desativada.
    • kubernetes.io/ingress.global-static-ip-name: "ingress-ip" vincula o endereço IP criado anteriormente ao balanceador de carga. Esse link permite que o endereço IP seja criado separadamente do balanceador de carga. Assim, o endereço IP poderá ser reutilizado separadamente do ciclo de vida do balanceador de carga.
    • networking.gke.io/managed-certificates: "gke-ingress-cert" vincula esse balanceador de carga ao recurso de certificado SSL gerenciado pelo Google criado anteriormente.
  2. Implante ingress.yaml no cluster:

    kubectl apply -f ingress.yaml
    
  3. Inspecione o recurso Entrada para verificar o progresso da implantação do balanceador de carga:

    kubectl describe ingress gke-ingress -n asm-ingress
    

    A resposta será semelhante a:

    ...
    Annotations:
      ingress.kubernetes.io/https-forwarding-rule:       k8s2-fs-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor
      ingress.kubernetes.io/ssl-cert:                    mcrt-306c779e-8439-408a-9634-163664ca6ced
      networking.gke.io/managed-certificates:            gke-ingress-cert
      kubernetes.io/ingress.global-static-ip-name:  ingress-ip
      ingress.gcp.kubernetes.io/pre-shared-cert:    mcrt-306c779e-8439-408a-9634-163664ca6ced
      ingress.kubernetes.io/backends:               {"k8s-be-31610--07bdde06b914144a":"HEALTHY","k8s1-07bdde06-asm-ingress-asm-ingressgateway-443-228c1881":"HEALTHY"}
      ingress.kubernetes.io/forwarding-rule:        k8s2-fr-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor
      ingress.kubernetes.io/https-target-proxy:     k8s2-ts-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor
      ingress.kubernetes.io/target-proxy:           k8s2-tp-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor
      ingress.kubernetes.io/url-map:                k8s2-um-fq3ng2uk-asm-ingress-gke-ingress-qm3qqdor
    ...
    

    O recurso Entrada está pronto quando as anotações ingress.kubernetes.io/backends indicam que os back-ends são HEALTHY. As anotações também mostram os nomes de diferentes recursos do Google Cloud provisionados, incluindo serviços de back-end, certificados SSL e proxies de destino HTTPS.

Instalar o certificado de gateway de entrada autoassinado

Nas etapas a seguir, você gera e instala um certificado (como um recurso secret do Kubernetes) que permite ao GFE estabelecer uma conexão TLS com o gateway de entrada da malha de serviço. Para mais detalhes sobre os requisitos do certificado do gateway de entrada, consulte o guia seguro de considerações do protocolo de back-end.

  1. No Cloud Shell, crie a chave privada e o certificado usando openssl:

    openssl req -new -newkey rsa:4096 -days 365 -nodes -x509 \
     -subj "/CN=frontend.endpoints.${PROJECT}.cloud.goog/O=Edge2Mesh Inc" \
     -keyout frontend.endpoints.${PROJECT}.cloud.goog.key \
     -out frontend.endpoints.${PROJECT}.cloud.goog.crt
    
  2. Crie o Secret no namespace asm-ingress:

    kubectl -n asm-ingress create secret tls edge2mesh-credential \
     --key=frontend.endpoints.${PROJECT}.cloud.goog.key \
     --cert=frontend.endpoints.${PROJECT}.cloud.goog.crt
    

Configurar o gateway de entrada para balanceamento de carga externo

Nas etapas a seguir, você criará um recurso compartilhado Gateway no namespace asm-ingress. Os gateways geralmente são de propriedade dos administradores da plataforma ou da equipe de administradores de rede. Assim, o recurso Gateway é criado no namespace asm-ingress de propriedade do administrador da plataforma e pode ser usado em outros namespaces com suas próprias entradas VirtualService.

  1. No Cloud Shell, execute o seguinte comando para criar o manifesto Gateway como ingress-gateway.yaml:

    cat <<EOF > ingress-gateway.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: Gateway
    metadata:
        name: asm-ingressgateway
        namespace: asm-ingress
    spec:
      selector:
        asm: ingressgateway
      servers:
      - port:
          number: 443
          name: https
          protocol: HTTPS
        hosts:
        - "*" # IMPORTANT: Must use wildcard here when using SSL, see note below
        tls:
          mode: SIMPLE
          credentialName: edge2mesh-credential
    EOF
    

    É necessário usar a entrada de caractere curinga * no campo hosts do Gateway. O GCLB não usa a extensão SNI nos back-ends. O uso da entrada de caractere curinga envia o pacote criptografado (do GCLB) para o gateway de entrada do ASM. O gateway de Entrada do ASM descriptografa o pacote e usa o cabeçalho de host HTTP no pacote descriptografado para tomar decisões de roteamento, com base nas entradas VirtualService.

  2. Implante ingress-gateway.yaml no cluster:

    kubectl apply -f ingress-gateway.yaml
    

    A saída será assim:

    gateway.networking.istio.io/asm-ingressgateway created
    

Como instalar o aplicativo de exemplo Online Boutique

  1. No Cloud Shell, crie um namespace onlineboutique dedicado:

    kubectl create namespace onlineboutique
    
  2. Adicione um rótulo ao namespace onlineboutique:

    kubectl label namespace onlineboutique istio-injection=enabled
    

    A saída será assim:

    namespace/onlineboutique labeled
    

    Rotular o namespace onlineboutique com istio-injection=enabled instrui o Anthos Service Mesh a injetar automaticamente os proxies sidecar do Envoy quando um aplicativo é implantado.

  3. Faça o download dos arquivos YAML do Kubernetes para o aplicativo de exemplo Online Boutique:

    curl -LO \
        https://raw.githubusercontent.com/GoogleCloudPlatform/microservices-demo/main/release/kubernetes-manifests.yaml
    
  4. Implante o aplicativo do Online Boutique:

    kubectl apply -f kubernetes-manifests.yaml -n onlineboutique
    

    A resposta será semelhante a:

    deployment.apps/frontend created
    service/frontend created
    service/frontend-external created
    ...
    
  5. Verifique se todas as implantações estão funcionando:

    kubectl get pods -n onlineboutique
    

    A saída será assim:

    NAME                                     READY   STATUS    RESTARTS   AGE
    adservice-d854d8786-fjb7q                2/2     Running   0          3m
    cartservice-85b5d5b4ff-8qn7g             2/2     Running   0          2m59s
    checkoutservice-5f9bf659b8-sxhsq         2/2     Running   0          3m1s
    ...
    
  6. Execute o seguinte comando para criar o manifesto VirtualService como frontend-virtualservice.yaml:

    cat <<EOF > frontend-virtualservice.yaml
    apiVersion: networking.istio.io/v1alpha3
    kind: VirtualService
    metadata:
      name: frontend-ingress
      namespace: onlineboutique
    spec:
      hosts:
      - "frontend.endpoints.${PROJECT}.cloud.goog"
      gateways:
      - asm-ingress/asm-ingressgateway
      http:
      - route:
        - destination:
            host: frontend
            port:
              number: 80
    EOF
    

    Observe que o VirtualService é criado no namespace do aplicativo (onlineboutique). Em geral, o proprietário do aplicativo decide e configura como e qual tráfego será roteado para o aplicativo frontend para que o VirtualService seja implantado pelo proprietário do aplicativo.

  7. Implante frontend-virtualservice.yaml no cluster:

    kubectl apply -f frontend-virtualservice.yaml
    

    A saída será assim:

    virtualservice.networking.istio.io/frontend-virtualservice created
    
  8. Acesse o seguinte link:

    echo "https://frontend.endpoints.${PROJECT}.cloud.goog"
    

    Seu front-end do Online Boutique é exibido.

    Produtos mostrados na página inicial da Online Boutique.

  9. Para exibir os detalhes do certificado, clique em Ver informações do site na barra de endereço do seu navegador e, depois, clique em Certificado (válido).

    O visualizador de certificados exibe detalhes do certificado gerenciado, incluindo a data de validade e quem emitiu o certificado.

Agora você tem um balanceador de carga HTTPS global que serve como front-end para seu aplicativo hospedado pela malha de serviço.

Limpeza

Após concluir este tutorial, é possível limpar os recursos que você criou no Google Cloud para que não sejam faturados no futuro. É possível excluir todo o projeto ou remover recursos do cluster e, depois, excluir o cluster.

Excluir o projeto

  1. No Console do Google Cloud, acesse a página Gerenciar recursos.

    Acessar "Gerenciar recursos"

  2. Na lista de projetos, selecione o projeto que você quer excluir e clique em Excluir .
  3. Na caixa de diálogo, digite o ID do projeto e clique em Encerrar para excluí-lo.

Excluir recursos individuais

Se você quiser manter o projeto do Google Cloud usado neste tutorial, exclua os recursos individuais:

  1. Exclua o recurso Entrada:

    kubectl delete -f ingress.yaml
    
  2. Exclua o certificado gerenciado:

    kubectl delete -f managed-cert.yaml
    
  3. Exclua a entrada DNS do Endpoints:

    gcloud endpoints services delete "frontend.endpoints.${PROJECT}.cloud.goog"
    

    A resposta será semelhante a:

    Are you sure? This will set the service configuration to be deleted, along
    with all of the associated consumer information. Note: This does not
    immediately delete the service configuration or data and can be undone using
    the undelete command for 30 days. Only after 30 days will the service be
    purged from the system.
    
  4. Quando for solicitado continuar, digite Y.

    A resposta será semelhante a:

    Waiting for async operation operations/services.frontend.endpoints.edge2mesh.cloud.goog-5 to complete...
    Operation finished successfully. The following command can describe the Operation details:
     gcloud endpoints operations describe operations/services.frontend.endpoints.edge2mesh.cloud.goog-5
    
  5. Exclua o endereço IP estático:

    gcloud compute addresses delete ingress-ip --global
    

    A resposta será semelhante a:

    The following global addresses will be deleted:
    
     - [ingress-ip]
    
  6. Quando for solicitado continuar, digite Y.

    A resposta será semelhante a:

    Deleted
    [https://www.googleapis.com/compute/v1/projects/edge2mesh/global/addresses/ingress-ip].
    
  7. Exclua o cluster do GKE:

    gcloud container clusters delete $CLUSTER_NAME --zone $CLUSTER_LOCATION
    

A seguir