// 删除路由,ip addr del xxx命令funcdeleteIPRoute(namestring,rawIPstring)error{retries:=2varifacenetlink.Linkvarerrerrorfori:=0;i<retries;i++{// 通过LinkByName方法找到需要设置的网络接口iface,err=netlink.LinkByName(name)iferr==nil{break}log.Debugf("error retrieving new bridge netlink link [ %s ]... retrying",name)time.Sleep(2*time.Second)}iferr!=nil{returnerrors.Wrap(err,"abandoning retrieving the new bridge link from netlink, Run [ ip link ] to troubleshoot")}// 查询对应设备的路由并全部删除list,err:=netlink.RouteList(iface,netlink.FAMILY_V4)iferr!=nil{returnerr}for_,route:=rangelist{ifroute.Dst.String()==rawIP{// 根据子网进行匹配err=netlink.RouteDel(&route)iferr!=nil{log.Errorf("route [%v] del failed,detail:%v",route,err)continue}}}returnnil}
SNAT 规则清理
iptables 删除比较简单,就是把添加命令中的 -A 改成 -D即可,相比于按行号删除,这种方式不会删错。
// deleteBridge deletes the bridgefunc(d*BridgeNetworkDriver)deleteBridge(n*Network)error{bridgeName:=n.Name// get the linkl,err:=netlink.LinkByName(bridgeName)iferr!=nil{returnfmt.Errorf("getting link with name %s failed: %v",bridgeName,err)}// delete the linkiferr=netlink.LinkDel(l);err!=nil{returnfmt.Errorf("failed to remove bridge interface %s delete: %v",bridgeName,err)}returnnil}
funcremoveContainer(containerIdstring,forcebool){containerInfo,err:=getInfoByContainerId(containerId)iferr!=nil{log.Errorf("Get container %s info error %v",containerId,err)return}switchcontainerInfo.Status{casecontainer.STOP:// STOP 状态容器直接删除即可// 先删除配置目录,再删除rootfs 目录iferr=container.DeleteContainerInfo(containerId);err!=nil{log.Errorf("Remove container [%s]'s config failed, detail: %v",containerId,err)return}container.DeleteWorkSpace(containerId,containerInfo.Volume)ifcontainerInfo.NetworkName!=""{// 清理网络资源iferr=network.Disconnect(containerInfo.NetworkName,containerInfo);err!=nil{log.Errorf("Remove container [%s]'s config failed, detail: %v",containerId,err)return}}casecontainer.RUNNING:// RUNNING 状态容器如果指定了 force 则先 stop 然后再删除if!force{log.Errorf("Couldn't remove running container [%s], Stop the container before attempting removal or"+" force remove",containerId)return}log.Infof("force delete running container [%s]",containerId)stopContainer(containerId)removeContainer(containerId,force)default:log.Errorf("Couldn't remove container,invalid status %s",containerInfo.Status)return}}
5. 测试
测试以下几部分:
网络资源清理测试
容器信息记录测试
容器网络资源清理测试
网络资源清理测试
测试网络删除后,对应的bridge、路由、iptables 等资源是否清理干净。
1
2
3
4
5
root@mydocker:~/feat-network-2/mydocker# go build .
root@mydocker:~/feat-network-2/mydocker# ./mydocker network create --driver bridge --subnet 10.10.10.1/24 testbr
root@mydocker:~/feat-network-3/mydocker# ./mydocker network list
NAME IpRange Driver
testbr1 10.10.0.1/24 bridge
查看对应设备
1
2
3
4
5
6
7
8
9
10
11
12
# brigde 设备root@mydocker:~/feat-network-3/mydocker# ip link show type bridge
15: testbr: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/ether 82:80:36:11:30:2f brd ff:ff:ff:ff:ff:ff
# 路由root@mydocker:~/feat-network-3/mydocker# ip r
10.10.10.0/24 dev testbr proto kernel scope link src 10.10.10.1
# iptablesroot@mydocker:~/feat-network-3/mydocker# iptables -t nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT)target prot opt source destination
MASQUERADE all -- 10.10.0.0/24 anywhere
# 网桥设备root@mydocker:~/feat-network-3/mydocker# ip link show type bridge
# 路由规则root@mydocker:~/feat-network-3/mydocker# ip r
# iptablesroot@mydocker:~/feat-network-3/mydocker# iptables -t nat -L POSTROUTING
Chain POSTROUTING (policy ACCEPT)target prot opt source destination
可以看到都删除了,说明网络资源清理是正常的。
容器信息记录测试
测试容器信息是否能够正常记录和展示。
创建一个网络
1
2
3
4
root@mydocker:~/feat-network-2/mydocker# ./mydocker network create --driver bridge --subnet 10.10.10.1/24 testbr
root@mydocker:~/feat-network-3/mydocker# ./mydocker network list
NAME IpRange Driver
testbr1 10.10.0.1/24 bridge
然后启动容器指定使用该网络
1
./mydocker run -it -net testbr busybox sh
另一个终端查看容器信息
1
2
3
root@mydocker:~/feat-network-3/mydocker# ./mydocker ps
ID NAME PID IP STATUS COMMAND CREATED
39943009863994300986 10.10.10.2 103669 running sh 2024-03-07 13:24:34
退出前台容器
1
/ # exit
再次查看容器信息
1
2
root@mydocker:~/feat-network-3/mydocker# ./mydocker ps
ID NAME PID IP STATUS COMMAND CREATED
删除了,一切正常。
容器网络资源清理测试
前台容器
1
./mydocker run -it -p 8080:80 -net testbr busybox sh
./mydocker run -d -p 8080:80 -net testbr busybox top
查看运行情况
1
2
3
root@mydocker:~/feat-network-3/mydocker# ./mydocker ps
ID NAME PID IP STATUS COMMAND CREATED
18918213121891821312 10.10.10.5 103828 running top 2024-03-07 13:32:19
同样的,查看 veth 设备和 DNAT 规则
1
2
3
4
5
6
7
8
9
root@mydocker:~/feat-network-3/mydocker# ip a
26: 18918@if25: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master testbr state UP group default qlen 1000 link/ether ba:ab:aa:cb:21:70 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet6 fe80::b8ab:aaff:fecb:2170/64 scope link
valid_lft forever preferred_lft forever
root@mydocker:~/feat-network-3/mydocker# iptables -t nat -L PREROUTING
Chain PREROUTING (policy ACCEPT)target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:http-alt to:10.10.10.5:80