下面是简单介绍
linux 的强大的网络配置命令:ip [root@master ~]#ip Usage: ip [ OPTIONS ] OBJECT { COMMAND | help } ip [ -force ] -batch filename where OBJECT := { link | address | addrlabel | route | rule | neigh | ntable | tunnel | tuntap | maddress | mroute | mrule | monitor | xfrm | netns | l2tp | macsec | tcp_metrics | token } OPTIONS := { -V[ersion] | -s[tatistics] | -d[etails] | -r[esolve] | -h[uman-readable] | -iec | -f[amily] { inet | inet6 | ipx | dnet | bridge | link } | -4 | -6 | -I | -D | -B | -0 | -l[oops] { maximum-addr-flush-attempts } | -o[neline] | -t[imestamp] | -ts[hort] | -b[atch] [filename] | -rc[vbuf] [size] | -n[etns] name | -a[ll] } netns可以让一台机器上模拟多个网络设备,是网络虚拟化的重要组成,将不同类型的网络应用隔离。 一个net namespace有自己独立的路由表,iptables策略,设备管理。说来说去,它就是用来隔离的。比如将eth0加入了netns 1, 那么netns 2中的应用程序就找不到eth0了。netns 1中的iptables策略,不会去影响netns 2中的iptables策略。 netns的用法 [root@master ~]#ip netns help Usage: ip netns list #列出网络名称空间 ip netns add NAME #添加网络名称空间 ip netns set NAME NETNSID ip [-all] netns delete [NAME] ip netns identify [PID] ip netns pids NAME ip [-all] netns exec [NAME] cmd ... #在某个网络名称空间执行命令,单独的网络名称空间可以看做一个虚拟机 ip netns monitor ip netns list-id 先打开内核的网络转发功能。 [root@master ~]#vim /etc/sysctl.conf [root@master ~]#sysctl -p net.ipv4.ip_forward = 1 添加两个namespace [root@master ~]#ip netns add ns1 [root@master ~]#ip netns add ns2 [root@master ~]#ip netns list ns2 ns1 查看ns1的网络 [root@master ~]#ip netns exec ns1 ifconfig -a lo: flags=8<LOOPBACK> mtu 65536 loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 为ns1的回环接口添加一个ip地址 [root@master ~]#ip netns exec ns1 ifconfig lo 127.0.0.1 up [root@master ~]#ip netns exec ns1 ifconfig -a lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 此时的ns2并没有地址,因为他们是被隔离的 在网络名称空间上添加一对网卡,一个在ns1,一个在ns2. [root@master ~]#ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 00:50:56:34:bc:93 brd ff:ff:ff:ff:ff:ff 这里可以看做是创建了一条线,这条线有两个接口,叫做veth1.1和veth1.2,后面会用这条线连接两个网络名称空间 [root@master ~]#ip link add veth1.1 type veth peer name veth1.2 [root@master ~]#ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT qlen 1000 link/ether 00:50:56:34:bc:93 brd ff:ff:ff:ff:ff:ff 3: veth1.2@veth1.1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether 32:97:c0:a3:ed:1d brd ff:ff:ff:ff:ff:ff 4: veth1.1@veth1.2: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT qlen 1000 link/ether ba:68:96:8e:83:53 brd ff:ff:ff:ff:ff:ff 将一对网卡分别添加给2个名称空间。 [root@master ~]#ip link set veth1.1 netns ns1 [root@master ~]#ip link set veth1.2 netns ns2 [root@master ~]#ip netns exec ns1 ifconfig -a lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 veth1.1: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether ba:68:96:8e:83:53 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@master ~]#ip netns exec ns2 ifconfig -a lo: flags=8<LOOPBACK> mtu 65536 loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 veth1.2: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 32:97:c0:a3:ed:1d txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 给ns1的veth1.1改个名字eth0 [root@master ~]#ip netns exec ns1 ip link set veth1.1 name eth0 [root@master ~]#ip netns exec ns1 ifconfig -a eth0: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether ba:68:96:8e:83:53 txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 给ns2的veth1.2改个名字eth0 [root@master ~]#ip netns exec ns2 ip link set veth1.2 name eth0 [root@master ~]#ip netns exec ns2 ifconfig -a eth0: flags=4098<BROADCAST,MULTICAST> mtu 1500 ether 32:97:c0:a3:ed:1d txqueuelen 1000 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=8<LOOPBACK> mtu 65536 loop txqueuelen 0 (Local Loopback) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 0 bytes 0 (0.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 为两个网卡添加ip地址 [root@master ~]#ip netns exec ns1 ifconfig eth0 10.0.1.1/24 up [root@master ~]#ip netns exec ns2 ifconfig eth0 10.0.1.2/24 up [root@master ~]#ip netns exec ns1 ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.1.1 netmask 255.255.255.0 broadcast 10.0.1.255 inet6 fe80::b868:96ff:fe8e:8353 prefixlen 64 scopeid 0x20<link> ether ba:68:96:8e:83:53 txqueuelen 1000 (Ethernet) RX packets 8 bytes 648 (648.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@master ~]#ip netns exec ns2 ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.1.2 netmask 255.255.255.0 broadcast 10.0.1.255 inet6 fe80::3097:c0ff:fea3:ed1d prefixlen 64 scopeid 0x20<link> ether 32:97:c0:a3:ed:1d txqueuelen 1000 (Ethernet) RX packets 8 bytes 648 (648.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 两个网络名称空间的网络是通的 [root@master ~]#ip netns exec ns1 ping 10.0.1.2 PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data. 64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=0.108 ms 64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=0.085 ms ^C --- 10.0.1.2 ping statistics --- 2 packets transmitted, 2 received, 0% packet loss, time 1000ms rtt min/avg/max/mdev = 0.085/0.096/0.108/0.015 ms 到目前为止,看吧,此时就好像创建了两个虚拟机一样。两个网络是互相独立的。但是在一个网段内的时候,又可以互相联通。(图4)
下面是一个实际例子,用到了docker,理解了这个例子,docker里面的网络就基本掌握了
下面是一个单独的例子,是在一台centos7.2虚拟机上,并安装好docker服务
先打开内核的网络转发功能。 [root@master ~]#vim /etc/sysctl.conf [root@master ~]#sysctl -p net.ipv4.ip_forward = 1 下面是brctl命令,网桥相关的命令,需安装bridge-utils包 [root@master ~]#brctl Usage: brctl [commands] commands: addbr <bridge> add bridge delbr <bridge> delete bridge addif <bridge> <device> add interface to bridge delif <bridge> <device> delete interface from bridge hairpin <bridge> <port> {on|off} turn hairpin on/off setageing <bridge> <time> set ageing time setbridgeprio <bridge> <prio> set bridge priority setfd <bridge> <time> set bridge forward delay sethello <bridge> <time> set hello time setmaxage <bridge> <time> set max message age setpathcost <bridge> <port> <cost> set path cost setportprio <bridge> <port> <prio> set port priority show [ <bridge> ] show a list of bridges showmacs <bridge> show a list of mac addrs showstp <bridge> show bridge stp info stp <bridge> {on|off} turn stp on/off 添加一个网桥,并启动网桥 [root@master ~]#brctl addbr br-ex [root@master ~]#brctl show bridge name bridge id STP enabled interfaces br-ex 8000.000000000000 no [root@master ~]#ip link set br-ex up [root@master ~]#ifconfig br-ex: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet6 fe80::2460:4ff:fe9f:9ea1 prefixlen 64 scopeid 0x20<link> ether 26:60:04:9f:9e:a1 txqueuelen 0 (Ethernet) RX packets 0 bytes 0 (0.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@master ~]#cat ab.sh ip addr del 192.168.170.20/24 dev eth0 ip addr add 192.168.170.20/24 dev br-ex brctl addif br-ex eth0 必须放到脚本中执行,如果一条一条命令行执行,终端会断掉 [root@master ~]#bash ab.sh [root@master ~]#ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast master br-ex state UP qlen 1000 link/ether 00:50:56:34:bc:93 brd ff:ff:ff:ff:ff:ff inet6 fe80::250:56ff:fe34:bc93/64 scope link valid_lft forever preferred_lft forever 5: br-ex: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP link/ether 00:50:56:34:bc:93 brd ff:ff:ff:ff:ff:ff inet 192.168.170.20/24 scope global br-ex valid_lft forever preferred_lft forever inet6 fe80::250:56ff:fe34:bc93/64 scope link valid_lft forever preferred_lft forever [root@master ~]#brctl show bridge name bridge id STP enabled interfaces br-ex 8000.00505634bc93 no eth0 为路由器R1添加一对网卡并且启动。 [root@master ~]#ip netns add r1 [root@master ~]#ip link add rinr type veth peer name rins [root@master ~]#ip link set rinr up [root@master ~]#ip link set rins up 创建网桥,并将rins网卡添加到网桥上 [root@master ~]#brctl addbr br-in [root@master ~]#ip link set br-in up [root@master ~]#brctl addif br-in rins [root@master ~]#brctl show bridge name bridge id STP enabled interfaces br-ex 8000.00505634bc93 no eth0 br-in 8000.d28a979f4b40 no rins 将rinr加入r1 [root@master ~]#ip link set rinr netns r1 给rinr改个名字,并且启动 [root@master ~]#ip netns exec r1 ip link set rinr name eth0 [root@master ~]#ip netns exec r1 ip link set eth0 up [root@master ~]#ip netns exec r1 ifconfig eth0 10.0.1.254/24 up [root@master ~]#ip netns exec r1 ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.1.254 netmask 255.255.255.0 broadcast 10.0.1.255 inet6 fe80::2c94:d0ff:fe59:6028 prefixlen 64 scopeid 0x20<link> ether 2e:94:d0:59:60:28 txqueuelen 1000 (Ethernet) RX packets 16 bytes 1296 (1.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 16 bytes 1296 (1.2 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 两个虚拟机的网关都指向10.0.1.254 启动一个容器,不要关闭 [root@master ~]#docker run --rm --name docker2 --hostname=docker2 -it --net=none centos:latest /bin/bash 执行下面的脚本来安装docker2网络 [root@master ~]#cat docker2.sh #!/bin/bash pid=`docker inspect -f '{{.State.Pid}}' docker2` mkdir -p /var/run/netns ln -s /proc/$pid/ns/net /var/run/netns/$pid ip link add vetha type veth peer name vethb brctl addif br-in vethb ip link set vethb up ip link set vetha netns $pid ip netns exec $pid ip link set dev vetha name eth0 ip netns exec $pid ip link set eth0 up ip netns exec $pid ip addr add 10.0.1.2/24 dev eth0 ip netns exec $pid ip route add default via 10.0.1.254 启动另外一个容器,不要关闭 [root@master ~]#docker run --rm --name docker3 --hostname=docker3 -it --net=none centos:latest /bin/bash 执行下面的脚本来安装docker3网络 [root@master ~]#cat docker3.sh #!/bin/bash pid=`docker inspect -f '{{.State.Pid}}' docker3` mkdir -p /var/run/netns ln -s /proc/$pid/ns/net /var/run/netns/$pid ip link add vethc type veth peer name vethd brctl addif br-in vethd ip link set vethd up ip link set vethc netns $pid ip netns exec $pid ip link set dev vethc name eth0 ip netns exec $pid ip link set eth0 up ip netns exec $pid ip addr add 10.0.1.3/24 dev eth0 ip netns exec $pid ip route add default via 10.0.1.254 执行后如下 [root@master ~]#brctl show bridge name bridge id STP enabled interfaces br-ex 8000.00505634bc93 no eth0 br-in 8000.62e2dd6c5f69 no rins vethb vethd ============================================================== 目前来说整幅图的右半边完全好了。 开始左半边。 添加一对网卡,再把其中一个桥接 [root@master ~]#ip link add rexr type veth peer name rexs [root@master ~]#brctl addif br-ex rexs [root@master ~]#ip link set rexs up [root@master ~]#brctl show bridge name bridge id STP enabled interfaces br-ex 8000.00505634bc93 no eth0 rexs br-in 8000.62e2dd6c5f69 no rins vethb vethd 将另一个网卡添加到路由器的另一边,且给个另一个网络的地址 [root@master ~]#ip link set rexr netns r1 [root@master ~]#ip netns exec r1 ip link set rexr name eth1 [root@master ~]#ip netns exec r1 ifconfig eth1 192.168.170.40/24 up [root@master ~]#ip netns exec r1 ifconfig eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.0.1.254 netmask 255.255.255.0 broadcast 10.0.1.255 inet6 fe80::78bc:62ff:fed7:2626 prefixlen 64 scopeid 0x20<link> ether 7a:bc:62:d7:26:26 txqueuelen 1000 (Ethernet) RX packets 13 bytes 858 (858.0 B) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 27 bytes 2150 (2.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 192.168.170.30 netmask 255.255.255.0 broadcast 192.168.170.255 inet6 fe80::6cd0:8ff:fe47:64ff prefixlen 64 scopeid 0x20<link> ether 6e:d0:08:47:64:ff txqueuelen 1000 (Ethernet) RX packets 19 bytes 1308 (1.2 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 8 bytes 648 (648.0 B) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@master ~]#ip netns exec r1 iptables -t nat -A POSTROUTING -s 10.0.1.0/24 -j SNAT --to-source 192.168.170.40 [root@master ~]#ip netns exec r1 iptables -t nat -nvL Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain INPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain OUTPUT (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination Chain POSTROUTING (policy ACCEPT 0 packets, 0 bytes) pkts bytes target prot opt in out source destination 0 0 SNAT all -- * * 10.0.1.0/24 !10.0.1.0/24 to:192.168.170.30 物理机添加网关 [root@master ~]#route add -net 0.0.0.0 gw 192.168.170.2 [root@master ~]#ip netns exec r1 route add default gw 192.168.170.2 到这里,两个docker容器就可以正常访问外部网络了,如果需要外部网络访问内部网络,需要做dnat,原理类似 下面的命令来获取容器对应的pid [root@master ~]#docker inspect -f '{{.State.Pid}}' docker3 2649 [root@master ~]#docker inspect -f '{{.State.Pid}}' docker2 2598
文件:
参考文档:
http://blog.csdn.net/ghost_leader/article/details/71075551
http://blog.csdn.net/ghost_leader/article/details/68174126
–
–
–
评论前必须登录!
注册