Learn
Kubernetes/07-services

服务发现 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: 80
kubectl 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 管理配置与密钥 →