在 Kubernetes 中,spec.type 是 Service 资源的一个关键字段,用于定义服务的暴露方式和访问范围。目前(Kubernetes v1.30+)官方支持 4 种类型:
✅ Service 的 spec.type 有以下 4 种:
| 类型 | 说明 | 适用场景 |
|---|---|---|
ClusterIP | 默认类型,仅在集群内部可访问 | 微服务间通信(最常用) |
NodePort | 在每个节点 IP 上开放一个端口,外部可通过 <NodeIP>:<NodePort> 访问 | 开发测试、简单暴露服务 |
LoadBalancer | 由云厂商创建外部负载均衡器(如 AWS ELB、阿里云 SLB),自动分配公网 IP | 生产环境对外提供服务 |
ExternalName | 通过 CNAME 将服务映射到外部 DNS 名称(不涉及 Pod 或代理) | 访问集群外部服务(如数据库、第三方 API) |
下面逐一详解:
1. ClusterIP(默认类型)
-
作用:为 Service 分配一个仅在集群内部可访问的虚拟 IP(ClusterIP) 。
-
访问方式:
- 其他 Pod 可通过
<ServiceName>.<Namespace>.svc.cluster.local或<ServiceName>(同命名空间)访问。 - 例如:
http://my-service:80
- 其他 Pod 可通过
-
不对外暴露:外部无法直接访问。
-
典型用途:后端微服务、数据库代理等内部通信。
apiVersion: v1
kind: Service
metadata:
name: backend
spec:
type: ClusterIP # 可省略(默认)
ports:
- port: 80
targetPort: 8080
selector:
app: backend
2. NodePort
-
作用:在每个工作节点(Node)的 IP 上打开一个固定端口(默认 30000–32767),外部可通过任意节点的 IP + 端口访问服务。
-
底层机制:
- 实际仍基于
ClusterIP,NodePort是在其基础上增加了一层“节点端口映射”。 - 流量路径:
<NodeIP>:<NodePort>→ClusterIP:port→ Pod
- 实际仍基于
-
访问方式:
http://<任意节点公网IP>:<NodePort>
-
注意:
- 需确保节点防火墙/安全组放行该端口。
- 不适合高并发生产环境(无高级负载均衡、SSL 终止等)。
spec:
type: NodePort
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 可选,不写则自动分配
selector:
app: web
3. LoadBalancer
-
作用:云厂商自动创建一个外部负载均衡器(如 AWS ELB、GCP CLB、阿里云 SLB),并分配公网 IP 或 DNS。
-
底层机制:
- 本质是
NodePort+ 云平台 LB。 - 云控制器(cloud-controller-manager)会监听此类 Service,并调用云 API 创建 LB。
- 本质是
-
访问方式:
- 通过云平台提供的公网 IP 或域名访问(如
http://203.0.113.10)
- 通过云平台提供的公网 IP 或域名访问(如
-
前提条件:
- 必须运行在支持 LoadBalancer 的云环境(公有云或私有云集成 CCM)。
- 本地 Minikube / Kind 不支持(除非用插件模拟)。
spec:
type: LoadBalancer
ports:
- port: 80
targetPort: 80
selector:
app: web
📌 应用后,
kubectl get svc会显示EXTERNAL-IP字段(不再是<none>)。
4. ExternalName
-
作用:不代理任何 Pod,而是通过 DNS CNAME 记录将服务名指向一个外部域名。
-
使用场景:
- 访问集群外部的服务(如 RDS 数据库、第三方 API)
- 统一内部服务调用方式(无论内外都用 Service 名称)
-
特点:
- 没有
selector、ports(可选)、ClusterIP - 依赖集群 DNS(CoreDNS)实现 CNAME 解析
- 没有
apiVersion: v1
kind: Service
metadata:
name: my-database
spec:
type: ExternalName
externalName: mydb.example.com # 外部 DNS 名称
在 Pod 中访问:
# 解析结果:my-database.default.svc.cluster.local → CNAME → mydb.example.com
curl http://my-database:3306
⚠️ 注意:
externalName必须是合法的 DNS 名称,不能是 IP 地址。
🔁 四种类型关系图
ExternalName
│
└── 不涉及 Pod,纯 DNS CNAME
ClusterIP ←── NodePort ←── LoadBalancer
(内部) (节点端口) (云 LB + NodePort)
✅
NodePort和LoadBalancer都基于ClusterIP构建。
📌 总结对比表
| 类型 | 是否分配 ClusterIP | 是否分配 NodePort | 是否创建外部 LB | 是否需要 selector | 适用环境 |
|---|---|---|---|---|---|
ClusterIP | ✅ | ❌ | ❌ | ✅ | 所有环境(默认) |
NodePort | ✅ | ✅ | ❌ | ✅ | 任意环境(含本地) |
LoadBalancer | ✅ | ✅ | ✅(云平台) | ✅ | 公有云/支持 CCM 的私有云 |
ExternalName | ❌ | ❌ | ❌ | ❌ | 访问外部服务 |
掌握这四种 Service 类型,你就能够灵活控制 Kubernetes 服务的内外访问策略,为不同场景选择最合适的暴露方式!🚀