replace '網絡' as '網路'

This commit is contained in:
a504082002
2014-11-20 01:06:47 +08:00
parent d24b44076b
commit 893e0f8bb7
22 changed files with 71 additions and 71 deletions

View File

@@ -6,8 +6,8 @@ Docker 底層的核心技術包括 Linux 上的名字空間Namespaces
這種直接的做法實現了對資源最完整的封裝,但很多時候往往意味著系統資源的浪費。
例如,以宿主機和虛擬機系統都為 Linux 系統為例,虛擬機中執行的應用其實可以利用宿主機系統中的執行環境。
我們知道,在作業系統中,包括內核、文件系統、網、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用程序直接共享的。
要想實現虛擬化除了要實現對內存、CPU、網IO、硬盤IO、存儲空間等的限制外還要實現文件系統、網、PID、UID、IPC等等的相互隔離。
我們知道,在作業系統中,包括內核、文件系統、網、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用程序直接共享的。
要想實現虛擬化除了要實現對內存、CPU、網IO、硬盤IO、存儲空間等的限制外還要實現文件系統、網、PID、UID、IPC等等的相互隔離。
前者相對容易實現一些,後者則需要宿主機系統的深入支持。
隨著 Linux 系統對於名字空間功能的完善實現程序員已經可以實現上面的所有需求讓某些程序在彼此隔離的名字空間中執行。大家雖然都共用一個內核和某些執行時環境例如一些系統命令和系統庫但是彼此卻看不到都以為系統中只有自己的存在。這種機制就是容器Container利用名字空間來做權限的隔離控制利用 cgroups 來做資源分配。

View File

@@ -5,7 +5,7 @@
不同用戶的程序就是通過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 LXC 程序在 Docker 中的父程序為Docker程序每個 LXC 程序具有不同的名字空間。同時由於允許嵌套,因此可以很方便的實現嵌套的 Docker 容器。
### net 名字空間
有了 pid 名字空間, 每個名字空間中的 pid 能夠相互隔離,但是網端口還是共享 host 的端口。網隔離是通過 net 名字空間實現的, 每個 net 名字空間有獨立的 網設備, IP 地址, 路由表, /proc/net 目錄。這樣每個容器的網就能隔離開來。Docker 默認采用 veth 的方式,將容器中的虛擬網卡同 host 上的一 個Docker 網橋 docker0 連接在一起。
有了 pid 名字空間, 每個名字空間中的 pid 能夠相互隔離,但是網端口還是共享 host 的端口。網隔離是通過 net 名字空間實現的, 每個 net 名字空間有獨立的 網設備, IP 地址, 路由表, /proc/net 目錄。這樣每個容器的網就能隔離開來。Docker 默認采用 veth 的方式,將容器中的虛擬網卡同 host 上的一 個Docker 網橋 docker0 連接在一起。
### ipc 名字空間
容器中程序交互還是采用了 Linux 常見的程序間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的程序間交互實際上還是 host 上具有相同 pid 名字空間中的程序間交互,因此需要在 IPC 資源申請時加入名字空間信息,每個 IPC 資源有一個唯一的 32 位 id。
@@ -14,7 +14,7 @@
類似 chroot將一個程序放到一個特定的目錄執行。mnt 名字空間允許不同名字空間的程序看到的文件結構不同,這樣每個名字空間 中的程序所看到的文件目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的信息只包含所在名字空間的 mount point。
### uts 名字空間
UTS("UNIX Time-sharing System") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網上可以被視作一個獨立的節點而非 主機上的一個程序。
UTS("UNIX Time-sharing System") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網上可以被視作一個獨立的節點而非 主機上的一個程序。
### user 名字空間
每個容器可以有不同的用戶和組 id, 也就是說可以在容器內用容器內部的用戶執行程序而非主機上的用戶。

View File

@@ -1,39 +1,39 @@
## Docker 網實現
## Docker 網實現
Docker 的網實現其實就是利用了 Linux 上的網名字空間和虛擬網設備(特別是 veth pair。建議先熟悉了解這兩部分的基本概念再閱讀本章。
Docker 的網實現其實就是利用了 Linux 上的網名字空間和虛擬網設備(特別是 veth pair。建議先熟悉了解這兩部分的基本概念再閱讀本章。
### 基本原理
首先,要實現網通信,機器需要至少一個網接口(物理接口或虛擬接口)來收發數據包;此外,如果不同子網之間要進行通信,需要路由機制。
首先,要實現網通信,機器需要至少一個網接口(物理接口或虛擬接口)來收發數據包;此外,如果不同子網之間要進行通信,需要路由機制。
Docker 中的網接口默認都是虛擬的接口。虛擬接口的優勢之一是轉發效率較高。
Linux 通過在內核中進行數據復制來實現虛擬接口之間的數據轉發,發送接口的發送緩存中的數據包被直接復制到接收接口的接收緩存中。對於本地系統和容器內系統看來就像是一個正常的以太網卡,只是它不需要真正同外部網設備通信,速度要快很多。
Docker 中的網接口默認都是虛擬的接口。虛擬接口的優勢之一是轉發效率較高。
Linux 通過在內核中進行數據復制來實現虛擬接口之間的數據轉發,發送接口的發送緩存中的數據包被直接復制到接收接口的接收緩存中。對於本地系統和容器內系統看來就像是一個正常的以太網卡,只是它不需要真正同外部網設備通信,速度要快很多。
Docker 容器網就利用了這項技術。它在本地主機和容器內分別創建一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做 `veth pair`)。
Docker 容器網就利用了這項技術。它在本地主機和容器內分別創建一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做 `veth pair`)。
### 創建網參數
### 創建網參數
Docker 創建一個容器的時候,會執行如下操作:
* 創建一對虛擬接口,分別放到本地主機和新容器中;
* 本地主機一端橋接到默認的 docker0 或指定網橋上,並具有一個唯一的名字,如 veth65f9
* 容器一端放到新容器中,並修改名字作為 eth0這個接口只在容器的名字空間可見
* 從網橋可用地址段中獲取一個空閑地址分配給容器的 eth0並配置默認路由到橋接網卡 veth65f9。
完成這些之後,容器就可以使用 eth0 虛擬網卡來連接其他容器和其他網
完成這些之後,容器就可以使用 eth0 虛擬網卡來連接其他容器和其他網
可以在 `docker run` 的時候通過 `--net` 參數來指定容器的網配置有4個可選值
可以在 `docker run` 的時候通過 `--net` 參數來指定容器的網配置有4個可選值
* `--net=bridge` 這個是默認值,連接到默認的網橋。
* `--net=host` 告訴 Docker 不要將容器網放到隔離的名字空間中,即不要容器化容器內的網。此時容器使用本地主機的網,它擁有完全的本地主機接口訪問權限。容器程序可以跟主機其它 root 程序一樣可以打開低範圍的端口,可以訪問本地網服務比如 D-bus還可以讓容器做一些影響整個主機系統的事情比如重啟主機。因此使用這個選項的時候要非常小心。如果進一步的使用 `--privileged=true`,容器會被允許直接配置主機的網堆棧。
* `--net=container:NAME_or_ID` 讓 Docker 將新建容器的程序放到一個已存在容器的網棧中,新容器程序有自己的文件系統、程序列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網資源,兩者程序可以直接通過 `lo` 環回接口通信。
* `--net=none` 讓 Docker 將新容器放到隔離的網棧中,但是不進行網配置。之後,用戶可以自己進行配置。
* `--net=host` 告訴 Docker 不要將容器網放到隔離的名字空間中,即不要容器化容器內的網。此時容器使用本地主機的網,它擁有完全的本地主機接口訪問權限。容器程序可以跟主機其它 root 程序一樣可以打開低範圍的端口,可以訪問本地網服務比如 D-bus還可以讓容器做一些影響整個主機系統的事情比如重啟主機。因此使用這個選項的時候要非常小心。如果進一步的使用 `--privileged=true`,容器會被允許直接配置主機的網堆棧。
* `--net=container:NAME_or_ID` 讓 Docker 將新建容器的程序放到一個已存在容器的網棧中,新容器程序有自己的文件系統、程序列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網資源,兩者程序可以直接通過 `lo` 環回接口通信。
* `--net=none` 讓 Docker 將新容器放到隔離的網棧中,但是不進行網配置。之後,用戶可以自己進行配置。
### 網配置細節
用戶使用 `--net=none` 後,可以自行配置網,讓容器達到跟平常一樣具有訪問網的權限。通過這個過程,可以了解 Docker 配置網的細節。
### 網配置細節
用戶使用 `--net=none` 後,可以自行配置網,讓容器達到跟平常一樣具有訪問網的權限。通過這個過程,可以了解 Docker 配置網的細節。
首先,啟動一個 `/bin/bash` 容器,指定 `--net=none` 參數。
```
$ sudo docker run -i -t --rm --net=none base /bin/bash
root@63f36fc01b5f:/#
```
在本地主機查找容器的程序 id並為它創建網命名空間。
在本地主機查找容器的程序 id並為它創建網命名空間。
```
$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
2778
@@ -54,7 +54,7 @@ $ sudo ip link add A type veth peer name B
$ sudo brctl addif docker0 A
$ sudo ip link set A up
```
將B放到容器的網命名空間,命名為 eth0啟動它並配置一個可用 IP橋接網段和默認網關。
將B放到容器的網命名空間,命名為 eth0啟動它並配置一個可用 IP橋接網段和默認網關。
```
$ sudo ip link set B netns $pid
$ sudo ip netns exec $pid ip link set dev B name eth0
@@ -62,8 +62,8 @@ $ 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 配置網的具體過程。
以上,就是 Docker 配置網的具體過程。
當容器結束後Docker 會清空容器,容器內的 eth0 會隨網命名空間一起被清除A 接口也被自動從 `docker0` 卸載。
當容器結束後Docker 會清空容器,容器內的 eth0 會隨網命名空間一起被清除A 接口也被自動從 `docker0` 卸載。
此外,用戶可以使用 `ip netns exec` 命令來在指定網名字空間中進行配置,從而配置容器內的網
此外,用戶可以使用 `ip netns exec` 命令來在指定網名字空間中進行配置,從而配置容器內的網