收起左侧

新手向,MACVLAN一键部署

0
回复
46
查看
[ 复制链接 ]

0

主题

7

回帖

0

牛值

江湖小虾

#!/bin/bash
set -e  # 遇到错误立即退出

# ========== 用户自定义区域 ==========
DOCKER_NETWORK_NAME="macvlan"          # 自定义1:Docker网络名称
HOST_INTERFACE_NAME="macvlan123"       # 自定义2:宿主机接口名称(必须是英文)
HOST_IP_SUFFIX=222                        # 自定义3:宿主机接口IP后缀(macvlan接口自身在宿主机上的IP地址后缀)
IP_RANGE_START=223                        # 自定义4:IP段起始地址(分配给macvlan网络内配备了macvlan网卡的容器的起始IP地址)
IP_RANGE_END=230                          # 自定义5:IP段结束地址(分配给macvlan网络内配备了macvlan网卡的容器的终点IP,此IP地址段内的容器均可接入macvlan网络)
# =====================================

# ========== IP冲突检测函数 ==========
check_ip_available() {
    local ip=$1
    local description=$2
  
    echo "   检测 $description: $ip ..."
  
    # 方法1:ARP表检测(最可靠)
    if ip neigh show | grep -q "$ip.*REACHABLE"; then
        echo "❌ 错误:${description} ($ip) 已被占用,请检查网络或修改自定义区域的IP段"
        exit 1
    fi
  
    # 方法2:尝试ping(作为补充)
    if ping -c 1 -W 1 $ip >/dev/null 2>&1; then
        echo "❌ 错误:${description} ($ip) 已被占用,请检查网络或修改自定义区域的IP段"
        exit 1
    fi
}

# ========== 强制清理残留配置 ==========
echo "🧹 正在清理旧配置: $DOCKER_NETWORK_NAME / $HOST_INTERFACE_NAME"
sleep 1

systemctl stop ${HOST_INTERFACE_NAME}.service 2>/dev/null || true
systemctl disable ${HOST_INTERFACE_NAME}.service 2>/dev/null || true
rm -f /etc/systemd/system/${HOST_INTERFACE_NAME}.service
rm -f /usr/local/bin/setup-${HOST_INTERFACE_NAME}.sh
ip link del ${HOST_INTERFACE_NAME} 2>/dev/null || true
docker network rm ${DOCKER_NETWORK_NAME} 2>/dev/null || true
systemctl daemon-reload
echo "✅ 清理完成"
sleep 1

# ========== 第一阶段:环境自动检测 ==========
echo "🔍 正在自动检测网络环境..."
sleep 1

PHY_NIC=$(ip -o route get 1.1.1.1 2>/dev/null | awk '{print $5}' | head -1)
if [ -z "$PHY_NIC" ]; then
  echo "❌ 错误:无法自动检测物理网卡"
  exit 1
fi

IP_WITH_MASK=$(ip -o addr show $PHY_NIC | awk '/inet / {print $4}' | head -1)
SUBNET=$(echo $IP_WITH_MASK | sed -E 's/([0-9]+\.[0-9]+\.[0-9]+)\.[0-9]+\/([0-9]+)/\1.0\/\2/')
GATEWAY=$(ip route show default | awk '/via/ {print $3}' | head -1)

echo "✅ 检测完成:网卡=$PHY_NIC 子网=$SUBNET 网关=$GATEWAY"
sleep 2

# ========== 第二阶段:IP冲突检测 ==========
echo "🔍 正在检测IP是否已被占用..."
NET_PREFIX=$(echo $IP_WITH_MASK | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\..*/\1/')

# 检测宿主机接口IP
check_ip_available "${NET_PREFIX}.${HOST_IP_SUFFIX}" "宿主机接口IP"

# 检测预留IP段
for ip in $(seq ${IP_RANGE_START} ${IP_RANGE_END}); do
    check_ip_available "${NET_PREFIX}.$ip" "预留容器IP"
done

echo "✅ IP检测完成,无冲突"
sleep 1

# ========== 第三阶段:创建 Docker macvlan 网络 ==========
echo -e "\n📦 正在创建 Docker macvlan 网络: $DOCKER_NETWORK_NAME"
docker network create -d macvlan \
  --subnet=$SUBNET \
  --gateway=$GATEWAY \
  --ipv6 \
  --subnet=fd00::/64 \
  -o parent=$PHY_NIC \
  ${DOCKER_NETWORK_NAME} && \
echo "✅ Docker ${DOCKER_NETWORK_NAME} 网络创建成功" || \
{ echo "❌ 网络创建失败"; exit 1; }
sleep 1

# ========== 第四阶段:配置宿主机接口 ==========
echo -e "\n🔧 正在配置宿主机接口: $HOST_INTERFACE_NAME"

# 创建启动脚本(关键修复:使用双引号并正确转义)
cat > /usr/local/bin/setup-${HOST_INTERFACE_NAME}.sh <<EOF
#!/bin/bash
PHY_NIC=\$(ip -o route get 1.1.1.1 2>/dev/null | awk '{print \$5}' | head -1)
NET_PREFIX=\$(ip -o addr show \$PHY_NIC | awk '/inet / {print \$4}' | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\..*/\1/')

# 清理旧接口
ip link del ${HOST_INTERFACE_NAME} 2>/dev/null

# 创建接口(变量在写入时展开)
ip link add ${HOST_INTERFACE_NAME} link \$PHY_NIC type macvlan mode bridge
ip addr add \${NET_PREFIX}.${HOST_IP_SUFFIX}/$(echo $IP_WITH_MASK | cut -d'/' -f2) dev ${HOST_INTERFACE_NAME}
ip link set ${HOST_INTERFACE_NAME} up

# 添加IP范围路由(循环在写入时展开)
$(for ip in $(seq ${IP_RANGE_START} ${IP_RANGE_END}); do
  echo "ip route add \${NET_PREFIX}.${ip}/32 dev ${HOST_INTERFACE_NAME} 2>/dev/null"
done)
EOF

chmod +x /usr/local/bin/setup-${HOST_INTERFACE_NAME}.sh

# 创建 systemd 服务
cat > /etc/systemd/system/${HOST_INTERFACE_NAME}.service <<EOF
[Unit]
Description=Macvlan interface ${HOST_INTERFACE_NAME}
After=network-online.target
Wants=network-online.target

[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/setup-${HOST_INTERFACE_NAME}.sh

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable ${HOST_INTERFACE_NAME}.service && echo "✅ 服务已设为开机自启"
systemctl start ${HOST_INTERFACE_NAME}.service && echo "✅ 服务启动成功" || echo "⚠️  服务启动可能失败"

sleep 1

# ========== 第五阶段:验证配置 ==========
echo -e "\n🔍 验证配置..."

NET_PREFIX=$(echo $IP_WITH_MASK | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\)\..*/\1/')
echo "   Docker ${DOCKER_NETWORK_NAME} 子网:"
docker network inspect ${DOCKER_NETWORK_NAME} | grep -A 1 "Subnet" | grep -v "\-\-"

echo "   宿主机 ${HOST_INTERFACE_NAME} 接口IP:"
ip addr show ${HOST_INTERFACE_NAME} | grep "inet " | awk '{print $2}'

ROUTE_COUNT=$(ip route | grep ${HOST_INTERFACE_NAME} | wc -l)
echo "   路由规则数量:$ROUTE_COUNT(应显示 $(($IP_RANGE_END-$IP_RANGE_START+1)) 条)"

echo "   Systemd 服务状态:"
systemctl is-active ${HOST_INTERFACE_NAME}.service

echo -e "\n🎉 全部配置完成!"
echo "********************************************************************************"
echo "📌 Docker 网络名称:${DOCKER_NETWORK_NAME}"
echo "📌 宿主机接口名称:${HOST_INTERFACE_NAME}"
echo "📌 已预留IP段:${NET_PREFIX}.${IP_RANGE_START}-${IP_RANGE_END}"
echo "********************************************************************************"

首先解释一下什么是macvlan:我们把docker里的普通网络想象为一台电脑,容器想象为电脑里各种各样的游戏。如果我为了玩COD,那么我就要开加速器,但是我又同时想玩CF,又不想让CF开加速器。那么普通网络局限性就体现出来了。自古COD、CF难两全。那么有没有什么办法同时让COD等外服游戏开加速器,而CF等国服游戏又不开加速器呢?有的,兄弟,有的!
这里就要引入macvlan网络了。把我们把macvlan网络想象成为一台全新的电脑。我们把COD、战地等需要开加速器的游戏留在老电脑,CF、**等国服游戏放入macvlan这台新电脑里。这样,你老电脑开加速器就不会影响新电脑里CF等国服游戏了。

但这又引出一个新问题,老电脑和新电脑之间并不会互通信息,那么我们只需要在新、老电脑之间架起一座通信桥梁就好了。这里不用担心,通信桥梁架好后,你老电脑开加速器依旧不会影响到你新电脑的网络。

原理图.jpg

解释代码:在自定义1里你需要给这个macvlan网络一个名字。自定义2就是需要给通信桥梁一个名字。自定义3就是由你来决定你要给新电脑用哪一个IP呢?自定义4和自定义5是一个IP段,比如XXX.XXX.223-XXX.XXX.XXX.230,这一段范围的每一个IP都算是放入新电脑里的游戏,比如以后我部署CF时,手动分配他地址为192.168.X.223,那么就代表他被放入新电脑了。或者我部署战地,我准备放入老电脑里使得它能开加速器,那么我在部署时就不给手动分配IP,那么就会被装入老电脑里。玩PT的也同理,你把QB和TR放入新电脑,那么你老电脑随便开什么加速器都不会影响到你QB和TR,这样可以避免因为你老电脑开加速器后QB和TR的上传被判定为盒子而封号。

注:新电脑中(macvlan网络)每个容器必须使用独立的IP地址,但端口可以相同(最好也别相同,因为我没试过)。如图所示。

具体操作步骤:1、首先确保你的飞牛NAS已经打开SSH和DOCKER。2、找一台同网络的电脑,进入cmd。3、输入代码 ssh 你飞牛账号@你飞牛的ip地址 -p 22,然后输入密码(此时输入密码并不会由任何显示,你输入完回车就完事了)。4、第一次连接SSH的话会提示询问你是否连接,有一个yes和no的选项,你输入yes。5、进入管理员模式,输入 sudo -i之后会提示你继续输入密码,你就继续输入吧。6、将上面的代码按你的要求更改好后复制进去并回车。不出意外你就应该可以看到提示全部配置完成,到这一步就算创建好了,你可以去你飞牛打开docker,下方有个网络,点击进去可以看见。

收藏
送赞
分享

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则