Configurar uma malha de serviço de arquivo secundário do Envoy

Esta configuração é compatível com clientes de pré-lançamento, mas não recomendamos para novos usuários do Cloud Service Mesh. Para mais informações, consulte a Visão geral do Cloud Service Mesh.

Este guia mostra como configurar uma malha de serviço simples na sua frota. O guia inclui as seguintes etapas:

  • Como implantar o injetor do arquivo secundário do Envoy no cluster. O injetor injeta o contêiner de proxy do Envoy em pods de aplicativo.
  • Como implantar os recursos da API Gateway que configuram o arquivo secundário do Envoy na malha de serviço para encaminhar solicitações para um serviço de exemplo no namespace store.
  • Como implantar um cliente simples para verificar a implantação.

O diagrama a seguir mostra a malha de serviço configurada.

Uma malha de serviço de arquivo secundário do Envoy em uma frota
Uma malha de serviço de arquivo secundário do Envoy em uma frota (clique para ampliar)

É possível configurar apenas um Mesh por cluster, porque o nome da malha na configuração do injetor do arquivo secundário e o nome do recurso Mesh precisam ser idênticos.

Implantar o injetor do arquivo secundário do Envoy

Para implantar o injetor do arquivo secundário, forneça dois valores.

  • TRAFFICDIRECTOR_GCP_PROJECT_NUMBER. Substitua PROJECT_NUMBER pelo número do seu projeto de configuração de cluster. O número é o identificador numérico do projeto.

  • TRAFFICDIRECTOR_MESH_NAME. Atribua o valor da seguinte maneira, em que MESH_NAME é o valor do campo metadata.name na especificação do recurso Mesh:

    gketd-MESH_NAME
    

    Por exemplo, se o valor de metadata.name no recurso Mesh for butterfly-mesh, defina o valor de TRAFFICDIRECTOR_MESH_NAME da seguinte maneira:

    TRAFFICDIRECTOR_MESH_NAME: "gketd-butterfly-mesh"
    
  • TRAFFICDIRECTOR_NETWORK_NAME. Verifique se o valor de TRAFFICDIRECTOR_NETWORK_NAME está definido como vazio:

    TRAFFICDIRECTOR_NETWORK_NAME=""
    
  1. Faça o download do pacote injetor do arquivo secundário:

    wget https://storage.googleapis.com/traffic-director/td-sidecar-injector-xdsv3.tgz
    tar -xzvf td-sidecar-injector-xdsv3.tgz
    cd td-sidecar-injector-xdsv3
    
  2. No arquivo specs/01-configmap.yaml, preencha os campos TRAFFICDIRECTOR_GCP_PROJECT_NUMBER e TRAFFICDIRECTOR_MESH_NAME e defina TRAFFICDIRECTOR_NETWORK_NAME como vazio.

        apiVersion: v1
        kind: ConfigMap
        metadata:
          name: istio
          namespace: istio-system
        data:
          mesh: |-
            defaultConfig:
              discoveryAddress: trafficdirector.googleapis.com:443
    
              # Envoy proxy port to listen on for the admin interface.
              # This port is bound to 127.0.0.1.
              proxyAdminPort: 15000
    
              proxyMetadata:
                # Google Cloud Project number that your Fleet belongs to.
                # This is the numeric identifier of your project
                TRAFFICDIRECTOR_GCP_PROJECT_NUMBER: "PROJECT_NUMBER"
    
                # TRAFFICDIRECTOR_NETWORK_NAME must be empty when
                # TRAFFICDIRECTOR_MESH_NAME is set.
                TRAFFICDIRECTOR_NETWORK_NAME: "NETWORK_NAME"
    
                # The value of `metadata.name` in the `Mesh` resource. When a
                # sidecar requests configurations from Cloud Service Mesh,
                # Cloud Service Mesh will only return configurations for the
                # specified mesh.
                TRAFFICDIRECTOR_MESH_NAME: "gketd-td-mesh"
    

Depois de concluir as instruções anteriores, siga estas etapas para implantar o injetor do arquivo secundário no cluster:

  1. Como configurar o TLS para o injetor do arquivo secundário.
  2. Como instalar o injetor do arquivo secundário no cluster do GKE.
  3. [Opcional] Como abrir a porta necessária em um cluster particular.
  4. Ative a injeção de arquivo secundário.

Implante o serviço store

Nesta seção, você implantará o serviço store na malha.

  1. No arquivo store.yaml, salve o seguinte manifesto:

    kind: Namespace
    apiVersion: v1
    metadata:
      name: store
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: store
      namespace: store
    spec:
      replicas: 2
      selector:
        matchLabels:
          app: store
          version: v1
      template:
        metadata:
          labels:
            app: store
            version: v1
        spec:
          containers:
          - name: whereami
            image: gcr.io/google-samples/whereami:v1.2.20
            ports:
            - containerPort: 8080
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: store
      namespace: store
    spec:
      selector:
        app: store
      ports:
      - port: 8080
        targetPort: 8080
    
  2. Aplique o manifesto a gke-1:

    kubectl apply -f store.yaml
    

Criar uma malha de serviço

  1. No arquivo mesh.yaml, salve o manifesto mesh a seguir. O nome do recurso mesh precisa corresponder ao nome da malha especificado no mapa de configuração do arquivo secundário. Nesta configuração de exemplo, o nome td-mesh é usado em ambos os lugares:

    apiVersion: net.gke.io/v1alpha1
    kind: TDMesh
    metadata:
      name: td-mesh
      namespace: default
    spec:
      gatewayClassName: gke-td
      allowedRoutes:
        namespaces:
          from: All
    
  2. Aplique o manifesto mesh a gke-1, o que cria uma malha lógica com o nome td-mesh:

    kubectl apply -f mesh.yaml
    
  3. No arquivo store-route.yaml, salve o manifesto HTTPRoute a seguir. O manifesto define um recurso HTTPRoute que encaminha o tráfego HTTP especificando o nome do host example.com para um serviço do Kubernetes store no namespace store:

    apiVersion: gateway.networking.k8s.io/v1alpha2
    kind: HTTPRoute
    metadata:
      name: store-route
      namespace: store
    spec:
      parentRefs:
      - name: td-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - "example.com"
      rules:
      - backendRefs:
        - name: store
          namespace: store
          port: 8080
    
  4. Aplique o manifesto do trajeto a gke-1:

    kubectl apply -f store-route.yaml
    

Validar a implantação

  1. Inspecione o status e os eventos Mesh para confirmar que os recursos Mesh e HTTPRoute foram implantados corretamente:

    kubectl describe tdmesh td-mesh
    

    A saída será assim:

    ...
    
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:08:39Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:08:28Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age   From                Message
      ----    ------  ----  ----                -------
      Normal  ADD     36s   mc-mesh-controller  Processing mesh default/td-mesh
      Normal  UPDATE  35s   mc-mesh-controller  Processing mesh default/td-mesh
      Normal  SYNC    24s   mc-mesh-controller  SYNC on default/td-mesh was a success
    
  2. Para garantir que a injeção de arquivo secundário esteja ativada no namespace padrão, execute o seguinte comando:

    kubectl get namespace default --show-labels
    

    Se a injeção de arquivo secundário estiver ativada, você verá o seguinte na saída:

    istio-injection=enabled
    

    Se a injeção de arquivo secundário não estiver ativada, consulte Ativar injeções de arquivos secundários.

  3. Para verificar a implantação, implante um pod cliente que sirva como um cliente no serviço store definido anteriormente. No arquivo client.yaml, salve o seguinte:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: client
      name: client
      namespace: default
    spec:
      replicas: 1
      selector:
        matchLabels:
          run: client
      template:
        metadata:
          labels:
            run: client
        spec:
          containers:
          - name: client
            image: curlimages/curl
            command:
            - sh
            - -c
            - while true; do sleep 1; done
    
  4. Implante a especificação:

    kubectl apply -f client.yaml
    

    O injetor secundário em execução no cluster injeta automaticamente um contêiner do Envoy no pod cliente.

  5. Para verificar se o contêiner do Envoy foi injetado, execute o seguinte comando:

    kubectl describe pods -l run=client
    

    A saída será assim:

    ...
    Init Containers:
      # Istio-init sets up traffic interception for the Pod.
      istio-init:
    ...
      # td-bootstrap-writer generates the Envoy bootstrap file for the Envoy container
      td-bootstrap-writer:
    ...
    Containers:
    # client is the client container that runs application code.
      client:
    ...
    # Envoy is the container that runs the injected Envoy proxy.
      envoy:
    ...
    

Depois que o pod cliente for provisionado, envie uma solicitação do pod cliente para o serviço store.

  1. Encontre o nome do pod do cliente:

    CLIENT_POD=$(kubectl get pod -l run=client -o=jsonpath='{.items[0].metadata.name}')
    
    # The VIP where the following request will be sent. Because all requests
    # from the client container are redirected to the Envoy proxy sidecar, you
    # can use any IP address, including 10.0.0.2, 192.168.0.1, and others.
    VIP='10.0.0.1'
    
  2. Envie uma solicitação para armazenar o serviço e gerar os cabeçalhos de resposta:

    TEST_CMD="curl -v -H 'host: example.com' $VIP"
    
  3. Execute o comando de teste no contêiner do cliente:

    kubectl exec -it $CLIENT_POD -c client -- /bin/sh -c "$TEST_CMD"
    

    A saída será assim:

    < Trying 10.0.0.1:80...
    < Connected to 10.0.0.1 (10.0.0.1) port 80 (#0)
    < GET / HTTP/1.1
    < Host: example.com
    < User-Agent: curl/7.82.0-DEV
    < Accept: */*
    <
    < Mark bundle as not supporting multiuse
    < HTTP/1.1 200 OK
    < content-type: application/json
    < content-length: 318
    < access-control-allow-origin: *
    < server: envoy
    < date: Tue, 12 Apr 2022 22:30:13 GMT
    <
    {
      "cluster_name": "gke-1",
      "zone": "us-west1-a",
      "host_header": "example.com",
      ...
    }
    

A seguir