准备工作

  • 安装1.13或者更高版本的docker。
  • 安装Docker Compose。Mac和window的Docker桌面版已经安装好,可以直接使用。在Linux上直接安装即可。在没有Hyper-v的window10系统中,请使用Docker Toolbox。
  • 已阅读第一部分中的概念。
  • 通过第二部分学会了如何创建一个容器。
  • 确保已经向仓库中提交了firendlyhello镜像,我们在本文中将使用这个已分享的公共镜像。
  • 确保你的镜像已经部署成了一个容器。执行命令docker run -p 4000:80 username/repo:tag,使用你的用户名(username)、仓库名(repo)和标签名(tag)对应替换即可。然后使用http://localhost:4000进行访问。

引言

在第三部分中,将拓展我们的应用,并开启负载均衡。为了完成这些,我们需要将应用提升到分布式应用这一级:服务。
- 堆栈(Stack)
- 服务(Services 当前层级)
- 容器(Container 第二部分描述)
-

关于服务

在一个分布式应用中,应用的不同部分被称之为“服务”。例如,假设你有一个视频分享网站,它可能包含一个用于存储应用数据的数据库,一个用于在后台对用户上传视频进行转码的服务,一个用于前端页面展示的服务,等等。

服务其实就是用于生产的一系列容器。一个服务只运行一个镜像,但是通过编码配置哪些端口在运行中会被使用、应该运行多少个副本以便服务具有相应的吞吐量等等。拓展服务会更改容器运行的实例个数,因此也会为服务分配更多的计算资源。

幸运的是对于Docker平台来说定义、运行和拓展一个服务是非常容易的,只需要编写一个docker-compose.yml文件即可。

第一个docker-compose.yml文件

docker-compose.yml文件定义了docker容器在生产环境中的一些行为。

docker-compose.yml

在任意目下创建并保存docker-complse.yml文件。确保你在第二部分创建的镜像已经被推送到了镜像仓库。将文件中的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:
      - "4000:80"
    networks:
      - webnet
networks:
  webnet:

docker-compose.yml文件主要告诉docker做以下事情:
- 拉取在第二部分上传的镜像
- 运行5个名为web的服务实例,并限制每个实例最大使用10%的CPU资源和50MB的运行内存。
- 当容器异常停止时及时重启。
- 使用外部的4000端口映射web服务的80端口。
- 指定web服务的所有容器通过一个名为webnet的负载均衡网络共享80端口(在内部,所有的容器均运行在一个端口号为80的临时端口上)。
- 指定webnet网络为默认配置(就是一个负载均衡网络)。

运行新的负载均衡应用

在运行docker stack deploy命令之前我们需要执行下面的命令:

docker swarm init

注意:我们将在第四部分中学习该指令的意思。如果你不执行docker swarm init命令,你将看到一个错误信息“this node is not a swarm manager”(这个节点不是swarm的管理端)。

现在我们开始运行这个应用。你需要给应用去个名字,这里我们使用getstartedlab:

docker stack deploy -c docker-compose.yml getstartedlab

我们的单一服务堆栈是在一个主机上部署了5个容器实例。下面让我们来查看一下。

在我们的应用中获取一个服务的ID:

docker service ls

查看web服务的相关输出,相关信息均以应用名开头。如果你使用案例中相同的应用名,那么输出项的名称为getstartedlab_web。服务的ID、副本数量、镜像名称以及暴露端口均以列表的形式展示。

服务中的一个运行中的容器我们称之为任务,每个任务都会分配一个数字递增的唯一ID,直到达到docker-compose.yml中定义的replicas数量。可以使用下面的指令来展示服务的所有任务:

docker service ps getstartedlab_web

如果您列出系统上的所有容器,任务也会显示,但不会针对服务过滤:

docker container ls -q

你可以多次执行curl -4 http://localhost:4000指令,或者在浏览器中访问这个地址并每隔一会儿进行刷新。

hello world in browser

无论哪种方式,容器ID都会发生变化,从而证明使用了负载均衡;对于每个请求,都采用轮询的方式选择5个任务中的一个来响应。 容器ID与上一条命令(docker container ls -q)的输出匹配。

在Win10上运行

Windows 10 PowerShell应该已经可以使用curl,但如果没有,你可以使用类似Git Bash这样的Linux模拟终端运行,或者下载wget类似的Window工具。

为什么会出现慢响应?

这取决于你环境的网络配置,容器最多可能需要30秒才能响应HTTP请求。这并不是因为docker和swarm的性能,而是因为到目前为止我们还没有部署redis服务。应用中的访问计数器不能工作也是因为这个原因,我们还没有添加响应的服务来保存数据。

拓展应用

你可以通过修改docker-compose.yml中的replicas的值来修改应用,然后通过docker stack deploy指令来重新运行:

docker stack deploy -c docker-compose.yml getstartedlab

Docker采用的本地更新(in-place)机制,不需要关闭整个服务栈或者关闭其他容器。

现在,再次运行docker container ls -q查看已部署的实例。如果你增加relicas的值,就会开启更多的任务,所以会运行更多的容器。

移除应用和swarm

  • 使用docker stack rm 移除应用:
docker stack rm getstartedlab
  • 移除swarm:
docker swarm leave --force

使用docker建立可拓展的应用是非常容易的。你已经朝着如何在生产环境中运行容器迈出了一大步,下一步你将学会如何在真正的docker集群机器中运行应用。

注意:像这样编写的compose文件适用于使用docker定义的应用,你可以选择docker云、docker商业版等工具上传到云端。

——————————————————————————
行路不知花开处,蓦然回首芷兰香。