设置节点内可见性


本指南介绍了如何在 Google Kubernetes Engine (GKE) 集群中设置节点内可见性

节点内可见性在集群中的每个节点上配置网络,以便从一个 Pod 发送到另一个 Pod 的流量由集群的 Virtual Private Cloud (VPC) 网络处理,即使这些 Pod 位于同一节点上也是如此。

默认情况下,节点内可见性在标准集群中处于停用状态,而在 Autopilot 集群中处于启用状态。

架构

节点内可见性可确保在 Pod 之间发送的数据包始终由 VPC 网络处理,从而确保防火墙规则、路由、流日志和数据包镜像配置应用于数据包。

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

节点内可见性会部署 netd DaemonSet。

优势

节点内可见性具有以下优势:

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

要求和限制

节点内可见性有以下要求和限制:

  • 您的集群必须为 GKE 1.15 或更高版本。
  • Windows Server 节点池不支持节点内可见性。
  • 如果您启用了节点内可见性,并使用了配置有 nonMasqueradeCIDRs 参数的 ip-masq-agent,则必须在 nonMasqueradeCIDRs 中添加 Pod CIDR 范围,以避免遇到节点内连接问题。

防火墙规则

启用节点内可见性后,VPC 网络会处理在 Pod 之间发送的所有数据包,包括在同一节点上的 Pod 之间发送的数据包。这意味着无论 Pod 位置如何,Pod 到 Pod 的通信都施行一致的 VPC 防火墙规则和分层防火墙政策。

如果您为集群内的通信配置自定义防火墙规则,请仔细评估集群的网络需求,以确定一组出站和入站许可规则。您可以使用连接测试来确保合法流量不受阻碍。例如,网络政策正常运行需要 Pod 到 Pod 的通信。

准备工作

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

  • 启用 Google Kubernetes Engine API。
  • 启用 Google Kubernetes Engine API
  • 如果您要使用 Google Cloud CLI 执行此任务,请安装初始化 gcloud CLI。 如果您之前安装了 gcloud CLI,请运行 gcloud components update 以获取最新版本。

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

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

gcloud

如需创建一个启用了节点内可见性的单节点集群,请使用 --enable-intra-node-visibility 标志:

gcloud container clusters create CLUSTER_NAME \
    --region=COMPUTE_REGION \
    --enable-intra-node-visibility

替换以下内容:

  • CLUSTER_NAME:新集群的名称。
  • COMPUTE_REGION:集群的 计算区域

控制台

如需创建一个启用了节点内可见性的单节点集群,请执行以下步骤:

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

  2. 点击 创建

  3. 输入集群的名称

  4. 配置集群对话框中,点击 GKE 标准旁边的配置

  5. 根据需要配置集群。

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

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

  8. 点击创建

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

您可以使用 gcloud CLI 或 Google Cloud Console 在现有集群上启用节点内可见性。

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

gcloud

如需在现有集群上启用节点内可见性,请使用 --enable-intra-node-visibility 标志:

gcloud container clusters update CLUSTER_NAME \
    --enable-intra-node-visibility

CLUSTER_NAME 替换为您的集群名称。

控制台

如需在现有集群上启用节点内可见性,请执行以下步骤:

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    前往 Google Kubernetes Engine

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

  3. 网络下,点击 修改节点内可见性

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

  5. 点击保存更改

停用节点内可见性

您可以使用 gcloud CLI 或 Google Cloud Console 在集群上停用节点内可见性。

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

gcloud

如需停用节点内可见性,请使用 --no-enable-intra-node-visibility 标志:

gcloud container clusters update CLUSTER_NAME \
    --no-enable-intra-node-visibility

CLUSTER_NAME 替换为您的集群名称。

控制台

如需停用节点内可见性,请执行以下步骤:

  1. 转到 Google Cloud 控制台中的 Google Kubernetes Engine 页面。

    转到 Google Kubernetes Engine

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

  3. 网络下,点击 修改节点内可见性

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

  5. 点击保存更改

练习:验证节点内可见性

本练习展示了启用节点内可见性并确认其适用于您的集群所需的步骤。

在本练习中,您将执行以下步骤:

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

启用流日志

  1. 为默认子网启用流日志:

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

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

    输出结果会显示已启用流日志,如下所示:

    ...
    enableFlowLogs: true
    ...
    

创建集群

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

    gcloud container clusters create flow-log-test \
        --zone=us-central1-a \
        --num-nodes=1 \
        --enable-intra-node-visibility
    
  2. 获取集群的凭据:

    gcloud container clusters get-credentials flow-log-test \
        --zone=us-central1-a
    

创建两个 Pod

  1. 创建一个 Pod。

    将以下清单保存到名为 pod-1.yaml 的文件中:

    apiVersion: v1
    kind: Pod
    metadata:
      name: pod-1
    spec:
      containers:
      - name: container-1
        image: us-docker.pkg.dev/google-samples/containers/gke/hello-app:1.0
    
  2. 将清单应用到您的集群:

    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: us-docker.pkg.dev/google-samples/containers/gke/hello-app:2.0
    
  4. 将清单应用到您的集群:

    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 的 IP 地址。

发送请求

  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, world!
    Version: 2.0.0
    Hostname: pod-2
    
  3. 输入 exit 以离开 shell 并返回到主命令行环境。

查看流日志条目

如需查看流日志条目,请使用以下命令:

gcloud logging read \
    'logName="projects/PROJECT_ID/logs/compute.googleapis.com%2Fvpc_flows" AND jsonPayload.connection.src_ip="POD_1_IP_ADDRESS" AND jsonPayload.connection.dest_ip="POD_2_IP_ADDRESS"'

替换以下内容:

  • PROJECT_ID:您的项目 ID。
  • POD_1_IP_ADDRESSpod-1 的 IP 地址。
  • POD_2_IP_ADDRESSpod-2 的 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. 删除集群:

    gcloud container clusters delete -q flow-log-test
    
  2. 停用默认子网的流日志:

    gcloud compute networks subnets update default --no-enable-flow-logs
    

后续步骤