type
status
date
slug
summary
category
tags
create_time
Sep 5, 2025 12:07 AM
icon
password
my_create_time

📝 前言

在 Kubernetes 中,Pod 是最小的运行单元,但 Pod 的生命周期是短暂且不稳定的。
如果直接通过 Pod IP 进行访问,当 Pod 重建或迁移时,IP 地址会发生变化,导致服务无法稳定访问。
为了解决这一问题,Kubernetes 引入了 Service 资源对象,它为一组 Pod 提供了一个稳定的访问入口,并支持多种服务暴露方式,是实现服务发现与负载均衡的关键组件。
本文将从概念、类型、工作原理,到实际操作全面解析 Service 资源对象,并通过多个实战案例帮助你更好地掌握。

🧠 本章知识卡片

notion image

🚀 本章小节

1️⃣ 什么是Service?

Service 是 Kubernetes 中用于定义一组 Pod 的抽象,提供稳定的网络访问方式。
它的主要作用包括:
  • 提供固定的虚拟 IP(ClusterIP)
  • 对后端 Pod 进行负载均衡(默认轮询)
  • 支持多种暴露方式(ClusterIP、NodePort、LoadBalancer、ExternalName)
  • 与 kube-proxy 配合实现服务转发
简单来说,Pod 是应用的运行单元,Service 是应用的访问入口
PS:在正式生产环境中 Service 通常都会结合 IngressGateway 使用,而不是直接作为访问入口。后两种资源会再接下来的文章中陆续介绍 。

2️⃣ Service 的类型

Kubernetes 提供了多种 Service 类型,以满足不同场景的需求:
ClusterIP(默认)
  • 提供一个仅在集群内部可访问的虚拟 IP。
  • 适合服务间调用。
  • 示例如下:
参数说明:
  • port:Service 对外暴露的端口
  • targetPort:Pod 实际监听的端口
我们也可以通过一行命令来快速创建 service:
NodePort
  • 在每个节点上暴露一个固定端口(默认范围:30000-32767)。
  • 可通过 <NodeIP>:NodePort 从集群外访问。
  • 适合小规模测试环境。
  • 示例如下:
参数说明:
  • nodePort:30080 固定映射的端口
  • 访问方式:http://<任意NodeIP>:30080
LoadBalancer
云厂商环境下最常见的对外暴露方式,自动创建公网负载均衡。
在阿里云、AWS、GCP 等环境中,Kubernetes 会向云厂商 API 申请公网负载均衡器,并自动绑定到 Service。 PS:成本较高,尽量避免创建多个。
示例如下:
访问方式:直接通过云厂商分配的公网 IP / 域名访问。
PS:如果是私有部署,也想使用 LoadBalancer 类型可以使用 Metallb 项目。
ExternalName
将 Service 映射到外部域名,不创建 ClusterIP。
示例如下:
访问 my-external-service.default.svc.cluster.local 时,会被解析为 api.example.com
常用于调用外部数据库、第三方 API 等服务。
Headless Service(无头 Service)
有时我们不希望 Service 提供负载均衡,而是直接让客户端获取后端所有 Pod 的 IP,这时就需要使用 Headless Service
其特点如下:
  • 不会分配 ClusterIP(clusterIP: None)。
  • 通过 DNS 查询时会返回 Pod 的 IP,而不是一个虚拟 IP。
  • 常用于有状态服务(如 MySQL 主从集群),让客户端直接感知具体 Pod。
  • 示例如下:
可进入到 pod 内通过 nslookup 命令查看解析地址测试:
可以明显看到 headless 解析到的是 Pod 原始IP,而普通 Serivce 则是自身的虚拟IP。
既然普通Service 只有虚拟IP,那又是如何将流量转发到 Pod 的呢,这里就需要再介绍一个 Endpoints 资源对象。

3️⃣ 什么是Endpoints?

Endpoints 是 Kubernetes 中的一个资源对象,用于记录 Service 选择到的 Pod IP 和端口。
当 Service 创建后,kube-controller-manager 会自动生成一个 同名 的 Endpoints 对象,并随着 Pod 的增删而动态更新。
Service 并不会直接绑定 Pod,而是通过 Endpoints 进行转发。
示例:查看某个 Service 对应的 Endpoints
其中 ENDPOINTS 即为 Pod 的IP和端口。
PS:这也是排查 Service 无法访问的一种有效常用方式,如果 ENDPOINTS 列表是空的,说明 Service 的 Label Selector 没有匹配到任何 Pod!!
从 Kubernetes v1.19 开始,官方引入了 EndpointSlice,用于替代传统 Endpoints。
主要是为了解决大规模集群下,单个 Endpoints 对象过大(会包含成千上万个 Pod)的性能问题。
示例:查看某个 Service 对应的 EndpointSlice

4️⃣ 工作原理

Service 的工作机制依赖 kube-proxy,不同模式下实现方式不同:
  • iptables 模式:通过 iptables 规则实现负载均衡。
  • IPVS 模式:通过 Linux 内核 IPVS 提供高性能转发。
Service 与 Pod 的关系
  • Service 使用 Label Selector 选择目标 Pod。
  • Pod 动态变化时,Endpoints 会同步更新。
  • kube-proxy 监听 Endpoints,更新转发表。
大致时序图如下:
notion image

5️⃣ 常见问题

1、Pod 重启后 IP 变了怎么办? Service 会通过 Label 自动发现并更新 Endpoints,不影响访问。
2、Service 访问不到 Pod?
  • 确认 Pod 的 Label 是否与 Service 的 selector 匹配。
  • 检查 Pod 是否处于 Running 状态。
  • 确认 kube-proxy 是否正常运行。
3、NodePort 超时或丢包?
  • 可能与 conntrack 相关。
  • 需检查节点防火墙和 NAT 映射。

✅ 总结

Service 是 Pod 的访问入口,解决了 Pod IP 不稳定问题。
支持多种类型:
  • ClusterIP:集群内部服务通信的默认方式。
  • NodePort:节点端口直接暴露服务,适合小规模测试或临时调试。
  • LoadBalancer:生产环境常用方式,借助云厂商提供的负载均衡器对外暴露服务。
  • ExternalName:将集群内部访问代理到外部域名,常用于调用外部系统。
Service 不直接管理 Pod,而是通过 Endpoints / EndpointSlice 间接关联。
借助 kube-proxy 实现服务发现与负载均衡。
在实战中,可以结合 Deployment 一起使用,确保服务高可用。
💡
有关文章的任何疑问,欢迎您在底部评论区留言,一起交流~
 
 
上一篇
Nginx+ACME服务器搭建
下一篇
第四部分:Deployment 资源对象介绍

评论
Loading...