Docker 的部署方式
在使用 docker run
命令启动 Docker 容器时,如果需要进行端口映射、目录挂载、网络信息等配置,整条命令将变得非常长,并且由于是一条 shell 命令,修改和复用也不方便。我们在大规模部署容器的时候不可能手动去输入众多的命令,所以需要一些工具来辅助我们实现 docker run
命令的编写,同时实现简单快捷的大规模部署。
docker-compose 部署
docker-compose 是一个读取特定格式的 yaml 文件并将其转换为 docker run
命令的工具,它有效的规避了上述的问题,并且它也是 docker swarm
、docker stack
等技术的基石。docker-compose 需要一份 yaml 格式的脚本,如果在使用命令时不想指定具体的脚本名称,那就需要将脚本命名为 docker-compose.yml
。下面是一份启动 MySQL 容器的 docker-compose 脚本。
version: "3"
services:
mysql:
container_name: login_db
image: mysql:5.7
ports:
- "3306:3306"
environment:
- MYSQL_ROOT_PASSWORD=123456
volumes:
- "mysql-data:/var/lib/mysql"
networks:
- my-bridge
volumes:
mysql-data:
networks:
my-bridge:
driver: bridge
全局配置
version
指定的是 docker-compose 的版本,由于 v2
和 v3
在语法上存在一些不同,所以需要明确告诉 docker-compose 当前脚本所使用的语法版本是多少。
services
表示服务定义。一份脚本中可以定义多个服务,docker-compose 会一并启动。
volumes
下的名称列表就是服务启动时要创建的所有数据卷的名称,只有先创建了数据卷才能在下面的服务定义中的 volumes
配置中进行挂载使用。注意区分全局的 volumes 和服务定义下的 volumes 配置。
networks
下配置的是服务启动时要创建的网络及其驱动类型。这里创建了一个驱动为 bridge
、名称为 my-bridge
的桥接网络。只有先创建了网络才能在下面的服务定义中的 networks
配置中进行注册使用。注意区分全局的 networks 和服务定义下的 networks 配置。
服务配置
mysql
表示定义一个名叫 mysql 的服务。
container_name
表示服务要启动的容器的名称,如果这个服务要动态扩展多个容器,则不可以指定容器名称,否则由于容器名称冲突将导致无法扩展。
image
表示服务要使用的镜像。
ports
表示容器与宿主机的端口映射关系。凡是指定了端口映射关系的服务都不能动态扩展容器数量,因为会导致端口冲突。
environment
表示要设置到容器中的环境变量。这里设置的环境变量将被放置到容器的全局环境变量中,你可以在容器中读取并操作。
volumes
表示要挂载的目录或者数据卷。这里和 docker run
命令中的 -v
参数作用是一致的,即可以挂载数据卷,也可以挂载目录。这里使用到的数据卷必须在全局配置中先指定,如果是挂载目录则需要先手动创建。
networks
表示这个服务要注册到哪些网络上去,这里使用到的网络必须在全局配置中先指定。注册到同一个网络上的容器之间可以使用服务名进行通信。
使用 docker-compose
通过 docker-compose 可以对服务进行启动、停止、删除、扩容等操作。docker-compose 的操作必须依赖脚本,如果脚本存在于当前目录下且名为 docker-compose.yml
则不需要额外指定,否则需要使用 -f
参数进行指定。
启动服务
启动服务使用命令 docker-compose -f /path/to/script.yml up -d
,up
表示启动服务,-d
表示后台运行。这个命令会读取脚本文件并首先创建申明的数据卷和网络,然后再启动服务。
停止服务
停止服务使用命令 docker-compose -f /path/to/script.yml stop
。这个命令会将脚本中的所有服务的所有容器都停止,但不会删除容器。
删除服务
删除服务使用命令 docker-compose -f /path/to/script.yml rm
。这个命令会要求二次确认删除,并且无法删除未停止的服务。删除服务时不会关联删除服务启动时创建的网络和数据卷。
强行删除服务
强行删除服务使用命令 docker-compose -f /path/to/script.yml down
。这个命令会将所有服务的所有容器都停止并删除,同时删除服务启动时创建的网络,但不会删除数据卷。
扩容服务
随着业务量的上升,我们可能需要将服务从一个容器扩展到多个容器以提高服务能力,这时候就可以使用 docker-compose 来直接扩容服务。
docker-compose -f /path/to/script.yml up --scale orderService=3 -d
这个命令表示将名为 orderService
的服务扩容至三个容器并后台启动。如果原本的容器数量大于 3 个,那么这个命令就是缩减容器数量操作。需要注意的是,支持服务扩容的要求是非常苛刻的,需要满足以下三点要求:
- 不能够指定 container_name,即容器名;
- 不能够指定端口映射关系;
- 不能够指定挂载数据卷或目录。
如果在脚本中指定了要挂在的目录或者数据卷,那么扩容后多个容器将共用一个数据卷和目录,这样就会导致数据出现混乱。解决方法是不指定任何数据卷和目录进行挂载,由 Docker 自行创建随机名称的数据卷。
Docker Swarm 部署
上文讲到的 docker-compose 部署方式还停留在单机部署上,但在实际生产环境中不同系统的 Docker 容器都是垮宿主机部署,这时候就需要将这些宿主机形成集群统一管理,Docker Swarm 就是 Docker 原生提供的一种集群管理模式。除了 Docker Swarm 外,还有 Mesos、Kubernates 等不同的集群管理模式。
在 Docker Swarm 集群模式下,当多个宿主机形成集群后,我们就可以在管理节点(Manager Node)上通过管理命令将不同服务的容器部署到集群内不同的宿主机上,同一个服务的多个容器也可以分布到集群内不同的宿主机上以实现负载均衡。
创建 Swarm 集群
创建集群之前需要先规划好集群内的节点角色,选择其中一台宿主机作为管理节点开始创建集群,执行如下命令:
docker swarm init --advertise-addr=本机IP
--advertise-addr
用于指定管理节点所在宿主机的 eth0
网卡的 IP 地址,如果存在多个网卡,这个参数一定要指定,否则可能造成管理节点和工作节点之间无法通信。命令执行完毕后会输出如下的提示信息:
Swarm initialized: current node (gmdscjfdlubanwl7i75z5cc85) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-6djatxtetutac68xd1u8v1icnyv6t0pcplhaph2irqqxqo1m2b-8w6lq2kpw6j1chqpu4vlf2cx3 \
管理节点IP:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
根据输出提示,我们需要在其他宿主机上执行 docker swarm join …
操作以使其加入到集群作为工作节点。集群节点加入完成后在管理节点执行 docker node ls
可以看到所有的节点状态信息。
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
gmdscjfdlubanwl7i75z5cc85 * docker-1 Ready Active Leader
xna7a0h6a0xhct95kh7v6p9pl docker-3 Ready Active
使用标签标记节点
Docker Swarm 会根据自己的负载均衡算法将服务分散部署到不同的集群节点上,但有时候我们也希望能够指定服务部署到指定的集群节点上,这时候就需要通过标签来指定具体的节点了。下面的名称尝试为 HOSTNAME 是 docker-3
的节点增加一个标签:
docker node update --label-add mytag=db xna7a0h6a0xhct95kh7v6p9pl
这条命令为 ID 为 xna7a0h6a0xhct95kh7v6p9pl
的节点增加了一个标签,标签名称为 mytag
,标签值为 db
。标签的使用会在下文 Docker Stack 部署服务时讲解。
在 Swarm 集群中部署服务
有了集群就可以进行服务部署,下面尝试在集群中部署一个 MySQL 服务,在管理节点执行命令如下:
docker service create --name mysql -e MYSQL_ROOT_PASSWORD=123456 mysql:5.7
命令的参数和 docker run
命令的参数是基本一致的,只是命令换成了 docker service create
。命令 docker service ls
用于查看所有已部署的服务;命令 docker service ps 服务名称
用于查看该服务容器的部署节点和状态:
ID NAME IMAGE NODE ESIRED STATE CURRENT STATE ERROR PORTS
0m5erytxi6sa mysql.1 mysql:5.7 docker-1 Running Running 3 minutes ago
上面的信息表示 MySQL 服务下共启动了 1 个容器,其部署在名为 docker-1
的节点上,容器ID 为 0m5erytxi6sa
,当前状态是正在运行,并且与期望的状态一致。
扩容服务
与使用 docker-compose 部署服务类似,docker service
命令也可以让指定的服务进行容量增减,下面的命令尝试将 MySQL 服务扩容至 3 个容器:
docker service scale mysql=3
再次执行 docker service ps mysql
查看容器部署情况:
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
0m5erytxi6sa mysql.1 mysql:5.7 docker-1 Running Running 13 minutes ago
idgvqymekwam mysql.2 mysql:5.7 docker-3 Running Running 3 minutes ago
fldlrega7p40 mysql.3 mysql:5.7 docker-3 Running Running 3 minutes ago
可以看到容器数量已经扩大至 3 个,其中两个部署在 docker-3
节点上。
更新服务
在服务使用多容器部署的情况下,可以使用服务更新来发布新的版本或调整服务部署参数,这样可以避免先删除服务再启动服务造成的服务中断。如下命令尝试使用新版本镜像来更新服务:
docker service update --image mysql:5.8 mysql
这个命令表示对名为 mysql
的服务使用使用 mysql:5.8
版本的镜像进行更新。需要注意的是,如果服务只部署了一个容器,那么更新过程中,对外服务是肯定会中断的。
删除服务
使用命令 docker service rm 服务名称
可以将已部署的服务删除。删除服务时服务下所有的容器都会被删除且不可恢复。
使用 Docker Stack 管理多个服务
Stack
在 Swarm 模式下,使用 docker service create
命令可以创建服务进行部署,当多个服务组合到一起时,我们就把它们看作是一个 Stack。简单来说,**Stack 就是多个 Service 的组合。在 Swarm 模式下可以使用 Docker Stack 可以实现服务的批量部署。
Docker Stack 脚本
Docker Stack 并不是新的技术点,它同样是使用 docker-compose 脚本来管理服务创建脚本,并且语法没有任何区别。下面的示例展示了怎么使用 Docker Stack 来部署一个 WordPress 和 MySQL 服务,其中 WordPress 服务需要引用 MySQL 服务进行数据读写:
version: '3'
services:
wordpress:
image: wordpress
ports:
- 80:80
environment:
- WORDPRESS_DB_HOST=mysql
- WORDPRESS_DB_PASSWORD=123456
networks:
- my-network
depends_on:
- mysql
deploy:
mode: replicated
replicas: 3
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
update_config:
parallelism: 1
delay: 10s
mysql:
image: mysql:5.7
environment:
- MYSQL_ROOT_PASSWORD=123456
- MYSQL_DATABASE=wordpress
volumes:
- mysql-data:/var/lib/mysql
networks:
- my-network
deploy:
mode: global
placement:
constraints: [node.labels.mytag == db]
volumes:
mysql-data:
networks:
my-network:
driver: overlay
在 wordpress
服务的 environment
中配置的环境变量 WORDPRESS_DB_HOST
的值是 mysql
,这个 mysql
表示的是下面的 mysql
服务。由于 wordpress
服务和 mysql
服务都注册到了 my-network
网络上,所以他们彼此可以通过服务名称进行通信,而不需要指定容器 IP。
depends_on
用于配置依赖关系。这里的配置表示 wordpress
服务必须等 mysql
服务启动后才开始启动,通过这个指令可以组织服务的启动顺序。
deploy
指令下配置的是部署相关的策略信息。
mode
表示部署模式是多副本部署(replicated
)还是全局单节点部署(global
)。replicas
表示多副本部署时需要多少个副本,即该服务需要启动多少个容器。restart_policy
用于指定服务下容器的重启策略,重启触发条件由condition
定义,delay
表示每次重启的间隔时间,max_attempts
表示最大尝试重启次数。update_config
用于指定服务更新的策略。parallelism
表示每次更新多少个容器,delay
表示两次更新的时间间隔。
placement
用于配置节点的部署位置。constraints
用于指定部署位置的判断条件,上文中的 node.labels.mytag == db
表示将 mysql
服务部署到标签 mytag
的值为 db
的节点上。
部署使用的网络 my-network
的驱动是 overlay
,这是一种跨主机通信的网络,在 Swarm 模式下为了让分布在集群内不同节点上的容器能够互相通信,他们就都必须注册到 overlay
驱动的网络上。我们也可以预先手动创建一个 overlay
驱动的网络:
docker network create -d overlay my-network
这样我们在 docker-compose 脚本中声明网络时就需要进行如下变更:
networks:
my-network:
external: true
external: true
这里的 my-network
网络引用的是预先创建好的同名网络。
部署 Stack
编写好 docker-compose 脚本后就可以使用 docker stack
命令进行服务部署了,假设上文的脚本命名为 myweb.yml
, 下面的命令使用上文的脚本进行服务部署:
docker stack deploy -c myweb.yml myweb
-c
参数是 --compose-file
的缩写,用于指定部署脚本的位置,最后的 myweb
是这个 Stack 的名字,可以任意设置,通常建议和脚本名称保持一致,便于管理。命令 docker stack ls
可以查看部署的所有 Stack;命令 docker stack ps Stack名称
可以查看该 Stack 下所有服务的容器部署情况;命令 docker stack services Stack 名称
可以查看该 Stack 下所有服务的部署情况,如部署模式、副本数量等信息。
删除 Stack
命令 docker stack rm Stack名称
可以删除一个指定的 Stack。这个命令会删除该 Stack 下所有的服务及其所有的容器,无法恢复。
规划 Stack
上文提到删除 Stack 时,其下所有服务都会被删除,那么规划 Stack 就变得尤为重要。如果在规划时将所有服务都放到一个 Stack 下,那么当需要重新部署某个服务时就不得不将其他所有服务也全部重新部署。通常建议将高耦合的服务放到一个 Stack中,每个中间件集群作为一个 Stack,这样可以避免重新部署时发生雪崩。总之,规划 Stack 与编写代码类似,都要减少相互的耦合,尽量避免出现雪崩。
Docker 的部署方式的更多相关文章
- docker中部署django项目~~Dockfile方式和compose方式
1. 背景: 本机win10上,后端django框架代码与前端vue框架代码联调通过. 2. 目的: 在centos7系统服务器上使用docker容器部署该项目. 3. 方案一:仅使用基 ...
- Docker对于部署来说及其重要
目前的IT环境发生了很大的变化,有big server到vm server到docker,一步步的敏捷快速,更加合理的利用硬件资源,分离不同环境带来的问题,简化部署. 2016过年的这几天就自学了一下 ...
- 使用docker安装部署Spark集群来训练CNN(含Python实例)
使用docker安装部署Spark集群来训练CNN(含Python实例) http://blog.csdn.net/cyh_24/article/details/49683221 实验室有4台神服务器 ...
- Docker 打包 部署
Docker 打包 部署 一贯的开场白,大家好: 开始学习Spring Boot ,同时也再学习 Maven 自动化构建. 项目的部署环境是 Linux 服务器,Docker容器. 之所以写这篇博客 ...
- 从头认识一下docker-附带asp.net core程序的docker化部署
从头认识一下docker-附带asp.net core程序的docker化部署 简介 在计算机技术日新月异的今天, Docker 在国内发展的如火如荼,特别是在一线互联网公司, Docker 的使用是 ...
- 私活利器,docker快速部署node.js应用
http://cnodejs.org/topic/53f494d9bbdaa79d519c9a4a 最近研究了几天docker的快速部署,感觉很有新意,非常轻量级和方便,打算在公司推广一下,解放运维, ...
- 基于Docker一键部署大规模Hadoop集群及设计思路
一.背景: 随着互联网的发展.互联网用户的增加,互联网中的数据也急剧膨胀.每天产生的数据量数以万计,本地文件系统和单机CPU已无法满足存储和计算要求.Hadoop分布式文件系统(HDFS)是海量数据存 ...
- docker stack 部署 mysql 5.6
=============================================== 2018/7/1_第1次修改 ccb_warlock === ...
- docker stack 部署 seafile(http)
=============================================== 2018/5/13_第1次修改 ccb_warlock == ...
随机推荐
- CSS滤镜模糊效果
.blur { -webkit-filter: blur(6px); -moz-filter: blur(6px); -ms-filter: blur(6px); filter: blur(6px); ...
- Linux性能监测:CPU篇
CPU 也是一种硬件资源,和任何其他硬件设备一样也需要驱动和管理程序才能使用,我们可以把内核的进程调度看作是 CPU 的管理程序,用来管理和分配 CPU 资源,合理安排进程抢占 CPU,并决定哪个进程 ...
- js中的class
js中的class 类写法 class SuperClass { constructor(option) { this.a = option; } fn() { console.log(this.b) ...
- 使用Handler类来更新UI
在android里面,我们经常要上网获取一些数据,然后更新UI,但获取数据是要时间的,如果在主线程里面直接使用获取数据的代码的话.整个activity就会卡在那,直至你获取到数据更新完UI才会加载完成 ...
- ubuntu安装Docky 3.0
添加PPA并在命令行安装,执行以下命令: sudo add-apt-repository ppa:ricotz/docky sudo apt-get update sudo apt-get insta ...
- export LD_LIBRARY_PATH 的使用
对linux不是很熟,之前只是听说过可以设置程序共享库位置也就是 使用 “export LD_LIBRARY_PATH” 今天用了用,感觉还挺不错,也很常用. 比如你编译了一个so 而这个so 同时又 ...
- mysql 存储过程 编写注意事项
mysql的存储过程有很多需要注意的地方,一不留神就会出错,可能调试了老半天才发现原因 1 没有return 语句 可以采用leave代替,返回直接使用select语句 比如select 1: 2. ...
- 2-1 gradle安装
因为Gradle是基于JVM的,所以一定要确保本机已经安装了JDK,我们可以通过java -version来验证一下是否已经安装了JDK. bin目录里面是两个可执行文件,一个是Windows下面的 ...
- laravel的模型关联之(一对多的反向)
一对多的反向 一对多的反向就相当于,一个用户有多篇文章,但是在显示文章模型的时候你又想显示这个用户的用户名,但是你只有用户id, 这时候就用到了一对多的反向,你用用户(User)模型里面定义了一对多来 ...
- Ubuntu18.04创建新的系统用户
目标: 1.为测试学习Docker,在虚拟机OS为18.04里,创建一个系统账号,账号名称:docker 2.在/home下有新建username的文件夹 一.建立账号 1.以root账号登录 2.u ...