news 2026/7/10 22:39:11

彻底搞懂 K8s 服务访问:ClusterIP、NodePort 流量机制

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
彻底搞懂 K8s 服务访问:ClusterIP、NodePort 流量机制

前言

在 Kubernetes 集群中,Pod 是最小的部署单元,但 Pod 的生命周期是短暂的——当 Pod 发生故障或被重新调度时,其 IP 地址也会随之改变。这就带来一个问题:如果一组 Pod 需要对外提供稳定服务(例如 HTTP 服务),客户端如何能始终访问到正确的 Pod 呢?Kubernetes 给出的标准答案就是Service

Service 是一种抽象对象,它定义了一组 Pod 的逻辑集合以及访问该集合的策略。Service 拥有自己固定的 Cluster IP,客户端只需访问这个 IP,而无需关心后端 Pod 的 IP 变化。本文将从 Service 的基本概念入手,通过实际演示和 iptables 底层分析,深入理解 Service 的工作原理,并展示如何在集群内部和外部访问 Service。


一、Service 概念与作用

Kubernetes 中的 Service 从逻辑上代表了一组 Pod。具体哪些 Pod 属于该 Service,由 Service 定义中的selector(标签选择器)来决定。Service 拥有一个固定不变的 IP 地址(Cluster IP),客户端只需访问这个 IP,Kubernetes 负责建立和维护 Service 与后端 Pod 的映射关系。无论后端 Pod 如何增删或 IP 如何变化,对客户端都不会产生任何影响。

Service 提供了以下核心能力:

  • 稳定的访问入口(Cluster IP)

  • 负载均衡(将请求分发到多个后端 Pod)

  • 服务发现(通过 DNS 或环境变量)


二、创建 Service 并演示用途

2.1 创建一个 Deployment

首先,我们创建一个 Deployment,它负责管理三个 httpd(Apache)Pod,并使用标签run: httpdservice标记它们。

http-service.yml内容:

apiVersion: apps/v1 kind: Deployment metadata: name: httpservice-deployment spec: replicas: 3 selector: matchLabels: run: httpdservice template: metadata: labels: run: httpdservice spec: containers: - name: httpdservice image: httpd ports: - containerPort: 80

执行以下命令创建 Deployment:

[root@master service]# kubectl apply -f http-service.yml

2.2 集群内部直接访问 Pod

每个 Pod 会被分配一个集群内部可访问的 IP(例如 10.244.1.28),但该 IP 仅能在 Kubernetes 集群中的节点和容器内访问:

[root@master service]# curl 10.244.1.28 <html><body><h1>It works!</h1></body></html>

2.3 创建 Service

接下来创建一个 Service,将流量从 Service 的8080端口转发到 Pod 的80端口,并通过selector匹配刚才的 Pod。

service.yml内容:

apiVersion: v1 kind: Service metadata: name: service-httpd spec: selector: run: httpdservice ports: - protocol: TCP port: 8080 targetPort: 80

创建 Service:

[root@master service]# kubectl apply -f service.yml [root@master service]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d service-httpd ClusterIP 10.101.20.80 <none> 8080/TCP 175m

现在可以通过 Service 的 Cluster IP 访问后端服务:

[root@master service]# curl 10.101.20.80:8080 <html><body><h1>It works!</h1></body></html>

2.4 查看 Service 与 Pod 的对应关系

[root@master service]# kubectl describe svc service-httpd Name: service-httpd Namespace: default Labels: <none> Annotations: Selector: run=httpdservice Type: ClusterIP IP: 10.101.20.80 Port: <unset> 8080/TCP TargetPort: 80/TCP Endpoints: 10.244.1.27:80,10.244.1.28:80,10.244.2.21:80 Session Affinity: None Events: <none>

从输出可以看到,该 Service 的 Endpoints 包含了三个 Pod 的 IP 和端口。


三、Service IP 内部实现原理分析

Pod 的 IP 是直接配置在容器网络中的,那么 Service 的 Cluster IP 是如何生效的?流量又是如何转发到后端 Pod 的呢?答案是iptables

Service 的 Cluster IP 是一个虚拟 IP,由每个节点上的 iptables 规则管理。我们可以通过iptables-save命令查看规则。

3.1 查看 Cluster IP 相关的 iptables 规则

[root@master service]# iptables-save | grep 10.101.20.80 -A KUBE-SERVICES ! -s 10.244.0.0/16 -d 10.101.20.80/32 -p tcp -m comment --comment "default/service-httpd: cluster IP" -m tcp --dport 8080 -j KUBE-MARK-MASQ -A KUBE-SERVICES -d 10.101.20.80/32 -p tcp -m comment --comment "default/service-httpd: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-5FEAUJNCXGRSJFN5

解释:

  • 第一条规则:对于源 IP 不是集群 CIDR(10.244.0.0/16)的请求,打上 MASQ 标记(用于 SNAT)。

  • 第二条规则:目标 IP 为 10.101.20.80、端口 8080 的请求,跳转到自定义链KUBE-SVC-5FEAUJNCXGRSJFN5

3.2 查看负载均衡链

[root@master service]# iptables-save | grep KUBE-SVC-5FEAUJNCXGRSJFN5 -A KUBE-SVC-5FEAUJNCXGRSJFN5 -m comment --comment "default/service-httpd:" -m statistic --mode random --probability 0.33333333333333 -j KUBE-SEP-KIILMGZB3LCHX6UB -A KUBE-SVC-5FEAUJNCXGRSJFN5 -m comment --comment "default/service-httpd:" -m statistic --mode random --probability 0.50000000000000 -j KUBE-SEP-JPXQHLXQSDHS2NX -A KUBE-SVC-5FEAUJNCXGRSJFN5 -m comment --comment "default/service-httpd:" -j KUBE-SEP-5H6K0BYUZ646ISHJ

每条规则按概率将流量跳转到不同的KUBE-SEP-*链,实现了类似轮询的负载均衡。

3.3 查看最终的 DNAT 规则

[root@master service]# iptables-save | grep KUBE-SEP-KIILMGZB3LCHX6UB -A KUBE-SEP-KIILMGZB3LCHX6UB -s 10.244.1.27/32 -j KUBE-MARK-MASQ -A KUBE-SEP-KIILMGZB3LCHX6UB -p tcp -j DNAT --to-destination 10.244.1.27:80

其他KUBE-SEP-*链类似,分别指向 10.244.1.28:80 和 10.244.2.21:80。

结论:iptables 将访问 Service Cluster IP 的流量随机转发到后端 Pod,实现负载均衡。每个节点上的 iptables 规则完全一致,因此整个集群中任意节点都可以通过 Service 的 Cluster IP 访问。


四、通过 DNS 访问 Service

除了通过 Cluster IP 访问,Kubernetes 还内置了 DNS 服务(CoreDNS),为 Service 提供域名解析。

4.1 查看 CoreDNS 部署

[root@master service]# kubectl get deployment --namespace=kube-system NAME READY UP-TO-DATE AVAILABLE AGE coredns 2/2 2 2 10d

每当有新 Service 创建,CoreDNS 会自动添加一条 DNS 记录,格式为:<SERVICE_NAME>.<NAMESPACE_NAME>.svc.cluster.local

4.2 使用 busybox 测试 DNS

启动一个临时 busybox 容器:

[root@master service]# kubectl run busybox --rm -it --image=busybox /bin/sh

在容器内部通过 Service 名称访问:

# wget service-httpd.default:8080 Connecting to service-httpd.default:8080 (10.101.20.80:8080) index.html 100% |******************************| 45 0:00:00 ETA # cat index.html <html><body><h1>It works!</h1></body></html>

注意:这里使用service-httpd.default,由于当前 Pod 与 Service 同属default命名空间,可简写为service-httpd:8080。跨命名空间访问时必须使用全限定名。


五、如何通过外网访问 Service

前面介绍的 ClusterIP 类型仅支持集群内部访问。为了让外部客户端访问 Service,Kubernetes 提供了多种 Service 类型:

  • ClusterIP(默认):仅集群内部可访问。

  • NodePort:在每个节点上开放一个静态端口,外部可通过<NodeIP>:<NodePort>访问。

  • LoadBalancer:利用云厂商的负载均衡器对外暴露服务。

下面重点演示NodePort的实现。

5.1 修改 Service 为 NodePort 类型

编辑service.yml,添加type: NodePort,并可指定nodePort(可选,若不指定则自动分配 30000-32767 范围内的端口):

apiVersion: v1 kind: Service metadata: name: service-httpd spec: type: NodePort selector: run: httpdservice ports: - protocol: TCP nodePort: 32000 # 可选,手动指定节点端口 port: 8080 targetPort: 80

重新应用配置:

[root@master service]# kubectl apply -f service.yml [root@master service]# kubectl get svc NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 10d service-httpd NodePort 10.101.20.80 <none> 8080:30271/TCP 5h7m

可以看到,Service 的 TYPE 变为 NodePort,PORT(S) 显示为8080:30271/TCP,其中30271是节点上随机监听的端口(若手动指定则为 32000)。

5.2 通过节点 IP 访问服务

现在,任意集群节点的 IP 加上该端口都可以访问服务:

[root@master service]# curl 172.16.213.221:30271 <html><body><h1>It works!</h1></body></html> [root@master service]# curl 172.16.213.222:30271 <html><body><h1>It works!</h1></body></html> [root@master service]# curl 172.16.213.223:30271 <html><body><h1>It works!</h1></body></html>

六、外网访问 Service 的映射机制

NodePort 的实现同样依赖 iptables。当 Service 类型切换为 NodePort 后,每个节点上会新增关于该 NodePort 的规则。

6.1 查看 NodePort 对应的 iptables 规则

[root@master service]# iptables-save | grep 30271 -A KUBE-NODEPORTS -p tcp -m comment --comment "default/service-httpd:" -m tcp --dport 30271 -j KUBE-MARK-MASQ -A KUBE-NODEPORTS -p tcp -m comment --comment "default/service-httpd:" -m tcp --dport 30271 -j KUBE-SVC-5FEAUJNCXGRSJFN5

解释:访问当前节点 30271 端口的请求,会被跳转到KUBE-SVC-5FEAUJNCXGRSJFN5链。

6.2 负载均衡链仍然复用

[root@master service]# iptables-save | grep KUBE-SVC-5FEAUJNCXGRSJFN5 : KUBE-SVC-5FEAUJNCXGRSJFN5 - [0:0] -A KUBE-NODEPORTS -p tcp -m comment --comment "default/service-httpd:" -m tcp --dport 30271 -j KUBE-SVC-5FEAUJNCXGRSJFN5 -A KUBE-SERVICES -d 10.101.20.80/32 -p tcp -m comment --comment "default/service-httpd: cluster IP" -m tcp --dport 8080 -j KUBE-SVC-5FEAUJNCXGRSJFN5 ...(以下为相同的概率转发规则)

可以看到,无论是通过 ClusterIP:8080 还是通过 NodeIP:30271 进来的流量,最终都汇聚到同一个负载均衡链KUBE-SVC-5FEAUJNCXGRSJFN5,然后随机转发到后端 Pod。

结论:NodePort 本质是在每个节点上监听一个端口,并将到达该端口的流量引入与 ClusterIP 相同的 iptables 负载均衡链路,从而实现外网访问。


结尾

本文从 Service 的基本概念出发,通过实际操作演示了如何创建 ClusterIP 和 NodePort 类型的 Service,并深入 iptables 层面分析了 Service 的流量转发与负载均衡原理。同时,我们还介绍了集群内部通过 DNS 名称访问 Service 的方法。

理解 Service 的实现机制有助于更好地排错和设计 Kubernetes 集群的网络架构。在实际生产环境中,还可以结合 Ingress、LoadBalancer 等更高级的资源对外暴露服务。希望本文能帮助你掌握 Kubernetes Service 的核心知识。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/10 22:35:48

Python深入浅出:从入门到工程实践13

第 13 章:并发基础:线程与进程 学习目标: 彻底理解 GIL 对 Python 并发的影响 掌握 threading 和 multiprocessing 的正确用法 能根据场景选择并发模型 13.0 为什么需要并发?——从现实问题出发 想象你在运营一个电商网站,需要完成以下任务: 任务 单线程耗时 说明 查询…

作者头像 李华
网站建设 2026/7/10 22:35:01

sc结构模块图中模块之间的关系(耦合、内聚)

耦合和内聚就是描述sc结构模块图中模块之间的关系 完全正确 内聚&#xff1a;描述单个模块内部元素联系紧密程度耦合&#xff1a;描述多个模块之间相互依赖关联程度 二者都是用来评判SC模块结构图设计好坏的核心指标 一、内聚&#xff08;管自己&#xff09; 定义 一个模块内部…

作者头像 李华
网站建设 2026/7/10 22:34:57

顶背离(Bearish Divergence)

顶背离&#xff08;Bearish Divergence&#xff09; 是技术分析里经典的见顶 / 反转预警信号&#xff1a;价格创新高&#xff0c;但动能指标&#xff08;MACD/RSI/KDJ&#xff09;不创新高、反而走低&#xff0c;说明上涨动能衰竭、多头乏力&#xff0c;大概率要回落。一、核心…

作者头像 李华
网站建设 2026/7/10 22:31:42

社群死群多?wechatapi iPad协议硬核破局

兄弟们&#xff0c;搞私域最怕啥&#xff1f;不是没流量&#xff0c;是流量进来后社群秒变僵尸群、广告群。多少老哥砸钱建群&#xff0c;最后群友全潜水&#xff0c;管理员累成狗&#xff0c;ROI直接崩盘。今天咱们就聊聊社群运营的硬核技术解法&#xff0c;用wechatapi的iPad…

作者头像 李华
网站建设 2026/7/10 22:31:39

天准星智发布首款具身智能控制器,满足高性能轻量化开发需求

近年来&#xff0c;具身智能&#xff08;Embodied AI&#xff09;成为全球人工智能领域的前沿热点&#xff0c;正逐步从理论走向实践。天准科技全资子公司天准星智顺势而为&#xff0c;推出了一款具有开创性意义的产品——星智001通用智能控制器&#xff0c;它将成为推动各行业…

作者头像 李华
网站建设 2026/7/10 22:31:35

主题演讲 | 基于 NVIDIA Jetson AGX Orin 的高算力控制器在自动驾驶场景的应用

10月17日&#xff0c;天准科技成功举办了“基于NVIDIA Jetson AGX Orin的高算力控制器产品在自动驾驶场景的应用”的线上演讲活动&#xff0c;详细介绍了天准TADC-Orin-2高算力产品解决方案在矿山工程、智慧港口、大型无人清扫以及无人小巴等场景的应用。双重利好低速无人驾驶产…

作者头像 李华