Merge pull request #19 from ensky/fix-cntw

修正多個用詞
This commit is contained in:
philipz 2014-11-24 23:06:32 +08:00
commit 51c7819ce1
71 changed files with 407 additions and 407 deletions

View File

@ -3,21 +3,21 @@ Docker —— 從入門到實踐
v0.2.9
[Docker](docker.com) 是個偉大的項目,它徹底釋放了虛擬化的,讓應用程式的分派、部署和管理都變得前所未有的高效和輕鬆!
[Docker](docker.com) 是個偉大的項目,它徹底釋放了虛擬化的,讓應用程式的分派、部署和管理都變得前所未有的有效率和輕鬆!
本書既適用於具備基礎 Linux 知識的 Docker 初學者,也可供希望理解原理和實現的進階用戶參考。同時,書中給出的實踐案例,可供在進行實際部署時借鑒。
本書既適用於具備基礎 Linux 知識的 Docker 初學者,也可供希望理解原理和實做的進階使用者參考。同時,書中給出的實踐案例,可供在進行實際部署時借鑒。
本書源於 [WaitFish](github.com/qcpm1983) 的《[Docker 學習手冊 v1.0](https://github.com/yeasy/docker_practice/raw/master/_local/docker_manual_waitfish.pdf)》內容。後來,[yeasy](github.com/yeasy)
根據最新 Docker 版本對內容進行了修訂和重寫,並增加內容;經協商將所有內容開源,採用互聯網合作的方式進行維護。
根據最新 Docker 版本對內容進行了修訂和重寫,並增加內容;經協商將所有內容開源,採用網合作的方式進行維護。
前六章為基礎內容,供使用者理解 Docker 的基本概念和操作7 ~ 9 章介紹一些高級操作;第 10 章給出典型的應用場景和實踐案例11 ~ 13 章介紹關於 Docker 實現的相關技術。
前六章為基礎內容,供使用者理解 Docker 的基本概念和操作7 ~ 9 章介紹一些進階操作;第 10 章給出典型的應用場景和實踐案例11 ~ 13 章介紹關於 Docker 實做的相關技術。
最新版本線上閱讀:[體版](https://www.gitbook.io/book/philipzheng/docker_practice)、[簡體版](https://www.gitbook.io/book/yeasy/docker_practice) 或 [DockerPool](http://dockerpool.com/static/books/docker_practice/index.html)。
最新版本線上閱讀:[體版](https://www.gitbook.io/book/philipzheng/docker_practice)、[簡體版](https://www.gitbook.io/book/yeasy/docker_practice) 或 [DockerPool](http://dockerpool.com/static/books/docker_practice/index.html)。
另外,歡迎加入 [Docker.Taipei](https://www.facebook.com/groups/docker.taipei/) 和 [Meetup](http://www.meetup.com/Docker-Taipei/) ,分享 Docker 資源,交流 Docker 技術。
本書碼在 Github 上維護,歡迎參與: [https://github.com/philipz/docker_practice](https://github.com/philipz/docker_practice)。
本書原始碼在 Github 上維護,歡迎參與: [https://github.com/philipz/docker_practice](https://github.com/philipz/docker_practice)。
感謝所有的 [貢獻者](https://github.com/philipz/docker_practice/graphs/contributors)。
@ -25,17 +25,17 @@ v0.2.9
* 0.3: 2014-10-TODO
* 完成倉庫章節;
* 重寫安全章節;
* 修正底層實章節的架構、名字空間、控制組、檔案系統、容器格式等內容;
* 添加對常見倉庫和鏡像的介紹;
* 添加 Dockerfile 的介紹;
* 修正底層實章節的架構、名字空間、控制組、檔案系統、容器格式等內容;
* 新增對常見倉庫和鏡像的介紹;
* 新增 Dockerfile 的介紹;
* 重新校訂中英文混排格式。
* 0.2: 2014-09-18
* 對照官方文檔重寫介紹、基本概念、安裝、鏡像、容器、倉庫、資料管理、網路等章節;
* 添加底層實現章節;
* 添加命令查詢和資源連結章節;
* 新增底層實做章節;
* 新增命令查詢和資源連結章節;
* 其它修正。
* 0.1: 2014-09-05
* 添加基本內容;
* 新增基本內容;
* 修正錯別字和表達不通順的地方。
## 貢獻力量
@ -77,9 +77,9 @@ v0.2.9
1. 首先 fork 我的項目
2. 把 fork 過去的項目也就是你的項目 clone 到你的本地
3. 在命令行執行 `git branch develop`建一個新分支
3. 在命令行執行 `git branch develop` 來建一個新分支
4. 執行 `git checkout develop` 來切換到新分支
5. 執行 `git remote add upstream https://github.com/philipz/docker_practice` 把我的庫添加為遠端庫
5. 執行 `git remote add upstream https://github.com/philipz/docker_practice` 把我的庫新增為遠端庫
6. 執行 `git remote update`更新
7. 執行 `git fetch upstream master` 拉取我的庫的更新到本地
8. 執行 `git rebase upstream/master` 將我的更新合並到你的分支

View File

@ -12,12 +12,12 @@
* [Ubuntu](install/ubuntu.md)
* [CentOS](install/centos.md)
* [映像檔](image/README.md)
* [取映像檔](image/pull.md)
* [映像檔](image/pull.md)
* [列出](image/list.md)
* [建](image/create.md)
* [](image/create.md)
* [存出和載入](image/save_load.md)
* [移除](image/rmi.md)
* [原理](image/internal.md)
* [原理](image/internal.md)
* [容器](container/README.md)
* [啟動](container/run.md)
* [守護態執行](container/daemon.md)
@ -28,7 +28,7 @@
* [倉庫](repository/README.md)
* [Docker Hub](repository/dockerhub.md)
* [私有倉庫](repository/local_repo.md)
* [配置文件](repository/config.md)
* [設定文件](repository/config.md)
* [數據管理](data_management/README.md)
* [數據卷](data_management/volume.md)
* [數據卷容器](data_management/container.md)
@ -36,19 +36,19 @@
* [使用網路](network/README.md)
* [外部訪問容器](network/port_mapping.md)
* [容器互連](network/linking.md)
* [高級網路配置](advanced_network/README.md)
* [快速配置指南](advanced_network/quick_guide.md)
* [配置 DNS](advanced_network/dns.md)
* [進階網路設定](advanced_network/README.md)
* [快速設定指南](advanced_network/quick_guide.md)
* [設定 DNS](advanced_network/dns.md)
* [容器訪問控制](advanced_network/access_control.md)
* [端口映射實](advanced_network/port_mapping.md)
* [配置 docker0 網橋](advanced_network/docker0.md)
* [端口映射實](advanced_network/port_mapping.md)
* [設定 docker0 網橋](advanced_network/docker0.md)
* [自定義網橋](advanced_network/bridge.md)
* [工具與範例](advanced_network/example.md)
* [編輯網路配置文件](advanced_network/config_file.md)
* [編輯網路設定文件](advanced_network/config_file.md)
* [實例:創造一個點對點連接](advanced_network/ptp.md)
* [實戰案例](cases/README.md)
* [使用 Supervisor 來管理程](cases/supervisor.md)
* [建 tomcat/weblogic 集群](cases/tomcat.md)
* [使用 Supervisor 來管理程](cases/supervisor.md)
* [ tomcat/weblogic 集群](cases/tomcat.md)
* [多台實體主機之間的容器互連](cases/container_connect.md)
* [標準化開發測試和生產環境](cases/environment.md)
* [安全](security/README.md)
@ -62,7 +62,7 @@
* [基本結構](dockerfile/basic_structure.md)
* [指令](dockerfile/instructions.md)
* [建立映像檔](dockerfile/build_image.md)
* [底層實](underly/README.md)
* [底層實](underly/README.md)
* [基本架構](underly/arch.md)
* [命名空間](underly/namespace.md)
* [控制組](underly/cgroups.md)

View File

@ -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 網路](../_images/network.png)
接下來的部分將介紹在一些場景中Docker 所有的網路自訂配置。以及通過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路配置
接下來的部分將介紹在一些場景中Docker 所有的網路自訂設定。以及透過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路設定

View File

@ -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` 來禁止它。
可見,默認情況下,不同容器之間是允許網路互通的。如果為了安全考慮,可以在 `/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
...

View File

@ -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
@ -31,4 +31,4 @@ $ sudo service docker start
啟動 Docker 服務。
新建一個容器,可以看到它已經橋接到了 `bridge0` 上。
可以繼續用 `brctl show` 命令查看橋接的息。另外,在容器中可以使用 `ip addr``ip route` 命令來查看 IP 地址配置和路由信息。
可以繼續用 `brctl show` 命令查看橋接的息。另外,在容器中可以使用 `ip addr``ip route` 命令來查看 IP 地址設定和路由訊息。

View File

@ -1,5 +1,5 @@
## 編輯網路配置文件
## 編輯網路設定文件
Docker 1.2.0 開始支持在執行中的容器編輯 `/etc/hosts`, `/etc/hostname``/etc/resolve.conf` 文件。
Docker 1.2.0 開始支持在執行中的容器編輯 `/etc/hosts`, `/etc/hostname``/etc/resolve.conf` 文件。
但是這些修改是臨時的,只在執行的容器中保留,容器終止或重啟後並不會被保存下來。也不會被 `docker commit` 提交。

View File

@ -1,8 +1,8 @@
## 配置 DNS
Docker 沒有為每個容器專門定制鏡像,那麽怎麽自定義配置容器的主機名和 DNS 配置呢?
秘訣就是它利用虛擬文件來掛載到來容器的 3 個相關配置文件。
## 設定 DNS
Docker 沒有為每個容器專門定制鏡像,那麽怎麽自定義設定容器的主機名和 DNS 設定呢?
秘訣就是它利用虛擬文件來掛載到來容器的 3 個相關設定文件。
在容器中使用 mount 命令可以看到掛載息:
在容器中使用 mount 命令可以看到掛載息:
```
$ mount
...
@ -11,19 +11,19 @@ $ 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`
註意:如果沒有上述最後 2 個選項Docker 會默認用主機上的 `/etc/resolv.conf`配置容器。
註意:如果沒有上述最後 2 個選項Docker 會默認用主機上的 `/etc/resolv.conf`設定容器。

View File

@ -1,12 +1,12 @@
## 配置 docker0 網橋
Docker 服務默認會建一個 `docker0` 網橋(其上有一個 `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 配置
* `--mtu=BYTES` -- 覆蓋默認的 Docker mtu 設定
也可以在配置文件中配置 DOCKER_OPTS然後重啟服務。
由於目前 Docker 網橋是 Linux 網橋,用戶可以使用 `brctl show` 來查看網橋和端口連接信息。
也可以在設定文件中設定 DOCKER_OPTS然後重啟服務。
由於目前 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

View File

@ -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 的服器。

View File

@ -1,8 +1,8 @@
## 映射容器端口到宿主主機的實
## 映射容器端口到宿主主機的實
默認情況下,容器可以主動訪問到外部網路的連接,但是外部網路無法訪問到容器。
### 容器訪問外部實
容器所有到外部網路的連接源地址都會被NAT成本地系統的IP地址。這是使用 `iptables` 的源地址偽裝操作實的。
### 容器訪問外部實
容器所有到外部網路的連接源地址都會被NAT成本地系統的IP地址。這是使用 `iptables` 的源地址偽裝操作實的。
查看主機的 NAT 規則。
```
@ -13,13 +13,13 @@ target prot opt source destination
MASQUERADE all -- 172.17.0.0/16 !172.17.0.0/16
...
```
其中,上述規則將所有源地址在 `172.17.0.0/16` 網段目標地址為其他網段外部網路的流量動態偽裝為從系統網卡發出。MASQUERADE 跟傳統 SNAT 的好處是它能動態從網卡取地址。
其中,上述規則將所有源地址在 `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 服務即可生效。
* 如果希望永久綁定到某個固定的 IP 地址,可以在 Docker 設定文件 `/etc/default/docker` 中指定 `DOCKER_OPTS="--ip=IP_ADDRESS"`,之後重啟 Docker 服務即可生效。

View File

@ -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` 來關閉容器之間的通信。

View File

@ -1,23 +1,23 @@
## 快速配置指南
## 快速設定指南
下面是一個跟 Docker 網路相關的命令列表。
其中有些命令選項只有在 Docker 服務啟動的時候才能配置,而且不能馬上生效。
其中有些命令選項只有在 Docker 服務啟動的時候才能設定,而且不能馬上生效。
* `-b BRIDGE or --bridge=BRIDGE` --指定容器掛載的網橋
* `--bip=CIDR` --定制 docker0 的掩碼
* `-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` 時可以覆蓋設置的默認值。
* `--dns=IP_ADDRESS...` --使用指定的DNS服
* `--dns=IP_ADDRESS...` --使用指定的DNS服器
* `--dns-search=DOMAIN...` --指定DNS搜索域
最後這些選項只有在 `docker run` 執行時使用,因為它是針對容器的特性內容。
* `-h HOSTNAME or --hostname=HOSTNAME` --配置容器主機名
* `--link=CONTAINER_NAME:ALIAS` --添加到另一個容器的連接
* `--net=bridge|none|container:NAME_or_ID|host` --配置容器的橋接模式
* `-h HOSTNAME or --hostname=HOSTNAME` --設定容器主機名
* `--link=CONTAINER_NAME:ALIAS` --新增到另一個容器的連接
* `--net=bridge|none|container:NAME_or_ID|host` --設定容器的橋接模式
* `-p SPEC or --publish=SPEC` --映射容器端口到宿主主機
* `-P or --publish-all=true|false` --映射容器所有端口到宿主主機

View File

@ -2,7 +2,7 @@
##基本語法
docker [OPTIONS] COMMAND [arg...]
一般來說Docker 命令可以用來管理 daemon或者通過 CLI 命令管理映像檔和容器。可以通`man docker` 來查看這些命令。
一般來說Docker 命令可以用來管理 daemon或者透過 CLI 命令管理映像檔和容器。可以透`man docker` 來查看這些命令。
##選項
@ -10,7 +10,7 @@
使用 debug 模式。預設為 false。
-H, --host=[unix:///var/run/docker.sock]: tcp://[host:port]來綁定或者 unix://[/path/to/socket] 來使用。
在 daemon 模式下綁定的 socket過一個或多個 tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd 來指定。
在 daemon 模式下綁定的 socket過一個或多個 tcp://host:port, unix:///path/to/socket, fd://* or fd://socketfd 來指定。
--api-enable-cors=true|false
在遠端 API 中啟用 CORS 頭。預設為 false。
@ -19,7 +19,7 @@
將容器掛載到一個已存在的網橋上。指定為 'none' 時則禁用容器的網路。
--bip=""
讓動態建的 docker0 采用指定的 CIDR 地址; 與 -b 選項互斥。
讓動態建的 docker0 采用指定的 CIDR 地址; 與 -b 選項互斥。
-d=true|false
使用 daemon 模式。預設為 false。
@ -37,7 +37,7 @@
綁定端口時候的預設 IP 地址。預設為 0.0.0.0。
--iptables=true|false
禁止 Docker 添加 iptables 規則。預設為 true。
禁止 Docker 新增 iptables 規則。預設為 true。
--mtu=VALUE
指定容器網路的 mtu。預設為 1500。
@ -62,10 +62,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
依附到一個正在執行的容器中。
docker-build(1)
從一個 Dockerfile 建一個映像檔
從一個 Dockerfile 建一個映像檔
docker-commit(1)
從一個容器的修改中建一個新的映像檔
從一個容器的修改中建一個新的映像檔
docker-cp(1)
從容器中複製文件到宿主系統中
@ -74,7 +74,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
檢查一個容器文件系統的修改
docker-events(1)
從服務端取實時的事件
從服務端取實時的事件
docker-export(1)
匯出容器內容為一個 tar 包
@ -86,7 +86,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
列出存在的映像檔
docker-import(1)
匯入一個文件(典型為 tar 包)路徑或目錄來建一個映像檔
匯入一個文件(典型為 tar 包)路徑或目錄來建一個映像檔
docker-info(1)
顯示一些相關的系統資訊
@ -95,10 +95,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
顯示一個容器的底層具體資訊。
docker-kill(1)
關閉一個執行中的容器 (包括程和所有資源)
關閉一個執行中的容器 (包括程和所有資源)
docker-load(1)
從一個 tar 包中載一個映像檔
從一個 tar 包中載一個映像檔
docker-login(1)
註冊或登錄到一個 Docker 的倉庫伺服器
@ -107,10 +107,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
從 Docker 的倉庫伺服器登出
docker-logs(1)
取容器的 log 資訊
容器的 log 資訊
docker-pause(1)
暫停一個容器中的所有程
暫停一個容器中的所有程
docker-port(1)
查找一個 nat 到一個私有網口的公共口
@ -134,7 +134,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
刪除指定的數個映像檔
docker-run(1)
建一個新容器,並在其中執行指定命令
一個新容器,並在其中執行指定命令
docker-save(1)
保存一個映像檔為 tar 包文件
@ -152,10 +152,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
為一個映像檔打標簽
docker-top(1)
查看一個容器中的正在執行的程資訊
查看一個容器中的正在執行的程資訊
docker-unpause(1)
將一個容器內所有的程從暫停狀態中恢復
將一個容器內所有的程從暫停狀態中恢復
docker-version(1)
輸出 Docker 的版本資訊

View File

@ -1,6 +1,6 @@
## [CentOS](https://registry.hub.docker.com/_/centos/)
### 基本
### 基本
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 發行版,其軟件包大多跟 RedHat 系列保持一致。
該倉庫提供了 CentOS 從 5 ~ 7 各個版本的鏡像。

View File

@ -1,7 +1,7 @@
## [MongoDB](https://registry.hub.docker.com/_/mongo/)
### 基本
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是開源的 NoSQL 數據庫實
### 基本
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是開源的 NoSQL 數據庫實
該倉庫提供了 MongoDB 2.2 ~ 2.7 各個版本的鏡像。
### 使用方法
@ -14,7 +14,7 @@ $ sudo docker run --name some-mongo -d mongo
```
$ sudo docker run --name some-app --link some-mongo:mongo -d application-that-uses-mongo
```
或者`mongo`
或者`mongo`
```
$ sudo docker run -it --link some-mongo:mongo --rm mongo sh -c 'exec mongo "$MONGO_PORT_27017_TCP_ADDR:$MONGO_PORT_27017_TCP_PORT/test"'
```

View File

@ -1,7 +1,7 @@
## [MySQL](https://registry.hub.docker.com/_/mysql/)
### 基本
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是開源的關系數據庫實
### 基本
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是開源的關系數據庫實
該倉庫提供了 MySQL 各個版本的鏡像,包括 5.6 系列、5.7 系列等。
### 使用方法
@ -13,7 +13,7 @@ $ sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d m
```
$ sudo docker run --name some-app --link some-mysql:mysql -d application-that-uses-mysql
```
或者`mysql`
或者`mysql`
```
$ sudo docker run -it --link some-mysql:mysql --rm mysql sh -c 'exec mysql -h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'
```

View File

@ -1,15 +1,15 @@
## [Nginx](https://registry.hub.docker.com/_/nginx/)
### 基本
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是開源的高效的 Web 服務器實現,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等協議。
### 基本
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是開源的有效率的 Web 伺服器實做,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等協議。
該倉庫提供了 Nginx 1.0 ~ 1.7 各個版本的鏡像。
### 使用方法
下面的命令將作為一個靜態頁面服器啟動。
下面的命令將作為一個靜態頁面服器啟動。
```
$ sudo docker run --name some-nginx -v /some/content:/usr/share/nginx/html:ro -d nginx
```
用戶也可以不使用這種映射方式,通過利用 Dockerfile 來直接將靜態頁面內容放到鏡像中,內容為
使用者也可以不使用這種映射方式,透過利用 Dockerfile 來直接將靜態頁面內容放到鏡像中,內容為
```
FROM nginx
COPY static-html-directory /usr/share/nginx/html
@ -24,11 +24,11 @@ $ sudo docker run --name some-nginx -d some-content-nginx
sudo docker run --name some-nginx -d -p 8080:80 some-content-nginx
```
Nginx的默認配置文件路徑為 `/etc/nginx/nginx.conf`,可以通過映射它來使用本地的配置文件,例如
Nginx的默認設定文件路徑為 `/etc/nginx/nginx.conf`,可以透過映射它來使用本地的設定文件,例如
```
docker run --name some-nginx -v /some/nginx.conf:/etc/nginx/nginx.conf:ro -d nginx
```
使用配置文件時,為了在容器中正常執行,需要保持 `daemon off;`
使用設定文件時,為了在容器中正常執行,需要保持 `daemon off;`
### Dockerfile
* [1 ~ 1.7 版本](https://github.com/nginxinc/docker-nginx/blob/3713a0157083eb4776e71f5a5aef4b2a5bc03ab1/Dockerfile)

View File

@ -1,17 +1,17 @@
## [Node.js](https://registry.hub.docker.com/_/node/)
### 基本
### 基本
[Node.js](https://en.wikipedia.org/wiki/Node.js)是基於 JavaScript 的可擴展服務端和網路軟件開發平臺。
該倉庫提供了 Node.js 0.8 ~ 0.11 各個版本的鏡像。
### 使用方法
在項目中建一個 Dockerfile。
在項目中建一個 Dockerfile。
```
FROM node:0.10-onbuild
# replace this with your application's default port
EXPOSE 8888
```
然後建鏡像,並啟動容器
然後建鏡像,並啟動容器
```
$ sudo docker build -t my-nodejs-app
$ sudo docker run -it --rm --name my-running-app my-nodejs-app

View File

@ -1,7 +1,7 @@
## [Redis](https://registry.hub.docker.com/_/redis/)
### 基本
[Redis](https://en.wikipedia.org/wiki/Redis) 是開源的內存 Key-Value 數據庫實
### 基本
[Redis](https://en.wikipedia.org/wiki/Redis) 是開源的內存 Key-Value 數據庫實
該倉庫提供了 Redis 2.6 ~ 2.8.9 各個版本的鏡像。
### 使用方法
@ -19,7 +19,7 @@ $ sudo docker run --name some-redis -d redis redis-server --appendonly yes
```
$ sudo docker run --name some-app --link some-redis:redis -d application-that-uses-redis
```
或者`redis-cli`
或者`redis-cli`
```
$ sudo docker run -it --link some-redis:redis --rm redis sh -c 'exec redis-cli -h "$REDIS_PORT_6379_TCP_ADDR" -p "$REDIS_PORT_6379_TCP_PORT"'
```

View File

@ -1,6 +1,6 @@
## [Ubuntu](https://registry.hub.docker.com/_/ubuntu/)
### 基本
### 基本
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 發行版,其自帶軟件版本往往較新一些。
該倉庫提供了 Ubuntu從12.04 ~ 14.10 各個版本的鏡像。

View File

@ -1,6 +1,6 @@
## [WordPress](https://registry.hub.docker.com/_/wordpress/)
### 基本
### 基本
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是開源的 Blog 和內容管理系統框架,它基於 PhP 和 MySQL。
該倉庫提供了 WordPress 4.0 版本的鏡像。

View File

@ -1,8 +1,8 @@
## Docker 容器
Docker 利用容器來執行應用。
容器是從映像檔建的執行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。
容器是從映像檔建的執行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。
可以把容器看做是一個簡易版的 Linux 環境包括root用戶權限、程序空間、用戶空間和網路空間等)和在其中執行的應用程序
可以把容器看做是一個簡易版的 Linux 環境包括root使用者權限、程式空間、使用者空間和網路空間等)和在其中執行的應用程式
*註:映像檔是唯讀的,容器在啟動的時候建一層可寫層作為最上層。
*註:映像檔是唯讀的,容器在啟動的時候建一層可寫層作為最上層。

View File

@ -1,8 +1,8 @@
## Docker 映像檔
Docker 映像檔就是一個唯讀的模板。
例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或用戶需要的其它應用程序
例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或使用者需要的其它應用程式
映像檔可以用來建 Docker 容器。
映像檔可以用來建 Docker 容器。
Docker 提供了一個很簡單的機制來創建映像檔或者更新現有的映像檔,用戶甚至可以直接從其他人那裡下載一個已經做好的映像檔來直接使用。
Docker 提供了一個很簡單的機制來建立映像檔或者更新現有的映像檔,使用者甚至可以直接從其他人那裡下載一個已經做好的映像檔來直接使用。

View File

@ -1,14 +1,14 @@
## Docker 倉庫
倉庫是集中存放映像檔文件的場所。有時候會把倉庫和倉庫註冊服Registry混為一談並不嚴格區分。實際上倉庫註冊服器上往往存放著多個倉庫每個倉庫中又包含了多個映像檔每個鏡像有不同的標籤tag
倉庫是集中存放映像檔文件的場所。有時候會把倉庫和倉庫註冊服器Registry混為一談並不嚴格區分。實際上倉庫註冊服器上往往存放著多個倉庫每個倉庫中又包含了多個映像檔每個鏡像有不同的標籤tag
倉庫分為公開倉庫Public和私有倉庫Private兩種形式。
最大的公開倉庫是 [Docker Hub](https://hub.docker.com),存放了數量龐大的映像檔供用戶下載。
大陸的公開倉庫包括 [Docker Pool](http://www.dockerpool.com) 等,可以提供大陸用戶更穩定快速的訪問。
最大的公開倉庫是 [Docker Hub](https://hub.docker.com),存放了數量龐大的映像檔供使用者下載。
大陸的公開倉庫包括 [Docker Pool](http://www.dockerpool.com) 等,可以提供大陸使用者更穩定快速的訪問。
當然,用戶也可以在本地網路內創建一個私有倉庫。
當然,使用者也可以在本地網路內建立一個私有倉庫。
用戶創建了自己的映像檔之後就可以使用 `push` 命令將它上傳到公有或者私有倉庫,這樣下次在另外一台機器上使用這個映像檔時候,只需要從倉庫上 `pull` 下來就可以了。
使用者建立了自己的映像檔之後就可以使用 `push` 命令將它上傳到公有或者私有倉庫,這樣下次在另外一台機器上使用這個映像檔時候,只需要從倉庫上 `pull` 下來就可以了。
*註Docker 倉庫的概念跟 [Git](http://git-scm.com) 類似,註冊服器可以理解為 GitHub 這樣的託管服務。
*註Docker 倉庫的概念跟 [Git](http://git-scm.com) 類似,註冊服器可以理解為 GitHub 這樣的託管服務。

View File

@ -1,5 +1,5 @@
## 多臺物理主機之間的容器互聯(暴露容器到真實網路中)
Docker 默認的橋接網卡是 docker0。它只會在本機橋接所有的容器網卡舉例來說容器的虛擬網卡在主機上看一般叫做 veth*** 而 Docker 只是把所有這些網卡橋接在一起,下:
Docker 默認的橋接網卡是 docker0。它只會在本機橋接所有的容器網卡舉例來說容器的虛擬網卡在主機上看一般叫做 veth*** 而 Docker 只是把所有這些網卡橋接在一起,下:
```
[root@opnvz ~]# brctl show
bridge name bridge id STP enabled interfaces
@ -23,7 +23,7 @@ root@ac6474aeb31d:~# ip a
inet6 fe80::487d:68ff:feda:9cf/64 scope link
valid_lft forever preferred_lft forever
```
這樣就可以把這個網路看成是一個私有的網路,過 nat 連接外網,如果要讓外網連接到容器中,就需要做端口映射,即 -p 參數。
這樣就可以把這個網路看成是一個私有的網路,過 nat 連接外網,如果要讓外網連接到容器中,就需要做端口映射,即 -p 參數。
如果在企業內部應用,或者做多個物理主機的集群,可能需要將多個物理主機的容器組到一個物理網路中來,那麽就需要將這個網橋橋接到我們指定的網卡上。
@ -32,8 +32,8 @@ root@ac6474aeb31d:~# ip a
![物理拓撲圖](../_images/container_connect_topology.png)
### ubuntu 示例
下面以 ubuntu 為例建多個主機的容器聯網:
建自己的網橋,編輯 /etc/network/interface 文件
下面以 ubuntu 為例建多個主機的容器聯網:
自己的網橋,編輯 /etc/network/interface 文件
```
auto br0
iface br0 inet static
@ -46,7 +46,7 @@ dns-nameservers 8.8.8.8 192.168.6.1
```
將 Docker 的默認網橋綁定到這個新建的 br0 上面,這樣就將這臺機器上容器綁定到 em1 這個網卡所對應的物理網路上了。
ubuntu 修改 /etc/default/docker 文件,添加最後一行內容
ubuntu 修改 /etc/default/docker 文件,新增最後一行內容
```
# Docker Upstart and SysVinit configuration file
@ -75,4 +75,4 @@ bridge name bridge id STP enabled interfaces
br0 8000.7e6e617c8d53 no em1
vethe6e5
```
這樣就直接把容器暴露到物理網路上了,多臺物理主機的容器也可以相互聯網了。需要註意的是,這樣就需要自己來保證容器的網路安全了。
這樣就直接把容器暴露到物理網路上了,多臺物理主機的容器也可以相網了。需要註意的是,這樣就需要自己來保證容器的網路安全了。

View File

@ -7,8 +7,8 @@
![企業應用結構](../_images/enterprise_usage.png)
Docker 占用資源小,在一臺 E5 128 G 內存的服器上部署 100 個容器都綽綽有余,可以單獨抽一個容器或者直接在宿主物理主機上部署 samba利用 samba 的 home 分享方案將每個用戶的 home 目錄映射到開發中心和測試部門的 Windows 機器上。
Docker 占用資源小,在一臺 E5 128 G 內存的服器上部署 100 個容器都綽綽有余,可以單獨抽一個容器或者直接在宿主物理主機上部署 samba利用 samba 的 home 分享方案將每個使用者的 home 目錄映射到開發中心和測試部門的 Windows 機器上。
針對某個項目組,由架構師搭建好一個標準的容器環境供項目組和測試部門使用,每個開發工程師可以擁有自己單獨的容器,通過 `docker run -v` 將用戶的 home 目錄映射到容器中。需要提交測試時,只需要將代碼移交給測試部門,然後分配一個容器使用 `-v` 載測試部門的 home 目錄啟動即可。這樣,在公司內部的開發、測試基本就統一了,不會出現開發部門提交的代碼,測試部門部署不了的問題。
針對某個項目組,由架構師搭建好一個標準的容器環境供項目組和測試部門使用,每個開發工程師可以擁有自己單獨的容器,透過 `docker run -v` 將使用者的 home 目錄映射到容器中。需要提交測試時,只需要將代碼移交給測試部門,然後分配一個容器使用 `-v`測試部門的 home 目錄啟動即可。這樣,在公司內部的開發、測試基本就統一了,不會出現開發部門提交的代碼,測試部門部署不了的問題。
測試部門發布測試過的報告後,架構師再一次檢測容器環境,就可以直接交由部署工程師將代碼和容器分別部署到生產環境中了。這種方式的部署橫向能的擴展性也極好。
測試部門發布測試過的報告後,架構師再一次檢測容器環境,就可以直接交由部署工程師將代碼和容器分別部署到生產環境中了。這種方式的部署橫向能的擴展性也極好。

View File

@ -1,10 +1,10 @@
## 使用 Supervisor 來管理程
Docker 容器在啟動的時候開啟單個程,比如,一個 ssh 或者 apache 的 daemon 服務。但我們經常需要在一個機器上開啟多個服務,這可以有很多方法,最簡單的就是把多個啟動命令方到一個啟動腳本裏面,啟動的時候直接啟動這個腳本,另外就是安裝程序管理工具。
## 使用 Supervisor 來管理程
Docker 容器在啟動的時候開啟單個程,比如,一個 ssh 或者 apache 的 daemon 服務。但我們經常需要在一個機器上開啟多個服務,這可以有很多方法,最簡單的就是把多個啟動命令方到一個啟動腳本裡面,啟動的時候直接啟動這個腳本,另外就是安裝程式管理工具。
本小節將使用程序管理工具 supervisor 來管理容器中的多個程序。使用 Supervisor 可以更好的控制、管理、重啟我們希望執行的程序。在這裏我們演示一下如何同時使用 ssh 和 apache 服務。
本小節將使用程式管理工具 supervisor 來管理容器中的多個程式。使用 Supervisor 可以更好的控制、管理、重啟我們希望執行的程式。在這裡我們演示一下如何同時使用 ssh 和 apache 服務。
### 配置
首先創建一個 Dockerfile內容和各部分的解釋如下。
### 設定
首先建立一個 Dockerfile內容和各部分的解釋以下。
```
FROM ubuntu:13.04
MAINTAINER examples@docker.com
@ -21,20 +21,20 @@ RUN mkdir -p /var/run/sshd
RUN mkdir -p /var/log/supervisor
```
裏安裝 3 個軟件,還創建了 2 個 ssh 和 supervisor 服務正常執行所需要的目錄。
裡安裝 3 個軟件,還建立了 2 個 ssh 和 supervisor 服務正常執行所需要的目錄。
```
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
```
添加 supervisord 的配置文件,並復制配置文件到對應目錄下面。
新增 supervisord 的設定文件,並復制設定文件到對應目錄下面。
```
EXPOSE 22 80
CMD ["/usr/bin/supervisord"]
```
我們映射了 22 和 80 端口,使用 supervisord 的可執行路徑啟動服務。
我們映射了 22 和 80 端口,使用 supervisord 的可執行路徑啟動服務。
### supervisor配置文件內容
### supervisor設定文件內容
```
[supervisord]
nodaemon=true
@ -44,10 +44,10 @@ command=/usr/sbin/sshd -D
[program:apache2]
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
```
配置文件包含目錄和程序,第一段 supervsord 配置軟件本身,使用 nodaemon 參數來執行。第二段包含要控制的 2 個服務。每一段包含一個服務的目錄和啟動這個服務的命令。
設定文件包含目錄和程式,第一段 supervsord 設定軟件本身,使用 nodaemon 參數來執行。第二段包含要控制的 2 個服務。每一段包含一個服務的目錄和啟動這個服務的命令。
### 使用方法
建鏡像。
鏡像。
```
$ sudo docker build -t test/supervisord .
```
@ -60,6 +60,6 @@ $ sudo docker run -p 22 -p 80 -t -i test/supervisords
2013-11-25 18:53:23,346 INFO spawned: 'sshd' with pid 6
2013-11-25 18:53:23,349 INFO spawned: 'apache2' with pid 7
```
使用 `docker run` 來啟動我們建的容器。使用多個 `-p` 來映射多個端口,這樣我們就能同時訪問 ssh 和 apache 服務了。
使用 `docker run` 來啟動我們建的容器。使用多個 `-p` 來映射多個端口,這樣我們就能同時訪問 ssh 和 apache 服務了。
可以使用這個方法建一個只有 ssh 服務的基礎鏡像,之後建鏡像可以使用這個鏡像為基礎來
可以使用這個方法建一個只有 ssh 服務的基礎鏡像,之後建鏡像可以使用這個鏡像為基礎來建

View File

@ -1,11 +1,11 @@
## 建 tomcat/weblogic 集群
## 建 tomcat/weblogic 集群
### 安裝 tomcat 鏡像
準備好需要的 jdk、tomcat 等軟件放到 home 目錄下面,啟動一個容器
```
docker run -t -i -v /home:/opt/data --name mk_tomcat ubuntu /bin/bash
```
這條命令掛載本地 home 目錄到容器的 /opt/data 目錄,容器內目錄若不存在,則會自動創建。接下來就是 tomcat 的基本配置jdk 環境變量設置好之後,將 tomcat 程序放到 /opt/apache-tomcat 下面
編輯 /etc/supervisor/conf.d/supervisor.conf 文件,添加 tomcat 項
這條命令掛載本地 home 目錄到容器的 /opt/data 目錄,容器內目錄若不存在,則會自動建立。接下來就是 tomcat 的基本設定jdk 環境變量設置好之後,將 tomcat 程式放到 /opt/apache-tomcat 下面
編輯 /etc/supervisor/conf.d/supervisor.conf 文件,新增 tomcat 項
```
[supervisord]
nodaemon=true
@ -24,13 +24,13 @@ FROM mk_tomcat
EXPOSE 22 8080
CMD ["/usr/bin/supervisord"]
```
根據 Dockerfile 建鏡像。
根據 Dockerfile 建鏡像。
```
docker build tomcat tomcat
```
### 安裝 weblogic 鏡像
步驟和 tomcat 基本一致,這裏貼一下配置文件
步驟和 tomcat 基本一致,這裡貼一下設定文件
```
supervisor.conf
[supervisord]
@ -54,9 +54,9 @@ CMD ["/usr/bin/supervisord"]
-v, --volume=[] Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)
將本地磁盤映射到容器內部,它在主機和容器之間是實時變化的,所以我們更新程、上傳代碼只需要更新物理主機的目錄就可以了
將本地磁盤映射到容器內部,它在主機和容器之間是實時變化的,所以我們更新程、上傳代碼只需要更新物理主機的目錄就可以了
#### tomcat 和 weblogic 集群的實
#### tomcat 和 weblogic 集群的實
tomcat 只要開啟多個容器即可
```
docker run -d -v -p 204:22 -p 7003:8080 -v /home/data:/opt/data --name tm1 tomcat /usr/bin/supervisord
@ -64,18 +64,18 @@ docker run -d -v -p 205:22 -p 7004:8080 -v /home/data:/opt/data --name tm2 tomca
docker run -d -v -p 206:22 -p 7005:8080 -v /home/data:/opt/data --name tm3 tomcat /usr/bin/supervisord
```
裏說一下 weblogic 的配置,大家知道 weblogic 有一個域的概念。如果要使用常規的 administrator +node 的方式部署,就需要在 supervisord 中分別寫出 administartor server 和 node server 的啟動腳本,這樣做的優點是:
裡說一下 weblogic 的設定,大家知道 weblogic 有一個域的概念。如果要使用常規的 administrator +node 的方式部署,就需要在 supervisord 中分別寫出 administartor server 和 node server 的啟動腳本,這樣做的優點是:
* 可以使用 weblogic 的集群,同步等概念
* 部署一個集群應用程,只需要安裝一次應用到集群上即可
* 部署一個集群應用程,只需要安裝一次應用到集群上即可
缺點是:
* Docker 配置復雜了
* 沒辦法自動擴展集群的計算容量,如需添加節點,需要在 administrator 上先創建節點,然後再配置新的容器 supervisor 啟動腳本,然後再啟動容器
另外種方法是將所有的程都安裝在 adminiserver 上面,需要擴展的時候,啟動多個節點即可,它的優點和缺點和上一種方法恰恰相反。(建議使用這種方式來部署開發和測試環境)
* Docker 設定復雜了
* 沒辦法自動擴展集群的計算容量,如需新增節點,需要在 administrator 上先建立節點,然後再設定新的容器 supervisor 啟動腳本,然後再啟動容器
另外種方法是將所有的程都安裝在 adminiserver 上面,需要擴展的時候,啟動多個節點即可,它的優點和缺點和上一種方法恰恰相反。(建議使用這種方式來部署開發和測試環境)
```
docker run -d -v -p 204:22 -p 7001:7001 -v /home/data:/opt/data --name node1 weblogic /usr/bin/supervisord
docker run -d -v -p 205:22 -p 7002:7001 -v /home/data:/opt/data --name node2 weblogic /usr/bin/supervisord
docker run -d -v -p 206:22 -p 7003:7001 -v /home/data:/opt/data --name node3 weblogic /usr/bin/supervisord
```
這樣在前端使用 nginx 來做負載均衡就可以完成配置
這樣在前端使用 nginx 來做負載均衡就可以完成設定

View File

@ -3,4 +3,4 @@
簡單的說,容器是獨立執行的一個或一組應用,以及它們的執行態環境。換句話說,虛擬機可以理解為模擬執行的一整套作業系統(提供了執行態環境和其他系統環境)和跑在上面的應用。
本章將具體介紹如何來管理一個容器,包括建、啟動和停止等。
本章將具體介紹如何來管理一個容器,包括建、啟動和停止等。

View File

@ -1,20 +1,20 @@
##守護態執行
更多的時候,需要讓 Docker 容器在後臺以守護態Daemonized形式執行。此時可以通過添加 `-d` 參數來實現
更多的時候,需要讓 Docker 容器在後臺以守護態Daemonized形式執行。此時可以透過新增 `-d` 參數來實做
下面的命令會在後臺執行容器。
下面的命令會在後臺執行容器。
```
$ sudo docker run -d ubuntu:14.04 /bin/sh -c "while true; do echo hello world; sleep 1; done"
1e5535038e285177d5214659a068137486f96ee5c2e85a4ac52dc83f2ebe4147
```
容器啟動後會返回一個唯一的 id也可以通過 `docker ps` 命令來查看容器信息。
容器啟動後會返回一個唯一的 id也可以透過 `docker ps` 命令來查看容器訊息。
```
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
1e5535038e28 ubuntu:14.04 /bin/sh -c 'while tr 2 minutes ago Up 1 minute insane_babbage
```
獲取容器的輸出信息,可以通`docker logs` 命令。
取得容器的輸出訊息,可以透`docker logs` 命令。
```
$ sudo docker logs insane_babbage
hello world

View File

@ -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-linux2.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
@ -33,11 +33,11 @@ $ cd util-linux-2.24
$ ./configure --without-ncurses && make nsenter
$ sudo cp nsenter /usr/local/bin
```
為了連接到容器,你還需要找到容器的第一個程序的 PID可以通過下面的命令獲取
為了連接到容器,你還需要找到容器的第一個程式的 PID可以透過下面的命令取得
```
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
```
過這個 PID就可以連接到這個容器
過這個 PID就可以連接到這個容器
```
$ nsenter --target $PID --mount --uts --ipc --net --pid
```
@ -59,7 +59,7 @@ root@243c32535da7:/#
$ wget -P ~ https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker;
$ echo "[ -f ~/.bashrc_docker ] && . ~/.bashrc_docker" >> ~/.bashrc; source ~/.bashrc
```
這個文件中定義了很多方便使用 Docker 的命令,例如 `docker-pid` 可以取某個容器的 PID`docker-enter` 可以進入容器或直接在容器內執行命令。
這個文件中定義了很多方便使用 Docker 的命令,例如 `docker-pid` 可以取某個容器的 PID`docker-enter` 可以進入容器或直接在容器內執行命令。
```
$ echo $(docker-pid <container>)
$ docker-enter <container> ls

View File

@ -18,11 +18,11 @@ $ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
test/ubuntu v1.0 9d37a6082e97 About a minute ago 171.3 MB
```
此外,也可以過指定 URL 或者某個目錄來導入,例如
此外,也可以過指定 URL 或者某個目錄來導入,例如
```
$sudo docker import http://example.com/exampleimage.tgz example/imagerepo
```
*註:用戶既可以使用 `docker load` 來導入映像檔儲存文件到本地映像檔庫,也可以使用 `docker import` 來導入一個容器快照到本地映像檔庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和原始數據息(即僅保存容器當時的快照狀態),而映像檔儲存文件將保存完整記錄,檔案體積也跟著變大。此外,從容器快照文件導入時可以重新指定標簽等原始數據息。
*註:使用者既可以使用 `docker load` 來導入映像檔儲存文件到本地映像檔庫,也可以使用 `docker import` 來導入一個容器快照到本地映像檔庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和原始數據息(即僅保存容器當時的快照狀態),而映像檔儲存文件將保存完整記錄,檔案體積也跟著變大。此外,從容器快照文件導入時可以重新指定標簽等原始數據息。

View File

@ -5,5 +5,5 @@
$sudo docker rm trusting_newton
trusting_newton
```
如果要刪除一個執行中的容器,可以添加 `-f` 參數。Docker 會發送 `SIGKILL` 信號給容器。
如果要刪除一個執行中的容器,可以新增 `-f` 參數。Docker 會發送 `SIGKILL` 信號給容器。

View File

@ -1,7 +1,7 @@
##啟動容器
啟動容器有兩種方式一種是將映像檔新建一個容器並啟動另外一個是將終止狀態stopped的容器重新啟動。
因為 Docker 的容器實在太輕量級了,用戶可以隨時刪除和新創建容器。
因為 Docker 的容器實在太輕量級了,使用者可以隨時刪除和新建立容器。
###新建並啟動
所需要的命令主要為 `docker run`
@ -13,14 +13,14 @@ Hello world
```
這跟在本地直接執行 `/bin/echo 'hello world'` 相同, 幾乎感覺不出任何區別。
下面的命令則啟動一個 bash 終端,允許用戶進行交互。
下面的命令則啟動一個 bash 終端,允許使用者進行交互。
```
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
root@af8bae53bdd3:/#
```
其中,`-t` 選項讓Docker分配一個虛擬終端pseudo-tty並綁定到容器的標準輸入上 `-i` 則讓容器的標準輸入保持打開。
在交互模式下,用戶可以通過所創建的終端來輸入命令,例如
在交互模式下,使用者可以透過所建立的終端來輸入命令,例如
```
root@af8bae53bdd3:/# pwd
/
@ -28,24 +28,24 @@ root@af8bae53bdd3:/# ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
```
當利用 `docker run`建容器時Docker 在後臺執行的標準操作包括:
當利用 `docker run` 來建容器時Docker 在後臺執行的標準操作包括:
* 檢查本地是否存在指定的映像檔,不存在就從公有倉庫下載
* 利用映像檔建並啟動一個容器
* 利用映像檔建並啟動一個容器
* 分配一個文件系統,並在唯讀的映像檔層外面掛載一層可讀寫層
* 從宿主主機配置的網路橋接口中橋接一個虛擬埠到容器中去
* 從地址堆中配置一個 ip 地址給容器
* 執行用戶指定的應用程序
* 從宿主主機設定的網路橋接口中橋接一個虛擬埠到容器中去
* 從地址堆中設定一個 ip 地址給容器
* 執行使用者指定的應用程式
* 執行完畢後容器被終止
###啟動已終止容器
可以利用 `docker start` 命令,直接將一個已經終止的容器啟動執行。
容器的核心為所執行的應用程序,所需要的資源都是應用程序執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps``top` 來查看程序信息。
容器的核心為所執行的應用程式,所需要的資源都是應用程式執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps``top` 來查看程式訊息。
```
root@ba267838cc1b:/# ps
PID TTY TIME CMD
1 ? 00:00:00 bash
11 ? 00:00:00 ps
```
可見,容器中僅執行了指定的 bash 應用。這種特點使得 Docker 對資源的用率極高,是貨真價實的輕量級虛擬化。
可見,容器中僅執行了指定的 bash 應用。這種特點使得 Docker 對資源的使用率極高,是貨真價實的輕量級虛擬化。

View File

@ -2,7 +2,7 @@
可以使用 `docker stop` 來終止一個執行中的容器。
此外當Docker容器中指定的應用終結時容器也自動終止。
例如對於上一章節中只啟動了一個終端機的容器,用戶通`exit` 命令或 `Ctrl+d` 來退出終端時,所建的容器立刻終止。
例如對於上一章節中只啟動了一個終端機的容器,使用者透`exit` 命令或 `Ctrl+d` 來退出終端時,所建的容器立刻終止。
終止狀態的容器可以用 `docker ps -a` 命令看到。例如
```
@ -12,6 +12,6 @@ ba267838cc1b ubuntu:14.04 "/bin/bash" 30 minutes a
98e5efa7d997 training/webapp:latest "python app.py" About an hour ago Exited (0) 34 minutes ago backstabbing_pike
```
處於終止狀態的容器,可以`docker start` 命令來重新啟動。
處於終止狀態的容器,可以`docker start` 命令來重新啟動。
此外,`docker restart` 命令會將一個執行中的容器終止,然後再重新啟動它。

View File

@ -1,9 +1,9 @@
## 數據卷容器
如果你有一些持續更新的數據需要在容器之間共享,最好建數據卷容器。
如果你有一些持續更新的數據需要在容器之間共享,最好建數據卷容器。
數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。
首先,建一個命名的數據卷容器 dbdata
首先,建一個命名的數據卷容器 dbdata
```
$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
```
@ -20,4 +20,4 @@ $ sudo docker run -d --name db3 --volumes-from db1 training/postgres
*註意:使用 `--volumes-from` 參數所掛載數據卷的容器自己並不需要保持在執行狀態。
如果刪除了掛載的容器(包括 dbdata、db1 和 db2數據卷並不會被自動刪除。如果要刪除一個數據卷必須在刪除最後一個還掛載著它的容器時使用 `docker rm -v` 命令來指定同時刪除關聯的容器。
這可以讓用戶在容器之間升級和移動數據卷。具體的操作將在下一節中進行講解。
這可以讓使用者在容器之間升級和移動數據卷。具體的操作將在下一節中進行講解。

View File

@ -2,7 +2,7 @@
可以利用數據卷對其中的數據進行進行備份、恢復和遷移。
### 備份
首先使用 `--volumes-from` 標記來建一個載 dbdata 容器卷的容器,並從本地主機掛載當前到容器的 /backup 目錄。命令下:
首先使用 `--volumes-from` 標記來建一個載 dbdata 容器卷的容器,並從本地主機掛載當前到容器的 /backup 目錄。命令下:
```
$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
```
@ -10,11 +10,11 @@ $ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup
### 恢復
如果要恢復數據到一個容器,首先建一個帶有數據卷的容器 dbdata2。
如果要恢復數據到一個容器,首先建一個帶有數據卷的容器 dbdata2。
```
$ sudo docker run -v /dbdata --name dbdata2 ubuntu /bin/bash
```
然後建另一個容器,掛載 dbdata2 的容器,並使用 `untar` 解壓備份文件到掛載的容器卷中。
然後建另一個容器,掛載 dbdata2 的容器,並使用 `untar` 解壓備份文件到掛載的容器卷中。
```
$ sudo docker run --volumes-from dbdata2 -v $(pwd):/backup busybox tar xvf
/backup/backup.tar

View File

@ -8,26 +8,26 @@
*數據卷的使用,類似於 Linux 下對目錄或文件進行 mount。
### 建一個數據卷
在用 `docker run` 命令的時候,使用 `-v` 標記來創建一個數據卷並掛載到容器裏。在一次 run 中多次使用可以掛載多個數據卷。
### 建一個數據卷
在用 `docker run` 命令的時候,使用 `-v` 標記來建立一個數據卷並掛載到容器裡。在一次 run 中多次使用可以掛載多個數據卷。
下面建一個 web 容器,並載一個數據卷到容器的 `/webapp` 目錄。
下面建一個 web 容器,並載一個數據卷到容器的 `/webapp` 目錄。
```
$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py
```
*註意:也可以在 Dockerfile 中使用 `VOLUME`添加一個或者多個新的卷到由該鏡像創建的任意容器。
*註意:也可以在 Dockerfile 中使用 `VOLUME`新增一個或者多個新的卷到由該鏡像建立的任意容器。
### 掛載一個主機目錄作為數據卷
使用 `-v` 標記也可以指定掛載一個本地主機的目錄到容器中去。
```
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
```
上面的命令載主機的 `/src/webapp` 目錄到容器的 `/opt/webapp`
目錄。這個功能在進行測試的時候十分方便,比如用戶可以放置一些程序到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動為你建它。
上面的命令載主機的 `/src/webapp` 目錄到容器的 `/opt/webapp`
目錄。這個功能在進行測試的時候十分方便,比如使用者可以放置一些程式到本地目錄中,來查看容器是否正常工作。本地目錄的路徑必須是絕對路徑,如果目錄不存在 Docker 會自動為你建它。
*註意Dockerfile 中不支持這種用法,這是因為 Dockerfile 是為了移植和分享用的。然而,不同作業系統的路徑格式不一樣,所以目前還不能支持。
Docker 掛載數據卷的默認權限是讀寫,用戶也可以通`:ro` 指定為唯讀。
Docker 掛載數據卷的默認權限是讀寫,使用者也可以透`:ro` 指定為唯讀。
```
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
training/webapp python app.py
@ -42,4 +42,4 @@ $ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
這樣就可以記錄在容器輸入過的命令了。
*註意:如果直接掛載一個文件,很多文件編輯工具,包括 `vi` 或者 `sed --in-place`,可能會造成文件 inode 的改變,從 Docker 1.1
.0起,這會導致報錯誤息。所以最簡單的辦法就直接掛載文件的父目錄。
.0起,這會導致報錯誤息。所以最簡單的辦法就直接掛載文件的父目錄。

View File

@ -1,5 +1,5 @@
## 基本結構
Dockerfile 由一行行命令語句組成,並且支援以 `#` 開頭的註行。
Dockerfile 由一行行命令語句組成,並且支援以 `#` 開頭的註行。
一般而言Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時執行指令。

View File

@ -1,7 +1,7 @@
## 建立映像檔
編輯完成 Dockerfile 之後,可以透過 `docker build` 命令建立映像檔。
基本的格式為 `docekr build [選項] 路徑`,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile並將該路徑下所有內容發送給 Docker 伺服端,由伺服端來建鏡像。因此一般會建議放置 Dockerfile 的目錄為空目錄。也可以透過 `.dockerignore` 文件(每一行添加一條排除模式exclusion patterns來讓 Docker 忽略路徑下的目錄和文件。
基本的格式為 `docekr build [選項] 路徑`,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile並將該路徑下所有內容發送給 Docker 伺服端,由伺服端來建鏡像。因此一般會建議放置 Dockerfile 的目錄為空目錄。也可以透過 `.dockerignore` 文件(每一行新增一條排除模式exclusion patterns來讓 Docker 忽略路徑下的目錄和文件。
要指定鏡像的標籤資訊,可以透過 `-t` 選項,例如
```

View File

@ -7,12 +7,12 @@
第一條指令必須為 `FROM` 指令。並且如果在同一個Dockerfile中建立多個映像檔時可以使用多個 `FROM` 指令(每個映像檔一次)。
### MAINTAINER
格式為 `MAINTAINER <name>`,指定維護者息。
格式為 `MAINTAINER <name>`,指定維護者息。
### RUN
格式為 `RUN <command>``RUN ["executable", "param1", "param2"]`
前者將在 shell 終端中運行命令,即 `/bin/sh -c`;後者則使用 `exec` 執行。指定使用其它終端可以通過第二種方式實現,例如 `RUN ["/bin/bash", "-c", "echo hello"]`
前者將在 shell 終端中運行命令,即 `/bin/sh -c`;後者則使用 `exec` 執行。指定使用其它終端可以透過第二種方式實做,例如 `RUN ["/bin/bash", "-c", "echo hello"]`
每條 `RUN` 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以使用 `\` 來換行。
@ -30,7 +30,7 @@
### EXPOSE
格式為 `EXPOSE <port> [<port>...]`
設定 Docker 伺服器容器對外的埠號,供外界使用。在啟動容器時需要過 -PDocker 會自動分配一個埠號轉發到指定的埠號。
設定 Docker 伺服器容器對外的埠號,供外界使用。在啟動容器時需要過 -PDocker 會自動分配一個埠號轉發到指定的埠號。
### ENV
格式為 `ENV <key> <value>`
@ -76,7 +76,7 @@ ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
指定運行容器時的使用者名稱或 UID後續的 `RUN` 也會使用指定使用者。
當服務不需要管理員權限時,可以過該命令指定運行使用者。並且可以在之前建立所需要的使用者,例如:`RUN groupadd -r postgres && useradd -r -g postgres postgres`。要臨時取管理員權限可以使用 `gosu`,而不推薦 `sudo`
當服務不需要管理員權限時,可以過該命令指定運行使用者。並且可以在之前建立所需要的使用者,例如:`RUN groupadd -r postgres && useradd -r -g postgres postgres`。要臨時取管理員權限可以使用 `gosu`,而不推薦 `sudo`
### WORKDIR
格式為 `WORKDIR /path/to/workdir`
@ -97,7 +97,7 @@ RUN pwd
指定當建立的映像檔作為其它新建立映像檔的基底映像檔時,所執行的操作指令。
例如Dockerfile 使用下的內容建立了映像檔 `image-A`
例如Dockerfile 使用下的內容建立了映像檔 `image-A`
```
[...]
ONBUILD ADD . /app/src
@ -105,7 +105,7 @@ ONBUILD RUN /usr/local/bin/python-build --dir /app/src
[...]
```
如果基於 image-A 建立新的映像檔時,新的 Dockerfile 中使用 `FROM image-A`指定基底映像檔時,會自動執行 `ONBUILD` 指令內容,等於在後面添加了兩條指令。
如果基於 image-A 建立新的映像檔時,新的 Dockerfile 中使用 `FROM image-A`指定基底映像檔時,會自動執行 `ONBUILD` 指令內容,等於在後面新增了兩條指令。
```
FROM image-A

View File

@ -2,9 +2,9 @@
在之前的介紹中,我們知道鏡像是 Docker 的三大組件之一。
Docker 在執行容器前需要本地存在對應的鏡像如果鏡像不存在本地Docker 會從鏡像倉庫下載(預設是 Docker Hub 公共註冊服器中的倉庫)。
Docker 在執行容器前需要本地存在對應的鏡像如果鏡像不存在本地Docker 會從鏡像倉庫下載(預設是 Docker Hub 公共註冊服器中的倉庫)。
本章將介紹更多關於鏡像的內容,包括:
* 從倉庫取鏡像;
* 從倉庫取鏡像;
* 管理本地主機上的鏡像;
* 介紹鏡像實的基本原理。
* 介紹鏡像實的基本原理。

View File

@ -1,6 +1,6 @@
##建鏡像
##建鏡像
創建鏡像有很多方法,用戶可以從 Docker Hub 獲取已有鏡像並更新,也可以利用本地文件系統建一個。
建立鏡像有很多方法,使用者可以從 Docker Hub 取得已有鏡像並更新,也可以利用本地文件系統建一個。
### 修改已有鏡像
先使用下載的鏡像啟動容器。
@ -10,7 +10,7 @@ root@0b2616b0e5a8:/#
```
註意:記住容器的 ID稍後還會用到。
在容器中添加 json 和 gem 兩個應用。
在容器中新增 json 和 gem 兩個應用。
```
root@0b2616b0e5a8:/# gem install json
```
@ -19,10 +19,10 @@ root@0b2616b0e5a8:/# gem install json
$ sudo docker commit -m "Added json gem" -a "Docker Newbee" 0b2616b0e5a8 ouruser/sinatra:v2
4f177bd27a9ff0f6dc2a830403925b5360bfe0b93d476f7fc3231110e7f71b1c
```
其中,`-m` 來指定提交的說明信息,跟我們使用的版本控制工具一樣;`-a` 可以指定更新的用戶信息;之後是用來創建鏡像的容器的 ID最後指定目標鏡像的倉庫名和 tag 信息。創建成功後會返回這個鏡像的 ID 信息。
其中,`-m` 來指定提交的說明訊息,跟我們使用的版本控制工具一樣;`-a` 可以指定更新的使用者訊息;之後是用來建立鏡像的容器的 ID最後指定目標鏡像的倉庫名和 tag 訊息。建立成功後會返回這個鏡像的 ID 訊息。
使用 `docker images` 來查看新建的鏡像。
使用 `docker images` 來查看新建的鏡像。
```
$ sudo docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
@ -36,8 +36,8 @@ $ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@78e82f680994:/#
```
###利用 Dockerfile 來建鏡像
使用 `docker commit` 來擴展一個鏡像比較簡單,但是不方便在一個團隊中分享。我們可以使用 `docker build`建一個新的鏡像。為此,首先需要建一個 Dockerfile包含一些如何建鏡像的指令。
###利用 Dockerfile 來建鏡像
使用 `docker commit` 來擴展一個鏡像比較簡單,但是不方便在一個團隊中分享。我們可以使用 `docker build` 來建一個新的鏡像。為此,首先需要建一個 Dockerfile包含一些如何建鏡像的指令。
新建一個目錄和一個 Dockerfile
```
@ -45,7 +45,7 @@ $ mkdir sinatra
$ cd sinatra
$ touch Dockerfile
```
Dockerfile 中每一條指令都建鏡像的一層,例如:
Dockerfile 中每一條指令都建鏡像的一層,例如:
```
# This is a comment
FROM ubuntu:14.04
@ -55,10 +55,10 @@ RUN apt-get -qqy install ruby ruby-dev
RUN gem install sinatra
```
Dockerfile 基本的語法是
* 使用`#`來註
* 使用`#`來註
* `FROM` 指令告訴 Docker 使用哪個鏡像作為基礎
* 接著是維護者的
* `RUN`開頭的指令會在創建中執行,比如安裝一個軟件包,在這裏使用 apt-get 來安裝了一些軟件
* 接著是維護者的
* `RUN`開頭的指令會在建立中執行,比如安裝一個軟件包,在這裡使用 apt-get 來安裝了一些軟件
編寫完成 Dockerfile 後可以使用 `docker build` 來生成鏡像。
@ -96,15 +96,15 @@ Successfully installed sinatra-1.4.5
Removing intermediate container 5e9d0065c1f7
Successfully built 324104cde6ad
```
其中 `-t` 標記來添加 tag指定新的鏡像的用戶信息。
其中 `-t` 標記來新增 tag指定新的鏡像的使用者訊息。
“.” 是 Dockerfile 所在的路徑(當前目錄),也可以替換為一個具體的 Dockerfile 的路徑。
可以看到 build 程在執行操作。它要做的第一件事情就是上傳這個 Dockerfile 內容,因為所有的操作都要依據 Dockerfile 來進行。
然後Dockfile 中的指令被一條一條的執行。每一步都建了一個新的容器,在容器中執行指令並提交修改(就跟之前介紹過的 `docker commit` 一樣)。當所有的指令都執行完畢之後,返回了最終的鏡像 id。所有的中間步驟所產生的容器都被刪除和清理了。
可以看到 build 程在執行操作。它要做的第一件事情就是上傳這個 Dockerfile 內容,因為所有的操作都要依據 Dockerfile 來進行。
然後Dockfile 中的指令被一條一條的執行。每一步都建了一個新的容器,在容器中執行指令並提交修改(就跟之前介紹過的 `docker commit` 一樣)。當所有的指令都執行完畢之後,返回了最終的鏡像 id。所有的中間步驟所產生的容器都被刪除和清理了。
*註意一個鏡像不能超過 127 層
此外,還可以利用 `ADD` 命令復制本地文件到鏡像;用 `EXPOSE` 命令來向外部開放端口;用 `CMD` 命令來描述容器啟動後執行的程等。例如
此外,還可以利用 `ADD` 命令復制本地文件到鏡像;用 `EXPOSE` 命令來向外部開放端口;用 `CMD` 命令來描述容器啟動後執行的程等。例如
```
# put my local web site in myApp folder to /var/www
ADD myApp /var/www
@ -114,7 +114,7 @@ EXPOSE 80
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
```
現在可以利用新建的鏡像來啟動一個容器。
現在可以利用新建的鏡像來啟動一個容器。
```
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
root@8196968dac35:/#
@ -132,7 +132,7 @@ ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
*註:更多用法,請參考 [Dockerfile](../dockerfile/README.md) 章節。
### 從本地文件系統導入
要從本地文件系統導入一個鏡像,可以使用 openvz容器虛擬化的先鋒技術的模板來建:
要從本地文件系統導入一個鏡像,可以使用 openvz容器虛擬化的先鋒技術的模板來建
openvz 的模板下載地址為 http://openvz.org/Download/templates/precreated。
比如,先下載了一個 ubuntu-14.04 的鏡像,之後使用以下命令導入:
@ -147,7 +147,7 @@ ubuntu 14.04 05ac7c0b9383 17 seconds ago
```
###上傳鏡像
用戶可以通過 `docker push` 命令,把自己創建的鏡像上傳到倉庫中來共享。例如,用戶在 Docker Hub 上完成註冊後,可以推送自己的鏡像到倉庫中。
使用者可以透過 `docker push` 命令,把自己建立的鏡像上傳到倉庫中來共享。例如,使用者在 Docker Hub 上完成註冊後,可以推送自己的鏡像到倉庫中。
```
$ sudo docker push ouruser/sinatra
The push refers to a repository [ouruser/sinatra] (len: 1)

View File

@ -1,7 +1,7 @@
## 鏡像的實原理
## 鏡像的實原理
Docker 鏡像是怎麽實增量的修改和維護的?
Docker 鏡像是怎麽實增量的修改和維護的?
每個鏡像都由很多層次構成Docker 使用 [Union FS](http://en.wikipedia.org/wiki/UnionFS) 將這些不同的層結合到一個鏡像中去。
通常 Union FS 有兩個用途, 一方面可以實不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更常用的就是將一個唯讀的分支和一個可寫的分支聯合在一起Live CD 正是基於此方法可以允許在鏡像不變的基礎上允許用戶在其上進行一些寫操作。
Docker 在 AUFS 上建的容器也是利用了類似的原理。
通常 Union FS 有兩個用途, 一方面可以實不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更常用的就是將一個唯讀的分支和一個可寫的分支聯合在一起Live CD 正是基於此方法可以允許在鏡像不變的基礎上允許使用者在其上進行一些寫操作。
Docker 在 AUFS 上建的容器也是利用了類似的原理。

View File

@ -16,12 +16,12 @@ ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
* 來自於哪個倉庫,比如 ubuntu
* 鏡像的標記,比如 14.04
* 它的 `ID` 號(唯一)
* 建時間
* 建時間
* 鏡像大小
其中鏡像的 `ID` 唯一標識了鏡像,注意到 `ubuntu:14.04``ubuntu:trusty` 具有相同的鏡像 `ID`,說明它們實際上是同一鏡像。
`TAG` 息用來標記來自同一個倉庫的不同鏡像。例如 `ubuntu` 倉庫中有多個鏡像,通過 `TAG` 信息來區分發行版本,例如 `10.04`、`12.04`、`12.10`、`13.04`、`14.04` 等。例如下面的命令指定使用鏡像 `ubuntu:14.04` 來啟動一個容器。
`TAG` 息用來標記來自同一個倉庫的不同鏡像。例如 `ubuntu` 倉庫中有多個鏡像,透過 `TAG` 訊息來區分發行版本,例如 `10.04`、`12.04`、`12.10`、`13.04`、`14.04` 等。例以下面的命令指定使用鏡像 `ubuntu:14.04` 來啟動一個容器。
```
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
```

View File

@ -1,6 +1,6 @@
## 取映像檔
## 取映像檔
可以使用 `docker pull` 命令來從倉庫取所需要的映像檔。
可以使用 `docker pull` 命令來從倉庫取所需要的映像檔。
下面的例子將從 Docker Hub 倉庫下載一個 Ubuntu 12.04 作業系統的映像檔。
```
@ -14,12 +14,12 @@ a300658979be: Download complete
ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
```
下載過程中,會輸出獲取鏡像的每一層信息。
下載過程中,會輸出取得鏡像的每一層訊息。
該命令實際上相當於 `$ sudo docker pull registry.hub.docker.com/ubuntu:12.04` 命令,即從註冊服`registry.hub.docker.com` 中的 `ubuntu` 倉庫來下載標記為 `12.04` 的映像檔。
該命令實際上相當於 `$ sudo docker pull registry.hub.docker.com/ubuntu:12.04` 命令,即從註冊服器 `registry.hub.docker.com` 中的 `ubuntu` 倉庫來下載標記為 `12.04` 的映像檔。
有時候官方倉庫註冊服器下載較慢,可以從其他倉庫下載。
從其它倉庫下載時需要指定完整的倉庫註冊服器地址。例如
有時候官方倉庫註冊服器下載較慢,可以從其他倉庫下載。
從其它倉庫下載時需要指定完整的倉庫註冊服器地址。例如
```
$ sudo docker pull dl.dockerpool.com:5000/ubuntu:12.04
Pulling dl.dockerpool.com:5000/ubuntu
@ -32,7 +32,7 @@ ffdaafd1ca50: Download complete
d047ae21eeaf: Download complete
```
完成後,即可隨時使用該映像檔了,例如建一個容器,讓其中執行 bash 應用。
完成後,即可隨時使用該映像檔了,例如建一個容器,讓其中執行 bash 應用。
```
$ sudo docker run -t -i ubuntu:12.04 /bin/bash
root@fe7fc4bd8fc9:/#

View File

@ -19,4 +19,4 @@ $ sudo docker load --input ubuntu_14.04.tar
```
$ sudo docker load < ubuntu_14.04.tar
```
這將導入鏡像以及其相關的元數據息(包括標簽等)。
這將導入鏡像以及其相關的元數據息(包括標簽等)。

View File

@ -3,7 +3,7 @@
Docker 支持 CentOS6 及以後的版本。
### CentOS6
對於 CentOS6可以使用 [EPEL](https://fedoraproject.org/wiki/EPEL) 套件庫安裝 Docker命令
對於 CentOS6可以使用 [EPEL](https://fedoraproject.org/wiki/EPEL) 套件庫安裝 Docker命令
```
$ sudo yum install http://mirrors.yun-idc.com/epel/6/i386/epel-release-6-8.noarch.rpm
$ sudo yum install docker-io
@ -15,7 +15,7 @@ CentOS7 系統 `CentOS-Extras` 庫中已內建 Docker可以直接安裝
$ sudo yum install docker
```
安裝之後啟動 Docker 服務,並讓它隨系統啟動自動載。
安裝之後啟動 Docker 服務,並讓它隨系統啟動自動載
```
$ sudo service docker start
$ sudo chkconfig docker on

View File

@ -1,6 +1,6 @@
## Ubuntu 系列安裝 Docker
### 過系統內建套件安裝
### 過系統內建套件安裝
Ubuntu 14.04 版本套件庫中已經內建了 Docker 套件,可以直接安裝。
```
$ sudo apt-get update
@ -9,10 +9,10 @@ $ sudo ln -sf /usr/bin/docker.io /usr/local/bin/docker
$ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
```
如果使用作業系統內建套件安裝 Docker目前安裝的版本是比較舊的 0.9.1。 要安裝更新的版本,可以過更新 Docker 套件庫的方式進行安裝。
如果使用作業系統內建套件安裝 Docker目前安裝的版本是比較舊的 0.9.1。 要安裝更新的版本,可以過更新 Docker 套件庫的方式進行安裝。
### 過Docker 套件庫安裝最新版本
要安裝最新的 Docker 版本,首先需要安裝 apt-transport-https 支持,之後通過添加套件庫來安裝。
### 過Docker 套件庫安裝最新版本
要安裝最新的 Docker 版本,首先需要安裝 apt-transport-https 支持,之後透過新增套件庫來安裝。
```
$ sudo apt-get install apt-transport-https
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9

View File

@ -5,4 +5,4 @@
用它會帶來什麼樣的好處?
好吧,讓我們帶著問題開始這神奇之旅。
好吧,讓我們帶著問題開始這神奇之旅。

View File

@ -1,15 +1,15 @@
## 什麼是 Docker
Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘項目。它基於 Google 公司推出的 Go 語言實
Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘項目。它基於 Google 公司推出的 Go 語言實
項目後來加入了 Linux 基金會,遵從了 Apache 2.0 協議,原始碼在 [GitHub](https://github.com/docker/docker) 上進行維護。
Docker 自開源後受到廣泛的關注和討論,以至於 dotCloud 公司後來都改名為 Docker Inc。Redhat 已經在其 RHEL6.5 中集中支持 DockerGoogle 也在其 PaaS 產品中廣泛應用。
Docker 項目的目標是實輕量級的作業系統虛擬化解決方案。
Docker 項目的目標是實輕量級的作業系統虛擬化解決方案。
Docker 的基礎是 Linux 容器LXC等技術。
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓用戶不需要去關心容器的管理,使得操作更為簡便。用戶操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓使用者不需要去關心容器的管理,使得操作更為簡便。使用者操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。
下面的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在作業系統層面上實現虛擬化,直接使用本地主機的作業系統,而傳統方式則是在硬體層面實現
下面的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在作業系統層面上實做虛擬化,直接使用本地主機的作業系統,而傳統方式則是在硬體層面實做
![傳統虛擬化](../_images/virtualization.png)

View File

@ -1,30 +1,30 @@
## 為什麼要使用 Docker
作為一種新興的虛擬化方式Docker 跟傳統的虛擬化方式相比具有眾多的優勢。
首先Docker 容器的啟動可以在秒級實,這相比傳統的虛擬機方式要快得多。
其次Docker 對系統資源的用率很高,一台主機上可以同時執行數千個 Docker 容器。
首先Docker 容器的啟動可以在秒級實,這相比傳統的虛擬機方式要快得多。
其次Docker 對系統資源的使用率很高,一台主機上可以同時執行數千個 Docker 容器。
容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的能很高,同時系統資源消耗更少。傳統虛擬機方式執行 10 個不同的應用就要啟動 10 個虛擬機,而 Docker 只需要啟動 10 個隔離的應用即可。
容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的能很高,同時系統資源消耗更少。傳統虛擬機方式執行 10 個不同的應用就要啟動 10 個虛擬機,而 Docker 只需要啟動 10 個隔離的應用即可。
具體說來Docker 在下幾個方面具有較大的優勢。
具體說來Docker 在下幾個方面具有較大的優勢。
### 更快速的交付和部署
對開發和維運develop人員來說最希望的就是一次建立或配置,可以在任意地方正常執行。
對開發和維運develop人員來說最希望的就是一次建立或設定,可以在任意地方正常執行。
開發者可以使用一個標準的映像檔來建一套開發容器,開發完成之後,維運人員可以直接使用這個容器來部署程式碼。
Docker 可以快速創建容器,快速迭代應用程序,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程序是如何創建和工作的。
開發者可以使用一個標準的映像檔來建一套開發容器,開發完成之後,維運人員可以直接使用這個容器來部署程式碼。
Docker 可以快速建立容器,快速迭代應用程式,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程式是如何建立和工作的。
Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。
### 更高效的虛擬化
Docker 容器的執行不需要額外的虛擬化支持,它是核心層級的虛擬化,因此可以實現更高的性能和效率。
### 更有效率的虛擬化
Docker 容器的執行不需要額外的虛擬化支持,它是核心層級的虛擬化,因此可以實做更高的效能和效率。
### 更輕鬆的遷移和擴展
Docker 容器幾乎可以在任意的平台上執行,包括實體機器、虛擬機、公有雲、私有雲、個人電腦、伺服器等。
這種兼容性可以讓用戶把一個應用程序從一個平台直接遷移到另外一個。
這種兼容性可以讓使用者把一個應用程式從一個平台直接遷移到另外一個。
### 更簡單的管理
使用 Docker只需要小小的修改就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新從而實現自動化並且高效的管理。
使用 Docker只需要小小的修改就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新從而實做自動化並且有效率的管理。
### 對比傳統虛擬機總結
@ -32,5 +32,5 @@ Docker 容器幾乎可以在任意的平台上執行,包括實體機器、虛
| ---- | ---- | ------ |
| 啟動 | 秒級 | 分鐘級 |
| 硬碟容量 | 一般為 MB | 一般為 GB |
| 能 | 接近原生 | 比較慢 |
| 能 | 接近原生 | 比較慢 |
| 系統支持量 | 單機支持上千個容器 | 一般幾十個 |

View File

@ -1,2 +1,2 @@
# Docker 中的網路功能介紹
Docker 允許過外部訪問容器或容器互聯的方式來提供網路服務。
Docker 允許過外部訪問容器或容器互聯的方式來提供網路服務。

View File

@ -1,12 +1,12 @@
## 容器互聯
容器的連接linking系統是除了端口映射外另一種跟容器中應用交互的方式。
該系統會在源和接收容器之間建一個隧道,接收容器可以看到源容器指定的息。
該系統會在源和接收容器之間建一個隧道,接收容器可以看到源容器指定的息。
### 自定義容器命名
連接系統依據容器的名稱來執行。因此,首先需要自定義一個好記的容器命名。
雖然當建容器的時候系統默認會分配一個名字。自定義命名容器有2個好處
雖然當建容器的時候系統默認會分配一個名字。自定義命名容器有2個好處
* 自定義的命名比較好記比如一個web應用容器我們可以給它起名叫web
* 當要連接其他容器時候可以作為一個有用的參考點比如連接web容器到db容器
@ -26,22 +26,22 @@ aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0
$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
/web
```
註意:容器的名稱是唯一的。如果已經命名了一個叫 web 的容器,當你要再次使用 web 這個名稱的時候,需要先用`docker rm` 來刪除之前建的同名容器。
註意:容器的名稱是唯一的。如果已經命名了一個叫 web 的容器,當你要再次使用 web 這個名稱的時候,需要先用`docker rm` 來刪除之前建的同名容器。
在執行 `docker run` 的時候如果添加 `--rm` 標記,則容器在終止後會立刻刪除。註意,`--rm` 和 `-d` 參數不能同時使用。
在執行 `docker run` 的時候如果新增 `--rm` 標記,則容器在終止後會立刻刪除。註意,`--rm` 和 `-d` 參數不能同時使用。
###容器互聯
使用 `--link` 參數可以讓容器之間安全的進行交互。
下面先建一個新的數據庫容器。
下面先建一個新的數據庫容器。
```
$ sudo docker run -d --name db training/postgres
```
刪除之前建的 web 容器
刪除之前建的 web 容器
```
$ docker rm -f web
```
然後建一個新的 web 容器,並將它連接到 db 容器
然後建一個新的 web 容器,並將它連接到 db 容器
```
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
```
@ -56,11 +56,11 @@ CONTAINER ID IMAGE COMMAND CREATED
349169744e49 training/postgres:latest su postgres -c '/usr About a minute ago Up About a minute 5432/tcp db, web/db
aed84ee21bde training/webapp:latest python app.py 16 hours ago Up 2 minutes 0.0.0.0:49154->5000/tcp web
```
可以看到自定義命名的容器db 和 webdb 容器的 names 列有 db 也有 web/db。這表示 web 容器鏈接到 db 容器web 容器將被允許訪問 db 容器的息。
可以看到自定義命名的容器db 和 webdb 容器的 names 列有 db 也有 web/db。這表示 web 容器鏈接到 db 容器web 容器將被允許訪問 db 容器的息。
Docker 在兩個互聯的容器之間建了一個安全隧道,而且不用映射它們的端口到宿主主機上。在啟動 db 容器的時候並沒有使用 `-p``-P` 標記,從而避免了暴露數據庫端口到外部網路上。
Docker 在兩個互聯的容器之間建了一個安全隧道,而且不用映射它們的端口到宿主主機上。在啟動 db 容器的時候並沒有使用 `-p``-P` 標記,從而避免了暴露數據庫端口到外部網路上。
Docker 通過 2 種方式為容器公開連接信息:
Docker 透過 2 種方式為容器公開連接訊息:
* 環境變量
* 更新 `/etc/hosts` 文件
@ -78,7 +78,7 @@ DB_PORT_5000_TCP_ADDR=172.17.0.5
```
其中 DB_ 開頭的環境變量是供 web 容器連接 db 容器使用,前綴采用大寫的連接別名。
除了環境變量Docker 還添加 host 信息到父容器的 `/etc/hosts` 的文件。下面是父容器 web 的 hosts 文件
除了環境變量Docker 還新增 host 訊息到父容器的 `/etc/hosts` 的文件。下面是父容器 web 的 hosts 文件
```
$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
@ -86,7 +86,7 @@ root@aed84ee21bde:/opt/webapp# cat /etc/hosts
. . .
172.17.0.5 db
```
有 2 個 hosts第一個是 web 容器web 容器用 id 作為他的主機名,第二個是 db 容器的 ip 和主機名。
有 2 個 hosts第一個是 web 容器web 容器用 id 作為他的主機名,第二個是 db 容器的 ip 和主機名。
可以在 web 容器中安裝 ping 命令來測試跟db容器的連通。
```
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
@ -99,4 +99,4 @@ PING db (172.17.0.5): 48 data bytes
用 ping 來測試db容器它會解析成 `172.17.0.5`
*註意:官方的 ubuntu 鏡像默認沒有安裝 ping需要自行安裝。
用戶可以鏈接多個子容器到父容器,比如可以鏈接多個 web 到 db 容器上。
使用者可以鏈接多個子容器到父容器,比如可以鏈接多個 web 到 db 容器上。

View File

@ -1,5 +1,5 @@
## 外部訪問容器
容器中可以執行一些網路應用,要讓外部也可以訪問這些應用,可以`-P``-p` 參數來指定端口映射。
容器中可以執行一些網路應用,要讓外部也可以訪問這些應用,可以`-P``-p` 參數來指定端口映射。
當使用 -P 標記時Docker 會隨機映射一個 `49000~49900` 的端口到內部容器開放的網路端口。
@ -10,7 +10,7 @@ $ sudo docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
```
同樣的,可以通過 `docker logs` 命令來查看應用的信息。
同樣的,可以透過 `docker logs` 命令來查看應用的訊息。
```
$ sudo docker logs -f nostalgic_morse
* Running on http://0.0.0.0:5000/
@ -41,14 +41,14 @@ $ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
```
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
```
### 查看映射端口配置
使用 `docker port` 來查看當前映射的端口配置,也可以查看到綁定的地址
### 查看映射端口設定
使用 `docker port` 來查看當前映射的端口設定,也可以查看到綁定的地址
```
$ docker port nostalgic_morse 5000
127.0.0.1:49155.
```
註意:
* 容器有自己的內部網路和 ip 地址(使用 `docker inspect` 可以取所有的變量Docker 還可以有一個可變的網路配置。)
* 容器有自己的內部網路和 ip 地址(使用 `docker inspect` 可以取所有的變量Docker 還可以有一個可變的網路設定。)
* -p 標記可以多次使用來綁定多個端口
例如

View File

@ -1,30 +1,30 @@
## 倉庫配置文件
Docker 的 Registry 利用配置文件提供了一些倉庫的模組flavor用戶可以直接使用它們來進行開發或生產部署。
## 倉庫設定文件
Docker 的 Registry 利用設定文件提供了一些倉庫的模組flavor使用者可以直接使用它們來進行開發或生產部署。
### 模組
`config_sample.yml` 文件中,可以看到一些現成的模組段:
* `common`:基礎配置
* `common`:基礎設定
* `local`:儲存數據到本地文件系統
* `s3`:儲存數據到 AWS S3 中
* `dev`:使用 `local` 模組的基本配置
* `dev`:使用 `local` 模組的基本設定
* `test`:單元測試使用
* `prod`:生產環境配置基本上跟s3配置類似)
* `prod`:生產環境設定基本上跟s3設定類似)
* `gcs`:儲存數據到 Google 的雲端
* `swift`:儲存數據到 OpenStack Swift 服務
* `glance`:儲存數據到 OpenStack Glance 服務,本地文件系統為後備
* `glance-swift`:儲存數據到 OpenStack Glance 服務Swift 為後備
* `elliptics`:儲存數據到 Elliptics key/value 存儲
用戶也可以添加自定義的模版段。
使用者也可以新增自定義的模版段。
預設情況下使用的模組是 `dev`,要使用某個模組作為預設值,可以添加 `SETTINGS_FLAVOR` 到環境變數中,例如
預設情況下使用的模組是 `dev`,要使用某個模組作為預設值,可以新增 `SETTINGS_FLAVOR` 到環境變數中,例如
```
export SETTINGS_FLAVOR=dev
```
另外,配置文件中支持從環境變數中加載值,語法格式為 `_env:VARIABLENAME[:DEFAULT]`
另外,設定文件中支持從環境變數中載入值,語法格式為 `_env:VARIABLENAME[:DEFAULT]`
### 範例配置
### 範例設定
```
common:
loglevel: info

View File

@ -1,12 +1,12 @@
## Docker Hub
目前 Docker 官方維護了一個公共倉庫 [Docker Hub](https://hub.docker.com/),其中已經包括了超過 15,000 的映像檔。大部分需求,都可以通過在 Docker Hub 中直接下載映像檔來實現
目前 Docker 官方維護了一個公共倉庫 [Docker Hub](https://hub.docker.com/),其中已經包括了超過 15,000 的映像檔。大部分需求,都可以透過在 Docker Hub 中直接下載映像檔來實做
### 登錄
可以通過執行 `docker login` 命令來輸入用戶名稱、密碼和電子信箱來完成註冊和登錄。
註冊成功後,本地用戶目錄的 `.dockercfg` 中將保存用戶的認證訊息。
可以透過執行 `docker login` 命令來輸入使用者名稱、密碼和電子信箱來完成註冊和登錄。
註冊成功後,本地使用者目錄的 `.dockercfg` 中將保存使用者的認證訊息。
### 基本操作
用戶無需登錄即可通`docker search` 命令來查詢官方倉庫中的映像檔,並利用 `docker pull` 命令來將它下載到本地。
使用者無需登錄即可透`docker search` 命令來查詢官方倉庫中的映像檔,並利用 `docker pull` 命令來將它下載到本地。
例如以 centos 為關鍵字進行搜索:
```
@ -19,14 +19,14 @@ saltstack/centos-6-minimal
tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4 instead. ... 5 [OK]
...
```
可以看到顯示了很多包含關鍵字的映像檔,其中包括映像檔名字、描述、星級(表示該映像檔的受歡迎程度)、是否官方建、是否自動建。
官方的映像檔說明是官方項目組創建和維護的automated 資源允許用戶驗證映像檔的來源和內容。
可以看到顯示了很多包含關鍵字的映像檔,其中包括映像檔名字、描述、星級(表示該映像檔的受歡迎程度)、是否官方建、是否自動建
官方的映像檔說明是官方項目組建立和維護的automated 資源允許使用者驗證映像檔的來源和內容。
根據是否是官方提供,可將映像檔資源分為兩類。
一種是類似 centos 這樣的基礎映像檔,被稱為基礎或根映像檔。這些基礎映像檔是由 Docker 公司建、驗證、支持、提供。這樣的映像檔往往使用單個單詞作為名字。
還有一種類型,比如 `tianon/centos` 映像檔,它是由 Docker 的用戶創建並維護的,往往帶有用戶名稱前綴。可以通過前綴 `user_name/` 來指定使用某個用戶提供的映像檔,比如 tianon 用戶
一種是類似 centos 這樣的基礎映像檔,被稱為基礎或根映像檔。這些基礎映像檔是由 Docker 公司建、驗證、支持、提供。這樣的映像檔往往使用單個單詞作為名字。
還有一種類型,比如 `tianon/centos` 映像檔,它是由 Docker 的使用者建立並維護的,往往帶有使用者名稱前綴。可以透過前綴 `user_name/` 來指定使用某個使用者提供的映像檔,比如 tianon 使用者
另外,在查詢的時候`-s N` 參數可以指定僅顯示評價為 `N` 星以上的映像檔。
另外,在查詢的時候`-s N` 參數可以指定僅顯示評價為 `N` 星以上的映像檔。
下載官方 centos 映像檔到本地。
```
@ -37,19 +37,19 @@ Pulling repository centos
511136ea3c5a: Download complete
7064731afe90: Download complete
```
用戶也可以在登錄後通`docker push` 命令來將映像檔推送到 Docker Hub。
使用者也可以在登錄後透`docker push` 命令來將映像檔推送到 Docker Hub。
### 自動
自動Automated Builds功能對於需要經常升級映像檔內程來說,十分方便。
有時候,用戶創建了映像檔,安裝了某個軟體,如果軟體發布新版本則需要手動更新映像檔。。
### 自動建
自動建Automated Builds功能對於需要經常升級映像檔內程來說,十分方便。
有時候,使用者建立了映像檔,安裝了某個軟體,如果軟體發布新版本則需要手動更新映像檔。。
而自動創建允許用戶通過 Docker Hub 指定跟蹤一個目標網站(目前支持 [GitHub](github.org) 或 [BitBucket](bitbucket.org))上的項目,一旦項目發生新的提交,則自動執行建。
而自動建立允許使用者透過 Docker Hub 指定跟蹤一個目標網站(目前支持 [GitHub](github.org) 或 [BitBucket](bitbucket.org))上的項目,一旦項目發生新的提交,則自動執行建
配置自動創建,包括如下的步驟:
* 建並登陸 Docker Hub以及目標網站
設定自動建立,包括以下的步驟:
* 建並登陸 Docker Hub以及目標網站
* 在目標網站中連接帳戶到 Docker Hub
* 在 Docker Hub 中 [配置一個自動創建](https://registry.hub.docker.com/builds/add/)
* 在 Docker Hub 中 [設定一個自動建立](https://registry.hub.docker.com/builds/add/)
* 選取一個目標網站中的項目(需要含 Dockerfile和分支
* 指定 Dockerfile 的位置,並提交建。
* 指定 Dockerfile 的位置,並提交建
之後,可以 在Docker Hub 的 [自動建頁面](https://registry.hub.docker.com/builds/) 中跟蹤每次建的狀態。
之後,可以 在Docker Hub 的 [自動頁面](https://registry.hub.docker.com/builds/) 中跟蹤每次建的狀態。

View File

@ -1,18 +1,18 @@
## 私有倉庫
有時候使用 Docker Hub 這樣的公共倉庫可能不方便,用戶可以創建一個本地倉庫供私人使用。
有時候使用 Docker Hub 這樣的公共倉庫可能不方便,使用者可以建立一個本地倉庫供私人使用。
本節介紹如何使用本地倉庫。
`docker-registry` 是官方提供的工具,可以用於建私有的映像檔倉庫。
`docker-registry` 是官方提供的工具,可以用於建私有的映像檔倉庫。
### 安裝執行 docker-registry
#### 容器執行
在安裝了 Docker 後,可以通過獲取官方 registry 映像檔來執行。
在安裝了 Docker 後,可以透過取得官方 registry 映像檔來執行。
```
$ sudo docker run -d -p 5000:5000 registry
```
這將使用官方的 registry 映像檔來啟動本地的私有倉庫。
用戶可以通過指定參數來配置私有倉庫位置,例如配置映像檔存儲到 Amazon S3 服務。
使用者可以透過指定參數來設定私有倉庫位置,例如設定映像檔存儲到 Amazon S3 服務。
```
$ sudo docker run \
-e SETTINGS_FLAVOR=s3 \
@ -24,18 +24,18 @@ $ sudo docker run \
-p 5000:5000 \
registry
````
此外,還可以指定本地路徑(如 `/home/user/registry-conf` )下的配置文件。
此外,還可以指定本地路徑(如 `/home/user/registry-conf` )下的設定文件。
```
$ sudo docker run -d -p 5000:5000 -v /home/user/registry-conf:/registry-conf -e DOCKER_REGISTRY_CONFIG=/registry-conf/config.yml registry
```
預設情況下,倉庫會被創建在容器的 `/tmp/registry` 下。可以通`-v` 參數來將映像檔文件存放在本地的指定路徑。
下面的例子將上傳的映像檔放到 `/opt/data/registry` 目錄。
預設情況下,倉庫會被建立在容器的 `/tmp/registry` 下。可以透`-v` 參數來將映像檔文件存放在本地的指定路徑。
下面的例子將上傳的映像檔放到 `/opt/data/registry` 目錄。
```
$ sudo docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
```
#### 本地安裝
對於 Ubuntu 或 CentOS 等發行版,可以直接過套件庫安裝。
對於 Ubuntu 或 CentOS 等發行版,可以直接過套件庫安裝。
* Ubuntu
```
$ sudo apt-get install -y build-essential python-dev libevent-dev python-pip liblzma-dev
@ -54,7 +54,7 @@ $ git clone https://github.com/docker/docker-registry.git
$ cd docker-registry
$ sudo python setup.py install
```
然後修改配置文件,主要修改 dev 模板段的 `storage_path` 到本地的儲存倉庫的路徑。
然後修改設定文件,主要修改 dev 模板段的 `storage_path` 到本地的儲存倉庫的路徑。
```
$ cp config/config_sample.yml config/config.yml
```
@ -68,10 +68,10 @@ $ sudo gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -
```
此時使用連結本地的 5000 端口,看到輸出 docker-registry 的版本訊息說明執行成功。
*註:`config/config_sample.yml` 文件是範例配置文件。
*註:`config/config_sample.yml` 文件是範例設定文件。
###在私有倉庫上傳、下載、搜索映像檔
建好私有倉庫之後,就可以使用 `docker tag` 來標記一個映像檔,然後推送它到倉庫,別的機器上就可以下載下來了。例如私有倉庫地址為 `192.168.7.26:5000`
好私有倉庫之後,就可以使用 `docker tag` 來標記一個映像檔,然後推送它到倉庫,別的機器上就可以下載下來了。例如私有倉庫地址為 `192.168.7.26:5000`
先在本機查看已有的映像檔。
```
@ -109,7 +109,7 @@ Pushing tag for rev [ba5877dc9bec] on {http://192.168.7.26:5000/v1/repositories/
$ curl http://192.168.7.26:5000/v1/search
{"num_results": 7, "query": "", "results": [{"description": "", "name": "library/miaxis_j2ee"}, {"description": "", "name": "library/tomcat"}, {"description": "", "name": "library/ubuntu"}, {"description": "", "name": "library/ubuntu_office"}, {"description": "", "name": "library/desktop_ubu"}, {"description": "", "name": "dockerfile/ubuntu"}, {"description": "", "name": "library/test"}]}
```
可以看到 `{"description": "", "name": "library/test"}`,表明映像檔已經被成功上傳了。
可以看到 `{"description": "", "name": "library/test"}`,表明映像檔已經被成功上傳了。
現在可以到另外一臺機器去下載這個映像檔。
```

View File

@ -1,5 +1,5 @@
# 安全
評估 Docker 的安全性時,主要考慮三個方面:
* 由內核的名字空間和控制組機制提供的容器內在安全
* Docker程(特別是服務端)本身的抗攻擊性
* Docker程(特別是服務端)本身的抗攻擊性
* 內核安全性的加強機制對容器安全性的影響

View File

@ -1,8 +1,8 @@
## 控制組
控制組是 Linux 容器機制的另外一個關鍵組件,負責實資源的審計和限制。
控制組是 Linux 容器機制的另外一個關鍵組件,負責實資源的審計和限制。
它提供了很多有用的特性以及確保各個容器可以公平地分享主機的內存、CPU、磁盤 IO 等資源;當然,更重要的是,控制組確保了當容器內的資源使用產生壓力時不會連累主機系統。
盡管控制組不負責隔離容器之間相互訪問、處理數據和程它在防止拒絕服務DDOS攻擊方面是必不可少的。尤其是在多用戶的平臺(比如公有或私有的 PaaS控制組十分重要。例如當某些應用程序表現異常的時候,可以保證一致地正常執行和性能。
盡管控制組不負責隔離容器之間相互訪問、處理數據和程它在防止拒絕服務DDOS攻擊方面是必不可少的。尤其是在多使用者的平臺(比如公有或私有的 PaaS控制組十分重要。例如當某些應用程式表現異常的時候,可以保證一致地正常執行和效能。
控制組機制始於 2006 年,內核從 2.6.24 版本開始被引入。

View File

@ -1,18 +1,18 @@
## Docker服務端的防護
執行一個容器或應用程序的核心是通過 Docker 服務端。Docker 服務的執行目前需要 root 權限,因此其安全性十分關鍵。
執行一個容器或應用程式的核心是透過 Docker 服務端。Docker 服務的執行目前需要 root 權限,因此其安全性十分關鍵。
首先,確保只有可信的用戶才可以訪問 Docker 服務。Docker 允許用戶在主機和容器間共享文件夾,同時不需要限制容器的訪問權限,這就容易讓容器突破資源限制。例如,惡意用戶啟動容器的時候將主機的根目錄`/`映射到容器的 `/host` 目錄中,那麽容器理論上就可以對主機的文件系統進行任意修改了。這聽起來很瘋狂?但是事實上幾乎所有虛擬化系統都允許類似的資源共享,而沒法禁止用戶共享主機根文件系統到虛擬機系統。
首先,確保只有可信的使用者才可以訪問 Docker 服務。Docker 允許使用者在主機和容器間共享文件夾,同時不需要限制容器的訪問權限,這就容易讓容器突破資源限制。例如,惡意使用者啟動容器的時候將主機的根目錄`/`映射到容器的 `/host` 目錄中,那麽容器理論上就可以對主機的文件系統進行任意修改了。這聽起來很瘋狂?但是事實上幾乎所有虛擬化系統都允許類似的資源共享,而沒法禁止使用者共享主機根文件系統到虛擬機系統。
這將會造成很嚴重的安全後果。因此,當提供容器創建服務時(例如通過一個 web 服務器),要更加註意進行參數的安全檢查,防止惡意的用戶用特定參數來創建一些破壞性的容器
這將會造成很嚴重的安全後果。因此,當提供容器建立服務時(例如透過一個 web 伺服器),要更加註意進行參數的安全檢查,防止惡意的使用者用特定參數來建立一些破壞性的容器
為了加強對服務端的保護Docker 的 REST API客戶端用來跟服務端通信在 0.5.2 之後使用本地的 Unix 套接字機制替代了原先綁定在 127.0.0.1 上的 TCP 套接字,因為後者容易遭受跨站腳本攻擊。現在用戶使用 Unix 權限檢查來加強套接字的訪問安全。
為了加強對服務端的保護Docker 的 REST API客戶端用來跟服務端通信在 0.5.2 之後使用本地的 Unix 套接字機制替代了原先綁定在 127.0.0.1 上的 TCP 套接字,因為後者容易遭受跨站腳本攻擊。現在使用者使用 Unix 權限檢查來加強套接字的訪問安全。
用戶仍可以利用 HTTP 提供 REST API 訪問。建議使用安全機制,確保只有可信的網路或 VPN或證書保護機制例如受保護的 stunnel 和 ssl 認證)下的訪問可以進行。此外,還可以使用 HTTPS 和證書來加強保護。
使用者仍可以利用 HTTP 提供 REST API 訪問。建議使用安全機制,確保只有可信的網路或 VPN或證書保護機制例如受保護的 stunnel 和 ssl 認證)下的訪問可以進行。此外,還可以使用 HTTPS 和證書來加強保護。
最近改進的 Linux 名字空間機制將可以實現使用非 root 用戶來執行全功能的容器。這將從根本上解決了容器和主機之間共享文件系統而引起的安全問題。
最近改進的 Linux 名字空間機制將可以實做使用非 root 使用者來執行全功能的容器。這將從根本上解決了容器和主機之間共享文件系統而引起的安全問題。
終極目標是改進 2 個重要的安全特性:
* 將容器的 root 用戶映射到本地主機上的非 root 用戶,減輕容器和主機之間因權限提升而引起的安全問題;
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程序來代理執行需要特權權限的操作。這些子程序將只允許在限定範圍內進行操作,例如僅僅負責虛擬網路設定或文件系統管理、配置操作等。
* 將容器的 root 使用者映射到本地主機上的非 root 使用者,減輕容器和主機之間因權限提升而引起的安全問題;
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程式來代理執行需要特權權限的操作。這些子程式將只允許在限定範圍內進行操作,例如僅僅負責虛擬網路設定或文件系統管理、設定操作等。
最後,建議采用專用的服器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
最後,建議采用專用的服器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。

View File

@ -1,26 +1,26 @@
## 內核能力機制
能力機制Capability是 Linux 內核一個強大的特性,可以提供細粒度的權限訪問控制。
Linux 內核自 2.2 版本起就支持能力機制,它將權限劃分為更加細粒度的操作能力,既可以作用在程上,也可以作用在文件上。
Linux 內核自 2.2 版本起就支持能力機制,它將權限劃分為更加細粒度的操作能力,既可以作用在程上,也可以作用在文件上。
例如,一個 Web 服務程只需要綁定一個低於 1024 的端口的權限,並不需要 root 權限。那麽它只需要被授權 `net_bind_service` 能力即可。此外,還有很多其他的類似能力來避免程序獲取 root 權限。
例如,一個 Web 服務程只需要綁定一個低於 1024 的端口的權限,並不需要 root 權限。那麽它只需要被授權 `net_bind_service` 能力即可。此外,還有很多其他的類似能力來避免程式取得 root 權限。
默認情況下Docker 啟動的容器被嚴格限制只允許使用內核的一部分能力。
使用能力機制對加強 Docker 容器的安全有很多好處。通常,在服務器上會執行一堆需要特權權限的程序,包括有 ssh、cron、syslogd、硬件管理工具模塊例如負載模塊、網路配置工具等等。容器跟這些程序是不同的因為幾乎所有的特權程序都由容器以外的支持系統來進行管理。
使用能力機制對加強 Docker 容器的安全有很多好處。通常,在伺服器上會執行一堆需要特權權限的程式,包括有 ssh、cron、syslogd、硬件管理工具模塊例如負載模塊、網路設定工具等等。容器跟這些程式是不同的因為幾乎所有的特權程式都由容器以外的支持系統來進行管理。
* ssh 訪問被主機上ssh服務來管理
* cron 通常應該作為用戶程序執行,權限交給使用它服務的應用來處理;
* cron 通常應該作為使用者程式執行,權限交給使用它服務的應用來處理;
* 日誌系統可由 Docker 或第三方服務管理;
* 硬件管理無關緊要,容器中也就無需執行 udevd 以及類似服務;
* 網路管理也都在主機上設置,除非特殊需求,容器不需要對網路進行配置
* 網路管理也都在主機上設置,除非特殊需求,容器不需要對網路進行設定
從上面的例子可以看出,大部分情況下,容器並不需要“真正的” root 權限,容器只需要少數的能力即可。為了加強安全,容器可以禁用一些沒必要的權限。
* 完全禁止任何 mount 操作;
* 禁止直接訪問本地主機的套接字;
* 禁止訪問一些文件系統的操作,比如建新的設備、修改文件屬性等;
* 禁止模塊載。
* 禁止訪問一些文件系統的操作,比如建新的設備、修改文件屬性等;
* 禁止模塊載
這樣,就算攻擊者在容器中取得了 root 權限,也不能獲得本地主機的較高權限,能進行的破壞也有限。
默認情況下Docker采用 [白名單](https://github.com/docker/docker/blob/master/daemon/execdriver/native/template/default_template.go) 機制,禁用 [必需功能](https://github.com/docker/docker/blob/master/daemon/execdriver/native/template/default_template.go) 之外的其它權限。
當然,用戶也可以根據自身需求來為 Docker 容器啟用額外的權限。
當然,使用者也可以根據自身需求來為 Docker 容器啟用額外的權限。

View File

@ -1,15 +1,15 @@
## 內核名字空間
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。當用 `docker run` 啟動一個容器時,在後臺 Docker 為容器建了一個獨立的名字空間和控制組集合。
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。當用 `docker run` 啟動一個容器時,在後臺 Docker 為容器建了一個獨立的名字空間和控制組集合。
名字空間提供了最基礎也是最直接的隔離,在容器中執行的程序不會被執行在主機上的程序和其它容器發現和作用。
名字空間提供了最基礎也是最直接的隔離,在容器中執行的程式不會被執行在主機上的程式和其它容器發現和作用。
每個容器都有自己獨有的網路棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據配置來限制通信的策略)。
每個容器都有自己獨有的網路棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據設定來限制通信的策略)。
從網路架構的角度來看,所有的容器通過本地主機的網橋接口相互通信,就像物理機器通過物理交換機通信一樣。
從網路架構的角度來看,所有的容器透過本地主機的網橋接口相互通信,就像物理機器透過物理交換機通信一樣。
那麽,內核中實名字空間和私有網路的代碼是否足夠成熟?
那麽,內核中實名字空間和私有網路的代碼是否足夠成熟?
內核名字空間從 2.6.15 版本2008 年 7 月發布)之後被引入,數年間,這些機制的可靠性在諸多大型生產系統中被實踐驗證。
實際上,名字空間的想法和設計提出的時間要更早,最初是為了在內核中引入一種機制來實 [OpenVZ](http://en.wikipedia.org/wiki/OpenVZ) 的特性。
而 OpenVZ 項目早在 2005 年就發布了,其設計和實都已經十分成熟。
實際上,名字空間的想法和設計提出的時間要更早,最初是為了在內核中引入一種機制來實 [OpenVZ](http://en.wikipedia.org/wiki/OpenVZ) 的特性。
而 OpenVZ 項目早在 2005 年就發布了,其設計和實都已經十分成熟。

View File

@ -1,9 +1,9 @@
## 其它安全特性
除了能力機制之外,還可以利用一些現有的安全機制來增強使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。
Docker 當前默認只啟用了能力機制。用戶可以采用多種方案來加強 Docker 主機的安全,例如:
* 在內核中啟用 GRSEC 和 PAX這將增加很多編譯和執行時的安全檢查通過地址隨機化避免惡意探測等。並且,啟用該特性不需要 Docker 進行任何配置
Docker 當前默認只啟用了能力機制。使用者可以采用多種方案來加強 Docker 主機的安全,例如:
* 在內核中啟用 GRSEC 和 PAX這將增加很多編譯和執行時的安全檢查透過地址隨機化避免惡意探測等。並且,啟用該特性不需要 Docker 進行任何設定
* 使用一些有增強安全特性的容器模板,比如帶 AppArmor 的模板和 Redhat 帶 SELinux 策略的模板。這些模板提供了額外的安全特性。
* 用戶可以自定義訪問控制機制來定制安全策略。
* 使用者可以自定義訪問控制機制來定制安全策略。
跟其它添加到 Docker 容器的第三方工具一樣(比如網路拓撲和文件系統共享),有很多類似的機制,在不改變 Docker 內核情況下就可以加固現有的容器。
跟其它新增到 Docker 容器的第三方工具一樣(比如網路拓撲和文件系統共享),有很多類似的機制,在不改變 Docker 內核情況下就可以加固現有的容器。

View File

@ -1,4 +1,4 @@
## 總結
總體來看Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程的話。
總體來看Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程的話。
另外,用戶可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實更復雜的安全機制。
另外,使用者可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實更復雜的安全機制。

View File

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

View File

@ -1,10 +1,10 @@
## 基本架構
Docker 采用了 C/S架構包括客戶端和服務端。
Docker daemon 作為服務端接受來自客戶的請求,並處理這些請求(建、執行、分發容器)。
客戶端和服務端既可以執行在一個機器上,也可過 socket 或者 RESTful API 來進行通信。
Docker daemon 作為服務端接受來自客戶的請求,並處理這些請求(建、執行、分發容器)。
客戶端和服務端既可以執行在一個機器上,也可過 socket 或者 RESTful API 來進行通信。
![Docker 基本架構](../_images/docker_arch.png)
Docker daemon 一般在宿主主機後臺執行,等待接收來自客戶端的消息。
Docker 客戶端則為用戶提供一系列可執行命令,用戶用這些命令實現跟 Docker daemon 交互。
Docker 客戶端則為使用者提供一系列可執行命令,使用者用這些命令實做跟 Docker daemon 交互。

View File

@ -2,7 +2,7 @@
控制組([cgroups](http://en.wikipedia.org/wiki/Cgroups))是 Linux 內核的一個特性,主要用來對共享資源進行隔離、限制、審計等。只有能控制分配到容器的資源,才能避免當多個容器同時執行時的對系統資源的競爭。
控制組技術最早是由 Google 的程員 2006 年起提出Linux 內核自 2.6.24 開始支持。
控制組技術最早是由 Google 的程員 2006 年起提出Linux 內核自 2.6.24 開始支持。
控制組可以提供對容器的內存、CPU、磁盤 IO 等資源的限制和審計管理。

View File

@ -2,21 +2,21 @@
名字空間是 Linux 內核一個強大的特性。每個容器都有自己單獨的名字空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名字空間保證了容器之間彼此互不影響。
### pid 名字空間
不同用戶的程序就是通過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 LXC 程序在 Docker 中的父程序為Docker程序每個 LXC 程序具有不同的名字空間。同時由於允許嵌套,因此可以很方便的實現嵌套的 Docker 容器。
不同使用者的程式就是透過 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。
容器中程式交互還是采用了 Linux 常見的程式間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的程式間交互實際上還是 host 上具有相同 pid 名字空間中的程式間交互,因此需要在 IPC 資源申請時加入名字空間訊息,每個 IPC 資源有一個唯一的 32 位 id。
### mnt 名字空間
類似 chroot將一個程序放到一個特定的目錄執行。mnt 名字空間允許不同名字空間的程序看到的文件結構不同,這樣每個名字空間 中的程序所看到的文件目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的息只包含所在名字空間的 mount point。
類似 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, 也就是說可以在容器內用容器內部的用戶執行程序而非主機上的用戶
每個容器可以有不同的使用者和組 id, 也就是說可以在容器內用容器內部的使用者執行程式而非主機上的使用者
*註:關於 Linux 上的名字空間,[這篇文章](http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/) 介紹的很好。

View File

@ -1,39 +1,39 @@
## Docker 網路實
## Docker 網路實
Docker 的網路實其實就是利用了 Linux 上的網路名字空間和虛擬網路設備(特別是 veth pair。建議先熟悉了解這兩部分的基本概念再閱讀本章。
Docker 的網路實其實就是利用了 Linux 上的網路名字空間和虛擬網路設備(特別是 veth pair。建議先熟悉了解這兩部分的基本概念再閱讀本章。
### 基本原理
首先,要實網路通信,機器需要至少一個網路接口(物理接口或虛擬接口)來收發數據包;此外,如果不同子網之間要進行通信,需要路由機制。
首先,要實網路通信,機器需要至少一個網路接口(物理接口或虛擬接口)來收發數據包;此外,如果不同子網之間要進行通信,需要路由機制。
Docker 中的網路接口默認都是虛擬的接口。虛擬接口的優勢之一是轉發效率較高。
Linux 通過在內核中進行數據復制來實現虛擬接口之間的數據轉發,發送接口的發送緩存中的數據包被直接復制到接收接口的接收緩存中。對於本地系統和容器內系統看來就像是一個正常的以太網卡,只是它不需要真正同外部網路設備通信,速度要快很多。
Linux 透過在內核中進行數據復制來實做虛擬接口之間的數據轉發,發送接口的發送緩存中的數據包被直接復制到接收接口的接收緩存中。對於本地系統和容器內系統看來就像是一個正常的以太網卡,只是它不需要真正同外部網路設備通信,速度要快很多。
Docker 容器網路就利用了這項技術。它在本地主機和容器內分別建一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做 `veth pair`)。
Docker 容器網路就利用了這項技術。它在本地主機和容器內分別建一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做 `veth pair`)。
### 建網路參數
Docker 創建一個容器的時候,會執行如下操作:
* 建一對虛擬接口,分別放到本地主機和新容器中;
### 建網路參數
Docker 建立一個容器的時候,會執行以下操作:
* 建一對虛擬接口,分別放到本地主機和新容器中;
* 本地主機一端橋接到默認的 docker0 或指定網橋上,並具有一個唯一的名字,如 veth65f9
* 容器一端放到新容器中,並修改名字作為 eth0這個接口只在容器的名字空間可見
* 從網橋可用地址段中獲取一個空閑地址分配給容器的 eth0並配置默認路由到橋接網卡 veth65f9。
* 從網橋可用地址段中取得一個空閑地址分配給容器的 eth0並設定默認路由到橋接網卡 veth65f9。
完成這些之後,容器就可以使用 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
@ -41,20 +41,20 @@ $ pid=2778
$ sudo mkdir -p /var/run/netns
$ sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
```
檢查橋接網卡的 IP 和子網掩碼息。
檢查橋接網卡的 IP 和子網掩碼息。
```
$ ip addr show docker0
21: docker0: ...
inet 172.17.42.1/16 scope global docker0
...
```
建一對 “veth pair” 接口 A 和 B綁定 A 到網橋 `docker0`,並啟用它
一對 “veth pair” 接口 A 和 B綁定 A 到網橋 `docker0`,並啟用它
```
$ 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` 卸載。
此外,用戶可以使用 `ip netns exec` 命令來在指定網路名字空間中進行配置,從而配置容器內的網路。
此外,使用者可以使用 `ip netns exec` 命令來在指定網路名字空間中進行設定,從而設定容器內的網路。

View File

@ -1,10 +1,10 @@
## Union 文件系統
Union文件系統[UnionFS](http://en.wikipedia.org/wiki/UnionFS))是一種分層、輕量級並且高能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)。
Union文件系統[UnionFS](http://en.wikipedia.org/wiki/UnionFS))是一種分層、輕量級並且高能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)。
Union 文件系統是 Docker 鏡像的基礎。鏡像可以過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。
Union 文件系統是 Docker 鏡像的基礎。鏡像可以過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。
另外,不同 Docker 容器就可以共享一些基礎的文件系統層,同時再加上自己獨有的改動層,大大提高了存儲的效率。
Docker 中使用的 AUFSAnotherUnionFS就是一種 Union FS。 AUFS 支持為每一個成員目錄(類似 Git 的分支設定唯讀readonly、讀寫readwrite和寫出whiteout-able權限, 同時 AUFS 有一個類似分層的概念, 對唯讀權限的分支可以邏輯上進行增量地修改(不影響唯讀部分的)。
Docker 中使用的 AUFSAnotherUnionFS就是一種 Union FS。 AUFS 支持為每一個成員目錄(類似 Git 的分支設定唯讀readonly、讀寫readwrite和寫出whiteout-able權限, 同時 AUFS 有一個類似分層的概念, 對唯讀權限的分支可以邏輯上進行增量地修改(不影響唯讀部分的)。
Docker 目前支持的 Union 文件系統種類包括 AUFS, btrfs, vfs 和 DeviceMapper。