diff --git a/.travis/book.json b/.travis/book.json index e9e4ffe..855b604 100644 --- a/.travis/book.json +++ b/.travis/book.json @@ -1,6 +1,12 @@ { "title": "Docker -- 从入门到实践", "author": "yeasy", + "language": "zh-hans", + "links": { + "sidebar": { + "GitHub": "https://github.com/yeasy/docker_practice" + } + }, "plugins": [ "image-captions", "github-buttons", diff --git a/SUMMARY.md b/SUMMARY.md index a78c8b5..820dd43 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -37,7 +37,7 @@ * [HEALTHCHECK 健康检查](image/dockerfile/healthcheck.md) * [ONBUILD 为他人作嫁衣裳](image/dockerfile/onbuild.md) * [参考文档](image/dockerfile/references.md) - * [Dockerfile 多阶段构建](image/multistage-builds.md) + * [Dockerfile 多阶段构建](image/multistage-builds.md) * [其它制作镜像的方式](image/other.md) * [删除本地镜像](image/rmi.md) * [实现原理](image/internal.md) @@ -94,6 +94,11 @@ * [安装](machine/install.md) * [使用](machine/usage.md) * [Docker 三剑客之 Docker Swarm](swarm/README.md) +* [Swarm mode](swarm_mode/README.md) + * [基本概念](swarm_mode/overview.md) + * [创建 Swarm 集群](swarm_mode/create.md) + * [在 Swarm 集群部署服务](swarm_mode/deploy.md) + * [在 Swarm 集群中使用 docker-compose.yml](swarm_mode/stack.md) * [Etcd 项目](etcd/README.md) * [简介](etcd/intro.md) * [安装](etcd/install.md) diff --git a/book.json b/book.json index e9e4ffe..855b604 100644 --- a/book.json +++ b/book.json @@ -1,6 +1,12 @@ { "title": "Docker -- 从入门到实践", "author": "yeasy", + "language": "zh-hans", + "links": { + "sidebar": { + "GitHub": "https://github.com/yeasy/docker_practice" + } + }, "plugins": [ "image-captions", "github-buttons", diff --git a/compose/README.md b/compose/README.md index cac62b6..d265bc1 100644 --- a/compose/README.md +++ b/compose/README.md @@ -1,5 +1,5 @@ # Docker Compose 项目 -Docker Compose 是 Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用。 +`Docker Compose` 是 Docker 官方编排(Orchestration)项目之一,负责快速在集群中部署分布式应用。 -本章将介绍 Compose 项目情况以及安装和使用。 +本章将介绍 `Compose` 项目情况以及安装和使用。 diff --git a/compose/commands.md b/compose/commands.md index 15e9bd1..c444c22 100644 --- a/compose/commands.md +++ b/compose/commands.md @@ -5,7 +5,7 @@ 执行 `docker-compose [COMMAND] --help` 或者 `docker-compose help [COMMAND]` 可以查看具体某个命令的使用格式。 -Compose 命令的基本的使用格式是 +`docker-compose` 命令的基本的使用格式是 ```bash docker-compose [-f=...] [options] [COMMAND] [ARGS...] diff --git a/compose/django.md b/compose/django.md index 8d962f2..0137889 100644 --- a/compose/django.md +++ b/compose/django.md @@ -1,6 +1,6 @@ ## 使用 Django -本小节内容适合 Python 开发人员阅读。 +本小节内容适合 `Python` 开发人员阅读。 我们现在将使用 `Docker Compose` 配置并运行一个 `Django/PostgreSQL` 应用。 @@ -57,7 +57,7 @@ $ docker-compose run web django-admin.py startproject django_example . Compose 会先使用 `Dockerfile` 为 web 服务创建一个镜像,接着使用这个镜像在容器里运行 `django-admin.py startproject composeexample` 指令。 -这将在当前目录生成一个 Django 应用。 +这将在当前目录生成一个 `Django` 应用。 ```bash $ ls @@ -110,7 +110,7 @@ web_1 | Starting development server at http://0.0.0.0:8000/ web_1 | Quit the server with CONTROL-C. ``` -这个 `Django` 应用已经开始在你的 Docker 守护进程里监听着 `8000` 端口了。打开 `127.0.0.1:8000` 即可看到 Django 欢迎页面。 +这个 `Django` 应用已经开始在你的 Docker 守护进程里监听着 `8000` 端口了。打开 `127.0.0.1:8000` 即可看到 `Django` 欢迎页面。 你还可以在 Docker 上运行其它的管理命令,例如对于同步数据库结构这种事,在运行完 `docker-compose up` 后,在另外一个终端进入文件夹运行以下命令即可: diff --git a/compose/install.md b/compose/install.md index 5612837..bcf8848 100644 --- a/compose/install.md +++ b/compose/install.md @@ -1,12 +1,12 @@ ## 安装与卸载 -Compose 目前支持 Linux、macOS、Windows 10 三大平台。 +`Compose` 目前支持 Linux、macOS、Windows 10 三大平台。 -Compose 可以通过 Python 的包管理工具 pip 进行安装,也可以直接下载编译好的二进制文件使用,甚至直接运行在 Docker 容器中。 +`Compose` 可以通过 Python 的包管理工具 pip 进行安装,也可以直接下载编译好的二进制文件使用,甚至直接运行在 Docker 容器中。 前两种方式是传统方式,适合本地环境下安装使用;最后一种方式则不破坏系统环境,更适合云计算场景。 -Docker for macOS 、Docker for Windows 自带 `docker-compose` 二进制文件,安装 Docker 之后可以直接使用。 +`Docker for macOS` 、`Docker for Windows` 自带 `docker-compose` 二进制文件,安装 Docker 之后可以直接使用。 ```bash $ docker-compose --version @@ -119,7 +119,7 @@ exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES $ sudo rm /usr/local/bin/docker-compose ``` -如果是通过 python pip 安装的,则执行如下命令即可删除。 +如果是通过 `pip` 安装的,则执行如下命令即可删除。 ```bash $ sudo pip uninstall docker-compose diff --git a/compose/introduction.md b/compose/introduction.md index 1cd3260..3c7ee5e 100644 --- a/compose/introduction.md +++ b/compose/introduction.md @@ -2,22 +2,22 @@ ![Docker Compose 项目](_images/docker_compose.jpg) -Compose 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 OpenStack 中的 Heat 十分类似。 +`Compose` 项目是 Docker 官方的开源项目,负责实现对 Docker 容器集群的快速编排。从功能上看,跟 `OpenStack` 中的 `Heat` 十分类似。 其代码目前在 [https://github.com/docker/compose](https://github.com/docker/compose) 上开源。 -Compose 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。 +`Compose` 定位是 「定义和运行多个 Docker 容器的应用(Defining and running multi-container Docker applications)」,其前身是开源项目 Fig。 通过第一部分中的介绍,我们知道使用一个 `Dockerfile` 模板文件,可以让用户很方便的定义一个单独的应用容器。然而,在日常工作中,经常会碰到需要多个容器相互配合来完成某项任务的情况。例如要实现一个 Web 项目,除了 Web 服务容器本身,往往还需要再加上后端的数据库服务容器,甚至还包括负载均衡容器等。 -Compose 恰好满足了这样的需求。它允许用户通过一个单独的 `docker-compose.yml` 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 +`Compose` 恰好满足了这样的需求。它允许用户通过一个单独的 `docker-compose.yml` 模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。 -Compose 中有两个重要的概念: +`Compose` 中有两个重要的概念: * 服务(service):一个应用的容器,实际上可以包括若干运行相同镜像的容器实例。 * 项目(project):由一组关联的应用容器组成的一个完整业务单元,在 `docker-compose.yml` 文件中定义。 -Compose 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。 +`Compose` 的默认管理对象是项目,通过子命令对项目中的一组容器进行便捷地生命周期管理。 -Compose 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 Compose 来进行编排管理。 +`Compose` 项目由 Python 编写,实现上调用了 Docker 服务提供的 API 来对容器进行管理。因此,只要所操作的平台支持 Docker API,就可以在其上利用 `Compose` 来进行编排管理。 diff --git a/compose/rails.md b/compose/rails.md index 226a61c..7f40faa 100644 --- a/compose/rails.md +++ b/compose/rails.md @@ -1,10 +1,11 @@ ## 使用 Rail -本小节内容适合 Ruby 开发人员阅读。 +本小节内容适合 `Ruby` 开发人员阅读。 -我们现在将使用 Compose 配置并运行一个 Rails/PostgreSQL 应用。 +我们现在将使用 `Compose` 配置并运行一个 `Rails/PostgreSQL` 应用。 + +在一切工作开始前,需要先设置好三个必要的文件。 -在一切工作开始前,需要先设置好三个必要的文件。 首先,因为应用将要运行在一个满足所有环境依赖的 Docker 容器里面,那么我们可以通过编辑 `Dockerfile` 文件来指定 Docker 容器要安装内容。内容如下: ```docker @@ -33,7 +34,7 @@ services: image: postgres ports: - "5432" - + web: build: . command: bundle exec rackup -p 3000 @@ -49,7 +50,7 @@ services: ```bash $ docker-compose run web rails new . --force --database=postgresql --skip-bundle ``` -Compose 会先使用 `Dockerfile` 为 web 服务创建一个镜像,接着使用这个镜像在容器里运行 `rails new ` 和它之后的命令。一旦这个命令运行完后,应该就可以看一个崭新的应用已经生成了。 +`Compose` 会先使用 `Dockerfile` 为 web 服务创建一个镜像,接着使用这个镜像在容器里运行 `rails new ` 和它之后的命令。一旦这个命令运行完后,应该就可以看一个崭新的应用已经生成了。 ```bash $ ls diff --git a/compose/usage.md b/compose/usage.md index ef1e069..6001b2f 100644 --- a/compose/usage.md +++ b/compose/usage.md @@ -3,11 +3,11 @@ ### 术语 首先介绍几个术语。 -* 服务 (service):一个应用容器,实际上可以运行多个相同镜像的实例。 +* 服务 (`service`):一个应用容器,实际上可以运行多个相同镜像的实例。 -* 项目 (project):由一组关联的应用容器组成的一个完整业务单元。 +* 项目 (`project`):由一组关联的应用容器组成的一个完整业务单元。 -可见,一个项目可以由多个服务(容器)关联而成,Compose 面向项目进行管理。 +可见,一个项目可以由多个服务(容器)关联而成,`Compose` 面向项目进行管理。 ### 场景 下面,我们创建一个经典的 Web 项目:一个 [Haproxy](http://www.haproxy.org/),挂载三个 Web 容器。 @@ -93,7 +93,7 @@ if __name__ == '__main__': ``` #### index.html -生成一个临时的 `index.html` 文件,其内容会被 index.py 更新。 +生成一个临时的 `index.html` 文件,其内容会被 `index.py` 更新。 ```bash $ touch index.html ``` @@ -145,7 +145,7 @@ backend web_backends http-check expect status 200 ``` ### docker-compose.yml -编写 `docker-compose.yml` 文件,这个是 Compose 使用的主模板文件。内容十分简单,指定 3 个 web 容器,以及 1 个 haproxy 容器。 +编写 `docker-compose.yml` 文件,这个是 `Compose` 使用的主模板文件。内容十分简单,指定 3 个 `web` 容器,以及 1 个 `haproxy` 容器。 ```yaml version: "3" @@ -201,6 +201,6 @@ Recreating composehaproxyweb_haproxy_1... Attaching to composehaproxyweb_webb_1, composehaproxyweb_webc_1, composehaproxyweb_weba_1, composehaproxyweb_haproxy_1 ``` -此时访问本地的 80 端口,会经过 haproxy 自动转发到后端的某个 web 容器上,刷新页面,可以观察到访问的容器地址的变化。 +此时访问本地的 `80` 端口,会经过 `haproxy` 自动转发到后端的某个 web 容器上,刷新页面,可以观察到访问的容器地址的变化。 -访问本地 70 端口,可以查看到 haproxy 的统计信息。 +访问本地 `70` 端口,可以查看到 `haproxy` 的统计信息。 diff --git a/compose/wordpress.md b/compose/wordpress.md index fbfdaf0..871e199 100644 --- a/compose/wordpress.md +++ b/compose/wordpress.md @@ -1,8 +1,8 @@ ## 使用 WordPress -本小节内容适合 PHP 开发人员阅读。 +本小节内容适合 `PHP` 开发人员阅读。 -Compose 可以很便捷的让 Wordpress 运行在一个独立的环境中。 +`Compose` 可以很便捷的让 `Wordpress` 运行在一个独立的环境中。 ### 创建空文件夹 @@ -44,4 +44,4 @@ volumes: ### 构建并运行项目 -运行 `docker-compose up -d` Compose 就会拉取镜像再创建我们所需要的镜像,然后启动 `wordpress` 和数据库容器。 接着浏览器访问 `127.0.0.1:8000` 端口就能看到 WordPress 安装界面了。 +运行 `docker-compose up -d` Compose 就会拉取镜像再创建我们所需要的镜像,然后启动 `wordpress` 和数据库容器。 接着浏览器访问 `127.0.0.1:8000` 端口就能看到 `WordPress` 安装界面了。 diff --git a/compose/yaml_file.md b/compose/yaml_file.md index b179789..ca0c933 100644 --- a/compose/yaml_file.md +++ b/compose/yaml_file.md @@ -1,6 +1,6 @@ ## Compose 模板文件 -模板文件是使用 Compose 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 `docker run` 相关参数的含义都是类似的。 +模板文件是使用 `Compose` 的核心,涉及到的指令关键字也比较多。但大家不用担心,这里面大部分指令跟 `docker run` 相关参数的含义都是类似的。 默认的模板文件名称为 `docker-compose.yml`,格式为 YAML 格式。 diff --git a/swarm_mode/README.md b/swarm_mode/README.md new file mode 100644 index 0000000..fb7c09a --- /dev/null +++ b/swarm_mode/README.md @@ -0,0 +1,5 @@ +# Swarm mode + +Docker 1.12 [Swarm mode](https://docs.docker.com/engine/swarm/) 已经内嵌入 Docker 引擎,成为了 docker 子命令 `docker swarm`。请注意与旧的 `Docker Swarm` 区分开来。 + +`Swarm mode` 内置 kv 存储功能,提供了众多的新特性,比如:具有容错能力的去中心化设计、内置服务发现、负载均衡、路由网格、动态伸缩、滚动更新、安全传输等。使得 Docker 原生的 `Swarm` 集群具备与 Mesos、Kubernetes 竞争的实力。 diff --git a/swarm_mode/create.md b/swarm_mode/create.md new file mode 100644 index 0000000..7f9b149 --- /dev/null +++ b/swarm_mode/create.md @@ -0,0 +1,68 @@ +## 创建 Swarm 集群 + +阅读 [基本概念](overview.md) 一节我们知道 `Swarm` 集群由管理节点和工作节点组成。本节我们来创建一个包含一个管理节点和两个工作节点的最小 `Swarm` 集群。 + +### 初始化集群 + +我们使用 `docker swarm init` 在本机初始化一个 `Swarm` 集群。 + +```bash +$ docker swarm init --advertise-addr 192.168.99.100 +Swarm initialized: current node (dxn1zf6l61qsb1josjja83ngz) is now a manager. + +To add a worker to this swarm, run the following command: + + docker swarm join \ + --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ + 192.168.99.100:2377 + +To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions. +``` + +如果你的 Docker 主机有多个网卡,拥有多个 IP,必须使用 `--advertise-addr` 指定 IP。 + +执行 `docker swarm init` 命令的节点自动成为管理节点。 + +### 增加工作节点 + +上一步中我们在本机初始化了一个 `Swarm` 集群,拥有了一个管理节点,下面我们使用 [`Docker Machine`](../machine) 创建两个 Docker 主机,并加入到集群中。 + +```bash +$ docker-machine create -d virtualbox worker1 + +$ docker-machine ssh worker1 + +docker@worker1:~$ docker swarm join \ + --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ + 192.168.99.100:2377 + +This node joined a swarm as a worker. +``` + +```bash +$ docker-machine create -d virtualbox worker2 + +$ docker-machine ssh worker2 + +docker@worker1:~$ docker swarm join \ + --token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2e7c \ + 192.168.99.100:2377 + +This node joined a swarm as a worker. +``` + +*注意:* 一些细心的读者可能通过 `docker-machine create --help` 查看到 `--swarm*` 等一系列参数。该参数是用于旧的 `Docker Swarm`,与本章所讲的 `Swarm mode` 没有关系。 + +### 查看集群 + +经过上边的两步,我们已经拥有了一个最小的 `Swarm` 集群,包含一个管理节点和两个工作节点。 + +在管理节点使用 `docker node ls` 查看集群。 + +```bash +$ docker node ls +ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS +03g1y59jwfg7cf99w4lt0f662 worker2 Ready Active +9j68exjopxe7wfl6yuxml7a7j worker1 Ready Active +dxn1zf6l61qsb1josjja83ngz * manager1 Ready Active Leader +``` diff --git a/swarm_mode/demo/docker-compose.yml b/swarm_mode/demo/docker-compose.yml new file mode 100644 index 0000000..45dff12 --- /dev/null +++ b/swarm_mode/demo/docker-compose.yml @@ -0,0 +1,47 @@ +version: "3" + +services: + wordpress: + image: wordpress + ports: + - 80:80 + networks: + - overlay + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + deploy: + mode: replicated + replicas: 3 + + db: + image: mysql + networks: + - overlay + volumes: + - db-data:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: somewordpress + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + deploy: + placement: + constraints: [node.role == manager] + + visualizer: + image: dockersamples/visualizer:stable + ports: + - "8080:8080" + stop_grace_period: 1m30s + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + deploy: + placement: + constraints: [node.role == manager] + +volumes: + db-data: +networks: + overlay: diff --git a/swarm_mode/deploy.md b/swarm_mode/deploy.md new file mode 100644 index 0000000..18b71a9 --- /dev/null +++ b/swarm_mode/deploy.md @@ -0,0 +1,53 @@ +## 部署服务 + +我们使用 `docker service` 命令来管理 `Swarm` 集群中的服务,该命令只能在管理节点运行。 + +### 新建服务 + +现在我们在上一节创建的 `Swarm` 集群中运行一个名为 `nginx` 服务。 + +```bash +$ docker service create --replicas 3 -p 80:80 --name nginx nginx:1.13.7-alpine +``` + +现在我们使用浏览器,输入任意节点 IP ,即可看到 nginx 默认页面。 + +### 查看服务 + +使用 `docker service ls` 来查看当前 `Swarm` 集群运行的服务。 + +```bash +$ docker service ls +ID NAME MODE REPLICAS IMAGE PORTS +kc57xffvhul5 nginx replicated 3/3 nginx:1.13.7-alpine *:80->80/tcp +``` + +使用 `docker service ps` 来查看某个服务的详情。 + +```bash +$ docker service ps nginx +ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS +pjfzd39buzlt nginx.1 nginx:1.13.7-alpine swarm2 Running Running about a minute ago +hy9eeivdxlaa nginx.2 nginx:1.13.7-alpine swarm1 Running Running about a minute ago +36wmpiv7gmfo nginx.3 nginx:1.13.7-alpine swarm3 Running Running about a minute ago +``` + +使用 `docker service logs` 来查看某个服务的日志。 + +```bash +$ docker service logs nginx +nginx.3.36wmpiv7gmfo@swarm3 | 10.255.0.4 - - [25/Nov/2017:02:10:30 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-" +nginx.3.36wmpiv7gmfo@swarm3 | 10.255.0.4 - - [25/Nov/2017:02:10:30 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-" +nginx.3.36wmpiv7gmfo@swarm3 | 2017/11/25 02:10:30 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.255.0.4, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.99.102" +nginx.1.pjfzd39buzlt@swarm2 | 10.255.0.2 - - [25/Nov/2017:02:10:26 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-" +nginx.1.pjfzd39buzlt@swarm2 | 10.255.0.2 - - [25/Nov/2017:02:10:27 +0000] "GET /favicon.ico HTTP/1.1" 404 169 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:58.0) Gecko/20100101 Firefox/58.0" "-" +nginx.1.pjfzd39buzlt@swarm2 | 2017/11/25 02:10:27 [error] 5#5: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.255.0.2, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "192.168.99.101" +``` + +### 删除服务 + +使用 `docker service rm` 来从 `Swarm` 集群移除某个服务。 + +```bash +$ docker service rm nginx +``` diff --git a/swarm_mode/image/wordpress.png b/swarm_mode/image/wordpress.png new file mode 100644 index 0000000..f7c026a Binary files /dev/null and b/swarm_mode/image/wordpress.png differ diff --git a/swarm_mode/overview.md b/swarm_mode/overview.md new file mode 100644 index 0000000..87c1117 --- /dev/null +++ b/swarm_mode/overview.md @@ -0,0 +1,27 @@ +## 基本概念 + +`Swarm` 是使用 [`SwarmKit`](https://github.com/docker/swarmkit/) 构建的 Docker 引擎内置(原生)的集群管理和编排工具。 + + 使用 `Swarm` 集群之前需要了解以下几个概念。 + +### 节点 + +运行 Docker 的主机可以主动初始化一个 `Swarm` 集群或者加入一个已存在的 `Swarm` 集群,这样这个运行 Docker 的主机就成为一个 `Swarm` 集群的节点 (`node`) 。 + +节点分为管理 (`manager`) 节点和工作 (`worker`) 节点。 + +管理节点用于 `Swarm` 集群的管理,`docker swarm` 命令基本只能在管理节点执行(节点退出集群命令 `docker swarm leave` 可以在工作节点执行)。一个 `Swarm` 集群可以有多个管理节点,但只有一个管理节点可以成为 `leader`,`leader` 通过 `raft` 协议实现。 + +工作节点是任务执行节点,管理节点将服务 (`service`) 下发至工作节点执行。管理节点默认也作为工作节点。你也可以通过配置让服务只运行在管理节点。 + +### 服务和任务 + +任务 (`Task`)是 `Swarm` 中的最小的调度单位,目前来说就是一个单一的容器。 + +服务 (`Services`) 是指一组任务的集合,服务定义了任务的属性。服务有两种模式: + +* `replicated services` 按照一定规则在各个工作节点上运行指定个数的任务。 + +* `global services` 每个工作节点上运行一个任务 + +两种模式通过 `docker service create` 的 `--mode` 参数指定。 diff --git a/swarm_mode/stack.md b/swarm_mode/stack.md new file mode 100644 index 0000000..66561f4 --- /dev/null +++ b/swarm_mode/stack.md @@ -0,0 +1,98 @@ +## 在 Swarm 集群中使用 compose 文件 + +正如之前使用 `docker-compose.yml` 来一次配置、启动多个容器,在 `Swarm` 集群中也可以使用 `compose` 文件 (`docker-compose.yml`) 来配置、启动多个服务。 + +上一节中,我们使用 `docker service create` 一次只能部署一个服务,使用 `docker-compose.yml` 我们可以一次启动多个关联的服务。 + +我们以在 `Swarm` 集群中部署 `WordPress` 为例进行说明。 + +```yaml +version: "3" + +services: + wordpress: + image: wordpress + ports: + - 80:80 + networks: + - overlay + environment: + WORDPRESS_DB_HOST: db:3306 + WORDPRESS_DB_USER: wordpress + WORDPRESS_DB_PASSWORD: wordpress + deploy: + mode: replicated + replicas: 3 + + db: + image: mysql + networks: + - overlay + volumes: + - db-data:/var/lib/mysql + environment: + MYSQL_ROOT_PASSWORD: somewordpress + MYSQL_DATABASE: wordpress + MYSQL_USER: wordpress + MYSQL_PASSWORD: wordpress + deploy: + placement: + constraints: [node.role == manager] + + visualizer: + image: dockersamples/visualizer:stable + ports: + - "8080:8080" + stop_grace_period: 1m30s + volumes: + - "/var/run/docker.sock:/var/run/docker.sock" + deploy: + placement: + constraints: [node.role == manager] + +volumes: + db-data: +networks: + overlay: +``` + +在 `Swarm` 集群管理节点新建该文件,其中的 `visualizer` 服务提供一个可视化页面,我们可以从浏览器中很直观的查看集群中各个服务的运行节点。 + +在 `Swarm` 集群中使用 `docker-compose.yml` 我们用 `docker stack` 命令,下面我们对该命令进行详细讲解。 + +### 部署服务 + +部署服务使用 `docker stack deploy`,其中 `-c` 参数指定 compose 文件名。 + +```bash +$ docker stack deploy -c docker-compose.yml wordpress +``` + +现在我们打开浏览器输入 `任一节点IP:8080` 即可看到各节点运行状态。如下图所示: + +![](image/wordpress.png) + +在浏览器新的标签页输入 `任一节点IP` 即可看到 `WordPress` 安装界面,安装完成之后,输入 `任一节点IP` 即可看到 `WordPress` 页面。 + +### 查看服务 + +```bash +$ docker stack ls +NAME SERVICES +wordpress 3 +``` + +### 移除服务 + +要移除服务,使用 `docker stack down` + +```bash +$ docker stack down wordpress +Removing service wordpress_db +Removing service wordpress_visualizer +Removing service wordpress_wordpress +Removing network wordpress_overlay +Removing network wordpress_default +``` + +该命令不会移除服务所使用的 `数据卷`,如果你想移除数据卷请使用 `docker volume rm` diff --git a/underly/arch.md b/underly/arch.md index a58f5ab..508ce5d 100644 --- a/underly/arch.md +++ b/underly/arch.md @@ -1,10 +1,11 @@ ## 基本架构 -Docker 采用了 C/S架构,包括客户端和服务端。 -Docker daemon 作为服务端接受来自客户的请求,并处理这些请求(创建、运行、分发容器)。 -客户端和服务端既可以运行在一个机器上,也可通过 socket 或者 RESTful API 来进行通信。 + +Docker 采用了 `C/S` 架构,包括客户端和服务端。Docker 守护进程 (`Daemon`)作为服务端接受来自客户端的请求,并处理这些请求(创建、运行、分发容器)。 + +客户端和服务端既可以运行在一个机器上,也可通过 `socket` 或者 `RESTful API` 来进行通信。 ![Docker 基本架构](_images/docker_arch.png) +Docker 守护进程一般在宿主主机后台运行,等待接收来自客户端的消息。 -Docker daemon 一般在宿主主机后台运行,等待接收来自客户端的消息。 -Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker daemon 交互。 +Docker 客户端则为用户提供一系列可执行命令,用户用这些命令实现跟 Docker 守护进程交互。 diff --git a/underly/cgroups.md b/underly/cgroups.md index f43b0a2..1914a69 100644 --- a/underly/cgroups.md +++ b/underly/cgroups.md @@ -2,8 +2,6 @@ 控制组([cgroups](http://en.wikipedia.org/wiki/Cgroups))是 Linux 内核的一个特性,主要用来对共享资源进行隔离、限制、审计等。只有能控制分配到容器的资源,才能避免当多个容器同时运行时的对系统资源的竞争。 -控制组技术最早是由 Google 的程序员 2006 年起提出,Linux 内核自 2.6.24 开始支持。 +控制组技术最早是由 Google 的程序员在 2006 年提出,Linux 内核自 2.6.24 开始支持。 控制组可以提供对容器的内存、CPU、磁盘 IO 等资源的限制和审计管理。 - - diff --git a/underly/container_format.md b/underly/container_format.md index b9ec19c..d634e30 100644 --- a/underly/container_format.md +++ b/underly/container_format.md @@ -1,4 +1,5 @@ ## 容器格式 -最初,Docker 采用了 LXC 中的容器格式。自 1.20 版本开始,Docker 也开始支持新的 [libcontainer](https://github.com/docker/libcontainer) 格式,并作为默认选项。 + +最初,Docker 采用了 `LXC` 中的容器格式。从 0.7 版本以后开始去除 LXC,转而使用自行开发的 [libcontainer](https://github.com/docker/libcontainer),从 1.11 开始,则进一步演进为使用 [runC](https://github.com/opencontainers/runc) 和 [containerd](https://containerd.tools/)。 对更多容器格式的支持,还在进一步的发展中。 diff --git a/underly/namespace.md b/underly/namespace.md index a78019a..0f318d8 100644 --- a/underly/namespace.md +++ b/underly/namespace.md @@ -19,4 +19,4 @@ UTS("UNIX Time-sharing System") 命名空间允许每个容器拥有独立的 ho ### 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/)。 diff --git a/underly/ufs.md b/underly/ufs.md index 256cc77..094086b 100644 --- a/underly/ufs.md +++ b/underly/ufs.md @@ -1,10 +1,11 @@ ## 联合文件系统 + 联合文件系统([UnionFS](http://en.wikipedia.org/wiki/UnionFS))是一种分层、轻量级并且高性能的文件系统,它支持对文件系统的修改作为一次提交来一层层的叠加,同时可以将不同目录挂载到同一个虚拟文件系统下(unite several directories into a single virtual filesystem)。 联合文件系统是 Docker 镜像的基础。镜像可以通过分层来进行继承,基于基础镜像(没有父镜像),可以制作各种具体的应用镜像。 另外,不同 Docker 容器就可以共享一些基础的文件系统层,同时再加上自己独有的改动层,大大提高了存储的效率。 -Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 AUFS 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 AUFS 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。 +Docker 中使用的 AUFS(AnotherUnionFS)就是一种联合文件系统。 `AUFS` 支持为每一个成员目录(类似 Git 的分支)设定只读(readonly)、读写(readwrite)和写出(whiteout-able)权限, 同时 `AUFS` 里有一个类似分层的概念, 对只读权限的分支可以逻辑上进行增量地修改(不影响只读部分的)。 -Docker 目前支持的联合文件系统种类包括 AUFS, btrfs, vfs 和 DeviceMapper。 +Docker 目前支持的联合文件系统包括 `OverlayFS`, `AUFS`, `Btrfs`, `VFS`, `ZFS` 和 `Device Mapper`。