鍍金池/ 教程/ Linux/ Docker 網(wǎng)絡(luò)實(shí)現(xiàn)
利用數(shù)據(jù)卷容器來(lái)備份、恢復(fù)、遷移數(shù)據(jù)卷
Docker 網(wǎng)絡(luò)實(shí)現(xiàn)
實(shí)戰(zhàn) Django
YAML 模板文件
名字空間
控制組
編輯網(wǎng)絡(luò)配置文件
列出
進(jìn)入容器
Compose 命令說(shuō)明
創(chuàng)建 Tomcat/Weblogic 集群
守護(hù)態(tài)運(yùn)行
快速配置指南
其它安全特性
示例:創(chuàng)建一個(gè)點(diǎn)到點(diǎn)連接
CentOS 系列安裝 Docker
數(shù)據(jù)卷容器
鏡像
指令
創(chuàng)建鏡像
Docker 容器
創(chuàng)建鏡像
常用倉(cāng)庫(kù)
總結(jié)
什么是 Docker
存出和載入鏡像
使用
獲取鏡像
容器互聯(lián)
為什么要使用 Docker?
使用 Wordpress 入門(mén) Fig
啟動(dòng)
容器訪問(wèn)控制
私有倉(cāng)庫(kù)
使用
基本架構(gòu)
自定義網(wǎng)橋
環(huán)境變量參考
實(shí)戰(zhàn) Rail
服務(wù)端的防護(hù)
刪除
鏡像的實(shí)現(xiàn)原理
多臺(tái)物理主機(jī)之間的容器互聯(lián)
Docker 倉(cāng)庫(kù)
簡(jiǎn)介
數(shù)據(jù)卷
命令參考
使用 Supervisor 來(lái)管理進(jìn)程
移除
基本結(jié)構(gòu)
命令查詢
終止容器
聯(lián)合文件系統(tǒng)
安裝
簡(jiǎn)介
配置 DNS
內(nèi)核能力機(jī)制
導(dǎo)出和導(dǎo)入容器
配置 docker0 網(wǎng)橋
倉(cāng)庫(kù)配置文件
內(nèi)核名字空間
標(biāo)準(zhǔn)化開(kāi)發(fā)測(cè)試和生產(chǎn)環(huán)境
外部訪問(wèn)容器
fig.yml 參考
Ubuntu 系列安裝 Docker
有用資源
安裝
端口映射實(shí)現(xiàn)
安裝 Fig
工具和示例
簡(jiǎn)介
控制組
容器格式
Docker Hub

Docker 網(wǎng)絡(luò)實(shí)現(xiàn)

Docker 的網(wǎng)絡(luò)實(shí)現(xiàn)其實(shí)就是利用了 Linux 上的網(wǎng)絡(luò)名字空間和虛擬網(wǎng)絡(luò)設(shè)備(特別是 veth pair)。建議先熟悉了解這兩部分的基本概念再閱讀本章。

基本原理

首先,要實(shí)現(xiàn)網(wǎng)絡(luò)通信,機(jī)器需要至少一個(gè)網(wǎng)絡(luò)接口(物理接口或虛擬接口)來(lái)收發(fā)數(shù)據(jù)包;此外,如果不同子網(wǎng)之間要進(jìn)行通信,需要路由機(jī)制。

Docker 中的網(wǎng)絡(luò)接口默認(rèn)都是虛擬的接口。虛擬接口的優(yōu)勢(shì)之一是轉(zhuǎn)發(fā)效率較高。 Linux 通過(guò)在內(nèi)核中進(jìn)行數(shù)據(jù)復(fù)制來(lái)實(shí)現(xiàn)虛擬接口之間的數(shù)據(jù)轉(zhuǎn)發(fā),發(fā)送接口的發(fā)送緩存中的數(shù)據(jù)包被直接復(fù)制到接收接口的接收緩存中。對(duì)于本地系統(tǒng)和容器內(nèi)系統(tǒng)看來(lái)就像是一個(gè)正常的以太網(wǎng)卡,只是它不需要真正同外部網(wǎng)絡(luò)設(shè)備通信,速度要快很多。

Docker 容器網(wǎng)絡(luò)就利用了這項(xiàng)技術(shù)。它在本地主機(jī)和容器內(nèi)分別創(chuàng)建一個(gè)虛擬接口,并讓它們彼此連通(這樣的一對(duì)接口叫做 veth pair)。

創(chuàng)建網(wǎng)絡(luò)參數(shù)

Docker 創(chuàng)建一個(gè)容器的時(shí)候,會(huì)執(zhí)行如下操作:

  • 創(chuàng)建一對(duì)虛擬接口,分別放到本地主機(jī)和新容器中;
  • 本地主機(jī)一端橋接到默認(rèn)的 docker0 或指定網(wǎng)橋上,并具有一個(gè)唯一的名字,如 veth65f9;
  • 容器一端放到新容器中,并修改名字作為 eth0,這個(gè)接口只在容器的名字空間可見(jiàn);
  • 從網(wǎng)橋可用地址段中獲取一個(gè)空閑地址分配給容器的 eth0,并配置默認(rèn)路由到橋接網(wǎng)卡 veth65f9。

完成這些之后,容器就可以使用 eth0 虛擬網(wǎng)卡來(lái)連接其他容器和其他網(wǎng)絡(luò)。

可以在 docker run 的時(shí)候通過(guò) --net 參數(shù)來(lái)指定容器的網(wǎng)絡(luò)配置,有4個(gè)可選值:

  • --net=bridge 這個(gè)是默認(rèn)值,連接到默認(rèn)的網(wǎng)橋。
  • --net=host 告訴 Docker 不要將容器網(wǎng)絡(luò)放到隔離的名字空間中,即不要容器化容器內(nèi)的網(wǎng)絡(luò)。此時(shí)容器使用本地主機(jī)的網(wǎng)絡(luò),它擁有完全的本地主機(jī)接口訪問(wèn)權(quán)限。容器進(jìn)程可以跟主機(jī)其它 root 進(jìn)程一樣可以打開(kāi)低范圍的端口,可以訪問(wèn)本地網(wǎng)絡(luò)服務(wù)比如 D-bus,還可以讓容器做一些影響整個(gè)主機(jī)系統(tǒng)的事情,比如重啟主機(jī)。因此使用這個(gè)選項(xiàng)的時(shí)候要非常小心。如果進(jìn)一步的使用 --privileged=true,容器會(huì)被允許直接配置主機(jī)的網(wǎng)絡(luò)堆棧。
  • --net=container:NAME_or_ID 讓 Docker 將新建容器的進(jìn)程放到一個(gè)已存在容器的網(wǎng)絡(luò)棧中,新容器進(jìn)程有自己的文件系統(tǒng)、進(jìn)程列表和資源限制,但會(huì)和已存在的容器共享 IP 地址和端口等網(wǎng)絡(luò)資源,兩者進(jìn)程可以直接通過(guò) lo 環(huán)回接口通信。
  • --net=none 讓 Docker 將新容器放到隔離的網(wǎng)絡(luò)棧中,但是不進(jìn)行網(wǎng)絡(luò)配置。之后,用戶可以自己進(jìn)行配置。

網(wǎng)絡(luò)配置細(xì)節(jié)

用戶使用 --net=none 后,可以自行配置網(wǎng)絡(luò),讓容器達(dá)到跟平常一樣具有訪問(wèn)網(wǎng)絡(luò)的權(quán)限。通過(guò)這個(gè)過(guò)程,可以了解 Docker 配置網(wǎng)絡(luò)的細(xì)節(jié)。

首先,啟動(dòng)一個(gè) /bin/bash 容器,指定 --net=none 參數(shù)。

$ sudo docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#

在本地主機(jī)查找容器的進(jìn)程 id,并為它創(chuàng)建網(wǎng)絡(luò)命名空間。

$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
$ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid

檢查橋接網(wǎng)卡的 IP 和子網(wǎng)掩碼信息。

$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...

創(chuàng)建一對(duì) “veth pair” 接口 A 和 B,綁定 A 到網(wǎng)橋 docker0,并啟用它

$ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up

將B放到容器的網(wǎng)絡(luò)命名空間,命名為 eth0,啟動(dòng)它并配置一個(gè)可用 IP(橋接網(wǎng)段)和默認(rèn)網(wǎng)關(guān)。

$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
$ sudo ip netns exec $pid ip link set eth0 up
$ sudo ip netns exec $pid ip addr add 172.17.42.99/16 dev eth0
$ sudo ip netns exec $pid ip route add default via 172.17.42.1

以上,就是 Docker 配置網(wǎng)絡(luò)的具體過(guò)程。

當(dāng)容器結(jié)束后,Docker 會(huì)清空容器,容器內(nèi)的 eth0 會(huì)隨網(wǎng)絡(luò)命名空間一起被清除,A 接口也被自動(dòng)從 docker0 卸載。

此外,用戶可以使用 ip netns exec 命令來(lái)在指定網(wǎng)絡(luò)名字空間中進(jìn)行配置,從而配置容器內(nèi)的網(wǎng)絡(luò)。