Auth0是一家“身份验证即服务”提供商,旨在为开发人员提供简单易用的身份管理服务。为了保持灵活性和可扩展性,Auth0身份管理平台允许开发人员在身份验证和授权管道中增加自定义代码。而在一个多租户环境中,为了保证不同用户的自定义代码可以互不影响,就需要一种技术提供必要的数据隔离和资源利用保障。在评估了多种现有方案后,Auth0决定构建自己的沙盒解决方案,并将其命名为Auth0 Webtasks。Tomasz Janczuk是Auth0的一名工程师。近日,他撰文介绍了这一解决方案。
Auth0执行的所有用户自定义代码都是使用Auth0 Webtasks运行在HTTP请求的上下文中。执行时间限制在HTTP请求的生命周期内。由于这些限制,他们选择了基于HTTP的执行模型。Webtask集群接收HTTP POST请求,后者包含要执行的代码,并给出了webtask容器的名称,限定了代码执行边界。用户与webtask容器一一对应。Webtask集群在webtask容器中执行自定义代码,并返回一个包含结果的JSON响应。
在这个模型中,所有用户都在统一的环境中运行自定义代码,不同用户的自定义代码都只能使用一组相同的功能和模块。Webtask的运行时是基于Node.js的,自定义代码只能使用webtask环境中预先配置的Node.js模块集合。这样做的好处是,Auth0很容易修改这个集合,而且他们可以维护一个webtask容器池,随时分配给用户使用,减少了容器冷启动延迟。
Webtask的编程模型非常简单。服务调用者提交一个JavaScript函数闭包,webtask集群调用那个函数,并提供一个回调参数。当自定义代码执行完毕,它就会调用回调函数,并提供一个错误信息或一个结果值。然后,那个值就会序列化为JSON,并在HTTP响应中返回给调用者:
return function (cb) { cb(null, “Hello, world”); }
在决定开发一个新的沙盒解决方案之前,Auth0评估了几种现有方案。Node-sandbox只能实现进程级隔离,而不支持操作系统级隔离,并且为每个请求创建新的Node.js进程会增加延迟。像Heroku或Windows Azure Web Sites这样的PaaS服务可以满足他们的需求,但需要他们为每个Auth0用户配置一个单独的站点,而且从成本上讲不具有可扩展性。而AWS Lambda的核心是一个异步编程模型,并不满足他们的需求。最终,他们决定开发Auth0 Webtasks。
Auth0 Webtasks基于AWS构建,架构图如下:
Auth0服务需要一个很高的可用性级别,因此:
Webtask VM的所有出站流量都经过具有固定Elastic IP的NAT VM。这些NAT VM还允许通过SSH隧道访问单个的webtask VM。每个webtask集群都运行在自己的VPC上。该VPC在每个可用区域内都有一个私有子网和一个公共子网,前者运行webtask VM,后者运行NAT VM和ELB。
在软件层面,Auth0 Webtasks基于CoreOS、Docker、etcd和fleet构建。为了实现代码和数据的隔离,每个用户的代码都在他们自己的Docker容器(即webtask容器)中运行。HTTP请求到达webtask VM后首先会由一个代理进行处理。该代理查看etcd配置来确定是否已经为发送该请求的用户分配了webtask容器。如果已经分配,代理就会将请求转发给该容器;如果没有,代理就会将webtask容器池中的一个容器分配给该用户,并在etcd中增加一条记录。该容器池由fleet管理,它会重启容器,并将其放回未分配池。
除了在各自的容器中运行各自的自定义代码外,Auth0在CoreOS webtask VM中配置了出口防火墙规则。这些规则能够防止webtask容器中的不受信任代码与其它容器或webtask基础设施通信。为了限制内存和CPU消耗,他们使用了Docker的cgroups机制。而且,每个webtask容器会创建一个Linux临时用户,并在启动时配置用户PAM限制。
Auth0 Webtasks使用bunyan实现了结构化的、基于JSON的日志记录。所有的日志都存储在Kafka中。为了隔离不同用户的日志,他们将每个用户的日志发布到单独的Kafka topic。而为了管理分析,所有的信息都会发布到一个系统级topic。
虽然JavaScript和Node.js提供了一个健全的编程模型,但也有许多人喜欢使用.NET和C#编写自定义代码。为了满足这种需求,Auth0 Webtasks允许执行C#代码。这是通过Edge.js实现的,它允许开发人员从Node.js中调用C#异步lambda表达式。另外,Edge.js使用Mono作为Linux上的CLR实现。借助这种机制,开发人员可以使用Mono框架的所有功能来编写自定义C#代码,并在基于Linux的webtask容器中运行。
目前,Auth0 webtasks允许用户导入自定义证书数据库以及在身份验证管道中运行自定义逻辑。
感谢郭蕾对本文的审校。
给InfoQ中文站投稿或者参与内容翻译工作,请邮件至[email protected]。也欢迎大家通过新浪微博(@InfoQ,@丁晓昀),微信(微信号:InfoQChina)关注我们,并与我们的编辑和其他读者朋友交流。