一、k8s网络通信
- k8s通过CNI接口接入其他插件来实现网络通讯。目前比较流行的插件有flannel,calico等。 CNI插件存放位置:# cat /etc/cni/net.d/10-flannel.conflist
插件使用的解决方案如下:
- 虚拟网桥,虚拟网卡,多个容器共用一个虚拟网卡进行通信。
- 多路复用:MacVLAN,多个容器共用一个物理网卡进行通信。
- 硬件交换:SR-LOV,一个物理网卡可以虚拟出多个接口,这个性能最好。
容器间通信:同一个pod内的多个容器间的通信,通过lo回环网络接口即可实现;
pod之间的通信:
同一节点的pod之间通过cni网桥转发数据包。
不同节点的pod之间的通信需要网络插件支持。
pod和service通信: 通过iptables或ipvs实现通信,ipvs取代不了iptables,因为ipvs只能做负载均衡,而做不了nat转换。
pod和外网通信: iptables的MASQUERADE。
Service与集群外部客户端的通信:ingress、nodeport、loadbalancer
二、service与service代理
- Service:Kubernetes Service 定义了这样一种抽象:逻辑上的一组 Pod,一种可以访问它们的策略 ,通常称为微服务。
- 在 Kubernetes 集群中,每个 Node 运行一个 kube-proxy 进程。 kube-proxy 负责为 Service
实现了一种 VIP(虚拟 IP)的形式,而不是 ExternalName 的形式。
01_ userspace 代理模式
- 这种模式,kube-proxy 会监视 Kubernetes 控制平面对 Service 对象和 Endpoints对象的添加和移除操作。 对每个 Service,它会在本地 Node 上打开一个端口(随机选择)。任何连接到“代理端口”的请求,都会被代理到 Service 的后端 Pods 中的某个上面(如 Endpoints 所报告的一样)。
使用哪个后端 Pod,是 kube-proxy 基于 SessionAffinity 来确定的。 - 最后,它配置 iptables 规则,捕获到达该 Service 的 clusterIP(是虚拟 IP) 和 Port
的请求,并重定向到代理端口,代理端口再代理请求到后端Pod。 - 默认情况下,用户空间模式下的 kube-proxy 通过轮转算法选择后端。
02_iptables 代理模式
- 这种模式,kube-proxy 会监视 Kubernetes 控制节点对 Service 对象和 Endpoints 对象的添加和移除。对每个 Service,它会配置 iptables 规则,从而捕获到达该 Service 的 clusterIP和端口的请求,进而将请求重定向到 Service 的一组后端中的某个 Pod 上面。 对于每个 Endpoints 对象,它也会配置iptables 规则,这个规则会选择一个后端组合。
- 默认的策略是,kube-proxy 在 iptables 模式下随机选择一个后端。
- 使用 iptables 处理流量具有较低的系统开销,因为流量由 Linux netfilter 处理,而无需在用户空间和内核空间之间切换。 这种方法也可能更可靠。
- 如果 kube-proxy 在 iptables 模式下运行,并且所选的第一个 Pod 没有响应, 则连接失败。这与用户空间模式不同:在这种情况下,kube-proxy 将检测到与第一个 Pod 的连接已失败, 并会自动使用其他后端 Pod 重试。
- 可以使用 Pod 就绪探测器 验证后端 Pod 可以正常工作,以便 iptables 模式下的 kube-proxy
仅看到测试正常的后端。 这样做意味着你避免将流量通过 kube-proxy 发送到已知已失败的 Pod。
03 _IPVS模式
- 在 ipvs 模式下,kube-proxy 监视 Kubernetes 服务和端点,调用 netlink 接口相应地创建 IPVS 规则,
并定期将 IPVS 规则与 Kubernetes 服务和端点同步。 该控制循环可确保IPVS 状态与所需状态匹配。访问服务时,IPVS将流量定向到后端Pod之一。 - IPVS代理模式基于类似于 iptables 模式的 netfilter 挂钩函数,但是使用哈希表作为基础数据结构,并且在内核空间中工作。 这意味着,与 iptables 模式下的 kube-proxy 相比,IPVS模式下的 kube-proxy 重定向通信的延迟要短,并且在同步代理规则时具有更好的性能。 与其他代理模式相比,IPVS模式还支持更高的网络流量吞吐量。
- IPVS 提供了更多选项来平衡后端 Pod 的流量。
- 要在 IPVS 模式下运行 kube-proxy,必须在启动 kube-proxy 之前使 IPVS 在节点上可用。
- 当 kube-proxy 以 IPVS 代理模式启动时,它将验证 IPVS 内核模块是否可用。 如果未检测到 IPVS 内核模块,则kube-proxy 将退回到以 iptables 代理模式运行。
- Service 是由 kube-proxy 组件,加上 iptables 来共同实现的.
- kube-proxy 通过 iptables 处理 Service 的过程,需要在宿主机上设置相当多的 iptables
规则,如果宿主机有大量的Pod,不断刷新iptables规则,会消耗大量的CPU资源。 - IPVS模式的service,可以使K8s集群支持更多量级的Pod。
开启kube-proxy的ipvs模式:
- 所有节点安装:
yum install -y ipvsadm
- master端修改为ipvs模式
kubectl edit cm kube-proxy -n kube-system
mode: "ipvs"
- master端更新kube-proxy
kubectl get pod -n kube-system |grep kube-proxy | awk '{system("kubectl delete pod "$1" -n kube-system")}'
- 创建ipvs模式的service
vim demo.yml
---
apiVersion: v1
kind: Service
metadata:
name: myservice
spec:
selector:
app: myapp
ports:
- protocol: TCP
port: 80
targetPort: 80
---
apiVersion: apps/v1
kind: Deployment
metadata