背景与技术选择

根据我之前的几篇「Django 系列」文章,后端架构中我使用了 Django + Celery + RabbitMQ 三个框架/服务。现在有几个问题:

  1. 如何用容器快速部署这三个应用?
  2. 如何提高性能?
  3. 如何保障后端可用性?

Docker Compose vs Swarm vs K8s

在我以往的实践中,容器的编排使用了 docker-compose 实现,问题一就已经解决。但 docker-compose 也只是用于编排,可以各启动三个服务的一个容器,性能与高可用性就可能不能满足要求。

对于性能与高可用,如果是大型项目,目前不二的选择就是 Kubernetes(K8s) ,但是我的项目不足以称之为「大型项目」,因此我考虑的是,如何在单宿主机上提高性能与高可用。

Docker Swarm 是官方集成至 Docker CLI 中的集群服务(虽然被 K8s 后来居上,但是其设计理念与功能也是十分成熟完善,架构上与 K8s 有很多共通点)。Swarm 可以连接多个宿主机作为集群节点,当然也是支持单机容器集群的部署。Swarm 的集群部署需要创建 services, secret 等,也是较为繁琐,因此有 Stack 工具能够解析 compose 文件,让创建各种服务的过程描述于 YAML 脚本中,更方便管理。

当然,Stack 解析的 compose 文件语法与 docker-compose 所支持的略微有不同,但大多是通用的,具体后面提到。

综上可以总结一下几个工具的关系与区别:

优势/劣势仅针对我的后端架构而言

工具/服务 优势 劣势 是否满足
docker-compose 容器编排 不支持高可用
Kubernetes 容器编排,高可用,适合大型项目
Swarm 容器编排,高可用 成熟度略差于K8s
Stack 属于Swarm的命令,用于应用Compose文件 N/A N/A

表格中特意加上了 Stack,因为最开始我把 StackSwarm 视为同一级了。Swarm 更多是提供集群环境,协调各种服务组件,而Stack 更像是一个命令行工具,调用 Swarm 的各种命令启动不同服务等。

Swarm 架构简介

Swarm 可以是一个 Docker 集群,在单宿主机上,Swarm 集群中运行着各种应用(App),每个应用由一个或多个服务(Service)组成,例如前端、后端、数据库三个服务可以组成一个应用。

每个服务由任务(Task)的复制集组成,一个任务就是一个容器(Container)。例如一个后端服务,我们可以通过启动 3 个复制任务来提高性能。服务是程序的出入口,虽然启动了 3 个任务,我们访问这个服务时候还是用服务名即可,请求会在几个任务之间按 RR(轮询) 机制被处理。

实现

介绍了 Docker Swarm 的几个概念之后,我们来实际实现标题「用 Docker Swarm 实现容器服务高可用」吧!

Swarm 集群初始化

因为我在单机上部署我的应用,扩展 Swarm 节点的操作就不赘述了。

首先初始一个Swarm集群:

docker swarm init
复制代码

集群初始化成功后,docker network ls 会看到新创建了两个网络:

  • 一个名为 ingress 的 overlay 网络,用于处理与 swarm 服务相关的控制命令和数据交互。
  • 一个名为 docker_gwbridge 的网桥,用于打通 swarm 集群中的每个独立的容器之间的网络。

异常解决

在调试 swarm 部署应用时,我在 3 台机器执行了一样的操作,奇怪的是其中一台服务器在初始化 swarm 集群后,只创建了 ingress,导致应用部署后任务无法启动。

通过执行:

docker service ps --no-trunc {serviceName}
复制代码

查看到部分报错信息如下:

ERROR: could not find an available, non-overlapping IPv4 address pool among the defaults to assign to the network
复制代码

发现是 docker 网络出了问题,通过对比几台服务器的网络找到是 docker_gwbridge 的缺失。

手动创建该网桥解决问题:

docker network create \
--subnet 172.20.0.0/20 \
--gateway 172.20.0.1 \
-o com.docker.network.bridge.enable_icc=false \
-o com.docker.network.bridge.name=docker_gwbridge \
docker_gwbridge
复制代码

应用部署

应用可以通过手动一个个创建服务的方式部署,通过引用同一个 docker 网络来保证服务间的通信可达。

但是 docker 提供了更方便的方式来部署、扩展一个应用———— docker-compose.yml 配置文件

Compose 文件

先按我的服务架构,写一份 docker-compose.yml 文件:

version: '3'

services:
rabbit:
image: rabbitmq:3
ports:
- "5672:5672"
networks:
- webnet web:
image: myweb:latest
command: python manage.py runserver 0.0.0.0:8000
environment:
- DJANGO_SETTINGS_MODULE=bd_annotation_proj.settings.staging
deploy:
replicas: 3
depends_on:
- rabbit
- worker
ports:
- "8000:8000"
networks:
- webnet celery-worker:
image: myweb:latest
command: celery -A bd_annotation_proj worker -l info
environment:
- DJANGO_SETTINGS_MODULE=bd_annotation_proj.settings.staging
deploy:
replicas: 2
depends_on:
- rabbit
networks:
- webnet networks:
webnet:
复制代码

重要字段含义如下:

  • version: docker-compose 文件的版本,docker stack 只支持版本 "3"
  • service: 服务列表
  • image: 指定运行的镜像
  • command: 容器启动的运行命令
  • environment: 容器内的环境变量,此处配置了 Django 的配置文件指向 staging
  • deploy: 指定部署限制,例如可以限制复制集(replicas)大小、CPU 上限等
  • depends_on: 指明服务间的依赖关系,应用部署时会以依赖关系按顺序启动服务
  • network: 指明应用中的各服务所接入的网络,指定后服务间通过服务名进行通信

创建应用与服务

有了 docker-compose.yml 文件,创建应用以及服务就简单了。假设应用名为 myapp ,直接执行:

docker stack deploy -c docker-compose.yml myapp
复制代码

服务查看

# 查看所有服务
docker service ls
# 查看与 myapp 相关的服务
docker stack services myapp
复制代码

服务中运行的任务可以直接通过 docker ps 查看容器 ID 等信息。

应用扩容

修改 docker-compose.yml 中的 replicas 配置来扩展复制集:

...
delopy:
replicas: 5
复制代码

修改后应用新配置:

docker stack deploy -c docker-compose.yml myapp
复制代码

镜像更新

如果镜像发生了更新,此时需要针对性地更新服务:

docker service update myapp_web --image myweb:latest --force
复制代码

会有进度条显示当前服务中任务的更新进度。

结束应用

通过执行:

docker stack rm myapp
复制代码

结束应用的生命周期,应用相关的任务、服务与网络都会被删除。

总结

通过 Docker Swarm 部署完成我的应用后,我通过删除容器查看重启情况实际测试了一下高可用性,完全符合我的预期。Swarm 中的 ingress 类似 Nginx,已经替我们完成了负载均衡,我们只要享受这种便利就好。

性能上,由于启动了 3 个容器,相比之前在一个容器中使用 uWSGI 的方式运行服务,部分请求响应时间提升 10 倍,相当满意。

容器是开发者的福音,无论是前后端还是测试运维都有必要学习与应用它。虽然容器编排的战役可以说是 K8s 拿下,但是 Swarm 在很多场景也是能够胜任。还是那句话:技术没有对错,只有合适不合适!

用Docker Swarm实现容器服务高可用的更多相关文章

  1. Docker consul的容器服务更新与发现(超详细配图)

    Docker consul的容器服务更新与发现 1.概述 2.部署 1.概述: (1)什么是服务注册与发现: 服务注册与发现是微服务架构中不可或缺的重要组件.起初服务都是单节点的,不保障高可用性,也不 ...

  2. Docker consul的容器服务更新与发现

    Docker consul的容器服务更新与发现 目录 Docker consul的容器服务更新与发现 一.Consul简介 1. 服务注册与发现 2. consul概述 3. consul的两种模式 ...

  3. Hive扩展功能(五)--HiveServer2服务高可用

    软件环境: linux系统: CentOS6.7 Hadoop版本: 2.6.5 zookeeper版本: 3.4.8 主机配置: 一共m1, m2, m3这五部机, 每部主机的用户名都为centos ...

  4. SQL Server上唯一的数据库集群:负载均衡、读写分离、容灾(数据零丢失、服务高可用)

    SQL Server上唯一的数据库集群:负载均衡.读写分离.容灾(数据零丢失.服务高可用).审计.优化,全面解决数据库用户问题.一键安装,易用稳定,性价比高,下载链接:http://www.zheti ...

  5. [转帖]keepalived实现服务高可用

    keepalived实现服务高可用 https://www.cnblogs.com/clsn/p/8052649.html 第1章 keepalived服务说明 1.1 keepalived是什么? ...

  6. docker swarm 搭建与服务更新

    一,docker swarm 是什么 Docker Swarm.Docker Machine与Docker Compose号称Docker三剑客Docker Swarm 和 Docker Compos ...

  7. docker swarm overlay stack 服务部署记录

    项目xxx(后端),xxx-ui前端(前后端分离的项目) 依赖mysql,elasticsearch.分别制作了四个镜像来做这件事.希望可以制作跨主机的部署,使用了swarm,以下是学习记录. 参考 ...

  8. Docker+Nginx+Keepalived实现架构高可用

    一.背景 通过keepalived实现nginx高可用,由于在家不想弄多台主机来搞,所以将运行环境用docker封装来模拟跨主机 docker基础镜像:centos 说之前,简单介绍一下: Keepa ...

  9. 32. docker swarm 集群服务通信 之 RoutingMesh - internal 网络

    1. 两个 service 是如何通信的 通过内置的 DNS 服务发现的功能  相互通信的 2. 创建一个 overlay 的 网络 docker network create -d overlay ...

  10. keepalived实现服务高可用

    第1章 keepalived服务说明 1.1 keepalived是什么? Keepalived软件起初是专为LVS负载均衡软件设计的,用来管理并监控LVS集群系统中各个服务节点的状态,后来又加入了可 ...

随机推荐

  1. SQL优化的这15招,真香!

    前言 sql优化是一个大家都比较关注的热门话题,无论你在面试,还是工作中,都很有可能会遇到. 如果某天你负责的某个线上接口,出现了性能问题,需要做优化.那么你首先想到的很有可能是优化sql语句,因为它 ...

  2. 关于动态使用keepAlive不生效的问题

    首先,我想实现在返回页面时,页面不进行刷新,比如我原先选择的第四页,返回后显示了第一页 想到使用keepAlive缓存组件,大部分推荐的方法为这样,但是不生效 <keep-alive v-if= ...

  3. Eval-Expression.NET:动态执行C#脚本,类似Javascript的Eval函数功能

    我们都知道在JavaScript中,我们可以通过Eval来执行JavaScript字符串代码. 下面推荐一个.Net版本的Eval的开源项目. 01 项目简介 Eval-Expression.NET是 ...

  4. .NET 9.0 使用 Vulkan API 编写跨平台图形应用

    前言 大家好,这次我来分享一下我自己实现的一个 Vulkan 库,这个库是用 C# 实现的,主要是为了学习 Vulkan 而写的. 在学习 Vulkan 的过程中,我主要参考 veldrid,它是一个 ...

  5. java线程池优化

    ThreadPoolExecutor机制 一.概述 1.ThreadPoolExecutor作为java.util.concurrent包对外提供基础实现,以内部线程池的形式对外提供管理任务执行,线程 ...

  6. Spaghetti pg walkthrough Intermediate

    nmap ┌──(root㉿kali)-[~] └─# nmap -p- -A 192.168.170.160 Starting Nmap 7.94SVN ( https://nmap.org ) a ...

  7. 2025苹果春季发布会前瞻:新品迭出,Apple Intelligence国行版即将上线!

    随着2025年的到来,苹果公司的春季发布会也渐行渐近.作为科技行业的领军企业,苹果每一次的新品发布都备受瞩目.本次春季发布会,苹果预计会带来一系列令人期待的新品,同时,国行Mac用户也将迎来一个重大更 ...

  8. Iceberg问题记录-数据湖问题记录跟进

    一.问题追踪 问题 详细描述 提出问题时间 是否完成 计划完成时间 备注 了解Iceberg数据存储方式 了解元数据存储信息.数据组织方式.查询时处理流程等 20231013 是 20231019 ! ...

  9. C# Winform 当音频播放完成后,播放下一个音频,怎么知道音频有没有播放完成

    程序在预警时,会发出报警音,当报警音频播放时间,超过预警频率时,就会像我们打印文档一样,像打印机发送10次打印任务.当打出第1张纸的时候,这时候想取消打印.就不能在电脑端通过软件操作了.因此为了避免这 ...

  10. IPTools for .NET:快速查询全球IP信息

    IPTools 是一个用于快速查询全球 IP 地址信息的库,支持国内和国际 IP 查询,提供详细的地理位置信息(如国家.省份.城市)以及经纬度等数据. 1. IPTools.China IPTools ...