您的位置:首页 > 运维架构 > Docker

[docker swarm] 从单容器走向负载均衡部署

2019-10-11 16:24 1456 查看

背景

    之前写过<<docker-compose真香>> 和《docker-compose、docker stack前世今生》两篇博客, 回顾一下思路:

① docker-compose是docker引擎之上的容器编排工具,Python语言编写; docker stack 是docker引擎原生支持的容器编排技术(Go语言)

② 两者都支持最近docker-compose.yml 版本3容器编排定义文件,部分指令有差异。

 昨天生产环境 .NetCore程序突然爆出错误(1个月前也出现过), 先抛出来给网友看下:

exception happen when [request for 2246:5ead5a42f80e1000100000005d99f945] : System.InvalidOperationException: Stack empty.
at System.Collections.Generic.Stack`1.ThrowForEmptyStack()
at System.Collections.Generic.Stack`1.Pop()
at NLog.NestedDiagnosticsContext.StackPopper.System.IDisposable.Dispose()
at Microsoft.Extensions.Logging.Logger.Scope.Dispose()
at Microsoft.Extensions.Http.Logging.LoggingScopeHttpMessageHandler.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.FinishSendAsyncBuffered(Task`1 sendTask, HttpRequestMessage request, CancellationTokenSource cts, Boolean disposeCts)

 重启容器之后恢复正常 ,( 报错Stack Empty:还比较棘手, 稍后再开篇深究)。

 本次借这个机会上手docker swarm

头脑风暴

之前《docker-compose真香》 编排了3个独立的容器,对应docker-compose.yml 文件中3个service,容器之间默认通过service name相互访问, , 如下图

docker-compose定义的service 与docker引擎原生定义的service还不一样:

 docker service 可以理解为 发布到生产环境时某组容器的预期状态:当您将service部署到群集,群集manager 接受你的服务定义,并认定为是容器的预期状态;然后将服务安排在群集中可用节点上v,作为副本任务;任务在群集的节点上彼此独立运行。

Swarm never creates individual containers like we did in the previous step of this tutorial; instead, all Swarm workloads are scheduled as services, which are scalable groups of containers with added networking features maintained automatically by Swarm. Furthermore, all Swarm objects can and should be described in manifests called stack files; these YAML files describe all the components and configurations of your Swarm app, and can be used to easily create and destroy your app in any Swarm environment.

Swarm 将所有工作负载安排为服务,这些服务是可伸缩的容器组,具有由Swarm自动维护的附加网络功能。此外,所有Swarm对象都可以并且应该在称为堆栈文件的清单中进行描述。这些YAML文件描述了Swarm应用程序的所有组件和配置,可用于在任何Swarm环境中轻松创建和销毁您的应用程序。

下面演示在单节点上部署 带负载均衡集群应用:

receiver ,app 服务均使用2个示例,每个示例一旦崩溃则重启; 指示所有服务均使用名为webnet的负载平衡网络; 同时利用默认的   docker_gwbridge 网桥访问宿主机。

为啥不直接多节点部署?

上面这个应用,还需要考虑 有状态的Redis服务,暂时没实现。

部署目标:

操作步骤

 ① 初始化swarm

docker swarm init

 

 ② 使用docker stack 部署

    docker stack 也使用类似于docker-compose.yml 容器编排文件,上文也提高过,部署指令各自有差异。

   上文也提到过,适用于docker-compose工具的yml 文件若迁移到 docker stack, 需要做一点修改。

其中我一直吐槽的,docker stack 默认不能加载 同目录下的.env 环境变量文件, 经过搜索,有一个变通方法,这样你的docker-compose.yml  大概率不需要做大的修改。

docker stack deploy -c <(docker-compose -f docker-stack.yml -f production.yml config) eqidstack

 

嗯,谷歌大发好。

下面给出适用于生产环境的附加yml文件:

version: "3.7"

services:
proxy:
networks:
- webnet
receiver:
deploy:
replicas: 2
restart_policy:
condition: on-failure
networks:
- webnet
volumes:
- type: bind
source: /home/huangjun/eqidmanager/receiver.secrets.json
target: /app/appsettings.secrets.json
app:
deploy:
replicas: 2
restart_policy:
condition: on-failure
networks:
- webnet
volumes:
- type: bind
source: /home/huangjun/eqidmanager/appsettings.secrets.json
target: /app/appsettings.secrets.json
networks:
webnet:

更多的部署指令,请参考:

③  三个服务已经在单机节点上部署

#docker stack ls:
NAME                SERVICES            ORCHESTRATOR
eqidstack           3                   Swarm

#docker service ls:
ID                  NAME                 MODE                REPLICAS            IMAGE                        PORTS
bld7jkfi5ony        eqidstack_app        replicated          2/2                 12205599/eqidmanager:v2.3
98u6biliwumw        eqidstack_proxy      replicated          1/1                 nginx:latest                 *:80->80/tcp, *:8080->8080/tcp
g9qy4p2gd2uh        eqidstack_receiver   replicated          2/2                 12205599/eqidreceiver:v2.3

完成以上操作,这只麻雀虽小的项目SLA应该进一步提升了。

后续集群部署,需要考虑的磁盘,网络、 有状态 知识点更多, 请关注官网。 

https://docs.docker.com/get-started/part4/

https://docs.docker.com/engine/swarm/how-swarm-mode-works/services/

https://docs.docker.com/compose/compose-file/

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: