找回密码
 立即注册
首页 业界区 业界 通过命令模拟pod创建

通过命令模拟pod创建

巨耗 3 天前
介绍

这篇文章主要涉及到 kubelet 通过 csi 向运行时发送创建请求,运行时发生了什么?pod 网络又是怎么连通的?
对应的流量图

我们将使用 docker 和 linux Bridge 去完成这个 pod 需求
流程描述

kubelet 通过 CRI 接口调用运行时(如 containerd)创建 pod。该过程分为两步:

  • 创建 Pod Sandbox:运行时先启动一个轻量的 pause 容器。其核心作用是调用 runc 创建并持有一个独立的 Linux Network Namespace,为 Pod 提供网络沙盒环境。
  • 创建业务容器:运行时随后创建业务容器(如 Nginx),并通过指定 network namespace 路径,使其直接加入 pause 容器所在的 Network Namespace,从而实现网络共享。
Pod 沙盒就绪后,运行时调用 CNI 插件配置网络。插件执行如下操作:

  • 创建 veth pair,一端放入容器命名空间内(命名为 eth0),另一端连接至主机网桥(如 br0)
  • 为容器内的 eth0 分配 IP 并设置路由,网关指向网桥。
  • 配置主机 iptables 规则,实现 SNAT 以使 Pod 能访问外部网络,并设置转发规则。
实际操作

创建网桥

这个网桥充当虚拟交换机,所有 pod 流量都通过该设备传递到物理网卡
  1. # 增加一个网卡设备
  2. ip link add name br0 type bridge
  3. # 向网卡设备添加地址
  4. ip addr add 10.0.0.1/24 dev br0
  5. # 设置网卡启动
  6. ip link set dev br0 up
  7. # 验证
  8. ip a
复制代码
启动 pod 外壳并劫持网络空间
  1. # 创建pod外壳容器
  2. docker run -itd --name my-pod --network=none docker.1ms.run/rancher/mirrored-pause:3.9
  3. # 劫持容器网络命名空间
  4. mkdir -p /var/run/netns
  5. ln -sf /var/run/docker/netns/ce39ddc16db1 /var/run/netns/my-pod
  6. # 验证
  7. ip netns
复制代码

配置 pod 网络(模拟 CNI 插件)

我们将手动模拟 CNI(bridge)插件的工作:创建 veth pair,连接容器和网桥,分配 IP,设置路由
  1. # 创建一对虚拟以太网设备(veth pair)
  2. # veth-pod:将留在主机默认命名空间的一端
  3. # veth-cont:将留在容器命名空间的一端
  4. ip link add veth-pod type veth peer name veth-cont
  5. # 将veth-cont 放到容器命名空间内部
  6. ip link set veth-cont netns my-pod
  7. # 重命名veth-cont,将其改成符合容器的标准名称eth0
  8. ip netns exec my-pod ip link set veth-cont name eth0
  9. # 启动容器内命名空间网卡
  10. ip netns exec my-pod ip link set eth0 up
  11. # 为容器命名空间内的网卡配置地址要和刚才网关网卡地址一致
  12. ip netns exec my-pod ip addr add 10.0.0.2/24 dev eth0
  13. # 添加到网关的路由
  14. ip netns exec my-pod ip route add default via 10.0.0.1
  15. # 给外面这一端网卡绑定master
  16. ip link set veth-pod master br0
  17. # 启动外面这一端网卡
  18. ip link set veth-pod up
  19. # 验证容器网络命名空间内网络环境
  20. ip netns exec my-pod ip addr show
  21. ip netns exec my-pod route -n
  22. ip netns exec my-pod ping 10.0.0.1
复制代码

创建业务容器
  1. docker run -itd --name nginx-pod --network container:my-pod nginx:alpine
复制代码
配置主机网络和 iptables 模拟 kubeporxy

为了让流量能进出 Pod,我们需要配置内核转发和 iptables 规则。
  1. # 开启内核转发功能
  2. echo 1 | sudo tee /proc/sys/net/ipv4/ip_forward
  3. # 配置SNAT
  4. # 解析:
  5. #  10.244.1.0/24(Pod网段),且要从主机的物理网卡(假设是eth0)出去的流量,将其源IP伪装成主机自己的IP。
  6. # 这样,外部网络回包时才知道送回给哪个主机
  7. iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
  8. # 添加一条 iptables DNAT 规则,将端口转发到业务网络命名空间内
  9. # -t nat: 操作 nat 表
  10. # -A PREROUTING: 在数据包刚到达时就进行规则判断
  11. # -p tcp --dport 30080: 匹配协议为 TCP,且目标端口是 30080 的流量
  12. # -j DNAT: 进行目标地址转换(DNAT)
  13. # --to-destination 10.0.0.2:80: 将目标地址改为 Pod 的 IP 和端口
  14. iptables -t nat -D PREROUTING -p tcp --dport 30080 -j DNAT --to-destination 10.0.0.2:80
  15. iptables -t nat -D OUTPUT -d 127.0.0.1/32 -p tcp --dport 30080 -j DNAT --to-destination 10.0.0.2:80
  16. iptables -t nat -I PREROUTING 1 -p tcp --dport 30080 -j DNAT --to-destination 10.0.0.2:80
  17. iptables -t nat -I OUTPUT 1 -p tcp --dport 30080 -j DNAT --to-destination 10.0.0.2:80
  18. # 验证规则
  19. iptables -t nat -L POSTROUTING -n -v
  20. # 验证访问
  21. curl -v http://192.168.1.114:30080
复制代码


清理环境
  1. # 删除容器
  2. docker stop 4728aeef69f8
  3. docker stop 3041747824eb
  4. docker rm 3041747824eb
  5. docker rm 4728aeef69f8
复制代码
重启主机

重启后所有规则默认删除

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

相关推荐

您需要登录后才可以回帖 登录 | 立即注册