一、Service 到底是什么?
Service = Kubernetes 里的 “固定入口 + 负载均衡器”
Pod 有个致命问题:IP 不固定、会漂移、会重启,直接用 Pod IP 访问完全不可靠。
Service 就是为了解决这个问题诞生的:
- 给一组功能相同的 Pod 分配固定 IP、固定域名
- 自动通过标签(label) 找到后端 Pod
- 自动把请求均匀分发到多个 Pod
- 不管 Pod 怎么重启、替换,访问入口永远不变
二、Service 三大核心作用
- 统一访问入口给 Pod 组一个固定 ClusterIP / 域名,不用管后端 Pod 怎么变。
- 自动负载均衡访问 Service → 自动轮询 / 随机转发到多个后端 Pod。
- 自动服务发现集群内其他服务可以通过 Service 名称 直接访问,不用写 IP。
三、Service 4 种类型
K8s Service 有 4 种类型,用途完全不同:
| 类型 | 作用 | 使用场景 |
|---|---|---|
| ClusterIP | 仅集群内部访问 | 微服务内部调用(默认) |
| NodePort | 集群外部访问(每个节点开端口) | 测试、内部系统、无云厂商 LB 时 |
| LoadBalancer | 云厂商提供公网 IP | 生产环境对外服务 |
| ExternalName | 映射外部服务 | 集群访问外部数据库 / 第三方服务 |
四、逐类型详细解释 + YAML 示例
1. ClusterIP(默认类型)
作用:
- 只在K8s 集群内部可访问
- 分配一个固定内部虚拟 IP
- 集群内其他 Pod 通过 Service 名 / IP 访问
示例:给 Nginx Pod 创建内部服务
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP # 可省略,默认就是它
selector:
app: nginx # 匹配标签为 app=nginx 的 Pod
ports:
- port: 80 # Service 端口
targetPort: 80 # 后端 Pod 端口
访问方式(集群内):
curl nginx-svc
curl 10.96.xxx.xxx
2. NodePort(外部访问最常用)
作用:
- 在每一台节点服务器上开放一个固定端口(30000-32767)
- 外部通过
节点IP:NodePort访问服务 - 底层依然依赖 ClusterIP
示例:暴露 Nginx 到外部
apiVersion: v1
kind: Service
metadata:
name: nginx-nodeport
spec:
type: NodePort
selector:
app: nginx
ports:
- port: 80
targetPort: 80
nodePort: 30080 # 手动指定端口(可选,不写自动分配)
外部访问:
http://节点IP:30080
3. LoadBalancer(云生产环境)
作用:
- 依赖云厂商负载均衡器(AWS ELB / 阿里云 SLB)
- 自动生成公网 IP
- 外部直接访问公网 IP 即可
apiVersion: v1
kind: Service
metadata:
name: nginx-lb
spec:
type: LoadBalancer
selector:
app: nginx
ports:
- port: 80
查看公网 IP:
kubectl get svc
输出:
nginx-lb LoadBalancer 10.96.xxx.xxx 47.xxx.xxx.xxx 80:32000/TCP
直接访问:47.xxx.xxx.xxx
4. ExternalName(特殊类型)
作用:
- 把集群外部服务映射成集群内部域名
- 不代理 Pod,不分配 IP,只是DNS 指向
示例:让集群内访问外部 MySQL
yaml
apiVersion: v1
kind: Service
metadata:
name: mysql-external
spec:
type: ExternalName
externalName: mysql.abc.com # 外部真实地址
集群内访问:
mysql -h mysql-external.default.svc.cluster.local
五、一张图总结 Service 工作流程
用户请求
↓
Service (固定IP/域名)
↓
标签选择器(app=nginx)
↓
Pod1 Pod2 Pod3 (负载均衡转发)
六、最实用的命令
# 查看所有 service
kubectl get svc
# 查看 service 详情
kubectl describe svc 名称
# 快速创建 Service(命令行)
kubectl expose pod nginx --port=80 --type=NodePort
总结
- Service = 固定入口 + 负载均衡 + 服务发现
- ClusterIP:集群内部用(默认)
- NodePort:外部访问(测试 / 自建集群)
- LoadBalancer:云厂商公网入口(生产)
- ExternalName:映射外部服务
Kubernetes 通过 Service 实现服务发现
一、核心原理
Service 通过固定的 DNS 域名 + ClusterIP,让集群内任意 Pod 不用知道后端 Pod IP,直接用「Service 名称」就能访问,这就是服务发现。
二、服务发现的 2 种方式
K8s 内置两种服务发现机制,自动生效、无需配置:
- DNS 域名发现(最主流、推荐)
- 环境变量发现(早期、少用)
1. DNS 服务发现
原理
- K8s 集群自带 CoreDNS 组件
- 每个 Service 会自动创建一条 DNS 记录 (/etc/resolv.conf)service-name.namespace.svc.cluster.local
- 同一命名空间下,直接写 Service 名字即可访问
示例
- Service 名称:
nginx-svc - 命名空间:
default
在任意 Pod 内都可以直接:
curl nginx-svc
curl nginx-svc.default.svc.cluster.local
为什么这叫服务发现?
- 后端 Pod IP 变了、重启了、扩缩容了
- Service 名字不变、DNS 不变、入口不变
- 业务完全不用改配置,自动找到新 Pod
2. 环境变量服务发现
原理
Pod 启动时,K8s 会把已存在的 Service信息注入环境变量:
<SVC_NAME>_SERVICE_HOST<SVC_NAME>_SERVICE_PORT
示例
Service 名为 nginx-svc,在 Pod 里执行:
env | grep NGINX
NGINX_SVC_SERVICE_HOST=10.96.128.100
NGINX_SVC_SERVICE_PORT=80
缺点:
- 必须先有 Service,再起 Pod
- 后创建的 Service 不会更新环境变量
- 现在基本不用,只用 DNS
三、完整演示:服务发现全过程
1. 创建 Nginx Pod
apiVersion: v1
kind: Pod
metadata:
name: nginx-pod
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx
2. 创建 Service
apiVersion: v1
kind: Service
metadata:
name: nginx-svc
spec:
type: ClusterIP
selector:
app: nginx
ports:
- port: 80
targetPort: 80
3. 进入另一个 Pod 测试服务发现
kubectl run -it --rm test --image=busybox sh
① DNS 发现(直接访问 Service 名)
wget -O- nginx-svc
成功访问 Nginx,不需要知道任何 Pod IP
② 查看 DNS 解析
nslookup nginx-svc
返回:
Server: 10.96.0.10
Address 1: 10.96.0.10 kube-dns.kube-system.svc.cluster.local
Name: nginx-svc
Address 1: 10.96.128.100 # Service IP(虚拟IP)
问:K8s 如何通过 Service 实现服务发现?**
答:
- Service 通过标签选择器关联一组 Pod,提供固定 ClusterIP 和 DNS 域名。
- 集群内部署 CoreDNS 组件,为每个 Service 自动生成 DNS 记录:
服务名.命名空间.svc.cluster.local。 - 集群内所有 Pod 可以直接通过 Service 名称访问,无需知道后端 Pod IP。
- 当 Pod 重启、漂移、扩缩容时,Service 自动更新后端端点(Endpoints),访问入口不变,实现自动服务发现。
- 另外还有环境变量方式,但现在主流只用 DNS 服务发现。
五、关键名词解释
- Endpoints(端点):Service 后端真实 Pod IP:Port 列表
- kube-proxy:维护 Service 规则,实现负载均衡转发
- CoreDNS:提供服务发现的 DNS 解析
Kubernetes Service 服务发现
一、整体架构
Pod IP 会变 → Service 提供固定入口 → CoreDNS 做域名解析 → kube-proxy 做负载均衡 → Endpoints 保存真实 Pod 地址
二、完整流程图解
┌─────────────────┐
│ 业务 Pod A │ (想访问 Nginx)
└────────┬────────┘
│
▼
┌─────────────────┐
│ CoreDNS │ (集群DNS:10.96.0.10)
│ 解析域名: │
│ nginx-svc → VIP │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Service(VIP) │ (固定ClusterIP:10.96.128.100)
│ 标签选择器: │
│ app=nginx │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Endpoints │ (自动维护)
│ 10.244.1.5:80 │ Pod1
│ 10.244.2.7:80 │ Pod2
│ 10.244.1.9:80 │ Pod3
└────────┬────────┘
│
▼
┌─────────────────┐
│ kube-proxy │ (每台节点都有)
│ 负载均衡转发 │
│ 轮询/随机 │
└────────┬────────┘
│
▼
┌─────────────────┐
│ 后端 Nginx Pod │ Pod1/Pod2/Pod3
└─────────────────┘
三、服务发现 **详细步骤
- 创建 Service
- 通过
selector: app=nginx匹配一组 Pod。 - 自动分配固定 ClusterIP(VIP)。
- 通过
- 自动生成 Endpoints
- Controller 管理器实时监听 Pod 状态。
- 把所有匹配的 Pod IP:Port 写入 Endpoints。
- Pod 挂掉、新增、重建,Endpoints 会自动更新。
- CoreDNS 自动解析
- 每个 Service 对应 DNS 记录:nginx-svc.default.svc.cluster.local
- 集群内所有 Pod 默认 DNS 指向 CoreDNS。
- 业务访问流程
- 业务 Pod 访问:
curl nginx-svc - 系统请求 CoreDNS 解析 → 得到 Service VIP
- 请求发给 VIP → 被节点
kube-proxy拦截 - kube-proxy 根据 Endpoints 列表,负载均衡转发到真实 Pod
- 业务 Pod 访问:
- 服务发现的本质
- 应用只认 Service 名字,不认 Pod IP
- Pod 任意变化,Service 名字、VIP、DNS 都不变
- 实现自动、无感的服务发现
四、核心组件职责
- Service:固定 VIP、提供统一入口、负载均衡
- Endpoints:存储真实 Pod 地址列表
- CoreDNS:提供域名解析,实现服务发现
- kube-proxy:维护节点转发规则,实现负载均衡
五、一句话总结
Kubernetes 通过 Service 提供固定域名与 VIP,CoreDNS 负责解析,Endpoints 维护后端真实 Pod,kube-proxy 负责转发,从而实现集群内自动、动态、无感的服务发现。
太好了