一. 简介
前面我们已经学习了Docker的相关概念和如何使用简单的Docker命令,这篇文章我们将继续学习Docker的三个重要内容:service、swam、stack。
二. 具体内容
2.1 service
在分布式应用程序中,应用程序的不同部分称为“服务”。服务是一组运行于集群不同结点中可复制的容器的集合。通过服务发现机制,使用该服务的客户端可以透明的访问这些容器。这些容器的分布、升级、故障管理有集群统一管理。一般地,集群内部服务容器地选择由动态DNS实现。服务只能“在容器里生成”。一个服务只运行一个镜像。
使用Docker运行和改变服务非常简单,只需编写一个docker-compose.yml文件,该文件定义Docker容器在生产过程中的行为。
首先创建docker-compose.yml文件,具体内容如下:
version: "3"
services:
web:
# replace username/repo:tag with your name and image details
image: hub.c.163.com/lingd3/friendlyhello:part2
deploy:
replicas: 5
resources:
limits:
cpus: "0.1"
memory: 50M
restart_policy:
condition: on-failure
ports:
- "80:80"
networks:
- webnet
networks:
webnet:
注意上面的镜像是你已经上传到你自己仓库的镜像。
该docker-compose.yml文件告诉Docker执行以下操作:
* 从registry(自己的仓库)中pull我们之前上传的镜像。
* 运行该镜像的五个实例作为调用的服务web,限制每个实例使用最多使用10%的CPU(跨所有内核)和50MB RAM。
* 如果发生故障,立即重新启动容器。
* 将端口80映射到主机web端口80。
* 指示web容器通过称为负载平衡网络共享端口80 webnet
* webnet使用默认设置(这是一个负载平衡的重叠网络)来定义网络
接着运行新的负载均衡程序:
// 集群初始化命令
$ docker swarm init
// 给应用程序指定名字,运行
$ docker stack deploy -c docker-compose.yml getstartedlab
// 看到刚刚推出的五个容器的列表:
$ docker stack ps getstartedlab
// 查看服务id
$ docker service ls
我们可以使用命令行多次执行 curl http://localhost,或者在浏览器中多次访问该URL。无论哪种方式,我们都可以看到容器ID更改,显示负载平衡, 在每个请求中,以循环方式选择五个副本之一进行响应。
当我们想修改实例数时,可以通过修改docker-compose.yml文件里的replicas值来实现。
修改完文件后执行下面命令即可:
//Docker将进行就地更新,无需首先从stack里移除或者杀死任何容器
docker stack deploy -c docker-compose.yml getstartedlab
移除命令如下:
// 从集群中移除应用
$ docker stack rm <appname>
// 移除集群
$ docker swarm leave --force
2.2 swarm
swam是一组运行着Docker并组成集群的机器。组成集群后,我们可以继续执行之前我们学习的Docker命令,只不过现在是在集群管理者管理下在一个集群上运行。在swarm中,机器可以是物理的,也可以是虚拟的。加入swarm后,它们被称为节点。
swarm管理者是swarm中唯一可以执行命令或授权其他机器作为工作人员加入swarm的管理机器(加入的节点不能)。工作机器只是提供能力,没有权力告诉任何其他机器它可以做什么和不能做什么。
在之前的学习中,我们已经能在本地计算机上以单主机模式使用Docker,Docker也可以切换到swarm模式。swarm 模式可以使当前的机器成为swarm管理员。从那时起,Docker将运行正在管理的swarm上执行的命令,而不是在当前的机器。
一个swarm有多个节点组成,可以是物理机也可以是虚拟机。设置swarm主要用到下面两条命令:
// 启用swarm模式,使您当前的机器成为群组管理器
$ docker swarm init
// 在其他机器上运行 ,让他们以工作人员身份加入群集
$ docker swarm join
接下来我们来学习构建集群。
首先,我们需要在本机上安装VirtualBox,然后使用命令创建两个虚拟机:
docker-machine create --driver virtualbox myvm1
docker-machine create --driver virtualbox myvm2
现在我们有两个虚拟机,myvm1和myvm2。使用下面命令查看它们的ip地址和其他信息:
docker-machine ls
下面我们将第一个虚拟机myvm1设为管理员,它将执行Docker命令并认证其他工作者加入swarm;第二个虚拟机myvm2将是一个工作者:
// myvm1 成为一个管理者
docker-machine ssh myvm1 "docker swarm init --advertise-addr <ip>”
// myvm2 成为一个工作者
docker-machine ssh myvm2 "docker swarm join --token <token> <ip>:<port>"
注意,上面的<>里的ip需要使用前面查看的虚拟机的ip地址,port填写2377(官方文档强烈建议Always run docker swarm init and docker swarm join with port 2377 (the swarm management port), or no port at all and let it take the default.),token则填写加入swarm所需的token值,这个值会在设置myvm1管理员时会提示。
在myvm1上执行docker node ls查看节点,因为myvm1是管理员:
docker-machine ssh myvm1 "docker node ls"
到这里我们已经成功创建了一个swarm。值得注意的是,只有swarm管理员myvm1能执行Docker命令,工作者myvm2只能工作。
接着我们在集群上部署应用程序。
首先将之前的docker-compose.yml文件复制到swarm管理员myvm1上,然后像之前单机器那样执行:
$ docker-machine scp docker-compose.yml myvm1:~
//将应用部署到集群上
docker@myvm1:~$docker stack deploy -c docker-compose.yml getstartedlab
使用docker stack ps getstartedlab可以看到容器自动已经在myvm1和myvm2两者之间分布。我们可以从myvm1或myvm2的ip地址来访问应用程序。我们创建的网络已经在两台机器之间共享并负载均衡。
还有两个常用命令:
// 移除应用程序
docker stack rm getstartedlab
//启动虚拟机
docker-machine start myvm1
2.3 stack
stack是能被编排和伸缩的一组相互依赖的服务。单个stack能够定义和协调整个应用程序的功能,尽管非常复杂的应用程序可能希望使用多个stack。
在前面的学习中我们已经多次使用docker stack deploy。其实,stack用 docker-compose.yml 文件描述服务之间的依赖、数据共享、网络等,并且使用 docker stack来管理:
docker-machine scp docker-compose.yml myvm1:~
//在管理员上运行命令进行更新
docker-machine ssh myvm1
docker stack deploy -c docker-compose.yml getstartedlab
// 通过运行docker stack ps <stack>来证明上面的可视化
docker@myvm1:~$ docker stack ps getstartedlab