内容简介:在使用docker-compose 是一个读取特定格式的 yaml 文件并将其转换为
在使用 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 的部署方式
- Python Web 部署方式大全
- 两种方式免费部署HTTPS
- SpringBoot实战分析-Tomcat方式部署
- Tomcat部署项目的几种常见方式
- Ant Design Pro 的 Docker 部署方式
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
零基础学Minecraft编程
Martin O''Hanlon、David Whale / 中文Minecraft Wiki翻译团队 / 人民邮电出版社 / 2015-9-7 / 79
在你体验Minecraft冒险的同时,学习宝贵的编程技能! 如果你很喜欢玩Minecraft,却被游戏中的建造耗费大量时间而困扰,并且你想要对游戏添加一些改动,那么本书就是为你而设计的。在游戏中,你可以学习许多Python编程技能,在PC、Mac或树莓派上与游戏进行互动。这些冒险不仅局限在虚拟世界——你也将会学习如何将Minecraft与电子元件连接起来,这样你的Minecraft世界就能够......一起来看看 《零基础学Minecraft编程》 这本书的介绍吧!