-
#define _GNU_SOURCE
-
#include <sys/types.h>
-
#include <sys/wait.h>
-
#include <sys/mount.h>
-
#include <stdio.h>
-
#include <sched.h>
-
#include <signal.h>
-
#include <unistd.h>
-
-
-
#define STACK_SIZE (1024 * 1024)
-
static char container_stack[STACK_SIZE];
-
-
char* const container_args[] = {
-
"/bin/bash",
-
NULL
-
};
-
-
-
int container_main(void* arg)
-
{
-
mount("none", "/", NULL, MS_REC|MS_PRIVATE, NULL);
-
mount("proc", "/proc", "proc", 0, NULL);
-
execv(container_args[0], container_args);
-
printf("Error!\n");
-
return 1;
-
}
-
-
int main()
-
{
-
int container_pid = clone(container_main, container_stack+STACK_SIZE,
-
CLONE_NEWUTS | CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWNET | SIGCHLD, NULL);
-
waitpid(container_pid, NULL, 0);
-
return 0;
-
}
调用
在自己独立的进程命名空间中,自身的进程号是1。
[root@localhost ns]# ./ns
[root@localhost ns]# ps -ef
UID PID PPID C STIME TTY TIME CMD
root 1 0 1 22:18 pts/1 00:00:00 /bin/bash
root 32 1 0 22:18 pts/1 00:00:00 ps -ef
[root@localhost ns]# echo $$
1
除了进程,还有独立的网络、挂载点等命名空间。
可以借助网桥让两个netns之间通信
先获取两个容器的进程号,然后执行下面脚本
p0=2016
p1=2024
ln -s /proc/$p0/ns/net /var/run/netns/$p0
ln -s /proc/$p1/ns/net /var/run/netns/$p1
brctl addbr br0
brctl stp br0 off
ip link set dev br0 up
ip link add e0 type veth peer name b0e0
brctl addif br0 b0e0
ip link set dev b0e0 up
ip link set e0 netns $p0
ip netns exec $p0 ifconfig e0 192.168.10.10 up
ip link add e1 type veth peer name b0e1
brctl addif br0 b0e1
ip link set dev b0e1 up
ip link set e1 netns $p1
ip netns exec $p1 ifconfig e1 192.168.10.11 up
如果是ehrl6,ip命令不支持“ip netns”选项,要到两个进程的容器里手工执行ifconfig
测试两个容器可以ping通
[root@localhost ~]# ip netns exec $p1 ping -c1 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.123 ms
--- 192.168.10.10 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.123/0.123/0.123/0.000 ms
[root@localhost ~]# ip netns exec $p0 ping -c1 192.168.10.11
PING 192.168.10.11 (192.168.10.11) 56(84) bytes of data.
64 bytes from 192.168.10.11: icmp_seq=1 ttl=64 time=0.130 ms
--- 192.168.10.11 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.130/0.130/0.130/0.000 ms
tcp链接也没问题
容器a
sh-4.2# gcc -o a a.c
sh-4.2# ./a 4444
listen ok.
容器b
sh-4.2# telnet 192.168.10.11 4444
Trying 192.168.10.11...
Connected to 192.168.10.11.
Escape character is '^]'.
hello
Connection closed by foreign host.
容器a
sh-4.2# ./a 4444
listen ok.
accepted 192.168.10.10