使用手动 Envoy 注入功能设置 Google Kubernetes Engine Pod

本指南介绍如何配置 Google Kubernetes Engine 或 Kubernetes Pod 主机以及 Cloud Service Mesh 所需的负载均衡组件。

在按照本指南中的说明操作之前,请先完成准备使用 Envoy 和无代理工作负载设置服务路由 API 中所述的前提任务。

您可以使用 Compute Engine 负载均衡 SDK 或 REST API 配置 Cloud Service Mesh。请参阅负载平衡 API 和 gcloud 参考

为 Cloud Service Mesh 配置 GKE/Kubernetes 集群

本部分介绍为了使 GKE/Kubernetes 集群能够与 Cloud Service Mesh 搭配使用而执行的必要步骤。

创建 GKE 集群

GKE 集群必须满足以下要求:

  • 必须启用网络端点组支持。如需了解详情和示例,请参阅独立网络端点组。独立的 NEG 功能现已面向 Cloud Service Mesh 推出正式版。
  • 集群节点实例的服务账号必须有权访问 Cloud Service Mesh API。
  • 容器必须有权访问受 OAuth 身份验证保护的 Cloud Service Mesh API。如需了解详情,请参阅主机配置

以下示例展示了如何在 us-central1-a 区域中创建名为 traffic-director-cluster 的 GKE 集群。

控制台

如需使用 Google Cloud 控制台创建集群,请执行以下步骤:

  1. 转到 Google Cloud 控制台中的 Kubernetes Engine 菜单。

    转到 Google Kubernetes Engine 菜单

  2. 点击创建集群

  3. 填写以下字段:

    • 名称:输入 traffic-director-cluster
    • 位置类型Zonal
    • 区域us-central1-a
  4. 在导航窗格的节点池下,点击默认池 (default-pool)。

  5. 大小字段表示要在集群中创建的节点数。您必须具有节点及其资源(例如防火墙路由)的可用资源配额

  6. 在导航窗格的默认池 (default-pool) 下,点击节点

  7. 机器类型字段表示用于实例的 Compute Engine 机器类型。每种机器类型的计费方式都各不相同。如需了解机器类型价格信息,请参阅 Compute Engine 价格页面

  8. 在导航窗格的默认池 (default-pool) 下,点击安全

  9. 访问权限范围下,点击授予对所有 Cloud API 的完整访问权限

  10. 根据需要自定义集群。

  11. 点击创建

在 Google Cloud 控制台中创建集群后,您需要配置 kubectl 以与该集群进行交互。如需了解详情,请参阅生成 kubeconfig 条目

gcloud

gcloud container clusters create traffic-director-cluster \
  --zone us-central1-a \
  --scopes=https://www.googleapis.com/auth/cloud-platform \
  --enable-ip-alias

获取所需的 GKE 集群权限

对于 GKE,请通过发出以下命令切换到刚创建的集群 (2)。这会将 kubectl 指向正确的集群。

gcloud container clusters get-credentials traffic-director-cluster \
    --zone us-central1-a

配置 GKE/Kubernetes 服务

本部分介绍如何准备 Kubernetes 部署规范以便使用 Cloud Service Mesh。这包括使用 NEG 来配置服务,以及将边车代理注入需要访问由 Cloud Service Mesh 管理的服务的 Pod 中。

配置防火墙规则

如需验证后端 Pod 是否正在运行,您必须配置允许健康检查器 IP 地址范围的防火墙规则。

控制台

  1. 进入 Google Cloud 控制台中的防火墙政策页面。
    进入“防火墙政策”页面
  2. 点击创建防火墙规则
  3. 在“创建防火墙规则”页面上,提供如下信息:
    • 名称:提供规则的名称。本示例使用的是 fw-allow-health-checks
    • 网络:选择一个 VPC 网络。
    • 优先级:输入一个表示优先级的数字。这个数字越小,优先级就越高。请确保防火墙规则的优先级高于可能会拒绝入站流量的其他规则的优先级。
    • 流量方向:选择入站
    • 匹配时执行的操作:选择允许
    • 目标:选择网络中的所有实例
    • 来源过滤条件:选择正确的 IP 地址范围类型。
    • 来源 IP 地址范围35.191.0.0/16,130.211.0.0/22
    • 目标过滤条件:选择 IP 类型。
    • 协议和端口:点击指定的端口和协议,然后勾选 tcp。TCP 是所有健康检查协议的底层协议。
    • 点击创建

gcloud

  1. 使用以下 gcloud 命令创建名为 fw-allow-health-checks 的防火墙规则,允许到网络中具有 allow-health-checks 标记的实例的传入连接。将 NETWORK_NAME 替换为您的网络名称。

    gcloud compute firewall-rules create fw-allow-health-checks \
        --network NETWORK_NAME \
        --action ALLOW \
        --direction INGRESS \
        --source-ranges 35.191.0.0/16,130.211.0.0/22 \
        --rules tcp

如需了解详情,请参阅为健康检查配置防火墙规则

使用 NEG 配置 GKE/Kubernetes 服务

GKE 服务必须通过网络端点组 (NEG) 公开,以便您可以将它们配置为 Cloud Service Mesh 后端服务的后端。将 NEG 注释添加到 Kubernetes 服务规范并选择一个名称(替换以下示例中的 NEG-NAME),以便于日后查找。当您将 NEG 附加到 Cloud Service Mesh 后端服务时,将需要该名称。如需详细了解如何为 NEG 添加注释,请参阅为 NEG 命名

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports": {"80":{"name": "NEG-NAME"}}}'
spec:
  ports:
  - port: 80
    name: service-test
    protocol: TCP
    targetPort: 8000

系统会为每项服务创建一个单独的 NEG,其中包含的端点是 pod 的 IP 地址和端口。如需了解详情和示例,请参阅独立网络端点组

为了进行演示,您可以部署一个示例服务,该服务在端口 80 上通过 HTTP 提供其主机名:

wget -q -O - \
https://storage.googleapis.com/traffic-director/demo/trafficdirector_service_sample.yaml \
| kubectl apply -f -

验证新服务主机名是否已创建,以及应用 Pod 是否正在运行:

kubectl get svc

此操作会返回:

NAME             TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service-test     ClusterIP   10.71.9.71   none          80/TCP    41m
[..skip..]

kubectl get pods

此操作会返回:

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

保存 NEG 的名称

找到在上述示例中创建的 NEG 并记下 NGE 的名称。

控制台

如需查看网络端点组的列表,请转到 Google Cloud Console 中的网络端点组页面。
转到网络端点组页面

gcloud

gcloud compute network-endpoint-groups list

此示例会返回以下内容:

NAME                 LOCATION          ENDPOINT_TYPE      SIZE
NEG-NAME           us-central1-a     GCE_VM_IP_PORT      1

将 NEG 名称保存在 NEG_NAME 变量中,例如:

NEG_NAME=$(gcloud compute network-endpoint-groups list \
| grep service-test | awk '{print $1}')

为 Cloud Service Mesh 配置 Google Cloud 负载均衡组件

本部分中的说明可确保使用与其他 Google Cloud Load Balancing 产品类似的负载均衡配置,在由 Cloud Service Mesh 进行负载均衡的服务 VIP 上可以访问 GKE 服务。

您必须配置以下组件:

下面的 Cloud Service Mesh 配置示例做出了以下假设:

  1. NEG 和所有其他资源是在区域 us-central1-adefault 网络中通过自动模式创建的。
  2. 集群的 NEG 名称存储在 ${NEG_NAME} 变量中。

创建健康检查

创建健康检查

控制台

  1. 转到 Google Cloud 控制台中的“健康检查”页面。
    转到“健康检查”页面
  2. 点击创建健康检查
  3. 对于名称,请输入 td-gke-health-check
  4. 对于协议,请选择 HTTP
  5. 点击创建

gcloud

gcloud compute health-checks create http td-gke-health-check \
  --use-serving-port

创建后端服务

使用负载平衡方案 INTERNAL_SERF_MANAGED 创建全局后端服务。在 Google Cloud 控制台中,负载均衡方案是隐式设置的。请将运行状况检查添加到后端服务。

控制台

  1. 前往 Google Cloud 控制台中的 Cloud Service Mesh 页面。

    前往 Cloud Service Mesh 页面

  2. 服务标签页上,点击创建服务

  3. 点击继续

  4. 对于服务名称,请输入 td-gke-service

  5. 后端类型下,选择网络端点组

  6. 选择您创建的网络端点组。

  7. RPS 上限设置为 5

  8. 点击完成

  9. 健康检查下,选择 td-gke-health-check,这是您创建的健康检查。

  10. 点击继续

gcloud

  1. 创建后端服务并将健康检查与后端服务相关联。

    gcloud compute backend-services create td-gke-service \
     --global \
     --health-checks td-gke-health-check \
     --load-balancing-scheme INTERNAL_SELF_MANAGED
    
  2. 将后端 NEG 添加到后端服务。

    gcloud compute backend-services add-backend td-gke-service \
     --global \
     --network-endpoint-group ${NEG_NAME} \
     --network-endpoint-group-zone us-central1-a \
     --balancing-mode RATE \
     --max-rate-per-endpoint 5
    

创建路由规则映射

按照以下说明为您的 Cloud Service Mesh 配置创建路由规则、转发规则和内部 IP 地址。

Envoy 代理会拦截发送到内部 IP 地址的流量,并根据主机和路径规则将其发送到相应的服务。

系统会将转发规则创建为全局转发规则,其中 load-balancing-scheme 设置为 INTERNAL_SELF_MANAGED

您可以将转发规则的地址设置为 0.0.0.0。如果您这样做,流量将根据网址映射中配置的 HTTP 主机名和路径信息进行路由,而不考虑该主机名解析到的实际 IP 地址。在这种情况下,主机规则中配置的服务网址(主机名和网址路径)在服务网格配置中必须是唯一的。也就是说,您不能拥有两项不同的服务,它们使用同一个主机名和路径组合,但具有不同的后端集。

或者,您也可以根据服务的实际目标 VIP 启用路由。如果您将服务的 VIP 配置为转发规则的 address 参数,则系统只会根据网址映射中指定的 HTTP 参数路由发往此 IP 地址的请求。

控制台

在 Console 中,目标代理已与转发规则相结合。创建转发规则时,Google Cloud 会自动创建目标 HTTP 代理并将其附加到网址映射。

路由规则由转发规则以及主机和路径规则(也称为网址映射)组成。

  1. 前往 Google Cloud 控制台中的 Cloud Service Mesh 页面。

    前往 Cloud Service Mesh 页面

  2. 点击路由规则映射

  3. 点击创建路由规则

  4. 输入 td-gke-url-map 作为网址映射的名称

  5. 点击添加转发规则

  6. 对于转发规则名称,请输入 td-gke-forwarding-rule

  7. 选择您的网络。

  8. 选择您的内部 IP

  9. 点击保存

  10. (可选)添加自定义主机和路径规则,或将路径规则保留为默认值。

  11. 将主机设置为 service-test

  12. 点击保存

gcloud

  1. 创建使用后端服务的网址映射。

    gcloud compute url-maps create td-gke-url-map \
       --default-service td-gke-service
    
  2. 创建网址映射路径匹配器和主机规则,以根据主机名和路径为您的服务路由流量。此示例使用 service-test 作为服务名称,并使用默认路径匹配器来匹配此主机 (/*) 的所有路径请求。service-test 也是上述示例配置中使用的 Kubernetes 服务的已配置名称。

    gcloud compute url-maps add-path-matcher td-gke-url-map \
       --default-service td-gke-service \
       --path-matcher-name td-gke-path-matcher
    
    gcloud compute url-maps add-host-rule td-gke-url-map \
       --hosts service-test \
       --path-matcher-name td-gke-path-matcher
    
  3. 创建目标 HTTP 代理。

    gcloud compute target-http-proxies create td-gke-proxy \
       --url-map td-gke-url-map
    
  4. 创建转发规则。

    gcloud compute forwarding-rules create td-gke-forwarding-rule \
      --global \
      --load-balancing-scheme=INTERNAL_SELF_MANAGED \
      --address=0.0.0.0 \
      --target-http-proxy=td-gke-proxy \
      --ports 80 --network default
    

此时,Cloud Service Mesh 配置为跨网络端点组中的后端,对网址映射中指定的服务进行流量负载平衡。

根据您的微服务在网络上的分布方式,您可能需要向网址映射添加更多转发规则或更多主机和路径规则。

通过为测试部署示例客户端来验证配置

本部分介绍如何从客户端应用访问 Cloud Service Mesh 后端。

为了演示功能,您可以部署运行 Busybox 的 Pod 示例。该 pod 可以访问 service-test(在上一部分中创建),并接收由 Cloud Service Mesh 进行负载均衡的流量。

将边车代理注入 GKE/Kubernetes pod

如需访问由 Cloud Service Mesh 管理的服务,Pod 必须安装与 xDS API 兼容的边车代理。

在此示例中,您部署一个 Busybox 客户端,并使用参考规范将 Istio 代理边车和 Init 容器添加到部署中。

如果您是使用旧版 API,请将 PROJECT_NUMBERNETWORK_NAME 变量替换为您的项目编号和网络名称:

wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_sample_xdsv3.yaml
sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_sample_xdsv3.yaml
sed -i "s/NETWORK_NAME/NETWORK_NAME/g" trafficdirector_client_sample_xdsv3.yaml
kubectl apply -f trafficdirector_client_sample_xdsv3.yaml

如果您是使用当前处于预览状态的新服务路由 API,请将 PROJECT_NUMBERMESH_NAME 变量替换为项目编号和 Mesh 名称:

wget -q -O - https://storage.googleapis.com/traffic-director/demo/trafficdirector_client_new_api_sample_xdsv3.yaml
sed -i "s/PROJECT_NUMBER/PROJECT_NUMBER/g" trafficdirector_client_new_api_sample_xdsv3.yaml
sed -i "s/MESH_NAME/MESH_NAME/g" trafficdirector_client_new_api_sample_xdsv3.yaml
kubectl apply -f trafficdirector_client_new_api_sample_xdsv3.yaml

Busybox Pod 有两个正在运行的容器。第一个容器是基于 Busybox 映像的客户端,第二个容器是作为 Sidecar 注入的 Envoy 代理。您可以通过运行以下命令来获取有关该 Pod 的更多信息:

kubectl describe pods -l run=client

访问后端服务

配置完成后,注入了边车代理的 Pod 上的应用可以访问由 Cloud Service Mesh 服务管理的服务。如需验证配置,您可以访问其中一个容器上的 Shell。

如果您使用了本指南中提供的演示配置,则可以执行以下验证命令以确保返回服务 Pod 的主机名。

# Get name of the Pod  with busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to execute that tests connectivity to the service service-test.
TEST_CMD="wget -q -O - service-test; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

了解 Sidecar 代理的流量拦截

请注意,在此示例中,当 Buybox 客户端向后端服务发出请求时,每个请求都由 Sidecar 代理进行代理。

此演示应用使用 Envoy 代理。因此,客户端会在服务器响应的标头中看到“server: envoy”。

如需确认这一点,请使用以下命令:

# Get the name of the Pod  with Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to send a request to service-test and output server response headers.
TEST_CMD="wget -S --spider service-test; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

在此示例中,您使用 VIP 地址 0.0.0.0 创建了转发规则。这意味着,Cloud Service Mesh 仅根据 Host 标头将请求转发到后端。在这种情况下,只要请求主机标头与网址映射 service-test 中定义的主机匹配,目标 IP 地址就可以是任何地址。

如需确认这一点,请运行以下测试命令:

# Get name of the Pod  with Busybox.
BUSYBOX_POD=$(kubectl get po -l run=client -o=jsonpath='{.items[0].metadata.name}')

# Command to send a request to service-test setting the Host header and using a random IP address.
TEST_CMD="wget -q --header 'Host: service-test' -O - 1.2.3.4; echo"

# Execute the test command on the Pod .
kubectl exec -it $BUSYBOX_POD -c busybox -- /bin/sh -c "$TEST_CMD"

后续步骤