Docker 與 Docker-Compose 設定 ipvlan 網路時遇到問題

大家好,

我正在嘗試在我的 TS-264 上設置多個容器,最初使用 Docker Compose,但沒有成功。所以我改用更簡單的純 Docker,但也失敗了。

最終,我需要運行 4 個容器,並且它們能夠彼此通信。計劃如下:

  • 3 個容器在 ipvlan 網路上。
  • 1 個容器採用 host 模式(因為它需要存取 USB 埠)。

為了測試方便,我寫了一個簡單的腳本,拉取並運行一個 Alpine 容器。

以下是我的腳本:

#!/bin/sh

# 1. 移除所有
docker network rm qnap-ipvlan 2>/dev/null || true
docker rm -f alpine 2>/dev/null || true

# 2. 建立 ipvlan 網路(L2 模式)
# docker network create -d ipvlan --subnet=10.159.2.0/24 --gateway=10.159.2.4 --ip-range=10.159.2.96/28 -o parent=eth1 -o ipvlan_mode=l2 qnap-ipvlan

docker network create -d ipvlan --subnet=10.159.2.0/24 --gateway=10.159.2.4 --ip-range=10.159.2.96/28 -o parent=eth1 -o ipvlan_mode=l2 -o ipvlan_flags=bridge -o com.docker.network.driver.mtu=1500 qnap-ipvlan

# 3. 檢查是否成功
docker network inspect qnap-ipvlan

# 4. 用 alpine 容器測試
docker run -it --rm --network=qnap-ipvlan --ip=10.159.2.109 alpine sh -c "ping -c 2 10.159.2.4 && ping -c 2 10.159.2.10"

# 5. Alpine 是否可達
# 從 QNAP 本機:
curl -I http://10.159.2.109 2>/dev/null || echo "Testing connection"

# 6. 狀態
docker-compose ps
docker network inspect qnap-ipvlan

這是我得到的結果/錯誤:

[/share/Container/docker-compose] # chmod ug+x ./setup_IPvlan_alpine.sh
[/share/Container/docker-compose] # ./setup_IPvlan_alpine.sh
qnap-ipvlan
9f3dbd6a27cfa1812--------636471f5893ba6b38bf15f7b2c
[
    {
        "Name": "qnap-ipvlan",
        "Id": "9f3dbd6a27cfa1812a----3b31636471f5893ba6b38bf15f7b2c",
        "Created": "2026-01-14T22:05:40.655178454+01:00",
        "Scope": "local",
        "Driver": "ipvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.159.2.0/24",
                    "IPRange": "10.159.2.96/28",
                    "Gateway": "10.159.2.4"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.driver.mtu": "1500",
            "ipvlan_flags": "bridge",
            "ipvlan_mode": "l2",
            "parent": "eth1"
        },
        "Labels": {}
    }
]
docker: Error response from daemon: failed to create the ipvlan port: device or resource busy.
Testing connection
WARN[0000] /share/Container/docker-compose/docker-compose.yml: the attribute `version` is obsolete, it will be ignored, please remove it to avoid potential confusion 
NAME      IMAGE     COMMAND   SERVICE   CREATED   STATUS    PORTS
[
    {
        "Name": "qnap-ipvlan",
        "Id": "9f3dbd6a27cfa1812a36-------893ba6b38bf15f7b2c",
        "Created": "2026-01-14T22:05:40.655178454+01:00",
        "Scope": "local",
        "Driver": "ipvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "10.159.2.0/24",
                    "IPRange": "10.159.2.96/28",
                    "Gateway": "10.159.2.4"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {},
        "Options": {
            "com.docker.network.driver.mtu": "1500",
            "ipvlan_flags": "bridge",
            "ipvlan_mode": "l2",
            "parent": "eth1"
        },
        "Labels": {}
    }
]

我遇到的主要錯誤是:
“docker: Error response from daemon: failed to create the ipvlan port: device or resource busy.”

為什麼會出現這個 “device or resource busy” 的 ipvlan 錯誤?我要怎麼修正才能繼續設置?

任何建議或意見都非常感謝

先謝謝大家!

有什麼理由必須使用 VLAN 嗎?QNAP 預設會將所有容器放在各自的網路上……

首先感謝您的時間。我本來想更早回覆,但不知何故,每次嘗試登入時都一直遇到「gateway time out(閘道逾時)」的問題。

其次,確實是有原因的。

預設的 Container Station 是透過埠映射(port forwarding)來暴露服務。

然而,我想要自訂 ipvlan 網路的原因,主要是基於一些架構和操作上的需求:ipvlan 網路允許容器在現有的 LAN 子網上擁有自己的專屬、可路由的 IP 位址,無需 NAT。這讓它們在網路上表現得像實體設備一樣,對於需要使用固定 IP 進行容器間直接通訊非常重要。這也讓 LAN 上的其他設備能直接存取容器,而不必經過主機的埠映射。

ipvlan 的 L2 模式比 Docker 預設的 bridge(橋接模式,會用 NAT 和 iptables 規則)負擔更小。對我的使用情境來說也更簡單,因為我不需要也不想管理一堆埠映射,尤其在我忙於容器本身用途時還要記住這些設定。

使用 Docker Compose 或腳本搭配定義好的 ipvlan 網路,可以讓整個設定自動記錄且易於移植。如果需要,我可以直接複製並在另一個 Docker 主機(不一定是 QNAP)上重現完全相同的網路配置,只需調整 parent 介面即可。

除了個人偏好和需求之外,還有一些操作上的考量。我目前比較關注的是,為什麼會收到「埠已被使用」的通知。您或其他人可以協助我解決這個問題嗎?

謝謝。

感謝您的發文。我一直以為在 Network and Virtual Switch 中由 ContainerStation 創建的額外網路是真正可路由的獨立網路。實際上不是這樣嗎?

根據我對 Container Station 的理解,你可以選擇像是「host」、「bridge」以及 VLAN 類型(macvlan?)等網路模式。

你可能比我更了解這方面,但我找不到方法可以在不使用埠轉發的情況下,為每個容器分配靜態 IP,同時讓它們能彼此直接通訊。我沒找到任何能達到這個目的的範例。當我嘗試在 bridge 模式下設置靜態 IP 時,只要選擇資料夾,容器設置就會卡住。這個問題,加上所需的時間和整體目標,讓我不太想繼續嘗試。

在 Container Station 裡建立可重複使用的設定感覺太麻煩了,特別是如果我之後想移到另一台 QNAP 或不同系統。我真的需要一個能一次套用所有必要設定的解決方案。

更新:

順帶一提,我剛剛發現錯誤的原因。QNAP 設定了虛擬介面,導致 eth1.100vsc0(或類似名稱)被阻擋。Docker——或系統本身——於是預設使用了 eth0

我透過執行 ip link set eth1 promisc on 部分解決了這個問題,這讓實體介面可以接受多個 IP 位址。

現在容器之間可以互相通訊,但奇怪的是,主機卻無法與容器通訊。

剛完成了一個測試腳本。也許有人可以幫忙看看。


#!/bin/sh

echo "1. 移除舊的容器"
docker rm -f container-a container-b 2>/dev/null || true
docker network rm qnap-ipvlan-static

echo "=== 1. 當前網路設定 ==="
echo "Eth1 IP 位址:"
ip addr show dev eth1 | grep inet
echo "—"
echo "Eth1 連線狀態:"
ip link show eth1

echo "=== 2. 移除舊的網路 ==="
docker network rm qnap-ipvlan 2>/dev/null || true

echo "=== IPVLAN 網路(固定 IP) ==="

echo "1. 開啟混雜模式"
ip link set eth1 promisc on

echo "2. 建立名為 'qnap-ipvlan-static' 的 IPVLAN 網路"
docker network create -d ipvlan --subnet=10.159.2.0/24 --gateway=10.159.2.4 --ip-range=10.159.2.96/28 -o parent=eth1 -o ipvlan_mode=l2 qnap-ipvlan-static

echo "3. 啟動 Container A,固定 IP 為 10.159.2.101"
docker run -d --name container-a --network=qnap-ipvlan-static --ip=10.159.2.101 alpine sleep 300
sleep 4

echo "4. 啟動 Container B,固定 IP 為 10.159.2.102"
docker run -d --name container-b --network=qnap-ipvlan-static --ip=10.159.2.102 alpine sleep 300
sleep 4

echo "=== 5. 網路測試 ==="

echo "測試 1:Container A 到 Container B"
docker exec container-a ping -c 2 10.159.2.102

echo "測試 2:Container B 到 Container A"
docker exec container-b ping -c 2 10.159.2.101

echo "警告 ---- ICMP 在防火牆中被封鎖"
echo "測試 3:Container A 到 Gateway"
docker exec container-a ping -c 2 10.159.2.4

echo "測試 4:Container B 到 Gateway"
docker exec container-b ping -c 2 10.159.2.4

echo "測試 5:主機到 Container A"
ping -c 2 10.159.2.101

echo "測試 6:QNAP 到 Container B"
ping -c 2 10.159.2.102

echo "=== 6. 從外部設備測試 ==="
echo "請從外部設備執行:"
echo "  ping 10.159.2.101"
echo "  ping 10.159.2.102"

#echo "=== 7. 清理 ==="

#docker rm -f container-a container-b

#docker network rm qnap-ipvlan-static

腳本執行結果,主機無法連線到容器。

[/share/Container/docker-compose] # ./setup3_IPvlan_alpine.sh

1. 移除舊的容器

container-a

container-b

qnap-ipvlan-static

=== 1. 當前網路設定 ===

Eth1 IP 位址:

    inet 10.159.2.10/24 brd 10.159.2.255 scope global eth1

---

Eth1 連線狀態:

3: eth1: <BROADCAST,MULTICAST,PROMISC,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000

    link/ether 24:5e:be:6d:3d:05 brd ff:ff:ff:ff:ff:ff

=== 2. 移除舊的網路 ===

=== IPVLAN 網路(固定 IP) ===

1. 開啟混雜模式

2. 建立 IPVLAN 網路

068597243bb2b05a185ef754a9eb00f0e06918b60028b01da9d159878e2b68be

3. 啟動 Container A,固定 IP 為 10.159.2.101

afbf...(略)

4. 啟動 Container B,固定 IP 為 10.159.2.102

7daa...(略)

=== 5. 網路測試 ===

測試 1:Container A 到 Container B

PING 10.159.2.102 (10.159.2.102): 56 data bytes

64 bytes from 10.159.2.102: seq=0 ttl=64 time=0.329 ms

64 bytes from 10.159.2.102: seq=1 ttl=64 time=0.076 ms



--- 10.159.2.102 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.076/0.202/0.329 ms

測試 2:Container B 到 Container A

PING 10.159.2.101 (10.159.2.101): 56 data bytes

64 bytes from 10.159.2.101: seq=0 ttl=64 time=0.072 ms

64 bytes from 10.159.2.101: seq=1 ttl=64 time=0.070 ms



--- 10.159.2.101 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.070/0.071/0.072 ms

ICMP 在防火牆中被封鎖

測試 3:Container A 到 Gateway

PING 10.159.2.4 (10.159.2.4): 56 data bytes

64 bytes from 10.159.2.4: seq=0 ttl=64 time=0.487 ms

64 bytes from 10.159.2.4: seq=1 ttl=64 time=0.257 ms



--- 10.159.2.4 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.257/0.372/0.487 ms

測試 4:Container B 到 Gateway

PING 10.159.2.4 (10.159.2.4): 56 data bytes

64 bytes from 10.159.2.4: seq=0 ttl=64 time=0.417 ms

64 bytes from 10.159.2.4: seq=1 ttl=64 time=0.231 ms



--- 10.159.2.4 ping statistics ---

2 packets transmitted, 2 packets received, 0% packet loss

round-trip min/avg/max = 0.231/0.324/0.417 ms

測試 5:主機到 Container A

PING 10.159.2.101 (10.159.2.101): 56 data bytes



--- 10.159.2.101 ping statistics ---

2 packets transmitted, 0 packets received, 100% packet loss

測試 6:QNAP 到 Container B

PING 10.159.2.102 (10.159.2.102): 56 data bytes



--- 10.159.2.102 ping statistics ---

2 packets transmitted, 0 packets received, 100% packet loss

=== 6. 從外部設備測試 ===

從外部設備執行:

  ping 10.159.2.101

  ping 10.159.2.102

ping 10.159.2.101 和 ping 10.159.2.102 從其他設備都可以正常運作。