pipework给docker设置ip

来源:互联网 发布:mysql 最小id 查询 编辑:程序博客网 时间:2024/06/07 16:33

pipework下载地址
解压之后,有一个pipework文件,其实就是shell脚本。
1.创建启动一个容器
docker run -it -d –name test_pipework –net=none centos bash
2.给docker设置ip
sh -x /usr/bin/pipework br0 test_pipework 192.168.0.12/24@192.168.0.254
这里给-x是为了看shell脚本的执行过程都打印出来,br0这个网桥不需要你提前创建,pipework在你执行这个语句的时候进行创建绑定,执行之后报错Object “netns” is unknown, try “ip help”.可以看到我们打印的执行过程最后一行是ip netns exec 6979 ip link set veth1pg6979 name eth1,恰恰说明了ip命令不支持netns选项
3.下载ip源码进行安装编译,为什么下载源码进行安装编译,后面会说,千万不要直接下载二进制ip命令文件。iproute2下载地址
4.解压之后编译源码,make,make install。再次执行,结果还是报错seting the network namespace failed: Function not implemented
5.我们可以去源码里面看这段报错是执行的哪一段代码,打开iproute2-3.1.0/ip/ipnetns.c文件,在static int netns_exec(int argc, char **argv)函数中

if (setns(netns, CLONE_NEWNET) < 0) {    fprintf(stderr, "seting the network namespace failed: %s\n",        strerror(errno));    return -1;}

我们再看setns函数

#ifndef HAVE_SETNSstatic int setns(int fd, int nstype){#ifdef __NR_setns    return syscall(__NR_setns, fd, nstype);#else    errno = ENOSYS;    return -1;#endif}#endif /* HAVE_SETNS */

很明显,由于宏__NR_setns造成了没有调用syscall,我们可以修改代码

#ifndef __NR_setns#if defined(__x86_64__)#define __NR_setns 308#elif defined(__i386__)#define __NR_setns 346#elif defined(__arm__)#define __NR_setns 375#elif defined(__aarch64__)#define __NR_setns 375#elif defined(__powerpc__)#define __NR_setns 350#elif defined(__s390__)#define __NR_setns 339#endif#endif#ifndef HAVE_SETNS#if defined(__NR_setns)#include <sys/syscall.h>static int setns(int fd, int nstype){    return syscall(__NR_setns, fd, nstype);}#else /* !__NR_setns */#error Please determine the syscall number for setns on your architecture#endif#endif

再次编译,执行,成功!所以说不要下载ip命令二进制文件,我们要下载源码来编译,因为__NR_setns这个宏的值和系统相关。
6.再执行pipework br0 test_pipework 192.168.0.12/24@192.168.0.254没报错,查看一下是否成功
docker exec test_pipework ifconfig
这里写图片描述
7.但是你会发现在宿主主机和其它主机上ping这个docker还是ping不通,因为pipework仅仅只是给我们简单创建了一个br0网桥,但是还没有配置它,还需要我们自己配置
brctl show
这里写图片描述
brctl addbr br0
ip link set br0 up
ip addr add 192.168.0.99/24 dev br0
ip addr del 192.168.0.99/24 dev eth0
brctl addif br0 eth0
ip route del default
ip route add default via 192.168.0.254 dev br0
我们再看一下网桥brctl show
这里写图片描述
这里先是给br0设置了原本eth0的ip地址,然后把eth0删除这个ip地址,再把eth0作为br0的网口,最后删除默认路由,增加一个新路由
给docker设置ip成功之后,如果重启docker,设置会失效,需要再次调用pipework重新设置ip。
现在这个test_pipework已经可以在宿主主机和同一网段其它机器都可以ping通
8.代码修改部分是参考这里https://www.redhat.com/archives/libvir-list/2015-August/msg00910.html
9.docker0和br0的网络配置区别http://www.linuxidc.com/Linux/2016-08/134035.htm

原创粉丝点击