使用pipework将Docker容器配置到本地网络环境中

by LauCyun Nov 10,2016 11:35:18 17,607 views

在使用Docker的过程中,有时候我们会有将Docker容器配置到和主机同一网段的需求。要实现这个需求,我们只要将Docker容器和主机的网卡桥接起来,再给Docker容器配上IP就可以了。

下面我们就使用pipework工具来实现这一需求。

实验环境:

  • 系统版本:Ubuntu 16.04
                      或
                      CentOS 6.8
  • Docker版本:17.05.0-ce, build 89658be

1 安装pipework

root@ubuntu:~# git clone https://github.com/jpetazzo/pipework
root@ubuntu:~# sudo cp pipework/pipework /usr/local/bin/
root@ubuntu:~# chmod +x /usr/local/bin/pipework

2 使用pipework

首先看一下,当前我的主机的IP地址为192.168.0.200,网关为192.168.0.1,使用的是eth0这块网卡。假定我需要给Docker容器的分配的地址为192.168.0.210

首先创建一个容器:

root@ubuntu:~# docker run -d -it --name test centos:6.8 /bin/bash
6ee257a1045d1c9a15ff602fe575ab4c767e6b9b054ca85b0b531bb91fe983ae

此时,查看容器的IP地址信息,其中有eth0lo,其中eth0的IP地址为172.17.0.4,如下:

root@ubuntu:~# docker exec test ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:04
          inet addr:172.17.0.4  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:738 (738.0 b)  TX bytes:0 (0.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

pipework首先会检查主机是否存在br0网桥,若不存在,就自己创建一个。这里以"br"开头,所以创建的是Linux bridge。如果以"ovs"开头,就会创建OpenVswitch网桥。

网桥创建过程请参考:

查看一下网桥信息:

root@ubuntu:~# brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.000d4826948c       no              enp3s0

下面配置容器test的网络,并连接到网桥br0上,其中@后面是网关地址:

root@ubuntu:~# pipework br0 test 192.168.0.210/24@192.168.0.1

另外,如果主机环境中有DHCP服务,也可以通过DHCP的方式获取IP:

[root@localhost ~]# pipework br0 test dhcp

此时查看容器的IP地址信息,发现新增加了一个网卡eth1,分配的IP地址是192.168.0.210,如下:

root@ubuntu:~# docker exec test ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:AC:11:00:04
          inet addr:172.17.0.4  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:7 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:738 (738.0 b)  TX bytes:0 (0.0 b)

eth1      Link encap:Ethernet  HWaddr 82:6D:DD:1C:EC:34
          inet addr:192.168.0.210  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:14 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:1158 (1.1 KiB)  TX bytes:42 (42.0 b)

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          UP LOOPBACK RUNNING  MTU:65536  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1
          RX bytes:0 (0.0 b)  TX bytes:0 (0.0 b)

现在,另开一个终端,可以通过ping 192.168.0.210来测试容器网络。或者从其它物理主机上ping这个容器地址。

$ ping 192.168.0.210

Pinging 192.168.0.210 with 32 bytes of data:
Reply from 192.168.0.210: bytes=32 time=1664ms TTL=64
Reply from 192.168.0.210: bytes=32 time=2ms TTL=64
Reply from 192.168.0.210: bytes=32 time=2ms TTL=64
Reply from 192.168.0.210: bytes=32 time=2ms TTL=64

Ping statistics for 192.168.0.210:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 2ms, Maximum = 1664ms, Average = 417ms

OK,成功~~

3 常见错误

3.1 Warning: arping not found; interface may not be immediately reachable

如果出现Warning: arping not found; interface may not be immediately reachable错误的话,提示arping命令没发现,可以通过apt-get install arping来安装即可。

3.2 Object "netns" is unknown, try "ip help"

使用ip netns会出现类似这样的报错:

Object "netns" is unknown, try "ip help".

pipework要用到网络namespace(可以理解为进程级别的网络设备),关于namespace介绍可以查阅其它相关质料。CentOS6.5以前,内核不支持网络namespace,需要升级内核和iproute。CentOS6.5以后内核已支持网络namespace,只需要升级iproute即可。

[root@localhost ~]# cat /etc/redhat-release
CentOS release 6.9 (Final)
方法一:升级iproute
# 安装yum源
[root@localhost ~]# yum install -y http://rdo.fedorapeople.org/rdo-release.rpm
# 
[root@localhost ~]# cat /etc/yum.repos.d/rdo-release.repo
[openstack-kilo]
name=OpenStack Kilo Repository
baseurl=https://repos.fedorapeople.org/repos/openstack/EOL/openstack-icehouse/epel-6/
skip_if_unavailable=0
enabled=1
gpgcheck=0
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-kilo
# 安装指定yum源的iproute包
[root@localhost ~]# yum install -y iproute
方法二:升级内核

通过yum快速升级CentOS 6.x 内核到3.1.0,依次执行如下命令,如果提示地址无法连接,可以把地址复制到浏览器地址栏下载,然后传到服务器上执行命令rpm -ivh下载的rpm来文件完成安装。

[root@localhost ~]# rpm -ivh http://www.elrepo.org/elrepo-release-6-5.el6.elrepo.noarch.rpm
[root@localhost ~]# yum --enablerepo=elrepo-kernel install kernel-lt -y
  1. 在grub.conf中确定装好的内核在哪个位置:
    [root@localhost ~]# vim /etc/grub.conf
    default=0
  2. 重启系统,查看内核信息
    [root@localhost ~]# uname -r3.10.94-1.el6.elrepo.x86_64

    更新iproute软件包,同理如果无法连接,则把地址复制到浏览器地址栏手动下载然后安装。

    [root@localhost ~]# yum install -y http://rdo.fedorapeople.org/rdo-release.rpm
  3. 修改地址
    [root@localhost ~]# vim /etc/yum.repos.d/rdo-release.repo
    [openstack-kilo]
    name=OpenStack Kilo Repository
    baseurl=https://repos.fedorapeople.org/repos/openstack/EOL/openstack-icehouse/epel-6/
    skip_if_unavailable=0
    enabled=1
    gpgcheck=0
    gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-RDO-kilo
  4. 升级iprpute软件包

    [root@localhost ~]# yum upgrade iproute
    [root@localhost ~]# rpm -qa|grep iproute
    iproute-2.6.32-130.el6ost.netns.2.x86_64

4 参考

5 修改日志

  • Nov 10,2016: 编撰,初稿;
  • Dec 07,2017: 添加缺少arping错误及解决方案。
  • Dec 30,2017: 添加Object "netns" is unknown, try "ip help".错误及解决方案。

Tags