Restruct and start rewring.
parent
f14fddbba8
commit
80eda65481
|
@ -7,9 +7,7 @@ v0.1.4
|
||||||
|
|
||||||
本书最初源于[WaitFish](mailto:dwj_wz@163.com)
|
本书最初源于[WaitFish](mailto:dwj_wz@163.com)
|
||||||
的<Docker学习手册v1.0> pdf内容,后来,[yeasy](github.com/yeasy)
|
的<Docker学习手册v1.0> pdf内容,后来,[yeasy](github.com/yeasy)
|
||||||
根据最新的官方文档对内容进行了修订,并与作者[WaitFish]
|
根据最新的官方文档对内容进行了修订,重写和增加了部分内容,并与作者[WaitFish](mailto:dwj_wz@163.com)协商,将内容开源,采用互联网合作的方式进行创作和维护。
|
||||||
(mailto:dwj_wz@163
|
|
||||||
.com)协商,将内容开源,采用互联网合作的方式进行创作和维护。
|
|
||||||
|
|
||||||
在线阅读:[https://www.gitbook.io/book/yeasy/docker_practice](https://www.gitbook.io/book/yeasy/docker_practice)
|
在线阅读:[https://www.gitbook.io/book/yeasy/docker_practice](https://www.gitbook.io/book/yeasy/docker_practice)
|
||||||
|
|
||||||
|
|
28
SUMMARY.md
28
SUMMARY.md
|
@ -6,22 +6,23 @@
|
||||||
* [更容易部署和扩展](introduction/easy_deployment.md)
|
* [更容易部署和扩展](introduction/easy_deployment.md)
|
||||||
* [效率更高](introduction/high_efficiency.md)
|
* [效率更高](introduction/high_efficiency.md)
|
||||||
* [快速部署也意味着更简单的管理](introduction/easy_management.md)
|
* [快速部署也意味着更简单的管理](introduction/easy_management.md)
|
||||||
* [Docker的体系结构](arch/README.md)
|
* [基本概念](basic_concept/README.md)
|
||||||
* [内部组件](arch/internal.md)
|
* [镜像](basic_concept/internal.md)
|
||||||
* [image的工作原理](arch/image.md)
|
* [容器](basic_concept/container.md)
|
||||||
* [仓库](arch/repo.md)
|
* [仓库](basic_concept/repository.md)
|
||||||
* [容器](arch/container.md)
|
|
||||||
* [底层技术](arch/underly.md)
|
|
||||||
* [安装](install/README.md)
|
* [安装](install/README.md)
|
||||||
* [Ubuntu](install/ubuntu144.md)
|
* [Ubuntu](install/ubuntu144.md)
|
||||||
* [CentOS](install/centos.md)
|
* [CentOS](install/centos.md)
|
||||||
* [image介绍](image/README.md)
|
* [镜像](image/README.md)
|
||||||
* [获取mage](image/get.md)
|
* [获取镜像](image/get.md)
|
||||||
* [查找image](image/search.md)
|
* [查找镜像](image/search.md)
|
||||||
* [下载image](image/download.md)
|
* [下载镜像](image/download.md)
|
||||||
* [创建自己的image](image/create.md)
|
* [创建镜像](image/create.md)
|
||||||
* [上传image](image/push.md)
|
* [上传镜像](image/push.md)
|
||||||
* [移除本地image](image/rmi.md)
|
* [移除镜像](image/rmi.md)
|
||||||
|
* [底层原理](image/internal.md)
|
||||||
|
* [容器](container/README.md)
|
||||||
|
* [仓库](repository/README.md)
|
||||||
* [网络介绍](network/README.md)
|
* [网络介绍](network/README.md)
|
||||||
* [端口映射](network/port_mapping.md)
|
* [端口映射](network/port_mapping.md)
|
||||||
* [docker中的容器互联-linking系统](network/linking.md)
|
* [docker中的容器互联-linking系统](network/linking.md)
|
||||||
|
@ -46,6 +47,7 @@
|
||||||
* [内核权限](container_security/kernel_capability.md)
|
* [内核权限](container_security/kernel_capability.md)
|
||||||
* [其他内核安全特性](container_security/other_feature.md)
|
* [其他内核安全特性](container_security/other_feature.md)
|
||||||
* [结论](container_security/summary.md)
|
* [结论](container_security/summary.md)
|
||||||
|
* [底层实现](arch/README.md)
|
||||||
* [实战案例](practice/README.md)
|
* [实战案例](practice/README.md)
|
||||||
* [部署本地仓库](practice/local_repo.md)
|
* [部署本地仓库](practice/local_repo.md)
|
||||||
* [使用 Supervisor来管理进程](practice/supervisor.md)
|
* [使用 Supervisor来管理进程](practice/supervisor.md)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
#架构
|
##基本架构
|
||||||
docker采用了C/S架构,包括client端和daemon端。
|
docker采用了C/S架构,包括client端和daemon端。
|
||||||
docker daemon作为server端接受来自client的请求,并处理这些请求(创建、运行、分发容器)。
|
docker daemon作为server端接受来自client的请求,并处理这些请求(创建、运行、分发容器)。
|
||||||
client端和server端既可以运行在一个机器上,也可通过socket或者RESTful API来进行通信。
|
client端和server端既可以运行在一个机器上,也可通过socket或者RESTful API来进行通信。
|
||||||
|
@ -8,3 +8,28 @@ client端和server端既可以运行在一个机器上,也可通过socket或
|
||||||
|
|
||||||
Docker daemon一般在宿主主机后台运行,等待接收来自client端的消息。
|
Docker daemon一般在宿主主机后台运行,等待接收来自client端的消息。
|
||||||
Docker client 则为用户提供一系列可执行命令,用户用这些docker命令实现跟docker daemon交互。
|
Docker client 则为用户提供一系列可执行命令,用户用这些docker命令实现跟docker daemon交互。
|
||||||
|
|
||||||
|
##核心技术
|
||||||
|
docker底层的2个核心技术分别是Namespaces和Control groups。
|
||||||
|
|
||||||
|
以下内容摘自InfoQ Docker,自1.20版本开始docker已经抛开lxc,不过下面的内容对于理解docker还是有很大帮助。
|
||||||
|
|
||||||
|
###pid namespace
|
||||||
|
不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。同时由于允许嵌套,因此可以很方便的实现 Docker in Docker。
|
||||||
|
|
||||||
|
###net namespace
|
||||||
|
有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过net namespace实现的, 每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来。docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge: docker0连接在一起。
|
||||||
|
|
||||||
|
###ipc namespace
|
||||||
|
container中进程交互还是采用linux常见的进程间交互方法(interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同 VM 不同的是,container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息 - 每个IPC资源有一个唯一的 32 位 ID。
|
||||||
|
|
||||||
|
###mnt namespace
|
||||||
|
类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace的mount point。
|
||||||
|
|
||||||
|
###uts namespace
|
||||||
|
UTS("UNIX Time-sharing System") namespace允许每个container拥有独立的hostname和domain name, 使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
|
||||||
|
|
||||||
|
###user namespace
|
||||||
|
每个container可以有不同的 user 和 group id, 也就是说可以在container内部用container内部的用户执行程序而非Host上的用户。
|
||||||
|
|
||||||
|
Control groups主要用来隔离各个容器和宿主主机的资源利用。
|
||||||
|
|
|
@ -1,18 +0,0 @@
|
||||||
##内部组件
|
|
||||||
docker有三个内部组件
|
|
||||||
* images(镜像
|
|
||||||
* registries(仓库)
|
|
||||||
* containers(容器)
|
|
||||||
|
|
||||||
### Images
|
|
||||||
docker images 就是一个只读的模板。比如:一个image可以包含一个完整的ubuntu的操作系统,里面仅安装了apache或者你需要的其它应用程序。
|
|
||||||
images可以用来创建docker containers,docker提供了一个很简单的机制来创建images或者更新现有的images,你甚至可以直接从其他人那里下载一个已经做好的images来直接使用。
|
|
||||||
|
|
||||||
###Registries
|
|
||||||
Docker registries 也叫docker仓库,它有公有仓库和私有仓库2种形式,他们都可以用来让你上传和下载images。公有的仓库,即[Docker Hub](https://hub.docker.com),提供了一个数量庞大的image库供用户下载。当然,你也可以在自己的局域网内建一个自己的私有仓库。
|
|
||||||
|
|
||||||
*从这个意义上看,Docker Hub的功能跟GitHub类似。
|
|
||||||
|
|
||||||
###Containers
|
|
||||||
即docker容器,容器是从image镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。
|
|
||||||
*image是只读的,container在启动的时候创建可写的一层作为最上层。
|
|
|
@ -1,24 +0,0 @@
|
||||||
##底层技术
|
|
||||||
docker底层的2个核心技术分别是Namespaces和Control groups。
|
|
||||||
|
|
||||||
以下内容摘自InfoQ Docker,自1.20版本开始docker已经抛开lxc,不过下面的内容对于理解docker还是有很大帮助。
|
|
||||||
|
|
||||||
###pid namespace
|
|
||||||
不同用户的进程就是通过pid namespace隔离开的,且不同 namespace 中可以有相同pid。所有的LXC进程在docker中的父进程为docker进程,每个lxc进程具有不同的namespace。同时由于允许嵌套,因此可以很方便的实现 Docker in Docker。
|
|
||||||
|
|
||||||
###net namespace
|
|
||||||
有了 pid namespace, 每个namespace中的pid能够相互隔离,但是网络端口还是共享host的端口。网络隔离是通过net namespace实现的, 每个net namespace有独立的 network devices, IP addresses, IP routing tables, /proc/net 目录。这样每个container的网络就能隔离开来。docker默认采用veth的方式将container中的虚拟网卡同host上的一个docker bridge: docker0连接在一起。
|
|
||||||
|
|
||||||
###ipc namespace
|
|
||||||
container中进程交互还是采用linux常见的进程间交互方法(interprocess communication - IPC), 包括常见的信号量、消息队列和共享内存。然而同 VM 不同的是,container 的进程间交互实际上还是host上具有相同pid namespace中的进程间交互,因此需要在IPC资源申请时加入namespace信息 - 每个IPC资源有一个唯一的 32 位 ID。
|
|
||||||
|
|
||||||
###mnt namespace
|
|
||||||
类似chroot,将一个进程放到一个特定的目录执行。mnt namespace允许不同namespace的进程看到的文件结构不同,这样每个 namespace 中的进程所看到的文件目录就被隔离开了。同chroot不同,每个namespace中的container在/proc/mounts的信息只包含所在namespace的mount point。
|
|
||||||
|
|
||||||
###uts namespace
|
|
||||||
UTS("UNIX Time-sharing System") namespace允许每个container拥有独立的hostname和domain name, 使其在网络上可以被视作一个独立的节点而非Host上的一个进程。
|
|
||||||
|
|
||||||
###user namespace
|
|
||||||
每个container可以有不同的 user 和 group id, 也就是说可以在container内部用container内部的用户执行程序而非Host上的用户。
|
|
||||||
|
|
||||||
Control groups主要用来隔离各个容器和宿主主机的资源利用。
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
docker有三个基本组件
|
||||||
|
* 镜像(Image)
|
||||||
|
* 容器(Container)
|
||||||
|
* 仓库(Repository)
|
||||||
|
|
||||||
|
|
||||||
|
### 镜像
|
||||||
|
docker 镜像就是一个只读的模板。比如:一个镜像可以包含一个完整的ubuntu的操作系统,里面仅安装了apache或者你需要的其它应用程序。
|
||||||
|
镜像可以用来创建docker 容器。docker提供了一个很简单的机制来创建镜像或者更新现有的镜像,你甚至可以直接从其他人那里下载一个已经做好的镜像来直接使用。
|
||||||
|
|
||||||
|
###容器
|
||||||
|
容器是从image镜像创建的运行实例。它可以被启动、开始、停止、删除。每个容器都是相互隔离的、保证安全的平台。可以把容器看做是一个应用程序。
|
||||||
|
|
||||||
|
*image是只读的,container在启动的时候创建可写的一层作为最上层。
|
||||||
|
|
||||||
|
|
||||||
|
###仓库
|
||||||
|
仓库是集中存放镜像文件的场所,可以用来让你上传和下载镜像。分为公有仓库和私有仓库2种形式。公有仓库,目前仅有[Docker Hub](https://hub.docker.com),提供了一个数量庞大的image库供用户下载。当然,用户也可以在本地网络内创建一个私有仓库。
|
||||||
|
|
||||||
|
*Docker Hub的功能跟GitHub类似。
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
##镜像
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
##创建我们自己的images
|
##创建镜像
|
||||||
别人的镜像虽然好,但不一定适合我们。
|
别人的镜像虽然好,但不一定适合我们。
|
||||||
我们可以对这些镜像做一些修改,有2个方法:利用现成的镜像进行修改或者利用dockerfile创建。
|
我们可以对这些镜像做一些修改,有2个方法:利用现成的镜像进行修改或者利用dockerfile创建。
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
##docker image的工作原理
|
##工作原理
|
||||||
|
|
||||||
docker image是怎么实现增量的修改和维护的?
|
docker image是怎么实现增量的修改和维护的?
|
||||||
每个docker都有很多层次构成,docker使用 [Union FS](http://en.wikipedia.org/wiki/UnionFS) 将这些不同的层结合到一个image中去。
|
每个docker都有很多层次构成,docker使用 [Union FS](http://en.wikipedia.org/wiki/UnionFS) 将这些不同的层结合到一个image中去。
|
|
@ -1,4 +1,4 @@
|
||||||
##使用docker push上传images
|
##上传镜像
|
||||||
用户也可以把自己创建的image上传到docker hub中来共享。
|
用户也可以把自己创建的image上传到docker hub中来共享。
|
||||||
```
|
```
|
||||||
$ sudo docker push ouruser/sinatra
|
$ sudo docker push ouruser/sinatra
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
##用docker rmi 移除本地images
|
##移除本地镜像
|
||||||
如果要移除本地的image,可以使用rmi命令。注意rm命令是移除容器。
|
如果要移除本地的image,可以使用rmi命令。注意rm命令是移除容器。
|
||||||
```
|
```
|
||||||
$ sudo docker rmi training/sinatra
|
$ sudo docker rmi training/sinatra
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
##docker中的容器互联-linking系统
|
##docker中的容器互联-linking系统
|
||||||
docker有一个linking 系统可以连接多个容器。它会创建一对父子关系,父容器可以看到所选择的子容器的信息。
|
docker有一个linking 系统可以连接多个容器。它会创建一对父子关系,父容器可以看到所选择的子容器的信息。
|
||||||
###容器的命名系统
|
###容器的命名系统
|
||||||
linking系统依据容器的名称来执行。当我们创建容器的时候,系统会随机分配一个名字。当然我们也可以自己来命名容器,这样做有2个好处:
|
linking系统依据容器的名称来执行。当我们创建容器的时候,系统会随机分配一个名字。当然用户也可以自己来命名容器,这样做有2个好处:
|
||||||
* 当我们自己指定名称的时候,比较好记,比如一个web应用我们可以给它起名叫web
|
* 当我们自己指定名称的时候,比较好记,比如一个web应用我们可以给它起名叫web
|
||||||
* 当我们要连接其他容器时候,可以作为一个有用的参考点,比如连接web容器到db容器
|
* 当我们要连接其他容器时候,可以作为一个有用的参考点,比如连接web容器到db容器
|
||||||
使用--name标记可以为容器命名
|
使用--name标记可以为容器命名
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -P --name web training/webapp python app.py
|
$ sudo docker run -d -P --name web training/webapp python app.py
|
||||||
```
|
```
|
||||||
使用docker -ps 来验证我们设定的命名
|
使用docker -ps 来验证设定的命名
|
||||||
```
|
```
|
||||||
$ sudo docker ps -l
|
$ sudo docker ps -l
|
||||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
||||||
|
|
|
@ -1,29 +1,40 @@
|
||||||
##端口映射
|
##端口映射
|
||||||
当我们使用-P 标记时,docker 会随机映射一个49000 到49900的端口到内部容器的端口。
|
当我们使用-P 标记时,docker 会随机映射一个49000 到49900的端口到内部容器开放的端口。
|
||||||
使用docker ps 可以看到 这次是49155映射到了5000
|
使用`docker ps`可以看到,本地主机的49155映射到了容器的5000端口。
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -P training/webapp python app.py
|
$ sudo docker run -d -P training/webapp python app.py
|
||||||
$ sudo docker ps nostalgic_morse
|
$ sudo docker ps -l
|
||||||
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
|
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
|
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
|
||||||
```
|
```
|
||||||
-p(小写的P)可以指定我们要映射的端口,但是,在一个指定端口上只可以绑定一个容器。
|
其中,-d是告诉docker在后台启动容器。-P会让docker将容器内必需的网络端口映射到本地主机。
|
||||||
|
|
||||||
|
|
||||||
|
-p(小写的P)则可以指定要映射的端口,并且,在一个指定端口上只可以绑定一个容器。支持的格式有`ip:hostPort:containerPort | ip::containerPort | hostPort:containerPort`。
|
||||||
|
|
||||||
|
###映射所有接口地址
|
||||||
|
使用`hostPort:containerPort`格式本地的5000端口映射到容器的5000端口,可以执行
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
|
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
|
||||||
```
|
```
|
||||||
-p默认会绑定本地所有接口地址,所以我们一般指定一个地址,比如localhost
|
此时默认会绑定本地所有接口上的所有地址。
|
||||||
|
|
||||||
|
###映射到指定地址的指定端口
|
||||||
|
可以使用`ip:hostPort:containerPort`格式指定映射使用一个特定地址,比如localhost地址127.0.0.1
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
|
$ sudo docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
|
||||||
```
|
```
|
||||||
或者绑定localhost的任意端口到容器的5000端口
|
###映射到指定地址的任意端口
|
||||||
|
使用`ip::containerPort`绑定localhost的任意端口到容器的5000端口,本地主机会自动分配一个端口。
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
|
$ sudo docker run -d -p 127.0.0.1::5000 training/webapp python app.py
|
||||||
```
|
```
|
||||||
还可以使用upd标记来指定udp端口
|
还可以使用udp标记来指定udp端口
|
||||||
```
|
```
|
||||||
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
|
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
|
||||||
```
|
```
|
||||||
使用dicker port 来查看当前绑定的端口配置,也可以查看到绑定的地址
|
###查看映射端口配置
|
||||||
|
使用`docker port` 来查看当前映射的端口配置,也可以查看到绑定的地址
|
||||||
```
|
```
|
||||||
$ docker port nostalgic_morse 5000
|
$ docker port nostalgic_morse 5000
|
||||||
127.0.0.1:49155.
|
127.0.0.1:49155.
|
||||||
|
|
Loading…
Reference in New Issue