探索K8s的网络与Cilium的实践
importance
date
May 24, 2024
slug
探索K8s的网络与Cilium的实践
status
Published
tags
k8s
cilium
summary
探索K8s的网络与Cilium的实践
type
Post
因为Cilium构建在eBPF之上,于是一个上午我都挣扎在eBPF,这耗费了我很多时间,但是我依旧没有搞清楚eBPF的原理、使用甚至于什么场景eBPF会用到我都不太明白,感觉这是一个非常大的topic,2小时的匆匆浏览几乎没有什么用处,令人沮丧。
Cilium为了解决什么问题?
在Cilium官网提到了为什么需要Cilium,主要要这几个问题:
传统的Linux网络安全方法(如iptables)基于IP地址和TCP/UDP端口进行过滤,但在动态微服务环境中IP地址频繁变化。容器的高度波动生命周期使得这些传统方法难以与应用程序的扩展同步。协议端口(如HTTP的TCP端口80)无法区分应用程序流量用于安全目的,因为一个机器运行多个微服务他们都通过80于外界沟通。
总结来说,传统的网络安全策略例如ufw还是作用在TCP/IP层,无法很好地对容器化的微服务进行有效管理。Cilium作用在应用层,它可以识别到不同的流量并进行过滤。
我自己的理解,Cilium解决的问题,或者说其最大的用处,是基于ebpf对service的网络进行管理,而k8s中的sevice都是有label的,因此Cilium可以利用label而非IP或者端口来进行网络管理。例如当前service只允许某个service进行访问。
example: Allowservice1
to produce on Kafka topictopic1
andservice2
to consume ontopic1
. Reject all other Kafka messages.
Cilium的组件
Cilium是一个CNI插件,CNI指的是Container Network Interface
In Kubernetes, each Pod is assigned a unique IP address and can communicate with other Pods without requiring NAT. To provide networking to Pods, Kubernetes uses Container Network Interface (CNI), a library for configuring network interfaces in Linux containers. The kubelet is responsible for setting up the network for new Pods using the CNI plugin specified in the configuration file located in the/etc/cni/net.d/
directory on the node
CNI就是 library for configuring network interfaces in Linux containers,kubelet在创建pod的时候会自动调用CNI插件(如果配置文件中有指定的的话)来设定网络。
K8s的网络很简单:
探索Minikube中的网络
首先我现在自己的机器上使用minikube创建了3个节点的集群。https://www.songlin.life/K8s Basic
可以看到他们处于192.169.49.0/24网段内
继续查看位于这些node之上的pods,如果pod位于同一个node,那么他们处于10.244.x.0/24子网内,如果位于不同node,则位于10.244.0.0/16 网段内。
问题来了,k8s官方的文档提到:
pods can communicate with all other pods on any other node without NAT.
意味着不同pod之间的网络是互通的。为了验证这一点,进入了my-webapp-9f87dd8f-wjw8r 10.244.2.4这个pod中,这个pod位于node -multinode-demo-m03中,node的ip为192.168.49.4
在这个pod内对其他pod进行ping操作,发现都是可以通的。10.244.1.2与10.244.0.3分别位于不同node上。
How k8s do that?
在pod中,先安装一个traceroute,使用traceroute查看路径。首先packet通过了10.244.2.1。
通过
ip route
查看了当前的路由表,默认情况下会发到eth0。而eth0为一个虚拟网卡,作为 Veth Pair,它的另一端在node中,发到eth0的数据,最终会被发到node的veth pair上。查看node中的路由表,可以看到10.244.0.0/24 也会通过eth0发送到192.168.49.2也就是node multinode-demo。为此,我需要进入宿主机中查看我当前宿主机的路由表。minikube 实际上就是通过创建了docker来模拟集群,所以这个eth0应该也是一个Veth pair。
最终通过br-c604这个设备发送到192.48.49.2这个虚拟node上。因为node也是container,所以br-c604知道如何发送数据。
由于我之前很少用perf之类的工具,很难深入了解这个packet在这些过程中发生了怎么的变化,只能从ip route 这个大的规则来理解整个网络。