commit
59da0ff5ad
119
README.md
119
README.md
|
@ -1,66 +1,95 @@
|
|||
Docker —— 从入门到实践
|
||||
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 版本对内容进行了修订和重写,并增加内容;经协商将所有内容开源,采用互联网合作的方式进行维护。
|
||||
本書源於 [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 的基本概念和操作;7 ~ 9 章介绍一些高级操作;第 10 章给出典型的应用场景和实践案例;11 ~ 13 章介绍关于 Docker 实现的相关技术。
|
||||
前六章為基礎內容,供使用者理解 Docker 的基本概念和操作;7 ~ 9 章介紹一些進階操作;第 10 章給出典型的應用場景和實踐案例;11 ~ 13 章介紹關於 Docker 實做的相關技術。
|
||||
|
||||
最新版本在线阅读:[GitBook](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)。
|
||||
|
||||
另外,欢迎加入 DockerPool QQ 群(341410255),分享 Docker 资源,交流 Docker 技术。
|
||||
另外,歡迎加入 [Docker.Taipei](https://www.facebook.com/groups/docker.taipei/) 和 [Meetup](http://www.meetup.com/Docker-Taipei/) ,分享 Docker 資源,交流 Docker 技術。
|
||||
|
||||
|
||||
本书源码在 Github 上维护,欢迎参与: [https://github.com/yeasy/docker_practice](https://github.com/yeasy/docker_practice)。
|
||||
本書原始碼在 Github 上維護,歡迎參與: [https://github.com/philipz/docker_practice](https://github.com/philipz/docker_practice)。
|
||||
|
||||
感谢所有的 [贡献者](https://github.com/yeasy/docker_practice/graphs/contributors)。
|
||||
感謝所有的 [貢獻者](https://github.com/philipz/docker_practice/graphs/contributors)。
|
||||
|
||||
## 主要版本历史
|
||||
## 主要版本歷史
|
||||
* 0.3: 2014-10-TODO
|
||||
* 完成仓库章节;
|
||||
* 重写安全章节;
|
||||
* 修正底层实现章节的架构、名字空间、控制组、文件系统、容器格式等内容;
|
||||
* 添加对常见仓库和镜像的介绍;
|
||||
* 添加 Dockerfile 的介绍;
|
||||
* 重新校订中英文混排格式。
|
||||
* 完成倉庫章節;
|
||||
* 重寫安全章節;
|
||||
* 修正底層實做章節的架構、名字空間、控制組、檔案系統、容器格式等內容;
|
||||
* 新增對常見倉庫和鏡像的介紹;
|
||||
* 新增 Dockerfile 的介紹;
|
||||
* 重新校訂中英文混排格式。
|
||||
* 0.2: 2014-09-18
|
||||
* 对照官方文档重写介绍、基本概念、安装、镜像、容器、仓库、数据管理、网络等章节;
|
||||
* 添加底层实现章节;
|
||||
* 添加命令查询和资源链接章节;
|
||||
* 對照官方文檔重寫介紹、基本概念、安裝、鏡像、容器、倉庫、資料管理、網路等章節;
|
||||
* 新增底層實做章節;
|
||||
* 新增命令查詢和資源連結章節;
|
||||
* 其它修正。
|
||||
* 0.1: 2014-09-05
|
||||
* 添加基本内容;
|
||||
* 修正错别字和表达不通顺的地方。
|
||||
* 新增基本內容;
|
||||
* 修正錯別字和表達不通順的地方。
|
||||
|
||||
## 貢獻力量
|
||||
|
||||
## 参加步骤
|
||||
* 在 GitHub 上 `fork` 到自己的仓库,如 `docker_user/docker_practice`,然后 `clone` 到本地,并设置用户信息。
|
||||
```
|
||||
$ git clone git@github.com:docker_user/docker_practice.git
|
||||
$ cd docker_practice
|
||||
$ git config user.name "Docker User"
|
||||
$ git config user.email docker_user@dockcer.com
|
||||
```
|
||||
* 修改代码后提交,并推送到自己的仓库。
|
||||
```
|
||||
$ #do some change on the content
|
||||
$ git commit -am "Fix issue #1: change helo to hello"
|
||||
$ git push
|
||||
```
|
||||
* 在 GitHub 网站上提交 pull request。
|
||||
* 定期使用项目仓库内容更新自己仓库内容。
|
||||
```
|
||||
$ git remote add upstream https://github.com/yeasy/docker_practice
|
||||
$ git fetch upstream
|
||||
$ git checkout master
|
||||
$ git rebase upstream/master
|
||||
$ git push -f origin master
|
||||
```
|
||||
如果想做出貢獻的話,你可以:
|
||||
|
||||
- 幫忙校對,挑錯別字、語病等等
|
||||
- 提出修改建議
|
||||
- 提出術語翻譯建議
|
||||
|
||||
## 翻譯建議
|
||||
|
||||
如果你願意一起校對的話,請仔細閱讀:
|
||||
|
||||
- 使用 markdown 進行翻譯,文件名必須使用英文,因為中文的話 gitbook 編譯的時候會出問題
|
||||
- 引號請使用「」和『』
|
||||
- fork 過去之後新建一個分支進行翻譯,完成後 pull request 這個分支,沒問題的話我會合併到 master 分支中
|
||||
- 有其他任何問題都歡迎發 issue,我看到了會盡快回覆
|
||||
|
||||
謝謝!
|
||||
|
||||
## 關於術語
|
||||
|
||||
翻譯術語的時候請參考這個流程:
|
||||
|
||||
- 盡量保證與台灣習慣術語和已翻譯的內容一致
|
||||
- 盡量先搜尋,一般來說程式語言的大部分術語是一樣的,可以參考[這個網站](http://jjhou.boolan.com/terms.htm)
|
||||
- 如果以上兩條都沒有找到合適的結果,請自己決定一個合適的翻譯或者直接使用英文原文,後期校對的時候會進行統一
|
||||
- 校稿時,若有發現沒有被翻譯成台灣術語的大陸術語,可以將它新增到 translation.json 中
|
||||
- 可以主動提交替換過的文本給我,或是僅提交新增過的 translation.json 也可,我會再進行文本的替換
|
||||
- 請務必確定提交的翻譯對照組不會造成字串循環替代(ex: 因為「類」->「類別」,造成下次再執行自動翻譯時「類別」又變成「類別別」)
|
||||
|
||||
對翻譯有任何意見都歡迎發 issue,我看到了會盡快回覆
|
||||
|
||||
## 參加步驟
|
||||
|
||||
參考 [Swift 說明](https://github.com/tommy60703/the-swift-programming-language-in-traditional-chinese/),欲翻譯章節就直接在 github 上發 Issue 中註明或直接發Pull Request 修改。m(_ _)m
|
||||
有些朋友可能不太清楚如何幫忙翻譯,我這裡寫一個簡單的流程,大家可以參考一下:
|
||||
|
||||
1. 首先 fork 我的項目
|
||||
2. 把 fork 過去的項目也就是你的項目 clone 到你的本地
|
||||
3. 在命令行執行 `git branch develop` 來建立一個新分支
|
||||
4. 執行 `git checkout develop` 來切換到新分支
|
||||
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` 將我的更新合並到你的分支
|
||||
|
||||
這是一個初始化流程,只需要做一遍就行,之後請一直在 develop 分支進行修改。
|
||||
|
||||
如果修改過程中我的庫有了更新,請重復 6、7、8 步。
|
||||
|
||||
修改之後,首先 push 到你的庫,然後登錄 GitHub,在你的 repo 的首頁可以看到一個 `pull request` 按鈕,點擊它,填寫一些說明資訊,然後提交即可。
|
||||
|
||||
## 原出處及參考資料
|
||||
1. [Docker —— 从入门到实践](https://github.com/yeasy/docker_practice/)
|
||||
2. [《The Swift Programming Language》正體中文版](https://github.com/tommy60703/the-swift-programming-language-in-traditional-chinese/)
|
||||
|
|
118
SUMMARY.md
118
SUMMARY.md
|
@ -1,76 +1,76 @@
|
|||
# Summary
|
||||
|
||||
* [前言](README.md)
|
||||
* [Docker 简介](introduction/README.md)
|
||||
* [什么是 Docker](introduction/what.md)
|
||||
* [为什么要用 Docker](introduction/why.md)
|
||||
* [Docker 簡介](introduction/README.md)
|
||||
* [什麼是 Docker](introduction/what.md)
|
||||
* [為什麼要用 Docker](introduction/why.md)
|
||||
* [基本概念](basic_concept/README.md)
|
||||
* [镜像](basic_concept/image.md)
|
||||
* [映像檔](basic_concept/image.md)
|
||||
* [容器](basic_concept/container.md)
|
||||
* [仓库](basic_concept/repository.md)
|
||||
* [安装](install/README.md)
|
||||
* [倉庫](basic_concept/repository.md)
|
||||
* [安裝](install/README.md)
|
||||
* [Ubuntu](install/ubuntu.md)
|
||||
* [CentOS](install/centos.md)
|
||||
* [镜像](image/README.md)
|
||||
* [获取镜像](image/pull.md)
|
||||
* [映像檔](image/README.md)
|
||||
* [取得映像檔](image/pull.md)
|
||||
* [列出](image/list.md)
|
||||
* [创建](image/create.md)
|
||||
* [存出和载入](image/save_load.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)
|
||||
* [终止](container/stop.md)
|
||||
* [进入容器](container/enter.md)
|
||||
* [导出和导入](container/import_export.md)
|
||||
* [删除](container/rm.md)
|
||||
* [仓库](repository/README.md)
|
||||
* [啟動](container/run.md)
|
||||
* [守護態執行](container/daemon.md)
|
||||
* [終止](container/stop.md)
|
||||
* [進入容器](container/enter.md)
|
||||
* [導出與導入](container/import_export.md)
|
||||
* [刪除](container/rm.md)
|
||||
* [倉庫](repository/README.md)
|
||||
* [Docker Hub](repository/dockerhub.md)
|
||||
* [私有仓库](repository/local_repo.md)
|
||||
* [配置文件](repository/config.md)
|
||||
* [数据管理](data_management/README.md)
|
||||
* [数据卷](data_management/volume.md)
|
||||
* [数据卷容器](data_management/container.md)
|
||||
* [备份、恢复、迁移数据卷](data_management/management.md)
|
||||
* [使用网络](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/access_control.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/ptp.md)
|
||||
* [实战案例](cases/README.md)
|
||||
* [使用 Supervisor 来管理进程](cases/supervisor.md)
|
||||
* [创建 tomcat/weblogic 集群](cases/tomcat.md)
|
||||
* [多台物理主机之间的容器互联](cases/container_connect.md)
|
||||
* [标准化开发测试和生产环境](cases/environment.md)
|
||||
* [私有倉庫](repository/local_repo.md)
|
||||
* [設定文件](repository/config.md)
|
||||
* [數據管理](data_management/README.md)
|
||||
* [數據卷](data_management/volume.md)
|
||||
* [數據卷容器](data_management/container.md)
|
||||
* [備份、恢復、遷移數據卷](data_management/management.md)
|
||||
* [使用網路](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/access_control.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/ptp.md)
|
||||
* [實戰案例](cases/README.md)
|
||||
* [使用 Supervisor 來管理程式](cases/supervisor.md)
|
||||
* [建立 tomcat/weblogic 集群](cases/tomcat.md)
|
||||
* [多台實體主機之間的容器互連](cases/container_connect.md)
|
||||
* [標準化開發測試和生產環境](cases/environment.md)
|
||||
* [安全](security/README.md)
|
||||
* [内核名字空间](security/kernel_ns.md)
|
||||
* [控制组](security/control_group.md)
|
||||
* [服务端防护](security/daemon_sec.md)
|
||||
* [内核能力机制](security/kernel_capability.md)
|
||||
* [其它安全特性](security/other_feature.md)
|
||||
* [总结](security/summary.md)
|
||||
* [內核命名空間](security/kernel_ns.md)
|
||||
* [控制組](security/control_group.md)
|
||||
* [伺服端防護](security/daemon_sec.md)
|
||||
* [內核能力機制](security/kernel_capability.md)
|
||||
* [其他安全特性](security/other_feature.md)
|
||||
* [總結](security/summary.md)
|
||||
* [Dockerfile](dockerfile/README.md)
|
||||
* [基本结构](dockerfile/basic_structure.md)
|
||||
* [基本結構](dockerfile/basic_structure.md)
|
||||
* [指令](dockerfile/instructions.md)
|
||||
* [创建镜像](dockerfile/build_image.md)
|
||||
* [底层实现](underly/README.md)
|
||||
* [基本架构](underly/arch.md)
|
||||
* [名字空间](underly/namespace.md)
|
||||
* [控制组](underly/cgroups.md)
|
||||
* [Union 文件系统](underly/ufs.md)
|
||||
* [建立映像檔](dockerfile/build_image.md)
|
||||
* [底層實做](underly/README.md)
|
||||
* [基本架構](underly/arch.md)
|
||||
* [命名空間](underly/namespace.md)
|
||||
* [控制組](underly/cgroups.md)
|
||||
* [Union 文件系統](underly/ufs.md)
|
||||
* [容器格式](underly/container_format.md)
|
||||
* [网络](underly/network.md)
|
||||
* [附录一:命令查询](appendix_command/README.md)
|
||||
* [附录二:常见仓库介绍](appendix_repo/README.md)
|
||||
* [網路](underly/network.md)
|
||||
* [附錄一:命令查詢](appendix_command/README.md)
|
||||
* [附錄二:常見倉庫介紹](appendix_repo/README.md)
|
||||
* [Ubuntu](appendix_repo/ubuntu.md)
|
||||
* [CentOS](appendix_repo/centos.md)
|
||||
* [MySQL](appendix_repo/mysql.md)
|
||||
|
@ -79,5 +79,5 @@
|
|||
* [Nginx](appendix_repo/nginx.md)
|
||||
* [WordPress](appendix_repo/wordpress.md)
|
||||
* [Node.js](appendix_repo/nodejs.md)
|
||||
* [附录三:资源链接](appendix_resources/README.md)
|
||||
* [附錄三:資源連結](appendix_resources/README.md)
|
||||
|
||||
|
|
|
@ -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 隨機分配一個本地未占用的私有網段(在 [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 網路](../_images/network.png)
|
||||
|
||||
接下来的部分将介绍在一些场景中,Docker 所有的网络定制配置。以及通过 Linux 命令来调整、补充、甚至替换 Docker 默认的网络配置。
|
||||
接下來的部分將介紹在一些場景中,Docker 所有的網路自訂設定。以及透過 Linux 命令來調整、補充、甚至替換 Docker 預設的網路設定。
|
||||
|
|
|
@ -1,35 +1,35 @@
|
|||
## 容器访问控制
|
||||
容器的访问控制,主要通过 Linux 上的 `iptables` 防火墙来进行管理和实现。`iptables` 是 Linux 上默认的防火墙软件,在大部分发行版中都自带。
|
||||
## 容器訪問控制
|
||||
容器的訪問控制,主要透過 Linux 上的 `iptables` 防火墻來進行管理和實做。`iptables` 是 Linux 上默認的防火墻軟件,在大部分發行版中都自帶。
|
||||
|
||||
### 容器访问外部网络
|
||||
容器要想访问外部网络,需要本地系统的转发支持。在Linux 系统中,检查转发是否打开。
|
||||
### 容器訪問外部網路
|
||||
容器要想訪問外部網路,需要本地系統的轉發支持。在Linux 系統中,檢查轉發是否打開。
|
||||
|
||||
```
|
||||
$sysctl net.ipv4.ip_forward
|
||||
net.ipv4.ip_forward = 1
|
||||
```
|
||||
如果为 0,说明没有开启转发,则需要手动打开。
|
||||
如果為 0,說明沒有開啟轉發,則需要手動打開。
|
||||
```
|
||||
$sysctl -w net.ipv4.ip_forward=1
|
||||
```
|
||||
如果在启动 Docker 服务的时候设定 `--ip-forward=true`, Docker 就会自动设定系统的 `ip_forward` 参数为 1。
|
||||
如果在啟動 Docker 服務的時候設定 `--ip-forward=true`, Docker 就會自動設定系統的 `ip_forward` 參數為 1。
|
||||
|
||||
### 容器之间访问
|
||||
容器之间相互访问,需要两方面的支持。
|
||||
* 容器的网络拓扑是否已经互联。默认情况下,所有容器都会被连接到 `docker0` 网桥上。
|
||||
* 本地系统的防火墙软件 -- `iptables` 是否允许通过。
|
||||
### 容器之間訪問
|
||||
容器之間相互訪問,需要兩方面的支持。
|
||||
* 容器的網路拓撲是否已經互聯。默認情況下,所有容器都會被連接到 `docker0` 網橋上。
|
||||
* 本地系統的防火墻軟件 -- `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` 规则。
|
||||
例如,在啟動 Docker 服務時,可以同時使用 `icc=false --iptables=true` 參數來關閉允許相互的網路訪問,並讓 Docker 可以修改系統中的 `iptables` 規則。
|
||||
|
||||
此时,系统中的 `iptables` 规则可能是类似
|
||||
此時,系統中的 `iptables` 規則可能是類似
|
||||
```
|
||||
$ sudo iptables -nL
|
||||
...
|
||||
|
@ -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
|
||||
...
|
||||
|
@ -52,4 +52,4 @@ ACCEPT tcp -- 172.17.0.3 172.17.0.2 tcp dpt:80
|
|||
DROP all -- 0.0.0.0/0 0.0.0.0/0
|
||||
```
|
||||
|
||||
注意:`--link=CONTAINER_NAME:ALIAS` 中的 `CONTAINER_NAME` 目前必须是 Docker 分配的名字,或使用 `--name` 参数指定的名字。主机名则不会被识别。
|
||||
註意:`--link=CONTAINER_NAME:ALIAS` 中的 `CONTAINER_NAME` 目前必須是 Docker 分配的名字,或使用 `--name` 參數指定的名字。主機名則不會被識別。
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
## 自定义网桥
|
||||
除了默认的 `docker0` 网桥,用户也可以指定网桥来连接各个容器。
|
||||
## 自定義網橋
|
||||
除了默認的 `docker0` 網橋,使用者也可以指定網橋來連接各個容器。
|
||||
|
||||
在启动 Docker 服务的时候,使用 `-b BRIDGE`或`--bridge=BRIDGE` 来指定使用的网桥。
|
||||
在啟動 Docker 服務的時候,使用 `-b BRIDGE`或`--bridge=BRIDGE` 來指定使用的網橋。
|
||||
|
||||
如果服务已经运行,那需要先停止服务,并删除旧的网桥。
|
||||
如果服務已經執行,那需要先停止服務,並刪除舊的網橋。
|
||||
```
|
||||
$ 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,12 +23,12 @@ $ 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
|
||||
```
|
||||
启动 Docker 服务。
|
||||
新建一个容器,可以看到它已经桥接到了 `bridge0` 上。
|
||||
啟動 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` 提交。
|
||||
但是這些修改是臨時的,只在執行的容器中保留,容器終止或重啟後並不會被保存下來。也不會被 `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` 看到。
|
||||
設定容器的主機名,它會被寫到容器內的 `/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` 来配置容器。
|
||||
設定容器的搜索域,當設定搜索域為 `.example.com` 時,在搜索一個名為 host 的主機時,DNS 不僅搜索host,還會搜索 `host.example.com`。
|
||||
註意:如果沒有上述最後 2 個選項,Docker 會默認用主機上的 `/etc/resolv.conf` 來設定容器。
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
## 配置 docker0 网桥
|
||||
Docker 服务默认会创建一个 `docker0` 网桥(其上有一个 `docker0` 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
|
||||
## 設定 docker0 網橋
|
||||
Docker 服務默認會建立一個 `docker0` 網橋(其上有一個 `docker0` 內部接口),它在內核層連通了其他的物理或虛擬網卡,這就將所有容器和本地主機都放到同一個物理網路。
|
||||
|
||||
Docker 默认指定了 `docker0` 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。
|
||||
* `--bip=CIDR` -- IP 地址加掩码格式,例如 192.168.1.5/24
|
||||
* `--mtu=BYTES` -- 覆盖默认的 Docker mtu 配置
|
||||
Docker 默認指定了 `docker0` 接口 的 IP 地址和子網掩碼,讓主機和容器之間可以透過網橋相互通信,它還給出了 MTU(接口允許接收的最大傳輸單元),通常是 1500 Bytes,或宿主主機網路路由上支持的默認值。這些值都可以在服務啟動的時候進行設定。
|
||||
* `--bip=CIDR` -- IP 地址加掩碼格式,例如 192.168.1.5/24
|
||||
* `--mtu=BYTES` -- 覆蓋默認的 Docker mtu 設定
|
||||
|
||||
也可以在配置文件中配置 DOCKER_OPTS,然后重启服务。
|
||||
由于目前 Docker 网桥是 Linux 网桥,用户可以使用 `brctl show` 来查看网桥和端口连接信息。
|
||||
也可以在設定文件中設定 DOCKER_OPTS,然後重啟服務。
|
||||
由於目前 Docker 網橋是 Linux 網橋,使用者可以使用 `brctl show` 來查看網橋和端口連接訊息。
|
||||
```
|
||||
$ sudo brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
docker0 8000.3a1d7362b4ee no veth65f9
|
||||
vethdda6
|
||||
```
|
||||
*注:`brctl` 命令在 Debian、Ubuntu 中可以使用 `sudo apt-get install bridge-utils` 来安装。
|
||||
*註:`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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## 工具和示例
|
||||
在介绍自定义网络拓扑之前,你可能会对一些外部工具和例子感兴趣:
|
||||
在介紹自定義網路拓撲之前,你可能會對一些外部工具和例子感興趣:
|
||||
|
||||
### pipework
|
||||
Jérôme Petazzoni 编写了一个叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 脚本,可以帮助用户在比较复杂的场景中完成容器的连接。
|
||||
Jérôme Petazzoni 編寫了一個叫 [pipework](https://github.com/jpetazzo/pipework) 的 shell 腳本,可以幫助使用者在比較復雜的場景中完成容器的連接。
|
||||
|
||||
### playground
|
||||
Brandon Rhodes 创建了一个提供完整的 Docker 容器网络拓扑管理的 [Python库](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墙;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的服务器。
|
||||
Brandon Rhodes 建立了一個提供完整的 Docker 容器網路拓撲管理的 [Python庫](https://github.com/brandon-rhodes/fopnp/tree/m/playground),包括路由、NAT 防火墻;以及一些提供 HTTP, SMTP, POP, IMAP, Telnet, SSH, FTP 的伺服器。
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
## 映射容器端口到宿主主机的实现
|
||||
## 映射容器端口到宿主主機的實做
|
||||
|
||||
默认情况下,容器可以主动访问到外部网络的连接,但是外部网络无法访问到容器。
|
||||
### 容器访问外部实现
|
||||
容器所有到外部网络的连接,源地址都会被NAT成本地系统的IP地址。这是使用 `iptables` 的源地址伪装操作实现的。
|
||||
默認情況下,容器可以主動訪問到外部網路的連接,但是外部網路無法訪問到容器。
|
||||
### 容器訪問外部實做
|
||||
容器所有到外部網路的連接,源地址都會被NAT成本地系統的IP地址。這是使用 `iptables` 的源地址偽裝操作實做的。
|
||||
|
||||
查看主机的 NAT 规则。
|
||||
查看主機的 NAT 規則。
|
||||
```
|
||||
$ sudo iptables -t nat -nL
|
||||
...
|
||||
|
@ -13,15 +13,15 @@ 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` 时:
|
||||
使用 `-P` 時:
|
||||
```
|
||||
$ iptables -t nat -nL
|
||||
...
|
||||
|
@ -30,14 +30,14 @@ target prot opt source destination
|
|||
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80
|
||||
```
|
||||
|
||||
使用 `-p 80:80` 时:
|
||||
使用 `-p 80:80` 時:
|
||||
```
|
||||
$ iptables -t nat -nL
|
||||
Chain DOCKER (2 references)
|
||||
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
|
||||
IP::port` 来指定允许访问容器的主机上的 IP、接口等,以制定更严格的规则。
|
||||
* 如果希望永久绑定到某个固定的 IP 地址,可以在 Docker 配置文件 `/etc/default/docker` 中指定 `DOCKER_OPTS="--ip=IP_ADDRESS"`,之后重启 Docker 服务即可生效。
|
||||
註意:
|
||||
* 這裡的規則映射了 0.0.0.0,意味著將接受主機來自所有接口的流量。使用者可以透過 `-p IP:host_port:container_port` 或 `-p
|
||||
IP::port` 來指定允許訪問容器的主機上的 IP、接口等,以制定更嚴格的規則。
|
||||
* 如果希望永久綁定到某個固定的 IP 地址,可以在 Docker 設定文件 `/etc/default/docker` 中指定 `DOCKER_OPTS="--ip=IP_ADDRESS"`,之後重啟 Docker 服務即可生效。
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## 示例:创建一个点到点连接
|
||||
默认情况下,Docker 会将所有容器连接到由 `docker0` 提供的虚拟子网中。
|
||||
## 示例:建立一個點到點連接
|
||||
默認情況下,Docker 會將所有容器連接到由 `docker0` 提供的虛擬子網中。
|
||||
|
||||
用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。
|
||||
使用者有時候需要兩個容器之間可以直連通信,而不用透過主機網橋進行橋接。
|
||||
|
||||
解决办法很简单:创建一对 `peer` 接口,分别放到两个容器中,配置成点到点链路类型即可。
|
||||
解決辦法很簡單:建立一對 `peer` 接口,分別放到兩個容器中,設定成點到點鏈路類型即可。
|
||||
|
||||
首先启动 2 个容器:
|
||||
首先啟動 2 個容器:
|
||||
```
|
||||
$ sudo docker run -i -t --rm --net=none base /bin/bash
|
||||
root@1f1f4c1f931a:/#
|
||||
|
@ -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
|
||||
|
||||
|
@ -38,8 +38,8 @@ $ sudo ip netns exec 3004 ip addr add 10.1.1.2/32 dev B
|
|||
$ sudo ip netns exec 3004 ip link set B up
|
||||
$ sudo ip netns exec 3004 ip route add 10.1.1.1/32 dev B
|
||||
```
|
||||
现在这 2 个容器就可以相互 ping 通,并成功建立连接。点到点链路不需要子网和子网掩码。
|
||||
現在這 2 個容器就可以相互 ping 通,並成功建立連接。點到點鏈路不需要子網和子網掩碼。
|
||||
|
||||
此外,也可以不指定 `--net=none` 来创建点到点链路。这样容器还可以通过原先的网络来通信。
|
||||
此外,也可以不指定 `--net=none` 來建立點到點鏈路。這樣容器還可以透過原先的網路來通信。
|
||||
|
||||
利用类似的办法,可以创建一个只跟主机通信的容器。但是一般情况下,更推荐使用 `--icc=false` 来关闭容器之间的通信。
|
||||
利用類似的辦法,可以建立一個只跟主機通信的容器。但是一般情況下,更推薦使用 `--icc=false` 來關閉容器之間的通信。
|
||||
|
|
|
@ -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 规则
|
||||
* `--mtu=BYTES` --容器网络中的 MTU
|
||||
其中有些命令選項只有在 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 規則
|
||||
* `--mtu=BYTES` --容器網路中的 MTU
|
||||
|
||||
下面2个命令选项既可以在启动服务时指定,也可以 Docker 容器启动(`docker run`)时候指定。在 Docker 服务启动的时候指定则会成为默认值,后面执行 `docker run` 时可以覆盖设置的默认值。
|
||||
* `--dns=IP_ADDRESS...` --使用指定的DNS服务器
|
||||
下面2個命令選項既可以在啟動服務時指定,也可以 Docker 容器啟動(`docker run`)時候指定。在 Docker 服務啟動的時候指定則會成為默認值,後面執行 `docker run` 時可以覆蓋設置的默認值。
|
||||
* `--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` --配置容器的桥接模式
|
||||
* `-p SPEC or --publish=SPEC` --映射容器端口到宿主主机
|
||||
* `-P or --publish-all=true|false` --映射容器所有端口到宿主主机
|
||||
最後這些選項只有在 `docker run` 執行時使用,因為它是針對容器的特性內容。
|
||||
* `-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` --映射容器所有端口到宿主主機
|
||||
|
|
|
@ -1,168 +1,168 @@
|
|||
# Docker命令查询
|
||||
# Docker命令查詢
|
||||
|
||||
##基本语法
|
||||
##基本語法
|
||||
docker [OPTIONS] COMMAND [arg...]
|
||||
一般来说,Docker 命令可以用来管理 daemon,或者通过 CLI 命令管理镜像和容器。可以通过 `man docker` 来查看这些命令。
|
||||
一般來說,Docker 命令可以用來管理 daemon,或者透過 CLI 命令管理映像檔和容器。可以透過 `man docker` 來查看這些命令。
|
||||
|
||||
|
||||
##选项
|
||||
##選項
|
||||
-D=true|false
|
||||
使用 debug 模式。默认为 false。
|
||||
使用 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 来指定。
|
||||
-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 來指定。
|
||||
|
||||
--api-enable-cors=true|false
|
||||
在远端 API 中启用 CORS 头。缺省为 false。
|
||||
在遠端 API 中啟用 CORS 頭。預設為 false。
|
||||
|
||||
-b=""
|
||||
将容器挂载到一个已存在的网桥上。指定为 'none' 时则禁用容器的网络。
|
||||
將容器掛載到一個已存在的網橋上。指定為 'none' 時則禁用容器的網路。
|
||||
|
||||
--bip=""
|
||||
让动态创建的 docker0 采用给定的 CIDR 地址; 与 -b 选项互斥。
|
||||
讓動態建立的 docker0 采用指定的 CIDR 地址; 與 -b 選項互斥。
|
||||
|
||||
-d=true|false
|
||||
使用 daemon 模式。缺省为 false。
|
||||
使用 daemon 模式。預設為 false。
|
||||
|
||||
--dns=""
|
||||
让 Docker 使用给定的 DNS 服务器。
|
||||
讓 Docker 使用指定的 DNS 伺服器。
|
||||
|
||||
-g=""
|
||||
指定 Docker 运行时的 root 路径。缺省为 /var/lib/docker。
|
||||
指定 Docker 執行時的 root 路徑。預設為 /var/lib/docker。
|
||||
|
||||
--icc=true|false
|
||||
启用容器间通信。默认为 true。
|
||||
啟用容器間通信。預設為 true。
|
||||
|
||||
--ip=""
|
||||
绑定端口时候的默认 IP 地址。缺省为 0.0.0.0。
|
||||
綁定端口時候的預設 IP 地址。預設為 0.0.0.0。
|
||||
|
||||
--iptables=true|false
|
||||
禁止 Docker 添加 iptables 规则。缺省为 true。
|
||||
禁止 Docker 新增 iptables 規則。預設為 true。
|
||||
|
||||
--mtu=VALUE
|
||||
指定容器网络的 mtu。缺省为 1500。
|
||||
指定容器網路的 mtu。預設為 1500。
|
||||
|
||||
-p=""
|
||||
指定 daemon 的 PID 文件路径。缺省为 /var/run/docker.pid。
|
||||
指定 daemon 的 PID 文件路徑。預設為 /var/run/docker.pid。
|
||||
|
||||
-s=""
|
||||
强制 Docker 运行时使用给定的存储驱动。
|
||||
強制 Docker 執行時使用指定的存儲驅動。
|
||||
|
||||
-v=true|false
|
||||
输出版本信息并退出。缺省值为 false。
|
||||
輸出版本資訊並退出。預設值為 false。
|
||||
|
||||
--selinux-enabled=true|false
|
||||
启用 SELinux 支持。缺省值为 false。SELinux 目前不支持 BTRFS 存储驱动。
|
||||
啟用 SELinux 支持。預設值為 false。SELinux 目前不支持 BTRFS 存儲驅動。
|
||||
|
||||
|
||||
##命令
|
||||
Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式执行。两者一致。
|
||||
Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式執行。兩者一致。
|
||||
|
||||
docker-attach(1)
|
||||
依附到一个正在运行的容器中。
|
||||
依附到一個正在執行的容器中。
|
||||
|
||||
docker-build(1)
|
||||
从一个 Dockerfile 创建一个镜像
|
||||
從一個 Dockerfile 建立一個映像檔
|
||||
|
||||
docker-commit(1)
|
||||
从一个容器的修改中创建一个新的镜像
|
||||
從一個容器的修改中建立一個新的映像檔
|
||||
|
||||
docker-cp(1)
|
||||
从容器中复制文件到宿主系统中
|
||||
從容器中複製文件到宿主系統中
|
||||
|
||||
docker-diff(1)
|
||||
检查一个容器文件系统的修改
|
||||
檢查一個容器文件系統的修改
|
||||
|
||||
docker-events(1)
|
||||
从服务端获取实时的事件
|
||||
從服務端取得實時的事件
|
||||
|
||||
docker-export(1)
|
||||
导出容器内容为一个 tar 包
|
||||
匯出容器內容為一個 tar 包
|
||||
|
||||
docker-history(1)
|
||||
显示一个镜像的历史
|
||||
顯示一個映像檔的歷史
|
||||
|
||||
docker-images(1)
|
||||
列出存在的镜像
|
||||
列出存在的映像檔
|
||||
|
||||
docker-import(1)
|
||||
导入一个文件(典型为 tar 包)路径或目录来创建一个镜像
|
||||
匯入一個文件(典型為 tar 包)路徑或目錄來建立一個映像檔
|
||||
|
||||
docker-info(1)
|
||||
显示一些相关的系统信息
|
||||
顯示一些相關的系統資訊
|
||||
|
||||
docker-inspect(1)
|
||||
显示一个容器的底层具体信息。
|
||||
顯示一個容器的底層具體資訊。
|
||||
|
||||
docker-kill(1)
|
||||
关闭一个运行中的容器 (包括进程和所有资源)
|
||||
關閉一個執行中的容器 (包括程式和所有資源)
|
||||
|
||||
docker-load(1)
|
||||
从一个 tar 包中加载一个镜像
|
||||
從一個 tar 包中載入一個映像檔
|
||||
|
||||
docker-login(1)
|
||||
注册或登录到一个 Docker 的仓库服务器
|
||||
註冊或登錄到一個 Docker 的倉庫伺服器
|
||||
|
||||
docker-logout(1)
|
||||
从 Docker 的仓库服务器登出
|
||||
從 Docker 的倉庫伺服器登出
|
||||
|
||||
docker-logs(1)
|
||||
获取容器的 log 信息
|
||||
取得容器的 log 資訊
|
||||
|
||||
docker-pause(1)
|
||||
暂停一个容器中的所有进程
|
||||
暫停一個容器中的所有程式
|
||||
|
||||
docker-port(1)
|
||||
查找一个 nat 到一个私有网口的公共口
|
||||
查找一個 nat 到一個私有網口的公共口
|
||||
|
||||
docker-ps(1)
|
||||
列出容器
|
||||
|
||||
docker-pull(1)
|
||||
从一个Docker的仓库服务器下拉一个镜像或仓库
|
||||
從一個Docker的倉庫伺服器下拉一個映像檔或倉庫
|
||||
|
||||
docker-push(1)
|
||||
将一个镜像或者仓库推送到一个 Docker 的注册服务器
|
||||
將一個映像檔或者倉庫推送到一個 Docker 的註冊伺服器
|
||||
|
||||
docker-restart(1)
|
||||
重启一个运行中的容器
|
||||
重新啟動一個執行中的容器
|
||||
|
||||
docker-rm(1)
|
||||
删除给定的若干个容器
|
||||
刪除指定的數個容器
|
||||
|
||||
docker-rmi(1)
|
||||
删除给定的若干个镜像
|
||||
刪除指定的數個映像檔
|
||||
|
||||
docker-run(1)
|
||||
创建一个新容器,并在其中运行给定命令
|
||||
建立一個新容器,並在其中執行指定命令
|
||||
|
||||
docker-save(1)
|
||||
保存一个镜像为 tar 包文件
|
||||
保存一個映像檔為 tar 包文件
|
||||
|
||||
docker-search(1)
|
||||
在 Docker index 中搜索一个镜像
|
||||
在 Docker index 中搜索一個映像檔
|
||||
|
||||
docker-start(1)
|
||||
启动一个容器
|
||||
啟動一個容器
|
||||
|
||||
docker-stop(1)
|
||||
终止一个运行中的容器
|
||||
終止一個執行中的容器
|
||||
|
||||
docker-tag(1)
|
||||
为一个镜像打标签
|
||||
為一個映像檔打標簽
|
||||
|
||||
docker-top(1)
|
||||
查看一个容器中的正在运行的进程信息
|
||||
查看一個容器中的正在執行的程式資訊
|
||||
|
||||
docker-unpause(1)
|
||||
将一个容器内所有的进程从暂停状态中恢复
|
||||
將一個容器內所有的程式從暫停狀態中恢復
|
||||
|
||||
docker-version(1)
|
||||
输出 Docker 的版本信息
|
||||
輸出 Docker 的版本資訊
|
||||
|
||||
docker-wait(1)
|
||||
阻塞直到一个容器终止,然后输出它的退出符
|
||||
阻塞直到一個容器終止,然後輸出它的退出符
|
||||
|
||||
##一张图总结 Docker 的命令
|
||||
##一張圖總結 Docker 的命令
|
||||
|
||||
![命令周期](../_images/cmd_logic.png)
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# 常见仓库介绍
|
||||
本章将介绍常见的一些仓库和镜像的功能,使用方法和生成它们的 Dockerfile 等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、Node.js 等。
|
||||
# 常見倉庫介紹
|
||||
本章將介紹常見的一些倉庫和鏡像的功能,使用方法和生成它們的 Dockerfile 等。包括 Ubuntu、CentOS、MySQL、MongoDB、Redis、Nginx、Wordpress、Node.js 等。
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## [CentOS](https://registry.hub.docker.com/_/centos/)
|
||||
|
||||
### 基本信息
|
||||
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。
|
||||
该仓库提供了 CentOS 从 5 ~ 7 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 發行版,其軟件包大多跟 RedHat 系列保持一致。
|
||||
該倉庫提供了 CentOS 從 5 ~ 7 各個版本的鏡像。
|
||||
|
||||
### 使用方法
|
||||
默认会启动一个最小化的 CentOS 环境。
|
||||
默認會啟動一個最小化的 CentOS 環境。
|
||||
```
|
||||
$ sudo docker run --name some-centos -i -t centos bash
|
||||
bash-4.2#
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
## [MongoDB](https://registry.hub.docker.com/_/mongo/)
|
||||
|
||||
### 基本信息
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。
|
||||
该仓库提供了 MongoDB 2.2 ~ 2.7 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是開源的 NoSQL 數據庫實做。
|
||||
該倉庫提供了 MongoDB 2.2 ~ 2.7 各個版本的鏡像。
|
||||
|
||||
### 使用方法
|
||||
默认会在 `27017` 端口启动数据库。
|
||||
默認會在 `27017` 端口啟動數據庫。
|
||||
```
|
||||
$ 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"'
|
||||
```
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
## [MySQL](https://registry.hub.docker.com/_/mysql/)
|
||||
|
||||
### 基本信息
|
||||
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是开源的关系数据库实现。
|
||||
该仓库提供了 MySQL 各个版本的镜像,包括 5.6 系列、5.7 系列等。
|
||||
### 基本訊息
|
||||
[MySQL](https://en.wikipedia.org/wiki/MySQL) 是開源的關系數據庫實做。
|
||||
該倉庫提供了 MySQL 各個版本的鏡像,包括 5.6 系列、5.7 系列等。
|
||||
|
||||
### 使用方法
|
||||
默认会在 `3306` 端口启动数据库。
|
||||
默認會在 `3306` 端口啟動數據庫。
|
||||
```
|
||||
$ sudo docker run --name some-mysql -e MYSQL_ROOT_PASSWORD=mysecretpassword -d mysql
|
||||
```
|
||||
之后就可以使用其它应用来连接到该容器。
|
||||
之後就可以使用其它應用來連接到該容器。
|
||||
```
|
||||
$ 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"'
|
||||
```
|
||||
|
|
|
@ -1,34 +1,34 @@
|
|||
## [Nginx](https://registry.hub.docker.com/_/nginx/)
|
||||
|
||||
### 基本信息
|
||||
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。
|
||||
该仓库提供了 Nginx 1.0 ~ 1.7 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[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
|
||||
```
|
||||
之后生成新的镜像,并启动一个容器。
|
||||
之後生成新的鏡像,並啟動一個容器。
|
||||
```
|
||||
$ sudo docker build -t some-content-nginx .
|
||||
$ sudo docker run --name some-nginx -d some-content-nginx
|
||||
```
|
||||
开放端口,并映射到本地的 `8080` 端口。
|
||||
開放端口,並映射到本地的 `8080` 端口。
|
||||
```
|
||||
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,23 +1,23 @@
|
|||
## [Node.js](https://registry.hub.docker.com/_/node/)
|
||||
|
||||
### 基本信息
|
||||
[Node.js](https://en.wikipedia.org/wiki/Node.js)是基于 JavaScript 的可扩展服务端和网络软件开发平台。
|
||||
该仓库提供了 Node.js 0.8 ~ 0.11 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[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
|
||||
```
|
||||
|
||||
也可以直接运行一个简单容器。
|
||||
也可以直接執行一個簡單容器。
|
||||
```
|
||||
$ sudo docker run -it --rm --name my-running-script -v "$(pwd)":/usr/src/myapp -w /usr/src/myapp node:0.10 node your-daemon-or-script.js
|
||||
```
|
||||
|
|
|
@ -1,25 +1,25 @@
|
|||
## [Redis](https://registry.hub.docker.com/_/redis/)
|
||||
|
||||
### 基本信息
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。
|
||||
该仓库提供了 Redis 2.6 ~ 2.8.9 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是開源的內存 Key-Value 數據庫實做。
|
||||
該倉庫提供了 Redis 2.6 ~ 2.8.9 各個版本的鏡像。
|
||||
|
||||
### 使用方法
|
||||
默认会在 `6379` 端口启动数据库。
|
||||
默認會在 `6379` 端口啟動數據庫。
|
||||
```
|
||||
$ sudo docker run --name some-redis -d redis
|
||||
```
|
||||
另外还可以启用 [持久存储](http://redis.io/topics/persistence)。
|
||||
另外還可以啟用 [持久存儲](http://redis.io/topics/persistence)。
|
||||
```
|
||||
$ sudo docker run --name some-redis -d redis redis-server --appendonly yes
|
||||
```
|
||||
默认数据存储位置在 `VOLUME/data`。可以使用 `--volumes-from some-volume-container` 或 `-v /docker/host/dir:/data` 将数据存放到本地。
|
||||
默認數據存儲位置在 `VOLUME/data`。可以使用 `--volumes-from some-volume-container` 或 `-v /docker/host/dir:/data` 將數據存放到本地。
|
||||
|
||||
使用其他应用连接到容器,可以用
|
||||
使用其他應用連接到容器,可以用
|
||||
```
|
||||
$ 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"'
|
||||
```
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## [Ubuntu](https://registry.hub.docker.com/_/ubuntu/)
|
||||
|
||||
### 基本信息
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。
|
||||
该仓库提供了 Ubuntu从12.04 ~ 14.10 各个版本的镜像。
|
||||
### 基本訊息
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 發行版,其自帶軟件版本往往較新一些。
|
||||
該倉庫提供了 Ubuntu從12.04 ~ 14.10 各個版本的鏡像。
|
||||
|
||||
### 使用方法
|
||||
默认会启动一个最小化的 Ubuntu 环境。
|
||||
默認會啟動一個最小化的 Ubuntu 環境。
|
||||
```
|
||||
$ sudo docker run --name some-ubuntu -i -t ubuntu
|
||||
root@523c70904d54:/#
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
## [WordPress](https://registry.hub.docker.com/_/wordpress/)
|
||||
|
||||
### 基本信息
|
||||
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是开源的 Blog 和内容管理系统框架,它基于 PhP 和 MySQL。
|
||||
该仓库提供了 WordPress 4.0 版本的镜像。
|
||||
### 基本訊息
|
||||
[WordPress](https://en.wikipedia.org/wiki/WordPress) 是開源的 Blog 和內容管理系統框架,它基於 PhP 和 MySQL。
|
||||
該倉庫提供了 WordPress 4.0 版本的鏡像。
|
||||
|
||||
### 使用方法
|
||||
启动容器需要 MySQL 的支持,默认端口为 `80`。
|
||||
啟動容器需要 MySQL 的支持,默認端口為 `80`。
|
||||
```
|
||||
$ sudo docker run --name some-wordpress --link some-mysql:mysql -d wordpress
|
||||
```
|
||||
启动 WordPress 容器时可以指定的一些环境参数包括
|
||||
* `-e WORDPRESS_DB_USER=...` 缺省为 “root”
|
||||
* `-e WORDPRESS_DB_PASSWORD=...` 缺省为连接 mysql 容器的环境变量 `MYSQL_ROOT_PASSWORD` 的值
|
||||
* `-e WORDPRESS_DB_NAME=...` 缺省为 “wordpress”
|
||||
* `-e WORDPRESS_AUTH_KEY=...`, `-e WORDPRESS_SECURE_AUTH_KEY=...`, `-e WORDPRESS_LOGGED_IN_KEY=...`, `-e WORDPRESS_NONCE_KEY=...`, `-e WORDPRESS_AUTH_SALT=...`, `-e WORDPRESS_SECURE_AUTH_SALT=...`, `-e WORDPRESS_LOGGED_IN_SALT=...`, `-e WORDPRESS_NONCE_SALT=...` 缺省为随机 sha1 串
|
||||
啟動 WordPress 容器時可以指定的一些環境參數包括
|
||||
* `-e WORDPRESS_DB_USER=...` 缺省為 “root”
|
||||
* `-e WORDPRESS_DB_PASSWORD=...` 缺省為連接 mysql 容器的環境變量 `MYSQL_ROOT_PASSWORD` 的值
|
||||
* `-e WORDPRESS_DB_NAME=...` 缺省為 “wordpress”
|
||||
* `-e WORDPRESS_AUTH_KEY=...`, `-e WORDPRESS_SECURE_AUTH_KEY=...`, `-e WORDPRESS_LOGGED_IN_KEY=...`, `-e WORDPRESS_NONCE_KEY=...`, `-e WORDPRESS_AUTH_SALT=...`, `-e WORDPRESS_SECURE_AUTH_SALT=...`, `-e WORDPRESS_LOGGED_IN_SALT=...`, `-e WORDPRESS_NONCE_SALT=...` 缺省為隨機 sha1 串
|
||||
|
||||
### Dockerfile
|
||||
* [4.0 版本](https://github.com/docker-library/wordpress/blob/aee00669e7c43f435f021cb02871bffd63d5677a/Dockerfile)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
# 资源链接
|
||||
* Docker 主站点: https://www.docker.io
|
||||
* Docker 注册中心API: http://docs.docker.com/reference/api/registry_api/
|
||||
# 資源鏈接
|
||||
* Docker 主站點: https://www.docker.io
|
||||
* Docker 註冊中心API: http://docs.docker.com/reference/api/registry_api/
|
||||
* Docker Hub API: http://docs.docker.com/reference/api/docker-io_api/
|
||||
* Docker 远端应用API: http://docs.docker.com/reference/api/docker_remote_api/
|
||||
* Dockerfile 参考:https://docs.docker.com/reference/builder/
|
||||
* Dockerfile 最佳实践:https://docs.docker.com/articles/dockerfile_best-practices/
|
||||
* Docker 遠端應用API: http://docs.docker.com/reference/api/docker_remote_api/
|
||||
* Dockerfile 參考:https://docs.docker.com/reference/builder/
|
||||
* Dockerfile 最佳實踐:https://docs.docker.com/articles/dockerfile_best-practices/
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
# 基本概念
|
||||
Docker 包括三个基本概念
|
||||
* 镜像(Image)
|
||||
Docker 包括三個基本概念
|
||||
|
||||
* 映像檔(Image)
|
||||
* 容器(Container)
|
||||
* 仓库(Repository)
|
||||
* 倉庫(Repository)
|
||||
|
||||
理解了这三个概念,就理解了 Docker 的整个生命周期。
|
||||
理解了這三個概念,就理解了 Docker 的整個生命週期。
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## Docker 容器
|
||||
Docker 利用容器来运行应用。
|
||||
Docker 利用容器來執行應用。
|
||||
|
||||
容器是从镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
|
||||
容器是從映像檔建立的執行實例。它可以被啟動、開始、停止、刪除。每個容器都是相互隔離的、保證安全的平台。
|
||||
|
||||
可以把容器看做是一个简易版的 Linux 环境(包括root用户权限、进程空间、用户空间和网络空间等)和运行在其中的应用程序。
|
||||
可以把容器看做是一個簡易版的 Linux 環境(包括root使用者權限、程式空間、使用者空間和網路空間等)和在其中執行的應用程式。
|
||||
|
||||
*注:镜像是只读的,容器在启动的时候创建一层可写层作为最上层。
|
||||
*註:映像檔是唯讀的,容器在啟動的時候建立一層可寫層作為最上層。
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## Docker 镜像
|
||||
Docker 镜像就是一个只读的模板。
|
||||
## Docker 映像檔
|
||||
Docker 映像檔就是一個唯讀的模板。
|
||||
|
||||
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
|
||||
例如:一個映像檔可以包含一個完整的 ubuntu 作業系統環境,裡面僅安裝了 Apache 或使用者需要的其它應用程式。
|
||||
|
||||
镜像可以用来创建 Docker 容器。
|
||||
映像檔可以用來建立 Docker 容器。
|
||||
|
||||
Docker 提供了一个很简单的机制来创建镜像或者更新现有的镜像,用户甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
|
||||
Docker 提供了一個很簡單的機制來建立映像檔或者更新現有的映像檔,使用者甚至可以直接從其他人那裡下載一個已經做好的映像檔來直接使用。
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
## Docker 仓库
|
||||
## Docker 倉庫
|
||||
|
||||
仓库是集中存放镜像文件的场所。有时候会把仓库和仓库注册服务器(Registry)混为一谈,并不严格区分。实际上,仓库注册服务器上往往存放着多个仓库,每个仓库中又包含了多个镜像,每个镜像有不同的标签(tag)。
|
||||
倉庫是集中存放映像檔文件的場所。有時候會把倉庫和倉庫註冊伺服器(Registry)混為一談,並不嚴格區分。實際上,倉庫註冊伺服器上往往存放著多個倉庫,每個倉庫中又包含了多個映像檔,每個鏡像有不同的標籤(tag)。
|
||||
|
||||
仓库分为公开仓库(Public)和私有仓库(Private)两种形式。
|
||||
倉庫分為公開倉庫(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 這樣的託管服務。
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#实战案例
|
||||
介绍一些典型的应用场景和案例。
|
||||
#實戰案例
|
||||
介紹一些典型的應用場景和案例。
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## 多台物理主机之间的容器互联(暴露容器到真实网络中)
|
||||
Docker 默认的桥接网卡是 docker0。它只会在本机桥接所有的容器网卡,举例来说容器的虚拟网卡在主机上看一般叫做 veth*** 而 Docker 只是把所有这些网卡桥接在一起,如下:
|
||||
## 多臺物理主機之間的容器互聯(暴露容器到真實網路中)
|
||||
Docker 默認的橋接網卡是 docker0。它只會在本機橋接所有的容器網卡,舉例來說容器的虛擬網卡在主機上看一般叫做 veth*** 而 Docker 只是把所有這些網卡橋接在一起,以下:
|
||||
```
|
||||
[root@opnvz ~]# brctl show
|
||||
bridge name bridge id STP enabled interfaces
|
||||
|
@ -7,7 +7,7 @@ docker0 8000.56847afe9799 no veth0889
|
|||
veth3c7b
|
||||
veth4061
|
||||
```
|
||||
在容器中看到的地址一般是像下面这样的地址:
|
||||
在容器中看到的地址一般是像下面這樣的地址:
|
||||
```
|
||||
root@ac6474aeb31d:~# ip a
|
||||
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 1500 qdisc noqueue state UNKNOWN group default
|
||||
|
@ -23,17 +23,17 @@ root@ac6474aeb31d:~# ip a
|
|||
inet6 fe80::487d:68ff:feda:9cf/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
这样就可以把这个网络看成是一个私有的网络,通过 nat 连接外网,如果要让外网连接到容器中,就需要做端口映射,即 -p 参数。
|
||||
這樣就可以把這個網路看成是一個私有的網路,透過 nat 連接外網,如果要讓外網連接到容器中,就需要做端口映射,即 -p 參數。
|
||||
|
||||
如果在企业内部应用,或者做多个物理主机的集群,可能需要将多个物理主机的容器组到一个物理网络中来,那么就需要将这个网桥桥接到我们指定的网卡上。
|
||||
如果在企業內部應用,或者做多個物理主機的集群,可能需要將多個物理主機的容器組到一個物理網路中來,那麽就需要將這個網橋橋接到我們指定的網卡上。
|
||||
|
||||
### 拓扑图
|
||||
主机 A 和主机 B 的网卡一都连着物理交换机的同一个 vlan 101,这样网桥一和网桥三就相当于在同一个物理网络中了,而容器一、容器三、容器四也在同一物理网络中了,他们之间可以相互通信,而且可以跟同一 vlan 中的其他物理机器互联。
|
||||
![物理拓扑图](../_images/container_connect_topology.png)
|
||||
### 拓撲圖
|
||||
主機 A 和主機 B 的網卡一都連著物理交換機的同一個 vlan 101,這樣網橋一和網橋三就相當於在同一個物理網路中了,而容器一、容器三、容器四也在同一物理網路中了,他們之間可以相互通信,而且可以跟同一 vlan 中的其他物理機器互聯。
|
||||
![物理拓撲圖](../_images/container_connect_topology.png)
|
||||
|
||||
### ubuntu 示例
|
||||
下面以 ubuntu 为例创建多个主机的容器联网:
|
||||
创建自己的网桥,编辑 /etc/network/interface 文件
|
||||
下面以 ubuntu 為例建立多個主機的容器聯網:
|
||||
建立自己的網橋,編輯 /etc/network/interface 文件
|
||||
```
|
||||
auto br0
|
||||
iface br0 inet static
|
||||
|
@ -44,9 +44,9 @@ bridge_ports em1
|
|||
bridge_stp off
|
||||
dns-nameservers 8.8.8.8 192.168.6.1
|
||||
```
|
||||
将 Docker 的默认网桥绑定到这个新建的 br0 上面,这样就将这台机器上容器绑定到 em1 这个网卡所对应的物理网络上了。
|
||||
將 Docker 的默認網橋綁定到這個新建的 br0 上面,這樣就將這臺機器上容器綁定到 em1 這個網卡所對應的物理網路上了。
|
||||
|
||||
ubuntu 修改 /etc/default/docker 文件,添加最后一行内容
|
||||
ubuntu 修改 /etc/default/docker 文件,新增最後一行內容
|
||||
|
||||
```
|
||||
# Docker Upstart and SysVinit configuration file
|
||||
|
@ -64,7 +64,7 @@ ubuntu 修改 /etc/default/docker 文件,添加最后一行内容
|
|||
DOCKER_OPTS="-b=br0"
|
||||
```
|
||||
|
||||
在启动 Docker 的时候 使用 -b 参数 将容器绑定到物理网络上。重启 Docker 服务后,再进入容器可以看到它已经绑定到你的物理网络上了。
|
||||
在啟動 Docker 的時候 使用 -b 參數 將容器綁定到物理網路上。重啟 Docker 服務後,再進入容器可以看到它已經綁定到你的物理網路上了。
|
||||
|
||||
```
|
||||
root@ubuntudocker:~# docker ps
|
||||
|
@ -75,4 +75,4 @@ bridge name bridge id STP enabled interfaces
|
|||
br0 8000.7e6e617c8d53 no em1
|
||||
vethe6e5
|
||||
```
|
||||
这样就直接把容器暴露到物理网络上了,多台物理主机的容器也可以相互联网了。需要注意的是,这样就需要自己来保证容器的网络安全了。
|
||||
這樣就直接把容器暴露到物理網路上了,多臺物理主機的容器也可以相網路了。需要註意的是,這樣就需要自己來保證容器的網路安全了。
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
## 标准化开发测试和生产环境
|
||||
对于大部分企业来说,搭建 PaaS 既没有那个精力,也没那个必要,用 Docker 做个人的 sandbox 用处又小了点。
|
||||
## 標準化開發測試和生產環境
|
||||
對於大部分企業來說,搭建 PaaS 既沒有那個精力,也沒那個必要,用 Docker 做個人的 sandbox 用處又小了點。
|
||||
|
||||
可以用 Docker 来标准化开发、测试、生产环境。
|
||||
可以用 Docker 來標準化開發、測試、生產環境。
|
||||
|
||||
|
||||
![企业应用结构](../_images/enterprise_usage.png)
|
||||
![企業應用結構](../_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
|
||||
|
@ -13,28 +13,28 @@ RUN apt-get update
|
|||
RUN apt-get upgrade -y
|
||||
```
|
||||
|
||||
### 安装 supervisor
|
||||
安装 ssh、apache 和 supervisor。
|
||||
### 安裝 supervisor
|
||||
安裝 ssh、apache 和 supervisor。
|
||||
```
|
||||
RUN apt-get install -y openssh-server apache2 supervisor
|
||||
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,14 +44,14 @@ 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 .
|
||||
```
|
||||
启动 supervisor 容器。
|
||||
啟動 supervisor 容器。
|
||||
```
|
||||
$ sudo docker run -p 22 -p 80 -t -i test/supervisords
|
||||
2013-11-25 18:53:22,312 CRIT Supervisor running as root (no user in config file)
|
||||
|
@ -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 服務的基礎鏡像,之後建立鏡像可以使用這個鏡像為基礎來建立
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
## 创建 tomcat/weblogic 集群
|
||||
### 安装 tomcat 镜像
|
||||
准备好需要的 jdk、tomcat 等软件放到 home 目录下面,启动一个容器
|
||||
## 建立 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
|
||||
|
@ -18,19 +18,19 @@ command=/usr/sbin/sshd -D
|
|||
docker commit ac6474aeb31d tomcat
|
||||
```
|
||||
|
||||
新建 tomcat 文件夹,新建 Dockerfile。
|
||||
新建 tomcat 文件夾,新建 Dockerfile。
|
||||
```
|
||||
FROM mk_tomcat
|
||||
EXPOSE 22 8080
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
根据 Dockerfile 创建镜像。
|
||||
根據 Dockerfile 建立鏡像。
|
||||
```
|
||||
docker build tomcat tomcat
|
||||
```
|
||||
### 安装 weblogic 镜像
|
||||
### 安裝 weblogic 鏡像
|
||||
|
||||
步骤和 tomcat 基本一致,这里贴一下配置文件
|
||||
步驟和 tomcat 基本一致,這裡貼一下設定文件
|
||||
```
|
||||
supervisor.conf
|
||||
[supervisord]
|
||||
|
@ -48,34 +48,34 @@ EXPOSE 22 7001
|
|||
CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
|
||||
### tomcat/weblogic 镜像的使用
|
||||
#### 存储的使用
|
||||
在启动的时候,使用 `-v` 参数
|
||||
### tomcat/weblogic 鏡像的使用
|
||||
#### 存儲的使用
|
||||
在啟動的時候,使用 `-v` 參數
|
||||
|
||||
-v, --volume=[] Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)
|
||||
|
||||
将本地磁盘映射到容器内部,它在主机和容器之间是实时变化的,所以我们更新程序、上传代码只需要更新物理主机的目录就可以了
|
||||
將本地磁盤映射到容器內部,它在主機和容器之間是實時變化的,所以我們更新程式、上傳代碼只需要更新物理主機的目錄就可以了
|
||||
|
||||
#### tomcat 和 weblogic 集群的实现
|
||||
tomcat 只要开启多个容器即可
|
||||
#### tomcat 和 weblogic 集群的實做
|
||||
tomcat 只要開啟多個容器即可
|
||||
```
|
||||
docker run -d -v -p 204:22 -p 7003:8080 -v /home/data:/opt/data --name tm1 tomcat /usr/bin/supervisord
|
||||
docker run -d -v -p 205:22 -p 7004:8080 -v /home/data:/opt/data --name tm2 tomcat /usr/bin/supervisord
|
||||
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 來做負載均衡就可以完成設定了
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# Docker 容器
|
||||
容器是 Docker 又一核心概念。
|
||||
|
||||
简单的说,容器是独立运行的一个或一组应用,以及它们的运行态环境。对应的,虚拟机可以理解为模拟运行的一整套操作系统(提供了运行态环境和其他系统环境)和跑在上面的应用。
|
||||
簡單的說,容器是獨立執行的一個或一組應用,以及它們的執行態環境。換句話說,虛擬機可以理解為模擬執行的一整套作業系統(提供了執行態環境和其他系統環境)和跑在上面的應用。
|
||||
|
||||
本章将具体介绍如何来管理一个容器,包括创建、启动和停止等。
|
||||
本章將具體介紹如何來管理一個容器,包括建立、啟動和停止等。
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## 进入容器
|
||||
在使用 `-d` 参数时,容器启动后会进入后台。
|
||||
某些时候需要进入容器进行操作,有很多种方法,包括使用 `docker attach` 命令或 `nsenter` 工具等。
|
||||
## 進入容器
|
||||
在使用 `-d` 參數時,容器啟動後會進入後臺。
|
||||
某些時候需要進入容器進行操作,有很多種方法,包括使用 `docker attach` 命令或 `nsenter` 工具等。
|
||||
### attach 命令
|
||||
`docker attach` 是Docker自带的命令。下面示例如何使用该命令。
|
||||
`docker attach` 是Docker內建的命令。下面示例如何使用該命令。
|
||||
```
|
||||
$ sudo docker run -idt ubuntu
|
||||
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
|
||||
|
@ -12,12 +12,12 @@ CONTAINER ID IMAGE COMMAND CREATED
|
|||
$sudo docker attach nostalgic_hypatia
|
||||
root@243c32535da7:/#
|
||||
```
|
||||
但是使用 `attach` 命令有时候并不方便。当多个窗口同时 attach 到同一个容器的时候,所有窗口都会同步显示。当某个窗口因命令阻塞时,其他窗口也无法执行操作了。
|
||||
但是使用 `attach` 命令有時候並不方便。當多個窗口同時 attach 到同一個容器的時候,所有窗口都會同步顯示。當某個窗口因命令阻塞時,其他窗口也無法執行操作了。
|
||||
|
||||
### nsenter 命令
|
||||
#### 安装
|
||||
`nsenter` 工具在 util-linux 包2.23版本后包含。
|
||||
如果系统中 util-linux 包没有该命令,可以按照下面的方法从源码安装。
|
||||
#### 安裝
|
||||
`nsenter` 工具已含括在 util-linux 2.23 後的版本內。
|
||||
如果系統中 util-linux 包沒有該命令,可以按照下面的方法從原始碼安裝。
|
||||
```
|
||||
$ cd /tmp; curl https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz | tar -zxf-; cd util-linux-2.24;
|
||||
$ ./configure --without-ncurses
|
||||
|
@ -25,23 +25,23 @@ $ make nsenter && sudo cp nsenter /usr/local/bin
|
|||
```
|
||||
|
||||
#### 使用
|
||||
`nsenter` 可以访问另一个进程的名字空间。nsenter 要正常工作需要有 root 权限。
|
||||
很不幸,Ubuntu 14.4 仍然使用的是 util-linux 2.20。安装最新版本的 util-linux(2.24)版,请按照以下步骤:
|
||||
`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
|
||||
$ 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
|
||||
```
|
||||
下面给出一个完整的例子。
|
||||
下面給出一個完整的例子。
|
||||
```
|
||||
$ sudo docker run -idt ubuntu
|
||||
243c32535da7d142fb0e6df616a3c3ada0b8ab417937c853a9e1c251f499f550
|
||||
|
@ -53,13 +53,13 @@ $ PID=$(docker-pid 243c32535da7)
|
|||
$ sudo nsenter --target 10981 --mount --uts --ipc --net --pid
|
||||
root@243c32535da7:/#
|
||||
```
|
||||
更简单的,建议大家下载
|
||||
[.bashrc_docker](https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker),并将内容放到 .bashrc 中。
|
||||
更簡單的,建議大家下載
|
||||
[.bashrc_docker](https://github.com/yeasy/docker_practice/raw/master/_local/.bashrc_docker),並將內容放到 .bashrc 中。
|
||||
```
|
||||
$ 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
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
##导出和导入容器
|
||||
##導出和導入容器
|
||||
|
||||
###导出容器
|
||||
如果要导出本地某个容器,可以使用 `docker export` 命令。
|
||||
###導出容器
|
||||
如果要導出本地某個容器,可以使用 `docker export` 命令。
|
||||
```
|
||||
$ sudo docker ps -a
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
7691a814370e ubuntu:14.04 "/bin/bash" 36 hours ago Exited (0) 21 hours ago test
|
||||
$ sudo docker export 7691a814370e > ubuntu.tar
|
||||
```
|
||||
这样将导出容器快照到本地文件。
|
||||
這樣將導出容器快照到本地文件。
|
||||
|
||||
###导入容器快照
|
||||
可以使用 `docker import` 从容器快照文件中再导入为镜像,例如
|
||||
###導入容器快照
|
||||
可以使用 `docker import` 從容器快照文件中再導入為映像檔,例如
|
||||
```
|
||||
$ cat ubuntu.tar | sudo docker import - test/buntu:v1.0
|
||||
$ 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` 來導入一個容器快照到本地映像檔庫。這兩者的區別在於容器快照文件將丟棄所有的歷史記錄和原始數據訊息(即僅保存容器當時的快照狀態),而映像檔儲存文件將保存完整記錄,檔案體積也跟著變大。此外,從容器快照文件導入時可以重新指定標簽等原始數據訊息。
|
||||
|
||||
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
##删除容器
|
||||
可以使用 `docker rm` 来删除一个处于终止状态的容器。
|
||||
##刪除容器
|
||||
可以使用 `docker rm` 來刪除一個處於終止狀態的容器。
|
||||
例如
|
||||
```
|
||||
$sudo docker rm trusting_newton
|
||||
trusting_newton
|
||||
```
|
||||
如果要删除一个运行中的容器,可以添加 `-f` 参数。Docker 会发送 `SIGKILL` 信号给容器。
|
||||
如果要刪除一個執行中的容器,可以新增 `-f` 參數。Docker 會發送 `SIGKILL` 信號給容器。
|
||||
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
##启动容器
|
||||
启动容器有两种方式,一种是基于镜像新建一个容器并启动,另外一个是将在终止状态(stopped)的容器重新启动。
|
||||
##啟動容器
|
||||
啟動容器有兩種方式,一種是將映像檔新建一個容器並啟動,另外一個是將終止狀態(stopped)的容器重新啟動。
|
||||
|
||||
因为 Docker 的容器实在太轻量级了,很多时候用户都是随时删除和新创建容器。
|
||||
因為 Docker 的容器實在太輕量級了,使用者可以隨時刪除和新建立容器。
|
||||
|
||||
###新建并启动
|
||||
所需要的命令主要为 `docker run`。
|
||||
###新建並啟動
|
||||
所需要的命令主要為 `docker run`。
|
||||
|
||||
例如,下面的命令输出一个 “Hello World”,之后终止容器。
|
||||
例如,下面的命令輸出一個 “Hello World”,之後終止容器。
|
||||
```
|
||||
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
|
||||
Hello world
|
||||
```
|
||||
这跟在本地直接执行 `/bin/echo '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` 则让容器的标准输入保持打开。
|
||||
其中,`-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` 命令,直接将一个已经终止的容器启动运行。
|
||||
###啟動已終止容器
|
||||
可以利用 `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 對資源的使用率極高,是貨真價實的輕量級虛擬化。
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
##终止容器
|
||||
可以使用 `docker stop` 来终止一个运行中的容器。
|
||||
##終止容器
|
||||
可以使用 `docker stop` 來終止一個執行中的容器。
|
||||
|
||||
此外,当Docker容器中指定的应用终结时,容器也自动终止。
|
||||
例如对于上一章节中只启动了一个终端的容器,用户通过 `exit` 命令或 `Ctrl+d` 来退出终端时,所创建的容器立刻终止。
|
||||
此外,當Docker容器中指定的應用終結時,容器也自動終止。
|
||||
例如對於上一章節中只啟動了一個終端機的容器,使用者透過 `exit` 命令或 `Ctrl+d` 來退出終端時,所建立的容器立刻終止。
|
||||
|
||||
终止状态的容器可以用 `docker ps -a` 命令看到。例如
|
||||
終止狀態的容器可以用 `docker ps -a` 命令看到。例如
|
||||
```
|
||||
sudo docker ps -a
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
|
@ -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` 命令会将一个运行态的容器终止,然后再重新启动它。
|
||||
此外,`docker restart` 命令會將一個執行中的容器終止,然後再重新啟動它。
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# Docker 数据管理
|
||||
这一章介绍如何在 Docker 内部以及容器之间管理数据,在容器中管理数据主要有两种方式:
|
||||
* 数据卷(Data volumes)
|
||||
* 数据卷容器(Data volume containers)
|
||||
# Docker 數據管理
|
||||
這一章介紹如何在 Docker 內部以及容器之間管理數據,在容器中管理數據主要有兩種方式:
|
||||
* 數據卷(Data volumes)
|
||||
* 數據卷容器(Data volume containers)
|
||||
|
|
|
@ -1,23 +1,23 @@
|
|||
## 数据卷容器
|
||||
如果你有一些持续更新的数据需要在容器之间共享,最好创建数据卷容器。
|
||||
## 數據卷容器
|
||||
如果你有一些持續更新的數據需要在容器之間共享,最好建立數據卷容器。
|
||||
|
||||
数据卷容器,其实就是一个正常的容器,专门用来提供数据卷供其它容器挂载的。
|
||||
數據卷容器,其實就是一個正常的容器,專門用來提供數據卷供其它容器掛載的。
|
||||
|
||||
首先,创建一个命名的数据卷容器 dbdata:
|
||||
首先,建立一個命名的數據卷容器 dbdata:
|
||||
```
|
||||
$ sudo docker run -d -v /dbdata --name dbdata training/postgres echo Data-only container for postgres
|
||||
```
|
||||
然后,在其他容器中使用 `--volumes-from` 来挂载 dbdata 容器中的数据卷。
|
||||
然後,在其他容器中使用 `--volumes-from` 來掛載 dbdata 容器中的數據卷。
|
||||
```
|
||||
$ sudo docker run -d --volumes-from dbdata --name db1 training/postgres
|
||||
$ sudo docker run -d --volumes-from dbdata --name db2 training/postgres
|
||||
```
|
||||
还可以使用多个 `--volumes-from` 参数来从多个容器挂载多个数据卷。
|
||||
也可以从其他已经挂载了容器卷的容器来挂载数据卷。
|
||||
還可以使用多個 `--volumes-from` 參數來從多個容器掛載多個數據卷。
|
||||
也可以從其他已經掛載了容器卷的容器來掛載數據卷。
|
||||
```
|
||||
$ sudo docker run -d --name db3 --volumes-from db1 training/postgres
|
||||
```
|
||||
*注意:使用 `--volumes-from` 参数所挂载数据卷的容器自己并不需要保持在运行状态。
|
||||
*註意:使用 `--volumes-from` 參數所掛載數據卷的容器自己並不需要保持在執行狀態。
|
||||
|
||||
如果删除了挂载的容器(包括 dbdata、db1 和 db2),数据卷并不会被自动删除。如果要删除一个数据卷,必须在删除最后一个还挂载着它的容器时使用 `docker rm -v` 命令来指定同时删除关联的容器。
|
||||
这可以让用户在容器之间升级和移动数据卷。具体的操作将在下一节中进行讲解。
|
||||
如果刪除了掛載的容器(包括 dbdata、db1 和 db2),數據卷並不會被自動刪除。如果要刪除一個數據卷,必須在刪除最後一個還掛載著它的容器時使用 `docker rm -v` 命令來指定同時刪除關聯的容器。
|
||||
這可以讓使用者在容器之間升級和移動數據卷。具體的操作將在下一節中進行講解。
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
## 利用数据卷容器来备份、恢复、迁移数据卷
|
||||
可以利用数据卷对其中的数据进行进行备份、恢复和迁移。
|
||||
## 利用數據卷容器來備份、恢復、遷移數據卷
|
||||
可以利用數據卷對其中的數據進行進行備份、恢復和遷移。
|
||||
|
||||
### 备份
|
||||
首先使用 `--volumes-from` 标记来创建一个加载 dbdata 容器卷的容器,并从本地主机挂载当前到容器的 /backup 目录。命令如下:
|
||||
### 備份
|
||||
首先使用 `--volumes-from` 標記來建立一個載入 dbdata 容器卷的容器,並從本地主機掛載當前到容器的 /backup 目錄。命令以下:
|
||||
```
|
||||
$ sudo docker run --volumes-from dbdata -v $(pwd):/backup ubuntu tar cvf /backup/backup.tar /dbdata
|
||||
```
|
||||
容器启动后,使用了 `tar` 命令来将 dbdata 卷备份为本地的 `/backup/backup.tar`。
|
||||
容器啟動後,使用了 `tar` 命令來將 dbdata 卷備份為本地的 `/backup/backup.tar`。
|
||||
|
||||
|
||||
### 恢复
|
||||
如果要恢复数据到一个容器,首先创建一个带有数据卷的容器 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
|
||||
|
|
|
@ -1,45 +1,45 @@
|
|||
## 数据卷
|
||||
数据卷是一个可供一个或多个容器使用的特殊目录,它绕过 UFS,可以提供很多有用的特性:
|
||||
* 数据卷可以在容器之间共享和重用
|
||||
* 对数据卷的修改会立马生效
|
||||
* 对数据卷的更新,不会影响镜像
|
||||
* 卷会一直存在,直到没有容器使用
|
||||
## 數據卷
|
||||
數據卷是一個可供一個或多個容器使用的特殊目錄,它繞過 UFS,可以提供很多有用的特性:
|
||||
* 數據卷可以在容器之間共享和重用
|
||||
* 對數據卷的修改會立馬生效
|
||||
* 對數據卷的更新,不會影響鏡像
|
||||
* 卷會一直存在,直到沒有容器使用
|
||||
|
||||
*数据卷的使用,类似于 Linux 下对目录或文件进行 mount。
|
||||
*數據卷的使用,類似於 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` 标记也可以指定挂载一个本地主机的目录到容器中去。
|
||||
### 掛載一個主機目錄作為數據卷
|
||||
使用 `-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 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。
|
||||
*註意:Dockerfile 中不支持這種用法,這是因為 Dockerfile 是為了移植和分享用的。然而,不同作業系統的路徑格式不一樣,所以目前還不能支持。
|
||||
|
||||
Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。
|
||||
Docker 掛載數據卷的默認權限是讀寫,使用者也可以透過 `:ro` 指定為唯讀。
|
||||
```
|
||||
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp:ro
|
||||
training/webapp python app.py
|
||||
```
|
||||
加了 `:ro` 之后,就挂载为只读了。
|
||||
加了 `:ro` 之後,就掛載為唯讀了。
|
||||
|
||||
### 挂载一个本地主机文件作为数据卷
|
||||
`-v` 标记也可以从主机挂载单个文件到容器中
|
||||
### 掛載一個本地主機文件作為數據卷
|
||||
`-v` 標記也可以從主機掛載單個文件到容器中
|
||||
```
|
||||
$ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
|
||||
```
|
||||
这样就可以记录在容器输入过的命令了。
|
||||
這樣就可以記錄在容器輸入過的命令了。
|
||||
|
||||
*注意:如果直接挂载一个文件,很多文件编辑工具,包括 `vi` 或者 `sed --in-place`,可能会造成文件 inode 的改变,从 Docker 1.1
|
||||
.0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
|
||||
*註意:如果直接掛載一個文件,很多文件編輯工具,包括 `vi` 或者 `sed --in-place`,可能會造成文件 inode 的改變,從 Docker 1.1
|
||||
.0起,這會導致報錯誤訊息。所以最簡單的辦法就直接掛載文件的父目錄。
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
# Dockerfile
|
||||
使用 Dockerfile 可以允许用户创建自定义的镜像。
|
||||
使用 Dockerfile 讓使用者可以建立自定義的映像檔。
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## 基本结构
|
||||
Dockerfile 由一行行命令语句组成,并且支持以 `#` 开头的注释行。
|
||||
## 基本結構
|
||||
Dockerfile 由一行行命令語句組成,並且支援以 `#` 開頭的註解行。
|
||||
|
||||
一般的,Dockerfile 分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。
|
||||
一般而言,Dockerfile 分為四部分:基底映像檔資訊、維護者資訊、映像檔操作指令和容器啟動時執行指令。
|
||||
|
||||
例如
|
||||
```
|
||||
|
@ -10,28 +10,28 @@ Dockerfile 由一行行命令语句组成,并且支持以 `#` 开头的注释
|
|||
# Author: docker_user
|
||||
# Command format: Instruction [arguments / command] ..
|
||||
|
||||
# Base image to use, this must be set as the first line
|
||||
# 基本映像檔,必須是第一個指令
|
||||
FROM ubuntu
|
||||
|
||||
# Maintainer: docker_user <docker_user at email.com> (@docker_user)
|
||||
# 維護者: docker_user <docker_user at email.com> (@docker_user)
|
||||
MAINTAINER docker_user docker_user@email.com
|
||||
|
||||
# Commands to update the image
|
||||
# 更新映像檔的指令
|
||||
RUN echo "deb http://archive.ubuntu.com/ubuntu/ raring main universe" >> /etc/apt/sources.list
|
||||
RUN apt-get update && apt-get install -y nginx
|
||||
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf
|
||||
|
||||
# Commands when creating a new container
|
||||
# 建立新容器時要執行的指令
|
||||
CMD /usr/sbin/nginx
|
||||
```
|
||||
|
||||
其中,一开始必须指明所基于的镜像名称,接下来推荐说明维护者信息。
|
||||
其中,一開始必須指明作為基底的映像檔名稱,接下來說明維護者資訊(建議)。
|
||||
|
||||
后面则是镜像操作指令,例如 `RUN` 指令,`RUN` 指令将对镜像执行跟随的命令。每运行一条 `RUN` 指令,镜像添加新的一层,并提交。
|
||||
接著則是映像檔操作指令,例如 `RUN` 指令,`RUN` 指令將對映像檔執行相對應的命令。每運行一條 `RUN` 指令,映像檔就會新增一層。
|
||||
|
||||
最后是 `CMD` 指令,来指定运行容器时的操作命令。
|
||||
最後是 `CMD` 指令,指定執行容器時的操作命令。
|
||||
|
||||
下面是一个更复杂的例子
|
||||
下面來看一個更複雜的例子
|
||||
```
|
||||
# Nginx
|
||||
#
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## 创建镜像
|
||||
编写完成 Dockerfile 之后,可以通过 `docker build` 命令来创建镜像。
|
||||
## 建立映像檔
|
||||
編輯完成 Dockerfile 之後,可以透過 `docker build` 命令建立映像檔。
|
||||
|
||||
基本的格式为 `docker build [选项] 路径`,该命令将读取指定路径下(包括子目录)的 Dockerfile,并将该路径下所有内容发送给 Docker 服务端,由服务端来创建镜像。因此一般建议放置 Dockerfile 的目录为空目录。也可以通过 `.dockerignore` 文件(每一行添加一条匹配模式)来让 Docker 忽略路径下的目录和文件。
|
||||
基本的格式為 `docekr build [選項] 路徑`,該命令將讀取指定路徑下(包括子目錄)的 Dockerfile,並將該路徑下所有內容發送給 Docker 伺服端,由伺服端來建立鏡像。因此一般會建議放置 Dockerfile 的目錄為空目錄。也可以透過 `.dockerignore` 文件(每一行新增一條排除模式:exclusion patterns)來讓 Docker 忽略路徑下的目錄和文件。
|
||||
|
||||
要指定镜像的标签信息,可以通过 `-t` 选项,例如
|
||||
要指定鏡像的標籤資訊,可以透過 `-t` 選項,例如
|
||||
```
|
||||
$ sudo docker build -t myrepo/myapp /tmp/test1/
|
||||
```
|
||||
|
|
|
@ -1,40 +1,40 @@
|
|||
## 指令
|
||||
指令的一般格式为 `INSTRUCTION arguments`,指令包括 `FROM`、`MAINTAINER`、`RUN` 等。
|
||||
指令的一般格式為 `INSTRUCTION arguments`,指令包括 `FROM`、`MAINTAINER`、`RUN` 等。
|
||||
|
||||
### FROM
|
||||
格式为 `FROM <image>`或`FROM <image>:<tag>`。
|
||||
格式為 `FROM <image>`或`FROM <image>:<tag>`。
|
||||
|
||||
第一条指令必须为 `FROM` 指令。并且,如果在同一个Dockerfile中创建多个镜像时,可以使用多个 `FROM` 指令(每个镜像一次)。
|
||||
第一條指令必須為 `FROM` 指令。並且,如果在同一個Dockerfile中建立多個映像檔時,可以使用多個 `FROM` 指令(每個映像檔一次)。
|
||||
|
||||
### MAINTAINER
|
||||
格式为 `MAINTAINER <name>`,指定维护者信息。
|
||||
格式為 `MAINTAINER <name>`,指定維護者訊息。
|
||||
|
||||
### RUN
|
||||
格式为 `RUN <command>` 或 `RUN ["executable", "param1", "param2"]`。
|
||||
格式為 `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` 指令将在当前镜像基础上执行指定命令,并提交为新的镜像。当命令较长时可以使用 `\` 来换行。
|
||||
每條 `RUN` 指令將在當前映像檔基底上執行指定命令,並產生新的映像檔。當命令較長時可以使用 `\` 來換行。
|
||||
|
||||
### CMD
|
||||
支持三种格式
|
||||
* `CMD ["executable","param1","param2"]` 使用 `exec` 执行,推荐方式;
|
||||
* `CMD command param1 param2` 在 `/bin/sh` 中执行,提供给需要交互的应用;
|
||||
* `CMD ["param1","param2"]` 提供给 `ENTRYPOINT` 的默认参数;
|
||||
支持三種格式
|
||||
* `CMD ["executable","param1","param2"]` 使用 `exec` 執行,推薦使用;
|
||||
* `CMD command param1 param2` 在 `/bin/sh` 中執行,使用在給需要互動的指令;
|
||||
* `CMD ["param1","param2"]` 提供給 `ENTRYPOINT` 的預設參數;
|
||||
|
||||
|
||||
指定启动容器时执行的命令,每个 Dockerfile 只能有一条 `CMD` 命令。如果指定了多条命令,只有最后一条会被执行。
|
||||
指定啟動容器時執行的命令,每個 Dockerfile 只能有一條 `CMD` 命令。如果指定了多條命令,只有最後一條會被執行。
|
||||
|
||||
如果用户启动容器时候指定了运行的命令,则会覆盖掉 `CMD` 指定的命令。
|
||||
如果使用者啟動容器時候指定了運行的命令,則會覆蓋掉 `CMD` 指定的命令。
|
||||
|
||||
### EXPOSE
|
||||
格式为 `EXPOSE <port> [<port>...]`。
|
||||
格式為 `EXPOSE <port> [<port>...]`。
|
||||
|
||||
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。
|
||||
設定 Docker 伺服器容器對外的埠號,供外界使用。在啟動容器時需要透過 -P,Docker 會自動分配一個埠號轉發到指定的埠號。
|
||||
|
||||
### ENV
|
||||
格式为 `ENV <key> <value>`。
|
||||
指定一个环境变量,会被后续 `RUN` 指令使用,并在容器运行时保持。
|
||||
格式為 `ENV <key> <value>`。
|
||||
指定一個環境變數,會被後續 `RUN` 指令使用,並在容器運行時保持。
|
||||
|
||||
例如
|
||||
```
|
||||
|
@ -45,59 +45,59 @@ ENV PATH /usr/local/postgres-$PG_MAJOR/bin:$PATH
|
|||
```
|
||||
|
||||
### ADD
|
||||
格式为 `ADD <src> <dest>`。
|
||||
格式為 `ADD <src> <dest>`。
|
||||
|
||||
该命令将复制指定的 `<src>` 到容器中的 `<dest>`。
|
||||
其中 `<src>` 可以是Dockerfile所在目录的一个相对路径;也可以是一个 URL;还可以是一个 tar 文件(自动解压为目录)。
|
||||
該命令將複製指定的 `<src>` 到容器中的 `<dest>`。
|
||||
其中 `<src>` 可以是 Dockerfile 所在目錄的相對路徑;也可以是一個 URL;還可以是一個 tar 文件(其複製後會自動解壓縮)。
|
||||
|
||||
### COPY
|
||||
格式为 `COPY <src> <dest>`。
|
||||
格式為 `COPY <src> <dest>`。
|
||||
|
||||
复制本地主机的 `<src>`(为 Dockerfile 所在目录的相对路径)到容器中的 `<dest>`。
|
||||
複製本地端的 `<src>`(為 Dockerfile 所在目錄的相對路徑)到容器中的 `<dest>`。
|
||||
|
||||
当使用本地目录为源目录时,推荐使用 `COPY`。
|
||||
當使用本地目錄為根目錄時,推薦使用 `COPY`。
|
||||
|
||||
### ENTRYPOINT
|
||||
两种格式:
|
||||
兩種格式:
|
||||
* `ENTRYPOINT ["executable", "param1", "param2"]`
|
||||
* `ENTRYPOINT command param1 param2`(shell中执行)。
|
||||
* `ENTRYPOINT command param1 param2`(shell中執行)。
|
||||
|
||||
配置容器启动后执行的命令,并且不可被 `docker run` 提供的参数覆盖。
|
||||
指定容器啟動後執行的命令,並且不會被 `docker run` 提供的參數覆蓋。
|
||||
|
||||
每个 Dockerfile 中只能有一个 `ENTRYPOINT`,当指定多个时,只有最后一个起效。
|
||||
每個 Dockerfile 中只能有一個 `ENTRYPOINT`,當指定多個時,只有最後一個會生效。
|
||||
|
||||
### VOLUME
|
||||
格式为 `VOLUME ["/data"]`。
|
||||
格式為 `VOLUME ["/data"]`。
|
||||
|
||||
创建一个可以从本地主机或其他容器挂载的挂载点,一般用来存放数据库和需要保持的数据等。
|
||||
建立一個可以從本地端或其他容器掛載的掛載點,一般用來存放資料庫和需要保存的資料等。
|
||||
|
||||
### USER
|
||||
格式为 `USER daemon`。
|
||||
格式為 `USER daemon`。
|
||||
|
||||
指定运行容器时的用户名或 UID,后续的 `RUN` 也会使用指定用户。
|
||||
指定運行容器時的使用者名稱或 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`。
|
||||
格式為 `WORKDIR /path/to/workdir`。
|
||||
|
||||
为后续的 `RUN`、`CMD`、`ENTRYPOINT` 指令配置工作目录。
|
||||
為後續的 `RUN`、`CMD`、`ENTRYPOINT` 指令指定工作目錄。
|
||||
|
||||
可以使用多个 `WORKDIR` 指令,后续命令如果参数是相对路径,则会基于之前命令指定的路径。例如
|
||||
可以使用多個 `WORKDIR` 指令,後續命令如果參數是相對路徑,則會基於之前命令指定的路徑。例如
|
||||
```
|
||||
WORKDIR /a
|
||||
WORKDIR b
|
||||
WORKDIR c
|
||||
RUN pwd
|
||||
```
|
||||
则最终路径为 `/a/b/c`。
|
||||
則最終路徑為 `/a/b/c`。
|
||||
|
||||
### ONBUILD
|
||||
格式为 `ONBUILD [INSTRUCTION]`。
|
||||
格式為 `ONBUILD [INSTRUCTION]`。
|
||||
|
||||
配置当所创建的镜像作为其它新创建镜像的基础镜像时,所执行的操作指令。
|
||||
指定當建立的映像檔作為其它新建立映像檔的基底映像檔時,所執行的操作指令。
|
||||
|
||||
例如,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
|
||||
|
||||
|
@ -114,5 +114,4 @@ ADD . /app/src
|
|||
RUN /usr/local/bin/python-build --dir /app/src
|
||||
```
|
||||
|
||||
使用 `ONBUILD` 指令的镜像,推荐在标签中注明,例如 `ruby:1.9-onbuild`。
|
||||
|
||||
使用 `ONBUILD` 指令的映像檔,推薦在標簽中註明,例如 `ruby:1.9-onbuild`。
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# Docker 镜像
|
||||
# Docker 鏡像
|
||||
|
||||
在之前的介绍中,我们知道镜像是 Docker 的三大组件之一。
|
||||
在之前的介紹中,我們知道鏡像是 Docker 的三大組件之一。
|
||||
|
||||
Docker 运行容器前需要本地存在对应的镜像,如果镜像不存在本地,Docker 会从镜像仓库下载(默认是 Docker Hub 公共注册服务器中的仓库)。
|
||||
Docker 在執行容器前需要本地存在對應的鏡像,如果鏡像不存在本地,Docker 會從鏡像倉庫下載(預設是 Docker Hub 公共註冊伺服器中的倉庫)。
|
||||
|
||||
本章将介绍更多关于镜像的内容,包括:
|
||||
* 从仓库获取镜像;
|
||||
* 管理本地主机上的镜像;
|
||||
* 介绍镜像实现的基本原理。
|
||||
本章將介紹更多關於鏡像的內容,包括:
|
||||
* 從倉庫取得鏡像;
|
||||
* 管理本地主機上的鏡像;
|
||||
* 介紹鏡像實做的基本原理。
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
##创建镜像
|
||||
##建立鏡像
|
||||
|
||||
创建镜像有很多方法,用户可以从 Docker Hub 获取已有镜像并更新,也可以利用本地文件系统创建一个。
|
||||
建立鏡像有很多方法,使用者可以從 Docker Hub 取得已有鏡像並更新,也可以利用本地文件系統建立一個。
|
||||
|
||||
### 修改已有镜像
|
||||
先使用下载的镜像启动容器。
|
||||
### 修改已有鏡像
|
||||
先使用下載的鏡像啟動容器。
|
||||
```
|
||||
$ sudo docker run -t -i training/sinatra /bin/bash
|
||||
root@0b2616b0e5a8:/#
|
||||
```
|
||||
注意:记住容器的 ID,稍后还会用到。
|
||||
註意:記住容器的 ID,稍後還會用到。
|
||||
|
||||
在容器中添加 json 和 gem 两个应用。
|
||||
在容器中新增 json 和 gem 兩個應用。
|
||||
```
|
||||
root@0b2616b0e5a8:/# gem install json
|
||||
```
|
||||
当结束后,我们使用 exit 来退出,现在我们的容器已经被我们改变了,使用 `docker commit` 命令来提交更新后的副本。
|
||||
當結束後,我們使用 exit 來退出,現在我們的容器已經被我們改變了,使用 `docker commit` 命令來提交更新後的副本。
|
||||
```
|
||||
$ 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
|
||||
|
@ -30,22 +30,22 @@ training/sinatra latest 5bc342fa0b91 10 hours ago 446.7 MB
|
|||
ouruser/sinatra v2 3c59e02ddd1a 10 hours ago 446.7 MB
|
||||
ouruser/sinatra latest 5db5f8471261 10 hours ago 446.7 MB
|
||||
```
|
||||
之后,可以使用新的镜像来启动容器
|
||||
之後,可以使用新的鏡像來啟動容器
|
||||
```
|
||||
$ 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
|
||||
新建一個目錄和一個 Dockerfile
|
||||
```
|
||||
$ mkdir sinatra
|
||||
$ cd sinatra
|
||||
$ touch Dockerfile
|
||||
```
|
||||
Dockerfile 中每一条指令都创建镜像的一层,例如:
|
||||
Dockerfile 中每一條指令都建立鏡像的一層,例如:
|
||||
```
|
||||
# This is a comment
|
||||
FROM ubuntu:14.04
|
||||
|
@ -54,13 +54,13 @@ RUN apt-get -qq update
|
|||
RUN apt-get -qqy install ruby ruby-dev
|
||||
RUN gem install sinatra
|
||||
```
|
||||
Dockerfile 基本的语法是
|
||||
* 使用`#`来注释
|
||||
* `FROM` 指令告诉 Docker 使用哪个镜像作为基础
|
||||
* 接着是维护者的信息
|
||||
* `RUN`开头的指令会在创建中运行,比如安装一个软件包,在这里使用 apt-get 来安装了一些软件
|
||||
Dockerfile 基本的語法是
|
||||
* 使用`#`來註解
|
||||
* `FROM` 指令告訴 Docker 使用哪個鏡像作為基礎
|
||||
* 接著是維護者的訊息
|
||||
* `RUN`開頭的指令會在建立中執行,比如安裝一個軟件包,在這裡使用 apt-get 來安裝了一些軟件
|
||||
|
||||
编写完成 Dockerfile 后可以使用 `docker build` 来生成镜像。
|
||||
編寫完成 Dockerfile 後可以使用 `docker build` 來生成鏡像。
|
||||
|
||||
```
|
||||
$ sudo docker build -t="ouruser/sinatra:v2" .
|
||||
|
@ -96,15 +96,15 @@ Successfully installed sinatra-1.4.5
|
|||
Removing intermediate container 5e9d0065c1f7
|
||||
Successfully built 324104cde6ad
|
||||
```
|
||||
其中 `-t` 标记来添加 tag,指定新的镜像的用户信息。
|
||||
“.” 是 Dockerfile 所在的路径(当前目录),也可以替换为一个具体的 Dockerfile 的路径。
|
||||
其中 `-t` 標記來新增 tag,指定新的鏡像的使用者訊息。
|
||||
“.” 是 Dockerfile 所在的路徑(當前目錄),也可以替換為一個具體的 Dockerfile 的路徑。
|
||||
|
||||
可以看到 build 进程在执行操作。它要做的第一件事情就是上传这个 Dockerfile 内容,因为所有的操作都要依据 Dockerfile 来进行。
|
||||
然后,Dockfile 中的指令被一条一条的执行。每一步都创建了一个新的容器,在容器中执行指令并提交修改(就跟之前介绍过的 `docker commit` 一样)。当所有的指令都执行完毕之后,返回了最终的镜像 id。所有的中间步骤所产生的容器都被删除和清理了。
|
||||
可以看到 build 程式在執行操作。它要做的第一件事情就是上傳這個 Dockerfile 內容,因為所有的操作都要依據 Dockerfile 來進行。
|
||||
然後,Dockfile 中的指令被一條一條的執行。每一步都建立了一個新的容器,在容器中執行指令並提交修改(就跟之前介紹過的 `docker commit` 一樣)。當所有的指令都執行完畢之後,返回了最終的鏡像 id。所有的中間步驟所產生的容器都被刪除和清理了。
|
||||
|
||||
*注意一个镜像不能超过 127 层
|
||||
*註意一個鏡像不能超過 127 層
|
||||
|
||||
此外,还可以利用 `ADD` 命令复制本地文件到镜像;用 `EXPOSE` 命令来向外部开放端口;用 `CMD` 命令来描述容器启动后运行的程序等。例如
|
||||
此外,還可以利用 `ADD` 命令復制本地文件到鏡像;用 `EXPOSE` 命令來向外部開放端口;用 `CMD` 命令來描述容器啟動後執行的程式等。例如
|
||||
```
|
||||
# put my local web site in myApp folder to /var/www
|
||||
ADD myApp /var/www
|
||||
|
@ -114,12 +114,12 @@ EXPOSE 80
|
|||
CMD ["/usr/sbin/apachectl", "-D", "FOREGROUND"]
|
||||
```
|
||||
|
||||
现在可以利用新创建的镜像来启动一个容器。
|
||||
現在可以利用新建立的鏡像來啟動一個容器。
|
||||
```
|
||||
$ sudo docker run -t -i ouruser/sinatra:v2 /bin/bash
|
||||
root@8196968dac35:/#
|
||||
```
|
||||
还可以用 `docker tag` 命令来修改镜像的标签。
|
||||
還可以用 `docker tag` 命令來修改鏡像的標簽。
|
||||
```
|
||||
$ sudo docker tag 5db5f8471261 ouruser/sinatra:devel
|
||||
$ sudo docker images ouruser/sinatra
|
||||
|
@ -129,25 +129,25 @@ ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB
|
|||
ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
|
||||
```
|
||||
|
||||
*注:更多用法,请参考 [Dockerfile](../dockerfile/README.md) 章节。
|
||||
*註:更多用法,請參考 [Dockerfile](../dockerfile/README.md) 章節。
|
||||
|
||||
### 从本地文件系统导入
|
||||
要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建:
|
||||
openvz 的模板下载地址为 http://openvz.org/Download/templates/precreated。
|
||||
### 從本地文件系統導入
|
||||
要從本地文件系統導入一個鏡像,可以使用 openvz(容器虛擬化的先鋒技術)的模板來建立:
|
||||
openvz 的模板下載地址為 http://openvz.org/Download/templates/precreated。
|
||||
|
||||
比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:
|
||||
比如,先下載了一個 ubuntu-14.04 的鏡像,之後使用以下命令導入:
|
||||
```
|
||||
sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04
|
||||
```
|
||||
然后查看新导入的镜像。
|
||||
然後查看新導入的鏡像。
|
||||
```
|
||||
docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
ubuntu 14.04 05ac7c0b9383 17 seconds ago 215.5 MB
|
||||
```
|
||||
|
||||
###上传镜像
|
||||
用户可以通过 `docker push` 命令,把自己创建的镜像上传到仓库中来共享。例如,用户在 Docker Hub 上完成注册后,可以推送自己的镜像到仓库中。
|
||||
###上傳鏡像
|
||||
使用者可以透過 `docker push` 命令,把自己建立的鏡像上傳到倉庫中來共享。例如,使用者在 Docker Hub 上完成註冊後,可以推送自己的鏡像到倉庫中。
|
||||
```
|
||||
$ sudo docker push ouruser/sinatra
|
||||
The push refers to a repository [ouruser/sinatra] (len: 1)
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## 镜像的实现原理
|
||||
## 鏡像的實做原理
|
||||
|
||||
Docker 镜像是怎么实现增量的修改和维护的?
|
||||
每个镜像都由很多层次构成,Docker 使用 [Union FS](http://en.wikipedia.org/wiki/UnionFS) 将这些不同的层结合到一个镜像中去。
|
||||
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 上建立的容器也是利用了類似的原理。
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## 列出本地镜像
|
||||
使用 `docker images` 显示本地已有的镜像。
|
||||
## 列出本地鏡像
|
||||
使用 `docker images` 顯示本地已有的鏡像。
|
||||
```
|
||||
$ sudo docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
|
@ -11,19 +11,19 @@ ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
|
|||
...
|
||||
```
|
||||
|
||||
在列出信息中,可以看到几个字段信息
|
||||
在列出訊息中,可以看到幾段文字訊息
|
||||
|
||||
* 来自于哪个仓库,比如 ubuntu
|
||||
* 镜像的标记,比如 14.04
|
||||
* 它的 `ID` 号(唯一)
|
||||
* 创建时间
|
||||
* 镜像大小
|
||||
* 來自於哪個倉庫,比如 ubuntu
|
||||
* 鏡像的標記,比如 14.04
|
||||
* 它的 `ID` 號(唯一)
|
||||
* 建立時間
|
||||
* 鏡像大小
|
||||
|
||||
其中镜像的 `ID` 唯一标识了镜像,注意到 `ubuntu:14.04` 和 `ubuntu:trusty` 具有相同的镜像 `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
|
||||
```
|
||||
|
||||
如果不指定具体的标记,则默认使用 `latest` 标记信息。
|
||||
如果不指定具體的標記,則預設使用 `latest`
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## 获取镜像
|
||||
## 取得映像檔
|
||||
|
||||
可以使用 `docker pull` 命令来从仓库获取所需要的镜像。
|
||||
可以使用 `docker pull` 命令來從倉庫取得所需要的映像檔。
|
||||
|
||||
下面的例子将从 Docker Hub 仓库下载一个 Ubuntu 12.04 操作系统的镜像。
|
||||
下面的例子將從 Docker Hub 倉庫下載一個 Ubuntu 12.04 作業系統的映像檔。
|
||||
```
|
||||
$ sudo docker pull ubuntu:12.04
|
||||
Pulling repository ubuntu
|
||||
|
@ -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:/#
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
## 移除本地镜像
|
||||
如果要移除本地的镜像,可以使用 `docker rmi` 命令。注意 `docker rm` 命令是移除容器。
|
||||
## 移除本地鏡像
|
||||
如果要移除本地的鏡像,可以使用 `docker rmi` 命令。註意 `docker rm` 命令是移除容器。
|
||||
```
|
||||
$ sudo docker rmi training/sinatra
|
||||
Untagged: training/sinatra:latest
|
||||
|
@ -8,4 +8,4 @@ Deleted: ed0fffdcdae5eb2c3a55549857a8be7fc8bc4241fb19ad714364cbfd7a56b22f
|
|||
Deleted: 5c58979d73ae448df5af1d8142436d81116187a7633082650549c52c3a2418f0
|
||||
```
|
||||
|
||||
*注意:在删除镜像之前要先用 `docker rm` 删掉依赖于这个镜像的所有容器。
|
||||
*註意:在刪除鏡像之前要先用 `docker rm` 刪掉依賴於這個鏡像的所有容器。
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## 存出和载入镜像
|
||||
## 存出和載入鏡像
|
||||
|
||||
### 存出镜像
|
||||
如果要导出镜像到本地文件,可以使用 `docker save` 命令。
|
||||
### 存出鏡像
|
||||
如果要導出鏡像到本地文件,可以使用 `docker save` 命令。
|
||||
```
|
||||
$ sudo docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
|
@ -10,8 +10,8 @@ ubuntu 14.04 c4ff7513909d 5 weeks ago
|
|||
$sudo docker save -o ubuntu_14.04.tar ubuntu:14.04
|
||||
```
|
||||
|
||||
### 载入镜像
|
||||
可以使用 `docker load` 从导出的本地文件中再导入到本地镜像库,例如
|
||||
### 載入鏡像
|
||||
可以使用 `docker load` 從導出的本地文件中再導入到本地鏡像庫,例如
|
||||
```
|
||||
$ sudo docker load --input ubuntu_14.04.tar
|
||||
```
|
||||
|
@ -19,4 +19,4 @@ $ sudo docker load --input ubuntu_14.04.tar
|
|||
```
|
||||
$ sudo docker load < ubuntu_14.04.tar
|
||||
```
|
||||
这将导入镜像以及其相关的元数据信息(包括标签等)。
|
||||
這將導入鏡像以及其相關的元數據訊息(包括標簽等)。
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# 安装
|
||||
官方网站上有各种环境下的 [安装指南](https://docs.docker.com/installation/#installation),这里主要介绍下Ubuntu和CentOS系列的安装。
|
||||
# 安裝
|
||||
官方網站上有各種環境下的 [安裝指南](https://docs.docker.com/installation/#installation),這裡主要介紹下Ubuntu和CentOS系列的安裝。
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
## CentOS 系列安装 Docker
|
||||
## CentOS 系列安裝 Docker
|
||||
|
||||
Docker 支持 CentOS6 及以后的版本。
|
||||
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
|
||||
```
|
||||
|
||||
### CentOS7
|
||||
CentOS7 系统 `CentOS-Extras` 库中已带 Docker,可以直接安装:
|
||||
CentOS7 系統 `CentOS-Extras` 庫中已內建 Docker,可以直接安裝:
|
||||
```
|
||||
$ sudo yum install docker
|
||||
```
|
||||
|
||||
安装之后启动 Docker 服务,并让它随系统启动自动加载。
|
||||
安裝之後啟動 Docker 服務,並讓它隨系統啟動自動載入。
|
||||
```
|
||||
$ sudo service docker start
|
||||
$ sudo chkconfig docker on
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
## Ubuntu 系列安装 Docker
|
||||
## Ubuntu 系列安裝 Docker
|
||||
|
||||
### 通过系统自带包安装
|
||||
Ubuntu 14.04 版本系统中已经自带了 Docker 包,可以直接安装。
|
||||
### 透過系統內建套件安裝
|
||||
Ubuntu 14.04 版本套件庫中已經內建了 Docker 套件,可以直接安裝。
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install -y docker.io
|
||||
|
@ -9,28 +9,28 @@ $ 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
|
||||
$ sudo bash -c "echo deb https://get.docker.io/ubuntu docker main > /etc/apt/sources.list.d/docker.list"
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install lxc-docker
|
||||
$ sudo apt-get install -y lxc-docker
|
||||
```
|
||||
|
||||
### 14.04 之前版本
|
||||
如果是较低版本的 Ubuntu 系统,需要先更新内核。
|
||||
如果是較舊版本的 Ubuntu 系統,需要先更新核心。
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
|
||||
$ sudo reboot
|
||||
```
|
||||
然后重复上面的步骤即可。
|
||||
然後重複上面的步驟即可。
|
||||
|
||||
安装之后启动 Docker 服务。
|
||||
安裝之後啟動 Docker 服務。
|
||||
```
|
||||
$ sudo service docker start
|
||||
```
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
# 简介
|
||||
本章将带领你进入 Docker 的世界。
|
||||
# 簡介
|
||||
本章將帶領你進入 Docker 的世界。
|
||||
|
||||
什么是 Docker?
|
||||
什麼是 Docker?
|
||||
|
||||
用它会带来什么样的好处?
|
||||
用它會帶來什麼樣的好處?
|
||||
|
||||
好吧,让我们带着问题开始这神奇之旅。
|
||||
好吧,讓我們帶著問題開始這神奇之旅。
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
## 什么是 Docker
|
||||
Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。
|
||||
项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 [GitHub](https://github.com/docker/docker) 上进行维护。
|
||||
## 什麼是 Docker
|
||||
Docker 是一個開源項目,誕生於 2013 年初,最初是 dotCloud 公司內部的一個業餘項目。它基於 Google 公司推出的 Go 語言實做。
|
||||
項目後來加入了 Linux 基金會,遵從了 Apache 2.0 協議,原始碼在 [GitHub](https://github.com/docker/docker) 上進行維護。
|
||||
|
||||
Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 产品中广泛应用。
|
||||
Docker 自開源後受到廣泛的關注和討論,以至於 dotCloud 公司後來都改名為 Docker Inc。Redhat 已經在其 RHEL6.5 中集中支持 Docker;Google 也在其 PaaS 產品中廣泛應用。
|
||||
|
||||
Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。
|
||||
Docker 的基础是 Linux 容器(LXC)等技术。
|
||||
Docker 項目的目標是實做輕量級的作業系統虛擬化解決方案。
|
||||
Docker 的基礎是 Linux 容器(LXC)等技術。
|
||||
|
||||
在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。
|
||||
在 LXC 的基礎上 Docker 進行了進一步的封裝,讓使用者不需要去關心容器的管理,使得操作更為簡便。使用者操作 Docker 的容器就像操作一個快速輕量級的虛擬機一樣簡單。
|
||||
|
||||
下面的图片比较了 Docker 和传统虚拟化方式的不同之处,可见容器是在操作系统层面上实现虚拟化,直接复用本地主机的操作系统,而传统方式则是在硬件层面实现。
|
||||
下面的圖片比較了 Docker 和傳統虛擬化方式的不同之處,可見容器是在作業系統層面上實做虛擬化,直接使用本地主機的作業系統,而傳統方式則是在硬體層面實做。
|
||||
|
||||
![传统虚拟化](../_images/virtualization.png)
|
||||
![傳統虛擬化](../_images/virtualization.png)
|
||||
|
||||
![Docker](../_images/docker.png)
|
||||
|
|
|
@ -1,35 +1,36 @@
|
|||
## 为什么要使用 Docker?
|
||||
作为一种新兴的虚拟化方式,Docker 跟传统的虚拟化方式相比具有众多的优势。
|
||||
## 為什麼要使用 Docker?
|
||||
作為一種新興的虛擬化方式,Docker 跟傳統的虛擬化方式相比具有眾多的優勢。
|
||||
|
||||
首先,Docker 容器的启动可以在秒级实现,这相比传统的虚拟机方式要快得多。
|
||||
其次,Docker 对系统资源的利用率很高,一台主机上可以同时运行数千个 Docker 容器。
|
||||
首先,Docker 容器的啟動可以在秒級實做,這相比傳統的虛擬機方式要快得多。
|
||||
其次,Docker 對系統資源的使用率很高,一台主機上可以同時執行數千個 Docker 容器。
|
||||
|
||||
容器除了运行其中应用外,基本不消耗额外的系统资源,使得应用的性能很高,同时系统的开销尽量小。传统虚拟机方式运行 10 个不同的应用就要起 10 个虚拟机,而Docker 只需要启动 10 个隔离的应用即可。
|
||||
容器除了執行其中應用外,基本不消耗額外的系統資源,使得應用的效能很高,同時系統資源消耗更少。傳統虛擬機方式執行 10 個不同的應用就要啟動 10 個虛擬機,而 Docker 只需要啟動 10 個隔離的應用即可。
|
||||
|
||||
具体说来,Docker 在如下几个方面具有较大的优势。
|
||||
具體說來,Docker 在以下幾個方面具有較大的優勢。
|
||||
|
||||
### 更快速的交付和部署
|
||||
对开发和运维(devop)人员来说,最希望的就是一次创建或配置,可以在任意地方正常运行。
|
||||
對開發和維運(develop)人員來說,最希望的就是一次建立或設定,可以在任意地方正常執行。
|
||||
|
||||
开发者可以使用一个标准的镜像来构建一套开发容器,开发完成之后,运维人员可以直接使用这个容器来部署代码。
|
||||
Docker 可以快速创建容器,快速迭代应用程序,并让整个过程全程可见,使团队中的其他成员更容易理解应用程序是如何创建和工作的。
|
||||
Docker 容器很轻很快!容器的启动时间是秒级的,大量地节约开发、测试、部署的时间。
|
||||
開發者可以使用一個標準的映像檔來建立一套開發容器,開發完成之後,維運人員可以直接使用這個容器來部署程式碼。
|
||||
Docker 可以快速建立容器,快速迭代應用程式,並讓整個過程全程可見,使團隊中的其他成員更容易理解應用程式是如何建立和工作的。
|
||||
Docker 容器很輕很快!容器的啟動時間是秒級的,大量地節約開發、測試、部署的時間。
|
||||
|
||||
### 更高效的虚拟化
|
||||
Docker 容器的运行不需要额外的 hypervisor 支持,它是内核级的虚拟化,因此可以实现更高的性能和效率。
|
||||
### 更有效率的虛擬化
|
||||
Docker 容器的執行不需要額外的虛擬化支持,它是核心層級的虛擬化,因此可以實做更高的效能和效率。
|
||||
|
||||
### 更轻松的迁移和扩展
|
||||
### 更輕鬆的遷移和擴展
|
||||
|
||||
Docker 容器几乎可以在任意的平台上运行,包括物理机、虚拟机、公有云、私有云、个人电脑、服务器等。
|
||||
这种兼容性可以让用户把一个应用程序从一个平台直接迁移到另外一个。
|
||||
Docker 容器幾乎可以在任意的平台上執行,包括實體機器、虛擬機、公有雲、私有雲、個人電腦、伺服器等。
|
||||
這種兼容性可以讓使用者把一個應用程式從一個平台直接遷移到另外一個。
|
||||
|
||||
### 更简单的管理
|
||||
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分发和更新,从而实现自动化并且高效的管理。
|
||||
### 更簡單的管理
|
||||
使用 Docker,只需要小小的修改,就可以替代以往大量的更新工作。所有的修改都以增量的方式被分發和更新,從而實做自動化並且有效率的管理。
|
||||
|
||||
### 对比传统虚拟机总结
|
||||
| 特性 | 容器 | 虚拟机 |
|
||||
| -- | -- | -- |
|
||||
| 启动 | 秒级 | 分钟级 |
|
||||
| 硬盘使用 | 一般为 MB | 一般为 GB |
|
||||
| 性能 | 接近原生 | 弱于 |
|
||||
| 系统支持量 | 单机支持上千个容器 | 一般几十个 |
|
||||
### 對比傳統虛擬機總結
|
||||
|
||||
| 特性 | 容器 | 虛擬機 |
|
||||
| ---- | ---- | ------ |
|
||||
| 啟動 | 秒級 | 分鐘級 |
|
||||
| 硬碟容量 | 一般為 MB | 一般為 GB |
|
||||
| 效能 | 接近原生 | 比較慢 |
|
||||
| 系統支持量 | 單機支持上千個容器 | 一般幾十個 |
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
# Docker 中的网络功能介绍
|
||||
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
|
||||
# Docker 中的網路功能介紹
|
||||
Docker 允許透過外部訪問容器或容器互聯的方式來提供網路服務。
|
||||
|
|
|
@ -1,70 +1,70 @@
|
|||
## 容器互联
|
||||
容器的连接(linking)系统是除了端口映射外,另一种跟容器中应用交互的方式。
|
||||
## 容器互聯
|
||||
容器的連接(linking)系統是除了端口映射外,另一種跟容器中應用交互的方式。
|
||||
|
||||
该系统会在源和接收容器之间创建一个隧道,接收容器可以看到源容器指定的信息。
|
||||
該系統會在源和接收容器之間建立一個隧道,接收容器可以看到源容器指定的訊息。
|
||||
|
||||
### 自定义容器命名
|
||||
连接系统依据容器的名称来执行。因此,首先需要自定义一个好记的容器命名。
|
||||
### 自定義容器命名
|
||||
連接系統依據容器的名稱來執行。因此,首先需要自定義一個好記的容器命名。
|
||||
|
||||
虽然当创建容器的时候,系统默认会分配一个名字。自定义命名容器有2个好处:
|
||||
* 自定义的命名,比较好记,比如一个web应用容器我们可以给它起名叫web
|
||||
* 当要连接其他容器时候,可以作为一个有用的参考点,比如连接web容器到db容器
|
||||
雖然當建立容器的時候,系統默認會分配一個名字。自定義命名容器有2個好處:
|
||||
* 自定義的命名,比較好記,比如一個web應用容器我們可以給它起名叫web
|
||||
* 當要連接其他容器時候,可以作為一個有用的參考點,比如連接web容器到db容器
|
||||
|
||||
使用 `--name` 标记可以为容器自定义命名。
|
||||
使用 `--name` 標記可以為容器自定義命名。
|
||||
```
|
||||
$ sudo docker run -d -P --name web training/webapp python app.py
|
||||
```
|
||||
|
||||
使用 `docker ps` 来验证设定的命名。
|
||||
使用 `docker ps` 來驗證設定的命名。
|
||||
```
|
||||
$ sudo docker ps -l
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
|
||||
```
|
||||
也可以使用 `docker inspect` 来查看容器的名字
|
||||
也可以使用 `docker inspect` 來查看容器的名字
|
||||
```
|
||||
$ 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` 参数可以让容器之间安全的进行交互。
|
||||
###容器互聯
|
||||
使用 `--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
|
||||
```
|
||||
此时,db 容器和 web 容器建立互联关系。
|
||||
此時,db 容器和 web 容器建立互聯關系。
|
||||
|
||||
`--link` 参数的格式为 `--link name:alias`,其中 `name` 是要链接的容器的名称,`alias` 是这个连接的别名。
|
||||
`--link` 參數的格式為 `--link name:alias`,其中 `name` 是要鏈接的容器的名稱,`alias` 是這個連接的別名。
|
||||
|
||||
使用 `docker ps` 来查看容器的连接
|
||||
使用 `docker ps` 來查看容器的連接
|
||||
```
|
||||
$ docker ps
|
||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||
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 在兩個互聯的容器之間建立了一個安全隧道,而且不用映射它們的端口到宿主主機上。在啟動 db 容器的時候並沒有使用 `-p` 和 `-P` 標記,從而避免了暴露數據庫端口到外部網路上。
|
||||
|
||||
Docker 通过 2 种方式为容器公开连接信息:
|
||||
* 环境变量
|
||||
Docker 透過 2 種方式為容器公開連接訊息:
|
||||
* 環境變量
|
||||
* 更新 `/etc/hosts` 文件
|
||||
|
||||
使用 `env` 命令来查看 web 容器的环境变量
|
||||
使用 `env` 命令來查看 web 容器的環境變量
|
||||
```
|
||||
$ sudo docker run --rm --name web2 --link db:db training/webapp env
|
||||
. . .
|
||||
|
@ -76,9 +76,9 @@ DB_PORT_5000_TCP_PORT=5432
|
|||
DB_PORT_5000_TCP_ADDR=172.17.0.5
|
||||
. . .
|
||||
```
|
||||
其中 DB_ 开头的环境变量是供 web 容器连接 db 容器使用,前缀采用大写的连接别名。
|
||||
其中 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,8 +86,8 @@ root@aed84ee21bde:/opt/webapp# cat /etc/hosts
|
|||
. . .
|
||||
172.17.0.5 db
|
||||
```
|
||||
这里有 2 个 hosts,第一个是 web 容器,web 容器用 id 作为他的主机名,第二个是 db 容器的 ip 和主机名。
|
||||
可以在 web 容器中安装 ping 命令来测试跟db容器的连通。
|
||||
這裡有 2 個 hosts,第一個是 web 容器,web 容器用 id 作為他的主機名,第二個是 db 容器的 ip 和主機名。
|
||||
可以在 web 容器中安裝 ping 命令來測試跟db容器的連通。
|
||||
```
|
||||
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
|
||||
root@aed84ee21bde:/opt/webapp# ping db
|
||||
|
@ -96,7 +96,7 @@ PING db (172.17.0.5): 48 data bytes
|
|||
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
|
||||
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms
|
||||
```
|
||||
用 ping 来测试db容器,它会解析成 `172.17.0.5`。
|
||||
*注意:官方的 ubuntu 镜像默认没有安装 ping,需要自行安装。
|
||||
用 ping 來測試db容器,它會解析成 `172.17.0.5`。
|
||||
*註意:官方的 ubuntu 鏡像默認沒有安裝 ping,需要自行安裝。
|
||||
|
||||
用户可以链接多个子容器到父容器,比如可以链接多个 web 到 db 容器上。
|
||||
使用者可以鏈接多個子容器到父容器,比如可以鏈接多個 web 到 db 容器上。
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
## 外部访问容器
|
||||
容器中可以运行一些网络应用,要让外部也可以访问这些应用,可以通过 `-P` 或 `-p` 参数来指定端口映射。
|
||||
## 外部訪問容器
|
||||
容器中可以執行一些網路應用,要讓外部也可以訪問這些應用,可以透過 `-P` 或 `-p` 參數來指定端口映射。
|
||||
|
||||
当使用 -P 标记时,Docker 会随机映射一个 `49000~49900` 的端口到内部容器开放的网络端口。
|
||||
當使用 -P 標記時,Docker 會隨機映射一個 `49000~49900` 的端口到內部容器開放的網路端口。
|
||||
|
||||
使用 `docker ps` 可以看到,本地主机的 49155 被映射到了容器的 5000 端口。此时访问本机的 49115 端口即可访问容器内 web 应用提供的界面。
|
||||
使用 `docker ps` 可以看到,本地主機的 49155 被映射到了容器的 5000 端口。此時訪問本機的 49115 端口即可訪問容器內 web 應用提供的界面。
|
||||
```
|
||||
$ sudo docker run -d -P training/webapp python app.py
|
||||
$ 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/
|
||||
|
@ -18,38 +18,38 @@ $ sudo docker logs -f nostalgic_morse
|
|||
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
```
|
||||
|
||||
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 `ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。
|
||||
-p(小寫的)則可以指定要映射的端口,並且,在一個指定端口上只可以綁定一個容器。支持的格式有 `ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。
|
||||
|
||||
### 映射所有接口地址
|
||||
使用 `hostPort:containerPort` 格式本地的 5000 端口映射到容器的 5000 端口,可以执行
|
||||
使用 `hostPort:containerPort` 格式本地的 5000 端口映射到容器的 5000 端口,可以執行
|
||||
```
|
||||
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
|
||||
```
|
||||
此时默认会绑定本地所有接口上的所有地址。
|
||||
此時默認會綁定本地所有接口上的所有地址。
|
||||
|
||||
### 映射到指定地址的指定端口
|
||||
可以使用 `ip:hostPort:containerPort` 格式指定映射使用一个特定地址,比如 localhost 地址 127.0.0.1
|
||||
可以使用 `ip:hostPort:containerPort` 格式指定映射使用一個特定地址,比如 localhost 地址 127.0.0.1
|
||||
```
|
||||
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
|
||||
```
|
||||
### 映射到指定地址的任意端口
|
||||
使用 `ip::containerPort` 绑定 localhost 的任意端口到容器的 5000 端口,本地主机会自动分配一个端口。
|
||||
使用 `ip::containerPort` 綁定 localhost 的任意端口到容器的 5000 端口,本地主機會自動分配一個端口。
|
||||
```
|
||||
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
|
||||
```
|
||||
还可以使用 udp 标记来指定 udp 端口
|
||||
還可以使用 udp 標記來指定 udp 端口
|
||||
```
|
||||
$ 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 还可以有一个可变的网络配置。)
|
||||
* -p 标记可以多次使用来绑定多个端口
|
||||
註意:
|
||||
* 容器有自己的內部網路和 ip 地址(使用 `docker inspect` 可以取得所有的變量,Docker 還可以有一個可變的網路設定。)
|
||||
* -p 標記可以多次使用來綁定多個端口
|
||||
|
||||
例如
|
||||
```
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
# 仓库
|
||||
# 倉庫
|
||||
|
||||
仓库(Repository)是集中存放镜像的地方。
|
||||
倉庫(Repository)是集中存放映像檔的地方。
|
||||
|
||||
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 `dl.dockerpool.com/ubuntu` 来说,`dl.dockerpool.com` 是注册服务器地址,`ubuntu` 是仓库名。
|
||||
一個容易混淆的概念是註冊伺服器(Registry)。實際上註冊伺服器是管理倉庫的具體伺服器,每個伺服器上可以有多個倉庫,而每個倉庫下面有多個映像檔。從這方面來說,倉庫可以被認為是一個具體的項目或目錄。例如對於倉庫地址 `dl.dockerpool.com/ubuntu` 來說,`dl.dockerpool.com` 是註冊伺服器地址,`ubuntu` 是倉庫名。
|
||||
|
||||
大部分时候,并不需要严格区分这两者的概念。
|
||||
大部分時候,並不需要嚴格區分這兩者的概念。
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,30 +1,30 @@
|
|||
## 仓库配置文件
|
||||
Docker 的 Registry 利用配置文件提供了一些仓库的模板(flavor),用户可以直接使用它们来进行开发或生产部署。
|
||||
## 倉庫設定文件
|
||||
Docker 的 Registry 利用設定文件提供了一些倉庫的模組(flavor),使用者可以直接使用它們來進行開發或生產部署。
|
||||
|
||||
### 模板
|
||||
在 `config_sample.yml` 文件中,可以看到一些现成的模板段:
|
||||
* `common`:基础配置
|
||||
* `local`:存储数据到本地文件系统
|
||||
* `s3`:存储数据到 AWS S3 中
|
||||
* `dev`:使用 `local` 模板的基本配置
|
||||
* `test`:单元测试使用
|
||||
* `prod`:生产环境配置(基本上跟s3配置类似)
|
||||
* `gcs`:存储数据到 Google 的云存储
|
||||
* `swift`:存储数据到 OpenStack Swift 服务
|
||||
* `glance`:存储数据到 OpenStack Glance 服务,本地文件系统为后备
|
||||
* `glance-swift`:存储数据到 OpenStack Glance 服务,Swift 为后备
|
||||
* `elliptics`:存储数据到 Elliptics key/value 存储
|
||||
### 模組
|
||||
在 `config_sample.yml` 文件中,可以看到一些現成的模組段:
|
||||
* `common`:基礎設定
|
||||
* `local`:儲存數據到本地文件系統
|
||||
* `s3`:儲存數據到 AWS S3 中
|
||||
* `dev`:使用 `local` 模組的基本設定
|
||||
* `test`:單元測試使用
|
||||
* `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
|
||||
|
@ -54,4 +54,4 @@ test:
|
|||
storage_path: /tmp/tmpdockertmp
|
||||
```
|
||||
|
||||
### 选项
|
||||
### 選項
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
## 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 为关键词进行搜索:
|
||||
例如以 centos 為關鍵字進行搜索:
|
||||
```
|
||||
$ sudo docker search centos
|
||||
NAME DESCRIPTION STARS OFFICIAL AUTOMATED
|
||||
|
@ -19,16 +19,16 @@ 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 镜像到本地。
|
||||
下載官方 centos 映像檔到本地。
|
||||
```
|
||||
$ sudo docker pull centos
|
||||
Pulling repository 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 中 [配置一个自动创建](https://registry.hub.docker.com/builds/add/);
|
||||
* 选取一个目标网站中的项目(需要含 Dockerfile)和分支;
|
||||
* 指定 Dockerfile 的位置,并提交创建。
|
||||
要設定自動建立,包括以下的步驟:
|
||||
* 建立並登陸 Docker Hub,以及目標網站;
|
||||
* 在目標網站中連接帳戶到 Docker Hub;
|
||||
* 在 Docker Hub 中 [設定一個自動建立](https://registry.hub.docker.com/builds/add/);
|
||||
* 選取一個目標網站中的項目(需要含 Dockerfile)和分支;
|
||||
* 指定 Dockerfile 的位置,並提交建立。
|
||||
|
||||
之后,可以 在Docker Hub 的 [自动创建页面](https://registry.hub.docker.com/builds/) 中跟踪每次创建的状态。
|
||||
之後,可以 在Docker Hub 的 [自動建立頁面](https://registry.hub.docker.com/builds/) 中跟蹤每次建立的狀態。
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
## 私有仓库
|
||||
## 私有倉庫
|
||||
|
||||
有时候使用 Docker Hub 这样的公共仓库可能不方便,用户可以创建一个本地仓库供私人使用。
|
||||
有時候使用 Docker Hub 這樣的公共倉庫可能不方便,使用者可以建立一個本地倉庫供私人使用。
|
||||
|
||||
本节介绍如何使用本地仓库。
|
||||
本節介紹如何使用本地倉庫。
|
||||
|
||||
`docker-registry` 是官方提供的工具,可以用于构建私有的镜像仓库。
|
||||
### 安装运行 docker-registry
|
||||
#### 容器运行
|
||||
在安装了 Docker 后,可以通过获取官方 registry 镜像来运行。
|
||||
`docker-registry` 是官方提供的工具,可以用於建立私有的映像檔倉庫。
|
||||
### 安裝執行 docker-registry
|
||||
#### 容器執行
|
||||
在安裝了 Docker 後,可以透過取得官方 registry 映像檔來執行。
|
||||
```
|
||||
$ sudo docker run -d -p 5000:5000 registry
|
||||
```
|
||||
这将使用官方的 registry 镜像来启动本地的私有仓库。
|
||||
用户可以通过指定参数来配置私有仓库位置,例如配置镜像存储到 Amazon S3 服务。
|
||||
這將使用官方的 registry 映像檔來啟動本地的私有倉庫。
|
||||
使用者可以透過指定參數來設定私有倉庫位置,例如設定映像檔存儲到 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
|
||||
|
@ -47,18 +47,18 @@ $ sudo yum install -y python-devel libevent-devel python-pip gcc xz-devel
|
|||
$ sudo python-pip install docker-registry
|
||||
```
|
||||
|
||||
也可以从 [docker-registry](https://github.com/docker/docker-registry) 项目下载源码进行安装。
|
||||
也可以從 [docker-registry](https://github.com/docker/docker-registry) 項目下載原始碼進行安裝。
|
||||
```
|
||||
$ sudo apt-get install build-essential python-dev libevent-dev python-pip libssl-dev liblzma-dev libffi-dev
|
||||
$ 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
|
||||
```
|
||||
之后启动 Web 服务。
|
||||
之後啟動 Web 服務。
|
||||
```
|
||||
$ sudo gunicorn -c contrib/gunicorn.py docker_registry.wsgi:application
|
||||
```
|
||||
|
@ -66,14 +66,14 @@ $ sudo gunicorn -c contrib/gunicorn.py docker_registry.wsgi:application
|
|||
```
|
||||
$ sudo gunicorn --access-logfile - --error-logfile - -k gevent -b 0.0.0.0:5000 -w 4 --max-requests 100 docker_registry.wsgi:application
|
||||
```
|
||||
此时使用访问本地的 5000 端口,看到输出 docker-registry 的版本信息说明运行成功。
|
||||
此時使用連結本地的 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`。
|
||||
|
||||
先在本机查看已有的镜像。
|
||||
先在本機查看已有的映像檔。
|
||||
```
|
||||
$ sudo docker images
|
||||
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE
|
||||
|
@ -81,7 +81,7 @@ ubuntu latest ba5877dc9bec 6 week
|
|||
ubuntu 14.04 ba5877dc9bec 6 weeks ago 192.7 MB
|
||||
```
|
||||
|
||||
使用`docker tag` 将 `ba58` 这个镜像标记为 `192.168.7.26:5000/test`(格式为 `docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]`)。
|
||||
使用`docker tag` 將 `ba58` 這個映像檔標記為 `192.168.7.26:5000/test`(格式為 `docker tag IMAGE[:TAG] [REGISTRYHOST/][USERNAME/]NAME[:TAG]`)。
|
||||
```
|
||||
$ sudo docker tag ba58 192.168.7.26:5000/test
|
||||
root ~ # docker images
|
||||
|
@ -90,7 +90,7 @@ ubuntu 14.04 ba5877dc9bec 6 week
|
|||
ubuntu latest ba5877dc9bec 6 weeks ago 192.7 MB
|
||||
192.168.7.26:5000/test latest ba5877dc9bec 6 weeks ago 192.7 MB
|
||||
```
|
||||
使用 `docker push` 上传标记的镜像。
|
||||
使用 `docker push` 上傳標記的映像檔。
|
||||
```
|
||||
$ sudo docker push 192.168.7.26:5000/test
|
||||
The push refers to a repository [192.168.7.26:5000/test] (len: 1)
|
||||
|
@ -104,14 +104,14 @@ Image 2318d26665ef already pushed, skipping
|
|||
Image ba5877dc9bec already pushed, skipping
|
||||
Pushing tag for rev [ba5877dc9bec] on {http://192.168.7.26:5000/v1/repositories/test/tags/latest}
|
||||
```
|
||||
用 curl 查看仓库中的镜像。
|
||||
用 curl 查看倉庫中的映像檔。
|
||||
```
|
||||
$ 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"}`,表明映像檔已經被成功上傳了。
|
||||
|
||||
现在可以到另外一台机器去下载这个镜像。
|
||||
現在可以到另外一臺機器去下載這個映像檔。
|
||||
```
|
||||
$ sudo docker pull 192.168.7.26:5000/test
|
||||
Pulling repository 192.168.7.26:5000/test
|
||||
|
@ -126,7 +126,7 @@ REPOSITORY TAG IMAGE ID CREAT
|
|||
192.168.7.26:5000/test latest ba5877dc9bec 6 weeks ago 192.7 MB
|
||||
```
|
||||
|
||||
可以使用 [这个脚本](https://github.com/yeasy/docker_practice/raw/master/_local/push_images.sh) 批量上传本地的镜像到注册服务器中,默认是本地注册服务器 `127.0.0.1:5000`。例如:
|
||||
可以使用 [這個腳本](https://github.com/yeasy/docker_practice/raw/master/_local/push_images.sh) 批次上傳本地的映像檔到註冊伺服器中,預設為本地註冊伺服器 `127.0.0.1:5000`。例如:
|
||||
```
|
||||
$ wget https://github.com/yeasy/docker_practice/raw/master/_local/push_images.sh; sudo chmod a+x push_images.sh
|
||||
$ ./push_images.sh ubuntu:latest centos:centos7
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# 安全
|
||||
评估 Docker 的安全性时,主要考虑三个方面:
|
||||
* 由内核的名字空间和控制组机制提供的容器内在安全
|
||||
* Docker程序(特别是服务端)本身的抗攻击性
|
||||
* 内核安全性的加强机制对容器安全性的影响
|
||||
評估 Docker 的安全性時,主要考慮三個方面:
|
||||
* 由內核的名字空間和控制組機制提供的容器內在安全
|
||||
* Docker程式(特別是服務端)本身的抗攻擊性
|
||||
* 內核安全性的加強機制對容器安全性的影響
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
## 控制组
|
||||
控制组是 Linux 容器机制的另外一个关键组件,负责实现资源的审计和限制。
|
||||
## 控制組
|
||||
控制組是 Linux 容器機制的另外一個關鍵組件,負責實做資源的審計和限制。
|
||||
|
||||
它提供了很多有用的特性;以及确保各个容器可以公平地分享主机的内存、CPU、磁盘 IO 等资源;当然,更重要的是,控制组确保了当容器内的资源使用产生压力时不会连累主机系统。
|
||||
它提供了很多有用的特性;以及確保各個容器可以公平地分享主機的內存、CPU、磁盤 IO 等資源;當然,更重要的是,控制組確保了當容器內的資源使用產生壓力時不會連累主機系統。
|
||||
|
||||
尽管控制组不负责隔离容器之间相互访问、处理数据和进程,它在防止拒绝服务(DDOS)攻击方面是必不可少的。尤其是在多用户的平台(比如公有或私有的 PaaS)上,控制组十分重要。例如,当某些应用程序表现异常的时候,可以保证一致地正常运行和性能。
|
||||
盡管控制組不負責隔離容器之間相互訪問、處理數據和程式,它在防止拒絕服務(DDOS)攻擊方面是必不可少的。尤其是在多使用者的平臺(比如公有或私有的 PaaS)上,控制組十分重要。例如,當某些應用程式表現異常的時候,可以保證一致地正常執行和效能。
|
||||
|
||||
控制组机制始于 2006 年,内核从 2.6.24 版本开始被引入。
|
||||
控制組機制始於 2006 年,內核從 2.6.24 版本開始被引入。
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
## Docker服务端的防护
|
||||
运行一个容器或应用程序的核心是通过 Docker 服务端。Docker 服务的运行目前需要 root 权限,因此其安全性十分关键。
|
||||
## Docker服務端的防護
|
||||
執行一個容器或應用程式的核心是透過 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 权限下运行,利用安全可靠的子进程来代理执行需要特权权限的操作。这些子进程将只允许在限定范围内进行操作,例如仅仅负责虚拟网络设定或文件系统管理、配置操作等。
|
||||
終極目標是改進 2 個重要的安全特性:
|
||||
* 將容器的 root 使用者映射到本地主機上的非 root 使用者,減輕容器和主機之間因權限提升而引起的安全問題;
|
||||
* 允許 Docker 服務端在非 root 權限下執行,利用安全可靠的子程式來代理執行需要特權權限的操作。這些子程式將只允許在限定範圍內進行操作,例如僅僅負責虛擬網路設定或文件系統管理、設定操作等。
|
||||
|
||||
最后,建议采用专用的服务器来运行 Docker 和相关的管理服务(例如管理服务比如 ssh 监控和进程监控、管理工具 nrpe、collectd 等)。其它的业务服务都放到容器中去运行。
|
||||
最後,建議采用專用的伺服器來執行 Docker 和相關的管理服務(例如管理服務比如 ssh 監控和程式監控、管理工具 nrpe、collectd 等)。其它的業務服務都放到容器中去執行。
|
||||
|
|
|
@ -1,26 +1,26 @@
|
|||
## 内核能力机制
|
||||
## 內核能力機制
|
||||
|
||||
能力机制(Capability)是 Linux 内核一个强大的特性,可以提供细粒度的权限访问控制。
|
||||
Linux 内核自 2.2 版本起就支持能力机制,它将权限划分为更加细粒度的操作能力,既可以作用在进程上,也可以作用在文件上。
|
||||
能力機制(Capability)是 Linux 內核一個強大的特性,可以提供細粒度的權限訪問控制。
|
||||
Linux 內核自 2.2 版本起就支持能力機制,它將權限劃分為更加細粒度的操作能力,既可以作用在程式上,也可以作用在文件上。
|
||||
|
||||
例如,一个 Web 服务进程只需要绑定一个低于 1024 的端口的权限,并不需要 root 权限。那么它只需要被授权 `net_bind_service` 能力即可。此外,还有很多其他的类似能力来避免进程获取 root 权限。
|
||||
例如,一個 Web 服務程式只需要綁定一個低於 1024 的端口的權限,並不需要 root 權限。那麽它只需要被授權 `net_bind_service` 能力即可。此外,還有很多其他的類似能力來避免程式取得 root 權限。
|
||||
|
||||
默认情况下,Docker 启动的容器被严格限制只允许使用内核的一部分能力。
|
||||
默認情況下,Docker 啟動的容器被嚴格限制只允許使用內核的一部分能力。
|
||||
|
||||
使用能力机制对加强 Docker 容器的安全有很多好处。通常,在服务器上会运行一堆需要特权权限的进程,包括有 ssh、cron、syslogd、硬件管理工具模块(例如负载模块)、网络配置工具等等。容器跟这些进程是不同的,因为几乎所有的特权进程都由容器以外的支持系统来进行管理。
|
||||
* ssh 访问被主机上ssh服务来管理;
|
||||
* cron 通常应该作为用户进程执行,权限交给使用它服务的应用来处理;
|
||||
* 日志系统可由 Docker 或第三方服务管理;
|
||||
* 硬件管理无关紧要,容器中也就无需执行 udevd 以及类似服务;
|
||||
* 网络管理也都在主机上设置,除非特殊需求,容器不需要对网络进行配置。
|
||||
使用能力機制對加強 Docker 容器的安全有很多好處。通常,在伺服器上會執行一堆需要特權權限的程式,包括有 ssh、cron、syslogd、硬件管理工具模塊(例如負載模塊)、網路設定工具等等。容器跟這些程式是不同的,因為幾乎所有的特權程式都由容器以外的支持系統來進行管理。
|
||||
* ssh 訪問被主機上ssh服務來管理;
|
||||
* cron 通常應該作為使用者程式執行,權限交給使用它服務的應用來處理;
|
||||
* 日誌系統可由 Docker 或第三方服務管理;
|
||||
* 硬件管理無關緊要,容器中也就無需執行 udevd 以及類似服務;
|
||||
* 網路管理也都在主機上設置,除非特殊需求,容器不需要對網路進行設定。
|
||||
|
||||
从上面的例子可以看出,大部分情况下,容器并不需要“真正的” root 权限,容器只需要少数的能力即可。为了加强安全,容器可以禁用一些没必要的权限。
|
||||
從上面的例子可以看出,大部分情況下,容器並不需要“真正的” root 權限,容器只需要少數的能力即可。為了加強安全,容器可以禁用一些沒必要的權限。
|
||||
* 完全禁止任何 mount 操作;
|
||||
* 禁止直接访问本地主机的套接字;
|
||||
* 禁止访问一些文件系统的操作,比如创建新的设备、修改文件属性等;
|
||||
* 禁止模块加载。
|
||||
* 禁止直接訪問本地主機的套接字;
|
||||
* 禁止訪問一些文件系統的操作,比如建立新的設備、修改文件屬性等;
|
||||
* 禁止模塊載入。
|
||||
|
||||
这样,就算攻击者在容器中取得了 root 权限,也不能获得本地主机的较高权限,能进行的破坏也有限。
|
||||
這樣,就算攻擊者在容器中取得了 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采用 [白名單](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 容器啟用額外的權限。
|
||||
|
|
|
@ -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 月发布)之后被引入,数年间,这些机制的可靠性在诸多大型生产系统中被实践验证。
|
||||
內核名字空間從 2.6.15 版本(2008 年 7 月發布)之後被引入,數年間,這些機制的可靠性在諸多大型生產系統中被實踐驗證。
|
||||
|
||||
实际上,名字空间的想法和设计提出的时间要更早,最初是为了在内核中引入一种机制来实现 [OpenVZ](http://en.wikipedia.org/wiki/OpenVZ) 的特性。
|
||||
而 OpenVZ 项目早在 2005 年就发布了,其设计和实现都已经十分成熟。
|
||||
實際上,名字空間的想法和設計提出的時間要更早,最初是為了在內核中引入一種機制來實做 [OpenVZ](http://en.wikipedia.org/wiki/OpenVZ) 的特性。
|
||||
而 OpenVZ 項目早在 2005 年就發布了,其設計和實做都已經十分成熟。
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## 其它安全特性
|
||||
除了能力机制之外,还可以利用一些现有的安全机制来增强使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。
|
||||
除了能力機制之外,還可以利用一些現有的安全機制來增強使用 Docker 的安全性,例如 TOMOYO, AppArmor, SELinux, GRSEC 等。
|
||||
|
||||
Docker 当前默认只启用了能力机制。用户可以采用多种方案来加强 Docker 主机的安全,例如:
|
||||
* 在内核中启用 GRSEC 和 PAX,这将增加很多编译和运行时的安全检查;通过地址随机化避免恶意探测等。并且,启用该特性不需要 Docker 进行任何配置。
|
||||
* 使用一些有增强安全特性的容器模板,比如带 AppArmor 的模板和 Redhat 带 SELinux 策略的模板。这些模板提供了额外的安全特性。
|
||||
* 用户可以自定义访问控制机制来定制安全策略。
|
||||
Docker 當前默認只啟用了能力機制。使用者可以采用多種方案來加強 Docker 主機的安全,例如:
|
||||
* 在內核中啟用 GRSEC 和 PAX,這將增加很多編譯和執行時的安全檢查;透過地址隨機化避免惡意探測等。並且,啟用該特性不需要 Docker 進行任何設定。
|
||||
* 使用一些有增強安全特性的容器模板,比如帶 AppArmor 的模板和 Redhat 帶 SELinux 策略的模板。這些模板提供了額外的安全特性。
|
||||
* 使用者可以自定義訪問控制機制來定制安全策略。
|
||||
|
||||
跟其它添加到 Docker 容器的第三方工具一样(比如网络拓扑和文件系统共享),有很多类似的机制,在不改变 Docker 内核情况下就可以加固现有的容器。
|
||||
跟其它新增到 Docker 容器的第三方工具一樣(比如網路拓撲和文件系統共享),有很多類似的機制,在不改變 Docker 內核情況下就可以加固現有的容器。
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## 总结
|
||||
总体来看,Docker 容器还是十分安全的,特别是在容器内不使用 root 权限来运行进程的话。
|
||||
## 總結
|
||||
總體來看,Docker 容器還是十分安全的,特別是在容器內不使用 root 權限來執行程式的話。
|
||||
|
||||
另外,用户可以使用现有工具,比如 Apparmor, SELinux, GRSEC 来增强安全性;甚至自己在内核中实现更复杂的安全机制。
|
||||
另外,使用者可以使用現有工具,比如 Apparmor, SELinux, GRSEC 來增強安全性;甚至自己在內核中實做更復雜的安全機制。
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
# 底层实现
|
||||
# 底層實做
|
||||
|
||||
Docker 底层的核心技术包括 Linux 上的名字空间(Namespaces)、控制组(Control groups)、Union 文件系统(Union file systems)和容器格式(Container format)。
|
||||
Docker 底層的核心技術包括 Linux 上的名字空間(Namespaces)、控制組(Control groups)、Union 文件系統(Union file systems)和容器格式(Container format)。
|
||||
|
||||
我们知道,传统的虚拟机通过在宿主主机中运行 hypervisor 来模拟一整套完整的硬件环境提供给虚拟机的操作系统。虚拟机系统看到的环境是可限制的,也是彼此隔离的。
|
||||
这种直接的做法实现了对资源最完整的封装,但很多时候往往意味着系统资源的浪费。
|
||||
例如,以宿主机和虚拟机系统都为 Linux 系统为例,虚拟机中运行的应用其实可以利用宿主机系统中的运行环境。
|
||||
我們知道,傳統的虛擬機透過在宿主主機中執行 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 來做資源分配。
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
## 基本架构
|
||||
Docker 采用了 C/S架构,包括客户端和服务端。
|
||||
Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。
|
||||
客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。
|
||||
## 基本架構
|
||||
Docker 采用了 C/S架構,包括客戶端和服務端。
|
||||
Docker daemon 作為服務端接受來自客戶的請求,並處理這些請求(建立、執行、分發容器)。
|
||||
客戶端和服務端既可以執行在一個機器上,也可透過 socket 或者 RESTful API 來進行通信。
|
||||
|
||||
![Docker 基本架构](../_images/docker_arch.png)
|
||||
![Docker 基本架構](../_images/docker_arch.png)
|
||||
|
||||
|
||||
Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。
|
||||
Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。
|
||||
Docker daemon 一般在宿主主機後臺執行,等待接收來自客戶端的消息。
|
||||
Docker 客戶端則為使用者提供一系列可執行命令,使用者用這些命令實做跟 Docker daemon 交互。
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
## 控制组
|
||||
## 控制組
|
||||
|
||||
控制组([cgroups](http://en.wikipedia.org/wiki/Cgroups))是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。
|
||||
控制組([cgroups](http://en.wikipedia.org/wiki/Cgroups))是 Linux 內核的一個特性,主要用來對共享資源進行隔離、限制、審計等。只有能控制分配到容器的資源,才能避免當多個容器同時執行時的對系統資源的競爭。
|
||||
|
||||
控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。
|
||||
控制組技術最早是由 Google 的程式員 2006 年起提出,Linux 內核自 2.6.24 開始支持。
|
||||
|
||||
控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。
|
||||
控制組可以提供對容器的內存、CPU、磁盤 IO 等資源的限制和審計管理。
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
## 容器格式
|
||||
最初,Docker 采用了 LXC 中的容器格式。自 1.20 版本开始,Docker 也开始支持新的 [libcontainer](https://github.com/docker/libcontainer) 格式,并作为默认选项。
|
||||
最初,Docker 采用了 LXC 中的容器格式。自 1.20 版本開始,Docker 也開始支持新的 [libcontainer](https://github.com/docker/libcontainer) 格式,並作為默認選項。
|
||||
|
||||
对更多容器格式的支持,还在进一步的发展中。
|
||||
對更多容器格式的支持,還在進一步的發展中。
|
||||
|
|
|
@ -1,22 +1,22 @@
|
|||
## 名字空间
|
||||
名字空间是 Linux 内核一个强大的特性。每个容器都有自己单独的名字空间,运行在其中的应用都像是在独立的操作系统中运行一样。名字空间保证了容器之间彼此互不影响。
|
||||
## 名字空間
|
||||
名字空間是 Linux 內核一個強大的特性。每個容器都有自己單獨的名字空間,執行在其中的應用都像是在獨立的作業系統中執行一樣。名字空間保證了容器之間彼此互不影響。
|
||||
|
||||
### pid 名字空间
|
||||
不同用户的进程就是通过 pid 名字空间隔离开的,且不同名字空间中可以有相同 pid。所有的 LXC 进程在 Docker 中的父进程为Docker进程,每个 LXC 进程具有不同的名字空间。同时由于允许嵌套,因此可以很方便的实现嵌套的 Docker 容器。
|
||||
### pid 名字空間
|
||||
不同使用者的程式就是透過 pid 名字空間隔離開的,且不同名字空間中可以有相同 pid。所有的 LXC 程式在 Docker 中的父程式為Docker程式,每個 LXC 程式具有不同的名字空間。同時由於允許嵌套,因此可以很方便的實做嵌套的 Docker 容器。
|
||||
|
||||
### net 名字空间
|
||||
有了 pid 名字空间, 每个名字空间中的 pid 能够相互隔离,但是网络端口还是共享 host 的端口。网络隔离是通过 net 名字空间实现的, 每个 net 名字空间有独立的 网络设备, IP 地址, 路由表, /proc/net 目录。这样每个容器的网络就能隔离开来。Docker 默认采用 veth 的方式,将容器中的虚拟网卡同 host 上的一 个Docker 网桥 docker0 连接在一起。
|
||||
### 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。
|
||||
### ipc 名字空間
|
||||
容器中程式交互還是采用了 Linux 常見的程式間交互方法(interprocess communication - IPC), 包括信號量、消息隊列和共享內存等。然而同 VM 不同的是,容器的程式間交互實際上還是 host 上具有相同 pid 名字空間中的程式間交互,因此需要在 IPC 資源申請時加入名字空間訊息,每個 IPC 資源有一個唯一的 32 位 id。
|
||||
|
||||
### mnt 名字空间
|
||||
类似 chroot,将一个进程放到一个特定的目录执行。mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个名字空间中的容器在 /proc/mounts 的信息只包含所在名字空间的 mount point。
|
||||
### mnt 名字空間
|
||||
類似 chroot,將一個程式放到一個特定的目錄執行。mnt 名字空間允許不同名字空間的程式看到的文件結構不同,這樣每個名字空間 中的程式所看到的文件目錄就被隔離開了。同 chroot 不同,每個名字空間中的容器在 /proc/mounts 的訊息只包含所在名字空間的 mount point。
|
||||
|
||||
### uts 名字空间
|
||||
UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。
|
||||
### uts 名字空間
|
||||
UTS("UNIX Time-sharing System") 名字空間允許每個容器擁有獨立的 hostname 和 domain name, 使其在網路上可以被視作一個獨立的節點而非 主機上的一個程式。
|
||||
|
||||
### user 名字空间
|
||||
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。
|
||||
### user 名字空間
|
||||
每個容器可以有不同的使用者和組 id, 也就是說可以在容器內用容器內部的使用者執行程式而非主機上的使用者。
|
||||
|
||||
*注:关于 Linux 上的名字空间,[这篇文章](http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/) 介绍的很好。
|
||||
*註:關於 Linux 上的名字空間,[這篇文章](http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/) 介紹的很好。
|
||||
|
|
|
@ -1,39 +1,39 @@
|
|||
## Docker 网络实现
|
||||
## Docker 網路實做
|
||||
|
||||
Docker 的网络实现其实就是利用了 Linux 上的网络名字空间和虚拟网络设备(特别是 veth pair)。建议先熟悉了解这两部分的基本概念再阅读本章。
|
||||
Docker 的網路實做其實就是利用了 Linux 上的網路名字空間和虛擬網路設備(特別是 veth pair)。建議先熟悉了解這兩部分的基本概念再閱讀本章。
|
||||
|
||||
### 基本原理
|
||||
首先,要实现网络通信,机器需要至少一个网络接口(物理接口或虚拟接口)来收发数据包;此外,如果不同子网之间要进行通信,需要路由机制。
|
||||
首先,要實做網路通信,機器需要至少一個網路接口(物理接口或虛擬接口)來收發數據包;此外,如果不同子網之間要進行通信,需要路由機制。
|
||||
|
||||
Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。
|
||||
Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要快很多。
|
||||
Docker 中的網路接口默認都是虛擬的接口。虛擬接口的優勢之一是轉發效率較高。
|
||||
Linux 透過在內核中進行數據復制來實做虛擬接口之間的數據轉發,發送接口的發送緩存中的數據包被直接復制到接收接口的接收緩存中。對於本地系統和容器內系統看來就像是一個正常的以太網卡,只是它不需要真正同外部網路設備通信,速度要快很多。
|
||||
|
||||
Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 `veth pair`)。
|
||||
Docker 容器網路就利用了這項技術。它在本地主機和容器內分別建立一個虛擬接口,並讓它們彼此連通(這樣的一對接口叫做 `veth pair`)。
|
||||
|
||||
### 创建网络参数
|
||||
Docker 创建一个容器的时候,会执行如下操作:
|
||||
* 创建一对虚拟接口,分别放到本地主机和新容器中;
|
||||
* 本地主机一端桥接到默认的 docker0 或指定网桥上,并具有一个唯一的名字,如 veth65f9;
|
||||
* 容器一端放到新容器中,并修改名字作为 eth0,这个接口只在容器的名字空间可见;
|
||||
* 从网桥可用地址段中获取一个空闲地址分配给容器的 eth0,并配置默认路由到桥接网卡 veth65f9。
|
||||
### 建立網路參數
|
||||
Docker 建立一個容器的時候,會執行以下操作:
|
||||
* 建立一對虛擬接口,分別放到本地主機和新容器中;
|
||||
* 本地主機一端橋接到默認的 docker0 或指定網橋上,並具有一個唯一的名字,如 veth65f9;
|
||||
* 容器一端放到新容器中,並修改名字作為 eth0,這個接口只在容器的名字空間可見;
|
||||
* 從網橋可用地址段中取得一個空閑地址分配給容器的 eth0,並設定默認路由到橋接網卡 veth65f9。
|
||||
|
||||
完成这些之后,容器就可以使用 eth0 虚拟网卡来连接其他容器和其他网络。
|
||||
完成這些之後,容器就可以使用 eth0 虛擬網卡來連接其他容器和其他網路。
|
||||
|
||||
可以在 `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 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。
|
||||
可以在 `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=none` 后,可以自行配置网络,让容器达到跟平常一样具有访问网络的权限。通过这个过程,可以了解 Docker 配置网络的细节。
|
||||
### 網路設定細節
|
||||
使用者使用 `--net=none` 後,可以自行設定網路,讓容器達到跟平常一樣具有訪問網路的權限。透過這個過程,可以了解 Docker 設定網路的細節。
|
||||
|
||||
首先,启动一个 `/bin/bash` 容器,指定 `--net=none` 参数。
|
||||
首先,啟動一個 `/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` 卸载。
|
||||
當容器結束後,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 文件系統
|
||||
Union文件系統([UnionFS](http://en.wikipedia.org/wiki/UnionFS))是一種分層、輕量級並且高效能的文件系統,它支持對文件系統的修改作為一次提交來一層層的疊加,同時可以將不同目錄掛載到同一個虛擬文件系統下(unite several directories into a single virtual filesystem)。
|
||||
|
||||
Union 文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。
|
||||
Union 文件系統是 Docker 鏡像的基礎。鏡像可以透過分層來進行繼承,基於基礎鏡像(沒有父鏡像),可以制作各種具體的應用鏡像。
|
||||
|
||||
另外,不同 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。
|
||||
Docker 目前支持的 Union 文件系統種類包括 AUFS, btrfs, vfs 和 DeviceMapper。
|
||||
|
|
Loading…
Reference in New Issue