Service 有哪几种类型(ClusterIP, NodePort, LoadBalancer, ExternalName)?
在 Kubernetes 中,Service 定义了一种抽象:一个逻辑上的 Pod 集合(通常由 Label Selector 选定)和访问它们的策略。
Service 主要有以下 4 种类型,它们决定了 Service 如何被暴露给网络(集群内部或外部):
1. ClusterIP (默认类型)
这是最基础、也是默认的 Service 类型。
- 原理:Kubernetes 会为该 Service 分配一个 仅集群内部可访问 的虚拟 IP 地址(即 ClusterIP)。
- 访问方式:
- 只能在集群内部(其他 Pod 或节点)通过
ClusterIP:Port访问。 - 也可以通过集群内部 DNS 名称访问(例如
my-svc.my-namespace.svc.cluster.local)。
- 只能在集群内部(其他 Pod 或节点)通过
- 适用场景:
- 服务之间的内部通信(例如:后端 API 访问数据库,前端 Pod 访问后端 Pod)。
- 不需要对外暴露的服务。
- 特例:Headless Service。如果你将 ClusterIP 设置为
None,K8s 不会分配 VIP,而是直接通过 DNS 返回后端 Pod 的 IP 列表。这通常用于 StatefulSet 或自定义服务发现。
2. NodePort
在 ClusterIP 的基础上,向外部暴露服务。
- 原理:Kubernetes 会在集群的 每一个 Node(节点) 上开放一个静态端口(默认范围 30000-32767)。
- 流量路径:
客户端 -> 任意 NodeIP:NodePort -> ClusterIP -> Pod。 - 访问方式:
- 集群外部可以通过
任意节点的 IP:NodePort访问该服务。
- 集群外部可以通过
- 适用场景:
- 临时演示或测试环境。
- 没有云厂商 LoadBalancer 支持的自建机房环境。
- 如果你自己在 K8s 外部配置了负载均衡器(如 Nginx),指向这些 NodePort。
- 缺点:
- 端口范围受限(30000+)。
- 安全性较差(直接暴露节点端口)。
- 客户端需要知道节点的 IP 地址,如果节点变动,IP 也会变。
3. LoadBalancer
这是在云环境(AWS, GCP, Azure, Aliyun 等)中暴露服务的标准方式。
- 原理:构建于 NodePort 之上。它会向云提供商(Cloud Provider)申请一个 外部的负载均衡器(如 AWS ELB)。
- 流量路径:
客户端 -> 云厂商 LB (Public IP) -> NodePort -> ClusterIP -> Pod。 - 访问方式:
- 通过云厂商提供的 公网 IP 访问。
- 适用场景:
- 生产环境中的对外服务(HTTP/HTTPS 流量通常配合 Ingress 使用,TCP 流量直接用 LoadBalancer)。
- 缺点:
- 成本:每个 Service 都会创建一个独立的云负载均衡器,这通常是收费的。
- 依赖:强依赖于底层云平台的支持。
4. ExternalName
这是一种特殊的类型,它不使用 Selector,也不定义任何端口或 IP。
- 原理:它将 Service 映射到一个 外部的 DNS 域名(CNAME 记录)。
- 工作方式:当集群内的 Pod 访问这个 Service 时,集群 DNS 服务会返回一个
CNAME记录(指向你配置的外部域名),而不是返回 ClusterIP。 - 访问方式:
- Pod 访问
my-service-> DNS 解析为my.database.example.com。
- Pod 访问
- 适用场景:
- 迁移过渡:你把应用迁到了 K8s,但数据库还在 K8s 外部(例如 AWS RDS)。你可以创建一个 ExternalName Service 指向 RDS 的域名,应用代码里只需要写 Service 的名字,未来数据库迁入 K8s 后,只需改 Service 类型,无需改代码。
- 访问集群外部的第三方 API。
总结对比图
| 类型 | 访问范围 | 依赖层级 | 典型用途 |
|---|---|---|---|
| ClusterIP | 仅集群内部 | 基础层 | 内部微服务通信、数据库 |
| NodePort | 集群外部 (通过节点IP) | 包含 ClusterIP | 测试、自建负载均衡入口 |
| LoadBalancer | 集群外部 (通过公网IP) | 包含 NodePort + ClusterIP | 生产环境对外暴露 (云环境) |
| ExternalName | 映射到外部域名 | 无 (DNS CNAME) | 引入外部服务到集群内 |
补充:Ingress 是什么?
虽然你问的是 Service 类型,但通常提到 LoadBalancer 时会涉及 Ingress。
- Service (LoadBalancer) 是 L4 (TCP/UDP) 层的负载均衡。如果你有 10 个服务,就需要 10 个 LoadBalancer,很贵。
- Ingress 不是 Service 类型,而是 K8s 的一种资源对象(L7 HTTP/HTTPS)。它通常只需要 一个 LoadBalancer Service 暴露 Ingress Controller,然后根据域名(如
a.com,b.com)或路径(/api,/web)将流量路由到集群内不同的 ClusterIP Service。