首先讲一下 docker的网络模式:
我们使用docker run创建容器时,可以使用--net选项指定容器的网络模式,docker一共有4中网络模式:
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 链接
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
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
本文讲的是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/
依赖包
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