K8S的spec.type 详解

220 阅读3分钟

在 Kubernetes 中,spec.typeService 资源的一个关键字段,用于定义服务的暴露方式和访问范围。目前(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
  • 不对外暴露:外部无法直接访问。

  • 典型用途:后端微服务、数据库代理等内部通信。

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 + 端口访问服务。

  • 底层机制

    • 实际仍基于 ClusterIPNodePort 是在其基础上增加了一层“节点端口映射”。
    • 流量路径:<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
  • 前提条件

    • 必须运行在支持 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 名称)
  • 特点

    • 没有 selectorports(可选)、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)

NodePortLoadBalancer 都基于 ClusterIP 构建。


📌 总结对比表

类型是否分配 ClusterIP是否分配 NodePort是否创建外部 LB是否需要 selector适用环境
ClusterIP所有环境(默认)
NodePort任意环境(含本地)
LoadBalancer✅(云平台)公有云/支持 CCM 的私有云
ExternalName访问外部服务

掌握这四种 Service 类型,你就能够灵活控制 Kubernetes 服务的内外访问策略,为不同场景选择最合适的暴露方式!🚀