工具
●采纳
Airflow仍然是我们广泛采用的最喜欢的开源工作流管理工具,用于构建作为有线无环图(DAGs)的数据处理流水线。这是一个蓬勃发展的领域,开源工具有 Luigi 和 Argo,厂商工具则有 Azure Data Factory 或者 AWS Data Pipeline。然而 Airflow 特别之处在于它对工作流的程序化定义,而非低代码配置文件,以及对自动化测试的支持,开源并支持多平台,对数据生态丰富的集成点还有广泛的社区支持。不过在像数据网格这样的去中心化数据架构中,Airflow 的劣势在于它是一个中心化的工作流编排。
在所有帮助保持依赖更新的可选工具中,Dependabot 一直是我们认为可靠的默认选择。Dependabot 跟GitHub 的集成平滑,并能自动发送你的pull request,更新依赖到最新的版本。它能在整个组织级别启动,这样所有团队接收到这些 pull request 要容易得多。即便你没有在使用 GitHub,也仍然可以在构建流水线中使用 Dependabot库。如果选择替代品,你可以考虑 Renovate,它支持更多的服务,包括 GitLab,Bitbucket 以及 Azure DevOps。
Helm 是用于 Kubernetes 的包管理器。它附带一个专为 Kubernetes 应用甄选过的仓库,维护于Charts 的官方库中。之前我们提到过 Helm,现在 Helm 3已经发布,其中最显著的变化是 Helm 2的服务器端组件 Tiller 的移除。去掉 Tiller 的设计好处在于,你只能从客户端对 Kubernetes 集群作出修改,也就是说,你只能依据作为 Helm 命令行用户的权限来修改集群。我们已经在许多客户项目中使用了 Helm,它的依赖管理、模板以及钩子机制都极大简化了 Kubernetes 的应用生命周期管理。
用来创建和部署容器的流水线,应该包含容器安全扫描这个步骤。我们的团队尤其喜欢 Trivy ——一个针对容器的漏洞扫描器。在这个领域的工具中,我们尝试过 Clair 和 Anchore Engine。跟 Clair 不一样,Trivy 不止会检查容器,而且会检查代码库中的依赖。同时,由于它是一个独立的二进制包,所以更容易在本地设置和运行。Trivy 的其他好处还有,它是开源软件,并支持 distroless containers 容器。
●试验
Bokeh 是 Python 中最重要的库之一,通过 JavaScript 在浏览器中的渲染,它可以用于科学绘制和数据可视化。与创建出静态图像的桌面工具相比,这样的工具更易于在 web 应用探索中重用代码。Bokeh 尤其擅长这一点。这个库已经足够成熟,功能齐全。我们喜爱 Bokeh 之处在于:它保持对于作为展示层工具的专注,不会越界到比如数据聚合(参照 ggplot)或者 web 应用开发(参照 Shiny或者 Dash)。所以当分离关注点对你来说很重要时,使用 Bokeh 就是件很愉悦的事情了。Boken 提供了web UI 小部件,并能运行于服务器模式,但你可以伺机使用或者放弃这些特性。Bokeh 很灵活,使用方式很直白,它也没有那么多依赖(比如 pandas或者 notebooks)。
这一期雷达引入了一些新的工具,它们可以创建出帮助终端用户可视化并与数据交互的 web 应用。虽然还有更多简单的可视化库比如 D3,但它们在构建独立的可以操作既有数据集的分析应用上,还是减少了可观的工作量。来自 Plotly 的 Dash 在数据科学家中获得越来越多的关注,它可以用 Python 创建出功能丰富的分析应用。Dash 增强了 Python 数据类库,就像 Shiny 之于 R。这些应用有时会被认为是仪表盘,但它们可能涉及的功能,要远远超过这个名词所暗含的部分。Dash 尤其适合构建可伸缩的,随时可上线的应用,这跟同门类中另一个工具 Streamlit 不同。当你需要为商业用户呈现更复杂的分析功能时,请考虑使用 Dash,如果只是少量甚至零代码的方案,你可以选择 Tableau。
维护大规模的 JavaScript 代码库从来不是一件容易的事情,而迁移重大的变更更是极具挑战。在简单的场景中,带有重构能力的 IDE 也许能帮得上忙。但是,如果代码库依赖广泛,每次想要做出重大的变更时,你都不得不遍历客户端代码库,才能做出合适的更新。这需要人工的监管并手工完成。jscodeshift,一个可以重构 JavaScript 和 TypeScript 的工具,能帮助减轻这种痛苦。它能把你的代码分析成抽象语法树(AST),并提供 API 通过不同的变换(也就是在既有的组件上添加、重命名以及删除属性)操作这棵树,然后把这棵树导出成最终源代码。jscodeshift 还附带一个简单的单元测试程序,它能用测试驱动开发的方法编写迁移 codemods。我们还发现 jscodeshift 对于维护设计系统尤其有效。
MLflow 是一款用于机器学习实验跟踪)和生命周期管理的开源工具。开发和持续进化一个机器学习模型的工作流包括,一系列实验(一些运行的集合),跟踪这些实验的效果(一些指标的集合),以及跟踪和调整模型(项目)。MLflow 可以通过支持已有的开源标准,以及与这个生态中许多其他工具的良好集成,来友好地辅助这个工作流。在 AWS 和 Azure 中,MLflow 作为云上 Databricks 的受管服务,正在加速成熟,我们已经在我们的项目中成功使用过它。我们还发现 MLflow 是一个模型管理,以及跟踪和支持基于 UI 和 API 交互模型的很棒的工具。唯一的担忧在于,MLflow 作为单一平台,一直在尝试交付太多的混淆关注点,比如模型服务和打分。
尽管基础设施领域的工具已经得到了极大的改进,在某些情况下编写一些 shell 脚本仍然是有价值的。但是由于 shell 脚本的语法非常晦涩难懂,再加上我们现在对编写shell 脚本疏于练习,我们已经开始乐于使用 ShellCheck 来简化 shell 脚本的编写。ShellCheck 可以用于命令行,或者作为构建的一部分,甚至作为很多流行的集成开发环境的扩展来使用。它的 Wiki 页面包含了数百个 ShellCheck 可以识别的问题的详细描述,而且绝大多数的工具和集成开发环境在发现问题的时候,都提供了非常方便地方式来访问该问题对应的 Wiki 页面。
我们已经广泛地使用 Terraform 来创建和管理云基础设施。根据我们的经验,在建立较大规模的基础设施时,代码往往会被拆分为若干个模块,并通过不同的方式被引入到基础设施的创建中,但是这种做法缺乏灵活性,进而会导致无法避免的代码重复,并最终会使团队停滞不前。我们通过使用 Terragrunt 来解决这个问题, 它是基于 Terraform 的一个很薄的包装层,它实现了 Yevgeniy Brikman 的 Terraform: Up and Running 倡导的实践。我们发现 Terragrunt 非常有用,它鼓励多环境的版本化模块和可复用性。生命周期钩子作为另一个非常有用的特性提供了更多的灵活性。在打包方面,Terragrunt 与 Terraform 具有相同的局限性:即没有一个合适的方式来定义包以及包与包之间的依赖关系。但是我们可以使用模块并指定一个与 Git 标签相关联的版本号来解决这个问题。
●评估
服务网格和 API 网关为流量路由到不同的微服务提供一个方便的方法,只要这些微服务都实现了相同的 API 接口。Flagger 利用这个特性,可以做到动态调整路由到某个新版本服务的部分流量。这对于金丝雀发布或者蓝绿部署是一项通用的技术。Flagger 和各种流行的代理(包括 Envoy 和 Kong)结合使用,可以逐步增加对于某个服务的请求,并报告负载的指标,从而为新的发布提供快速反馈。我们很高兴 Flagger 简化了这个极具价值的实践,从而可以被广泛采纳。虽然 Flagger 由 Weaveworks 赞助,但你可以独立使用 Flagger,无需捆绑使用 Weaveworks 的其他工具。
当你想要连接到 AWS 上的某个服务器实例时,我们通常推荐要经由一个堡垒机,而不是直接连接。然而,仅仅因此而预置一台堡垒机的过程会让人崩溃掉,这也是为什么AWS 的系统会话管理器提供了管道来更容易地连接到你的服务器。Gossm 是一个开源的 CLI 工具,它可以更方便地使用会话管理器。Gossm 让你通过 ssh 或者 scp 这样的工具,在终端直接利用会话管理器的安全机制和 IAM 策略。它还有一些 AWS CLI 不具备的能力,包括服务器发现和 SSH 集成。
随着 CD4ML 的兴起,数据工程和数据科学的运维方面获得了更多的关注。自动化数据治理是发展的结果之一。Great Expectations 是一款可以帮助你在数据流水线中,编制内建控件用于标记异常和质量问题的框架。就像运行在构建流水线中的单元测试,Great Expectations 在数据流水线的执行过程中作出断言。这不仅对于为数据流水线实现某种 Andon,或是确保基于模型的算法保持在训练数据决定的操作范围内,都有帮助。像这样的自动化控件可以帮助分发以及民主化数据访问和保管。Great Expectations 还配有一个探查工具,帮助理解特定数据集的质量,并设置合适的约束。
我们对 k6 的出现感到很兴奋,它是性能测试生态环境中比较新的一款工具,尤其注重开发者体验。k6 命令行运行器执行 JavaScript 编写的脚本,并让你配置执行时间和虚拟用户的数目。它的命令行有一系列高级特性,比如可以在测试执行完成前,让你看到当前的统计数据,动态伸缩最初定义的虚拟用户数量,甚至暂停和继续一个运行中的测试。命令行输出提供了一套带有转换器的可定制指标,能让你在 Datadog 和其他观察工具中可视化结果。为你的脚本添加 checks,可以很容易将性能测试集成到你的CI/CD流水线中去。如果要加速性能测试,可以看看它的商业版本 k6 Cloud,它提供了云伸缩以及额外的可视化能力。
考虑到服务网格越来越多被用来部署大量的容器化微服务,我们期待看到能自动化并简化此类架构风格相关的管理工具的出现。Kiali 就是这样的工具。Kiali 提供了一个图形化用户界面,用于观察和控制使用 Istio 部署的服务网络。我们发现 Kiali 对可视化网络中的服务拓扑结构,并理解它们彼此之间的路由流量,尤其有帮助。比如,当和 Flagger 结合使用时,Kiali 可以显示出那些路由到某个金丝雀服务发布的请求。我们特别喜欢 Kiali 的一个能力,它能让我们向某个服务网格人工注入网络错误,以测试面临网络中断时的弹力。因为配置以及在复杂的微服务网格中运行错误测试带来的复杂度,这个实践经常会被忽略掉。
编写安全的代码十分重要,但是开发人员还有很多其他事情需要考虑,不能把时间全花在这里。LGTM 不仅为开发人员提供了一道安全防护网,也是一个安全代码实践的知识库。这是一个专注于安全的静态代码分析工具,以 CodeQL 查询语言实现了(部分开放源代码的)安全编码规则。LGTM 适用于Java、Go、JavaScript、Python、C#及C/C++,并可以将白盒安全检查集成到持续集成流水线中。LGTM 与 CodeQL 都来自于 Github 安全实验室。
Litmus 是一个低门槛的混沌工程工具。它可以用很低的代价往你的 Kubernetes 集群中注入各种各样的错误。除了随机干掉某些 Pod 之外,它提供的众多功能尤其让我们感到兴奋,比如仿真各种网络问题、CPU 问题、内存问题和 I/O 问题等。Litmus 还支持一些量身定制的试验,来仿真 Kafka 和 Cassandra 等常见服务中的错误。
能够识别出应用系统的依赖是否含有已知漏洞,对于开发团队来说是很重要的事情。OSS Index 可以帮助到这一点。OSS Index是一套免费的开源组件目录,以及设计用来帮助开发者识别漏洞、了解风险并确保软件安全的扫描工具。我们的团队已经通过不同的语言,把这份索引集成到流水线中,比如 AuditJS 和 Gradle plugin。它的运行速度很快,定位漏洞精准,并且几乎没有误报。
Web UI 测试一直是一片活跃的疆域。 Puppeteer 的部分缔造者在转向微软后,开始将所学投用在 Playwright。它可以让你通过相同的API,为Chromium、Firefox以及 WebKit 编写测试。因为对所有主流浏览器引擎的支持,Playwright 成功获得了一些关注,并作为补丁版本包含在 Firefox 和 Webkit 中。其他工具将如何赶上,让我们拭目以待,毕竟现在 Chrome DevTools Protocol 作为自动操作浏览器的通用 API,正在获得越来越多的支持。
来自 Secure Code Warrior 的 Sensei 是一款可以很容易地创建和分发安全代码质量规则的 Java IDE 插件。在 ThoughtWorks,我们通常提倡“工具胜过规则”,也就是说,要更容易地做正确的事情,而不是遵守像检查列表那样的治理规则和过程,而 Sensei 就符合这个哲学。开发者可以创建出很容易跟其他团队成员共享的代码片段。它们被实现成针对 Java AST 的查询,可以很简单,也可以很复杂,这样的例子包括对于 SQL 注入和加密漏洞的警告,以及其他。另外一个我们喜欢的特性是,Sensei 在 IDE 中一旦发现代码变化就开始执行,因此它比其他传统的静态分析工具提供了更快的反馈。
●暂缓
