非常好的问题!验证 Kubernetes Service(svc)是否正常工作,是日常开发和运维的核心技能。下面我为你设计 5 个由浅入深的动手实验 ,全部基于命令行操作,你可以在自己的集群(如你的 k8s-master-node)上直接运行。
🧪 实验前提
确保你已有一个运行中的 Pod(我们用 Nginx 作为示例):
ini
# 创建 Deployment
kubectl create deployment nginx --image=nginx --replicas=2
# 等待 Pod Running
kubectl get pods -l app=nginx
🔬 实验 1:创建 ClusterIP Service 并从集群内访问
✅ 目标:验证 Service 能在集群内部负载均衡
步骤:
ini
# 1. 创建 ClusterIP Service
kubectl expose deployment nginx --port=80 --target-port=80 --name=nginx-svc
# 2. 查看 Service 和 Endpoints
kubectl get svc nginx-svc
kubectl get endpoints nginx-svc # 应显示 2 个 Pod IP
# 3. 启动一个临时调试 Pod(busybox)
kubectl run debug --image=busybox:1.28 -it --rm --restart=Never -- sh
# 在 debug 容器内执行:
/ # wget -qO- http://nginx-svc
/ # wget -qO- http://nginx-svc
✅ 预期结果:
- 每次请求可能返回不同 Pod 的欢迎页(虽然内容一样,但可通过日志区分)
- 证明 Service 做了负载均衡
💡 提示:你可以进入每个 Nginx Pod 添加唯一标识:
csskubectl exec <pod1> -- sh -c 'echo "<h1>Pod 1</h1>" > /usr/share/nginx/html/index.html' kubectl exec <pod2> -- sh -c 'echo "<h1>Pod 2</h1>" > /usr/share/nginx/html/index.html'再 curl 就能看到轮流返回 Pod 1 / Pod 2!
🔬 实验 2:验证 DNS 解析(Service 名称 → ClusterIP)
✅ 目标:确认 CoreDNS 能正确解析 Service
步骤:
ini
# 进入 debug Pod(如果已退出,重新创建)
kubectl run dns-test --image=busybox:1.28 -it --rm --restart=Never -- nslookup nginx-svc
✅ 预期输出:
yaml
Server: 10.96.0.10 # CoreDNS IP
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.96.123.45 # 这就是 Service 的 ClusterIP!
✅ 说明:
nginx-svc被成功解析为 ClusterIP
扩展测试(完整 FQDN):
arduino
kubectl run dns-fqdn --image=busybox:1.28 -it --rm --restart=Never -- \
nslookup nginx-svc.default.svc.cluster.local
🔬 实验 3:创建 NodePort Service 并从集群外访问
✅ 目标:验证外部流量能通过节点端口到达 Pod
步骤:
bash
# 1. 创建 NodePort Service(自动分配端口)
kubectl expose deployment nginx --port=80 --target-port=80 --type=NodePort --name=nginx-np
# 2. 查看分配的端口
kubectl get svc nginx-np
# 输出示例:nginx-np NodePort 10.96.200.100 80:31234/TCP
# 记下 31234(你的端口可能不同)
# 3. 从你的本地电脑(或 master 节点 shell)访问
curl http://localhost:31234 # 如果你在 master 节点本机
# 或
curl http://<你的节点公网/内网IP>:31234 # 如 192.168.18.133:31234
⚠️ 如果访问失败,检查:
- 防火墙是否放行端口(如
sudo ufw allow 31234) - 节点安全组(云服务器需配置入站规则)
✅ 预期结果:
返回 Nginx 欢迎页,证明 外部 → NodePort → Service → Pod 链路打通。
🔬 实验 4:故意破坏 Service,观察故障现象
✅ 目标:理解 Service 与 Pod 的解耦关系
步骤:
ini
# 1. 删除所有后端 Pod(Deployment 会自动重建)
kubectl delete pods -l app=nginx
# 2. 立即查看 Endpoints
kubectl get endpoints nginx-svc # 应该为空(<none>)
# 3. 尝试访问 Service(从 debug Pod)
kubectl run test-bad --image=curlimages/curl -it --rm --restart=Never -- \
curl -m 3 http://nginx-svc
✅ 预期结果:
- 请求超时(
curl: (28) Connection timed out) - 说明:Service 存在 ≠ 后端可用,必须有匹配的 Pod
💡 这就是为什么监控要同时关注 Service 和 Pod Ready 状态
🔬 实验 5:跨命名空间调用 Service
✅ 目标:验证 Service 的命名空间隔离与跨空间访问
步骤:
arduino
# 1. 创建新命名空间
kubectl create ns test-ns
# 2. 在 default 命名空间保留 nginx-svc
# 3. 从 test-ns 中访问 default 的 Service
kubectl run cross-ns --image=busybox:1.28 -n test-ns -it --rm --restart=Never -- \
wget -qO- http://nginx-svc.default.svc.cluster.local
✅ 关键点:
- 必须使用 完整 DNS 名称 :
<service>.<namespace>.svc.cluster.local - 不能只写
nginx-svc(因为当前命名空间是test-ns)
✅ 预期结果:
成功返回 Nginx 页面,证明跨命名空间通信可行。
🛠️ 附加:常用诊断命令速查表
| 场景 | 命令 |
|---|---|
| 查看 Service 详情 | kubectl describe svc <name> |
| 查看后端 Pod 列表 | kubectl get endpoints <svc-name> |
| 测试连通性(集群内) | kubectl run -it --rm debug --image=busybox --restart=Never -- telnet <svc> 80 |
| 查看 kube-proxy 日志 | kubectl logs -n kube-system -l k8s-app=kube-proxy |
| 检查防火墙(Linux) | sudo ufw status 或 sudo iptables -L |
✅ 总结:验证 Service 的核心思路
- 查配置 :
kubectl get/describe svc - 查后端 :
kubectl get endpoints(必须非空!) - 集群内测:用临时 Pod curl/telnet
- 集群外测:NodePort / LoadBalancer + 防火墙检查
- 看 DNS :
nslookup <svc-name>
💡 记住:Service 是虚拟 IP,真正干活的是 Endpoints(Pod 列表)!
现在就去你的 k8s-master-node 上动手试试吧!每完成一个实验,你对 K8s 网络的理解就更深一层。如果某个实验卡住了,欢迎贴出你的命令和输出,我可以帮你分析!🚀