Kubernetes (K8S) 网络原理

Veth 对OSPF基本配置

本页将详细介绍如何在 Linux 网络命名空间和 Veth 对环境中配置基本的 OSPF 路由。通过一个简单的实验,我们将展示 OSPF 如何自动发现路由并适应网络拓扑的变化。

实验环境准备

在开始实验之前,我们需要准备实验环境。这包括安装必要的软件包和创建网络拓扑。

安装必要的软件包

我们将使用 FRRouting (FRR) 作为 OSPF 路由软件。FRR 是一个功能强大的开源路由软件套件,支持多种路由协议,包括 OSPF。

# 添加 FRR 源 curl -s https://deb.frrouting.org/frr/keys.asc | sudo apt-key add - echo deb https://deb.frrouting.org/frr $(lsb_release -s -c) frr-stable | sudo tee -a /etc/apt/sources.list.d/frr.list # 安装 FRR sudo apt update sudo apt install -y frr frr-pythontools # 安装其他必要的工具 sudo apt install -y net-tools tcpdump traceroute

实验拓扑

我们将创建一个简单的拓扑,包含三个网络命名空间,形成一个三角形。每个命名空间都通过 Veth 对与其他两个命名空间相连。

每个命名空间还有一个环回接口,用于模拟内部网络:

创建网络拓扑

首先,我们需要创建网络命名空间和 Veth 对,并配置 IP 地址。

创建网络命名空间

# 创建三个网络命名空间 sudo ip netns add ns1 sudo ip netns add ns2 sudo ip netns add ns3 # 验证创建结果 ip netns list

创建 Veth 对

# 创建三对 Veth 设备 # ns1 和 ns2 之间的 Veth 对 sudo ip link add veth1-2 type veth peer name veth2-1 # ns1 和 ns3 之间的 Veth 对 sudo ip link add veth1-3 type veth peer name veth3-1 # ns2 和 ns3 之间的 Veth 对 sudo ip link add veth2-3 type veth peer name veth3-2 # 验证创建结果 ip link show type veth

分配 Veth 设备到网络命名空间

# 将 Veth 设备分配到相应的网络命名空间 # ns1 的设备 sudo ip link set veth1-2 netns ns1 sudo ip link set veth1-3 netns ns1 # ns2 的设备 sudo ip link set veth2-1 netns ns2 sudo ip link set veth2-3 netns ns2 # ns3 的设备 sudo ip link set veth3-1 netns ns3 sudo ip link set veth3-2 netns ns3 # 验证分配结果 sudo ip netns exec ns1 ip link show sudo ip netns exec ns2 ip link show sudo ip netns exec ns3 ip link show

配置 IP 地址

# 配置 ns1 的 IP 地址 sudo ip netns exec ns1 ip addr add 10.0.1.1/24 dev veth1-2 sudo ip netns exec ns1 ip addr add 10.0.2.1/24 dev veth1-3 sudo ip netns exec ns1 ip addr add 192.168.1.1/24 dev lo sudo ip netns exec ns1 ip link set veth1-2 up sudo ip netns exec ns1 ip link set veth1-3 up sudo ip netns exec ns1 ip link set lo up # 配置 ns2 的 IP 地址 sudo ip netns exec ns2 ip addr add 10.0.1.2/24 dev veth2-1 sudo ip netns exec ns2 ip addr add 10.0.3.1/24 dev veth2-3 sudo ip netns exec ns2 ip addr add 192.168.2.1/24 dev lo sudo ip netns exec ns2 ip link set veth2-1 up sudo ip netns exec ns2 ip link set veth2-3 up sudo ip netns exec ns2 ip link set lo up # 配置 ns3 的 IP 地址 sudo ip netns exec ns3 ip addr add 10.0.2.2/24 dev veth3-1 sudo ip netns exec ns3 ip addr add 10.0.3.2/24 dev veth3-2 sudo ip netns exec ns3 ip addr add 192.168.3.1/24 dev lo sudo ip netns exec ns3 ip link set veth3-1 up sudo ip netns exec ns3 ip link set veth3-2 up sudo ip netns exec ns3 ip link set lo up # 验证配置 sudo ip netns exec ns1 ip addr sudo ip netns exec ns2 ip addr sudo ip netns exec ns3 ip addr

启用 IP 转发

# 在所有命名空间中启用 IP 转发 sudo ip netns exec ns1 sysctl -w net.ipv4.ip_forward=1 sudo ip netns exec ns2 sysctl -w net.ipv4.ip_forward=1 sudo ip netns exec ns3 sysctl -w net.ipv4.ip_forward=1 # 验证 IP 转发是否启用 sudo ip netns exec ns1 sysctl net.ipv4.ip_forward sudo ip netns exec ns2 sysctl net.ipv4.ip_forward sudo ip netns exec ns3 sysctl net.ipv4.ip_forward

配置 FRRouting

现在我们需要为每个网络命名空间配置 FRRouting,启用 OSPF。

为每个命名空间创建 FRR 配置目录

# 创建配置目录 sudo mkdir -p /etc/frr/ns1 sudo mkdir -p /etc/frr/ns2 sudo mkdir -p /etc/frr/ns3 # 复制默认配置文件 sudo cp /etc/frr/daemons /etc/frr/ns1/ sudo cp /etc/frr/daemons /etc/frr/ns2/ sudo cp /etc/frr/daemons /etc/frr/ns3/ # 创建空的 frr.conf 文件 sudo touch /etc/frr/ns1/frr.conf sudo touch /etc/frr/ns2/frr.conf sudo touch /etc/frr/ns3/frr.conf # 设置权限 sudo chown -R frr:frr /etc/frr/ns1 sudo chown -R frr:frr /etc/frr/ns2 sudo chown -R frr:frr /etc/frr/ns3 sudo chmod 640 /etc/frr/ns1/frr.conf sudo chmod 640 /etc/frr/ns2/frr.conf sudo chmod 640 /etc/frr/ns3/frr.conf

启用 OSPF

# 编辑 ns1 的 daemons 文件 sudo sed -i 's/ospfd=no/ospfd=yes/' /etc/frr/ns1/daemons # 编辑 ns2 的 daemons 文件 sudo sed -i 's/ospfd=no/ospfd=yes/' /etc/frr/ns2/daemons # 编辑 ns3 的 daemons 文件 sudo sed -i 's/ospfd=no/ospfd=yes/' /etc/frr/ns3/daemons

创建 FRR 配置文件

# 创建 ns1 的 frr.conf 文件 cat << 'EOF' | sudo tee /etc/frr/ns1/frr.conf frr version 7.5 frr defaults traditional hostname ns1 log syslog informational service integrated-vtysh-config ! router ospf ospf router-id 192.168.1.1 network 10.0.1.0/24 area 0 network 10.0.2.0/24 area 0 network 192.168.1.0/24 area 0 ! line vty ! EOF # 创建 ns2 的 frr.conf 文件 cat << 'EOF' | sudo tee /etc/frr/ns2/frr.conf frr version 7.5 frr defaults traditional hostname ns2 log syslog informational service integrated-vtysh-config ! router ospf ospf router-id 192.168.2.1 network 10.0.1.0/24 area 0 network 10.0.3.0/24 area 0 network 192.168.2.0/24 area 0 ! line vty ! EOF # 创建 ns3 的 frr.conf 文件 cat << 'EOF' | sudo tee /etc/frr/ns3/frr.conf frr version 7.5 frr defaults traditional hostname ns3 log syslog informational service integrated-vtysh-config ! router ospf ospf router-id 192.168.3.1 network 10.0.2.0/24 area 0 network 10.0.3.0/24 area 0 network 192.168.3.0/24 area 0 ! line vty ! EOF

启动 FRRouting

现在我们需要在每个网络命名空间中启动 FRRouting。

创建运行脚本

# 创建运行脚本 cat << 'EOF' | sudo tee /tmp/start_frr.sh #!/bin/bash # 停止主机上的 FRR sudo systemctl stop frr # 在 ns1 中启动 FRR sudo ip netns exec ns1 /usr/lib/frr/zebra -d -f /etc/frr/ns1/zebra.conf -z /tmp/ns1_zebra.sock -i /tmp/ns1_zebra.pid sudo ip netns exec ns1 /usr/lib/frr/ospfd -d -f /etc/frr/ns1/ospfd.conf -z /tmp/ns1_zebra.sock -i /tmp/ns1_ospfd.pid # 在 ns2 中启动 FRR sudo ip netns exec ns2 /usr/lib/frr/zebra -d -f /etc/frr/ns2/zebra.conf -z /tmp/ns2_zebra.sock -i /tmp/ns2_zebra.pid sudo ip netns exec ns2 /usr/lib/frr/ospfd -d -f /etc/frr/ns2/ospfd.conf -z /tmp/ns2_zebra.sock -i /tmp/ns2_ospfd.pid # 在 ns3 中启动 FRR sudo ip netns exec ns3 /usr/lib/frr/zebra -d -f /etc/frr/ns3/zebra.conf -z /tmp/ns3_zebra.sock -i /tmp/ns3_zebra.pid sudo ip netns exec ns3 /usr/lib/frr/ospfd -d -f /etc/frr/ns3/ospfd.conf -z /tmp/ns3_zebra.sock -i /tmp/ns3_ospfd.pid EOF # 设置执行权限 sudo chmod +x /tmp/start_frr.sh # 运行脚本 sudo /tmp/start_frr.sh

验证 FRR 是否运行

# 检查进程 ps aux | grep frr

验证 OSPF 配置

现在我们需要验证 OSPF 是否正常工作。

检查 OSPF 邻居

# 在 ns1 中检查 OSPF 邻居 sudo ip netns exec ns1 vtysh -c "show ip ospf neighbor" # 在 ns2 中检查 OSPF 邻居 sudo ip netns exec ns2 vtysh -c "show ip ospf neighbor" # 在 ns3 中检查 OSPF 邻居 sudo ip netns exec ns3 vtysh -c "show ip ospf neighbor"

检查 OSPF 路由

# 在 ns1 中检查 OSPF 路由 sudo ip netns exec ns1 vtysh -c "show ip ospf route" # 在 ns2 中检查 OSPF 路由 sudo ip netns exec ns2 vtysh -c "show ip ospf route" # 在 ns3 中检查 OSPF 路由 sudo ip netns exec ns3 vtysh -c "show ip ospf route"

检查 IP 路由表

# 在 ns1 中检查 IP 路由表 sudo ip netns exec ns1 ip route # 在 ns2 中检查 IP 路由表 sudo ip netns exec ns2 ip route # 在 ns3 中检查 IP 路由表 sudo ip netns exec ns3 ip route

测试连通性

现在我们需要测试网络连通性,验证 OSPF 是否正确地发现了所有路由。

测试直接连接

# 从 ns1 ping ns2 sudo ip netns exec ns1 ping -c 3 10.0.1.2 # 从 ns1 ping ns3 sudo ip netns exec ns1 ping -c 3 10.0.2.2 # 从 ns2 ping ns3 sudo ip netns exec ns2 ping -c 3 10.0.3.2

测试环回接口

# 从 ns1 ping ns2 的环回接口 sudo ip netns exec ns1 ping -c 3 192.168.2.1 # 从 ns1 ping ns3 的环回接口 sudo ip netns exec ns1 ping -c 3 192.168.3.1 # 从 ns2 ping ns3 的环回接口 sudo ip netns exec ns2 ping -c 3 192.168.3.1

使用 traceroute 查看路径

# 从 ns1 到 ns2 的环回接口 sudo ip netns exec ns1 traceroute 192.168.2.1 # 从 ns1 到 ns3 的环回接口 sudo ip netns exec ns1 traceroute 192.168.3.1 # 从 ns2 到 ns3 的环回接口 sudo ip netns exec ns2 traceroute 192.168.3.1

模拟链路故障

现在我们将模拟链路故障,观察 OSPF 如何自动调整路由。

关闭 ns1 和 ns2 之间的链路

# 关闭 ns1 和 ns2 之间的链路 sudo ip netns exec ns1 ip link set veth1-2 down sudo ip netns exec ns2 ip link set veth2-1 down # 等待 OSPF 收敛 sleep 30

检查 OSPF 邻居

# 在 ns1 中检查 OSPF 邻居 sudo ip netns exec ns1 vtysh -c "show ip ospf neighbor" # 在 ns2 中检查 OSPF 邻居 sudo ip netns exec ns2 vtysh -c "show ip ospf neighbor"

检查 IP 路由表

# 在 ns1 中检查 IP 路由表 sudo ip netns exec ns1 ip route # 在 ns2 中检查 IP 路由表 sudo ip netns exec ns2 ip route

测试连通性

# 从 ns1 ping ns2 的环回接口 sudo ip netns exec ns1 ping -c 3 192.168.2.1 # 使用 traceroute 查看路径 sudo ip netns exec ns1 traceroute 192.168.2.1

你应该看到 ns1 到 ns2 的流量现在通过 ns3 转发,这是因为 OSPF 检测到直接链路故障,自动切换到备用路径。

恢复链路

现在我们将恢复链路,观察 OSPF 如何再次调整路由。

启用 ns1 和 ns2 之间的链路

# 启用 ns1 和 ns2 之间的链路 sudo ip netns exec ns1 ip link set veth1-2 up sudo ip netns exec ns2 ip link set veth2-1 up # 等待 OSPF 收敛 sleep 30

检查 OSPF 邻居

# 在 ns1 中检查 OSPF 邻居 sudo ip netns exec ns1 vtysh -c "show ip ospf neighbor" # 在 ns2 中检查 OSPF 邻居 sudo ip netns exec ns2 vtysh -c "show ip ospf neighbor"

检查 IP 路由表

# 在 ns1 中检查 IP 路由表 sudo ip netns exec ns1 ip route # 在 ns2 中检查 IP 路由表 sudo ip netns exec ns2 ip route

测试连通性

# 从 ns1 ping ns2 的环回接口 sudo ip netns exec ns1 ping -c 3 192.168.2.1 # 使用 traceroute 查看路径 sudo ip netns exec ns1 traceroute 192.168.2.1

你应该看到 ns1 到 ns2 的流量现在又通过直接链路转发,这是因为 OSPF 检测到链路恢复,自动切换回最优路径。

清理实验环境

实验完成后,我们需要清理环境。

清理 FRRouting

# 创建清理脚本 cat << 'EOF' | sudo tee /tmp/stop_frr.sh #!/bin/bash # 停止 ns1 中的 FRR sudo kill $(cat /tmp/ns1_ospfd.pid) $(cat /tmp/ns1_zebra.pid) # 停止 ns2 中的 FRR sudo kill $(cat /tmp/ns2_ospfd.pid) $(cat /tmp/ns2_zebra.pid) # 停止 ns3 中的 FRR sudo kill $(cat /tmp/ns3_ospfd.pid) $(cat /tmp/ns3_zebra.pid) # 删除 PID 文件 sudo rm -f /tmp/ns*_*.pid # 删除 socket 文件 sudo rm -f /tmp/ns*_*.sock # 重启主机上的 FRR sudo systemctl start frr EOF # 设置执行权限 sudo chmod +x /tmp/stop_frr.sh # 可选:如果需要,运行清理脚本 # sudo /tmp/stop_frr.sh

删除网络命名空间

# 删除网络命名空间 sudo ip netns delete ns1 sudo ip netns delete ns2 sudo ip netns delete ns3 # 验证删除结果 ip netns list

删除配置文件

# 删除配置文件 sudo rm -rf /etc/frr/ns1 sudo rm -rf /etc/frr/ns2 sudo rm -rf /etc/frr/ns3 sudo rm -f /tmp/ns* sudo rm -f /tmp/start_frr.sh sudo rm -f /tmp/stop_frr.sh

总结

在这个实验中,我们成功地在 Linux 网络命名空间环境中配置了 OSPF 路由。我们观察到 OSPF 如何自动发现路由,并在链路故障和恢复时自动调整路由。这展示了 OSPF 作为一种动态路由协议的强大功能。

主要收获:

下一步,你可以尝试更复杂的 OSPF 配置,如区域划分、路由汇总、路由重分发等。这些高级配置将在 OSPF 高级配置 页面中介绍。

相关资源