在 Kubernetes 中,Service 是定义一组 Pod 访问策略的抽象层,主要解决 Pod 的动态变化(如重启、扩缩容)导致 IP 变化带来的访问问题。Service 的核心作用是为 Pod 提供稳定的网络端点(IP 地址或 DNS 名称)和负载均衡。其类型主要有以下四种:
-
ClusterIP (默认类型)
- 描述: 为 Service 分配一个仅在 Kubernetes 集群内部可访问的虚拟 IP 地址(Cluster IP)。
- 访问方式: 集群内的其他 Pod 或组件(如 Deployment, StatefulSet 中的 Pod)可以通过这个 Cluster IP 或 Service 的 DNS 名称(
<service-name>.<namespace>.svc.cluster.local)来访问该 Service 背后的 Pod。 - 用途: 这是最常用的类型,适用于那些只需要在集群内部被访问的后端服务,例如数据库服务、内部 API 服务、微服务间的调用等。
- 特点: 安全(外部无法直接访问),高效(集群内部网络通信)。
-
NodePort
- 描述: 在 ClusterIP 的基础上,Kubernetes 会在每个 Node(工作节点) 的相同指定端口(NodePort,范围默认 30000-32767)上打开一个端口。
- 访问方式:
- 集群内部: 通过 Cluster IP 或 Service DNS 名称(同 ClusterIP)。
- 集群外部: 通过访问
<任意 Node 的 IP 地址>:<NodePort>。流量会先到达该 Node 的 NodePort,然后由 kube-proxy 转发到 Service 的 ClusterIP,最后负载均衡到后端 Pod。即使 Pod 不在该 Node 上,流量也会被正确路由(可能需要额外的网络跳转)。
- 用途: 适用于需要让集群外部用户或系统能够访问,但又没有负载均衡器或 Ingress 控制器的情况,常用于开发、测试环境或临时暴露服务。生产环境通常会用 LoadBalancer 或 Ingress 替代。
- 特点: 暴露节点端口,外部可访问,但需要知道节点 IP 和端口,不太适合高可用生产环境(节点故障需切换 IP)。
-
LoadBalancer
- 描述: 在 NodePort 的基础上,Kubernetes 会向所运行的云服务提供商(如 AWS, GCP, Azure, Alibaba Cloud 等) 申请一个外部负载均衡器(如 ELB, ALB, NLB)。云提供商会分配一个外部 IP 地址(公网或内网)给这个负载均衡器。
- 访问方式:
- 集群内部: 通过 Cluster IP 或 Service DNS 名称。
- 集群外部: 通过访问负载均衡器分配的外部 IP 地址(和端口)。负载均衡器会将流量分发到集群所有节点的 NodePort(通常对用户透明),最终到达后端 Pod。
- 用途: 这是将服务直接暴露给公网或特定 VPC 网络的标准方式,适用于需要稳定外部访问的生产环境服务。云提供商负责负载均衡器的健康检查、高可用和扩展。
- 特点: 最方便的外部暴露方式,由云平台管理负载均衡器,自动集成云平台特性(如 SSL 终止、WAF),但通常会产生额外的云服务费用。如果集群不在云上(如本地机房),此类型可能不可用或需要额外插件支持(如 MetalLB)。
-
ExternalName
- 描述: 这是一种特殊的 Service 类型,它没有选择器(
selector),也不会创建 Endpoints 或定义任何 Pod 的代理规则。它只是将 Service 映射到一个外部的 DNS 名称(例如my.database.example.com)。 - 访问方式: 当集群内的 Pod 或组件通过该 Service 的 DNS 名称(
<service-name>.<namespace>.svc.cluster.local)进行访问时,DNS 查询会被重定向(CNAME 记录)到.spec.externalName字段指定的外部 DNS 名称。 - 用途: 主要用于在集群内部提供一个统一的 DNS 名称来访问集群外部的服务,例如云托管的数据库、老旧的遗留系统或其他不在 Kubernetes 管理的服务。它简化了集群内部应用访问外部服务的配置(应用只需要知道 Service 名称,无需关心外部服务的实际地址)。
- 特点: 不代理流量,纯粹是 DNS 重定向。依赖集群 DNS 解析。
- 描述: 这是一种特殊的 Service 类型,它没有选择器(
重要补充:Headless Services
- 严格来说,Headless Service 不是一种独立的
type,而是通过在ClusterIP(或NodePort,LoadBalancer) 类型的 Service 上显式设置clusterIP: None来实现的一种特殊模式。 - 描述: 当设置
clusterIP: None时,Kubernetes 不会为该 Service 分配 Cluster IP,DNS 查询行为也会改变。 - 访问方式:
- 对于定义了选择器(
selector)的 Headless Service:DNS 查询会返回该 Service 后端所有 Pod 的 IP 地址列表(A 或 AAAA 记录),而不是一个单一的 Cluster IP。客户端(通常是 StatefulSet 的 Pod)可以自己决定如何连接这些 Pod(例如直接连接)。 - 对于没有选择器的 Headless Service(需要手动管理 Endpoints 或 EndpointSlice):DNS 查询会返回手动配置的 Endpoints 的地址列表。
- 对于定义了选择器(
- 用途:
- 需要直接连接到每个 Pod 的场景,例如有状态应用(StatefulSet)需要稳定的网络标识和点对点通信。
- 实现自定义的服务发现和负载均衡逻辑。
- 与非 Kubernetes 管理的服务集成(结合手动 Endpoints)。
Ingress 不是 Service 类型!
- Ingress 是一个独立的 API 对象,工作在应用层(通常是 HTTP/HTTPS)。
- 它充当集群的入口点,提供基于主机名(域名)和路径的路由规则、SSL/TLS 终止等功能。
- Ingress 需要配合 Ingress Controller(如 Nginx Ingress Controller, Traefik)运行。
- Ingress 通常将外部流量路由到后端 Service(通常是
ClusterIP或NodePort类型)。它本身不是 Service 的一种类型,而是位于 Service 之上的一层抽象。
总结:
| 类型 (Type) | 集群内部访问 | 集群外部访问方式 | 主要用途 | 特点 |
|---|---|---|---|---|
| ClusterIP | ✅ | ❌ (默认) | 集群内部服务间通信 | 默认,安全,高效 |
| NodePort | ✅ | <NodeIP>:<NodePort> |
开发测试、临时外部访问 | 暴露节点端口,需知节点 IP |
| LoadBalancer | ✅ | <External-LB-IP> (云平台提供) |
生产环境直接外部暴露(公有云) | 云平台负载均衡器,方便但可能有费用 |
| ExternalName | N/A | N/A | 提供集群内 DNS 别名访问外部服务 | 纯 DNS CNAME 重定向,不代理流量 |
| Headless | ✅ (特殊) | 取决于底层 Type (通常 ClusterIP) | 直接访问 Pod (如 StatefulSet)、自定义负载均衡 | clusterIP: None, DNS 返回 Pod IP 列表 |
选择哪种 Service 类型取决于你的服务是否需要被集群外部访问、你的运行环境(云上/本地)以及对高可用、成本和便利性的要求。理解这些类型的区别对于设计 Kubernetes 应用的网络拓扑至关重要。
