docker配置网卡使宿主机和容器ip处于同一网段

首先讲一下 docker的网络模式:
我们使用docker run创建容器时,可以使用--net选项指定容器的网络模式,docker一共有4中网络模式:

docker配置网卡使宿主机和容器ip处于同一网段_第1张图片

host模式    - -net=host    host模式,容器不会获得一个独立的network namespace,而是与宿主机共用一个network namespace,容器不会虚拟出自己的网卡、配置自己的ip等,而是使用宿主机的ip和端口。    当网络不应与Docker主机隔离,但又希望容器的其他方面隔离时,主机网络是最佳选择。


container模式    - -net=container    container模式,指定新创建的容器和已经存在的一个容器共享一个network namespace,而不是和宿主机共享,新创建的容器不会创建自己的网卡、配置自己的ip,而是和指定的容器共享ip、端口等。两个容器除网络方面相同外,其他的如文件系统、进程列表等还是隔离的。 

   
none模式    - -net=none    none模式,容器拥有自己的network namespace,但是并未对容器进行任何网络配置,需要手工为容器添加网卡、配置ip等。可以使用pipework工具为容器指定ip等信息。    第三方网络插件使您可以将docker与专用网络集成。


bridge模式    - -net=bridge    bridge模式是容器默认的网络模式,该模式会为每个容器分配独立的network namespace,设置ip、路由等信息,默认会将容器连接到一个虚拟网桥交换机docker0上,容器之间组成一个局域网,可以相互访问。    当您需要多个容器在同一docker主机上进行通信时,最好使用用户定义的网桥网络。用户定义的网桥网络的容器会自动将所有端口彼此公开,而不会向外界公开任何端口。默认网桥网络上运行相同的应用程序堆栈,则需要使用-p或–publish 标志分别打开Web端口和数据库端口。这意味着docker主机需要通过其他方式阻止对数据库端口的访问。


macvlan模式        Macvlan网络允许您将MAC地址分配给容器,使其在网络上显示为物理设备。Docker守护程序通过其MAC地址将流量路由到容器。    从VM设置迁移或需要容器看起来像网络上的物理主机(每个主机都有唯一的MAC地址)时,Macvlan网络是最好的。


overlay模式    覆盖网络    覆盖网络将多个docker守护程序连接在一起,并使群集服务能够相互通信。还可以使用覆盖网络来促进群集服务和独立容器之间或不同Docker守护程序上的两个独立容器之间的通信。    当您需要在不同Docker主机上运行的容器进行通信时,或者当多个应用程序使用集群服务一起工作时,覆盖网络是最好的。
 

https://docs.docker.com/network/

https://blog.csdn.net/csdn_wangyixiao/article/details/108975947   ssh  链接

docker配置网卡使宿主机和容器ip处于同一网段_第2张图片

https://www.infoq.cn/article/docker-source-code-analysis-part1/  docker  源码解读

查看my-net网桥网络。

docker network inspect my-net

docker exec 命令来了解容器如何查看自己的网络接口

$ docker exec my-second-macvlan-alpine ip addr show eth0
docker exec my-second-macvlan-alpine ip route

停止容器(因为 --rm 标志,Docker 会删除容器),删除网络。

$ docker container stop my-second-macvlan-alpin

$ docker network rm my-8021q-macvlan-net

以下是几种分配IP的方式:

一.  maclvan

https://docs.docker.com/network/macvlan/

1、创建自定义网络

docker network create -d macvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o parent=eth0 mynet

2、创建固定IP容器

docker run -itd --name test --net mynet --ip 192.168.1.101 centos /bin/bash

3、macvlan 是 Linux kernel 支持的新特性,支持的版本有 v3.9-3.19 和 4.0+,比较稳定的版本推荐 4.0+。它一般是以内核模块的形式存在,我们可以通过以下方法判断当前系统是否支持:
modprobe macvlan
lsmod | grep macvlan
 

二、pipework  


本文讲的是Docker使用自定义网桥docker,并且自定义容器的ip地址。 Docker 服务默认会创建一个 docker0 网桥,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。 用户也可以指定网桥来连接各个容器。

 这种方法docker官网是不推荐的,记录一下这个方法。但是这个方法可以使宿主机和容器在同一个网段通信。

1.Linux桥接设置
设置桥接的思路:
1. 先建立一个br0的虚拟交换机
2. 把物理端口加入到br0设备中
3. 修改br0 和 物理接口的配置文件--保证持久化
一.准备工作

1.下载brctl git
[root@tiger ~]# yum install -y bridge-utils git.
 
2.下载pipework
[root@tiger ~]# git clone https://github.com/jpetazzo/pipework
 
3.拷贝命令到bin下
[root@tiger ~]# cp ~/pipework/pipework /usr/local/bin/


二. 建立虚拟交换机,并把物理接口加入

1.创建网桥
[root@tiger ~]# brctl addbr br0
 
2.把ens33加入到br0这个网卡中
[root@tiger ~]# brctl addif br0 ens33
 
3.有关stp协议的
[root@tiger ~]# brctl stp br0 on


三. 修改物理网卡和br0的网卡保证持久化

[root@tiger network-scripts]# pwd
/etc/sysconfig/network-scripts
[root@tiger network-scripts]# cp ifcfg-ens33 ifcfg-br0
TYPE=Bridge
BOOTPROTO=no
NAME=br0
DEVICE=br0
ONBOOT=yes
IPADDR=192.168.3.3
PREFIX=24
GATEWAY=192.168.3.1
DNS1=223.5.5.5
DNS2=8.8.8.8
 
ens33的网卡
TYPE=Ethernet
PROXY_METHOD=none
BROWSER_ONLY=no
BOOTPROTO=no
DEFROUTE=yes
IPV4_FAILURE_FATAL=no
NAME=em1
UUID=06c95b32-c733-2611-a7aa-4d0ec8bd07f6
DEVICE=em1
ONBOOT=yes
#IPADDR=192.168.3.3
#PREFIX=24
#GATEWAY=192.168.3.1
#DNS1=223.5.5.5
#DNS2=8.8.8.8
BRIDGE=br0
 
重启下网卡
[root@tiger network-scripts]# systemctl restart network


四.为容器配置ip

1.开启一个新容器
[root@tiger ~]# docker run -d --privileged --net none --name tiger 5182e46232bf /sbin/init
 
2.pipework配置网络
[root@tiger ~]# pipework br0 -i ens33 15b022498573 192.168.3.11/[email protected]
 
3.进入容器使用,安装ssh便可以本地使用xshell连接容器
[root@tiger ~]# docker exec -it tiger bash 

本文利用到 ipvlan/macvlan 和 ip route 的一些基础功能,基本上只要认真阅读,想实现 Docker 网络和物理网络互联互通是没啥难度的。通过本文,你可以为每一个 Container 分配一个其专属的物理网络 IP,以便其和物理网络的其它服务或客户端轻松通讯,而无需顾虑宿主机端口 - Port 不够映射的问题。

  另外,此方案在云主机上实施时,需要云服务厂商的网络设备支持(目前大部分是不支持的)。

  简要说明一下原理:Docker 设计的时候就考虑了跨主机通讯和宿主机网络隔离的安全问题,在 VLAN 模式下只允许同 VLAN 的 MACVLAN/IPVLAN 子接口内部通讯,同时对来自宿主通过父接口到子接口的通讯进行了过滤(阻断),以确保安全。因此可利用子接口可相互通讯的原理,在宿主多配置一个子接口,并多分配一个 IP 地址,同时在路由表配置正确的情况下,容器就能和物理网络完全互通了。

0x00:
先决条件
1、确保宿主机 Linux Kernel 内核版本 ≥ 4.20 (此版本是 Docker Network 对 IPVLAN 模式稳定支持的最低限度版本)
2、一定的 Linux Shell 命令行及 IP Router Config 配置基础
3、宿主需要安装iproute2依赖库
4、能看得懂本文

0x01:
创建一个 IPVLAN/MACVLAM 类型的 Docker Network (根据需要任选其一即可)

# MACVLAN
docker network create \
    --driver=macvlan            `# 指定网络驱动类型为:macvlan` \
    --subnet=10.1.0.0/23        `# 接口所对应的物理网络网域(网段)` \
    --ip-range=10.1.0.0/24      `# 划分一段网段用于给容器分配 IP 地址使用(可选)` \
    --gateway=10.1.1.254        `# 物理网络的网关` \
    --opt parent=eth0           `# 绑定子接口到物理网卡(父接口)` \
    pub                         `# 给此 Docker Network 指派一个名称`


# IPVLAN
docker network create \
    --driver=ipvlan             `# 指定网络驱动类型为:ipvlan ` \
    --subnet=10.1.0.0/23        `# 接口所对应的物理网络网域(网段)` \
    --ip-range=10.1.0.0/24      `# 划分一段网段用于给容器分配 IP 地址使用(可选)` \
    --gateway=10.1.1.254        `# 物理网络的网关` \
    --opt parent=eth0           `# 绑定子接口到物理网卡(父接口)` \
    pub                         `# 给此 Docker Network 指派一个名称`
# 新建关于 Docker 容器的专用路由表
echo "100     docker" >> /etc/iproute2/rt_tables
ip route flush table docker
 

 
0x02:
配置 IPVLAN/MACVLAN 静态路由表(根据需求选择对应的模式)
(步骤 0x02/0x03 二选一即可,使用 0x02 的方法则不需要再继续配置 0x03 的方法,反之亦然)

创建用于配置宿主机关于物理网络及 Docker 网络的静态路由表的脚本(用于开机自启时执行)
docker-network-boot-config.sh

# MACVLAN
ip link add mac0 link eth0 type macvlan mode bridge         # 根据需求创建一个新的 MACVLAN 子接口
ip addr add 10.1.0.1 dev mac0                               # 为子接口手动分配一个静态 IP 地址
ip link set mac0 up                                         # 打开子接口
ip link set eth0 promisc on                                 # 启用父接口网络混杂支持
ip link set mac0 promisc on                                 # 启用子接口网络混杂支持
ip route add default via 10.1.0.1 table docker              # 配置到容器的默认路由表
ip route add 10.1.0.0/23 dev mac0 src 10.1.0.1 metric 10    # 为子接口配置对应的静态路由表
ip rule add from all to 10.1.0.0/24 table docker            # 配置本地回环到容器的路由规则


# IPVLAN
ip link add ipvl link eth0 type ipvlan                      # 根据需求创建一个新的 IPVLAN 子接口
ip addr add 10.1.0.1 dev ipvl                               # 为子接口手动分配一个静态 IP 地址
ip link set ipvl up                                         # 打开子接口
ip link set eth0 promisc on                                 # 启用父接口网络混杂支持
ip link set ipvl promisc on                                 # 启用子接口网络混杂支持
ip route add default via 10.1.0.1 table docker              # 配置到容器的默认路由表
ip route add 10.1.0.0/23 dev ipvl src 10.1.0.1 metric 10    # 为子接口配置对应的静态路由表
ip rule add from all to 10.1.0.0/24 table docker            # 配置本地回环到容器的路由规则

将创建的 docker-network-boot-config.sh 脚本添加到 Linux 开机自启里(以便每次开机能自动配置)
然后重启 Linux 或执行下docker-network-boot-config.sh(记得 chmod +x)

0x03:
另一种更优雅的子接口配置方式,直接在网卡配置文件里设置(推荐

nano /etc/network/interfaces
auto lo
iface lo inet loopback


auto eth0
iface eth0 inet static
        address 10.1.1.0
        gateway 10.1.1.254
        netmask 255.255.254.0
        dns-nameservers 10.1.0.53
        up ip link set $IFACE promisc on


auto mac0
iface mac0 inet static
        address 10.1.0.1
        gayway 10.1.1.254
        netmask 255.255.254.0
        dns-nameservers 10.1.0.53
        pre-up ip link add mac0 link eth0 type macvlan mode bridge
        up ip link set $IFACE promisc on
        up ip route add default via 10.1.0.1 table docker
        up ip rule add from all to 10.1.0.0/24 table docker
        post-down ip link del mac0 link eth0 type macvlan mode bridge


auto ipvl
iface ipvl inet static
        address 10.1.0.1
        gayway 10.1.1.254
        netmask 255.255.254.0
        dns-nameservers 10.1.0.53
        pre-up ip link add ipvl link eth0 type ipvl
        up ip link set $IFACE promisc on
        up ip route add default via 10.1.0.1 table docker
        up ip rule add from all to 10.1.0.0/24 table docker
        post-down ip link del ipvl link eth0 type ipvl

 
 
 
资料参考:
https://docs.docker.com/network/macvlan/
https://docs.docker.com/engine/reference/commandline/network_create/

方法4

依赖包
net-tools iproute2 bridge-utils git curl

权限
需要在 root 下执行

脚本
dnet.sh j脚本内容

#like br0 要创建的桥接设备名
BRNAME=$1
#like eth0 要矫健的网络接口名
IFNAME=$2
#192.168.1.2/24 当前主机IP
LOCALIP=$3
#192.168.1.1 当前主机网关
GWIP=$4
# 注意如果此脚本出错会导致主机离线,无法进行网络访问,请做好应急预案
yum install -y net-tools iproute2  bridge-utils git
git clone https://github.com/jpetazzo/pipework
cp pipework/pipework /usr/local/bin/
(ip link add dev "$BRNAME" type bridge > /dev/null 2>&1) || (brctl addbr "$BRNAME")
ip link set "$BRNAME" up
ip addr add $LOCALIP dev $BRNAME; \
ip addr del $LOCALIP dev $IFNAME; \
brctl addif $BRNAME $IFNAME; \
ip route del default; \
ip route add default via $GWIP dev $BRNAME


实例
 

sh dnet.sh br0 eth0 192.168.1.2/24 192.168.1.1


创建一个测试用容器
 

docker run -itd --name testweb1 nginx


为创建好的容器分配主机同网段IP

pipework br0 testweb1 192.168.1.3/[email protected]


验证是否成功
在任意同网段主机内执行都可成功访问

ping 192.168.1.3
curl http://192.168.1.3


原文链接:https://blog.csdn.net/zhangjunli/article/details/103894719

你可能感兴趣的:(docker)