杨峰 译 分布式实验室
这是一个关于扩展性和使用痛点的软件架构故事,和其他好的技术故事一样,也是从点滴开始的。
在Panorays,我们帮助大量企业用户衡量供应商的安全地位,但是我更愿意看到集中式第三方安全管理。我们先从架构和流程开始。
开始时候,管理虚机都是通过Bash进行的,使用大量的脚本。
每个公司都有一个独特的虚机实例
每个虚机串行执行很多作业模拟黑客的业务
并行作业是通过启动更多虚机完成
采用Cron和Bash创建内部编排功能
问题在于:
并发在于公司层面而不是作业层面
进程不透明
服务器利用率太低
手工触发
兴起
这样的问题引发了Transport工具的兴起,Transport是一个动态工作流引擎,将工作流当做Kubernetes的作业调度。基于容器架构使得Transport灵活配置工作,又能有效扩展。根据工作流依存度,可能时提供最佳并发性,并提供完整RESTAPI实现自动管道管理。
当有新公司进入平台后,Transport的API会自动被触发,根据实现定义好的工作流情况,Transport将并行或串行将作业提交给Kubernetes执行。
Transport初始版根据如下规则运行:
作用
Transport的作用就是用户定义工作流,Transport确保发生。但是定义工作流前又需要先定义作业。
我们的例子中,作业等同于运行Docker容器;一组作业叫做阶段,可以是串行或者并行;工作流是阶段的序列。在新环境下,我们可以在某些规则定义下,实现并行。
不要做无法实现的承诺
Transport调度一个分布式任务队列架构,架构中Transport把任务放入队列中,workers则从队列中取出任务并执行。此架构支持任务重试、设置超时、设置优先级和定时调度任务。任务开始、成功或者失败,Transport会往工作流中发送通知。
揭秘
现在可以揭秘了,Transport提供服务端点来操作工作流,工作流被转译成Celery任务,我们使用celery链和组设置依赖性,Transport根据依赖性将任务转发到队列;另外celery workers则从队列中提取任务,并部署相应的Kubernetes任务。这样一个工作流根据作业依存性得以完成。
也可以添加为workers提供易用性的服务端点。同时运行worker数量设置了同时可以运行的作业数量。
不要打开打包容器
新部署流程包括安全创建和将docker images推上Google Cloud Registry。
Transport将作业根据工作流转化成相关作业,而ConfigMap则定义作业版本。
Kubernetes则提供Docker容器底层运行引擎。
命名
开始时我们用与初始作业一样的名字命名Kubernetes作业,他们有同一个唯一号。
这样我们发现了一些Kubernetes的命名限制:
第一个正则表达式用于确认名字只由字母和下划线及横杠构成,我们发现了第二个最长字符限制。
框架
我们也调研过一些框架方案:
Airflow:这是一个很棒的方案,将Python文件渲染成代表工作流的DAGs。如果有一个运行前确定状态的静态工作流,推荐使用Airflow。Airflow的问题在于动态工作流,stackoverflow里有很多如何正确创建动态工作流的方法。因为改变了RESTAPI的请求方法,我们不需要生成动态工作流。
Google Pub/Sub:是谷歌pub/sub方案,因为需要在“作业端”修改大量的代码因此我们也没有采用它。
可以从更多的任务队列中找到替换项。
UI:添加UI来对正在运行和完成工作流进行监控和排错。
Generify : 如果想使Transport更加普适化,可以将其开源。
原文链接:https://hackernoon.com/https-medium-com-talperetz24-scaling-effectively-when-kubernetes-met-celery-e6abd7ce4fed