设置节点内可见性

本指南介绍了如何在 Google Kubernetes Engine (GKE) 集群中设置节点内可见性,以便 Google Cloud 网络能够看到您的集群中的所有网络流量。

利用节点内可见性,您可以:

  • 查看 Pod 之间所有流量(包括同一节点上 Pod 之间的流量)的流日志
  • 创建应用于 Pod(甚至是同一节点上的 Pod)间所有流量的防火墙规则
  • 使用数据包镜像克隆同一节点上 Pod 之间的流量,并将其转发以供检查。

当一个 Pod 向同一节点上的另一个 Pod 发送数据包时,数据包将离开该节点并由 Google Cloud 网络处理。然后,数据包会立即发送回同一个节点并转发到目标 Pod。

节点内可见性在默认情况下处于停用状态。

如果您希望集群使用 MTU 为 1500 个字节的 VPC 网络,则需要节点内可见性。此外,集群的 GKE 版本必须为 1.15 或更高版本。如需详细了解 MTU 为 1500 个字节的 VPC 网络,请参阅 VPC 文档中的最大传输单元

需要考虑的事项

日志量增加

启用节点内可见性后,流日志量可能会随着 VPC 所捕获流量的增加而增加。您可以通过调整日志记录设置来管理与流日志记录相关的费用。

所有 Pod 间流量均受防火墙约束

启用节点内可见性时,Pod(包括部署到同一节点的 Pod)之间的所有流量均对 VPC 可见。启用节点内可见性可能会导致以前不受限制的流量遭到防火墙规则的约束。请使用连接测试评估您的节点级防火墙,以确保合法流量不受阻碍。

准备工作

在开始之前,请确保您已执行以下任务:

使用以下任一方法设定默认的 gcloud 设置:

  • 使用 gcloud init(如果您想要在系统引导下完成默认设置)。
  • 使用 gcloud config(如果您想单独设置项目 ID、区域和地区)。

使用 gcloud init

如果您收到 One of [--zone, --region] must be supplied: Please specify location 错误,请完成本部分。

  1. 运行 gcloud init 并按照说明操作:

    gcloud init

    如果您要在远程服务器上使用 SSH,请使用 --console-only 标志来防止命令启动浏览器:

    gcloud init --console-only
  2. 按照说明授权 gcloud 使用您的 Google Cloud 帐号。
  3. 创建新配置或选择现有配置。
  4. 选择 Google Cloud 项目。
  5. 为可用区级集群选择默认 Compute Engine 可用区,或为区域级集群或 Autopilot 集群选择区域。

使用 gcloud config

  • 设置默认项目 ID
    gcloud config set project PROJECT_ID
  • 如果您使用的是可用区级集群,请设置默认计算可用区
    gcloud config set compute/zone COMPUTE_ZONE
  • 如果您使用的是 Autopilot 集群或区域级集群,请设置默认计算区域
    gcloud config set compute/region COMPUTE_REGION
  • gcloud 更新到最新版本:
    gcloud components update

任务概览

为了演示如何设置节点内可见性,下面简要介绍了您所执行的任务:

  1. us-central1 区域中的默认子网启用流日志。
  2. 创建一个启用了节点内可见性的单节点集群。
  3. 在集群中创建两个 Pod。
  4. 从一个 Pod 向另一个 Pod 发送 HTTP 请求。
  5. 查看 Pod 到 Pod 请求的流日志条目。

本指南中的示例:

  • 使用 us-central1 作为默认区域。
  • 使用 us-central1-a 作为默认地区。

为子网启用流日志

您可以使用 gcloud 工具或 Google Cloud Console 为子网启用流日志

gcloud

  1. us-central1 区域中的默认子网启用流日志:

    gcloud compute networks subnets update default --region us-central1 \
        --enable-flow-logs
    
  2. 验证您的子网是否已启用流日志:

    gcloud compute networks subnets describe default --region us-central1
    

    输出会显示已启用流日志:

    ...
    enableFlowLogs: true
    ...
    ipCidrRange: 10.128.0.0/20
    region: https://www.googleapis.com/compute/v1/projects/abc-712099/regions/us-central1
    

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine“VPC 网络”页面。

    访问“VPC 网络”页面

  2. us-central1 行中,点击默认

  3. 子网详情页面上,点击 修改

  4. 流日志下,选择开启

  5. 点击保存

创建一个启用了节点内可见性的集群

您可以使用 gcloud 工具或 Google Cloud Console 创建一个启用了节点内可见性的集群。

gcloud

创建一个启用了节点内可见性的单节点集群:

gcloud container clusters create cluster-name \
    --zone us-central1-a \
    --num-nodes 1 \
    --enable-intra-node-visibility

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 点击 创建

  3. 输入集群的名称

  4. 对于位置类型,选择地区

  5. 地区下拉列表中,选择 us-central1-a

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

  7. 输入节点池名称

  8. 对于静态版本节点,请选择节点版本

  9. 对于节点数,请输入 1

  10. 在导航窗格的集群下,点击网络

  11. 选中启用节点内可见性复选框。

  12. 点击创建

为您的集群获取凭据

为您的新集群获取凭据:

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

凭据会保存在您的 kubeconfig 文件中,该文件通常位于 $HOME/.kube/config

创建两个 Pod

  1. 对于第一个 Pod,请根据以下示例清单创建一个名为 pod-1.yaml 的文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-1
    spec:
      containers:
      - name: container-1
        image: gcr.io/google-samples/hello-app:2.0
    
  2. 通过运行以下命令创建 Pod:

    kubectl apply -f pod-1.yaml
    
  3. 对于第二个 Pod,请根据以下示例清单创建一个名为 pod-2.yaml 的文件:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-2
    spec:
      containers:
      - name: container-2
        image: gcr.io/google-samples/node-hello:1.0
    
  4. 通过运行以下命令创建 Pod:

    kubectl apply -f pod-2.yaml
    
  5. 查看 Pod:

    kubectl get pod pod-1 pod-2 --output wide
    

    输出会显示 Pod 的 IP 地址。记下这些地址。

    NAME      READY     STATUS    RESTARTS   AGE       IP           ...
    pod-1     1/1       Running   0          1d        10.52.0.13   ...
    pod-2     1/1       Running   0          1d        10.52.0.14   ...
    

pod-1pod-2 发送请求

  1. 获取连接至 pod-1 中容器的 shell:

    kubectl exec -it pod-1 sh
    
  2. 在您的 shell 中,向 pod-2 发送请求:

    wget -qO- pod-2-ip-address:8080
    

    其中,pod-2-ip-address 是您之前记下的 pod-2 的 IP 地址。

    输出会显示 pod-2 中运行的容器返回的响应:

    Hello Kubernetes!
    
  3. 输入 exit 以退出 shell 并返回到主命令行环境。

查看流日志条目

您可以使用 gcloud 工具或 Google Cloud Console 查看流日志条目。

gcloud

查看与从 pod-1pod-2 发送的请求相关的流日志条目:

gcloud logging read \
    'logName="projects/project-id/logs/compute.googleapis.com%2Fvpc_flows" AND jsonPayload.connection.src_ip="pod-1-ip-address"'

其中:

  • project-id 是您的项目 ID。
  • pod-1-ip-addresspod-1 的 IP 地址。

输出显示与从 pod-1pod-2 发送的请求相关的流日志条目。在本示例中,pod-1 的 IP 地址为 10.56.0.13,而 pod-2 的 IP 地址为 10.56.0.14

...
jsonPayload:
  bytes_sent: '0'
  connection:
    dest_ip: 10.56.0.14
    dest_port: 8080
    protocol: 6
    src_ip: 10.56.0.13
    src_port: 35414
...

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine“Stackdriver 日志”页面。

    访问“Stackdriver 日志”页面

  2. 在过滤条件字段中,点击 ,然后点击转换为高级过滤条件

  3. 将过滤条件字段中的任何文本替换为以下内容:

    resource.type="gce_subnetwork"
    logName="projects/project-id/logs/compute.googleapis.com%2Fvpc_flows"
    jsonPayload.connection.src_ip="pod-1-ip-address"
    

    请替换以下内容:

    • project-id 是项目 ID。
    • pod-1-ip-addresspod-1 的 IP 地址。
  4. 展开显示的日志条目。在 jsonPayload 下,您可以看到请求已从 pod-1 发送到 pod-2。在以下示例中,pod-1 的 IP 地址为 10.56.0.13,pod-2 的 IP 地址为 10.56.0.14。

    jsonPayload: {
      bytes_sent:  "0"
      connection: {
        dest_ip:  "10.56.0.14"
        dest_port:  8080
        protocol:  6
        src_ip:  "10.56.0.13"
        src_port:  35414
    

回想一下,您的集群只有一个节点。因此,pod-1pod-2 位于同一个节点上。即便如此,pod-1pod-2 之间的节点内通信也会产生流日志条目。

在现有集群上启用节点内可见性

您可以使用 gcloud 工具或 Google Cloud Console 为现有集群启用节点内可见性。

gcloud

gcloud beta container clusters update cluster-name \
    --enable-intra-node-visibility

其中,cluster-name 是您的现有集群的名称。

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 菜单。

    访问 Google Kubernetes Engine 菜单

  2. 在集群列表中,点击您要修改的集群的名称。

  3. 网络下,点击节点内可见性字段旁边的 修改节点内可见性

  4. 选中启用节点内可见性复选框。

  5. 点击保存更改

如果您为现有集群启用节点内可见性,则将重启控制层面和工作器节点中的组件。

启用此功能后,您可以通过检查节点上的路由规则来确认其已激活:

  1. 显示 IP 规则:

    ip rule show
    

    输出类似于以下内容:

    0:  from all lookup local
    30001:  from all fwmark 0x4000/0x4000 lookup main
    30002:  from all iif lo lookup main
    30003:  not from all iif eth0 lookup 1
    32766:  from all lookup main
    32767:  from all lookup default
    
  2. 显示 IP 路由:

    ip route show table 1
    

    输出类似于以下内容:

    default via GKE-node-subnet-gw dev eth0
    

停用节点内可见性

您可以使用 gcloud 工具或 Google Cloud Console 为现有集群停用节点内可见性。

gcloud

gcloud beta container clusters update cluster-name \
    --no-enable-intra-node-visibility

其中,cluster-name 是您的现有集群的名称。

控制台

  1. 访问 Cloud Console 中的 Google Kubernetes Engine 页面。

    访问 Google Kubernetes Engine 页面

  2. 在集群列表中,点击您要修改的集群的名称。

  3. 网络下,点击节点内可见性字段旁边的 修改节点内可见性

  4. 取消选中启用节点内可见性复选框。

  5. 点击保存更改

如果您为现有集群停用节点内可见性,则将重启控制层面和工作器节点中的组件。

限制

启用了节点内可见性的集群具有以下限制:

  • 如果您启用了节点内可见性,并使用了配置有 nonMasqueradeCIDRs 参数的 ip-masq-agent,则 nonMasqueradeCIDRs 需要包含 Pod CIDR,否则您可能会遇到节点内连接问题。

后续步骤