使用Docker的Swarm模式创建集群环境

这篇文章是关于第二个dwango 2016年降临节的第九天的。

我在这个圣诞节倒数日里是少数几个仍在职的员工之一。平时我主要负责对前端工程师工作,包括在Niconico直播和Webpack、TypeScript等方面的使用。

我最近对使用Docker和Swarm进行集群和监控很感兴趣,想要尝试一下。

首先,Swarm是什么?

这是在 Docker 1.12 版本中添加的 Docker 引擎集群管理功能。与之前存在的 Docker Swarm 是不同的,也被称为 swarm mode。请参考官方网页了解更多详情。

我这次想做的事情

    • DockerのサービスとしてWebサーバー、APIサーバーを建てる

 

    それらのログを収集して、よしなに表示してくれる環境を作る

准备服务器

在Docker v1.12中,需要64-bit的Linux内核版本不低于3.10。因此,我们选择了Centos 7系列作为本次服务器操作系统。
恰好在Conoha VPS中,已经准备了64位Centos 7.2的模板,我们将使用这个模板。

本次我们准备了一个管理用的管理器实例和两个工作实例。准备阶段的Ansible Playbook。

サーバーが建った図

这一次没有使用,但是Conoha的VPS拥有私人网络功能,非常方便。实际上当我需要创建并运行一些东西时,我非常想要使用它。

准备进行聚类分析

将镜像推送到Docker Hub。

我在DockerHub上预先上传了我想要运行的图像。对于私有图像,也可以考虑使用Google容器注册表等。由于这只是一个测试,所以我只是简单地将API服务器和Web服务器这两种图像上传到了Docker Hub上。

设置Docker的Swarm

经理的设置

选择一台作为 Swarm 管理器(管理实例)的服务器,并在该实例上输入以下命令。

docker swarm init --advertise-addr XXX.XXX.XXX.XXX

由於稍後會使用到此處顯示的令牌,因此請將其複製保存。

还需要创建用于Web实例和Api实例之间通信的网络。本次将创建两个网络,一个是服务网络,另一个是状态监控网络。请注意设置子网以避免对其他系统产生影响。

docker network create --driver overlay --subnet 10.0.2.0/24 service
docker network create --driver overlay --subnet 10.0.3.0/24 monitoring

工人的安装

同样,我们也要设置工作人员。使用刚才在经理设置中显示的令牌。

docker swarm join --token YYYYYYY XX.XX.XX.XX:2377

您可以回到管理者,并使用以下命令来确认已成功将其集成到集群中。

docker node ls
swarm

启动API、Web服务

docker service create --replicas 1 --env NODE_ENV=production --env PORT=80 --name api --network service --constraint 'node.role == worker' viviljp/test-api
docker service create --replicas 1 --env NODE_ENV=production --env PORT=3000 --publish 3000:3000  --name web --network service --constraint 'node.role == worker' viviljp/test-web

过了一会儿,您就会发现服务已经启动了。

docker service ls 
sevice

进行缩放

由於組建了折角群集,因此我們也將嘗試進行擴展。
作為經理,您可以通過輸入以下命令來指示進行擴展。

docker service scale web=3
3台に増やした

可以使用以下命令来查看每台机器分配了多少个实例。

ノードの割当
docker service ps web

已经关闭的实例仍然显示为“Shutdown”状态。这里可以看到(由于有意停止了web2服务器两次),Web.1实例已经重新启动了两次。

在Docker Swarm中,有一个名为Ingress Network的内部覆盖网络,它具有方便的功能,即使访问一个服务器,也会自动进行内部路由。(在本次架构中,连接到Web和API实例的服务也是覆盖网络。)

因此,即使建立了多个实例,它也会自动进行负载均衡。我认为这真是个方便的时代。

监视

只是部署服务还不能保证它是否正常运行,这让人感到担心。在这里,我们也希望对每个容器进行监控。

在每个节点上设置用于资源确认的工具。

我们使用了cAdvisor作为资源监控工具。

docker service create --network=monitoring --mode global --name cadvisor \
  --mount type=bind,source=/,target=/rootfs,readonly=true \
  --mount type=bind,source=/var/run,target=/var/run,readonly=false \
  --mount type=bind,source=/sys,target=/sys,readonly=true \
  --mount type=bind,source=/var/lib/docker/,target=/var/lib/docker,readonly=true \
  google/cadvisor

在这种情况下,我们希望每个节点都有一台服务器,所以我们使用全局模式进行部署。这种模式可以确保每台服务器都配置了一个实例,虽然不支持扩展。

虽然只是这样也可以进行监视,但是进入每台服务器进行检查很麻烦,而且我们希望在一个地方集中监视。

在管理节点上设置监控工具。

我会为经理设立一个用于监视资源监控工具的工具。

这次我打算尝试使用 Prometheus。

docker service create --publish 9090:9090 --network=monitoring --name prometheus \
  --mount type=bind,source=/tmp/prometheus.yml,target=/etc/prometheus/prometheus.yml,readonly=false \
  --constraint 'node.role == manager' prom/prometheus
global:
  external_labels:
      monitor: 'service'
scrape_configs:
  - job_name: 'docker'
    scrape_interval: 5s
    dns_sd_configs:
      - names: ['tasks.cadvisor']
        type: 'A'
        port: 8080  
prometheus.png

可以获取到各种信息,如CPU使用率、内存使用率和网络状况等。

将其可视化得更易于阅读

用Prometheus获取的信息需要逐个确认,但为了整体确认,使用像Grafana这样的工具进行可视化也是一个好选择。

docker service create --constraint 'node.role == manager' --publish 3001:3000 grafana/grafana

默认情况下使用3000端口,但是由于和Web实例的端口冲突,所以进行了调整…如果事先做好端口规划就好了,现在真后悔。

如果进行适当配置,Grafana可以默认使用Prometheus作为数据源。

datasource

写有localhost的地方将会变成管理器实例的IP地址。

只需要按照您喜欢的方式自己调整仪表板的外观,您就可以创建出像下面的图像一样最易读的监控工具。

dashboard.png

如果没有指定服务名称,Docker会为您分配一个随意的名称。

由于Grafana和Prometheus似乎具备发送警报的功能,因此当错误日志堆积时,我们可以轻松地构建系统,将通知发送到Slack!这对工程师来说非常有用。

使用elasticsearch和fluentd进行日志收集可能也是一种有趣的尝试。

最后

Docker近期宣布收购存储服务Infinit,这意味着未来我们将更频繁地接触到Docker。作为前端工程师,我希望能不断挑战新的领域,而不仅仅局限于自己熟悉的领域。

明天是D3vel0pper先生。

bannerAds