修正多個用詞
"s/程序/程式/g" "s/性能/效能/g" "s/如下/以下/g" "s/加載/載入/g" "s/獲取/取得/g" "s/服務器/伺服器/g" "s/信息/訊息/g" "s/註釋/註解/g" "s/裏/裡/g" "s/構建/建立/g" "s/配置/設定/g"pull/24/head^2
parent
9d0330915d
commit
a795bf863a
|
@ -3,7 +3,7 @@ Docker —— 從入門到實踐
|
|||
|
||||
v0.2.9
|
||||
|
||||
[Docker](docker.com) 是個偉大的項目,它徹底釋放了虛擬化的,讓應用程式的分派、部署和管理都變得前所未有的高效和輕鬆!
|
||||
[Docker](docker.com) 是個偉大的項目,它徹底釋放了虛擬化的,讓應用程式的分派、部署和管理都變得前所未有的有效率和輕鬆!
|
||||
|
||||
本書既適用於具備基礎 Linux 知識的 Docker 初學者,也可供希望理解原理和實做的進階使用者參考。同時,書中給出的實踐案例,可供在進行實際部署時借鑒。
|
||||
|
||||
|
|
16
SUMMARY.md
16
SUMMARY.md
|
@ -12,7 +12,7 @@
|
|||
* [Ubuntu](install/ubuntu.md)
|
||||
* [CentOS](install/centos.md)
|
||||
* [映像檔](image/README.md)
|
||||
* [獲取映像檔](image/pull.md)
|
||||
* [取得映像檔](image/pull.md)
|
||||
* [列出](image/list.md)
|
||||
* [建立](image/create.md)
|
||||
* [存出和載入](image/save_load.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,18 +36,18 @@
|
|||
* [使用網路](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)
|
||||
* [設定 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)
|
||||
* [使用 Supervisor 來管理程式](cases/supervisor.md)
|
||||
* [建立 tomcat/weblogic 集群](cases/tomcat.md)
|
||||
* [多台實體主機之間的容器互連](cases/container_connect.md)
|
||||
* [標準化開發測試和生產環境](cases/environment.md)
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 進階網路配置
|
||||
本章將介紹 Docker 的一些進階網路配置和選項。
|
||||
# 進階網路設定
|
||||
本章將介紹 Docker 的一些進階網路設定和選項。
|
||||
|
||||
當 Docker 啟動時,會自動在主機上建立一個 `docker0` 虛擬橋接器,實際上是 Linux 的一個 bridge,可以理解為一個軟體交換機。它會在掛載到它的網卡之間進行轉發。
|
||||
|
||||
|
@ -9,4 +9,4 @@
|
|||
|
||||
![Docker 網路](../_images/network.png)
|
||||
|
||||
接下來的部分將介紹在一些場景中,Docker 所有的網路自訂配置。以及透過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路配置。
|
||||
接下來的部分將介紹在一些場景中,Docker 所有的網路自訂設定。以及透過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路設定。
|
||||
|
|
|
@ -20,9 +20,9 @@ $sysctl -w net.ipv4.ip_forward=1
|
|||
* 本地系統的防火墻軟件 -- `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` 選項來訪問容器的開放端口。
|
||||
|
|
|
@ -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 地址設定和路由訊息。
|
||||
|
|
|
@ -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` 提交。
|
||||
|
|
|
@ -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` 來設定容器。
|
||||
|
|
|
@ -1,12 +1,12 @@
|
|||
## 配置 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
|
||||
|
|
|
@ -5,4 +5,4 @@
|
|||
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 的伺服器。
|
||||
|
|
|
@ -13,7 +13,7 @@ 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 的好處是它能動態從網卡取得地址。
|
||||
|
||||
### 外部訪問容器實做
|
||||
|
||||
|
@ -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 服務即可生效。
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
使用者有時候需要兩個容器之間可以直連通信,而不用透過主機網橋進行橋接。
|
||||
|
||||
解決辦法很簡單:建立一對 `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
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## 快速配置指南
|
||||
## 快速設定指南
|
||||
|
||||
下面是一個跟 Docker 網路相關的命令列表。
|
||||
|
||||
其中有些命令選項只有在 Docker 服務啟動的時候才能配置,而且不能馬上生效。
|
||||
其中有些命令選項只有在 Docker 服務啟動的時候才能設定,而且不能馬上生效。
|
||||
* `-b BRIDGE or --bridge=BRIDGE` --指定容器掛載的網橋
|
||||
* `--bip=CIDR` --定制 docker0 的掩碼
|
||||
* `-H SOCKET... or --host=SOCKET...` --Docker 服務端接收命令的通道
|
||||
|
@ -12,12 +12,12 @@
|
|||
* `--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` --配置容器主機名
|
||||
* `-h HOSTNAME or --hostname=HOSTNAME` --設定容器主機名
|
||||
* `--link=CONTAINER_NAME:ALIAS` --新增到另一個容器的連接
|
||||
* `--net=bridge|none|container:NAME_or_ID|host` --配置容器的橋接模式
|
||||
* `--net=bridge|none|container:NAME_or_ID|host` --設定容器的橋接模式
|
||||
* `-p SPEC or --publish=SPEC` --映射容器端口到宿主主機
|
||||
* `-P or --publish-all=true|false` --映射容器所有端口到宿主主機
|
||||
|
|
|
@ -74,7 +74,7 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
|
|||
檢查一個容器文件系統的修改
|
||||
|
||||
docker-events(1)
|
||||
從服務端獲取實時的事件
|
||||
從服務端取得實時的事件
|
||||
|
||||
docker-export(1)
|
||||
匯出容器內容為一個 tar 包
|
||||
|
@ -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 到一個私有網口的公共口
|
||||
|
@ -152,10 +152,10 @@ Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。
|
|||
為一個映像檔打標簽
|
||||
|
||||
docker-top(1)
|
||||
查看一個容器中的正在執行的程序資訊
|
||||
查看一個容器中的正在執行的程式資訊
|
||||
|
||||
docker-unpause(1)
|
||||
將一個容器內所有的程序從暫停狀態中恢復
|
||||
將一個容器內所有的程式從暫停狀態中恢復
|
||||
|
||||
docker-version(1)
|
||||
輸出 Docker 的版本資訊
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [CentOS](https://registry.hub.docker.com/_/centos/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 發行版,其軟件包大多跟 RedHat 系列保持一致。
|
||||
該倉庫提供了 CentOS 從 5 ~ 7 各個版本的鏡像。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [MongoDB](https://registry.hub.docker.com/_/mongo/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是開源的 NoSQL 數據庫實做。
|
||||
該倉庫提供了 MongoDB 2.2 ~ 2.7 各個版本的鏡像。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [MySQL](https://registry.hub.docker.com/_/mysql/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是開源的關系數據庫實做。
|
||||
該倉庫提供了 MySQL 各個版本的鏡像,包括 5.6 系列、5.7 系列等。
|
||||
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## [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
|
||||
```
|
||||
|
@ -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)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [Node.js](https://registry.hub.docker.com/_/node/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[Node.js](https://en.wikipedia.org/wiki/Node.js)是基於 JavaScript 的可擴展服務端和網路軟件開發平臺。
|
||||
該倉庫提供了 Node.js 0.8 ~ 0.11 各個版本的鏡像。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [Redis](https://registry.hub.docker.com/_/redis/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是開源的內存 Key-Value 數據庫實做。
|
||||
該倉庫提供了 Redis 2.6 ~ 2.8.9 各個版本的鏡像。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [Ubuntu](https://registry.hub.docker.com/_/ubuntu/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 發行版,其自帶軟件版本往往較新一些。
|
||||
該倉庫提供了 Ubuntu從12.04 ~ 14.10 各個版本的鏡像。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## [WordPress](https://registry.hub.docker.com/_/wordpress/)
|
||||
|
||||
### 基本信息
|
||||
### 基本訊息
|
||||
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是開源的 Blog 和內容管理系統框架,它基於 PhP 和 MySQL。
|
||||
該倉庫提供了 WordPress 4.0 版本的鏡像。
|
||||
|
||||
|
|
|
@ -3,6 +3,6 @@ Docker 利用容器來執行應用。
|
|||
|
||||
容器是從映像檔建立的執行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。
|
||||
|
||||
可以把容器看做是一個簡易版的 Linux 環境(包括root使用者權限、程序空間、使用者空間和網路空間等)和在其中執行的應用程序。
|
||||
可以把容器看做是一個簡易版的 Linux 環境(包括root使用者權限、程式空間、使用者空間和網路空間等)和在其中執行的應用程式。
|
||||
|
||||
*註:映像檔是唯讀的,容器在啟動的時候建立一層可寫層作為最上層。
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Docker 映像檔
|
||||
Docker 映像檔就是一個唯讀的模板。
|
||||
|
||||
例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或使用者需要的其它應用程序。
|
||||
例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或使用者需要的其它應用程式。
|
||||
|
||||
映像檔可以用來建立 Docker 容器。
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
## Docker 倉庫
|
||||
|
||||
倉庫是集中存放映像檔文件的場所。有時候會把倉庫和倉庫註冊服務器(Registry)混為一談,並不嚴格區分。實際上,倉庫註冊服務器上往往存放著多個倉庫,每個倉庫中又包含了多個映像檔,每個鏡像有不同的標籤(tag)。
|
||||
倉庫是集中存放映像檔文件的場所。有時候會把倉庫和倉庫註冊伺服器(Registry)混為一談,並不嚴格區分。實際上,倉庫註冊伺服器上往往存放著多個倉庫,每個倉庫中又包含了多個映像檔,每個鏡像有不同的標籤(tag)。
|
||||
|
||||
倉庫分為公開倉庫(Public)和私有倉庫(Private)兩種形式。
|
||||
|
||||
|
@ -11,4 +11,4 @@
|
|||
|
||||
當使用者建立了自己的映像檔之後就可以使用 `push` 命令將它上傳到公有或者私有倉庫,這樣下次在另外一台機器上使用這個映像檔時候,只需要從倉庫上 `pull` 下來就可以了。
|
||||
|
||||
*註:Docker 倉庫的概念跟 [Git](http://git-scm.com) 類似,註冊服務器可以理解為 GitHub 這樣的託管服務。
|
||||
*註:Docker 倉庫的概念跟 [Git](http://git-scm.com) 類似,註冊伺服器可以理解為 GitHub 這樣的託管服務。
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## 多臺物理主機之間的容器互聯(暴露容器到真實網路中)
|
||||
Docker 默認的橋接網卡是 docker0。它只會在本機橋接所有的容器網卡,舉例來說容器的虛擬網卡在主機上看一般叫做 veth*** 而 Docker 只是把所有這些網卡橋接在一起,如下:
|
||||
Docker 默認的橋接網卡是 docker0。它只會在本機橋接所有的容器網卡,舉例來說容器的虛擬網卡在主機上看一般叫做 veth*** 而 Docker 只是把所有這些網卡橋接在一起,以下:
|
||||
```
|
||||
[root@opnvz ~]# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
|
|
|
@ -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 目錄啟動即可。這樣,在公司內部的開發、測試基本就統一了,不會出現開發部門提交的代碼,測試部門部署不了的問題。
|
||||
|
||||
測試部門發布測試透過的報告後,架構師再一次檢測容器環境,就可以直接交由部署工程師將代碼和容器分別部署到生產環境中了。這種方式的部署橫向性能的擴展性也極好。
|
||||
測試部門發布測試透過的報告後,架構師再一次檢測容器環境,就可以直接交由部署工程師將代碼和容器分別部署到生產環境中了。這種方式的部署橫向效能的擴展性也極好。
|
||||
|
|
|
@ -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,7 +44,7 @@ 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 個服務。每一段包含一個服務的目錄和啟動這個服務的命令。
|
||||
|
||||
### 使用方法
|
||||
建立鏡像。
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
```
|
||||
docker run -t -i -v /home:/opt/data --name mk_tomcat ubuntu /bin/bash
|
||||
```
|
||||
這條命令掛載本地 home 目錄到容器的 /opt/data 目錄,容器內目錄若不存在,則會自動建立。接下來就是 tomcat 的基本配置,jdk 環境變量設置好之後,將 tomcat 程序放到 /opt/apache-tomcat 下面
|
||||
這條命令掛載本地 home 目錄到容器的 /opt/data 目錄,容器內目錄若不存在,則會自動建立。接下來就是 tomcat 的基本設定,jdk 環境變量設置好之後,將 tomcat 程式放到 /opt/apache-tomcat 下面
|
||||
編輯 /etc/supervisor/conf.d/supervisor.conf 文件,新增 tomcat 項
|
||||
```
|
||||
[supervisord]
|
||||
|
@ -30,7 +30,7 @@ docker build tomcat tomcat
|
|||
```
|
||||
### 安裝 weblogic 鏡像
|
||||
|
||||
步驟和 tomcat 基本一致,這裏貼一下配置文件
|
||||
步驟和 tomcat 基本一致,這裡貼一下設定文件
|
||||
```
|
||||
supervisor.conf
|
||||
[supervisord]
|
||||
|
@ -54,7 +54,7 @@ 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 只要開啟多個容器即可
|
||||
|
@ -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 來做負載均衡就可以完成設定了
|
||||
|
|
|
@ -2,19 +2,19 @@
|
|||
|
||||
更多的時候,需要讓 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
|
||||
|
|
|
@ -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)版,請按照以下步驟:
|
||||
```
|
||||
$ 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
|
||||
$ sudo cp nsenter /usr/local/bin
|
||||
```
|
||||
為了連接到容器,你還需要找到容器的第一個程序的 PID,可以透過下面的命令獲取。
|
||||
為了連接到容器,你還需要找到容器的第一個程式的 PID,可以透過下面的命令取得。
|
||||
```
|
||||
PID=$(docker inspect --format "{{ .State.Pid }}" <container>)
|
||||
```
|
||||
|
@ -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
|
||||
|
|
|
@ -23,6 +23,6 @@ test/ubuntu v1.0 9d37a6082e97 About a minute ago
|
|||
$sudo docker import http://example.com/exampleimage.tgz example/imagerepo
|
||||
```
|
||||
|
||||
*註:使用者既可以使用 `docker load` 來導入映像檔儲存文件到本地映像檔庫,也可以使用 `docker import` 來導入一個容器快照到本地映像檔庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和原始數據信息(即僅保存容器當時的快照狀態),而映像檔儲存文件將保存完整記錄,檔案體積也跟著變大。此外,從容器快照文件導入時可以重新指定標簽等原始數據信息。
|
||||
*註:使用者既可以使用 `docker load` 來導入映像檔儲存文件到本地映像檔庫,也可以使用 `docker import` 來導入一個容器快照到本地映像檔庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和原始數據訊息(即僅保存容器當時的快照狀態),而映像檔儲存文件將保存完整記錄,檔案體積也跟著變大。此外,從容器快照文件導入時可以重新指定標簽等原始數據訊息。
|
||||
|
||||
|
||||
|
|
|
@ -33,15 +33,15 @@ bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr
|
|||
* 檢查本地是否存在指定的映像檔,不存在就從公有倉庫下載
|
||||
* 利用映像檔建立並啟動一個容器
|
||||
* 分配一個文件系統,並在唯讀的映像檔層外面掛載一層可讀寫層
|
||||
* 從宿主主機配置的網路橋接口中橋接一個虛擬埠到容器中去
|
||||
* 從地址堆中配置一個 ip 地址給容器
|
||||
* 執行使用者指定的應用程序
|
||||
* 從宿主主機設定的網路橋接口中橋接一個虛擬埠到容器中去
|
||||
* 從地址堆中設定一個 ip 地址給容器
|
||||
* 執行使用者指定的應用程式
|
||||
* 執行完畢後容器被終止
|
||||
|
||||
###啟動已終止容器
|
||||
可以利用 `docker start` 命令,直接將一個已經終止的容器啟動執行。
|
||||
|
||||
容器的核心為所執行的應用程序,所需要的資源都是應用程序執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps` 或 `top` 來查看程序信息。
|
||||
容器的核心為所執行的應用程式,所需要的資源都是應用程式執行所必需的。除此之外,並沒有其它的資源。可以在偽終端中利用 `ps` 或 `top` 來查看程式訊息。
|
||||
```
|
||||
root@ba267838cc1b:/# ps
|
||||
PID TTY TIME CMD
|
||||
|
|
|
@ -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
|
||||
```
|
||||
|
|
|
@ -9,9 +9,9 @@
|
|||
|
||||
|
||||
### 建立一個數據卷
|
||||
在用 `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
|
||||
```
|
||||
|
@ -22,8 +22,8 @@ $ sudo docker run -d -P --name web -v /webapp training/webapp python app.py
|
|||
```
|
||||
$ 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 是為了移植和分享用的。然而,不同作業系統的路徑格式不一樣,所以目前還不能支持。
|
||||
|
||||
|
@ -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起,這會導致報錯誤訊息。所以最簡單的辦法就直接掛載文件的父目錄。
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## 基本結構
|
||||
Dockerfile 由一行行命令語句組成,並且支援以 `#` 開頭的註釋行。
|
||||
Dockerfile 由一行行命令語句組成,並且支援以 `#` 開頭的註解行。
|
||||
|
||||
一般而言,Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時執行指令。
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
第一條指令必須為 `FROM` 指令。並且,如果在同一個Dockerfile中建立多個映像檔時,可以使用多個 `FROM` 指令(每個映像檔一次)。
|
||||
|
||||
### MAINTAINER
|
||||
格式為 `MAINTAINER <name>`,指定維護者信息。
|
||||
格式為 `MAINTAINER <name>`,指定維護者訊息。
|
||||
|
||||
### RUN
|
||||
格式為 `RUN <command>` 或 `RUN ["executable", "param1", "param2"]`。
|
||||
|
@ -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
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
在之前的介紹中,我們知道鏡像是 Docker 的三大組件之一。
|
||||
|
||||
Docker 在執行容器前需要本地存在對應的鏡像,如果鏡像不存在本地,Docker 會從鏡像倉庫下載(預設是 Docker Hub 公共註冊服務器中的倉庫)。
|
||||
Docker 在執行容器前需要本地存在對應的鏡像,如果鏡像不存在本地,Docker 會從鏡像倉庫下載(預設是 Docker Hub 公共註冊伺服器中的倉庫)。
|
||||
|
||||
本章將介紹更多關於鏡像的內容,包括:
|
||||
* 從倉庫獲取鏡像;
|
||||
* 從倉庫取得鏡像;
|
||||
* 管理本地主機上的鏡像;
|
||||
* 介紹鏡像實做的基本原理。
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
##建立鏡像
|
||||
|
||||
建立鏡像有很多方法,使用者可以從 Docker Hub 獲取已有鏡像並更新,也可以利用本地文件系統建立一個。
|
||||
建立鏡像有很多方法,使用者可以從 Docker Hub 取得已有鏡像並更新,也可以利用本地文件系統建立一個。
|
||||
|
||||
### 修改已有鏡像
|
||||
先使用下載的鏡像啟動容器。
|
||||
|
@ -19,7 +19,7 @@ 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` 來查看新建立的鏡像。
|
||||
|
@ -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 來進行。
|
||||
可以看到 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
|
||||
|
|
|
@ -4,4 +4,4 @@ Docker 鏡像是怎麽實做增量的修改和維護的?
|
|||
每個鏡像都由很多層次構成,Docker 使用 [Union FS](http://en.wikipedia.org/wiki/UnionFS) 將這些不同的層結合到一個鏡像中去。
|
||||
|
||||
通常 Union FS 有兩個用途, 一方面可以實做不借助 LVM、RAID 將多個 disk 掛到同一個目錄下,另一個更常用的就是將一個唯讀的分支和一個可寫的分支聯合在一起,Live CD 正是基於此方法可以允許在鏡像不變的基礎上允許使用者在其上進行一些寫操作。
|
||||
Docker 在 AUFS 上構建的容器也是利用了類似的原理。
|
||||
Docker 在 AUFS 上建立的容器也是利用了類似的原理。
|
||||
|
|
|
@ -21,7 +21,7 @@ ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
|
|||
|
||||
其中鏡像的 `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
|
||||
```
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -19,4 +19,4 @@ $ sudo docker load --input ubuntu_14.04.tar
|
|||
```
|
||||
$ sudo docker load < ubuntu_14.04.tar
|
||||
```
|
||||
這將導入鏡像以及其相關的元數據信息(包括標簽等)。
|
||||
這將導入鏡像以及其相關的元數據訊息(包括標簽等)。
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -4,27 +4,27 @@
|
|||
首先,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 |
|
||||
| 性能 | 接近原生 | 比較慢 |
|
||||
| 效能 | 接近原生 | 比較慢 |
|
||||
| 系統支持量 | 單機支持上千個容器 | 一般幾十個 |
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## 容器互聯
|
||||
容器的連接(linking)系統是除了端口映射外,另一種跟容器中應用交互的方式。
|
||||
|
||||
該系統會在源和接收容器之間建立一個隧道,接收容器可以看到源容器指定的信息。
|
||||
該系統會在源和接收容器之間建立一個隧道,接收容器可以看到源容器指定的訊息。
|
||||
|
||||
### 自定義容器命名
|
||||
連接系統依據容器的名稱來執行。因此,首先需要自定義一個好記的容器命名。
|
||||
|
@ -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 和 web,db 容器的 names 列有 db 也有 web/db。這表示 web 容器鏈接到 db 容器,web 容器將被允許訪問 db 容器的信息。
|
||||
可以看到自定義命名的容器,db 和 web,db 容器的 names 列有 db 也有 web/db。這表示 web 容器鏈接到 db 容器,web 容器將被允許訪問 db 容器的訊息。
|
||||
|
||||
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
|
||||
|
|
|
@ -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 標記可以多次使用來綁定多個端口
|
||||
|
||||
例如
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
## 倉庫配置文件
|
||||
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 服務,本地文件系統為後備
|
||||
|
@ -22,9 +22,9 @@ Docker 的 Registry 利用配置文件提供了一些倉庫的模組(flavor)
|
|||
export SETTINGS_FLAVOR=dev
|
||||
```
|
||||
|
||||
另外,配置文件中支持從環境變數中加載值,語法格式為 `_env:VARIABLENAME[:DEFAULT]`。
|
||||
另外,設定文件中支持從環境變數中載入值,語法格式為 `_env:VARIABLENAME[:DEFAULT]`。
|
||||
|
||||
### 範例配置
|
||||
### 範例設定
|
||||
```
|
||||
common:
|
||||
loglevel: info
|
||||
|
|
|
@ -40,15 +40,15 @@ Pulling repository centos
|
|||
使用者也可以在登錄後透過 `docker push` 命令來將映像檔推送到 Docker Hub。
|
||||
|
||||
### 自動建立
|
||||
自動建立(Automated Builds)功能對於需要經常升級映像檔內程序來說,十分方便。
|
||||
自動建立(Automated Builds)功能對於需要經常升級映像檔內程式來說,十分方便。
|
||||
有時候,使用者建立了映像檔,安裝了某個軟體,如果軟體發布新版本則需要手動更新映像檔。。
|
||||
|
||||
而自動建立允許使用者透過 Docker Hub 指定跟蹤一個目標網站(目前支持 [GitHub](github.org) 或 [BitBucket](bitbucket.org))上的項目,一旦項目發生新的提交,則自動執行建立。
|
||||
|
||||
要配置自動建立,包括如下的步驟:
|
||||
要設定自動建立,包括以下的步驟:
|
||||
* 建立並登陸 Docker Hub,以及目標網站;
|
||||
* 在目標網站中連接帳戶到 Docker Hub;
|
||||
* 在 Docker Hub 中 [配置一個自動建立](https://registry.hub.docker.com/builds/add/);
|
||||
* 在 Docker Hub 中 [設定一個自動建立](https://registry.hub.docker.com/builds/add/);
|
||||
* 選取一個目標網站中的項目(需要含 Dockerfile)和分支;
|
||||
* 指定 Dockerfile 的位置,並提交建立。
|
||||
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
|
||||
本節介紹如何使用本地倉庫。
|
||||
|
||||
`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,12 +24,12 @@ $ 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` 目錄。
|
||||
例以下面的例子將上傳的映像檔放到 `/opt/data/registry` 目錄。
|
||||
```
|
||||
$ sudo docker run -d -p 5000:5000 -v /opt/data/registry:/tmp/registry registry
|
||||
```
|
||||
|
@ -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,7 +68,7 @@ $ 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`。
|
||||
|
@ -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"}`,表明映像檔已經被成功上傳了。
|
||||
|
||||
現在可以到另外一臺機器去下載這個映像檔。
|
||||
```
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 安全
|
||||
評估 Docker 的安全性時,主要考慮三個方面:
|
||||
* 由內核的名字空間和控制組機制提供的容器內在安全
|
||||
* Docker程序(特別是服務端)本身的抗攻擊性
|
||||
* Docker程式(特別是服務端)本身的抗攻擊性
|
||||
* 內核安全性的加強機制對容器安全性的影響
|
||||
|
|
|
@ -3,6 +3,6 @@
|
|||
|
||||
它提供了很多有用的特性;以及確保各個容器可以公平地分享主機的內存、CPU、磁盤 IO 等資源;當然,更重要的是,控制組確保了當容器內的資源使用產生壓力時不會連累主機系統。
|
||||
|
||||
盡管控制組不負責隔離容器之間相互訪問、處理數據和程序,它在防止拒絕服務(DDOS)攻擊方面是必不可少的。尤其是在多使用者的平臺(比如公有或私有的 PaaS)上,控制組十分重要。例如,當某些應用程序表現異常的時候,可以保證一致地正常執行和性能。
|
||||
盡管控制組不負責隔離容器之間相互訪問、處理數據和程式,它在防止拒絕服務(DDOS)攻擊方面是必不可少的。尤其是在多使用者的平臺(比如公有或私有的 PaaS)上,控制組十分重要。例如,當某些應用程式表現異常的時候,可以保證一致地正常執行和效能。
|
||||
|
||||
控制組機制始於 2006 年,內核從 2.6.24 版本開始被引入。
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## Docker服務端的防護
|
||||
執行一個容器或應用程序的核心是透過 Docker 服務端。Docker 服務的執行目前需要 root 權限,因此其安全性十分關鍵。
|
||||
執行一個容器或應用程式的核心是透過 Docker 服務端。Docker 服務的執行目前需要 root 權限,因此其安全性十分關鍵。
|
||||
|
||||
首先,確保只有可信的使用者才可以訪問 Docker 服務。Docker 允許使用者在主機和容器間共享文件夾,同時不需要限制容器的訪問權限,這就容易讓容器突破資源限制。例如,惡意使用者啟動容器的時候將主機的根目錄`/`映射到容器的 `/host` 目錄中,那麽容器理論上就可以對主機的文件系統進行任意修改了。這聽起來很瘋狂?但是事實上幾乎所有虛擬化系統都允許類似的資源共享,而沒法禁止使用者共享主機根文件系統到虛擬機系統。
|
||||
|
||||
這將會造成很嚴重的安全後果。因此,當提供容器建立服務時(例如透過一個 web 服務器),要更加註意進行參數的安全檢查,防止惡意的使用者用特定參數來建立一些破壞性的容器
|
||||
這將會造成很嚴重的安全後果。因此,當提供容器建立服務時(例如透過一個 web 伺服器),要更加註意進行參數的安全檢查,防止惡意的使用者用特定參數來建立一些破壞性的容器
|
||||
|
||||
為了加強對服務端的保護,Docker 的 REST API(客戶端用來跟服務端通信)在 0.5.2 之後使用本地的 Unix 套接字機制替代了原先綁定在 127.0.0.1 上的 TCP 套接字,因為後者容易遭受跨站腳本攻擊。現在使用者使用 Unix 權限檢查來加強套接字的訪問安全。
|
||||
|
||||
|
@ -13,6 +13,6 @@
|
|||
|
||||
終極目標是改進 2 個重要的安全特性:
|
||||
* 將容器的 root 使用者映射到本地主機上的非 root 使用者,減輕容器和主機之間因權限提升而引起的安全問題;
|
||||
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程序來代理執行需要特權權限的操作。這些子程序將只允許在限定範圍內進行操作,例如僅僅負責虛擬網路設定或文件系統管理、配置操作等。
|
||||
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程式來代理執行需要特權權限的操作。這些子程式將只允許在限定範圍內進行操作,例如僅僅負責虛擬網路設定或文件系統管理、設定操作等。
|
||||
|
||||
最後,建議采用專用的服務器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程序監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
|
||||
最後,建議采用專用的伺服器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程式監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
|
||||
|
|
|
@ -1,24 +1,24 @@
|
|||
## 內核能力機制
|
||||
|
||||
能力機制(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 權限,也不能獲得本地主機的較高權限,能進行的破壞也有限。
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## 內核名字空間
|
||||
Docker 容器和 LXC 容器很相似,所提供的安全特性也差不多。當用 `docker run` 啟動一個容器時,在後臺 Docker 為容器建立了一個獨立的名字空間和控制組集合。
|
||||
|
||||
名字空間提供了最基礎也是最直接的隔離,在容器中執行的程序不會被執行在主機上的程序和其它容器發現和作用。
|
||||
名字空間提供了最基礎也是最直接的隔離,在容器中執行的程式不會被執行在主機上的程式和其它容器發現和作用。
|
||||
|
||||
每個容器都有自己獨有的網路棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據配置來限制通信的策略)。
|
||||
每個容器都有自己獨有的網路棧,意味著它們不能訪問其他容器的 sockets 或接口。不過,如果主機系統上做了相應的設置,容器可以像跟主機交互一樣的和其他容器交互。當指定公共端口或使用 links 來連接 2 個容器時,容器就可以相互通信了(可以根據設定來限制通信的策略)。
|
||||
|
||||
從網路架構的角度來看,所有的容器透過本地主機的網橋接口相互通信,就像物理機器透過物理交換機通信一樣。
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
除了能力機制之外,還可以利用一些現有的安全機制來增強使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。
|
||||
|
||||
Docker 當前默認只啟用了能力機制。使用者可以采用多種方案來加強 Docker 主機的安全,例如:
|
||||
* 在內核中啟用 GRSEC 和 PAX,這將增加很多編譯和執行時的安全檢查;透過地址隨機化避免惡意探測等。並且,啟用該特性不需要 Docker 進行任何配置。
|
||||
* 在內核中啟用 GRSEC 和 PAX,這將增加很多編譯和執行時的安全檢查;透過地址隨機化避免惡意探測等。並且,啟用該特性不需要 Docker 進行任何設定。
|
||||
* 使用一些有增強安全特性的容器模板,比如帶 AppArmor 的模板和 Redhat 帶 SELinux 策略的模板。這些模板提供了額外的安全特性。
|
||||
* 使用者可以自定義訪問控制機制來定制安全策略。
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## 總結
|
||||
總體來看,Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程序的話。
|
||||
總體來看,Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程式的話。
|
||||
|
||||
另外,使用者可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實做更復雜的安全機制。
|
||||
|
|
|
@ -6,8 +6,8 @@ Docker 底層的核心技術包括 Linux 上的名字空間(Namespaces)、
|
|||
這種直接的做法實做了對資源最完整的封裝,但很多時候往往意味著系統資源的浪費。
|
||||
例如,以宿主機和虛擬機系統都為 Linux 系統為例,虛擬機中執行的應用其實可以利用宿主機系統中的執行環境。
|
||||
|
||||
我們知道,在作業系統中,包括內核、文件系統、網路、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用程序直接共享的。
|
||||
我們知道,在作業系統中,包括內核、文件系統、網路、PID、UID、IPC、內存、硬盤、CPU 等等,所有的資源都是應用程式直接共享的。
|
||||
要想實做虛擬化,除了要實做對內存、CPU、網路IO、硬盤IO、存儲空間等的限制外,還要實做文件系統、網路、PID、UID、IPC等等的相互隔離。
|
||||
前者相對容易實做一些,後者則需要宿主機系統的深入支持。
|
||||
|
||||
隨著 Linux 系統對於名字空間功能的完善實做,程序員已經可以實做上面的所有需求,讓某些程序在彼此隔離的名字空間中執行。大家雖然都共用一個內核和某些執行時環境(例如一些系統命令和系統庫),但是彼此卻看不到,都以為系統中只有自己的存在。這種機制就是容器(Container),利用名字空間來做權限的隔離控制,利用 cgroups 來做資源分配。
|
||||
隨著 Linux 系統對於名字空間功能的完善實做,程式員已經可以實做上面的所有需求,讓某些程式在彼此隔離的名字空間中執行。大家雖然都共用一個內核和某些執行時環境(例如一些系統命令和系統庫),但是彼此卻看不到,都以為系統中只有自己的存在。這種機制就是容器(Container),利用名字空間來做權限的隔離控制,利用 cgroups 來做資源分配。
|
||||
|
|
|
@ -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 等資源的限制和審計管理。
|
||||
|
||||
|
|
|
@ -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 連接在一起。
|
||||
|
||||
### 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/) 介紹的很好。
|
||||
|
|
|
@ -11,29 +11,29 @@ Linux 透過在內核中進行數據復制來實做虛擬接口之間的數據
|
|||
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,7 +41,7 @@ $ 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: ...
|
||||
|
@ -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` 卸載。
|
||||
|
||||
此外,使用者可以使用 `ip netns exec` 命令來在指定網路名字空間中進行配置,從而配置容器內的網路。
|
||||
此外,使用者可以使用 `ip netns exec` 命令來在指定網路名字空間中進行設定,從而設定容器內的網路。
|
||||
|
|
|
@ -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 鏡像的基礎。鏡像可以透過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。
|
||||
|
||||
另外,不同 Docker 容器就可以共享一些基礎的文件系統層,同時再加上自己獨有的改動層,大大提高了存儲的效率。
|
||||
|
||||
Docker 中使用的 AUFS(AnotherUnionFS)就是一種 Union FS。 AUFS 支持為每一個成員目錄(類似 Git 的分支)設定唯讀(readonly)、讀寫(readwrite)和寫出(whiteout-able)權限, 同時 AUFS 裏有一個類似分層的概念, 對唯讀權限的分支可以邏輯上進行增量地修改(不影響唯讀部分的)。
|
||||
Docker 中使用的 AUFS(AnotherUnionFS)就是一種 Union FS。 AUFS 支持為每一個成員目錄(類似 Git 的分支)設定唯讀(readonly)、讀寫(readwrite)和寫出(whiteout-able)權限, 同時 AUFS 裡有一個類似分層的概念, 對唯讀權限的分支可以邏輯上進行增量地修改(不影響唯讀部分的)。
|
||||
|
||||
Docker 目前支持的 Union 文件系統種類包括 AUFS, btrfs, vfs 和 DeviceMapper。
|
||||
|
|
Loading…
Reference in New Issue