原文地址
docker run -p 80:80 username/repo:tag
,然后访问:http://localhost/
。在这一章,我们扩展应用并开启负载均衡。要实现这些,必须去分布式应用层级架构的上一层:service。
在分布式应用程序中,应用程序的不同部分被称为“服务”。例如,如果有一个视频共享网站,它可能包括一个用于将应用程序数据存储在数据库中的服务,一个在用户上传东西后在后台进行视频转码的服务,一个用于前端页面的服务等等。
服务实际上只是“生产中的容器”。每个服务只运行一个映像,但它编码了镜像的运行方式 - 应该使用哪个端口,容器应运行多少个副本以满足性能要求等等。 伸缩服务可以更改运行该软件的容器实例的数量,从而为进程中的服务分配更多计算资源。
定义、运行和伸缩 Docker 平台的服务很简单,只需要写一个 docker-compose.yml
文件。
docker-compose.yml
文件docker-compose.yml
文件是 YAML 格式的,定义了生产中的 Docker 容器的表现。
docker-compose.yml
文件放在哪了都行。确保上一章节中创建的镜像已经上传到 registry 中了,并且用这个镜像信息替换下面文件中的 username/repo:tag
。
version: "3"
services:
web:
# 用你的镜像信息替换 `username/repo:tag`
image: username/repo:tag
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 下载镜像。
在一个名为 web 的 service 中运行 5 个实例,限制每个实例最多使用 10% 的 CPU(在所有核心上),最多使用 50 MB 内存。
如果容器挂掉,立刻重启。
将容器的 80 端口映射到宿主机的 80 端口。
指示 web 服务的容器通过名为 webnet 的负载均衡网络共享 80 端口。在内部,容器本身通过临时端口发布到 web 服务的 80 端口。
用默认设置(load-balanced overlay network)来定义 webnet 网络。
在使用 docker stack deploy
命令之前首先运行:
docker swarm init
注意:在下一章节就会知道这句话的意思。如果没有运行 docker swarm init
,会报错 this node is not a swarm manager
。
现在可以运行了。需要为应用程序指定名字,这里是 getstartedlab:
docker stack deploy -c docker-compose.yml getstartedlab
我们唯一的 service stack 正在运行 5 个我们之前部署的镜像的实例。下面来检查一下。
获取我们应用中的 service 的 ID:
docker service ls
查找输出中以你的应用程序名称作为前缀的 web 服务。 如果其命名与此示例中的相同,则服务名称为 getstartedlab_web。 此外还列出了 service ID 以及副本数量,镜像名称和暴露的端口号。
服务中运行的每一个容器叫做一个任务 task。每个任务都有独立的、数值增加的 ID,和 docker-compose.yml
文件中定义的副本个数相关。列出服务中的 task:
docker service ps getstartedlab_web
如果您只列出了系统中的所有容器,任务也显示出来,尽管这不是按服务过滤的:
docker container ls -q
可以在一行运行多次 curl -4 http://localhost
,或在浏览器中打开这个 URL 并刷新几次。
不管怎样,容器的 ID 都会变化,证明负载均衡工作了;对于每个请求,这 5 个 task 中的一个会被选中(通过 round-robin 方式)用来响应。容器的 ID 和之前命令的输出一致(docker container ls -q
)。
Windows 10 的 PowerShell 应该具备 curl 功能,如果没有的话,你可以使用 Linux 终端模拟器(比如 Git BASH),或下载 wget。
如果响应很慢?
根据你的环境的网络配置,容器响应一个 HTTP 请求可能会花费 30 秒。这并不代表 Docker 或 swarm 的性能,而是我们稍后在本教程中讨论的未满足的 Redis 依赖项。 因为同样的原因,访客计数器也不能工作,我们还没有添加服务来保存数据。
可以通过改变 docker-compose.yml
文件的 replicas
的值来扩展应用。保存变更后需要重新运行 docker stack deploy
命令:
docker stack deploy -c docker-compose.yml getstartedlab
Docker 执行一个就地更新,不需要先停下 stack 或杀死任何容器。
现在,再次运行 docker container ls -q
来查看重新配置了的部署的实例。如果增大了 replicas,会更多运行的 task,因此启动更多的容器。
docker stack rm
命令关闭应用:docker stack rm getstartedlab
docker swarm leave --force
通过 Docker 很容易启动和伸缩应用。你已经朝着学习如何在生产中运行容器迈出了一大步。 接下来,将学习如何将这个应用程序作为 Docker 机器集群上的真正集群运行(how to run this app as a bonafide swarm on a cluster of Docker machines)。
注意:像这样的 Compose 文件用来定义使用 Docker 的应用,可以被上传到使用 Docker Cloud 的云服务商,或使用 Docker 企业版的硬件或云服务商。
虽然通过 docker run
启动容器很简单,但是生产中容器的使用方式是当做服务 service 来运行。service 在 Compose 文件中编码了容器的表现,这个文件可以用来伸缩、限制和部署应用。对 service 的变更可以通过再次运行启动服务的命令 docker stack deploy
就地生效。
这一章的命令:
docker stack ls # 列出 stacks 或应用
docker stack deploy -c # 运行指定的 Compose 文件
docker service ls # 列出运行的、关联到应用的 service
docker service ps # 列出关联到应用的任务 task
docker inspect # 检查 task 或 container
docker container ls -q # 列出容器的 ID
docker stack rm # 关闭应用
docker swarm leave --force # 从管理端关闭 swarm 的一个节点