docker中创建虚拟网卡

docker本身对于host来说就是一个虚拟化的东西,要在其中创建一个虚拟网卡,还真要花费点心思。下面为大家分享一下配置虚拟网卡的方法。

如果在旧版本的docker中,我所发现的目前就一(或者两种  使用参数 --privileged=true 使能像mount 和 tunctl这样的命令)种方法:就是在host中创建一个虚拟的网卡,在创建容器的时候使用‘--net=host’ 参数,和host共同分享一个Network Namespace。

第一次安装docker时,使用Ubuntu 14.04版本官方软件源中已经自带的Docker包(docker.io)完成了Docker的安装,但是安装后的版本为1.0.1比较老,一些新的功能无法使用(比如,docker exec,--mac-address),本文记录升级到最新Docker的方法。

第一次的安装方法:(apt-get)

$ sudo apt-getinstall -y docker.io 
$ sudo ln -sf/usr/bin/docker.io /usr/local/bin/docker 
$ sudo sed -i`$acomplete -F _docker docker` /etc/bash_completion.d/docker.io 

 

安装的版本信息:

docker中创建虚拟网卡_第1张图片

在配置虚拟网卡之前,我们先来了解一下有关docker的四种网络模式:

Docker run 创建 Docker 容器时,可以用 --net 选项指定容器的网络模式,Docker 有以下 4 种网络模式:

  • host 模式,使用 --net=host 指定。
  • container 模式,使用     --net=container:NAMEorID 指定。
  • none 模式,使用 --net=none 指定。
  • bridge 模式,使用 --net=bridge 指定,默认设置。

host 模式

如果启动容器的时候使用 host 模式,那么这个容器将不会获得一个独立的 Network Namespace,而是和宿主机共用一个 Network Namespace。容器将不会虚拟出自己的网卡,配置自己的 IP 等,而是使用宿主机的 IP 和端口。

例如,我们在 10.10.101.105/24 的机器上用 host 模式启动一个含有 web 应用的 Docker 容器,监听 tcp 80 端口。当我们在容器中执行任何类似 ifconfig 命令查看网络环境时,看到的都是宿主机上的信息。而外界访问容器中的应用,则直接使用 10.10.101.105:80 即可,不用任何 NAT 转换,就如直接跑在宿主机中一样。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。

container 模式

这个模式指定新创建的容器和已经存在的一个容器共享一个 Network Namespace,而不是和宿主机共享。新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离的。两个容器的进程可以通过 lo 网卡设备通信。

none模式

这个模式和前两个不同。在这种模式下,Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker容器进行任何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。需要我们自己为 Docker 容器添加网卡、配置 IP 等。

bridge模式

docker中创建虚拟网卡_第2张图片

 

bridge 模式是 Docker 默认的网络设置,此模式会为每一个容器分配 Network Namespace、设置 IP 等,并将一个主机上的 Docker 容器连接到一个虚拟网桥上。当 Docker server 启动时,会在主机上创建一个名为 docker0 的虚拟网桥,此主机上启动的 Docker 容器会连接到这个虚拟网桥上。虚拟网桥的工作方式和物理交换机类似,这样主机上的所有容器就通过交换机连在了一个二层网络中。接下来就要为容器分配 IP 了,Docker 会从 RFC1918 所定义的私有 IP 网段中,选择一个和宿主机不同的IP地址和子网分配给docker0,连接到 docker0 的容器就从这个子网中选择一个未占用的 IP 使用。如一般 Docker 会使用 172.17.0.0/16 这个网段,并将 172.17.42.1/16 分配给 docker0 网桥(在主机上使用 ifconfig 命令是可以看到 docker0 的,可以认为它是网桥的管理接口,在宿主机上作为一块虚拟网卡使用)

 

 

docker本身对于host来说就是一个虚拟化的东西,要在其中创建一个虚拟网卡,还真要花费点心思。下面为大家分享一下配置虚拟网卡的方法。

如果在旧版本的docker中,我所发现的目前就一种方法:就是在host中创建一个虚拟的网卡,在创建容器的时候使用‘--net=host’ 参数,和host共同分享一个Network Namespace。

在host中创建一个虚拟网卡的方法如下:

$ sudo apt-get install uml-utilities
$ sudo tunctl -t eth1 
$ sudo ifconfig eth1 down
$ sudo ifconfig eth1 hw ether ee:ee:ee:ee:ee:ee
$ sudo ifconfig eth1 up


我们上面提到的  --privileged=true 参数的使用如下:

$ sudo docker run -it -v /home:/media --privileged=true ubuntu:14.04 /bin/bash

进入容器后就可以像在host中创建虚拟网卡一样了。如果在旧版本中不能使用的话,那就升级到最新版本吧。





如果是在新的版本中还有另外一种可行的方法:就是使用--mac-address=“” 参数。不过在这之前你必须对docker进行更新。

升级的方法:(从Docker官方源安装最新的版本,首先需要安装apt-transport-https,并添加Docker官方源)
 

$ sudo apt-getinstall apt-transport-https  

# Add the Dockerrepository key to your local keychain  
$ sudo apt-key adv--keyserver keyserver.ubuntu.com --recv-keys36A1D7869245C8950F966E92D8576A8BA88D21E9 

# Add the Dockerrepository to your apt sources list.
$ sudo sh -c"echo deb https://get.docker.io/ubuntu docker main >/etc/apt/sources.list.d/docker.list" 

# update yoursources list 
$ sudo apt-getupdate

# 之后通过下面命令来安装最新版本的docker:
$ sudo apt-getinstall -y lxc-docker 
$ sudo ln -sf/usr/bin/docker /usr/local/bin/docker

# 以后更新则: 
$ sudo apt-getupdate -y lxc-docker  
$ sudo ln -sf/usr/bin/docker /usr/local/bin/docker

升级后的版本信息:

docker中创建虚拟网卡_第3张图片

 

之后你就可以通过这个参数进行创建了。

docker中创建虚拟网卡_第4张图片

 


附加:两个容器间的点对点的连接

默认情况下,Docker会将所有容器连接到由 docker0 提供的虚拟子网中。

用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。

解决办法很简单:创建一对 peer 接口,分别放到两个容器中,配置成点到点链路类型即可。

首先启动 2 个容器:

$ sudo dockerrun -i -t --rm --net=none base /bin/bash
root@1f1f4c1f931a:/#
$ sudo dockerrun -i -t --rm --net=none base /bin/bash
root@12e343489d2f:/#

 

找到进程号,然后创建网络名字空间的跟踪文件。

$ sudo dockerinspect -f '{{.State.Pid}}' 1f1f4c1f931a
2989
$ sudo dockerinspect -f '{{.State.Pid}}' 12e343489d2f
3004
$ sudo mkdir -p/var/run/netns
$ sudo ln -s/proc/2989/ns/net /var/run/netns/2989
$ sudo ln -s/proc/3004/ns/net /var/run/netns/3004

 

创建一对 peer 接口,然后配置路由

$ sudo ip linkadd A type veth peer name B
$ sudo ip linkset A netns 2989
$ sudo ip netnsexec 2989 ip addr add 10.1.1.1/32 dev A
$ sudo ip netnsexec 2989 ip link set A up
$ sudo ip netnsexec 2989 ip route add 10.1.1.2/32 dev A
$ sudo ip linkset B netns 3004
$ sudo ip netnsexec 3004 ip addr add 10.1.1.2/32 dev B
$ sudo ip netnsexec 3004 ip link set B up
$ sudo ip netnsexec 3004 ip route add 10.1.1.1/32 dev B

 

现在这2 个容器就可以相互 ping 通,并成功建立连接。点到点链路不需要子网和子网掩码。

此外,也可以不指定 --net=none 来创建点到点链路。这样容器还可以通过原先的网络来通信。

利用类似的办法,可以创建一个只跟主机通信的容器。但是一般情况下,更推荐使用 --icc=false 来关闭容器之间的通信。

参考

[1] Docker技术入门与实践

[2] https://docs.docker.com/installation/ubuntulinux/

[3] How to manage Linux containers withDocker on Ubuntu

你可能感兴趣的:(ubuntu)