当前位置: 首页 > news >正文

14. Service

Service

为什么需要 Service?

在 Kubernetes 中:

  • Pod 的生命周期短暂:一旦被销毁,重建后 IP 会变化。
  • 其他应用如果直接依赖 Pod IP,就会出现“找不到服务”的问题。
  • 在传统架构中,我们用 Nginx + Consul / ZooKeeper / etcd 做服务发现与负载均衡。

在 Kubernetes 中,这个功能由 Service 统一提供。

Service = 一组 Pod 的抽象 + 访问策略 + 负载均衡入口

Service 根据 selector 自动维护后端 Pod 列表(Endpoints),从而实现前端与后端的解耦。

ubernetes 中三种 IP

IP 类型 说明 作用范围
Node IP 节点物理机(主机)的 IP 集群内外可访问
Pod IP 每个 Pod 的独立 IP 集群内部可访问,Pod 重建后会变化
Cluster IP Service 的虚拟 IP 集群内部可访问,不随 Pod 变化

Service 的使用

有一组 Pod,标签为 app=myapp,对外暴露端口 8080:

# myapp-deploy.yaml
apiVersion: apps/v1
kind: Deployment
metadata:name: myapp
spec:replicas: 3selector:matchLabels:app: myapptemplate:metadata:labels:app: myappspec:containers:- name: nginximage: nginx:latestports:- containerPort: 80

ClusterIP 类型:

# myapp-svc.yaml
apiVersion: v1
kind: Service
metadata:name: myservice
spec:selector:app: myappports:- protocol: TCPport: 80targetPort: 80name: myapp-http

NodePort Service:

# myapp-nodeport.yaml
apiVersion: v1
kind: Service
metadata:name: myapp-nodeport
spec:type: NodePortselector:app: myappports:- port: 80targetPort: 80

作用:

  • ClusterIP 会自动分配
  • selector 匹配的 Pod 会自动加入 Endpoints

验证:

# 创建应用
ubuntu@ubuntu:~/example/service$ kubectl apply -f ./myapp-deploy.yaml 
deployment.apps/myapp created
ubuntu@ubuntu:~/example/service$ kubectl get pods -n default -o wide
NAME                     READY   STATUS    RESTARTS   AGE   IP             NODE    NOMINATED NODE   READINESS GATES
myapp-5c8d88cd7d-58xhs   1/1     Running   0          12s   10.244.2.189   node1   <none>           <none>
myapp-5c8d88cd7d-gjrm8   1/1     Running   0          12s   10.244.1.164   node2   <none>           <none>
myapp-5c8d88cd7d-jj748   1/1     Running   0          12s   10.244.2.188   node1   <none>           <none>
# 创建svc
ubuntu@ubuntu:~/example/service$ kubectl apply -f ./myapp-svc.yaml 
service/myservice created
ubuntu@ubuntu:~/example/service$ kubectl get svc -n default
NAME         TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
kubernetes   ClusterIP   10.96.0.1      <none>        443/TCP   75d
myservice    ClusterIP   10.107.155.4   <none>        80/TCP    18s
# 查看endPoint
ubuntu@ubuntu:~/example/service$ kubectl get endpoints myservice
Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice
NAME        ENDPOINTS                                               AGE
myservice   10.244.1.164:8080,10.244.2.188:8080,10.244.2.189:8080   93s
# 启动临时应用访问测试
ubuntu@ubuntu:~$ kubectl run curl --image=busybox -it --rm -- sh
# If you don't see a command prompt, try pressing enter.
/ # wget -qO- http://myservice
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p><p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p><p><em>Thank you for using nginx.</em></p>
</body>
</html>
/ # exit
Session ended, resume using 'kubectl attach curl -c curl -i -t' command when the pod is running
pod "curl" deleted
# 可以开另外一个终端查看日志
ubuntu@ubuntu:~/example/service$ kubectl logs -f myapp-5c8d88cd7d-58xhs
10.244.2.190 - - [18/Nov/2025:05:45:29 +0000] "GET / HTTP/1.1" 200 615 "-" "Wget" "-"
# 可以观察到负载均衡的效果# 验证endpoint
ubuntu@ubuntu:~/example/service$ kubectl apply -f ./myapp-nodeport.yaml
service/myapp-nodeport created
# 查看端口:
ubuntu@ubuntu:~/example/service$ kubectl get svc myapp-nodeport 
NAME             TYPE       CLUSTER-IP     EXTERNAL-IP   PORT(S)        AGE
myapp-nodeport   NodePort   10.106.46.35   <none>        80:31770/TCP   63s
# 打开浏览器 输入 http://192.168.236.101:31770/
# 这个IP是 物理机的IP,  NodePort 的作用就是 在每个节点上暴露同一个端口, 所以 101,102,103 都能访问。

Service 的内部机制:kube-proxy

每个 Node 上都运行 kube-proxy,它负责监听 Service 和 Endpoints,并同步规则。

1)iptables 模式(默认,适合中小规模)

kube-proxy:

  • 监听 Service 和 Endpoints 的变化
  • 生成 iptables 规则(DNAT)
  • 默认随机选择一个后端 Pod

特点:

  • 成熟稳定
  • 但大量规则时性能下降

2)ipvs 模式(推荐,适合大规模)
优点:

  • 内核级负载均衡
  • 使用哈希表,性能远高于 iptables
  • 支持更多调度策略,如:
    • rr(轮询)
    • lc(最少连接)
    • sh(源地址哈希)
    • sed(最短期望延迟)

开启方式(kube-proxy 配置):

--proxy-mode=ipvs
--ipvs-scheduler=rr

Session Affinity(会话保持)

Service 提供简单的基于 ClientIP 的会话亲和性:

spec:sessionAffinity: ClientIP

用于保证同一个客户端永远访问同一个 Pod。

Service 类型

  1. ClusterIP(默认)

仅在集群内部访问:

ServiceIP:Port -> PodIP:TargetPort
  1. NodePort

在每个 Node 上开放一个端口(30000~32767),通过该端口访问 Service。

示例:

apiVersion: v1
kind: Service
metadata:name: myservice
spec:selector:app: myapptype: NodePortports:- port: 80targetPort: 80

访问方式:

NodeIP:NodePort
  1. LoadBalancer

云厂商自动创建一个公网 LB,与 NodePort 结合使用。

  1. ExternalName [例如云服务的中间件可以用这种]

用于集群外服务,返回 CNAME,不走 kube-proxy。

示例:

apiVersion: v1
kind: Service
metadata:name: my-db
spec:type: ExternalNameexternalName: my.database.example.com

使用 Endpoints 引入外部服务

当使用 clusterIP=None 且与 Service 同名时,可以自定义 Endpoints:

Service:

apiVersion: v1
kind: Service
metadata:name: etcd-k8s
spec:clusterIP: Noneports:- port: 2379

Endpoints:

apiVersion: v1
kind: Endpoints
metadata:name: etcd-k8s
subsets:
- addresses:- ip: 10.151.30.57ports:- port: 2379

Service 与 externalIPs

externalIPs 是 Service 的一个可选属性,用于暴露服务到集群外的指定 IP。

当某个外部 IP 可以路由到集群 Node 时,可以通过 Service 的 externalIPs 将流量路由到对应 Service。

注意:

  • externalIPs 不由 Kubernetes 管理,需要集群管理员保证外部 IP 的路由正确。
  • Service 仍然通过 Endpoints 或 EndpointSlice 将流量转发到后端 Pod。
# my-app-external.yaml
apiVersion: v1
kind: Service
metadata:name: my-app-external
spec:selector:app: myappports:- port: 80targetPort: 80externalIPs:- 192.168.236.101 # 集群上某个node

验证:

# 删掉之前的
ubuntu@ubuntu:~/example/service$ kubectl delete -f ./myapp-nodeport.yaml 
service "myapp-nodeport" deleted
ubuntu@ubuntu:~/example/service$ kubectl apply -f ./my-app-external.yaml 
service/my-app-external created
# 查看信息
ubuntu@ubuntu:~/example/service$ kubectl get svc my-app-external
NAME              TYPE        CLUSTER-IP     EXTERNAL-IP     PORT(S)   AGE
my-app-external   ClusterIP   10.108.2.244   192.168.1.101   80/TCP    74s
# 浏览器测试访问
# 只有  http://192.168.236.101 可以访问,其他均不可以

Endpoints (废弃)

Warning: v1 Endpoints is deprecated in v1.33+; use discovery.k8s.io/v1 EndpointSlice

Endpoints 是 Kubernetes 的资源对象,用来存储一个 Service 对应的后端 Pod 的 IP 地址及端口。

自动创建:当 Service 有 selector 且 Pod 就绪时,Kubernetes 会自动创建 Endpoints。

更新机制:

  • Pod 被创建/销毁/重启 → Endpoints 自动同步更新。
  • Pod readiness probe 未就绪 → 不会加入 Endpoints。

结构

subsets:- addresses:- ip: 10.244.1.5ports:- port: 80

不足:

  • 单个 Endpoints 对象有最大数量限制(默认 1000 个端点)。
  • Pod 数量巨大时(上千),更新 Pod 会导致 Endpoints 对象很大 → 集群性能下降。

EndpointSlice

和endpoint 一样,一般情况不需要手动创建,创建 EndpointSlice 主要出现在 Service 没有 selector 或者要代理外部服务 的场景。这里主要聊一下概念。

EndpointSlice 是 Endpoints 的可扩展替代方案,设计目标:

  • 缓解大规模 Pod 的性能问题。
  • 支持拓扑信息(节点、可用区等)。
  • 支持就绪、服务中、终止状态。

特点:

  • 默认每个 EndpointSlice 最多 100 个端点(可通过 kube-controller-manager --max-endpoints-per-slice 调整)。
  • Pod 数量多时,会创建多个 EndpointSlice → 每个更新只影响相关 slice → 降低网络和 API 负载。
  • kube-proxy 会 watch 所有 EndpointSlice 来更新 iptables 或 IPVS 规则。

端点状态字段:

  • ready:Pod 就绪状态。
  • serving:Pod 服务状态,不考虑终止。
  • terminating:Pod 终止中状态。

标签管理:

endpointslice.kubernetes.io/managed-by 标识控制器管理的对象(默认:endpointslice-controller.k8s.io)。

地址类型:

IPv4、IPv6、FQDN

示例:

apiVersion: v1
kind: EndpointSlice
metadata:name: httpbin-xyzlabels:endpointslice.kubernetes.io/managed-by: endpointslice-controller.k8s.io
addressType: IPv4
ports:- name: httpport: 80
endpoints:- addresses:- 10.244.1.5conditions:ready: trueserving: trueterminating: false
spec:selector:app: myappports:- port: 80targetPort: 80

Service → Endpoints / EndpointSlice 的关系

Service (ClusterIP / NodePort / LoadBalancer)│ selector▼Endpoints 或 EndpointSlice│ 各个 Pod IP + 端口▼Pod

核心作用:Service 抽象 Pod 集合,对客户端隐藏 Pod 的 IP 变动。

流量转发:kube-proxy 通过 iptables 或 IPVS 将请求分发到 Pod。

可扩展性

  • 少量 Pod → Endpoints 足够
  • 大量 Pod → EndpointSlice 更高效

小结 / 建议

资源 用途 适用场景
Service 流量入口,抽象 Pod 集合 集群内部访问 / 外部访问
Endpoints 存储 Service 对应 Pod 的 IP(单对象) Pod 数量较少 (<1000),频繁更新量不大
EndpointSlice 分片存储 Pod IP,可扩展、支持拓扑信息 大规模集群、多副本 Pod (>1000)
externalIPs 外部 IP 直接访问 Service 需指定外部路由的场景
http://www.jsqmd.com/news/43714/

相关文章:

  • 基于图像小波变换的多尺度自适应双边滤波matlab仿真 - 指南
  • 2025年11月防晒选购指南:花西子/珀莱雅/薇诺娜/安热沙实测,全肤质闭眼入款竟是它
  • 使用马尔科夫蒙特卡洛方法对非常规的概率密度函数进行样本抽取
  • 如何在Totally Stub区域达成负载均衡
  • 2025年江苏产学研合作协议展会权威推荐:江苏产学研合作优化/江苏产学研合作促进会/江苏产学研合作模式机构精选
  • 理解Spring AI Message API
  • CSP2025游寄
  • 2025年眼镜护理液批发厂家权威推荐榜单:硬性隐形眼镜护理液/隐形眼镜护理液/硬镜护理液源头厂家精选
  • 2025北京专门做马来西亚留学机构
  • 2025年国内旧房翻新服务商综合实力排行榜前十强推荐
  • 2025年lora传感器定做厂家权威推荐榜单:lora组网/lora通信/lora网关源头厂家精选
  • 国标GB28181算法算力平台EasyGBS:构筑银行金融网点的智能安全与高效运营新模式
  • 2025 年 11 月水位计厂家推荐排行榜,超声波/雷达/气泡式水位计,水位测针,雷达/一体式分体式电子水尺,液位计/管网液位计/液位差计,雷达物位计/平板雷达公司推荐
  • AI元人文价值原语化理论体系深度研究报告
  • swagger 自动化文档
  • 2025年房梁装修生产商权威推荐:房梁定制厂家/房梁打孔/房梁装饰源头厂家精选
  • 2025年PPH真空机组定制厂家权威推荐:PPH环保型水喷射真空机组/PP水喷射真空机组/聚丙烯水喷射真空机组源头厂家精选
  • 云原生周刊:Kubernetes 的十字路口
  • javascript的版本
  • 2025 滑轨品牌口碑排行榜:权威测评!炬森五金登顶,6 大热门品牌实力对决
  • 2025国内靠谱留学机构真实测评:5大机构核心优势全解析,精准适配不同申请需求
  • 基于深度学习计算机视觉的风格迁移高效的技术原理与经典完成解析
  • 段式液晶驱动芯片水电表段码屏驱动高抗干扰LCD显示驱动IC VK2C22B
  • 2025 年 11 月热电偶厂家推荐排行榜,热电偶感温线,针式热电偶,扣式热电偶,高精度测温设备公司推荐
  • linux apache2 配置
  • 2025 年 11 月电热管厂家推荐排行榜,不锈钢/单头/空气干烧/浸入式/分流板/热流板/翅片/铁氟龙/工业电热管,电热圈,半导体电热,反应釜电热公司推荐
  • linux apache 配置文件
  • 2025 年 11 月热流道发热圈厂家推荐排行榜,铜套/弹簧/钢套/瓶盖/云母发热圈,翅片干烧发热管源头厂家精选
  • 从零构建生产级日志分析体系:Flask + Docker + Nginx 完整实战
  • 2025年气流烘干机优质厂家权威推荐榜单:沸腾烘干机/流化床烘干机/真空烘干机源头厂家精选