设置无代理 gRPC 服务网格

本指南演示了如何配置无代理 gRPC 服务网格。

预览版客户支持该配置,但不建议新的 Cloud Service Mesh 用户采用。如需了解详情,请参阅 Cloud Service Mesh 概览

准备工作

请勿在启用了 Envoy Sidecar 自动注入的命名空间中创建无代理 gRPC 服务网格。如需确定是否已启用 Sidecar 注入,请运行以下命令:

kubectl get namespace default --show-labels

如果启用了 Sidecar 自动注入,请运行以下命令来移除该标签:

kubectl label namespace default istio-injection-

部署 gRPC 服务

在本部分中,您将部署 gRPC helloworld 示例服务。helloworld 示例服务是一个 gRPC 服务器应用,会返回简单消息来响应 gRPC 客户端的请求。helloworld 服务会在集群中的端口 8080 上公开 gRPC 服务。

  1. grpc-td-helloworld.yaml 文件中,保存以下内容:

    apiVersion: v1
    kind: Service
    metadata:
      name: helloworld
      namespace: default
    spec:
      ports:
      - port: 8080
        name: helloworld
        protocol: TCP
        targetPort: 50051
      selector:
        run: app1
      type: ClusterIP
    
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      labels:
        run: app1
      name: app1
      namespace: default
    spec:
      selector:
        matchLabels:
          run: app1
      replicas: 2
      template:
        metadata:
          labels:
            run: app1
          annotations:
            sidecar.istio.io/inject: "false"
        spec:
          containers:
          - image: grpc/java-example-hostname:1.37.0
            name: app1
            ports:
            - protocol: TCP
              containerPort: 50051
    
  2. 应用文件 grpc-td-helloworld.yaml

    kubectl apply -f grpc-td-helloworld.yaml
    
  3. 验证是否已创建新的 helloworld 服务:

    kubectl get svc -n default
    

    输出类似于以下内容:

    NAME           TYPE        CLUSTER-IP   EXTERNAL-IP   PORT (S)   AGE
    helloworld     ClusterIP   10.71.9.71   <none>        8080/TCP  41m
    [..skip..]
    
  4. 验证应用 Pod 是否正在运行:

    kubectl get pods -n default
    
  5. 输出 Pod 应类似于以下内容:

    NAME                        READY     STATUS    RESTARTS   AGE
    app1-6db459dcb9-zvfg2   1/1       Running   0          6m
    app1-6db459dcb9-hlvhj   1/1       Running   0          6m
    [..skip..]
    

配置 gRPC 服务网格

在本部分中,您将配置一个简单的 gRPC 服务网格。

  1. td-grpc-mesh.yaml 文件中,保存以下 mesh 清单:

    kind: TDMesh
    apiVersion: net.gke.io/v1alpha1
    metadata:
      name: td-grpc-mesh
      namespace: default
    spec:
      gatewayClassName: gke-td
      allowedRoutes:
        namespaces:
          from: All
        kinds:
        - group: net.gke.io
          kind: TDGRPCRoute
    
  2. 将网格清单应用于 gke-1

    kubectl apply -f td-grpc-mesh.yaml
    

    示例 TDMesh 仅允许将 TDGRPCRoute 资源附加到其中。该清单定义了允许的路由类型。

  3. 验证是否已创建新的 td-grpc-mesh 网格:

    kubectl describe tdmesh td-grpc-mesh -n default
    

    输出内容类似如下:

    ...
    Status:
      Conditions:
        Last Transition Time:  2022-04-14T22:22:09Z
        Message:
        Reason:                MeshReady
        Status:                True
        Type:                  Ready
        Last Transition Time:  2022-04-14T22:21:41Z
        Message:
        Reason:                Scheduled
        Status:                True
        Type:                  Scheduled
    Events:
      Type    Reason  Age   From                Message
      ----    ------  ----  ----                -------
      Normal  ADD     79s   mc-mesh-controller  Processing mesh default/td-grpc-mesh
      Normal  UPDATE  79s   mc-mesh-controller  Processing mesh default/td-grpc-mesh
      Normal  SYNC    50s   mc-mesh-controller  SYNC on default/td-grpc-mesh was a success
    
  4. helloworld-route.yaml 文件中,保存以下清单:

    kind: TDGRPCRoute
    apiVersion: net.gke.io/v1alpha1
    metadata:
      name: helloworld-route
      namespace: default
    spec:
      parentRefs:
      - name: td-grpc-mesh
        namespace: default
        group: net.gke.io
        kind: TDMesh
      hostnames:
      - helloworld
      rules:
      - backendRefs:
        - name: helloworld
          port: 8080
          namespace: default
    
  5. helloworld-route.yaml 清单应用于 gke-1

    kubectl apply -f helloworld-route.yaml
    
  6. 验证是否已创建新的 helloworld-route GRPCRoute 资源:

    kubectl get tdgrpcroute -n default
    

验证配置

配置过程完成后,验证是否可以使用无代理 gRPC 客户端访问 helloworld gRPC 服务器。此客户端连接到 Cloud Service Mesh,获取 helloworld 服务的相关信息,并使用此信息将流量发送到服务的后端。

在以下示例中,您将使用 grpcurl 工具验证 Cloud Service Mesh 是否在网格中正确路由流量。您将创建一个客户端 Pod,然后打开 shell 并从 shell 运行验证命令。

设置环境变量和引导文件

  1. grpc-client.yaml 文件中,保存以下 Pod 清单:

    apiVersion: v1
    kind: Pod
    metadata:
      name: static-sleeper
      namespace: default
      annotations:
        sidecar.istio.io/inject: "false"
    spec:
      containers:
      - image: curlimages/curl:7.82.0
        imagePullPolicy: IfNotPresent
        name: sleeper
        command:
        - sleep
        - 365d
        env:
        - name: GRPC_XDS_BOOTSTRAP
          value: "/tmp/grpc-xds/td-grpc-bootstrap.json"
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/grpc-xds/
      initContainers:
      - args:
        - --config-mesh-experimental
        - "gketd-td-grpc-mesh"
        - --output
        - "/tmp/bootstrap/td-grpc-bootstrap.json"
        image: gcr.io/trafficdirector-prod/td-grpc-bootstrap:0.14.0
        imagePullPolicy: IfNotPresent
        name: grpc-td-init
        volumeMounts:
        - name: grpc-td-conf
          mountPath: /tmp/bootstrap/
      volumes:
      - name: grpc-td-conf
        emptyDir:
          medium: Memory
    
  2. gke-1 中应用 Pod 清单:

    kubectl apply -f grpc-client.yaml
    
  3. Pod 准备就绪后,打开一个连接到客户端 Pod 的 shell:

    kubectl exec -it static-sleeper -- /bin/sh
    

您可以将 grpcurl 工具用作无代理 gRPC 客户端。grpcurl 工具使用环境变量和引导信息连接到 Cloud Service Mesh。然后,该工具会了解配置了 Cloud Service Mesh 的 helloworld 服务。

如需使用 grpcurl 工具验证您的配置,请执行以下操作:

  1. 下载并安装 grpcurl 工具:

    cd /home/curl_user
    curl -L https://github.com/fullstorydev/grpcurl/releases/download/v1.8.1/grpcurl_1.8.1_linux_x86_64.tar.gz | tar -xz
    
  2. 运行 grpcurl 工具,将 xds:///helloworld 作为服务 URI,将 helloworld.Greeter/SayHello 作为服务名称和要调用的方法。使用 -d 选项传递 SayHello 方法的参数:

    ./grpcurl --plaintext \
      -d '{"name": "world"}' \
      xds:///helloworld helloworld.Greeter/SayHello
    

    输出内容如下所示,其中 INSTANCE_HOST_NAME 是 Pod 的主机名:

    Greetings: Hello world, from INSTANCE_HOST_NAME
    

输出会验证无代理 gRPC 客户端是否已成功连接到 Cloud Service Mesh,并使用 xds 名称解析器了解 helloworld 服务的后端。客户端会向服务的其中一个后端发送请求,而无需知道其 IP 地址,也无需执行 DNS 解析。

后续步骤