服务发现 Service
Pod 的 IP 是短暂且随机的——每次重建都会变。其他服务不可能"写死 IP"去调用它。Kubernetes 用 Service 给一组 Pod 提供一个稳定不变的虚拟 IP 和 DNS 名,并自动做负载均衡。
1. Service 解决什么问题
- Pod IP 会随重建变化 → 需要稳定地址
- 有多个副本 → 需要把流量分摊到每个副本
- 调用方只关心"服务名" → 需要内置 DNS 解析
Service 通过 Label Selector 选中后端 Pod,把请求转发给它们。
2. ClusterIP(集群内访问,默认)
只在集群内部可达,是大多数微服务间调用的类型。
apiVersion: v1
kind: Service
metadata:
name: nginx
spec:
type: ClusterIP
selector:
app: nginx # 选中带这个标签的 Pod
ports:
- port: 80 # Service 暴露的端口
targetPort: 80 # Pod 容器实际监听的端口集群内其他 Pod 直接用 http://nginx 即可访问(DNS 名 = Service 名)。
ℹ️DNS 名规则
同命名空间内用 nginx 即可;跨命名空间用 nginx.<命名空间>.svc.cluster.local。Kubernetes 内置了这套 DNS。
3. NodePort(从节点端口暴露)
在每个节点上开一个固定端口(默认 30000–32767),外部可通过「节点 IP:NodePort」访问。
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 可选,不写则随机分配💡NodePort 适合简单暴露
本地学习、临时测试用 NodePort 最方便:浏览器直接访问 http://<节点IP>:30080。生产一般不直接用它。
4. LoadBalancer(云上对外暴露)
在云厂商(AWS/GCP/腾讯云…)上会自动创建一个外部负载均衡器,分配公网 IP。
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
targetPort: 80kubectl get svc nginx
# 等待 EXTERNAL-IP 从 `pending` 变成真实 IP 即可访问⚠️本地环境没有真负载均衡器
minikube/kind 上 LoadBalancer 的 EXTERNAL-IP 会一直 pending。本地想验证请用 NodePort 或 minikube tunnel。
5. 三种类型对比
| 类型 | 访问范围 | 典型用途 |
|---|---|---|
| ClusterIP | 集群内部 | 微服务间调用(默认) |
| NodePort | 节点 IP + 端口 | 本地测试、简单暴露 |
| LoadBalancer | 公网(云) | 对外服务 |
6. 排查 Service 不通
kubectl describe svc nginx # 看 endpoints 是否为空
kubectl get endpoints nginx # 空 = selector 没匹配到 Pod🎯练习
为第 6 章的 nginx Deployment 创建一个 ClusterIP Service,再用 kubectl run client --rm -it --image=busybox -- wget -qO- nginx 从集群内访问它,验证服务发现生效。
小结
- Service 提供稳定虚拟 IP + DNS,并负载均衡到后端 Pod
- ClusterIP 集群内、NodePort 节点端口、LoadBalancer 云上公网
- Service 不通先查
endpoints是否为空(selector 匹配问题) - 下一章用 ConfigMap/Secret 管理配置与密钥 →