Docker精华问答 | 如何让一个容器连接两个网络?
如今Docker的使用已經非常普遍,特別在一線互聯網公司。使用Docker技術可以幫助企業快速水平擴展服務,從而到達彈性部署業務的能力。在云服務概念興起之后,Docker的使用場景和范圍進一步發展。今天,就讓我們來看看關于Docker的深度問答。
1
Q:vethxxxx?這種虛擬網卡和容器的對應關系從哪里看??
A:使用如下命令:
$ docker network ls
注意這里的?br-56f04389b8f0?以及?br-094fcb269385,br-?后面的是上面的網絡id,由此可以看出?veth?和 Docker 網絡的對應關系,而容器都是連接到了某個Docker網絡上的,從而就有了容器和?veth?的對應關系。對于某個網絡出現了多個veth?的情況,可以觀察veth22996d2@if11?后面的?if11?這部分,和容器內的?ip addr?的結果,一般奇-偶是一對。
Q:如何讓一個容器連接兩個網絡??
A:如果是使用?docker run,那很不幸,一次只可以連接一個網絡,因為?docker run?的?--network?參數只可以出現一次(如果出現多次,最后的會覆蓋之前的)。不過容器運行后,可以用命令?docker network connect?連接多個網絡。假設我們創建了兩個網絡:
3Q:Docker 多宿主網絡怎么配置
A:Docker 跨節點容器網絡互聯,最通用的是使用?overlay?網絡。
一代 Swarm 已經不再使用,它要求使用?overlay?網絡前先準備好分布式鍵值庫,比如?etcd,?consul?或?zookeeper。然后在每個節點的 Docker 引擎中,配置?--cluster-store?和?--cluster-advertise?參數。這樣才可以互連。可以參考我寫的 LNMP 容器互聯例子中的?run1.sh?這個腳本,這個腳本是利用?docker-machine自動建立 Swarm 并且配置好?overlay?的腳本,可以分析其流程。
現在都在使用二代 Swarm,也就是?Docker Swarm Mode,非常簡單,只要?docker swarm init?建立集群,其它節點?docker swarm join?加入集群后,集群內的服務就自動建立了?overlay?網絡互聯能力。
需要注意的是,如果是多網卡環境,無論是?docker swarm init?還是?docker swarm join,都不要忘記使用參數?--advertise-addr?指定宣告地址,否則自動選擇的地址很可能不是你期望的,從而導致集群互聯失敗。格式為?--advertise-addr <地址>:<端口>,地址可以是 IP 地址,也可以是網卡接口,比如?eth0。端口默認為?2377,如果不改動可以忽略。
此外,這是供服務使用的?overlay,因此所有?docker service create?的服務容器可以使用該網絡,而?docker run?不可以使用該網絡,除非明確該網絡為?--attachable。
Q:明明?docker network ls?中看到了建立的?overlay?網絡,怎么docker run?還說網絡不存在啊??
A:如果在?docker network ls?中看到了如下的?overlay?網絡:
報錯說mynet?網絡找不到。其實如果仔細觀察,會看到這個名為mynet?的網絡,驅動是?overlay沒有錯,但它的Scope?是swarm。這個意思是說這個網絡是在二代Swarm環境中建立的overlay網絡,因此只可以由Swarm環境下的服務容器才可以使用。而docker run所運行的只是零散的容器,并非Service,因此自然在零散容器所能使用的網絡中,不存在叫mynet網絡。
docker run可以使用的overlay網絡是Scope為global的overlay網絡,也就是使用外置鍵值庫所建立的overlay網絡,比如一代Swarm的overlay網絡。這點在 1.13 后稍有變化。如果是 1.13 以后的系統,會看到這樣的信息:
Q:容器怎么取宿主機 IP 啊??
A:單機環境?
如果是單機環境,很簡單,不必琢磨怎么突破命名空間限制,直接用環境變量送進去即可。
然后容器內直接讀取?HOST_IP?環境變量即可。
集群環境?
集群環境相對比較復雜,docker service create?中的?-e?以及?--env-file是在服務創建時指定、讀取環境變量內容,而不是運行時,因此對于每個節點都是一樣的。而且目前不存在?dockerd -e?選項,所以直接使用這些選項達不到我們想要的效果。不過有變通的辦法,可以在宿主上建立一個?/etc/variables?文件(名字隨意,這里用這個文件舉例)。其內容為:
其中?1.2.3.4?是這個節點的宿主 IP,因此每個節點的?/etc/variables?的內容不同。
而在啟動服務時,指定掛載這個服務端本地文件:
docker service create --name app \
--mount type=bind,source=/etc/variables,target=/etc/variables:ro \
myapp
由于?--mount?是發生于容器運行時,因此所加載的是所運行的服務器的?/etc/variables,里面所包含的也是該服務器的 IP 地址。在?myapp?這個鏡像的入口腳本加入加載該環境變量文件的命令:
這樣app這個服務容器就會擁有?HOST_IP?環境變量,其值為所運行的宿主 IP。
小伙伴們沖鴨,后臺留言區等著你!
關于Docker,今天你學到了什么?還有哪些不懂的?除此還對哪些話題感興趣?快來留言區打卡啦!留言方式:打開第XX天,答:……
同時歡迎大家搜集更多問題,投稿給我們!風里雨里留言區里等你~
福利
1、掃描添加小編微信,備注“姓名+公司職位”,加入【云計算學習交流群】,和志同道合的朋友們共同打卡學習!
2、公眾號后臺回復:白皮書,獲取IDC最新數據白皮書整理資料!
推薦閱讀:
全面剖析企業私有云
30 秒?!Chrome 插件帶你速成編程學習 | 程序員硬核評測
為什么程序員下班后只關顯示器從不關電腦?
算法警告!該圖片涉嫌違規不予顯示
交易機器人春天已來?先看完這篇再說吧
2019年中國IT市場趨勢熱點
2019年最值得關注的五大微服務發展趨勢
總結
以上是生活随笔為你收集整理的Docker精华问答 | 如何让一个容器连接两个网络?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样注册投资公司
- 下一篇: Kubernetes API 与 Ope