CentOS7下docker用原生方法使用宿主机所在网络

背景

docker以前的版本不支持直接配置宿主机所在网段ip并跟其直接互通的功能,当然,也可以实现这个功能,只是有点绕,而且还有一些第三方工具例如pipework把这些琐碎的过程封装起来,让步骤简化。但是,现在不需要了,现在1.12docker已经直接支持了直接使用宿主机所在网段资源。

具体步骤

环境准备

  • 宿主机一台
    • CentOS 7.x
    • eth0 配 ip 地址:10.0.0.2/24
    • 缺省网关:10.0.0.1

在宿主机上安装软件,执行:

1
2
3
4
5
6
7
8
9
10
11
12
13
yum -y install kernel; # 更新到最新的kernel版本
yum -y update; # 更新到最新的CentOS7.x
tee /etc/yum.repos.d/docker.repo <<-'EOF'
[dockerrepo]name=Docker Repository
baseurl=https://yum.dockerproject.org/repo/main/centos/7/
enabled=1
gpgcheck=1
gpgkey=https://yum.dockerproject.org/gpg
EOF

yum -y install docker-engine; # 安装docker最新版
systemctl start docker.service; # 启动docker
systemctl enable docker.service; # 使docker服务随着机器启动而启动

网络创建

1
2
3
4
docker network create -d macvlan \
--subnet=10.0.0.0/24 \
--gateway=10.0.0.1 \
-o parent=eth0 MACNET;

注意:

  1. 这里的macvlan是kernel的模块名,docker 1.12 开始支持其作为驱动来创建网络
  2. 这里的10.0.0.0/24是宿主机所在网络的网段
  3. 10.0.0.1是网关
  4. eth0是宿主机接入10.0.0.0/24的网络设备

创建实例

1
2
3
4
docker run --net=MACNET \
--ip=10.0.0.11 \
-it \
--rm alpine /bin/sh;

注意:

  • 10.0.0.11是新docker实例的ip地址

简单测试

步骤

在刚起来的这个 docker 实例里执行测试:

1
ping -c 5 10.0.0.1;

显示能通,证明能通网关。

1
ping -c 5 10.0.0.2;

显示不能通,证明能通宿主机在同一网段的 ip。

在宿主机外同网段其他机器上执行测试:

1
ping -c 5 10.0.0.11;

ping docker 实例能通。

结论

  • 这样配出来的 docker 实例跟现有网络是完全联通的
  • 但是:跟宿主机在现有网络的 ip 地址不通

其他维护命令

1
2
docker network ls; # 显示现有network
docker network rm MACVLAN; # 删除掉前面建立的MACVLAN的网络

FAQ

Q: 为嘛这里的docker不支持ipvlan的驱动呢?
A: 因为官方资料显示kernel 4.2以上才支持ipvlan(虽然准确讲4.2之前也有支持,但是有bug),而从3.9就开始支持macvlan了。

Q: 为嘛RedHat这么喜欢把高版本的功能backport到老版本的操行,却没有把ipvlan的支持backport到3.10(CentOS 7.x的kernel版本)呢?
A: 。。。zzzzzzZZZZZZZZZ