10x系列之Clay.io的服务发现


【编者的话】Clay.io的Zoli Kahan撰写了“10X”系列博文,分享如何只使用一个很小的团队支撑Clay.io的大规模应用。本文是整个系列的第四篇,介绍如何构建一个服务发现系统。

synapse.png


架构

面向服务的架构是构建绝大多数产品的最可迭代和可用的软件配置之一。这些系统也遇到过很多问题,其中最大的问题可能就是服务发现问题。服务发现实际定义了你的服务如何与其它服务通信。Docker里也有这个问题。如果你不知道我们如何部署Docker,请参看Docker at Clay.io中文翻译)。

教程

Synapse(https://github.com/claydotio/synapse)是一个动态配置本地HAproxy的后台程序。HAproxy负责在集群内将请求转发到服务,它会根据配置文件的定义,寻找Amazon EC2(或其它)服务。我们用的是ec2tag,可以很容易地通过标签化服务器将其添加到集群。

HAProxy

让我们从服务入手。服务之间通过本地的HAProxy实例互相通信。因为服务运行在Docker内部,我们需要为服务指定宿主IP在某个特定端口寻找服务。

我们使用Ansible将本地IP和端口传给运行在机器上的服务。
SERVICE_API=http://{ ansible_default_ipv4.address }:{ service_port }   

对于要使用其它服务的服务,只需要简单地调用IP/端口。这里的关键点是IP是本地机器的IP,它可以被HAProxy处理。我们发布了一个HAProxy docker容器,它监控挂载着的配置文件,在有变化时自动更新:
https://github.com/claydotio/haproxy
docker run
--restart always
--name haproxy
-v /var/log:/var/log
-v /etc/haproxy:/etc/haproxy
-d
-p 50001:50001
-p 50002:50002
-p 50003:50003
-p 50004:50004
...
-p 1937:1937
-t clay/haproxy

我们默认在/etc/haproxy 使用noop config,它会挂载到Docker容器中并监控变化。我们也会将相同的HAproxy config挂载到Synapse容器。需要注意的是,如果这个容器关闭了,机器上的所有服务就不会被其它服务发现。因此,我们给容器也分配了另外的端口以供未来的新服务使用(因为无法被动态分配)。

Synapse

好了,现在开始搭建Synapse。

Synapse的运行很简单(归功于公共Docker容器库)。
docker run
--restart always
--name synapse
-v /var/log:/var/log
-v /etc/synapse:/etc/synapse
-v /etc/haproxy:/etc/haproxy
-e AWS_ACCESS_KEY_ID=XXX
-e AWS_SECRET_ACCESS_KEY=XXX
-e AWS_REGION=XXX
-d
-t clay/synapse
synapse -c /etc/synapse/synapse.conf.json

注意我们如何在容器里挂载Synapse config以及HAproxy config。HAProxy配置就是上文提到的noop config(因为其会由Synapse自动生成),我们来看看如何配置Synapse。

配置Synapse有些难,因为文档写得不是很好。如下是示例配置,可以解释所有文档里缺失的信息:
{
"services": {
"myservice": {
  "discovery": {
    // use amazon ec2 tags
    "method": "ec2tag",
    "tag_name": "servicename",
    "tag_value": "true",
    // if this is too low, Amazon will rate-limit and block requests
    "check_interval": 120.0
  },
  "haproxy": {
    // This is the port other services will use to talk to this service
    // e.g. http://10.0.1.10:50003
    "port": 50003,
    "listen": [
      "mode http"
    ],
    // This is the port that the service exposes itself
    "server_port_override": "50001",
    // This is our custom (non-documented) config for our backup server
    // See http://zolmeister.com/2014/12/10x-docker-at-clay-io.html
    // for details on how our zero-downtime deploys work
    "server_backup_port": "50002",
    "server_options": "check"
  }
}
},
// See the manual for details on parameters:
// http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
"haproxy": {
// This is never used because HAProxy runs in a separate container
// Reloads happen automatically via the file-watcher
"reload_command": "echo noop",
"config_file_path": "/etc/haproxy/haproxy.cfg",
"socket_file_path": "/var/haproxy/stats.sock",
"do_writes": true,
"do_reloads": true,
"do_socket": false,
// By default, this is localhost, however because HAProxy is running
// inside of a container, we need to expose it to the host machine
"bind_address": "0.0.0.0",
"global": [
  "daemon",
  "user    haproxy",
  "group   haproxy",
  "chroot  /var/lib/haproxy",
  "maxconn 4096",
  "log     127.0.0.1 local0",
  "log     127.0.0.1 local1 notice"
],
"defaults": [
  "log            global",
  "mode           http",
  "maxconn        2000",
  "retries        3",
  "timeout        connect 5s",
  "timeout        client  1m",
  "timeout        server  1m",
  "option         redispatch",
  "balance        roundrobin",
  "default-server inter 2s rise 3 fall 2",
  "option         dontlognull",
  "option         dontlog-normal"
],
"extra_sections": {
  "listen stats :1937": [
    "stats enable",
    "stats uri /",
    "stats realm Haproxy Statistics"
  ]
}
}
}

结论

特别感谢Airbnb开源了他们的工具,这使得我们可以以简单可扩展的方式搭建服务发现系统。对于没有使用Amazon EC2的人,可以使用Zookeeper watcher(我们没有用到),或者即将可以使用的etcd watcher

一旦代码被合并,我们可能会选择使用Nerveetcd替代EC2标签,来发布服务。以下etcd示例的Docker信息仅供参考:
curl https://discovery.etcd.io/new?size=3
docker run
--restart always
--name etcd
-d
-p 2379:2379
-p 2380:2380
-v /opt/etcd:/opt/etcd
-v /var/log:/var/log
-v /etc/ssl/certs:/etc/ssl/certs
quay.io/coreos/etcd:v2.0.0
-data-dir /opt/etcd
-name etcd-unique-name
-listen-client-urls http://0.0.0.0:2379
-listen-peer-urls http://0.0.0.0:2380
-advertise-client-urls http://localhost:2379
-initial-advertise-peer-urls http://localhost:2380
-discovery https://discovery.etcd.io/XXXXXXXXXXXX
-initial-cluster-token cluster-token-here

本系列的其它文章

1. 10x系列之Clay.io的架构
2. 10x系列之Clay.io是如何处理日志的
3. 10x系列之Docker在Clay.io

原文链接:10x: Service Discovery at Clay.io(翻译:崔婧雯 校对:李颖杰)

===========================
译者介绍
崔婧雯,现就职于VMware,高级软件工程师,负责桌面虚拟化产品的质量保证工作。曾在IBM WebSphere业务流程管理软件担任多年系统测试工作。对虚拟化,中间件技术有浓厚的兴趣。

0 个评论

要回复文章请先登录注册