目的
由于日常开发需要多个开发环境的获取单独的局域网ip,docker默认的网卡配置无法满足在局域网内互通的需求,偶然发现docker带有macvlan的功能,以下是配置的一些信息记录
下文仅对网络配置有较为详细的介绍,docker的使用不做过多的说明,可以参考网上其他的一些文章
虚拟机环境配置
1.由于依赖于具体的局域网环境,所以要求虚拟机有一张网卡是桥接模式,对应的Linux系统网卡为enp0s9,下面是常用的两种虚拟机配置方式
- VirtualBox
- VMware
2.检查Linux系统网卡能够获取到路由器分配的ip,确保虚拟机可以正常获取到路由器的分配的ip
3.设置Linux系统网卡开启混杂模式
在终端输入sudo ip link set enp0s9 promisc on
开启网卡接口enp0s9
的混杂模式,enp0s9
根据实际配置网卡填写
在终端输入ifconfig
查看是否开启混杂模式,显示有PROMISC
即为混杂模式已开启
上面用到的相关命令
#使用ip命令配置
sudo ip link set enp0s9 promisc on #设置混杂模式
sudo ip link set enp0s9 promisc off #取消混杂模式
#没有安装ip命令的用ifconfig也行
sudo ifconfig enp0s9 promisc #设置混杂模式
sudo ifconfig enp0s9 -promisc #取消混杂模式
#配置到启动脚本里
echo -e "auto enp0s9 \niface enp0s9 inet manual \n\tup ifconfig \$IFACE 0.0.0.0 up \n\tup ip link set \$IFACE promisc on" | sudo tee -a /etc/network/interfaces
Docker运行环境安装
1.在linux下安装docker engine
#ubuntu 18.04以上
curl -sSL https://get.daocloud.io/docker | sh
# ubuntu 16.04
sudo apt install docker.io
#将当前用户添加至docker用户组 后面就是可以省去再docker命令前加sudo
sudo groupadd docker #添加docker用户组
sudo gpasswd -a $USER docker #将当前用户添加至docker用户组
newgrp docker #更新docker用户组
2.测试安装是否正确
docker run -it --rm hello-world
Docker穿透网络配置
1.创建macvlan网络,创建过一次就行
网卡名为macvlan-net-1 ,将subnet、gateway和parent值修改为在自己环境中有意义的值
#创建网络
docker network create -d macvlan \
--gateway=192.168.188.1 \
--subnet=192.168.188.0/24 \
-o parent=enp0s9\
macvlan-net-1
#查看网卡
docker network ls
#删除网卡
docker network rm macvlan-net-1
2.测试穿透网络配置是否生效
# 创建一个测试容器
docker run --rm -dit \
--network macvlan-net-1 \
--name my-macvlan-alpine \
--ip=192.168.188.11 \
alpine:latest \
ash
# 测试ip获取是否正常,也可以在宿主机去ping容器的ip
docker exec my-macvlan-alpine ip addr show eth0
docker exec my-macvlan-alpine ip route
# 测试完成之后,删除容器(因为启动的时候时候添加了--rm参数,只需要停止容器就行了)
docker container stop my-macvlan-alpine
一键配置脚本
#!/bin/bash
#使用方式 env_set.sh enp0s9(虚拟机的网卡名) 192.168.188.1(网段)
SHELL_ROOT_DIR=$(dirname $(readlink -f "$0"))
SHELL_FILE_NAME=$(readlink -f "$0")
# 网络参数初始化配置文件
net_cfg_file=/etc/network/interfaces
# docker共享目录
docker_share_dir=~/docker_share
# macvlan 网络名
macvlan_name=macvlan-net-1
# 参数检查
if [ -z "$1" ];then
echo "Please input network interface"
echo "Usage:"
echo "$SHELL_FILE_NAME enp0s9 192.168.188.1"
exit 1
elif [ -z "$(ifconfig -a | grep $1)" ];then
echo "Please check input network interface name"
echo "Usage:"
echo "$SHELL_FILE_NAME enp0s9 192.168.188.1"
exit 1
else
net_interface_name=$1
echo "net_interface_name:$net_interface_name"
fi
# 检查路由器ip
if [ -z "$2" ];then
echo "Please input route ip"
echo "Usage:"
echo "$SHELL_FILE_NAME enp0s9 192.168.188.1"
exit 1
else
#因为只PING一次,丢包数为0则表示成功,否则失败
p=`ping -c 1 $2|grep loss|awk '{print $6}'|awk -F "%" '{print $1}'`
if [ "0" != "$p" ];then
echo "Please check input vaild route ip, or try again"
echo "Usage:"
echo "$SHELL_FILE_NAME enp0s9 192.168.188.1"
exit 1
else
# 检查是否为xxx.xxx.xxx.1的地址
if [ ${2: 0-2 :2} != ".1" ];then
echo "Please check input vaild route ip, or try again"
echo "Usage:"
echo "$SHELL_FILE_NAME enp0s9 192.168.188.1"
exit 1
else
route_ip=$2
subnet="${2%.*}.0/24"
echo "route_ip:$route_ip"
echo "subnet:$subnet"
fi
fi
fi
# 配置混杂模式
sudo ip link set $net_interface_name promisc on
# 配置启动时的混杂模式
if [ ! -f $net_cfg_file ];then
# 网卡配置文件不存在,只能手动启动网卡混杂模式
echo "$net_cfg_file not exists, Please set promisc on manual"
elif [ ! -z "$(cat $net_cfg_file | grep $net_interface_name)" ];then
# 网卡自启动混杂模式已经配置过了
echo "auto promisc on exists, skip"
else
echo -e "auto $net_interface_name \niface $net_interface_name inet manual \n\tup ifconfig \$IFACE 0.0.0.0 up \n\tup ip link set \$IFACE promisc on" | sudo tee -a $net_cfg_file
fi
#创建共享目录,后续给多容器共享目录使用
if [ ! -d $docker_share_dir ];then
mkdir $docker_share_dir
echo "create docker_share_dir:$docker_share_dir"
fi
#检查ubuntu版本,并安装docker
type docker >> /dev/null
if [ $? ];then
echo 'exists docker cmd, skip install'
elif [ -z "$(cat /etc/issue | grep "Ubuntu")" ];then
# 不是ubuntu 需要自己手动安装 docker
echo "host linux version is not Ubuntu, Please install Docker yourself!"
echo "you can try this cmd or other"
echo "curl -sSL https://get.daocloud.io/docker | sh"
exit 1
else
# 检测ubunt版本
echo 'no exists docker cmd, start install docker'
if [ ! -z "$(cat /etc/issue | grep "Ubuntu 14")" ];then
echo "host linux version is Ubuntu 14.x not support, please update version"\
exit 1
elif [ ! -z "$(cat /etc/issue | grep "Ubuntu 16")" ];then
echo "host linux version is Ubuntu 16.x"
use_apt=1
else
echo "host linux version is higher then Ubuntu 16.x"
use_apt=0
fi
while true; do
read -p "Your version is right?(y/n)" yn
case $yn in
[Yy]* ) break;;
[Nn]* ) echo "Break install";exit;;
* ) echo "Please answer yes or no.";;
esac
done
# 是否有curl命令
type curl >> /dev/null
if [ ! $? ];then
echo "install curl"
sudo apt -y install curl
# 检测安装是否成功
type curl >> /dev/null
if [ ! $? ];then
echo "install curl failed!"
exit 1
fi
fi
#安装docker
if [ $use_apt ];then
sudo apt -y install docker
else
curl -sSL https://get.daocloud.io/docker | sh
fi
# 检测安装是否成功
type docker
if [ ! $? ];then
echo "install docker failed!"
fi
echo "success install docker"
fi
#创建macvlan网络
if [ -z "$(sudo docker network ls | grep $macvlan_name)" ];then
echo "create macvlan: $macvlan_name"
sudo docker network create -d macvlan \
--gateway=$route_ip \
--subnet=$subnet \
-o parent=$net_interface_name\
$macvlan_name
else
#已经存在了,不需要重新创建
echo "macvlan: $macvlan_name exists, not create angin"
fi
echo "docker env set success!"
exit 0
配置参考链接 : CSDN macvlan官方文档