本指南介绍了如何在 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 可见。启用节点内可见性可能会导致以前不受限制的流量遭到防火墙规则的约束。请使用连接测试评估您的节点级防火墙,以确保合法流量不受阻碍。
准备工作
在开始之前,请确保您已执行以下任务:
- 确保您已启用 Google Kubernetes Engine API。 启用 Google Kubernetes Engine API
- 确保您已安装 Cloud SDK。
使用以下任一方法设定默认的 gcloud
设置:
- 使用
gcloud init
(如果您想要在系统引导下完成默认设置)。 - 使用
gcloud config
(如果您想单独设置项目 ID、区域和地区)。
使用 gcloud init
如果您收到 One of [--zone, --region] must be supplied: Please specify
location
错误,请完成本部分。
-
运行
gcloud init
并按照说明操作:gcloud init
如果您要在远程服务器上使用 SSH,请使用
--console-only
标志来防止命令启动浏览器:gcloud init --console-only
-
按照说明授权
gcloud
使用您的 Google Cloud 帐号。 - 创建新配置或选择现有配置。
- 选择 Google Cloud 项目。
- 选择默认的 Compute Engine 区域。
使用 gcloud config
任务概览
为了演示如何设置节点内可见性,下面简要介绍了您所执行的任务:
- 为
us-central1
区域中的默认子网启用流日志。 - 创建一个启用了节点内可见性的单节点集群。
- 在集群中创建两个 Pod。
- 从一个 Pod 向另一个 Pod 发送 HTTP 请求。
- 查看 Pod 到 Pod 请求的流日志条目。
本指南中的示例:
- 使用
us-central1
作为默认区域。 - 使用
us-central1-a
作为默认地区。
为子网启用流日志
您可以使用 gcloud
工具或 Google Cloud Console 为子网启用流日志。
gcloud
为
us-central1
区域中的默认子网启用流日志:gcloud compute networks subnets update default --region us-central1 \ --enable-flow-logs
验证您的子网是否已启用流日志:
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
控制台
访问 Cloud Console 中的 Google Kubernetes Engine“VPC 网络”页面。
在 us-central1 行中,点击默认。
点击修改。
在流日志下,选择开启。
点击保存。
创建一个启用了节点内可见性的集群
您可以使用 gcloud
工具或 Google Cloud Console 创建一个启用了节点内可见性的集群。
gcloud
创建一个启用了节点内可见性的单节点集群:
gcloud container clusters create cluster-name \
--zone us-central1-a \
--num-nodes 1 \
--enable-intra-node-visibility
控制台
访问 Cloud Console 中的 Google Kubernetes Engine 菜单。
点击创建集群按钮。
输入集群的名称。
对于位置类型,选择地区。
在地区下拉列表中,选择 us-central1-a。
在导航窗格的节点池下,点击默认池 (default-pool)。
输入节点池的名称。
为您的节点选择节点版本。
对于节点数,请输入
1
。在导航窗格的集群下,点击网络。
选中启用节点内可见性复选框。
点击创建。
为您的集群获取凭据
为您的新集群获取凭据:
gcloud container clusters get-credentials cluster-name \
--zone us-central1-a
凭据会保存在您的 kubeconfig 文件中,该文件通常位于 $HOME/.kube/config
。
创建两个 Pod
对于第一个 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
通过运行以下命令创建 Pod:
kubectl apply -f pod-1.yaml
对于第二个 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
通过运行以下命令创建 Pod:
kubectl apply -f pod-2.yaml
查看 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-1
向 pod-2
发送请求
获取连接至
pod-1
中容器的 shell:kubectl exec -it pod-1 sh
在您的 shell 中,向
pod-2
发送请求:wget -qO- pod-2-ip-address:8080
其中,pod-2-ip-address 是您之前记下的
pod-2
的 IP 地址。输出会显示
pod-2
中运行的容器返回的响应:Hello Kubernetes!
输入
exit
以退出 shell 并返回到主命令行环境。
查看流日志条目
您可以使用 gcloud
工具或 Google Cloud Console 查看流日志条目。
gcloud
查看与从 pod-1
向 pod-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-address 是
pod-1
的 IP 地址。
输出显示与从 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
...
控制台
访问 Cloud Console 中的 Google Kubernetes Engine“Stackdriver 日志”页面。
在页面顶部右侧的“过滤条件”框中,点击向下箭头,然后选择转换为高级过滤条件。
删除“过滤条件”框中的所有文本,然后输入以下查询:
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-address 是
pod-1
的 IP 地址。
展开显示的日志条目。在
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-1
和 pod-2
位于同一个节点上。即便如此,pod-1
和 pod-2
之间的节点内通信也会产生流日志条目。
在现有集群上启用节点内可见性
您可以使用 gcloud
工具或 Google Cloud Console 为现有集群启用节点内可见性。
gcloud
gcloud beta container clusters update cluster-name \
--enable-intra-node-visibility
其中,cluster-name 是您的现有集群的名称。
控制台
访问 Cloud Console 中的 Google Kubernetes Engine 菜单。
点击集群的“修改”按钮 edit(铅笔图案)。
启用节点内可见性。
点击保存。
如果您为现有集群启用节点内可见性,则将重启控制层面和工作器节点中的组件。
启用此功能后,您可以通过检查节点上的路由规则来确认其已激活:
显示 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
显示 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 是您的现有集群的名称。
控制台
访问 Cloud Console 中的“Kubernetes 集群”页面。
点击集群的“修改”按钮 edit(铅笔图案)。
从节点内可见性下拉菜单中,选择已停用。
点击保存。
如果您为现有集群停用节点内可见性,则将重启控制层面和工作器节点中的组件。
限制
启用了节点内可见性的集群具有以下限制:
- 如果您启用了节点内可见性,并使用了配置有
nonMasqueradeCIDRs
参数的 ip-masq-agent,则nonMasqueradeCIDRs
需要包含 Pod CIDR,否则您可能会遇到节点内连接问题。