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

Essa configuração tem suporte para clientes de pré-lançamento, mas não é recomendada 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 sidecar,

  1. Configurar as informações do projeto

    # The project that contains your GKE cluster.
    export CLUSTER_PROJECT_ID=YOUR_CLUSTER_PROJECT_NUMBER_HERE
    # The name of your GKE cluster.
    export CLUSTER=YOUR_CLUSTER_NAME
    # The channel of your GKE cluster. Eg: rapid, regular, stable.
    export CHANNEL=YOUR_CLUSTER_CHANNEL
    # The location of your GKE cluster, Eg: us-central1 for regional GKE cluster,
    # us-central1-a for zonal GKE cluster
    export LOCATION=ZONE
    
    # The mesh name of the traffic director load balancing API.
    export MESH_NAME=YOUR_MESH_NAME
    # The project that holds the mesh resources.
    export MESH_PROJECT_NUMBER=YOUR_PROJECT_NUMBER_HERE
    
    export TARGET=projects/${MESH_PROJECT_NUMBER}/locations/global/meshes/${MESH_NAME}
    
    gcloud config set project ${CLUSTER_PROJECT_ID}
    

    Para descobrir o 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 MESH_NAME da seguinte maneira:

    export MESH_NAME="gketd-butterfly-mesh"
    
  2. Aplicar as configurações para o webhook mutável

    As seções a seguir fornecem instruções para aplicar o MutatingWebhookConfiguration ao cluster. Quando um pod é criado, o controlador de admissão no cluster é invocado. O controlador de admissão se comunica com o injetor de sidecar gerenciado para adicionar o contêiner do Envoy ao pod.

    Aplique as seguintes configurações de webhook mutável ao cluster.

    cat <<EOF | kubectl apply -f -
    apiVersion: admissionregistration.k8s.io/v1
    kind: MutatingWebhookConfiguration
    metadata:
      labels:
        app: sidecar-injector
      name: td-mutating-webhook
    webhooks:
    - admissionReviewVersions:
      - v1beta1
      - v1
      clientConfig:
        url: https://meshconfig.googleapis.com/v1internal/projects/${CLUSTER_PROJECT_ID}/locations/${LOCATION}/clusters/${CLUSTER}/channels/${CHANNEL}/targets/${TARGET}:tdInject
      failurePolicy: Fail
      matchPolicy: Exact
      name: namespace.sidecar-injector.csm.io
      namespaceSelector:
        matchExpressions:
        - key: td-injection
          operator: Exists
      reinvocationPolicy: Never
      rules:
      - apiGroups:
        - ""
        apiVersions:
        - v1
        operations:
        - CREATE
        resources:
        - pods
        scope: '*'
      sideEffects: None
      timeoutSeconds: 30
    EOF
    

    Se você precisar personalizar o injetor do sidecar, siga estas etapas para personalizar o injetor do sidecar no cluster:

  3. Como configurar o TLS para o injetor do arquivo secundário.

  4. Ative a injeção de arquivo secundário.

  5. Opções para injeções automáticas do Envoy

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: us-docker.pkg.dev/google-samples/containers/gke/whereami:v1
            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