网络连通性基础测试
本文介绍采用了 kubernetes 官方自带的 e2e 测试框架,对于 kubernetes 集群中的网络连通性进行了全面测试的原理与方法。关于 kubernetes e2e test framework,可以参考 Kubernetes End-to-end Testing for Everyone,此处不再详述。
测试原理
k8s 中网络连通性的 e2e 测试主要包括以下几个方面:
- Pod 与 Pod 互通
- Pod 与 Node 互通
- Pod 与 Service 互通
下面分别对这几个项目详细介绍。
Pod 与 Pod 互通
为了测试网络方案的全面可靠,首先需要进行的测试是 Pod 与 Pod 间的网络互通,包括 HTTP 协议、UDP 协议的测试。
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- testPod 直接通过 netserver Pod 的 Pod IP 来访问
下面是 e2e 测试代码:
|
|
Pod 与 Node 互通
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- testPod 直接通过 netserver Pod 的 Pod IP 来访问
- 这里的 testPod 采用 hostNetworking 网络模式
|
|
Pod 与 Service 互通
pod-Service
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- testPod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
node-Service
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- testPod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
- 这里的 testPod 采用 hostNetworking 网络模式
endpoint-Service
- 在集群的每个节点创建一个 netserver 的 Endpoint Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- 在 Endpoint Pod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- 在 Endpoint Pod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
Multi-Endpoint Service with same selector
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建第二个 NodePortService,与第一个 NodePortService 采用相同的 selector
- 在 Endpoint Pod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- 在 Endpoint Pod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
- 测试两个 service 同时存在的时候可以访问连通,只存在一个的时候也都可以访问连通
Update Endpoint
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- 删除 netserver 的一个 EndPoint 后,等待 kube-proxy 同步
- testPod 再次通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
NodePort UDP
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 这里的 testPod 采用 hostNetworking 网络模式
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
Update NodePort
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 这里的 testPod 采用 hostNetworking 网络模式
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
- 删除 NodePort Service 后,等待 kube-proxy 同步
- testPod 再次通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性,此时应当不再连通
SessionAffinity Service
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口,设置该 Service 的 SessionAffinity 为 ClusterIP
- 在 Endpoint Pod 通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
Large Request
- 在集群的每个节点创建一个 netserver 的 Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- 这里访问连通性的是否会传递大消息,大小为 2 KBytes
HostNetwork
- 在集群的每个节点创建一个 netserver 的EndPoint Pod 作为 webserver 暴露 TCP 8080 端口和 UDP 8081 端口,这里 EndPoint Pod 采用 HostNetwork 网络模式
- 创建一个 test Pod 作为 client 连接 netserver 的 TCP 或 UDP 端口,检查端口访问连通性
- 创建一个 NodePortService, 暴露 TCP 8080 端口和 UDP 8081 端口
- testPod 直接通过 NodePort Service 的 ClusterIP 来访问 netserver 检查端口访问连通性
- testPod 直接通过 NodePort Service 的 NodeIP 来访问 netserver 检查端口访问连通性
测试方法
基本方法
下载 k8s 代码,并checkout到指定分支,这里以 release-1.20 为例
|
|
build e2e测试 manifest
|
|
生成 e2e.test 二进制
|
|
登陆到待测试k8s集群节点,上传e2e.test到指定节点,配置e2e.test需要的镜像仓库列表
|
|
执行e2e测试,这里以 Networking 为例
|
|
也可以使用 ginkgo
|
|
使用技巧
- 根据使用的 k8s 版本不同,e2e 可能依赖的部分 image 来自于 gcr,在国内的主机可能因为防火墙拉不下来,要手动拉取。
|
|
- focus=Networking 中主要的测试case来自于
kubernetes/test/e2e/network/networking.go,其中一项测试是测试集群连通外部网络的连通性,代码中通过访问google.com来测试。在国内,因为防火墙的因素可能无法访问导致此项测试不通过,可以修改此处代码为baidu.com或者其他来修复。
- focus 语法实际上是通过正则表达式来匹配要进行测试的case,只是指定
Networking可能测试的case比较多,可以进行更加细粒度的规则。比如:
|
|
这里的focus中的语法来自于 ginkgo 中 Describe 语法。一般跑完一次测试时间相对较长,在跑完一遍完整测试后,可以通过这种细粒度的语法单独对没通过的case进行再测试与分析。
- 基本的连通性只需要 focus 在 Networking 即可,如果想要进行更详细的测试,比如 NetworkPolicy、DNS、双栈或者其他测试,可以再单独测试,下面列出了 k8s 1.18 中所有会测试到的case。对于后续版本可能会有部分更新。
- 如果利用 k8s 1.18 跑 Networking 的测试,可能碰到
Requires at least 2 nodes (not 0)的报错信息一直卡住,这是因为 k8s 的 bug,换成 k8s 1.20 就好了。
这里是在检查可调度的 Node 是否 < minNodeCount(这里设置的是2),但是 framework.TestContext.CloudConfig.NumNodes 为 0
|
|
但是这个 TestContext.CloudConfig.NumNodes 并没有被真正赋值过,赋值的是 framework.TestContext.CloudConfig.NumNodes
查看 framework.TestContext.CloudConfig.NumNodes 在哪里赋值的,通过 k8s client 查询集群实际可用的Node进行赋值
|
|
换成 1.20 的版本:
|
|
测试结果
这里基于腾讯云 TKE 全局路由网络方案进行了全面的 e2e 测试,测试详细数据如下:
| 测试功能 | 全局路由测试结果 tke1.18.4 |
|---|---|
| should provide Internet connection for containers [Feature:Networking-IPv4] | 支持 |
| should provide Internet connection for containers [Feature:Networking-IPv6][Experimental][LinuxOnly] | 不支持 |
| should provide unchanging, static URL paths for kubernetes api services | 支持 |
| should check kube-proxy urls | 支持 |
| should function for pod-Service: http | 支持 |
| should function for pod-Service: udp | 支持 |
| should function for pod-Service: sctp [Feature:SCTPConnectivity][Disruptive] | 不支持 |
| should function for node-Service: http | 支持 |
| should function for node-Service: udp | 支持 |
| should function for endpoint-Service: http | 支持 |
| should function for endpoint-Service: udp | 支持 |
| should function for endpoint-Service: sctp [Feature:SCTPConnectivity][Disruptive] | 不支持 |
| should function for multiple endpoint-Services with same selector | 支持 |
| should update endpoints: http | 支持 |
| should update endpoints: udp | 支持 |
| should update nodePort: http [Slow] | 支持 |
| should update nodePort: udp [Slow] | 支持 |
| should support basic nodePort: udp functionality | 支持 |
| should function for client IP based session affinity: http [LinuxOnly] | 支持 |
| should function for client IP based session affinity: udp [LinuxOnly] | 支持 |
| should be able to handle large requests: http | 支持 |
| should be able to handle large requests: udp | 支持 |
| should function for pod-Service(hostNetwork): udp | 支持 |
| should function for service endpoints using hostNetwork | 不支持 |
| should recreate its iptables rules if they are deleted [Disruptive] | 支持 |
| should function for intra-pod communication: http [NodeConformance] | 支持 |
| should function for intra-pod communication: udp [NodeConformance] | 支持 |
| should function for intra-pod communication: sctp [LinuxOnly][Feature:SCTPConnectivity][Disruptive] | 不支持 |
| should function for node-pod communication: http [LinuxOnly] [NodeConformance] | 支持 |
| should function for node-pod communication: udp [LinuxOnly] [NodeConformance] | 支持 |
- 目前 TKE 尚未支持 Pod 间通信 SCTP 协议,所以可以看到关于 SCTP 的相关测试都不通过。
- 目前 TKE 尚未支持 IPv4/ IPv6 双栈,所以关于 IPv6 的测试没有通过
-
No backlinks found.