为 Google Kubernetes Engine Pod 进行自动 Envoy 注入的 Traffic Director 设置

概览

在服务网格中,您的应用代码不需要了解网络配置。相反,您的应用通过数据平面进行通信,该数据平面由处理服务网络的控制平面进行配置。在本指南中,Traffic Director 是您的控制平面,而 Envoy Sidecar 代理是您的数据平面。

Envoy Sidecar 注入器可轻松将 Envoy Sidecar 代理添加到您的 Google Kubernetes Engine Pod 中。在 Envoy Sidecar 注入器添加代理时,它还会设置该代理以处理应用流量并连接到 Traffic Director 以进行配置。

本指南将逐步介绍 Google Kubernetes Engine 的 Traffic Director 设置。这些步骤为扩展到高级使用场景奠定了基础,例如扩展到多个 Google Kubernetes Engine 集群以及 Compute Engine 虚拟机的服务网格。

设置过程包括:

  1. 为您的工作负载创建 GKE 集群。
  2. 安装 Envoy Sidecar 注入器并启用注入。
  3. 部署样本客户端并验证注入。
  4. 部署 Kubernetes 服务以进行测试。
  5. 使用 Cloud Load Balancing 组件配置 Traffic Director,以将流量路由到测试服务。
  6. 从示例客户端向测试服务发送请求以验证配置。
在此设置指南中部署的组件概览(点击可放大)
在此设置指南中部署的组件概览(点击可放大)

前提条件

在按照本指南中的说明进行操作之前,请先查看设置 Traffic Director 前的准备工作,并确保您已完成该文档中所述的前提任务。

为您的工作负载创建 GKE 集群

GKE 集群必须满足以下要求才能支持 Traffic Director:

创建 GKE 集群

us-central1-a 区域创建一个名为 traffic-director-cluster 的 GKE 集群。

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

将 kubectl 指向新创建的集群

发出以下命令,将 kubectl 的当前上下文更改为新创建的集群:

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

安装 Envoy Sidecar 注入器

以下部分提供了安装 Envoy Sidecar 注入器的说明。启用 Sidecar 注入器后,它将自动为新的和现有的 Google Kubernetes Engine 工作负载部署 Sidecar 代理。因为 Envoy Sidecar 注入器在 GKE 集群内运行,所以如果要使用 Traffic Director 支持多集群服务网格,则需要将其安装到每个集群一次。

下载 Sidecar 注入器

下载并解压缩 Envoy Sidecar 注入器。

wget https://storage.googleapis.com/traffic-director/td-sidecar-injector.tgz
tar -xzvf td-sidecar-injector.tgz
cd td-sidecar-injector

配置 Sidecar 注入器

修改 specs/01-configmap.yaml 以配置Sidecar注入器:

  • your-project-here 替换为项目编号以填充TRAFFICDIRECTOR_GCP_PROJECT_NUMBER。项目编号是您的项目的数字标识符。如需了解如何获取所有项目列表,请参阅识别项目
  • TRAFFICDIRECTOR_NETWORK_NAME 替换为要用于 Traffic Director 的 Google Cloud Virtual Private Cloud 网络名称以填充 your-network-here。记下此 VPC 网络名称,因为稍后配置 Traffic Director 时将会用到。

您还可以选择为每个自动注入的代理启用日志记录和跟踪。如需详细了解这些配置,请参阅为 Sidecar 代理配置其他属性

请注意,TRAFFICDIRECTOR_INTERCEPTION_PORT 不应在此 ConfigMap 中配置,因为 Sidecar 注入器已对其进行配置。

为 Sidecar 注入器配置传输层安全协议 (TLS)

本部分介绍如何为 Sidecar 注入器配置传输层安全协议 (TLS)。

Sidecar 注入器使用 Kubernetes 更改准入网络钩子在创建新 pod时注入代理。此网络钩子是一个 HTTPS 端点,因此您需要提供密钥和传输层安全协议 (TLS) 证书。

您可以使用 openssl 创建私钥和自签名证书以保护 Sidecar 注入器。

如果您有私钥和由可信证书授权机构 (CA) 签名的证书,则可以跳过这一步。

CN=istio-sidecar-injector.istio-control.svc

openssl req \
  -x509 \
  -newkey rsa:4096 \
  -keyout key.pem \
  -out cert.pem \
  -days 365 \
  -nodes \
  -subj "/CN=${CN}"

cp cert.pem ca-cert.pem

此示例 openssl 命令会向 key.pem 输出一个 4096 位 RSA 私钥,并向 cert.pem 输出一个 X.509 格式的自签名证书。因为证书是自签名的,所以证书被复制到 ca-cert.pem,并且被视为由 CA 签名的证书。证书在 365 天内有效,无需密码。如需详细了解如何创建证书和签名,请参阅有关证书签名请求的 Kubernetes 文档。

必须每年重复执行本部分中的步骤,以在密钥和证书过期之前重新生成并应用。

获取密钥和证书后,您必须创建一个 Kubernetes Secret 并更新 Sidecar 注入器的网络钩子。

  1. 创建要在其下创建 Kubernetes Secret 的命名空间:

    kubectl apply -f specs/00-namespaces.yaml
    
  2. 为 Sidecar 注入器创建 Secret。

    kubectl create secret generic istio-sidecar-injector -n istio-control \
      --from-file=key.pem \
      --from-file=cert.pem \
      --from-file=ca-cert.pem
    
  3. 修改 specs/02-injector.yaml 中名为 istio-sidecar-injector-istio-control 的 Sidecar 注入网络钩子的caBundle

    CA_BUNDLE=$(cat cert.pem | base64 | tr -d '\n')
    sed -i "s/caBundle:.*/caBundle:\ ${CA_BUNDLE}/g" specs/02-injector.yaml
    

将 Sidecar 注入器安装到 GKE 集群

  1. 部署Sidecar 注入器。

    kubectl apply -f specs/
    
  2. 验证Sidecar 注入器正在运行。

    kubectl get pods -A | grep sidecar-injector
    

    这将返回如下所示的输出:

    istio-control   istio-sidecar-injector-6b475bfdf9-79965  1/1 Running   0   11s
    istio-control   istio-sidecar-injector-6b475bfdf9-vntjd  1/1 Running   0   11s
    

启用 Sidecar 注入

以下命令为 default 命名空间启用注入。Sidecar 注入器会将 Sidecar容器注入在此命名空间下创建的 pod:

kubectl label namespace default istio-injection=enabled

您可以运行以下命令来验证 default 命名空间是否已正确启用:

kubectl get namespace -L istio-injection

此时应返回:

NAME              STATUS   AGE     ISTIO-INJECTION
default           Active   7d16h   enabled
istio-control     Active   7d15h
istio-system      Active   7d15h

部署示例客户端并验证注入

本部分介绍如何部署运行 Busybox 的示例 pod,它提供了一个简单的接口,可连接测试服务。在实际部署中,您应改为部署自己的客户端应用。

kubectl create -f demo/client_sample.yaml

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

kubectl describe pods -l run=client

此时应返回:

…
Init Containers:
# Istio-init sets up traffic interception for the pod.
  Istio-init:
…
Containers:
# busybox is the client container that runs application code.
  busybox:
…
# Istio-proxy is the container that runs the injected Envoy proxy.
  Istio-proxy:
…

部署 Kubernetes 服务以进行测试

下文将介绍如何设置测试服务,您将在本指南的后面部分使用该测试服务提供设置的端到端验证。

使用 NEG 配置 GKE 服务

GKE 服务必须通过网络端点组 (NEG) 公开,以便您可以将它们配置为 Traffic Director 服务的后端。

...
metadata:
  annotations:
    cloud.google.com/neg: '{"exposed_ports":{"80":{}}}'

此注释创建一个独立的 NEG,其中包含与服务 pod 的 IP 地址和端口相对应的端点。如需了解详情和示例,请参阅独立网络端点组

以下示例服务包括 NEG 注释。该服务在端口 80 上通过 HTTP 提供主机名。使用以下命令获取该服务并将其部署到 GKE 集群。

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

验证与此服务关联的应用 pod 是否正在运行:

kubectl get pods
此操作会返回:
NAME                        READY     STATUS    RESTARTS   AGE
app1-6db459dcb9-zvfg2       2/2       Running   0          6m
[..skip..]

保存 NEG 的名称

找到在上述示例中创建的 NEG 并记下其名称,以用于下一部分的 Traffic Director 配置。

gcloud compute network-endpoint-groups list

此操作会返回:

NAME                                           LOCATION       ENDPOINT_TYPE SIZE
k8s1-7e91271e-default-service-test-80-a652810c  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 Load Balancing 组件配置 Traffic Director

本部分使用 Compute Engine 负载平衡资源配置 Traffic Director。这样一来,示例客户端的 Sidecar 代理即可接收来自 Traffic Director 的配置。来自示例客户端的出站请求由 Sidecar 代理处理并路由到测试服务。

您必须配置以下组件:

创建运行状况检查和防火墙规则

控制台

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

  6. 转到 Google Cloud Console 中的“防火墙”页面。
    转到“防火墙”页面

  7. 点击创建防火墙规则

  8. 在“创建防火墙规则”页面上,提供如下信息:

    • 名称:提供规则的名称。本示例使用的是 fw-allow-health-checks
    • 网络:选择一个 VPC 网络。
    • 优先级:输入一个表示优先级的数字。这个数字越小,优先级就越高。请确保防火墙规则的优先级高于可能会拒绝入站流量的其他规则的优先级。
    • 流量方向:选择入站
    • 匹配时执行的操作:选择允许
    • 目标:选择网络中的所有实例
    • 来源过滤条件:选择 IP 地址范围
    • 来源 IP 地址范围35.191.0.0/16,130.211.0.0/22
    • 允许的协议和端口:使用 tcp。TCP 是所有运行状况检查协议的底层协议。
    • 点击创建

gcloud

  1. 创建运行状况检查

    gcloud compute health-checks create http td-gke-health-check \
      --use-serving-port
    
  2. 创建防火墙规则以允许运行状况检查程序 IP 地址范围。

    gcloud compute firewall-rules create fw-allow-health-checks \
      --action ALLOW \
      --direction INGRESS \
      --source-ranges 35.191.0.0/16,130.211.0.0/22 \
      --target-tags td-http-server \
      --rules tcp:80
    

创建后端服务

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

控制台

  1. 转到 Cloud Console 中的 Traffic Director 页面。

    转到 Traffic Director 页面

  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
    

创建路由规则映射

路由规则映射定义了 Traffic Director 如何路由您的流量。作为路由规则映射的一部分,您可以配置虚拟 IP (VIP) 地址和一组关联的流量管理规则,例如基于主机的路由。当应用向 VIP 发送请求时,附加的 Envoy Sidecar 代理将执行以下操作:

  1. 拦截请求。
  2. 根据网址映射中的流量管理规则对其进行评估。
  3. 根据请求中的主机名选择后端服务。
  4. 选择与所选后端服务关联的后端或端点。
  5. 将流量发送到该后端或端点。

控制台

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

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

  1. 转到 Cloud Console 中的 Traffic Director 页面。

    转到 Traffic Director 页面

  2. 点击路由规则映射

  3. 点击创建路由规则

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

  5. 点击添加转发规则

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

  7. 选择您的网络。

  8. 选择您的内部 IP

  9. 点击保存

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

  11. 将主机设置为 service-test

  12. 点击保存

gcloud

  1. 创建将 td-gke-service 用作默认后端服务的网址映射。

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

    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
    

此时,Traffic Director 将您的 Sidecar 代理配置为将指定 service-test 主机名的请求路由到 td-gke-service 的后端。在此示例中,这些后端是与您之前部署的 Kubernetes 测试服务关联的网络端点组中的端点。

验证配置

本部分介绍如何验证从示例 Busybox 客户端发送的流量是否路由到您的 service-test Kubernetes 服务。如需发送测试请求,您可以在其中一个容器上访问 shell并执行以下验证命令。service-test pod 应返回服务 pod 的主机名。

# Get the name of the pod running 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"

验证配置的方法如下:

  • 示例客户端发送一个指定service-test主机名的请求。
  • 示例客户端具有由 Envoy Sidecar 注入器注入的 Envoy Sidecar 代理。
  • Sidecar 代理拦截该请求。
  • 由于您在路由规则映射中将 0.0.0.0 配置为 VIP,因此 Envoy 会检查请求的主机名。
  • Envoy 使用网址映射匹配 service-test 主机名与 td-gke-service Traffic Director 服务。
  • Envoy 从与 td-gke-service 关联的网络端点组中选择一个端点。
  • Envoy 将请求发送到与 service-test Kubernetes 服务关联的 pod。

后续步骤

根据您的微服务在网络上的分布方式,您可能需要向网址映射添加更多转发规则或更多主机和路径规则。 如需详细了解转发规则和网址映射,请阅读以下文档: