需求

需要容器 dhcp 获取IP, 而且网络和宿主机处于同一级网络

容器内部命令

  1. __set_network() {
  2. _bridge="br-wan1" # 外部网桥, 容器网络最终连接的外部网络
  3. _netns_pid=$(nsenter --mount=/host/1/ns/mnt docker inspect $(cat /proc/self/cgroup | grep devices | grep -Po '[0-9a-z]{64}' | cut -c1-12) -f '{{.State.Pid}}') # 取得容器的 Pid
  4. nsenter --mount=/host/1/ns/mnt --net=/host/1/ns/net bash -c "mkdir -p /var/run/netns/; ln -s /proc/${_netns_pid}/ns/net /var/run/netns/${_netns_pid};" # 创建文件夹, 将容器的命名空间表现出来
  5. nsenter --mount=/host/1/ns/mnt --net=/host/1/ns/net bash -c "ip link add veth-n-${_netns_pid} type veth peer name veth-w-${_netns_pid}; " # 链接容器 netns
  6. nsenter --mount=/host/1/ns/mnt --net=/host/1/ns/net bash -c "ip link set dev veth-w-${_netns_pid} master ${_bridge}; ip link set up veth-w-${_netns_pid}" # 创建 veth 并加入网桥
  7. nsenter --mount=/host/1/ns/mnt --net=/host/1/ns/net bash -c "ip link set dev veth-n-${_netns_pid} name eth1 netns ${_netns_pid};" # 将 veth 对端加入容器 netns, 这里的 eth1 是可更改的, 是显示在容器内部的网卡名称
  8. nsenter --mount=/host/1/ns/mnt --net=/host/1/ns/net bash -c "ip a | grep LOWERLAYERDOWN | awk -F '@|:' '{print \$2}' | xargs -I{} echo 'ip link del dev {}'" # 清除一些已经失效的命名空间 (可选)
  9. # 直接配置 ip,
  10. ip addr flush dev eth1
  11. ip addr add 192.168.2.11/24 dev eth1
  12. ip link set up eth1
  13. ip r replace default via 192.168.2.254 dev eth1
  14. # 如果像使用dhcp 服务的话, 直接运dhcp客户端就行, ubuntu 容器内部推荐安装 dhcpcd5
  15. # apt-get install dhcpcd5
  16. # tcpdump -nnt -i veth-w-13208
  17. }
  18. __set_network

本文涉及以下知识点

Docker 容器内执行宿主机命令
Linux 虚拟网络设备 veth-pair 详解
Linux 网桥