在容器服务上可以通过
acsrouting 将基于域名的 HTTP 服务暴露出去,而且能够配合健康检查自动的负载均衡和服务发现,当其中一个容器出现问题之后,routing 会自动将健康检查失败的容器从后端摘除,所以能做到自动的服务发现。
然而这个例子是将服务暴露到外网,那么服务间如何通过这种方式做到自动的服务发现和负载均衡呢?容器服务引入了负载均衡功能,您只需要使用以 .local 结尾的域名,并在依赖的服务的 external_links 中增加这个域名, 依赖的服务便可以通过 .local 的域名访问到依赖的服务,并且能够配合健康检查做到自动的服务发现。
实现原理
- 利用了 Docker 1.10 之后支持在容器中做别名的方式,在依赖负载于 restserver.local 的服务的容器中restserver.local 的域名解析到的是 routing 服务的地址,这样可以将 HTTP 请求转发到 routing 的容器,并带上 HOST 为 restserver.local 的请求头。
- routing 会对配置了 aliyun.routing_port_xxx: restserver.local 的服务监听其容器的健康状态并挂载到 HAProxy 的后端,HAProxy 接收到带有 restserver.local HOST 头的 HTTP 请求就能转发到对应了容器了。
优势
- 相对于使用 link 或者 hostname 的基于 DNS 的方式,首先不同客户端对 DNS 缓存的处理不一致会导致服务发现的延迟性,其次 DNS 的方案也只有 round robin,对于微服务的场景是不够用的。
- 而相对于其他的微服务服务发现的解决方案,提供了一个实现无关的服务发现和负载均衡机制,无需 server 端和 client 应用做任何修改即可使用。
- 服务生命周期是解耦的,每个微服务可以采用一个 docker-compose 模板独立部署,更新。相互之间只是通过一个虚拟域名实现动态绑定即可。
编排实例
- [backcolor=transparent]restserver[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]# 模拟 rest 服务
- [backcolor=transparent] image[backcolor=transparent]:[backcolor=transparent] nginx
- [backcolor=transparent] labels[backcolor=transparent]:
- [backcolor=transparent] aliyun[backcolor=transparent].[backcolor=transparent]routing[backcolor=transparent].[backcolor=transparent]port_80[backcolor=transparent]:[backcolor=transparent] restserver[backcolor=transparent].[backcolor=transparent]local[backcolor=transparent] [backcolor=transparent]# 使用 local 的域名,只有集群内的容器可以访问这个域名
- [backcolor=transparent] aliyun[backcolor=transparent].[backcolor=transparent]scale[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"2"[backcolor=transparent] [backcolor=transparent]# 扩展出两个实例,模拟负载均衡
- [backcolor=transparent] aliyun[backcolor=transparent].[backcolor=transparent]probe[backcolor=transparent].[backcolor=transparent]url[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"http://container:80"[backcolor=transparent] [backcolor=transparent]# 定义容器的健康检查策略是 http,端口是 80
- [backcolor=transparent] aliyun[backcolor=transparent].[backcolor=transparent]probe[backcolor=transparent].[backcolor=transparent]initial_delay_seconds[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"2"[backcolor=transparent] [backcolor=transparent]# 健康检查在容器起来之后两秒之后再检查
- [backcolor=transparent] aliyun[backcolor=transparent].[backcolor=transparent]probe[backcolor=transparent].[backcolor=transparent]timeout_seconds[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"2"[backcolor=transparent] [backcolor=transparent]# 健康检查超时时间,如果两秒还没返回认为不健康
- [backcolor=transparent]restclient[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]# 模拟 rest 服务消费者
- [backcolor=transparent] image[backcolor=transparent]:[backcolor=transparent] registry[backcolor=transparent].[backcolor=transparent]aliyuncs[backcolor=transparent].[backcolor=transparent]com[backcolor=transparent]/[backcolor=transparent]acs[backcolor=transparent]-[backcolor=transparent]sample[backcolor=transparent]/[backcolor=transparent]alpine[backcolor=transparent]:[backcolor=transparent]3.3
- [backcolor=transparent] command[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"sh -c 'apk update; apk add curl; while true; do curl --head restserver.local; sleep 1; done'"[backcolor=transparent] [backcolor=transparent]#访问 rest 服务,测试负载均衡
- [backcolor=transparent] tty[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]true[backcolor=transparent]
- [backcolor=transparent] external_links[backcolor=transparent]:[backcolor=transparent]
- [backcolor=transparent] [backcolor=transparent]-[backcolor=transparent] [backcolor=transparent]"restserver.local"[backcolor=transparent] [backcolor=transparent]#指定 link 的服务的域名。请确保您设置了 external_links,否则访问会失败。
然后,通过如下的 restclient 服务的日志,您可以看到 restclient 的 curl 的 http 请求被路由到不同的 rest 服务的容器上了,容器 ID 分别为 053cb232fdfbcb5405ff791650a0746ab77f26cce74fea2320075c2af55c975f 和b8c36abca525ac7fb02d2a9fcaba8d36641447a774ea956cd93068419f17ee3f。
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066803626Z[backcolor=transparent] [backcolor=transparent]Server[backcolor=transparent]:[backcolor=transparent] nginx[backcolor=transparent]/[backcolor=transparent]1.11[backcolor=transparent].[backcolor=transparent]1
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066814507Z[backcolor=transparent] [backcolor=transparent]Date[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]Fri[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]01[backcolor=transparent] [backcolor=transparent]Jul[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent] [backcolor=transparent]06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49[backcolor=transparent] GMT
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066821392Z[backcolor=transparent] [backcolor=transparent]Content[backcolor=transparent]-[backcolor=transparent]Type[backcolor=transparent]:[backcolor=transparent] text[backcolor=transparent]/[backcolor=transparent]html
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066829291Z[backcolor=transparent] [backcolor=transparent]Content[backcolor=transparent]-[backcolor=transparent]Length[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]612
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066835259Z[backcolor=transparent] [backcolor=transparent]Last[backcolor=transparent]-[backcolor=transparent]Modified[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]Tue[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]31[backcolor=transparent] [backcolor=transparent]May[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent] [backcolor=transparent]14[backcolor=transparent]:[backcolor=transparent]40[backcolor=transparent]:[backcolor=transparent]22[backcolor=transparent] GMT
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066841201Z[backcolor=transparent] [backcolor=transparent]ETag[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"574da256-264"
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066847245Z[backcolor=transparent] [backcolor=transparent]Accept[backcolor=transparent]-[backcolor=transparent]Ranges[backcolor=transparent]:[backcolor=transparent] bytes
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]49.066853137Z[backcolor=transparent] [backcolor=transparent]Set[backcolor=transparent]-[backcolor=transparent]Cookie[backcolor=transparent]:[backcolor=transparent] CONTAINERID[backcolor=transparent]=[backcolor=transparent]053cb232fdfbcb5405ff791650a0746ab77f26cce74fea2320075c2af55c975f[backcolor=transparent];[backcolor=transparent] path[backcolor=transparent]=/
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.080502413Z[backcolor=transparent] HTTP[backcolor=transparent]/[backcolor=transparent]1.1[backcolor=transparent] [backcolor=transparent]200[backcolor=transparent] OK
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082548154Z[backcolor=transparent] [backcolor=transparent]Server[backcolor=transparent]:[backcolor=transparent] nginx[backcolor=transparent]/[backcolor=transparent]1.11[backcolor=transparent].[backcolor=transparent]1
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082559109Z[backcolor=transparent] [backcolor=transparent]Date[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]Fri[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]01[backcolor=transparent] [backcolor=transparent]Jul[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent] [backcolor=transparent]06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50[backcolor=transparent] GMT
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082589299Z[backcolor=transparent] [backcolor=transparent]Content[backcolor=transparent]-[backcolor=transparent]Type[backcolor=transparent]:[backcolor=transparent] text[backcolor=transparent]/[backcolor=transparent]html
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082596541Z[backcolor=transparent] [backcolor=transparent]Content[backcolor=transparent]-[backcolor=transparent]Length[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]612
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082602580Z[backcolor=transparent] [backcolor=transparent]Last[backcolor=transparent]-[backcolor=transparent]Modified[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]Tue[backcolor=transparent],[backcolor=transparent] [backcolor=transparent]31[backcolor=transparent] [backcolor=transparent]May[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent] [backcolor=transparent]14[backcolor=transparent]:[backcolor=transparent]40[backcolor=transparent]:[backcolor=transparent]22[backcolor=transparent] GMT
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082608807Z[backcolor=transparent] [backcolor=transparent]ETag[backcolor=transparent]:[backcolor=transparent] [backcolor=transparent]"574da256-264"
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082614780Z[backcolor=transparent] [backcolor=transparent]Accept[backcolor=transparent]-[backcolor=transparent]Ranges[backcolor=transparent]:[backcolor=transparent] bytes
- [backcolor=transparent]internal[backcolor=transparent]-[backcolor=transparent]loadbalance_restclient_1 [backcolor=transparent]|[backcolor=transparent] [backcolor=transparent]2016[backcolor=transparent]-[backcolor=transparent]07[backcolor=transparent]-[backcolor=transparent]01T06[backcolor=transparent]:[backcolor=transparent]43[backcolor=transparent]:[backcolor=transparent]50.082621152Z[backcolor=transparent] [backcolor=transparent]Set[backcolor=transparent]-[backcolor=transparent]Cookie[backcolor=transparent]:[backcolor=transparent] CONTAINERID[backcolor=transparent]=[backcolor=transparent]b8c36abca525ac7fb02d2a9fcaba8d36641447a774ea956cd93068419f17ee3f[backcolor=transparent];[backcolor=transparent] path[backcolor=transparent]=/