0
点赞
收藏
分享

微信扫一扫

Docker容器获取局域网ip(使用macvlan)

心如止水_c736 2022-04-14 阅读 85
dockerip

目的

由于日常开发需要多个开发环境的获取单独的局域网ip,docker默认的网卡配置无法满足在局域网内互通的需求,偶然发现docker带有macvlan的功能,以下是配置的一些信息记录
下文仅对网络配置有较为详细的介绍,docker的使用不做过多的说明,可以参考网上其他的一些文章

虚拟机环境配置

1.由于依赖于具体的局域网环境,所以要求虚拟机有一张网卡是桥接模式,对应的Linux系统网卡为enp0s9,下面是常用的两种虚拟机配置方式

  • VirtualBox

image-20220414222246225

  • VMware

image-20220414222655881

2.检查Linux系统网卡能够获取到路由器分配的ip,确保虚拟机可以正常获取到路由器的分配的ip

image-20220414223403372

3.设置Linux系统网卡开启混杂模式

在终端输入sudo ip link set enp0s9 promisc on开启网卡接口enp0s9的混杂模式,enp0s9根据实际配置网卡填写

在终端输入ifconfig查看是否开启混杂模式,显示有PROMISC即为混杂模式已开启

image-20220414223712052

上面用到的相关命令

#使用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

image-20220414224525647

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

image-20220414224803045

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

image-20220414225016211

一键配置脚本

#!/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官方文档

举报

相关推荐

0 条评论