Pipework在CoreOS上的一個(gè)小bug

Intro

某日辦公室要斷電維護(hù),作為 IT 狗需要在斷電之前把辦公室的服務(wù)器都停掉,來(lái)電后再把這些服務(wù)器啟起來(lái),其中有臺(tái)服務(wù)器,跑的是 CoreOS 系統(tǒng),上面一堆的 docker container。系統(tǒng)起來(lái)后,我發(fā)現(xiàn)這些 docker container,一個(gè)都不通,顯然,踩著大坑了......

環(huán)境

  • CoreOS stable (1185.5.0)
  • 4.7.3-coreos-r3
  • ip utility, iproute2-ss150210
  • Pipework 20150123

現(xiàn)象

簡(jiǎn)言之,就是用 net=none 啟動(dòng)的 docker 實(shí)例,用 Pipework 配置 ip 地址后 ping 不通,用代碼表示是這樣的:

docker run -i -t -d \
    --name=test \
    -h test \
    --net none \
    centos:6;
sudo pipework br0 \
    -i eth0 \
    test \
    10.0.0.3/24@10.0.0.1;
# br0 是橋,ip 地址是 10.0.0.2
# enp0s25 是直接在 10.0.0.0/24 網(wǎng)段的物理設(shè)備
# enp0s25 同時(shí)是橋 br0 的一個(gè) interface
# eth0 是 docker 的網(wǎng)卡設(shè)備名
# 這個(gè)測(cè)試 docker 的 ip 地址是 10.0.0.3
# 10.0.0.0/24 的網(wǎng)關(guān)是 10.0.0.1

結(jié)果 10.0.0.0/24 段的其他機(jī)器上 ping 不通 10.0.0.3,

docker exec -it test /bin/bash

進(jìn)入 docker 實(shí)例 test 內(nèi)部以后也 ping 不通網(wǎng)關(guān) 10.0.0.1

原因

最早懷疑是 proxy_arp 的問(wèn)題,但實(shí)際證明不是,最后發(fā)現(xiàn)是由于 docker 建立的 veth 設(shè)備(宿主機(jī)這端的)沒(méi)有正確添加到橋設(shè)備 br0 里去,從而導(dǎo)致怎么都不通。

解決起來(lái)也很簡(jiǎn)單,直接用

sudo brctl addif br0 vethlxxx
# vethlxxx 是這個(gè) docker 實(shí)例在宿主機(jī)側(cè)的網(wǎng)絡(luò)設(shè)備

然后就通了。

分析問(wèn)題

找到表面原因容易,可為什么沒(méi)能正確把 vethlxxx 設(shè)備加到橋設(shè)備 br0 里去呢?也不是第一次跑 Pipework 了,以前一直是好的。

看了看 Pipework 的代碼,并調(diào)試執(zhí)行了幾遍,發(fā)現(xiàn)這個(gè)問(wèn)題不是百分百出現(xiàn)的,只是有很大一部分概率。

最后大概定位問(wèn)題在 Pipework 的這幾句代碼上:

(ip link set "$LOCAL_IFNAME" master "$IFNAME" > /dev/null 2>&1) \
    || (brctl addif "$IFNAME" "$LOCAL_IFNAME")

和后面的

ip link set "$LOCAL_IFNAME" up

為什么這么說(shuō)呢,因?yàn)樵诟戒浀哪莻€(gè)鏈接里,有段話(huà)說(shuō)道:

To add an interface (e.g. eth0) into the bridge, its state must be up:

這也就是說(shuō)將某個(gè) interface 加入到橋設(shè)備之前,必須要先保證這個(gè) interface 的狀態(tài)是 up 的,但顯然在 Pipework 這份代碼里不是這樣的,這里是先加入到 br0,然后再將這個(gè) interface 設(shè)置為 up 的。

為了證明這個(gè),寫(xiě)了一段 bash 腳本,來(lái)模擬這個(gè)情況,具體如下(文件名叫 test.sh):

#!/bin/bash

set -x

IFNAME="brtest"
MTU=1500

(ip link add dev "$IFNAME" type bridge ) \
    || (brctl addbr "$IFNAME")
ip link set "$IFNAME" up
for i in {10..90}; do
    LOCAL_IFNAME="vethltest${i}"
    GUEST_IFNAME="vethgtest${i}"
    ip link add name "$LOCAL_IFNAME" \
        mtu "$MTU" type veth \
        peer name "$GUEST_IFNAME" \
        mtu "$MTU"
#   ip link show "$LOCAL_IFNAME"
    if ((${i}%2)); then
        ip link set "$LOCAL_IFNAME" down
    else
        ip link set "$LOCAL_IFNAME" up
    fi
    (ip link set "$LOCAL_IFNAME" master "$IFNAME") \
        || (brctl addif "$IFNAME" "$LOCAL_IFNAME")
    ip link set "$LOCAL_IFNAME" up
done

在 CoreOS 上執(zhí)行:

chmod +x test.sh # 這句執(zhí)行一遍即可
sudo ./test.sh

最后再

brctl show brtest

看結(jié)果,發(fā)現(xiàn):

  • vethltest${i}(i 為偶數(shù)的設(shè)備)都被正確添加到 brtest 里
  • vethltest${i}(i 為奇數(shù)的設(shè)備)有一些沒(méi)有被正確添加到 brtest 里

結(jié)論:

在我所測(cè)試的平臺(tái)(CoreOS)上,Pipework 是有問(wèn)題的,原因來(lái)自于調(diào)用的命令 ip(來(lái)自于軟件包 iproute2)

多說(shuō)一句

隨后我把測(cè)試程序 test.sh 拷貝到一臺(tái) CentOS 7 上跑,發(fā)現(xiàn) CentOS 7 沒(méi)有這個(gè)問(wèn)題。

Appendix

參考了一些網(wǎng)上的文檔:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評(píng)論 19 139
  • 0×1.幀中繼概述Frame Relay,簡(jiǎn)稱(chēng)FR,可以將它看做X.25協(xié)議的簡(jiǎn)化版本,幀中繼網(wǎng)絡(luò)中不考慮傳輸差錯(cuò)...
    Zero___閱讀 2,569評(píng)論 0 2
  • 0 01、網(wǎng)絡(luò)管理的五大功能(包括每項(xiàng)功能的具體情況) 1.配置管理:ISO定義的管理功能域中,配置管理包括視圖管...
    哈熝少主閱讀 3,622評(píng)論 1 20
  • 本文整理了在實(shí)踐過(guò)程中使用的Linux網(wǎng)絡(luò)工具,這些工具提供的功能非常強(qiáng)大,我們平時(shí)使用的只是冰山一角,比如lso...
    老夫劉某閱讀 3,812評(píng)論 0 7
  • 很多人說(shuō),余生很長(zhǎng),努力去做自己喜歡的事,堅(jiān)持下去就能得到自己想要的結(jié)果。 總說(shuō),堅(jiān)持就是勝利。 也有很多人說(shuō),余...
    夢(mèng)千機(jī)閱讀 523評(píng)論 0 0

友情鏈接更多精彩內(nèi)容