跳到主要內容

Docker 無法連線至特定網段 (172.17.x.x)

公司正逐步採用 docker 來進行快速部署,一開始先從 Jenkins、Redis 這類基礎服務著手,在開發環境一切都很順利,加上 docker 的部署速度,讓整個計劃倍受好評,沒想到在 stage 環境卻出現意料外的狀況:docker 建立的服務與 docker host 都無法連線至 172.17 開頭的 server

重現問題

  1. 無法連線至 172.17
    117217
  2. 連線 172.16 則一切正常
    211716

如何確認是 docker 造成的

  1. 在 docker host 上找出 docker 的 bridge
    1
    brctl show
    3brctl
  2. 將 docker 的 bridge 停用
    1
    ifconfig docker0 down
  3. 重新測試是否可以連線至目標 server
    4downping
    如果已可正常連線,基本上已經可以確認是 docker 所造成的問題,以下的 step 4 與 step 5 是用來協助再次確認問題是 docker 造成的,非必要執行
  4. 重複驗證 - 將 docker bridge0 啟用
    1
    ifconfig docker0 up
  5. 確認是否又無法正常連線
    5upping

問題發生原因

docker 在 linux 環境中預設指定給 container 使用的 ip 就是 172.17.x.x 開頭,因此在 container 或是 docker host 會將所有對於 172.17.x.x 的 request 導向 docker bridge 處理
相關細節請參考 Customize the docker0 bridge

解決方式

  1. 在 /etc/docker/ 加上 daemon.json
    1
    vi /etc/docker/daemon.json
  2. 在 daemon.json 指定 bip 範圍
    1
    2
    3
    {
    "bip": "192.168.168.1/24"
    }
    bip 範圍請依實際情況調整,詳細設定請參考官方文件 dockerd
  3. 重啟 docker service 以套用設定
    只重啟 container 沒有作用。注意:重啟 dcoker service 會 shutdown 所有 container
    1
    service docker restart
    6dockerrestart
  4. 效果
    使用 docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' container_name_or_id 來確認 container 使用的 ip,詳細介紹可以參考 如何取得 Container 所使用的 Ip
    • 修改前:預設使用 172.17.0.3
      7before
    • 修改後:依設定使用 192.168.168.2
      8after
    • 已可正常存取 172.17.x.x 網段 server
      4downping

心得

其實這個 issue 只有在 docker 需要與 172.17.x.x 網段 server 互動時才會出現,但剛好公司不少 server 都用到 172.17.x.x 網段,算是天時地利搭配得好才有機會踩到這個問題 @@”
雖然花了不少時間才解決,不過也多虧這次機會多了解 docker 配置 container ip 的機制,也許以後還會派上用場,多學總是好的

參考資訊

  1. Customize the docker0 bridge
  2. 如何取得 Container 所使用的 Ip
  3. dockerd

 Yowko's Notes 由 Yowko Tsai 製作,以創用CC 姓名標示-非商業性-相同方式分享 3.0 台灣 授權條款 釋出。

留言