pipework給docker設置ip

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/[email protected]
這裏給-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_SETNS
static 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/[email protected]沒報錯,查看一下是否成功
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

發佈了68 篇原創文章 · 獲贊 74 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章