replace '進程' as '程序'
parent
45acb9c3c3
commit
d24b44076b
|
@ -47,7 +47,7 @@
|
||||||
* [編輯網路配置文件](advanced_network/config_file.md)
|
* [編輯網路配置文件](advanced_network/config_file.md)
|
||||||
* [實例:創造一個點對點連接](advanced_network/ptp.md)
|
* [實例:創造一個點對點連接](advanced_network/ptp.md)
|
||||||
* [實戰案例](cases/README.md)
|
* [實戰案例](cases/README.md)
|
||||||
* [使用 Supervisor 來管理進程](cases/supervisor.md)
|
* [使用 Supervisor 來管理程序](cases/supervisor.md)
|
||||||
* [創建 tomcat/weblogic 集群](cases/tomcat.md)
|
* [創建 tomcat/weblogic 集群](cases/tomcat.md)
|
||||||
* [多台實體主機之間的容器互連](cases/container_connect.md)
|
* [多台實體主機之間的容器互連](cases/container_connect.md)
|
||||||
* [標準化開發測試和生產環境](cases/environment.md)
|
* [標準化開發測試和生產環境](cases/environment.md)
|
||||||
|
|
|
@ -19,7 +19,7 @@ tmpfs on /etc/resolv.conf type tmpfs ...
|
||||||
設定容器的主機名,它會被寫到容器內的 `/etc/hostname` 和 `/etc/hosts`。但它在容器外部看不到,既不會在 `docker ps` 中顯示,也不會在其他的容器的 `/etc/hosts` 看到。
|
設定容器的主機名,它會被寫到容器內的 `/etc/hostname` 和 `/etc/hosts`。但它在容器外部看不到,既不會在 `docker ps` 中顯示,也不會在其他的容器的 `/etc/hosts` 看到。
|
||||||
|
|
||||||
`--link=CONTAINER_NAME:ALIAS`
|
`--link=CONTAINER_NAME:ALIAS`
|
||||||
選項會在創建容器的時候,添加一個其他容器的主機名到 `/etc/hosts` 文件中,讓新容器的進程可以使用主機名 ALIAS 就可以連接它。
|
選項會在創建容器的時候,添加一個其他容器的主機名到 `/etc/hosts` 文件中,讓新容器的程序可以使用主機名 ALIAS 就可以連接它。
|
||||||
|
|
||||||
`--dns=IP_ADDRESS`
|
`--dns=IP_ADDRESS`
|
||||||
添加 DNS 服務器到容器的 `/etc/resolv.conf` 中,讓容器用這個服務器來解析所有不在 `/etc/hosts` 中的主機名。
|
添加 DNS 服務器到容器的 `/etc/resolv.conf` 中,讓容器用這個服務器來解析所有不在 `/etc/hosts` 中的主機名。
|
||||||
|
|
|
@ -13,7 +13,7 @@ $ sudo docker run -i -t --rm --net=none base /bin/bash
|
||||||
root@12e343489d2f:/#
|
root@12e343489d2f:/#
|
||||||
```
|
```
|
||||||
|
|
||||||
找到進程號,然後創建網絡名字空間的跟蹤文件。
|
找到程序號,然後創建網絡名字空間的跟蹤文件。
|
||||||
```
|
```
|
||||||
$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
|
$ sudo docker inspect -f '{{.State.Pid}}' 1f1f4c1f931a
|
||||||
2989
|
2989
|
||||||
|
|
|
@ -95,7 +95,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
|
||||||
顯示一個容器的底層具體信息。
|
顯示一個容器的底層具體信息。
|
||||||
|
|
||||||
docker-kill(1)
|
docker-kill(1)
|
||||||
關閉一個執行中的容器 (包括進程和所有資源)
|
關閉一個執行中的容器 (包括程序和所有資源)
|
||||||
|
|
||||||
docker-load(1)
|
docker-load(1)
|
||||||
從一個 tar 包中加載一個鏡像
|
從一個 tar 包中加載一個鏡像
|
||||||
|
@ -110,7 +110,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
|
||||||
獲取容器的 log 信息
|
獲取容器的 log 信息
|
||||||
|
|
||||||
docker-pause(1)
|
docker-pause(1)
|
||||||
暫停一個容器中的所有進程
|
暫停一個容器中的所有程序
|
||||||
|
|
||||||
docker-port(1)
|
docker-port(1)
|
||||||
查找一個 nat 到一個私有網口的公共口
|
查找一個 nat 到一個私有網口的公共口
|
||||||
|
@ -152,10 +152,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
|
||||||
為一個鏡像打標簽
|
為一個鏡像打標簽
|
||||||
|
|
||||||
docker-top(1)
|
docker-top(1)
|
||||||
查看一個容器中的正在執行的進程信息
|
查看一個容器中的正在執行的程序信息
|
||||||
|
|
||||||
docker-unpause(1)
|
docker-unpause(1)
|
||||||
將一個容器內所有的進程從暫停狀態中恢復
|
將一個容器內所有的程序從暫停狀態中恢復
|
||||||
|
|
||||||
docker-version(1)
|
docker-version(1)
|
||||||
輸出 Docker 的版本信息
|
輸出 Docker 的版本信息
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## 使用 Supervisor 來管理進程
|
## 使用 Supervisor 來管理程序
|
||||||
Docker 容器在啟動的時候開啟單個進程,比如,一個 ssh 或者 apache 的 daemon 服務。但我們經常需要在一個機器上開啟多個服務,這可以有很多方法,最簡單的就是把多個啟動命令方到一個啟動腳本裏面,啟動的時候直接啟動這個腳本,另外就是安裝進程管理工具。
|
Docker 容器在啟動的時候開啟單個程序,比如,一個 ssh 或者 apache 的 daemon 服務。但我們經常需要在一個機器上開啟多個服務,這可以有很多方法,最簡單的就是把多個啟動命令方到一個啟動腳本裏面,啟動的時候直接啟動這個腳本,另外就是安裝程序管理工具。
|
||||||
|
|
||||||
本小節將使用進程管理工具 supervisor 來管理容器中的多個進程。使用 Supervisor 可以更好的控制、管理、重啟我們希望執行的進程。在這裏我們演示一下如何同時使用 ssh 和 apache 服務。
|
本小節將使用程序管理工具 supervisor 來管理容器中的多個程序。使用 Supervisor 可以更好的控制、管理、重啟我們希望執行的程序。在這裏我們演示一下如何同時使用 ssh 和 apache 服務。
|
||||||
|
|
||||||
### 配置
|
### 配置
|
||||||
首先創建一個 Dockerfile,內容和各部分的解釋如下。
|
首先創建一個 Dockerfile,內容和各部分的解釋如下。
|
||||||
|
@ -44,7 +44,7 @@ command=/usr/sbin/sshd -D
|
||||||
[program:apache2]
|
[program:apache2]
|
||||||
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
|
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
|
||||||
```
|
```
|
||||||
配置文件包含目錄和進程,第一段 supervsord 配置軟件本身,使用 nodaemon 參數來執行。第二段包含要控制的 2 個服務。每一段包含一個服務的目錄和啟動這個服務的命令。
|
配置文件包含目錄和程序,第一段 supervsord 配置軟件本身,使用 nodaemon 參數來執行。第二段包含要控制的 2 個服務。每一段包含一個服務的目錄和啟動這個服務的命令。
|
||||||
|
|
||||||
### 使用方法
|
### 使用方法
|
||||||
創建鏡像。
|
創建鏡像。
|
||||||
|
|
|
@ -25,7 +25,7 @@ $ make nsenter && sudo cp nsenter /usr/local/bin
|
||||||
```
|
```
|
||||||
|
|
||||||
#### 使用
|
#### 使用
|
||||||
`nsenter` 可以訪問另一個進程的名字空間。nsenter 要正常工作需要有 root 權限。
|
`nsenter` 可以訪問另一個程序的名字空間。nsenter 要正常工作需要有 root 權限。
|
||||||
很不幸,Ubuntu 14.4 仍然使用的是 util-linux 2.20。安裝最新版本的 util-linux(2.24)版,請按照以下步驟:
|
很不幸,Ubuntu 14.4 仍然使用的是 util-linux 2.20。安裝最新版本的 util-linux(2.24)版,請按照以下步驟:
|
||||||
```
|
```
|
||||||
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz; tar xzvf util-linux-2.24.tar.gz
|
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz; tar xzvf util-linux-2.24.tar.gz
|
||||||
|
@ -33,7 +33,7 @@ $ cd util-linux-2.24
|
||||||
$ ./configure --without-ncurses && make nsenter
|
$ ./configure --without-ncurses && make nsenter
|
||||||
$ sudo cp nsenter /usr/local/bin
|
$ sudo cp nsenter /usr/local/bin
|
||||||
```
|
```
|
||||||
為了連接到容器,你還需要找到容器的第一個進程的 PID,可以通過下面的命令獲取。
|
為了連接到容器,你還需要找到容器的第一個程序的 PID,可以通過下面的命令獲取。
|
||||||
```
|
```
|
||||||
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
|
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
|
||||||
```
|
```
|
||||||
|
|
|
@ -41,7 +41,7 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr
|
||||||
###啟動已終止容器
|
###啟動已終止容器
|
||||||
可以利用 `docker start` 命令,直接將一個已經終止的容器啟動執行。
|
可以利用 `docker start` 命令,直接將一個已經終止的容器啟動執行。
|
||||||
|
|
||||||
容器的核心為所執行的應用程序,所需要的資源都是應用程序執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps` 或 `top` 來查看進程信息。
|
容器的核心為所執行的應用程序,所需要的資源都是應用程序執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps` 或 `top` 來查看程序信息。
|
||||||
```
|
```
|
||||||
root@ba267838cc1b:/# ps
|
root@ba267838cc1b:/# ps
|
||||||
PID TTY TIME CMD
|
PID TTY TIME CMD
|
||||||
|
|
|
@ -99,7 +99,7 @@ Successfully built 324104cde6ad
|
||||||
其中 `-t` 標記來添加 tag,指定新的鏡像的用戶信息。
|
其中 `-t` 標記來添加 tag,指定新的鏡像的用戶信息。
|
||||||
“.” 是 Dockerfile 所在的路徑(當前目錄),也可以替換為一個具體的 Dockerfile 的路徑。
|
“.” 是 Dockerfile 所在的路徑(當前目錄),也可以替換為一個具體的 Dockerfile 的路徑。
|
||||||
|
|
||||||
可以看到 build 進程在執行操作。它要做的第一件事情就是上傳這個 Dockerfile 內容,因為所有的操作都要依據 Dockerfile 來進行。
|
可以看到 build 程序在執行操作。它要做的第一件事情就是上傳這個 Dockerfile 內容,因為所有的操作都要依據 Dockerfile 來進行。
|
||||||
然後,Dockfile 中的指令被一條一條的執行。每一步都創建了一個新的容器,在容器中執行指令並提交修改(就跟之前介紹過的 `docker commit` 一樣)。當所有的指令都執行完畢之後,返回了最終的鏡像 id。所有的中間步驟所產生的容器都被刪除和清理了。
|
然後,Dockfile 中的指令被一條一條的執行。每一步都創建了一個新的容器,在容器中執行指令並提交修改(就跟之前介紹過的 `docker commit` 一樣)。當所有的指令都執行完畢之後,返回了最終的鏡像 id。所有的中間步驟所產生的容器都被刪除和清理了。
|
||||||
|
|
||||||
*註意一個鏡像不能超過 127 層
|
*註意一個鏡像不能超過 127 層
|
||||||
|
|
|
@ -3,6 +3,6 @@
|
||||||
|
|
||||||
它提供了很多有用的特性;以及確保各個容器可以公平地分享主機的內存、CPU、磁盤 IO 等資源;當然,更重要的是,控制組確保了當容器內的資源使用產生壓力時不會連累主機系統。
|
它提供了很多有用的特性;以及確保各個容器可以公平地分享主機的內存、CPU、磁盤 IO 等資源;當然,更重要的是,控制組確保了當容器內的資源使用產生壓力時不會連累主機系統。
|
||||||
|
|
||||||
盡管控制組不負責隔離容器之間相互訪問、處理數據和進程,它在防止拒絕服務(DDOS)攻擊方面是必不可少的。尤其是在多用戶的平臺(比如公有或私有的 PaaS)上,控制組十分重要。例如,當某些應用程序表現異常的時候,可以保證一致地正常執行和性能。
|
盡管控制組不負責隔離容器之間相互訪問、處理數據和程序,它在防止拒絕服務(DDOS)攻擊方面是必不可少的。尤其是在多用戶的平臺(比如公有或私有的 PaaS)上,控制組十分重要。例如,當某些應用程序表現異常的時候,可以保證一致地正常執行和性能。
|
||||||
|
|
||||||
控制組機制始於 2006 年,內核從 2.6.24 版本開始被引入。
|
控制組機制始於 2006 年,內核從 2.6.24 版本開始被引入。
|
||||||
|
|
|
@ -13,6 +13,6 @@
|
||||||
|
|
||||||
終極目標是改進 2 個重要的安全特性:
|
終極目標是改進 2 個重要的安全特性:
|
||||||
* 將容器的 root 用戶映射到本地主機上的非 root 用戶,減輕容器和主機之間因權限提升而引起的安全問題;
|
* 將容器的 root 用戶映射到本地主機上的非 root 用戶,減輕容器和主機之間因權限提升而引起的安全問題;
|
||||||
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子進程來代理執行需要特權權限的操作。這些子進程將只允許在限定範圍內進行操作,例如僅僅負責虛擬網絡設定或文件系統管理、配置操作等。
|
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程序來代理執行需要特權權限的操作。這些子程序將只允許在限定範圍內進行操作,例如僅僅負責虛擬網絡設定或文件系統管理、配置操作等。
|
||||||
|
|
||||||
最後,建議采用專用的服務器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和進程監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
|
最後,建議采用專用的服務器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程序監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
## 內核能力機制
|
## 內核能力機制
|
||||||
|
|
||||||
能力機制(Capability)是 Linux 內核一個強大的特性,可以提供細粒度的權限訪問控制。
|
能力機制(Capability)是 Linux 內核一個強大的特性,可以提供細粒度的權限訪問控制。
|
||||||
Linux 內核自 2.2 版本起就支持能力機制,它將權限劃分為更加細粒度的操作能力,既可以作用在進程上,也可以作用在文件上。
|
Linux 內核自 2.2 版本起就支持能力機制,它將權限劃分為更加細粒度的操作能力,既可以作用在程序上,也可以作用在文件上。
|
||||||
|
|
||||||
例如,一個 Web 服務進程只需要綁定一個低於 1024 的端口的權限,並不需要 root 權限。那麽它只需要被授權 `net_bind_service` 能力即可。此外,還有很多其他的類似能力來避免進程獲取 root 權限。
|
例如,一個 Web 服務程序只需要綁定一個低於 1024 的端口的權限,並不需要 root 權限。那麽它只需要被授權 `net_bind_service` 能力即可。此外,還有很多其他的類似能力來避免程序獲取 root 權限。
|
||||||
|
|
||||||
默認情況下,Docker 啟動的容器被嚴格限制只允許使用內核的一部分能力。
|
默認情況下,Docker 啟動的容器被嚴格限制只允許使用內核的一部分能力。
|
||||||
|
|
||||||
使用能力機制對加強 Docker 容器的安全有很多好處。通常,在服務器上會執行一堆需要特權權限的進程,包括有 ssh、cron、syslogd、硬件管理工具模塊(例如負載模塊)、網絡配置工具等等。容器跟這些進程是不同的,因為幾乎所有的特權進程都由容器以外的支持系統來進行管理。
|
使用能力機制對加強 Docker 容器的安全有很多好處。通常,在服務器上會執行一堆需要特權權限的程序,包括有 ssh、cron、syslogd、硬件管理工具模塊(例如負載模塊)、網絡配置工具等等。容器跟這些程序是不同的,因為幾乎所有的特權程序都由容器以外的支持系統來進行管理。
|
||||||
* ssh 訪問被主機上ssh服務來管理;
|
* ssh 訪問被主機上ssh服務來管理;
|
||||||
* cron 通常應該作為用戶進程執行,權限交給使用它服務的應用來處理;
|
* cron 通常應該作為用戶程序執行,權限交給使用它服務的應用來處理;
|
||||||
* 日誌系統可由 Docker 或第三方服務管理;
|
* 日誌系統可由 Docker 或第三方服務管理;
|
||||||
* 硬件管理無關緊要,容器中也就無需執行 udevd 以及類似服務;
|
* 硬件管理無關緊要,容器中也就無需執行 udevd 以及類似服務;
|
||||||
* 網絡管理也都在主機上設置,除非特殊需求,容器不需要對網絡進行配置。
|
* 網絡管理也都在主機上設置,除非特殊需求,容器不需要對網絡進行配置。
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
## 內核名字空間
|
## 內核名字空間
|
||||||
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。當用 `docker run` 啟動一個容器時,在後臺 Docker 為容器創建了一個獨立的名字空間和控制組集合。
|
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。當用 `docker run` 啟動一個容器時,在後臺 Docker 為容器創建了一個獨立的名字空間和控制組集合。
|
||||||
|
|
||||||
名字空間提供了最基礎也是最直接的隔離,在容器中執行的進程不會被執行在主機上的進程和其它容器發現和作用。
|
名字空間提供了最基礎也是最直接的隔離,在容器中執行的程序不會被執行在主機上的程序和其它容器發現和作用。
|
||||||
|
|
||||||
每個容器都有自己獨有的網絡棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據配置來限制通信的策略)。
|
每個容器都有自己獨有的網絡棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據配置來限制通信的策略)。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
## 總結
|
## 總結
|
||||||
總體來看,Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行進程的話。
|
總體來看,Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程序的話。
|
||||||
|
|
||||||
另外,用戶可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實現更復雜的安全機制。
|
另外,用戶可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實現更復雜的安全機制。
|
||||||
|
|
|
@ -6,8 +6,8 @@ Docker 底層的核心技術包括 Linux 上的名字空間(Namespaces)、
|
||||||
這種直接的做法實現了對資源最完整的封裝,但很多時候往往意味著系統資源的浪費。
|
這種直接的做法實現了對資源最完整的封裝,但很多時候往往意味著系統資源的浪費。
|
||||||
例如,以宿主機和虛擬機系統都為 Linux 系統為例,虛擬機中執行的應用其實可以利用宿主機系統中的執行環境。
|
例如,以宿主機和虛擬機系統都為 Linux 系統為例,虛擬機中執行的應用其實可以利用宿主機系統中的執行環境。
|
||||||
|
|
||||||
我們知道,在作業系統中,包括內核、文件系統、網絡、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用進程直接共享的。
|
我們知道,在作業系統中,包括內核、文件系統、網絡、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用程序直接共享的。
|
||||||
要想實現虛擬化,除了要實現對內存、CPU、網絡IO、硬盤IO、存儲空間等的限制外,還要實現文件系統、網絡、PID、UID、IPC等等的相互隔離。
|
要想實現虛擬化,除了要實現對內存、CPU、網絡IO、硬盤IO、存儲空間等的限制外,還要實現文件系統、網絡、PID、UID、IPC等等的相互隔離。
|
||||||
前者相對容易實現一些,後者則需要宿主機系統的深入支持。
|
前者相對容易實現一些,後者則需要宿主機系統的深入支持。
|
||||||
|
|
||||||
隨著 Linux 系統對於名字空間功能的完善實現,程序員已經可以實現上面的所有需求,讓某些進程在彼此隔離的名字空間中執行。大家雖然都共用一個內核和某些執行時環境(例如一些系統命令和系統庫),但是彼此卻看不到,都以為系統中只有自己的存在。這種機制就是容器(Container),利用名字空間來做權限的隔離控制,利用 cgroups 來做資源分配。
|
隨著 Linux 系統對於名字空間功能的完善實現,程序員已經可以實現上面的所有需求,讓某些程序在彼此隔離的名字空間中執行。大家雖然都共用一個內核和某些執行時環境(例如一些系統命令和系統庫),但是彼此卻看不到,都以為系統中只有自己的存在。這種機制就是容器(Container),利用名字空間來做權限的隔離控制,利用 cgroups 來做資源分配。
|
||||||
|
|
|
@ -2,19 +2,19 @@
|
||||||
名字空間是 Linux 內核一個強大的特性。每個容器都有自己單獨的名字空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名字空間保證了容器之間彼此互不影響。
|
名字空間是 Linux 內核一個強大的特性。每個容器都有自己單獨的名字空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名字空間保證了容器之間彼此互不影響。
|
||||||
|
|
||||||
### pid 名字空間
|
### pid 名字空間
|
||||||
不同用戶的進程就是通過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 LXC 進程在 Docker 中的父進程為Docker進程,每個 LXC 進程具有不同的名字空間。同時由於允許嵌套,因此可以很方便的實現嵌套的 Docker 容器。
|
不同用戶的程序就是通過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 LXC 程序在 Docker 中的父程序為Docker程序,每個 LXC 程序具有不同的名字空間。同時由於允許嵌套,因此可以很方便的實現嵌套的 Docker 容器。
|
||||||
|
|
||||||
### net 名字空間
|
### 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 名字空間
|
### ipc 名字空間
|
||||||
容器中進程交互還是采用了 Linux 常見的進程間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的進程間交互實際上還是 host 上具有相同 pid 名字空間中的進程間交互,因此需要在 IPC 資源申請時加入名字空間信息,每個 IPC 資源有一個唯一的 32 位 id。
|
容器中程序交互還是采用了 Linux 常見的程序間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的程序間交互實際上還是 host 上具有相同 pid 名字空間中的程序間交互,因此需要在 IPC 資源申請時加入名字空間信息,每個 IPC 資源有一個唯一的 32 位 id。
|
||||||
|
|
||||||
### mnt 名字空間
|
### mnt 名字空間
|
||||||
類似 chroot,將一個進程放到一個特定的目錄執行。mnt 名字空間允許不同名字空間的進程看到的文件結構不同,這樣每個名字空間 中的進程所看到的文件目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的信息只包含所在名字空間的 mount point。
|
類似 chroot,將一個程序放到一個特定的目錄執行。mnt 名字空間允許不同名字空間的程序看到的文件結構不同,這樣每個名字空間 中的程序所看到的文件目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的信息只包含所在名字空間的 mount point。
|
||||||
|
|
||||||
### uts 名字空間
|
### uts 名字空間
|
||||||
UTS("UNIX Time-sharing System") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網絡上可以被視作一個獨立的節點而非 主機上的一個進程。
|
UTS("UNIX Time-sharing System") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網絡上可以被視作一個獨立的節點而非 主機上的一個程序。
|
||||||
|
|
||||||
### user 名字空間
|
### user 名字空間
|
||||||
每個容器可以有不同的用戶和組 id, 也就是說可以在容器內用容器內部的用戶執行程序而非主機上的用戶。
|
每個容器可以有不同的用戶和組 id, 也就是說可以在容器內用容器內部的用戶執行程序而非主機上的用戶。
|
||||||
|
|
|
@ -21,8 +21,8 @@ Docker 創建一個容器的時候,會執行如下操作:
|
||||||
|
|
||||||
可以在 `docker run` 的時候通過 `--net` 參數來指定容器的網絡配置,有4個可選值:
|
可以在 `docker run` 的時候通過 `--net` 參數來指定容器的網絡配置,有4個可選值:
|
||||||
* `--net=bridge` 這個是默認值,連接到默認的網橋。
|
* `--net=bridge` 這個是默認值,連接到默認的網橋。
|
||||||
* `--net=host` 告訴 Docker 不要將容器網絡放到隔離的名字空間中,即不要容器化容器內的網絡。此時容器使用本地主機的網絡,它擁有完全的本地主機接口訪問權限。容器進程可以跟主機其它 root 進程一樣可以打開低範圍的端口,可以訪問本地網絡服務比如 D-bus,還可以讓容器做一些影響整個主機系統的事情,比如重啟主機。因此使用這個選項的時候要非常小心。如果進一步的使用 `--privileged=true`,容器會被允許直接配置主機的網絡堆棧。
|
* `--net=host` 告訴 Docker 不要將容器網絡放到隔離的名字空間中,即不要容器化容器內的網絡。此時容器使用本地主機的網絡,它擁有完全的本地主機接口訪問權限。容器程序可以跟主機其它 root 程序一樣可以打開低範圍的端口,可以訪問本地網絡服務比如 D-bus,還可以讓容器做一些影響整個主機系統的事情,比如重啟主機。因此使用這個選項的時候要非常小心。如果進一步的使用 `--privileged=true`,容器會被允許直接配置主機的網絡堆棧。
|
||||||
* `--net=container:NAME_or_ID` 讓 Docker 將新建容器的進程放到一個已存在容器的網絡棧中,新容器進程有自己的文件系統、進程列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網絡資源,兩者進程可以直接通過 `lo` 環回接口通信。
|
* `--net=container:NAME_or_ID` 讓 Docker 將新建容器的程序放到一個已存在容器的網絡棧中,新容器程序有自己的文件系統、程序列表和資源限制,但會和已存在的容器共享 IP 地址和端口等網絡資源,兩者程序可以直接通過 `lo` 環回接口通信。
|
||||||
* `--net=none` 讓 Docker 將新容器放到隔離的網絡棧中,但是不進行網絡配置。之後,用戶可以自己進行配置。
|
* `--net=none` 讓 Docker 將新容器放到隔離的網絡棧中,但是不進行網絡配置。之後,用戶可以自己進行配置。
|
||||||
|
|
||||||
### 網絡配置細節
|
### 網絡配置細節
|
||||||
|
@ -33,7 +33,7 @@ Docker 創建一個容器的時候,會執行如下操作:
|
||||||
$ sudo docker run -i -t --rm --net=none base /bin/bash
|
$ sudo docker run -i -t --rm --net=none base /bin/bash
|
||||||
root@63f36fc01b5f:/#
|
root@63f36fc01b5f:/#
|
||||||
```
|
```
|
||||||
在本地主機查找容器的進程 id,並為它創建網絡命名空間。
|
在本地主機查找容器的程序 id,並為它創建網絡命名空間。
|
||||||
```
|
```
|
||||||
$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
|
$ sudo docker inspect -f '{{.State.Pid}}' 63f36fc01b5f
|
||||||
2778
|
2778
|
||||||
|
|
Loading…
Reference in New Issue