Service 网络原理
Service 服务发现
在 Kubernetes 中,Pod 是动态的,会随扩缩容或故障恢复而变化,其 IP 地址不是固定的。
为了让集群中的其他组件或 Pod 能稳定访问某个服务,K8s 提供了 Service(服务抽象层)。
-
Service 的作用:为一组 Pod 提供一个稳定的访问入口(虚拟 IP + DNS 名称)。
-
服务发现机制:让客户端无需关心 Pod IP,只需通过 Service 名称或环境变量访问目标。
服务发现机制
Kubernetes 支持两种服务发现方式:
(1) 环境变量(旧方法)
当 Pod 启动时,Kubelet 会为每个可见的 Service 自动注入环境变量。
例如存在名为 myservice
的 Service:
MYSERVICE_SERVICE_HOST=10.96.0.5
MYSERVICE_SERVICE_PORT=80
应用程序可以直接读取这些变量连接服务。
⚠️ 局限:
-
Pod 启动时才注入,之后新增的 Service 不会自动注入。
-
不灵活,现代部署通常使用 DNS。
(2) DNS(推荐方法)
Kubernetes 内部通过 CoreDNS 实现基于 DNS 的服务发现。
1️ CoreDNS 介绍
CoreDNS 是集群的 DNS 服务,部署在 kube-system 命名空间中:
kubectl get pods -n kube-system -l k8s-app=kube-dns
它监听 K8s API Server,根据 Service、Pod 的变化自动更新 DNS 记录。
2️ CoreDNS 工作流程
-
Pod 发送 DNS 查询(如
myservice.default.svc.cluster.local
)。 -
请求被转发到集群内的 CoreDNS Pod。
-
CoreDNS 根据 Service 对象查出对应 ClusterIP。
-
返回结果给 Pod,使其通过 ClusterIP 访问目标。
Service 的完整域名格式:
<service-name>.<namespace>.svc.cluster.local
例如:
nginx-service.default.svc.cluster.local
CoreDNS 的配置文件位于:
/etc/coredns/Corefile
3️ Pod 的 DNS 策略
Pod 的 DNS 行为可通过 dnsPolicy
控制:
策略 | 说明 |
---|---|
ClusterFirst (默认) | 优先解析集群内部 DNS(svc.cluster.local),否则转外部 DNS。 |
ClusterFirstWithHostNet | Pod 使用宿主机网络(hostNetwork: true)时使用此策略。 |
Default | 使用宿主机的 /etc/resolv.conf,不使用集群 DNS。 |
None | 完全自定义 DNS 配置,配合 dnsConfig 使用。 |
示例:
spec:dnsPolicy: NonednsConfig:nameservers:- 8.8.8.8searches:- mycustom.local
4️自定义 DNS 记录
CoreDNS 可以通过 ConfigMap 扩展自定义解析规则。
查看 CoreDNS 配置:
kubectl -n kube-system get configmap coredns -o yaml
示例:为集群内添加静态解析记录
apiVersion: v1
kind: ConfigMap
metadata:name: corednsnamespace: kube-system
data:Corefile: |.:53 {kubernetes cluster.local in-addr.arpa ip6.arpa {pods insecurefallthrough in-addr.arpa ip6.arpa}hosts {10.1.2.3 external-db.localfallthrough}forward . /etc/resolv.conf}
hosts
插件相当于 /etc/hosts
的功能,可添加固定解析。
5️ 指定外部 DNS 服务器
如果需要让集群 Pod 使用自定义外部 DNS,可在 Pod 中设置:
spec:dnsPolicy: NonednsConfig:nameservers:- 8.8.8.8- 114.114.114.114searches:- mycorp.local
或者在 CoreDNS 的 ConfigMap 里通过 forward
插件转发请求:
forward . 8.8.8.8 1.1.1.1
Service 代理模式
Kubernetes 的 Service 虚拟 IP(ClusterIP)本身并不存在于某个物理网卡上。
真正实现流量转发的是每个节点上的 kube-proxy 组件。
kube-proxy
负责监听 API Server 中 Service 和 Endpoint 对象的变化,
并在节点上设置相应的转发规则。
支持 iptables(主流默认) ipvs(高性能推荐)
iptables 模式
1️ 概念介绍
iptables
是 Linux 内核自带的 包过滤与 NAT 转发机制。
在这种模式下,kube-proxy
会为每个 Service 和对应的 Pod 创建多条 iptables 规则来实现转发。
Kubernetes 默认使用该模式(如果系统内核不支持 ipvs)。
2️ 原理与运作过程
整体流程:
-
kube-proxy 监听 Service 和 Endpoints。
-
为每个 Service 分配一个 ClusterIP。
-
在每个节点上创建
iptables
规则,实现:-
ClusterIP → Pod IP 转发。
-
负载均衡(随机或轮询)。
-
-
当请求访问 ClusterIP:Port 时,iptables 规则匹配后 NAT 转发到某个 Pod。
示意:
请求流向如下:
Client Pod → ClusterIP:80↓
iptables 规则匹配↓
DNAT → 10.244.1.15:8080 (某个后端 Pod)
关键链:
-
KUBE-SERVICES
:匹配所有 Service 的主入口链。 -
KUBE-SVC-xxxx
:特定 Service 的规则链。 -
KUBE-SEP-xxxx
:特定 Pod(Endpoint)的链。
查看命令:
# 查看 kube-proxy 使用的模式
kubectl -n kube-system get configmap kube-proxy -o yaml | grep mode# 查看 NAT 规则(重点关注 KUBE-*)
sudo iptables -t nat -L -n | grep KUBE
示例输出:
Chain KUBE-SERVICES (2 references)
target prot opt source destination
KUBE-SVC-XYZ tcp -- 0.0.0.0/0 10.96.0.1 /* default/kubernetes: cluster IP */ tcp dpt:443
优点:
- 稳定、兼容性好。
- 无需额外内核模块。
缺点:
- 每次规则更新需全表重写,性能较差。
- 规则数量多时(几千个 Service)会造成延迟。
ipvs 模式
1️ 概念介绍
ipvs (IP Virtual Server)
是 Linux 内核的 四层负载均衡框架,
相当于内核级 LVS(Layer 4 Load Balancer),性能远高于 iptables。
kube-proxy
在 ipvs 模式下会直接通过 netlink API 操作内核 IPVS 表项,
无需频繁改写 iptables 规则。
2️ 原理与运作过程
流程:
-
kube-proxy 监听 Service / Endpoints 变化。
-
为每个 Service 在内核中创建一个虚拟服务(Virtual Service)。
-
为每个 Endpoint 添加真实服务器(Real Server)。
-
使用 连接哈希算法 实现负载均衡(支持 RR、LC、WRR 等策略)。
数据流示意:
Client Pod → ClusterIP:80↓
内核 IPVS 匹配 Virtual Service↓
选择某个 Real Server (Pod)↓
转发数据包
查看命令:
# 查看当前 kube-proxy 模式
kubectl -n kube-system get configmap kube-proxy -o yaml | grep mode# 查看 ipvs 路由表
sudo ipvsadm -Ln# 或使用简化视图
sudo ipvsadm -Ln --stats
示例输出:
TCP 10.96.0.1:443 rr-> 192.168.1.11:6443 Masq 1 0 0-> 192.168.1.12:6443 Masq 1 0 0
这里 rr
表示 round-robin 轮询算法。
3 切换为 ipvs 模式
编辑 kube-proxy 的 ConfigMap:
kubectl -n kube-system edit configmap kube-proxy
修改:
mode: "ipvs"
然后重启 kube-proxy:
kubectl -n kube-system delete pod -l k8s-app=kube-proxy
也是复归了,一卡就是好久