使用kube-proxy让外部网络访问K8S service的ClusterIP

本文详细介绍Kubernetes 1.5.2版本下网络配置方法及原理,包括kube-proxy两种模式Userspace与Iptables的工作机制对比,ClusterIP、NodePort、LoadBalancer与Ingress四种服务暴露方式的特点,并解释了service中port、nodePort与targetPort的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文基于kubernetes 1.5.2版本编写

配置方式

kubernetes版本大于或者等于1.2时,外部网络(即非K8S集群内的网络)访问cluster IP的办法是:
修改master的/etc/kubernetes/proxy,把KUBE_PROXY_ARGS=”“改为KUBE_PROXY_ARGS=”–proxy-mode=userspace”
重启kube-proxy服务
在核心路由设备或者源主机上添加一条路由,访问cluster IP段的路由指向到master上。

kubernetes版本小于1.2时,直接添加路由

这里写图片描述

kube-proxy转发的两种模式

一个简单的网络代理和负载均衡器,负责service的实现,每个Service都会在所有的Kube-proxy节点上体现。具体来说,就是实现了内部从pod到service和外部的从node port向service的访问。

kube-proxy在转发时主要有两种模式Userspace和Iptables。

kuer-proxy目前有userspace和iptables两种实现方式。
userspace(如下图)是在用户空间,通过kuber-proxy实现LB的代理服务。在K8S1.2版本之前,是kube-proxy默认方式,所有的转发都是通过kube-proxy实现的。这个是kube-proxy的最初的版本,较为稳定,但是效率也自然不太高。

另外一种方式是iptables方式(如下图)。是纯采用iptables来实现LB。在K8S1.2版本之后,kube-proxy默认方式。所有转发都是通过Iptables内核模块实现,而kube-proxy只负责生成相应的Iptables规则。

使用Userspace模式(k8s版本为1.2之前默认模式),外部网络可以直接访问cluster IP。
使用Iptables模式(k8s版本为1.2之后默认模式),外部网络不能直接访问cluster IP。

转发K8S后端服务的四种方式

ClusterIP

此类型会提供一个集群内部的虚拟IP(与Pod不在同一网段),以供集群内部的pod之间通信使用。ClusterIP也是Kubernetes service的默认类型。
ClusterIP
为了实现图上的功能主要需要以下几个组件的协同工作:
apiserver:在创建service时,apiserver接收到请求以后将数据存储到etcd中。
kube-proxy:k8s的每个节点中都有该进程,负责实现service功能,这个进程负责感知service,pod的变化,并将变化的信息写入本地的iptables中。
iptables:使用NAT等技术将virtualIP的流量转至endpoint中。

NodePort

NodePort模式除了使用cluster ip外,也将service的port映射到每个node的一个指定内部port上,映射的每个node的内部port都一样。
为每个节点暴露一个端口,通过nodeip + nodeport可以访问这个服务,同时服务依然会有cluster类型的ip+port。内部通过clusterip方式访问,外部通过nodeport方式访问。
这里写图片描述

loadbalance

LoadBalancer在NodePort基础上,K8S可以请求底层云平台创建一个负载均衡器,将每个Node作为后端,进行服务分发。该模式需要底层云平台(例如GCE)支持。

Ingress

Ingress,是一种HTTP方式的路由转发机制,由Ingress Controller和HTTP代理服务器组合而成。Ingress Controller实时监控Kubernetes API,实时更新HTTP代理服务器的转发规则。HTTP代理服务器有GCE Load-Balancer、HaProxy、Nginx等开源方案。
详细说明请见http://blog.youkuaiyun.com/liyingke112/article/details/77066814
这里写图片描述

service的三种端口

port

service暴露在cluster ip上的端口,:port 是提供给集群内部客户访问service的入口。

nodePort

nodePort是k8s提供给集群外部客户访问service入口的一种方式,:nodePort 是提供给集群外部客户访问service的入口。

targetPort

targetPort是pod上的端口,从port和nodePort上到来的数据最终经过kube-proxy流入到后端pod的targetPort上进入容器。

port、nodePort总结

总的来说,port和nodePort都是service的端口,前者暴露给集群内客户访问服务,后者暴露给集群外客户访问服务。从这两个端口到来的数据都需要经过反向代理kube-proxy流入后端pod的targetPod,从而到达pod上的容器内。

<think>我们之前讨论了如何验证excludeCIDRs是否生效,现在用户遇到了修改后未生效的问题用户需求:确认kube-proxyexcludeCIDRs修改后未生效的原因及解决方案根据之前的回答,我们需要检查多个环节:配置是否正确加载、代理模式、规则生成等可能的原因及排查步骤:1.检查ConfigMap是否已正确更新,并且kube-proxyPod是否使用了最新的配置(通过查看Pod启动参数)2.确保kube-proxyPod已经重启(因为ConfigMap更新后需要重启Pod才能生效)3.检查kube-proxy的代理模式(iptables或IPVS),然后检查对应模式下的规则4.确认排除的CIDR范围是否正确(比如是否与集群CIDR重叠等)5.检查kube-proxy日志是否有相关错误解决方案:步骤1:验证ConfigMap更新kubectl-nkube-systemgetcmkube-proxy-oyaml|grepexcludeCIDRs确保已经正确设置,并且值符合预期(比如CIDR格式正确,用逗号分隔)步骤2:确保kube-proxyPod重启更新ConfigMap后,kube-proxyPod不会自动重启,需要手动删除Pod让其重建删除Pod:kubectl-nkube-systemdeletepod-lk8s-app=kube-proxy然后查看新Pod的启动参数:kubectl-nkube-systemgetpod<pod-name>-ojsonpath='{.spec.containers[0].command}'|grepexclude-cidrs步骤3:检查代理模式查看ConfigMap中的mode字段,确认是iptables还是ipvs检查对应规则:IPVS模式:使用ipvsadm-ln命令,查看是否有排除的CIDR规则iptables模式:使用iptables-tnat-S查看是否有排除的CIDR规则(比如在KUBE-SERVICES链中)步骤4:验证CIDR范围确保要排除的CIDR范围不会与集群内服务ClusterIP范围、PodCIDR等重叠(否则可能会被忽略)检查方法:对比集群的service-cluster-ip-range和pod-cidr参数(通常在kube-apiserver和kube-controller-manager的启动参数中)步骤5:检查日志查看kube-proxy的日志:kubectl-nkube-systemlogs<kube-proxy-pod-name>注意是否有关于excludeCIDRs的解析错误或警告其他考虑:-如果集群使用网络插件(如Calico),确保它支持excludeCIDRs特性(尤其是IPVS模式)-检查网络插件是否覆盖了kube-proxy的设置(例如,如果网络插件也设置了类似规则)根据引用[1],对于Calico,我们需要检查其配置(cm/calico-config)是否与IPVS模式兼容,但excludeCIDRs是kube-proxy的功能,所以我们主要关注kube-proxy引用[4]提到Calico的IPPool配置,如果我们要排除的CIDR与Calico的IPPool重叠,可能会产生冲突。但通常excludeCIDRs用于排除外部IP,所以注意不要与集群内部CIDR重叠。解决方案总结:1.更新ConfigMap并重启kube-proxyPod2.检查启动参数是否正确3.检查规则4.检查日志5.确保CIDR范围合理且不冲突生成相关问题:1.如何重启kube-proxyDaemonSet的所有Pod?2.如何确认kube-proxy当前的工作模式?3.kube-proxy的日志中常见错误有哪些?4.如何解决CIDR范围冲突问题?</think> ### Kubernetes kube-proxy excludeCIDRs 未生效的原因及解决方案 当 kube-proxy 的 `excludeCIDRs` 配置修改后未生效时,可能由以下原因导致: --- #### **原因1:配置未正确加载到 kube-proxy** - **检查步骤**: 1. 验证 ConfigMap 是否更新成功: ```bash kubectl -n kube-system get cm kube-proxy -o yaml | grep excludeCIDRs ``` 2. 确认 kube-proxy Pod 已使用最新配置: ```bash kubectl -n kube-system get pod -l k8s-app=kube-proxy -o jsonpath='{.items[*].spec.containers[*].command}' | grep exclude-cidrs ``` 如果输出为空或参数值未更新,说明配置未加载[^1]。 - **解决方案**: 删除 kube-proxy Pod 触发重建(DaemonSet 会自动重建): ```bash kubectl -n kube-system delete pod -l k8s-app=kube-proxy ``` --- #### **原因2:代理模式不兼容** - **检查步骤**: 1. 查看 kube-proxy 当前模式: ```bash kubectl -n kube-system get cm kube-proxy -o yaml | grep mode: ``` 若为 `ipvs` 模式: ```bash ipvsadm -ln | grep <排除的CIDR> ``` 若为 `iptables` 模式: ```bash iptables -t nat -L KUBE-SERVICES -nv | grep <排除的CIDR> ``` 2. 检查网络插件是否支持: ```bash # Calico 示例 kubectl -n kube-system get cm calico-config -o yaml | grep -i ipvs ``` 若网络插件不支持 IPVS 模式,规则可能不生效[^1]。 - **解决方案**: - **IPVS 模式**:确保网络插件启用 IPVS 支持(如 Calico 需配置 `ipipMode: Never` 和 `vxlanMode: Always`)。 - **iptables 模式**:确认节点 iptables 版本 >1.8。 --- #### **原因3:CIDR 范围冲突** - **检查步骤**: 1. 确认排除的 CIDR 是否与集群核心服务重叠(如 kube-dns): ```bash kubectl get svc -A | grep -E 'kube-dns|kubernetes' ``` 2. 检查是否与 Pod CIDR/Service CIDR 冲突: ```bash kubeadm config view | grep -E 'podSubnet|serviceSubnet' ``` - **解决方案**: ```bash # 示例:避免与默认服务 CIDR(10.96.0.0/12)重叠 excludeCIDRs: - "192.168.100.0/24" # 使用非集群内部范围的 CIDR ``` --- #### **原因4:kube-proxy 日志报错** - **检查步骤**: 查看 kube-proxy 日志: ```bash kubectl -n kube-system logs <kube-proxy-pod-name> | grep -i exclude ``` 常见错误: - `invalid CIDR`(格式错误) - `unsupported feature`(模式不兼容) - **解决方案**: 根据日志修复配置,例如: ```yaml # 正确格式(YAML 数组) excludeCIDRs: - "172.18.0.0/24" - "10.2.1.0/24" ``` --- #### **终极验证方法** 1. 创建测试 Service: ```bash kubectl expose deploy nginx --port=80 --target-port=80 --name=test-svc ``` 2. 从排除的 CIDR 发起请求(如节点网络): ```bash # 在节点上执行 curl -I <test-svc-IP> ``` **预期结果**:直接返回(不经过 kube-proxy),而非 Service 的响应。 若仍返回 Service 响应,说明规则未生效。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值