第02章:AI帮我配置了Service但外网无法访问

第02章:AI帮我配置了Service但外网无法访问

“AI 帮你创建了 Service,kubectl get svc 显示 EXTERNAL-IP 一直是 <pending>。或者有 IP 了但浏览器访问超时。Service 类型、端口映射、网络策略、云负载均衡——任何一环出问题都会导致外网无法访问,AI 给你的可能只是一个起点。”


ℹ️ 版本说明:本章基于 Kubernetes 1.36.1

2.1 AI默认会生成什么

# AI 通常给你的 Service
apiVersion: v1
kind: Service
metadata:
  name: my-app-service
spec:
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

这个配置看起来完整,但可能的问题:

  • 本地 minikube/kind 集群:LoadBalancer 类型没有云提供商,EXTERNAL-IP 永远是 <pending>
  • 云集群:selector 的 label 和 Pod 实际 label 不匹配,没有 Pod 被选中
  • 端口不对:容器实际监听的端口不是 8080

2.2 AI通常遗漏的4个坑

⚠️ 坑1:Service 类型的适用场景

ClusterIP(默认):只能在集群内访问
  → 用于微服务间通信

NodePort:通过节点 IP + 端口访问(30000-32767)
  → 测试环境、没有负载均衡器时

LoadBalancer:云提供商自动创建外部负载均衡器
  → 生产环境(AWS ELB、GCP LB、阿里云 SLB)
  → 本地集群用不了(EXTERNAL-IP = <pending>)

ExternalName:把 Service 映射到外部 DNS 名称
  → 用于访问集群外的服务

⚠️ 坑2:selector 不匹配是最常见的原因

# 检查 Service 是否选中了 Pod
kubectl get endpoints my-app-service
# 如果 ENDPOINTS 显示 <none>,说明没有 Pod 匹配

# 比较 Service 的 selector 和 Pod 的 labels
kubectl get svc my-app-service -o yaml | grep -A5 selector
kubectl get pods --show-labels | grep my-app

常见错误:

# Service selector
selector:
  app: my-app       # ← 这个

# Pod label(不匹配!)
labels:
  app: myapp        # ← 这个(少了连字符)

⚠️ 坑3:NetworkPolicy 阻止了流量

如果集群开启了 NetworkPolicy,默认 deny all 的策略会阻止所有未明确允许的流量:

# 检查是否有 NetworkPolicy
kubectl get networkpolicy -n your-namespace

# 如果有 deny-all 策略,需要显式允许流量
kubectl describe networkpolicy

⚠️ 坑4:Ingress vs LoadBalancer 的选择

对于 HTTP/HTTPS 服务,通常应该用 Ingress(一个负载均衡器处理多个服务的路由),而不是每个服务都创建 LoadBalancer(云资源和成本浪费):

LoadBalancer:每个服务一个外部 IP + 一个云负载均衡器(成本高)
Ingress:一个外部 IP + 基于 Host/Path 路由到多个服务(成本低)

2.3 更好的提示词

提示词 P01:诊断 Service 外网无法访问

使用时机:Service 配置了但无法访问,逐步排查

我的 Kubernetes Service 配置好了但外网无法访问,帮我系统排查。

当前情况:
kubectl get svc 输出:
[粘贴]

kubectl get pods 输出:
[粘贴]

集群类型:[minikube / kind(本地)/ EKS / GKE / AKS / 其他云]

逐步排查(给我每步的命令和预期输出):

1. 检查 Service 是否选中了 Pod:
   kubectl get endpoints my-app-service
   → 预期:显示 Pod 的 IP:Port

2. 如果 endpoints 为空:
   - 比较 selector 和 Pod labels
   - kubectl get pods --show-labels

3. 如果 endpoints 正常,检查容器是否在监听端口:
   kubectl exec -it <pod> -- netstat -tlnp(或 ss -tlnp)

4. 如果容器端口正常,检查网络连通性:
   - 集群内部:kubectl run test --image=busybox --rm -it -- wget -O- my-app-service:80
   - 检查是否有 NetworkPolicy 阻止

5. EXTERNAL-IP 为 <pending>(LoadBalancer):
   - 本地集群怎么解决?(minikube tunnel)
   - 云集群为什么 pending?(权限问题?)

给我每步的判断逻辑(如果A → 做B,如果C → 做D)。

基于 Kubernetes 1.36.1。

提示词 P02:设计 Ingress 路由(HTTP/HTTPS)

使用时机:需要把多个服务暴露到外网,用 Ingress 统一处理

帮我配置 Kubernetes Ingress,把多个服务暴露到外网。

服务列表:
- api-service:ClusterIP,端口8080,路径 /api/*
- frontend-service:ClusterIP,端口3000,路径 /* 
- docs-service:ClusterIP,端口4000,Host: docs.example.com

Ingress Controller:[nginx-ingress / traefik / 其他]
域名:[api.example.com 和 docs.example.com]
HTTPS:[是,使用 cert-manager + Let's Encrypt]

帮我生成:
1. Ingress 规则(基于 Host 和 Path 路由)
2. cert-manager 的 ClusterIssuer(Let's Encrypt 生产 HTTPS)
3. 如何验证 Ingress 是否工作?
4. 证书申请失败时的排查步骤

基于 Kubernetes 1.36.1 + nginx-ingress + cert-manager。

提示词 P03:Service 网络诊断工具集

使用时机:需要系统地诊断 K8s 网络问题

帮我准备 Kubernetes 网络诊断工具集,用于排查 Service 连通性问题。

给我以下工具和命令:

1. 临时调试 Pod(用 busybox/netshoot 镜像):
   - 启动临时 Pod 并进入 shell
   - 从里面测试 Service 连通性(wget/curl/nslookup)

2. 网络诊断命令速查:
   - 检查 DNS 解析(my-app-service 能解析到 ClusterIP 吗?)
   - 检查 Service 的 endpoints(有 Pod 被选中吗?)
   - 检查 Pod 是否在监听正确端口
   - 端对端连通性测试(Pod → Service → 目标 Pod)

3. NetworkPolicy 诊断:
   - 列出所有 NetworkPolicy
   - 判断某条流量是否被允许
   - 临时禁用 NetworkPolicy 测试(如何操作?)

4. 常见错误排查:
   - connection refused(容器没有监听)
   - connection timed out(NetworkPolicy 或路由问题)
   - no such host(DNS 问题)
   - 503 Service Unavailable(没有健康的 Endpoints)

基于 Kubernetes 1.36.1。

2.4 验收清单

检查项 验证方法 AI辅助
Service endpoints 非空 kubectl get endpoints <svc> 有 IP:Port 用 P01 排查
Service type 选择合适 生产用 ClusterIP + Ingress,非每服务 LB 用 P02 设计 Ingress
Ingress 路由规则正确 curl 测试每个 path/host 让 AI 生成验证命令
HTTPS 证书有效 openssl s_client -connect domain:443 用 P02 配置 cert-manager
无不必要的 NetworkPolicy 阻断 新部署的服务默认可访问 用 P03 诊断 NetworkPolicy
诊断工具 Pod 模板已准备 kubectl run 测试 Pod 命令在手 用 P03 准备工具集

2.5 本章小结

如果你只记一件事:Service 无法访问时,先跑 kubectl get endpoints <service-name>——如果 ENDPOINTS 显示 <none>,说明 selector 和 Pod labels 不匹配,一切流量问题的起点都是"服务没有选中任何 Pod"。检查 Service 的 selector 和 Pod 的 labels 是否完全一致(包括大小写和连字符)。

Service 排查的三步法

  1. 检查 Endpointskubectl get endpoints):有没有 Pod 被选中
  2. 检查 Pod 状态kubectl get pods):Pod 是否 Running 且 Ready
  3. 检查网络路径(NetworkPolicy / Ingress 规则 / 云 LB 配置):路由是否通

→ 第3章:AI生成的Dockerfile镜像运行为root用户