mirror of
https://github.com/yeasy/docker_practice.git
synced 2025-08-04 06:51:42 +00:00
修正多個用詞
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
# 高級網路配置
|
||||
本章將介紹 Docker 的一些高級網路配置和選項。
|
||||
# 進階網路配置
|
||||
本章將介紹 Docker 的一些進階網路配置和選項。
|
||||
|
||||
當 Docker 啟動時,會自動在主機上創建一個 `docker0` 虛擬橋接器,實際上是 Linux 的一個 bridge,可以理解為一個軟體交換機。它會在掛載到它的網卡之間進行轉發。
|
||||
當 Docker 啟動時,會自動在主機上建立一個 `docker0` 虛擬橋接器,實際上是 Linux 的一個 bridge,可以理解為一個軟體交換機。它會在掛載到它的網卡之間進行轉發。
|
||||
|
||||
同時,Docker 隨機分配一個本地未占用的私有網段(在 [RFC1918](http://tools.ietf.org/html/rfc1918) 中定義)中的一個地址給 `docker0` 接口。比如典型的 `172.17.42.1`,網路遮罩為 `255.255.0.0`。此後啟動的容器內的網卡也會自動分配一個同一網段(`172.17.0.0/16`)的網址。
|
||||
|
||||
當創建一個 Docker 容器的時候,同時會創建了一對 `veth pair` 接口(當數據包發送到一個接口時,另外一個接口也可以收到相同的數據包)。這對接口一端在容器內,即 `eth0`;另一端在本地並被掛載到 `docker0` 網橋,名稱以 `veth` 開頭(例如 `vethAQI2QT`)。通過這種方式,主機可以跟容器通信,容器之間也可以相互通信。Docker 就創建了在主機和所有容器之間一個虛擬共享網路。
|
||||
當建立一個 Docker 容器的時候,同時會建立了一對 `veth pair` 接口(當數據包發送到一個接口時,另外一個接口也可以收到相同的數據包)。這對接口一端在容器內,即 `eth0`;另一端在本地並被掛載到 `docker0` 網橋,名稱以 `veth` 開頭(例如 `vethAQI2QT`)。透過這種方式,主機可以跟容器通信,容器之間也可以相互通信。Docker 就建立了在主機和所有容器之間一個虛擬共享網路。
|
||||
|
||||

|
||||
|
||||
接下來的部分將介紹在一些場景中,Docker 所有的網路自訂配置。以及通過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路配置。
|
||||
接下來的部分將介紹在一些場景中,Docker 所有的網路自訂配置。以及透過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路配置。
|
||||
|
@@ -1,5 +1,5 @@
|
||||
## 容器訪問控制
|
||||
容器的訪問控制,主要通過 Linux 上的 `iptables` 防火墻來進行管理和實現。`iptables` 是 Linux 上默認的防火墻軟件,在大部分發行版中都自帶。
|
||||
容器的訪問控制,主要透過 Linux 上的 `iptables` 防火墻來進行管理和實做。`iptables` 是 Linux 上默認的防火墻軟件,在大部分發行版中都自帶。
|
||||
|
||||
### 容器訪問外部網路
|
||||
容器要想訪問外部網路,需要本地系統的轉發支持。在Linux 系統中,檢查轉發是否打開。
|
||||
@@ -17,15 +17,15 @@ $sysctl -w net.ipv4.ip_forward=1
|
||||
### 容器之間訪問
|
||||
容器之間相互訪問,需要兩方面的支持。
|
||||
* 容器的網路拓撲是否已經互聯。默認情況下,所有容器都會被連接到 `docker0` 網橋上。
|
||||
* 本地系統的防火墻軟件 -- `iptables` 是否允許通過。
|
||||
* 本地系統的防火墻軟件 -- `iptables` 是否允許透過。
|
||||
|
||||
#### 訪問所有端口
|
||||
當啟動 Docker 服務時候,默認會添加一條轉發策略到 iptables 的 FORWARD 鏈上。策略為通過(`ACCEPT`)還是禁止(`DROP`)取決於配置`--icc=true`(缺省值)還是 `--icc=false`。當然,如果手動指定 `--iptables=false` 則不會添加 `iptables` 規則。
|
||||
當啟動 Docker 服務時候,默認會新增一條轉發策略到 iptables 的 FORWARD 鏈上。策略為透過(`ACCEPT`)還是禁止(`DROP`)取決於配置`--icc=true`(缺省值)還是 `--icc=false`。當然,如果手動指定 `--iptables=false` 則不會新增 `iptables` 規則。
|
||||
|
||||
可見,默認情況下,不同容器之間是允許網路互通的。如果為了安全考慮,可以在 `/etc/default/docker` 文件中配置 `DOCKER_OPTS=--icc=false` 來禁止它。
|
||||
|
||||
#### 訪問指定端口
|
||||
在通過 `-icc=false` 關閉網路訪問後,還可以通過 `--link=CONTAINER_NAME:ALIAS` 選項來訪問容器的開放端口。
|
||||
在透過 `-icc=false` 關閉網路訪問後,還可以透過 `--link=CONTAINER_NAME:ALIAS` 選項來訪問容器的開放端口。
|
||||
|
||||
例如,在啟動 Docker 服務時,可以同時使用 `icc=false --iptables=true` 參數來關閉允許相互的網路訪問,並讓 Docker 可以修改系統中的 `iptables` 規則。
|
||||
|
||||
@@ -39,9 +39,9 @@ DROP all -- 0.0.0.0/0 0.0.0.0/0
|
||||
...
|
||||
```
|
||||
|
||||
之後,啟動容器(`docker run`)時使用 `--link=CONTAINER_NAME:ALIAS` 選項。Docker 會在 `iptable` 中為 兩個容器分別添加一條 `ACCEPT` 規則,允許相互訪問開放的端口(取決於 Dockerfile 中的 EXPOSE 行)。
|
||||
之後,啟動容器(`docker run`)時使用 `--link=CONTAINER_NAME:ALIAS` 選項。Docker 會在 `iptable` 中為 兩個容器分別新增一條 `ACCEPT` 規則,允許相互訪問開放的端口(取決於 Dockerfile 中的 EXPOSE 行)。
|
||||
|
||||
當添加了 `--link=CONTAINER_NAME:ALIAS` 選項後,添加了 `iptables` 規則。
|
||||
當新增了 `--link=CONTAINER_NAME:ALIAS` 選項後,新增了 `iptables` 規則。
|
||||
```
|
||||
$ sudo iptables -nL
|
||||
...
|
||||
|
@@ -1,5 +1,5 @@
|
||||
## 自定義網橋
|
||||
除了默認的 `docker0` 網橋,用戶也可以指定網橋來連接各個容器。
|
||||
除了默認的 `docker0` 網橋,使用者也可以指定網橋來連接各個容器。
|
||||
|
||||
在啟動 Docker 服務的時候,使用 `-b BRIDGE`或`--bridge=BRIDGE` 來指定使用的網橋。
|
||||
|
||||
@@ -9,13 +9,13 @@ $ sudo service docker stop
|
||||
$ sudo ip link set dev docker0 down
|
||||
$ sudo brctl delbr docker0
|
||||
```
|
||||
然後創建一個網橋 `bridge0`。
|
||||
然後建立一個網橋 `bridge0`。
|
||||
```
|
||||
$ sudo brctl addbr bridge0
|
||||
$ sudo ip addr add 192.168.5.1/24 dev bridge0
|
||||
$ sudo ip link set dev bridge0 up
|
||||
```
|
||||
查看確認網橋創建並啟動。
|
||||
查看確認網橋建立並啟動。
|
||||
```
|
||||
$ ip addr show bridge0
|
||||
4: bridge0: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state UP group default
|
||||
@@ -23,7 +23,7 @@ $ ip addr show bridge0
|
||||
inet 192.168.5.1/24 scope global bridge0
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
配置 Docker 服務,默認橋接到創建的網橋上。
|
||||
配置 Docker 服務,默認橋接到建立的網橋上。
|
||||
```
|
||||
$ echo 'DOCKER_OPTS="-b=bridge0"' >> /etc/default/docker
|
||||
$ sudo service docker start
|
||||
|
@@ -11,18 +11,18 @@ $ mount
|
||||
tmpfs on /etc/resolv.conf type tmpfs ...
|
||||
...
|
||||
```
|
||||
這種機制可以讓宿主主機 DNS 信息發生更新後,所有 Docker 容器的 dns 配置通過 `/etc/resolv.conf` 文件立刻得到更新。
|
||||
這種機制可以讓宿主主機 DNS 信息發生更新後,所有 Docker 容器的 dns 配置透過 `/etc/resolv.conf` 文件立刻得到更新。
|
||||
|
||||
如果用戶想要手動指定容器的配置,可以利用下面的選項。
|
||||
如果使用者想要手動指定容器的配置,可以利用下面的選項。
|
||||
|
||||
`-h HOSTNAME or --hostname=HOSTNAME`
|
||||
設定容器的主機名,它會被寫到容器內的 `/etc/hostname` 和 `/etc/hosts`。但它在容器外部看不到,既不會在 `docker ps` 中顯示,也不會在其他的容器的 `/etc/hosts` 看到。
|
||||
|
||||
`--link=CONTAINER_NAME:ALIAS`
|
||||
選項會在創建容器的時候,添加一個其他容器的主機名到 `/etc/hosts` 文件中,讓新容器的程序可以使用主機名 ALIAS 就可以連接它。
|
||||
選項會在建立容器的時候,新增一個其他容器的主機名到 `/etc/hosts` 文件中,讓新容器的程序可以使用主機名 ALIAS 就可以連接它。
|
||||
|
||||
`--dns=IP_ADDRESS`
|
||||
添加 DNS 服務器到容器的 `/etc/resolv.conf` 中,讓容器用這個服務器來解析所有不在 `/etc/hosts` 中的主機名。
|
||||
新增 DNS 服務器到容器的 `/etc/resolv.conf` 中,讓容器用這個服務器來解析所有不在 `/etc/hosts` 中的主機名。
|
||||
|
||||
`--dns-search=DOMAIN`
|
||||
設定容器的搜索域,當設定搜索域為 `.example.com` 時,在搜索一個名為 host 的主機時,DNS 不僅搜索host,還會搜索 `host.example.com`。
|
||||
|
@@ -1,12 +1,12 @@
|
||||
## 配置 docker0 網橋
|
||||
Docker 服務默認會創建一個 `docker0` 網橋(其上有一個 `docker0` 內部接口),它在內核層連通了其他的物理或虛擬網卡,這就將所有容器和本地主機都放到同一個物理網路。
|
||||
Docker 服務默認會建立一個 `docker0` 網橋(其上有一個 `docker0` 內部接口),它在內核層連通了其他的物理或虛擬網卡,這就將所有容器和本地主機都放到同一個物理網路。
|
||||
|
||||
Docker 默認指定了 `docker0` 接口 的 IP 地址和子網掩碼,讓主機和容器之間可以通過網橋相互通信,它還給出了 MTU(接口允許接收的最大傳輸單元),通常是 1500 Bytes,或宿主主機網路路由上支持的默認值。這些值都可以在服務啟動的時候進行配置。
|
||||
Docker 默認指定了 `docker0` 接口 的 IP 地址和子網掩碼,讓主機和容器之間可以透過網橋相互通信,它還給出了 MTU(接口允許接收的最大傳輸單元),通常是 1500 Bytes,或宿主主機網路路由上支持的默認值。這些值都可以在服務啟動的時候進行配置。
|
||||
* `--bip=CIDR` -- IP 地址加掩碼格式,例如 192.168.1.5/24
|
||||
* `--mtu=BYTES` -- 覆蓋默認的 Docker mtu 配置
|
||||
|
||||
也可以在配置文件中配置 DOCKER_OPTS,然後重啟服務。
|
||||
由於目前 Docker 網橋是 Linux 網橋,用戶可以使用 `brctl show` 來查看網橋和端口連接信息。
|
||||
由於目前 Docker 網橋是 Linux 網橋,使用者可以使用 `brctl show` 來查看網橋和端口連接信息。
|
||||
```
|
||||
$ sudo brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
@@ -16,7 +16,7 @@ docker0 8000.3a1d7362b4ee no veth65f9
|
||||
*註:`brctl` 命令在 Debian、Ubuntu 中可以使用 `sudo apt-get install bridge-utils` 來安裝。
|
||||
|
||||
|
||||
每次創建一個新容器的時候,Docker 從可用的地址段中選擇一個空閑的 IP 地址分配給容器的 eth0 端口。使用本地主機上 `docker0` 接口的 IP 作為所有容器的默認網關。
|
||||
每次建立一個新容器的時候,Docker 從可用的地址段中選擇一個空閑的 IP 地址分配給容器的 eth0 端口。使用本地主機上 `docker0` 接口的 IP 作為所有容器的默認網關。
|
||||
```
|
||||
$ sudo docker run -i -t --rm base /bin/bash
|
||||
$ ip addr show eth0
|
||||
|
@@ -2,7 +2,7 @@
|
||||
在介紹自定義網路拓撲之前,你可能會對一些外部工具和例子感興趣:
|
||||
|
||||
### pipework
|
||||
Jérôme Petazzoni 編寫了一個叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 腳本,可以幫助用戶在比較復雜的場景中完成容器的連接。
|
||||
Jérôme Petazzoni 編寫了一個叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 腳本,可以幫助使用者在比較復雜的場景中完成容器的連接。
|
||||
|
||||
### playground
|
||||
Brandon Rhodes 創建了一個提供完整的 Docker 容器網路拓撲管理的 [Python庫](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墻;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服務器。
|
||||
Brandon Rhodes 建立了一個提供完整的 Docker 容器網路拓撲管理的 [Python庫](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墻;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服務器。
|
||||
|
@@ -1,8 +1,8 @@
|
||||
## 映射容器端口到宿主主機的實現
|
||||
## 映射容器端口到宿主主機的實做
|
||||
|
||||
默認情況下,容器可以主動訪問到外部網路的連接,但是外部網路無法訪問到容器。
|
||||
### 容器訪問外部實現
|
||||
容器所有到外部網路的連接,源地址都會被NAT成本地系統的IP地址。這是使用 `iptables` 的源地址偽裝操作實現的。
|
||||
### 容器訪問外部實做
|
||||
容器所有到外部網路的連接,源地址都會被NAT成本地系統的IP地址。這是使用 `iptables` 的源地址偽裝操作實做的。
|
||||
|
||||
查看主機的 NAT 規則。
|
||||
```
|
||||
@@ -15,11 +15,11 @@ MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16
|
||||
```
|
||||
其中,上述規則將所有源地址在 `172.17.0.0/16` 網段,目標地址為其他網段(外部網路)的流量動態偽裝為從系統網卡發出。MASQUERADE 跟傳統 SNAT 的好處是它能動態從網卡獲取地址。
|
||||
|
||||
### 外部訪問容器實現
|
||||
### 外部訪問容器實做
|
||||
|
||||
容器允許外部訪問,可以在 `docker run` 時候通過 `-p` 或 `-P` 參數來啟用。
|
||||
容器允許外部訪問,可以在 `docker run` 時候透過 `-p` 或 `-P` 參數來啟用。
|
||||
|
||||
不管用那種辦法,其實也是在本地的 `iptable` 的 nat 表中添加相應的規則。
|
||||
不管用那種辦法,其實也是在本地的 `iptable` 的 nat 表中新增相應的規則。
|
||||
|
||||
使用 `-P` 時:
|
||||
```
|
||||
@@ -38,6 +38,6 @@ target prot opt source destination
|
||||
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
|
||||
```
|
||||
註意:
|
||||
* 這裏的規則映射了 0.0.0.0,意味著將接受主機來自所有接口的流量。用戶可以通過 `-p IP:host_port:container_port` 或 `-p
|
||||
* 這裏的規則映射了 0.0.0.0,意味著將接受主機來自所有接口的流量。使用者可以透過 `-p IP:host_port:container_port` 或 `-p
|
||||
IP::port` 來指定允許訪問容器的主機上的 IP、接口等,以制定更嚴格的規則。
|
||||
* 如果希望永久綁定到某個固定的 IP 地址,可以在 Docker 配置文件 `/etc/default/docker` 中指定 `DOCKER_OPTS="--ip=IP_ADDRESS"`,之後重啟 Docker 服務即可生效。
|
||||
|
@@ -1,9 +1,9 @@
|
||||
## 示例:創建一個點到點連接
|
||||
## 示例:建立一個點到點連接
|
||||
默認情況下,Docker 會將所有容器連接到由 `docker0` 提供的虛擬子網中。
|
||||
|
||||
用戶有時候需要兩個容器之間可以直連通信,而不用通過主機網橋進行橋接。
|
||||
使用者有時候需要兩個容器之間可以直連通信,而不用透過主機網橋進行橋接。
|
||||
|
||||
解決辦法很簡單:創建一對 `peer` 接口,分別放到兩個容器中,配置成點到點鏈路類型即可。
|
||||
解決辦法很簡單:建立一對 `peer` 接口,分別放到兩個容器中,配置成點到點鏈路類型即可。
|
||||
|
||||
首先啟動 2 個容器:
|
||||
```
|
||||
@@ -13,7 +13,7 @@ $ sudo docker run -i -t --rm --net=none base /bin/bash
|
||||
root@12e343489d2f:/#
|
||||
```
|
||||
|
||||
找到程序號,然後創建網路名字空間的跟蹤文件。
|
||||
找到程序號,然後建立網路名字空間的跟蹤文件。
|
||||
```
|
||||
$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
|
||||
2989
|
||||
@@ -24,7 +24,7 @@ $ sudo ln -s /proc/2989/ns/net /var/run/netns/2989
|
||||
$ sudo ln -s /proc/3004/ns/net /var/run/netns/3004
|
||||
```
|
||||
|
||||
創建一對 `peer` 接口,然後配置路由
|
||||
建立一對 `peer` 接口,然後配置路由
|
||||
```
|
||||
$ sudo ip link add A type veth peer name B
|
||||
|
||||
@@ -40,6 +40,6 @@ $ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B
|
||||
```
|
||||
現在這 2 個容器就可以相互 ping 通,並成功建立連接。點到點鏈路不需要子網和子網掩碼。
|
||||
|
||||
此外,也可以不指定 `--net=none` 來創建點到點鏈路。這樣容器還可以通過原先的網路來通信。
|
||||
此外,也可以不指定 `--net=none` 來建立點到點鏈路。這樣容器還可以透過原先的網路來通信。
|
||||
|
||||
利用類似的辦法,可以創建一個只跟主機通信的容器。但是一般情況下,更推薦使用 `--icc=false` 來關閉容器之間的通信。
|
||||
利用類似的辦法,可以建立一個只跟主機通信的容器。但是一般情況下,更推薦使用 `--icc=false` 來關閉容器之間的通信。
|
||||
|
@@ -8,7 +8,7 @@
|
||||
* `-H SOCKET... or --host=SOCKET...` --Docker 服務端接收命令的通道
|
||||
* `--icc=true|false` --是否支持容器之間進行通信
|
||||
* `--ip-forward=true|false` --請看下文容器之間的通信
|
||||
* `--iptables=true|false` --禁止 Docker 添加 iptables 規則
|
||||
* `--iptables=true|false` --禁止 Docker 新增 iptables 規則
|
||||
* `--mtu=BYTES` --容器網路中的 MTU
|
||||
|
||||
下面2個命令選項既可以在啟動服務時指定,也可以 Docker 容器啟動(`docker run`)時候指定。在 Docker 服務啟動的時候指定則會成為默認值,後面執行 `docker run` 時可以覆蓋設置的默認值。
|
||||
@@ -17,7 +17,7 @@
|
||||
|
||||
最後這些選項只有在 `docker run` 執行時使用,因為它是針對容器的特性內容。
|
||||
* `-h HOSTNAME or --hostname=HOSTNAME` --配置容器主機名
|
||||
* `--link=CONTAINER_NAME:ALIAS` --添加到另一個容器的連接
|
||||
* `--link=CONTAINER_NAME:ALIAS` --新增到另一個容器的連接
|
||||
* `--net=bridge|none|container:NAME_or_ID|host` --配置容器的橋接模式
|
||||
* `-p SPEC or --publish=SPEC` --映射容器端口到宿主主機
|
||||
* `-P or --publish-all=true|false` --映射容器所有端口到宿主主機
|
||||
|
Reference in New Issue
Block a user