Kubernetes中的service使用及说明

 更新时间:2025年10月02日 17:14:47   作者:火星MARK  
Kubernetes Service通过固定IP和端口实现Pod的负载均衡和服务发现,解决动态IP问题,支持ClusterIP、NodePort、LoadBalancer等五种类型,适用于集群内通信、对外暴露及访问外部服务,结合Endpoints和负载均衡策略确保服务稳定性

在 Kubernetes(K8s)生态中,Service 是核心资源之一,其核心作用是解决 Pod 的动态性问题 —— 通过为一组功能相同的 Pod 提供一个固定的访问入口(IP 和端口),实现对 Pod 的负载均衡和服务发现,屏蔽 Pod 频繁创建、销毁、IP 变化带来的访问波动。

一、Service 的核心价值:为何需要 Service?

Pod 是 K8s 中最小的部署单元,但存在天然的 “不稳定性”:

  • IP 动态变化:Pod 重启、重建(如 Deployment 扩缩容、节点故障迁移)后,IP 会重新分配;
  • 访问入口不固定:若直接通过 Pod IP 访问,一旦 Pod 变化,客户端需手动更新目标 IP,无法自动化。

Service 正是为解决这些问题而生,其核心价值可概括为三点:

  1. 固定访问入口:Service 创建后会分配一个集群内固定的虚拟 IP(ClusterIP) 和端口,客户端只需访问该 IP:Port,无需关注后端 Pod 的具体 IP;
  2. Pod 负载均衡:Service 会自动将请求分发到后端健康的 Pod 上(默认轮询策略),实现流量分摊;
  3. 服务发现:结合 K8s 的 DNS 组件(如 CoreDNS),Service 可通过 “服务名” 被集群内其他 Pod 访问(如 http://<service-name>.<namespace>.svc.cluster.local),无需硬编码 IP。

二、Service 的工作原理:流量如何流转?

Service 的实现依赖 kube-proxy(每个节点上运行的网络代理组件)和 iptables/IPVS(Linux 内核的流量转发机制),核心流程如下:

  1. Service 创建:用户通过 YAML/CLI 创建 Service 后,K8s 控制器会为其分配 ClusterIP(仅集群内可见),并关联后端 Pod(通过 selector 匹配 Pod 标签);
  2. kube-proxy 同步规则:每个节点的 kube-proxy 会监听 K8s API,实时同步 Service 和 Pod 的信息,并在节点内核中配置 iptables/IPVS 规则
  3. 流量转发:当客户端(如集群内其他 Pod)访问 Service 的 ClusterIP:Port 时,请求会被节点内核的 iptables/IPVS 规则拦截,转发到后端任意一个健康的 Pod 的 IP:Port;
  4. 健康检查:Service 依赖 Pod 的 就绪探针(Readiness Probe) 判断 Pod 是否可用 —— 若 Pod 未通过就绪探针,会被从 Service 的后端列表中移除,不再接收流量。

三、Service 的核心组成:YAML 配置解析

Service 的配置通过 YAML 文件定义,核心字段如下(以最常见的 ClusterIP 类型为例):

apiVersion: v1  # Service 属于 v1 版本 API
kind: Service   # 资源类型为 Service
metadata:
  name: my-service  # Service 名称(集群内 DNS 解析的核心标识)
  namespace: default  # 所属命名空间(默认 default,不同命名空间的 Service 需加命名空间访问)
spec:
  type: ClusterIP  # Service 类型(核心字段,决定访问范围)
  selector:        # 标签选择器:匹配后端 Pod 的标签(关键!Service 仅转发匹配 Pod 的流量)
    app: my-app    # 假设后端 Pod 有标签 app=my-app
  ports:           # 端口映射规则(可配置多个 port)
  - name: http     # 端口名称(可选,用于区分多个端口)
    port: 80       # Service 对外暴露的端口(客户端访问的端口)
    targetPort: 8080  # 后端 Pod 实际提供服务的端口(需与 Pod 容器的端口一致)
    protocol: TCP  # 协议(默认 TCP,支持 UDP、SCTP)
  sessionAffinity: None  # 会话亲和性(默认 None,可选 ClientIP:同一客户端请求转发到同一 Pod)

关键字段说明:

  • selector:Service 与 Pod 的 “绑定桥梁”,仅匹配标签的 Pod 会被加入 Service 后端。
  • 若不配置 selector(如对接集群外服务),需手动通过 Endpoints 关联后端地址;

ports.port vs targetPort

  • port:Service 自身的端口(客户端访问的入口);
  • targetPort:Pod 容器的端口(流量最终转发到的端口),支持数字或 Pod 容器的端口名(如 targetPort: http,需 Pod 容器定义 name: http);
  • sessionAffinity:会话亲和性,用于保证同一客户端的请求始终转发到同一 Pod(适用于需要会话保持的场景,如登录状态存储)。

四、Service 的 5 种核心类型

Service 的 type 字段决定了其访问范围和暴露方式,K8s 支持 5 种常见类型,适用于不同场景:

类型核心特点适用场景
ClusterIP仅集群内可见的虚拟 IP,无法从集群外访问集群内服务间通信(如后端 API 给前端提供服务)
NodePort在每个节点上开放一个静态端口,通过 节点IP:NodePort 访问 Service开发 / 测试环境:快速从集群外访问服务
LoadBalancer借助云厂商 LB(如 AWS ELB、阿里云 SLB),自动分配公网 IP,转发流量到 NodePort生产环境:公网暴露服务(需云厂商支持)
ExternalName不关联 Pod,直接将 Service 映射到集群外的域名(如 xxx.com)访问集群外服务(如数据库、第三方 API)
Headless无 ClusterIP,通过 DNS 直接返回后端 Pod 的 IP 列表(不做负载均衡)需自行处理负载均衡或需直接访问 Pod 的场景

各类型详解与配置示例

1. ClusterIP(默认类型)

  • 特点:K8s 自动分配一个集群内唯一的虚拟 IP(无法 ping 通,仅用于流量转发),仅集群内 Pod 可访问;
  • 配置type: ClusterIP(或不写 type,默认为此类型);
  • 访问方式ClusterIP:port 或 service-name.namespace.svc.cluster.local:port(DNS 解析)。

2. NodePort

  • 特点:在 ClusterIP 基础上,在每个节点上开放一个 静态端口(NodePort)(范围:30000-32767),通过 任意节点IP:NodePort 可从集群外访问;

配置示例

spec:
  type: NodePort
  ports:
  - port: 80        # Service 内部端口
    targetPort: 8080 # Pod 端口
    nodePort: 30080  # 手动指定 NodePort(可选,不指定则自动分配)
  • 访问方式节点IP:30080(需确保节点 IP 可被外部访问,且防火墙开放 30080 端口);
  • 注意:NodePort 本质是 “每个节点都开放相同端口”,外部请求可发往任意节点,kube-proxy 会转发到后端 Pod。

3. LoadBalancer

  • 特点:依赖云厂商的负载均衡服务(如 AWS ELB、GCP LB),K8s 会自动创建云 LB 并关联所有节点的 NodePort,外部流量通过云 LB 的公网 IP 进入,再转发到 NodePort → Pod;

配置示例

spec:
  type: LoadBalancer
  ports:
  - port: 80
    targetPort: 8080
  loadBalancerIP: 1.2.3.4  # 可选,指定云 LB 的静态公网 IP(需云厂商支持)
  • 访问方式:云 LB 分配的公网 IP:80(无需记节点 IP,LB 自动做节点级负载均衡);
  • 注意:仅在云环境(如 EKS、GKE、ACK)中生效,本地集群(如 Minikube)需用 minikube tunnel 模拟 LoadBalancer。

4. ExternalName

  • 特点:不关联任何 Pod,仅作为 “域名别名”—— 将 Service 名映射到集群外的域名(如 db.example.com),通过 DNS 解析实现访问;

配置示例(访问集群外的 MySQL 服务):

spec:
  type: ExternalName
  externalName: db.example.com  # 集群外服务的域名
  ports:
  - port: 3306  # 外部服务的端口
  • 访问方式:集群内 Pod 访问 my-service.default.svc.cluster.local:3306,会自动解析为 db.example.com:3306
  • 适用场景:访问集群外的固定服务(如托管数据库、第三方 API),避免硬编码域名到应用中。

5. Headless Service(无头服务)

  • 特点:无 ClusterIP,Service 创建后不分配虚拟 IP;通过 DNS 解析时,直接返回后端所有 Pod 的 IP 列表(而非 Service IP),负载均衡需客户端自行实现;
spec:
  type: ClusterIP  # 关键:将 clusterIP 设为 None,即 Headless
  clusterIP: None
  selector:
    app: my-app
  ports:
  - port: 80
    targetPort: 8080
  • 访问方式:集群内 Pod 访问 my-service.default.svc.cluster.local,DNS 会返回所有匹配 Pod 的 IP 列表;

适用场景

  • 客户端需自行控制负载均衡策略(如 MongoDB 副本集、Elasticsearch 集群,需节点间直接通信);
  • 需通过 DNS 发现所有后端 Pod 的场景(如 StatefulSet 管理的有状态服务,每个 Pod 有固定 hostname)。

五、Service 与 Endpoints 的关系

Endpoints 是 K8s 中的另一个核心资源,用于存储 Service 后端的 “实际访问地址”(IP:Port 列表)。两者的关系是:

  • 自动关联:若 Service 配置了 selector,K8s 会自动创建一个与 Service 同名的 Endpoints 资源,实时同步匹配 selector 的 Pod 的 IP:Port 列表(Pod 就绪则加入,未就绪则移除);
  • 手动关联:若 Service 未配置 selector(如访问集群外服务),需手动创建 Endpoints,将外部服务的 IP:Port 写入 Endpoints,Service 会通过 Endpoints 转发流量。

手动关联 Endpoints 示例(访问集群外服务)

创建无 selector 的 Service:

apiVersion: v1
kind: Service
metadata:
  name: external-service
spec:
  ports:
  - port: 80
    targetPort: 80

手动创建同名 Endpoints,关联集群外服务的 IP:Port:

apiVersion: v1
kind: Endpoints
metadata:
  name: external-service  # 必须与 Service 同名,才能关联
subsets:
- addresses:
  - ip: 192.168.1.100  # 集群外服务的 IP
  ports:
  - port: 80            # 集群外服务的端口

集群内 Pod 访问 external-service.default.svc.cluster.local:80,流量会转发到 192.168.1.100:80

六、Service 的负载均衡策略

Service 的负载均衡由 kube-proxy 实现,kube-proxy 支持两种模式(通过 --proxy-mode 配置),对应不同的负载均衡策略:

1. iptables 模式(默认)

  • 原理:kube-proxy 在每个节点的 iptables 中配置 DNAT 规则,将 Service 的 ClusterIP:Port 转发到后端 Pod 的 IP:Port;
  • 负载均衡策略:默认 轮询(Round-Robin),即请求依次分发到后端 Pod;

优缺点

  • 优点:轻量、无额外进程,依赖内核转发,性能较好;
  • 缺点:后端 Pod 数量多时,iptables 规则会急剧增加,导致转发延迟升高(适合中小规模集群)。

2. IPVS 模式(推荐大规模集群)

  • 原理:依赖 Linux 内核的 IPVS(IP Virtual Server)模块,kube-proxy 会创建 IPVS 虚拟服务(对应 Service),并将后端 Pod 作为 IPVS 真实服务器;

负载均衡策略:支持多种策略(可通过 Service 的 externalTrafficPolicy 或 internalTrafficPolicy 配置):

  • rr:轮询(默认);
  • wrr:加权轮询(根据 Pod 权重分配流量);
  • lc:最少连接(请求分发到当前连接数最少的 Pod);
  • sh:源地址哈希(同 iptables 的 ClientIP 亲和性);

优缺点

  • 优点:支持更多负载均衡策略,规则管理高效(适合大规模集群,Pod 数量上千);
  • 缺点:需提前在节点上加载 IPVS 内核模块(modprobe ip_vs)。

七、Service 的常见问题与最佳实践

1. 常见问题

Service 访问不通?

  • 检查 selector 是否与 Pod 标签匹配(kubectl describe svc <service-name> 查看 Endpoints 是否有 Pod IP);
  • 检查 Pod 的就绪探针是否通过(未通过就绪探针的 Pod 不会加入 Endpoints);
  • 检查 Pod 容器的 targetPort 是否与 Service 配置一致;
  • 检查网络策略(NetworkPolicy)是否阻止了 Service 到 Pod 的流量。

NodePort 端口冲突?

  • NodePort 范围默认是 30000-32767,若手动指定 nodePort,需确保该端口未被其他 Service 或节点进程占用;
  • 建议不手动指定 nodePort,由 K8s 自动分配,避免冲突。

2. 最佳实践

  • 使用 DNS 名称访问 Service:避免硬编码 ClusterIP,通过 service-name.namespace.svc.cluster.local 访问(跨命名空间需加命名空间);
  • 为端口配置名称:Service 和 Pod 的端口都配置 name(如 name: http),避免 targetPort 数字写错导致转发失败;
  • 大规模集群用 IPVS 模式:当集群 Pod 数量超过 1000 时,建议将 kube-proxy 切换为 IPVS 模式,提升负载均衡效率;
  • 生产环境用 LoadBalancer + Ingress:LoadBalancer 用于暴露 Ingress Controller,Ingress 用于管理多个服务的域名和路由(比直接用 LoadBalancer 暴露多个 Service 更节省资源);
  • 有状态服务用 Headless Service:StatefulSet 管理的服务(如数据库集群)需固定网络标识,搭配 Headless Service 可通过 DNS 发现所有 Pod。

八、总结

Service 是 K8s 中连接 “动态 Pod” 与 “稳定访问” 的核心桥梁,其核心能力是固定入口、负载均衡、服务发现

在实际使用中,需根据场景选择合适的 Service 类型(如集群内用 ClusterIP、公网暴露用 LoadBalancer、访问外部服务用 ExternalName),并结合 Endpoints、iptables/IPVS 等组件理解流量转发逻辑,确保服务的稳定访问。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • K8S部署rocketmq5全过程

    K8S部署rocketmq5全过程

    在开发环境中部署RocketMQ 5并验证新版本代理特性,遇到一系列问题,包括存储权限、主从副本配置和命名空间问题,通过修改配置文件和PV设置,最终解决了这些问题,成功部署了RocketMQ集群
    2025-01-01
  • 如何在Centos中搭建 K8s 1.23 集群

    如何在Centos中搭建 K8s 1.23 集群

    文章详细介绍了在CentOS上搭建Kubernetes 1.23集群的步骤,包括准备环境、安装Kubernetes软件包、上传离线镜像、初始化集群、添加节点、安装网络插件以及测试验证,感兴趣的朋友一起看看吧
    2025-03-03
  • Rainbond云原生部署SpringCloud应用架构实践

    Rainbond云原生部署SpringCloud应用架构实践

    这篇文章主要为大家介绍了Rainbond云原生部署SpringCloud应用架构实践,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-04-04
  • 玩客云内置EMMC存储刷入Armbian系统(图文详解)

    玩客云内置EMMC存储刷入Armbian系统(图文详解)

    Armbian是其他项目可以信赖的单板计算机(SBC)的基本操作系统平台,接下来通过本文给大家介绍玩客云内置EMMC存储刷入Armbian系统,需要的朋友可以参考下
    2022-05-05
  • K8S集群需要开放的端口说明介绍

    K8S集群需要开放的端口说明介绍

    这篇文章主要介绍了K8S集群需要开放的端口说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2025-05-05
  • 云原生Kubernetes初始化容器Init使用教程

    云原生Kubernetes初始化容器Init使用教程

    这篇文章主要为大家介绍了云原生Kubernetes初始化容器Init使用教程,有需要的朋友可以借鉴参考下,希望能够有所帮助祝大家多多进步早日升职加薪
    2022-03-03
  • k8s调度原理和策略详解

    k8s调度原理和策略详解

    Kubernetes调度器通过节点预选、优先级排序和节点选定三阶段分配Pod,基于资源类型(可压缩/不可压缩)、亲和性(硬/软)、污点与容忍度机制,实现灵活调度与抢占,优化资源利用率和集群稳定性
    2025-09-09
  • K8s如何拉取habor镜像

    K8s如何拉取habor镜像

    这篇文章主要介绍了K8s如何拉取habor镜像,在daemon.json中添加仓库地址,需要在创建资源对象所在的节点进行添加,本文给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-04-04
  • k8s跨服务调用入门到实战示例详解

    k8s跨服务调用入门到实战示例详解

    这篇文章主要为大家介绍了k8s跨服务调用入门到实战示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-09-09
  • kubeadm部署k8s集群全过程

    kubeadm部署k8s集群全过程

    本文详细描述了如何在VMware虚拟机上基于CentOS8操作系统搭建Kubernetes集群,包括环境准备、Docker安装、Kubernetes组件安装、网络插件配置以及KuboardUI的安装和访问
    2025-01-01

最新评论