mirror of
https://github.com/yeasy/docker_practice.git
synced 2024-12-25 14:38:54 +00:00
Fix issue#20, format following the guidelines
This commit is contained in:
parent
9d26f96ba2
commit
cb903202ba
13
README.md
13
README.md
@ -1,14 +1,14 @@
|
||||
Docker —— 从入门到实践
|
||||
===============
|
||||
|
||||
v0.2.8
|
||||
v0.2.9
|
||||
|
||||
[Docker](docker.com) 是个伟大的项目,它彻底释放了虚拟化的威力,让应用的分发、部署和管理都变得前所未有的高效和轻松!
|
||||
|
||||
本书既适用于具备基础 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协商,将所有内容开源,采用互联网合作的方式进行创作和维护。
|
||||
根据最新 Docker 版本对内容进行了修订和重写,并增加内容;经协商将所有内容开源,采用互联网合作的方式进行维护。
|
||||
|
||||
前六章为基础内容,供用户理解 Docker 的基本概念和操作;7 ~ 9 章介绍一些高级操作;第 10 章给出典型的应用场景和实践案例;11 ~ 13 章介绍关于 Docker 实现的相关技术。
|
||||
|
||||
@ -17,7 +17,7 @@ v0.2.8
|
||||
另外,欢迎加入 DockerPool QQ 群(341410255),分享 Docker 资源,交流 Docker 技术。
|
||||
|
||||
|
||||
本书源码在Github上维护,欢迎参与: [https://github.com/yeasy/docker_practice](https://github.com/yeasy/docker_practice)
|
||||
本书源码在 Github 上维护,欢迎参与: [https://github.com/yeasy/docker_practice](https://github.com/yeasy/docker_practice)。
|
||||
|
||||
感谢所有的 [贡献者](https://github.com/yeasy/docker_practice/graphs/contributors)。
|
||||
|
||||
@ -27,19 +27,20 @@ v0.2.8
|
||||
* 重写安全章节;
|
||||
* 修正底层实现章节的架构、名字空间、控制组、文件系统、容器格式等内容;
|
||||
* 添加对常见仓库和镜像的介绍;
|
||||
* 添加Dockerfile的介绍。
|
||||
* 添加 Dockerfile 的介绍;
|
||||
* 重新校订中英文混排格式。
|
||||
* 0.2: 2014-09-18
|
||||
* 对照官方文档重写介绍、基本概念、安装、镜像、容器、仓库、数据管理、网络等章节;
|
||||
* 添加底层实现章节;
|
||||
* 添加命令查询和资源链接章节;
|
||||
* 其它修正。
|
||||
* 0.1: 2014-09-05
|
||||
* 添加pdf文件内容;
|
||||
* 添加基本内容;
|
||||
* 修正错别字和表达不通顺的地方。
|
||||
|
||||
|
||||
## 参加步骤
|
||||
* 在GitHub上fork到自己的仓库,如docker_user/docker_practice,然后clone到本地,并设置用户信息。
|
||||
* 在 GitHub 上 `fork` 到自己的仓库,如 `docker_user/docker_practice`,然后 `clone` 到本地,并设置用户信息。
|
||||
```
|
||||
$ git clone git@github.com:docker_user/docker_practice.git
|
||||
$ cd docker_practice
|
||||
|
@ -41,7 +41,7 @@
|
||||
* [配置 DNS](advanced_network/dns.md)
|
||||
* [容器访问控制](advanced_network/access_control.md)
|
||||
* [端口映射实现](advanced_network/port_mapping.md)
|
||||
* [配置docker0](advanced_network/docker0.md)
|
||||
* [配置 docker0 网桥](advanced_network/docker0.md)
|
||||
* [自定义网桥](advanced_network/bridge.md)
|
||||
* [工具和示例](advanced_network/example.md)
|
||||
* [编辑网络配置文件](advanced_network/config_file.md)
|
||||
|
@ -9,4 +9,4 @@
|
||||
|
||||
![Docker 网络](../_images/network.png)
|
||||
|
||||
接下来的部分将介绍在一些场景中,docker所有的网络定制配置。linux的原生命令将调整、补充、甚至替换docker默认的网络配置。
|
||||
接下来的部分将介绍在一些场景中,Docker 所有的网络定制配置。以及通过 Linux 命令来调整、补充、甚至替换 Docker 默认的网络配置。
|
||||
|
@ -22,12 +22,12 @@ $sysctl -w net.ipv4.ip_forward=1
|
||||
#### 访问所有端口
|
||||
当启动 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` 选项来访问容器的开放端口。
|
||||
|
||||
例如,在启动Docker服务时,可以同时使用`icc=false --iptables=true`2个参数来关闭允许相互的网络访问,并让Docker可以修改系统中的`iptables`规则。
|
||||
例如,在启动 Docker 服务时,可以同时使用 `icc=false --iptables=true` 参数来关闭允许相互的网络访问,并让 Docker 可以修改系统中的 `iptables` 规则。
|
||||
|
||||
此时,系统中的 `iptables` 规则可能是类似
|
||||
```
|
||||
@ -39,7 +39,7 @@ DROP all -- 0.0.0.0/0 0.0.0.0/0
|
||||
...
|
||||
```
|
||||
|
||||
之后,启动容器(`docker run`)时使用`--link=CONTAINER_NAME:ALIAS`选项。docker会在`iptable`中为2个容器分别添加一条`ACCEPT`规则,允许相互访问开放的端口(取决于dockerfile中的EXPOSE行)。
|
||||
之后,启动容器(`docker run`)时使用 `--link=CONTAINER_NAME:ALIAS` 选项。Docker 会在 `iptable` 中为 两个容器分别添加一条 `ACCEPT` 规则,允许相互访问开放的端口(取决于 Dockerfile 中的 EXPOSE 行)。
|
||||
|
||||
当添加了 `--link=CONTAINER_NAME:ALIAS` 选项后,添加了 `iptables` 规则。
|
||||
```
|
||||
|
@ -31,4 +31,4 @@ $ sudo service docker start
|
||||
启动 Docker 服务。
|
||||
新建一个容器,可以看到它已经桥接到了 `bridge0` 上。
|
||||
|
||||
可以继续用`brctl show`命令查看桥接的信息。另外,在容器中可以使用`ip addr`和`ip route`命令来查看ip地址配置和路由信息。
|
||||
可以继续用 `brctl show` 命令查看桥接的信息。另外,在容器中可以使用 `ip addr` 和 `ip route` 命令来查看 IP 地址配置和路由信息。
|
||||
|
@ -1,5 +1,5 @@
|
||||
## 配置 DNS
|
||||
Docker没有每个容器专门定制镜像,那么怎么自定义配置容器的主机名和dns配置呢?
|
||||
Docker 没有每个容器专门定制镜像,那么怎么自定义配置容器的主机名和 DNS 配置呢?
|
||||
秘诀就是它利用虚拟文件来挂载到来容器的 3 个相关配置文件。
|
||||
|
||||
在容器中使用 mount 命令可以看到挂载信息:
|
||||
@ -22,8 +22,8 @@ tmpfs on /etc/resolv.conf type tmpfs ...
|
||||
选项会在创建容器的时候,添加一个其他容器的主机名到 `/etc/hosts` 文件中,让新容器的进程可以使用主机名 ALIAS 就可以连接它。
|
||||
|
||||
`--dns=IP_ADDRESS`
|
||||
添加dns服务器到容器的`/etc/resolv.conf`中,让容器用这ip地址来解析所有不在`/etc/hosts`中的主机名。
|
||||
添加 DNS 服务器到容器的 `/etc/resolv.conf` 中,让容器用这个服务器来解析所有不在 `/etc/hosts` 中的主机名。
|
||||
|
||||
`--dns-search=DOMAIN`
|
||||
设定容器的搜索域,当设定搜索域为`.example.com`时,在搜索一个名为host的主机时,dns不仅搜索host,还会搜索`host.example.com`。
|
||||
设定容器的搜索域,当设定搜索域为 `.example.com` 时,在搜索一个名为 host 的主机时,DNS 不仅搜索host,还会搜索 `host.example.com`。
|
||||
注意:如果没有上述最后 2 个选项,Docker 会默认用主机上的 `/etc/resolv.conf` 来配置容器。
|
||||
|
@ -1,9 +1,9 @@
|
||||
##配置docker0
|
||||
Docker服务默认会创建一个`docker0`接口,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
|
||||
## 配置 docker0 网桥
|
||||
Docker 服务默认会创建一个 `docker0` 网桥(其上有一个 `docker0` 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。
|
||||
|
||||
Docker默认指定了`docker0`的IP地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了MTU(接口允许接收的最大传输单元),通常是1500bytes,或宿主主机网络路由上支持的默认值,这2个都可以在服务启动的时候进行配置。
|
||||
* --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` 来查看网桥和端口连接信息。
|
||||
@ -13,10 +13,10 @@ 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端口。Docker主机上接口`docker0`的IP作为所有容器的默认网关。
|
||||
每次创建一个新容器的时候,Docker 从可用的地址段中选择一个空闲的 IP 地址分配给容器的 eth0 端口。使用本地主机上 `docker0` 接口的 IP 作为所有容器的默认网关。
|
||||
```
|
||||
$ sudo docker run -i -t --rm base /bin/bash
|
||||
$ ip addr show eth0
|
||||
|
@ -1,9 +1,9 @@
|
||||
## 示例:创建一个点到点连接
|
||||
默认情况下,Docker 会将所有容器连接到由 `docker0` 提供的虚拟子网中。
|
||||
|
||||
用户有时候需要2个容器之间可以直连通信,而不用通过主机网桥进行桥接。
|
||||
用户有时候需要两个容器之间可以直连通信,而不用通过主机网桥进行桥接。
|
||||
|
||||
解决办法很简单:创建一对“peer”接口,分别放到2个容器中,配置成点到点链路类型即可。
|
||||
解决办法很简单:创建一对 `peer` 接口,分别放到两个容器中,配置成点到点链路类型即可。
|
||||
|
||||
首先启动 2 个容器:
|
||||
```
|
||||
@ -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
|
||||
|
||||
|
@ -3,21 +3,21 @@
|
||||
下面是一个跟 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
|
||||
* `-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服务器
|
||||
* --dns-search=DOMAIN... --指定DNS搜索域
|
||||
* `--dns=IP_ADDRESS...` --使用指定的DNS服务器
|
||||
* `--dns-search=DOMAIN...` --指定DNS搜索域
|
||||
|
||||
最后这些选项只有在 `docker run` 执行时使用,因为它是针对容器的特性内容。
|
||||
* -h HOSTNAME or --hostname=HOSTNAME --配置容器主机名
|
||||
* --link=CONTAINER_NAME:ALIAS --添加到另一个容器的连接
|
||||
* --net=bridge|none|container:NAME_or_ID|host --配置容器的桥接模式
|
||||
* -p SPEC or --publish=SPEC --映射容器端口到宿主主机
|
||||
* -P or --publish-all=true|false --映射容器所有端口到宿主主机
|
||||
* `-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` --映射容器所有端口到宿主主机
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
##基本语法
|
||||
docker [OPTIONS] COMMAND [arg...]
|
||||
一般来说,docker命令可以用来管理daemon,或者通过CLI命令管理镜像和容器。可以通过`man docker`来查看这些命令。
|
||||
一般来说,Docker 命令可以用来管理 daemon,或者通过 CLI 命令管理镜像和容器。可以通过 `man docker` 来查看这些命令。
|
||||
|
||||
|
||||
##选项
|
||||
@ -56,7 +56,7 @@
|
||||
|
||||
|
||||
##命令
|
||||
docker的命令可以采用`docker-CMD`或者`docker CMD`的方式执行。两者一致。
|
||||
Docker 的命令可以采用 `docker-CMD` 或者 `docker CMD` 的方式执行。两者一致。
|
||||
|
||||
docker-attach(1)
|
||||
依附到一个正在运行的容器中。
|
||||
@ -149,7 +149,7 @@ docker的命令可以采用`docker-CMD`或者`docker CMD`的方式执行。两
|
||||
终止一个运行中的容器
|
||||
|
||||
docker-tag(1)
|
||||
为一个image打标签
|
||||
为一个镜像打标签
|
||||
|
||||
docker-top(1)
|
||||
查看一个容器中的正在运行的进程信息
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[CentOS](https://en.wikipedia.org/wiki/CentOS) 是流行的 Linux 发行版,其软件包大多跟 RedHat 系列保持一致。
|
||||
该仓库提供了CentOS从5到7各个版本的镜像。
|
||||
该仓库提供了 CentOS 从 5 ~ 7 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
默认会启动一个最小化的 CentOS 环境。
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[MongoDB](https://en.wikipedia.org/wiki/MongoDB) 是开源的 NoSQL 数据库实现。
|
||||
该仓库提供了MongoDB从2.2到2.7各个版本的镜像。
|
||||
该仓库提供了 MongoDB 2.2 ~ 2.7 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
默认会在 `27017` 端口启动数据库。
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[Nginx](https://en.wikipedia.org/wiki/Nginx) 是开源的高效的 Web 服务器实现,支持 HTTP、HTTPS、SMTP、POP3、IMAP 等协议。
|
||||
该仓库提供了Nginx从1.0到1.7各个版本的镜像。
|
||||
该仓库提供了 Nginx 1.0 ~ 1.7 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
下面的命令将作为一个静态页面服务器启动。
|
||||
@ -31,4 +31,4 @@ docker run --name some-nginx -v /some/nginx.conf:/etc/nginx/nginx.conf:ro -d ngi
|
||||
使用配置文件时,为了在容器中正常运行,需要保持 `daemon off;`。
|
||||
|
||||
### Dockerfile
|
||||
* [1到1.7版本](https://github.com/nginxinc/docker-nginx/blob/3713a0157083eb4776e71f5a5aef4b2a5bc03ab1/Dockerfile)
|
||||
* [1 ~ 1.7 版本](https://github.com/nginxinc/docker-nginx/blob/3713a0157083eb4776e71f5a5aef4b2a5bc03ab1/Dockerfile)
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[Node.js](https://en.wikipedia.org/wiki/Node.js)是基于 JavaScript 的可扩展服务端和网络软件开发平台。
|
||||
该仓库提供了Node.js从0.8到0.11各个版本的镜像。
|
||||
该仓库提供了 Node.js 0.8 ~ 0.11 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
在项目中创建一个 Dockerfile。
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[Redis](https://en.wikipedia.org/wiki/Redis) 是开源的内存 Key-Value 数据库实现。
|
||||
该仓库提供了Redis从2.6到2.8.9各个版本的镜像。
|
||||
该仓库提供了 Redis 2.6 ~ 2.8.9 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
默认会在 `6379` 端口启动数据库。
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
### 基本信息
|
||||
[Ubuntu](https://en.wikipedia.org/wiki/Ubuntu) 是流行的 Linux 发行版,其自带软件版本往往较新一些。
|
||||
该仓库提供了Ubuntu从12.04到14.10各个版本的镜像。
|
||||
该仓库提供了 Ubuntu从12.04 ~ 14.10 各个版本的镜像。
|
||||
|
||||
### 使用方法
|
||||
默认会启动一个最小化的 Ubuntu 环境。
|
||||
|
@ -1,7 +1,7 @@
|
||||
## Docker 镜像
|
||||
Docker 镜像就是一个只读的模板。
|
||||
|
||||
例如:一个镜像可以包含一个完整的ubuntu的操作系统环境,里面仅安装了Apache或用户需要的其它应用程序。
|
||||
例如:一个镜像可以包含一个完整的 ubuntu 操作系统环境,里面仅安装了 Apache 或用户需要的其它应用程序。
|
||||
|
||||
镜像可以用来创建 Docker 容器。
|
||||
|
||||
|
@ -11,4 +11,4 @@
|
||||
|
||||
当用户创建了自己的镜像之后就可以使用 `push` 命令将它上传到公有或者私有仓库,这样下次在另外一台机器上使用这个镜像时候,只需要从仓库上 `pull` 下来就可以了。
|
||||
|
||||
*注:Docker仓库的概念跟[Git](http://git-scm.com)的类似,注册服务器可以理解为GitHub这样的托管服务。
|
||||
*注:Docker 仓库的概念跟 [Git](http://git-scm.com) 类似,注册服务器可以理解为 GitHub 这样的托管服务。
|
||||
|
@ -1 +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
|
||||
@ -23,7 +23,8 @@ root@ac6474aeb31d:~# ip a
|
||||
inet6 fe80::487d:68ff:feda:9cf/64 scope link
|
||||
valid_lft forever preferred_lft forever
|
||||
```
|
||||
这样就可以把这个网络看成是一个私有的网络,通过nat 连接外网,如果要让外网连接到容器中,就需要做端口映射,即-p参数(更多原理参见本文第六小节)
|
||||
这样就可以把这个网络看成是一个私有的网络,通过 nat 连接外网,如果要让外网连接到容器中,就需要做端口映射,即 -p 参数。
|
||||
|
||||
如果在企业内部应用,或者做多个物理主机的集群,可能需要将多个物理主机的容器组到一个物理网络中来,那么就需要将这个网桥桥接到我们指定的网卡上。
|
||||
|
||||
### 拓扑图
|
||||
@ -43,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
|
||||
@ -63,7 +64,7 @@ ubuntu修改/etc/default/docker文件 添加最后一行内容
|
||||
DOCKER_OPTS="-b=br0"
|
||||
```
|
||||
|
||||
在启动docker的时候 使用-b参数 将容器绑定到物理网络上。重启docker服务后,再进入容器可以看到它已经绑定到你的物理网络上了。
|
||||
在启动 Docker 的时候 使用 -b 参数 将容器绑定到物理网络上。重启 Docker 服务后,再进入容器可以看到它已经绑定到你的物理网络上了。
|
||||
|
||||
```
|
||||
root@ubuntudocker:~# docker ps
|
||||
@ -74,4 +75,4 @@ bridge name bridge id STP enabled interfaces
|
||||
br0 8000.7e6e617c8d53 no em1
|
||||
vethe6e5
|
||||
```
|
||||
这样就直接把容器暴露到你的物理网络上了,多台物理主机的容器也可以相互联网了。需要注意的是,这样就需要自己来保证容器的网络安全了。
|
||||
这样就直接把容器暴露到物理网络上了,多台物理主机的容器也可以相互联网了。需要注意的是,这样就需要自己来保证容器的网络安全了。
|
||||
|
@ -1,4 +1,4 @@
|
||||
#标准化开发测试和生产环境
|
||||
## 标准化开发测试和生产环境
|
||||
对于大部分企业来说,搭建 PaaS 既没有那个精力,也没那个必要,用 Docker 做个人的 sandbox 用处又小了点。
|
||||
|
||||
可以用 Docker 来标准化开发、测试、生产环境。
|
||||
@ -7,7 +7,7 @@
|
||||
![企业应用结构](../_images/enterprise_usage.png)
|
||||
|
||||
|
||||
Docker占用资源小,在一台E5 128G内存的服务器上部署100个容器都绰绰有余,可以单独抽一个容器或者直接在宿主物理主机上部署samba,利用samba的home分享方案将每个用户的home目录映射到开发中心和测试部门的windows机器上。
|
||||
Docker 占用资源小,在一台 E5 128 G 内存的服务器上部署 100 个容器都绰绰有余,可以单独抽一个容器或者直接在宿主物理主机上部署 samba,利用 samba 的 home 分享方案将每个用户的 home 目录映射到开发中心和测试部门的 Windows 机器上。
|
||||
|
||||
针对某个项目组,由架构师搭建好一个标准的容器环境供项目组和测试部门使用,每个开发工程师可以拥有自己单独的容器,通过 `docker run -v` 将用户的 home 目录映射到容器中。需要提交测试时,只需要将代码移交给测试部门,然后分配一个容器使用 `-v` 加载测试部门的 home 目录启动即可。这样,在公司内部的开发、测试基本就统一了,不会出现开发部门提交的代码,测试部门部署不了的问题。
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
## 使用 Supervisor 来管理进程
|
||||
docker 容器在启动的时候开启单个进程,比如,一个ssh或者apache 的daemon服务。但我们经常需要在一个机器上开启多个服务,这可以有很多方法,最简单的就是把多个启动命令方到一个启动脚本里面,启动的时候直接启动这个脚本,另外就是安装进程管理工具。
|
||||
Docker 容器在启动的时候开启单个进程,比如,一个 ssh 或者 apache 的 daemon 服务。但我们经常需要在一个机器上开启多个服务,这可以有很多方法,最简单的就是把多个启动命令方到一个启动脚本里面,启动的时候直接启动这个脚本,另外就是安装进程管理工具。
|
||||
|
||||
本小节将使用进程管理工具 supervisor 来管理容器中的多个进程。使用 Supervisor 可以更好的控制、管理、重启我们希望运行的进程。在这里我们演示一下如何同时使用 ssh 和 apache 服务。
|
||||
|
||||
### 配置
|
||||
首先创建一个dockerfile,内容和各部分的解释如下。
|
||||
首先创建一个 Dockerfile,内容和各部分的解释如下。
|
||||
```
|
||||
FROM ubuntu:13.04
|
||||
MAINTAINER examples@docker.com
|
||||
@ -25,7 +25,7 @@ RUN mkdir -p /var/log/supervisor
|
||||
```
|
||||
COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf
|
||||
```
|
||||
添加supervisor‘s的配置文件,并复制配置文件到对应目录下面。
|
||||
添加 supervisord 的配置文件,并复制配置文件到对应目录下面。
|
||||
|
||||
```
|
||||
EXPOSE 22 80
|
||||
@ -44,7 +44,7 @@ command=/usr/sbin/sshd -D
|
||||
[program:apache2]
|
||||
command=/bin/bash -c "source /etc/apache2/envvars && exec /usr/sbin/apache2 -DFOREGROUND"
|
||||
```
|
||||
配置文件包含目录和进程,第一段supervsord配置软件本身,使用nodaemon参数来运行。第二段包含要控制的2个服务。每一段包含一个服务的目录和启动这个服务的命令
|
||||
配置文件包含目录和进程,第一段 supervsord 配置软件本身,使用 nodaemon 参数来运行。第二段包含要控制的 2 个服务。每一段包含一个服务的目录和启动这个服务的命令。
|
||||
|
||||
### 使用方法
|
||||
创建镜像。
|
||||
@ -62,4 +62,4 @@ $ sudo docker run -p 22 -p 80 -t -i test/supervisords
|
||||
```
|
||||
使用 `docker run` 来启动我们创建的容器。使用多个 `-p` 来映射多个端口,这样我们就能同时访问 ssh 和 apache 服务了。
|
||||
|
||||
可以使用这个方法创建一个只有ssh服务基础image,之后创建镜像可以以这个镜像为基础来创建
|
||||
可以使用这个方法创建一个只有 ssh 服务的基础镜像,之后创建镜像可以以这个镜像为基础来创建
|
||||
|
@ -1,6 +1,6 @@
|
||||
## 创建 tomcat/weblogic 集群
|
||||
### 安装 tomcat 镜像
|
||||
准备好需要的jdk tomcat等软件放到home目录下面,启动一个虚拟机
|
||||
准备好需要的 jdk、tomcat 等软件放到 home 目录下面,启动一个虚拟机
|
||||
```
|
||||
docker run -t -i -v /home:/opt/data --name mk_tomcat ubuntu /bin/bash
|
||||
```
|
||||
@ -18,13 +18,13 @@ command=/usr/sbin/sshd -D
|
||||
docker commit ac6474aeb31d tomcat
|
||||
```
|
||||
|
||||
新建tomcat文件夹,新建Dockerfile
|
||||
新建 tomcat 文件夹,新建 Dockerfile。
|
||||
```
|
||||
FROM mk_tomcat
|
||||
EXPOSE 22 8080
|
||||
CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
根据dockerfile 创建image
|
||||
根据 Dockerfile 创建镜像。
|
||||
```
|
||||
docker build tomcat tomcat
|
||||
```
|
||||
@ -49,13 +49,14 @@ CMD ["/usr/bin/supervisord"]
|
||||
```
|
||||
|
||||
### tomcat/weblogic 镜像的使用
|
||||
1)存储的使用
|
||||
在启用docker run 的时候,使用 -v参数
|
||||
#### 存储的使用
|
||||
在启动的时候,使用 `-v` 参数
|
||||
|
||||
-v, --volume=[] Bind mount a volume (e.g. from the host: -v /host:/container, from docker: -v /container)
|
||||
|
||||
将本地磁盘映射到虚拟机内部,它在主机和虚拟机容器之间是实时变化的,所以我们更新程序、上传代码只需要更新物理主机的目录就可以了,数据存储的详细介绍请参见本文第七小节
|
||||
2)tomcat和weblogic集群的实现
|
||||
将本地磁盘映射到虚拟机内部,它在主机和虚拟机容器之间是实时变化的,所以我们更新程序、上传代码只需要更新物理主机的目录就可以了
|
||||
|
||||
#### tomcat 和 weblogic 集群的实现
|
||||
tomcat 只要开启多个容器即可
|
||||
```
|
||||
docker run -d -v -p 204:22 -p 7003:8080 -v /home/data:/opt/data --name tm1 tomcat /usr/bin/supervisord
|
||||
@ -66,10 +67,11 @@ docker run -d -v -p 206:22 -p 7005:8080 -v /home/data:/opt/data --name tm3 tomca
|
||||
这里说一下 weblogic 的配置,大家知道 weblogic 有一个域的概念。如果要使用常规的 administrator +node 的方式部署,就需要在 supervisord 中分别写出 administartor server 和 node server 的启动脚本,这样做的优点是:
|
||||
* 可以使用 weblogic 的集群,同步等概念
|
||||
* 部署一个集群应用程序,只需要安装一次应用到集群上即可
|
||||
|
||||
缺点是:
|
||||
* docker配置复杂了
|
||||
* Docker 配置复杂了
|
||||
* 没办法自动扩展集群的计算容量,如需添加节点,需要在 administrator 上先创建节点,然后再配置新的容器 supervisor 启动脚本,然后再启动容器
|
||||
另外种方法是将所有的程序都安装在adminiserver上面,需要扩展的时候,启动多个节点即可,它的优点和缺点和上一种方法恰恰相反。(目前我使用这种方式来部署开发和测试环境)
|
||||
另外种方法是将所有的程序都安装在 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
|
||||
|
@ -26,7 +26,7 @@ $ make nsenter && sudo cp nsenter /usr/local/bin
|
||||
|
||||
#### 使用
|
||||
`nsenter` 可以访问另一个进程的名字空间。nsenter 要正常工作需要有 root 权限。
|
||||
很不幸,Ubuntu 14.4仍然使用的是util-linux版本2.20。安装最新版本的util-linux(2.24)版,请按照以下步骤:
|
||||
很不幸,Ubuntu 14.4 仍然使用的是 util-linux 2.20。安装最新版本的 util-linux(2.24)版,请按照以下步骤:
|
||||
```
|
||||
$ wget https://www.kernel.org/pub/linux/utils/util-linux/v2.24/util-linux-2.24.tar.gz; tar xzvf util-linux-2.24.tar.gz
|
||||
$ cd util-linux-2.24
|
||||
|
@ -5,5 +5,5 @@
|
||||
$sudo docker rm trusting_newton
|
||||
trusting_newton
|
||||
```
|
||||
如果要删除一个运行中的容器,可以添加`-f`参数。Docker会发送SIGKILL信号给容器。
|
||||
如果要删除一个运行中的容器,可以添加 `-f` 参数。Docker 会发送 `SIGKILL` 信号给容器。
|
||||
|
||||
|
@ -6,14 +6,14 @@
|
||||
###新建并启动
|
||||
所需要的命令主要为 `docker run`。
|
||||
|
||||
例如,下面的命令输出一个"Hello World",之后终止容器。
|
||||
例如,下面的命令输出一个 “Hello World”,之后终止容器。
|
||||
```
|
||||
$ sudo docker run ubuntu:14.04 /bin/echo 'Hello world'
|
||||
Hello world
|
||||
```
|
||||
这跟在本地直接执行 `/bin/echo 'hello world'` 几乎感觉不出任何区别。
|
||||
|
||||
下面的命令则启动一个bash终端,可以让用户进行交互。
|
||||
下面的命令则启动一个 bash 终端,允许用户进行交互。
|
||||
```
|
||||
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
|
||||
root@af8bae53bdd3:/#
|
||||
|
@ -15,7 +15,7 @@
|
||||
```
|
||||
$ sudo docker run -d -P --name web -v /webapp training/webapp python app.py
|
||||
```
|
||||
*注意:也可以在dockerfile中使用volume来添加一个或者多个新的卷到由该镜像创建的任意容器。
|
||||
*注意:也可以在 Dockerfile 中使用 `VOLUME` 来添加一个或者多个新的卷到由该镜像创建的任意容器。
|
||||
|
||||
### 挂载一个主机目录作为数据卷
|
||||
使用 `-v` 标记也可以指定挂载一个本地主机的目录到容器中去。
|
||||
@ -23,9 +23,9 @@ $ sudo docker run -d -P --name web -v /webapp training/webapp python app.py
|
||||
$ sudo docker run -d -P --name web -v /src/webapp:/opt/webapp training/webapp python app.py
|
||||
```
|
||||
上面的命令加载主机的 `/src/webapp` 目录到容器的 `/opt/webapp`
|
||||
目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在docker会自动为你创建它。
|
||||
目录。这个功能在进行测试的时候十分方便,比如用户可以放置一些程序到本地目录中,来查看容器是否正常工作。本地目录的路径必须是绝对路径,如果目录不存在 Docker 会自动为你创建它。
|
||||
|
||||
*注意:dockerfile中不支持这种用法,这是因为dockerfile是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。
|
||||
*注意:Dockerfile 中不支持这种用法,这是因为 Dockerfile 是为了移植和分享用的。然而,不同操作系统的路径格式不一样,所以目前还不能支持。
|
||||
|
||||
Docker 挂载数据卷的默认权限是读写,用户也可以通过 `:ro` 指定为只读。
|
||||
```
|
||||
@ -41,5 +41,5 @@ $ sudo docker run --rm -it -v ~/.bash_history:/.bash_history ubuntu /bin/bash
|
||||
```
|
||||
这样就可以记录在容器输入过的命令了。
|
||||
|
||||
*注意:如果直接挂载一个文件,很多文件编辑工具,包括`vi`或者`sed --in-place`,可能会造成文件inode的改变,从docker 1.1
|
||||
*注意:如果直接挂载一个文件,很多文件编辑工具,包括 `vi` 或者 `sed --in-place`,可能会造成文件 inode 的改变,从 Docker 1.1
|
||||
.0起,这会导致报错误信息。所以最简单的办法就直接挂载文件的父目录。
|
||||
|
@ -7,5 +7,3 @@
|
||||
```
|
||||
$ sudo docker build -t myrepo/myapp /tmp/test1/
|
||||
```
|
||||
|
||||
|
||||
|
@ -30,7 +30,7 @@
|
||||
### EXPOSE
|
||||
格式为 `EXPOSE <port> [<port>...]`。
|
||||
|
||||
告诉Docker服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过-P,docker主机会自动分配一个端口转发到指定的端口。
|
||||
告诉 Docker 服务端容器暴露的端口号,供互联系统使用。在启动容器时需要通过 -P,Docker 主机会自动分配一个端口转发到指定的端口。
|
||||
|
||||
### ENV
|
||||
格式为 `ENV <key> <value>`。
|
||||
@ -105,7 +105,7 @@ ONBUILD RUN /usr/local/bin/python-build --dir /app/src
|
||||
[...]
|
||||
```
|
||||
|
||||
如果基于A创建新的镜像时,新的Dockerfile中使用`FROM image-A`指定基础镜像时,会自动执行`ONBUILD`指令内容,等价于在后面添加了两条指令。
|
||||
如果基于 image-A 创建新的镜像时,新的Dockerfile中使用 `FROM image-A`指定基础镜像时,会自动执行 `ONBUILD` 指令内容,等价于在后面添加了两条指令。
|
||||
```
|
||||
FROM image-A
|
||||
|
||||
|
@ -14,15 +14,15 @@ root@0b2616b0e5a8:/#
|
||||
```
|
||||
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
|
||||
@ -36,10 +36,10 @@ $ 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
|
||||
@ -55,12 +55,12 @@ RUN apt-get -qqy install ruby ruby-dev
|
||||
RUN gem install sinatra
|
||||
```
|
||||
Dockerfile 基本的语法是
|
||||
* 使用#来注释
|
||||
* FROM指令告诉docker 使用哪个镜像作为基础
|
||||
* 使用`#`来注释
|
||||
* `FROM` 指令告诉 Docker 使用哪个镜像作为基础
|
||||
* 接着是维护者的信息
|
||||
* RUN开头的指令会在创建中运行,比如安装一个软件包,在这里使用apt 来安装了一些软件
|
||||
* `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,指定新的镜像的用户信息。
|
||||
其中 `-t` 标记来添加 tag,指定新的镜像的用户信息。
|
||||
“.” 是 Dockerfile 所在的路径(当前目录),也可以替换为一个具体的 Dockerfile 的路径。
|
||||
|
||||
我们可以看到build进程在执行操作。它要做的第一件事情就是上传这个Dockerfile内容,因为所有的操作都要依据Dockerfile来进行。
|
||||
然后,dockfile中的指令被一条一条的执行。每一步都创建了一个新的容器,在容器中执行指令并提交修改(就跟之前介绍过的`docker commit`一样)。当所有的指令都执行完毕之后,返回了最终的镜像 id。所有的中间步骤所产生的容器都被删除和清理了。
|
||||
可以看到 build 进程在执行操作。它要做的第一件事情就是上传这个 Dockerfile 内容,因为所有的操作都要依据 Dockerfile 来进行。
|
||||
然后,Dockfile 中的指令被一条一条的执行。每一步都创建了一个新的容器,在容器中执行指令并提交修改(就跟之前介绍过的 `docker commit` 一样)。当所有的指令都执行完毕之后,返回了最终的镜像 id。所有的中间步骤所产生的容器都被删除和清理了。
|
||||
|
||||
*注意一个镜像不能超过 127 层
|
||||
|
||||
此外,还可以利用ADD命令复制本地文件到镜像;用EXPOSE命令来向外部开放端口;用CMD命令来描述容器启动后运行的程序等。例如
|
||||
此外,还可以利用 `ADD` 命令复制本地文件到镜像;用 `EXPOSE` 命令来向外部开放端口;用 `CMD` 命令来描述容器启动后运行的程序等。例如
|
||||
```
|
||||
# put my local web site in myApp folder to /var/www
|
||||
ADD myApp /var/www
|
||||
@ -129,13 +129,13 @@ ouruser/sinatra devel 5db5f8471261 11 hours ago 446.7 MB
|
||||
ouruser/sinatra v2 5db5f8471261 11 hours ago 446.7 MB
|
||||
```
|
||||
|
||||
*注:更多用法,请参考dockerfile章节。
|
||||
*注:更多用法,请参考 [Dockerfile](../dockerfile/README.md) 章节。
|
||||
|
||||
### 从本地文件系统导入
|
||||
要从本地文件系统导入一个镜像,可以使用 openvz(容器虚拟化的先锋技术)的模板来创建:
|
||||
openvz 的模板下载地址为 http://openvz.org/Download/templates/precreated。
|
||||
|
||||
比如:先下载了一个ubuntu14.04的镜像,之后使用以下命令导入:
|
||||
比如,先下载了一个 ubuntu-14.04 的镜像,之后使用以下命令导入:
|
||||
```
|
||||
sudo cat ubuntu-14.04-x86_64-minimal.tar.gz |docker import - ubuntu:14.04
|
||||
```
|
||||
|
@ -21,7 +21,7 @@ ubuntu trusty 99ec81b80c55 4 weeks ago 266 MB
|
||||
|
||||
其中镜像的 `ID` 唯一标识了镜像,注意到 `ubuntu:14.04` 和 `ubuntu:trusty` 具有相同的镜像 `ID`,说明它们实际上是同一镜像。
|
||||
|
||||
`TAG`信息用来标记来自同一个仓库的不同镜像。例如`ubuntu`仓库中有多个镜像,通过`TAG`信息来区分发行版本,例如10.04、12.04、12.10、13.04、14.04等。例如下面的命令指定使用镜像`ubuntu:14.04`来启动一个容器。
|
||||
`TAG` 信息用来标记来自同一个仓库的不同镜像。例如 `ubuntu` 仓库中有多个镜像,通过 `TAG` 信息来区分发行版本,例如 `10.04`、`12.04`、`12.10`、`13.04`、`14.04` 等。例如下面的命令指定使用镜像 `ubuntu:14.04` 来启动一个容器。
|
||||
```
|
||||
$ sudo docker run -t -i ubuntu:14.04 /bin/bash
|
||||
```
|
||||
|
@ -15,6 +15,7 @@ ffdaafd1ca50: Download complete
|
||||
d047ae21eeaf: Download complete
|
||||
```
|
||||
下载过程中,会输出获取镜像的每一层信息。
|
||||
|
||||
该命令实际上相当于 `$ sudo docker pull registry.hub.docker.com/ubuntu:12.04` 命令,即从注册服务器 `registry.hub.docker.com` 中的 `ubuntu` 仓库来下载标记为 `12.04` 的镜像。
|
||||
|
||||
有时候官方仓库注册服务器下载较慢,可以从其他仓库下载。
|
||||
|
@ -1,4 +1,4 @@
|
||||
## CentOS系列安装docker
|
||||
## CentOS 系列安装 Docker
|
||||
|
||||
Docker 支持 CentOS6 及以后的版本。
|
||||
|
||||
@ -10,7 +10,7 @@ $ sudo yum install docker-io
|
||||
```
|
||||
|
||||
### CentOS7
|
||||
CentOS7系统CentOS-Extras库中已带Docker,可以直接安装:
|
||||
CentOS7 系统 `CentOS-Extras` 库中已带 Docker,可以直接安装:
|
||||
```
|
||||
$ sudo yum install docker
|
||||
```
|
||||
|
@ -12,7 +12,7 @@ $ sudo sed -i '$acomplete -F _docker docker' /etc/bash_completion.d/docker.io
|
||||
如果使用操作系统自带包安装 Docker,目前安装的版本是比较旧的 0.9.1。 要安装更新的版本,可以通过使用 Docker 源的方式。
|
||||
|
||||
### 通过Docker源安装最新版本
|
||||
要安装最新的Docker版本,首先需要安装apt-get的https支持,之后通过添加源来安装。
|
||||
要安装最新的 Docker 版本,首先需要安装 apt-transport-https 支持,之后通过添加源来安装。
|
||||
```
|
||||
$ sudo apt-get install apt-transport-https
|
||||
$ sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 36A1D7869245C8950F966E92D8576A8BA88D21E9
|
||||
@ -21,8 +21,8 @@ $ sudo apt-get update
|
||||
$ sudo apt-get install lxc-docker
|
||||
```
|
||||
|
||||
### 低版本
|
||||
如果是低版本的Ubuntu系统,需要先更新内核。
|
||||
### 14.04 之前版本
|
||||
如果是较低版本的 Ubuntu 系统,需要先更新内核。
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install linux-image-generic-lts-raring linux-headers-generic-lts-raring
|
||||
|
@ -1 +1,2 @@
|
||||
# Docker 中的网络功能介绍
|
||||
Docker 允许通过外部访问容器或容器互联的方式来提供网络服务。
|
||||
|
@ -10,7 +10,6 @@
|
||||
* 自定义的命名,比较好记,比如一个web应用容器我们可以给它起名叫web
|
||||
* 当要连接其他容器时候,可以作为一个有用的参考点,比如连接web容器到db容器
|
||||
|
||||
|
||||
使用 `--name` 标记可以为容器自定义命名。
|
||||
```
|
||||
$ sudo docker run -d -P --name web training/webapp python app.py
|
||||
@ -59,7 +58,7 @@ aed84ee21bde training/webapp:latest python app.py 16 hours ago
|
||||
```
|
||||
可以看到自定义命名的容器,db 和 web,db 容器的 names 列有 db 也有 web/db。这表示 web 容器链接到 db 容器,web 容器将被允许访问 db 容器的信息。
|
||||
|
||||
Docker在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动db容器的时候并没有使用-p和-P标记,从而避免了暴露数据库端口到外部网络上。
|
||||
Docker 在两个互联的容器之间创建了一个安全隧道,而且不用映射它们的端口到宿主主机上。在启动 db 容器的时候并没有使用 `-p` 和 `-P` 标记,从而避免了暴露数据库端口到外部网络上。
|
||||
|
||||
Docker 通过 2 种方式为容器公开连接信息:
|
||||
* 环境变量
|
||||
@ -79,7 +78,7 @@ DB_PORT_5000_TCP_ADDR=172.17.0.5
|
||||
```
|
||||
其中 DB_ 开头的环境变量是供 web 容器连接 db 容器使用,前缀采用大写的连接别名。
|
||||
|
||||
除了环境变量,docker还添加host信息到父容器的`/etc/hosts`的文件。下面是父容器web的hosts文件
|
||||
除了环境变量,Docker 还添加 host 信息到父容器的 `/etc/hosts` 的文件。下面是父容器 web 的 hosts 文件
|
||||
```
|
||||
$ sudo docker run -t -i --rm --link db:db training/webapp /bin/bash
|
||||
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
|
||||
@ -97,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来ping db容器,它会解析成172.17.0.5。
|
||||
用 ping 来测试db容器,它会解析成 `172.17.0.5`。
|
||||
*注意:官方的 ubuntu 镜像默认没有安装 ping,需要自行安装。
|
||||
|
||||
注意:官方的ubuntu镜像默认没有安装ping
|
||||
注意:用户可以链接多个子容器到父容器,比如可以链接多个web到db容器上。
|
||||
用户可以链接多个子容器到父容器,比如可以链接多个 web 到 db 容器上。
|
||||
|
@ -18,7 +18,7 @@ $ sudo docker logs -f nostalgic_morse
|
||||
10.0.2.2 - - [23/May/2014 20:16:31] "GET /favicon.ico HTTP/1.1" 404 -
|
||||
```
|
||||
|
||||
-p(小写的P)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有`ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。
|
||||
-p(小写的)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有 `ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。
|
||||
|
||||
### 映射所有接口地址
|
||||
使用 `hostPort:containerPort` 格式本地的 5000 端口映射到容器的 5000 端口,可以执行
|
||||
@ -48,7 +48,7 @@ $ docker port nostalgic_morse 5000
|
||||
127.0.0.1:49155.
|
||||
```
|
||||
注意:
|
||||
* 容器有自己的内部网络和ip地址(使用 docker inspect 可以获取所有的变量,docker还可以有一个可变的网络配置。)
|
||||
* 容器有自己的内部网络和 ip 地址(使用 `docker inspect` 可以获取所有的变量,Docker 还可以有一个可变的网络配置。)
|
||||
* -p 标记可以多次使用来绑定多个端口
|
||||
|
||||
例如
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
一个容易混淆的概念是注册服务器(Registry)。实际上注册服务器是管理仓库的具体服务器,每个服务器上可以有多个仓库,而每个仓库下面有多个镜像。从这方面来说,仓库可以被认为是一个具体的项目或目录。例如对于仓库地址 `dl.dockerpool.com/ubuntu` 来说,`dl.dockerpool.com` 是注册服务器地址,`ubuntu` 是仓库名。
|
||||
|
||||
大部分时候,并不严格区分这两者的概念。
|
||||
大部分时候,并不需要严格区分这两者的概念。
|
||||
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
## 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` 命令来输入用户名、密码和邮箱来完成注册和登录。
|
||||
@ -26,7 +26,7 @@ tutum/centos-6.4 DEPRECATED. Use tutum/centos:6.4
|
||||
一种是类似 centos 这样的基础镜像,被称为基础或根镜像。这些基础镜像是由 Docker 公司创建、验证、支持、提供。这样的镜像往往使用单个单词作为名字。
|
||||
还有一种类型,比如 `tianon/centos` 镜像,它是由 Docker 的用户创建并维护的,往往带有用户名称前缀。可以通过前缀 `user_name/` 来指定使用某个用户提供的镜像,比如 tianon 用户。
|
||||
|
||||
另外,在查找的时候通过`-s n`参数可以指定仅显示评价为`n`星以上的镜像。
|
||||
另外,在查找的时候通过 `-s N` 参数可以指定仅显示评价为 `N` 星以上的镜像。
|
||||
|
||||
下载官方 centos 镜像到本地。
|
||||
```
|
||||
@ -37,7 +37,7 @@ Pulling repository centos
|
||||
511136ea3c5a: Download complete
|
||||
7064731afe90: Download complete
|
||||
```
|
||||
用户也可以在登录后通过`docker push`命令来将镜像推送到Docker Hub中。
|
||||
用户也可以在登录后通过 `docker push` 命令来将镜像推送到 Docker Hub。
|
||||
|
||||
### 自动创建
|
||||
自动创建(Automated Builds)功能对于需要经常升级镜像内程序来说,十分方便。
|
||||
|
@ -12,7 +12,7 @@
|
||||
$ sudo docker run -d -p 5000:5000 registry
|
||||
```
|
||||
这将使用官方的 registry 镜像来启动本地的私有仓库。
|
||||
用户可以通过指定参数来配置私有仓库位置,例如配置镜像存储到Amazon的S3服务
|
||||
用户可以通过指定参数来配置私有仓库位置,例如配置镜像存储到 Amazon S3 服务。
|
||||
```
|
||||
$ sudo docker run \
|
||||
-e SETTINGS_FLAVOR=s3 \
|
||||
@ -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
|
||||
@ -156,4 +156,3 @@ Pushing tag for rev [70214e5d0a90] on {http://127.0.0.1:5000/v1/repositories/cen
|
||||
Untagged: 127.0.0.1:5000/centos:centos7
|
||||
Done
|
||||
```
|
||||
|
||||
|
@ -14,7 +14,7 @@ Linux内核自2.1版本起就支持能力机制,它将权限划分为更加细
|
||||
* 硬件管理无关紧要,容器中也就无需执行 udevd 以及类似服务;
|
||||
* 网络管理也都在主机上设置,除非特殊需求,容器不需要对网络进行配置。
|
||||
|
||||
从上面的例子可以看出,大部分情况下,容器并不需要“真正的”root权,容器只需要少数的能力即可。为了加强安全,容器可以禁用一些没必要的权限。
|
||||
从上面的例子可以看出,大部分情况下,容器并不需要“真正的” root 权限,容器只需要少数的能力即可。为了加强安全,容器可以禁用一些没必要的权限。
|
||||
* 完全禁止任何 mount 操作;
|
||||
* 禁止直接访问本地主机的套接字;
|
||||
* 禁止访问一些文件系统的操作,比如创建新的设备、修改文件属性等;
|
||||
|
@ -9,7 +9,7 @@ Docker容器和LXC容器很相似,所提供的安全特性也差不多。当
|
||||
|
||||
那么,内核中实现名字空间和私有网络的代码是否足够成熟?
|
||||
|
||||
内核名字空间从2.6.15版本(2008年七月发布)之后被引入,数年间,这些机制的可靠性在诸多大型生产系统中被实践验证。
|
||||
内核名字空间从 2.6.15 版本(2008 年 7 月发布)之后被引入,数年间,这些机制的可靠性在诸多大型生产系统中被实践验证。
|
||||
|
||||
实际上,名字空间的想法和设计提出的时间要更早,最初是为了在内核中引入一种机制来实现 [OpenVZ](http://en.wikipedia.org/wiki/OpenVZ) 的特性。
|
||||
而 OpenVZ 项目早在 2005 年就发布了,其设计和实现都已经十分成熟。
|
||||
|
@ -1,10 +1,10 @@
|
||||
## 基本架构
|
||||
Docker 采用了 C/S架构,包括客户端和服务端。
|
||||
docker daemon作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。
|
||||
Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。
|
||||
客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。
|
||||
|
||||
![Docker 基本架构](../_images/docker_arch.png)
|
||||
|
||||
|
||||
Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。
|
||||
Docker客户端则为用户提供一系列可执行命令,用户用这些命令实现跟docker daemon交互。
|
||||
Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。
|
||||
|
@ -14,9 +14,9 @@
|
||||
类似 chroot,将一个进程放到一个特定的目录执行。mnt 名字空间允许不同名字空间的进程看到的文件结构不同,这样每个名字空间 中的进程所看到的文件目录就被隔离开了。同 chroot 不同,每个名字空间中的容器在 /proc/mounts 的信息只包含所在名字空间的 mount point。
|
||||
|
||||
### uts 名字空间
|
||||
UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的hostname和domain name, 使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
|
||||
UTS("UNIX Time-sharing System") 名字空间允许每个容器拥有独立的 hostname 和 domain name, 使其在网络上可以被视作一个独立的节点而非 主机上的一个进程。
|
||||
|
||||
### user 名字空间
|
||||
每个容器可以有不同的用户和组id, 也就是说可以在容器内用容器内部的用户执行程序而非Host上的用户。
|
||||
每个容器可以有不同的用户和组 id, 也就是说可以在容器内用容器内部的用户执行程序而非主机上的用户。
|
||||
|
||||
*注:关于 Linux 上的名字空间,[这篇文章](http://blog.scottlowe.org/2013/09/04/introducing-linux-network-namespaces/) 介绍的很好。
|
||||
|
@ -8,7 +8,7 @@ Docker的网络实现其实就是利用了Linux上的网络名字空间和虚拟
|
||||
Docker 中的网络接口默认都是虚拟的接口。虚拟接口的优势之一是转发效率较高。
|
||||
Linux 通过在内核中进行数据复制来实现虚拟接口之间的数据转发,发送接口的发送缓存中的数据包被直接复制到接收接口的接收缓存中。对于本地系统和容器内系统看来就像是一个正常的以太网卡,只是它不需要真正同外部网络设备通信,速度要很快。
|
||||
|
||||
Docker容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做“veth pair”)。
|
||||
Docker 容器网络就利用了这项技术。它在本地主机和容器内分别创建一个虚拟接口,并让它们彼此连通(这样的一对接口叫做 `veth pair`)。
|
||||
|
||||
### 创建网络参数
|
||||
Docker 创建一个容器的时候,会执行如下操作:
|
||||
@ -17,12 +17,12 @@ Docker创建一个容器的时候,会执行如下操作:
|
||||
* 容器一端放到新容器中,并修改名字作为 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=container:NAME_or_ID` 让 Docker 将新建容器的进程放到一个已存在容器的网络栈中,新容器进程有自己的文件系统、进程列表和资源限制,但会和已存在的容器共享 IP 地址和端口等网络资源,两者进程可以直接通过 `lo` 环回接口通信。
|
||||
* `--net=none` 让 Docker 将新容器放到隔离的网络栈中,但是不进行网络配置。之后,用户可以自己进行配置。
|
||||
|
||||
### 网络配置细节
|
||||
|
@ -7,4 +7,4 @@ Union文件系统是Docker镜像的基础。镜像可以通过分层来进行继
|
||||
|
||||
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
Block a user