专栏首页CNCF使用Kubernetes和容器扩展Spinnaker

使用Kubernetes和容器扩展Spinnaker

作者:Ethan Rogers

Kubernetes和容器完全改变了我们对完成工作所使用的工具的看法。扩展自动化平台需要通过fork开发定制扩展,并决定是否应该贡献上游的日子已经一去不复返了。对于大多数组织来说,是否使用平台或工具的选择取决于它的可扩展性。

Spinnaker的设计初衷是可扩展。如果你的部署或发布工作流不受开箱即用阶段的支持,你可以使用许多选项来处理这些用例。这些包括:

  • Webhook和自定义Webhook阶段
  • 运行作业阶段(Run Job stages)和自定义作业阶段(Custom Job Stages)
  • 使用Java/Spring扩展自定义构建

在这篇博客文章中,我们将讨论运行作业阶段,以及它如何使团队能够使用Kubernetes和容器的功能扩展Spinnaker。

关于批处理作业

当涉及到自动化工作流中的任务时,批处理作业是一个强大的工具。批处理作业通常用于处理大量数据,可以用于任何需要定期或突发运行的任务,而传统的“持久”工作负载则需要始终可用。批处理作业具有一些特性,使它们不仅仅适合数据处理。

  1. 批处理作业可以用任何语言编写,使团队中的任何工程师都可以访问它们。
  2. 它们通常由一些事件触发;例如,批处理作业可以在CRON调度上运行,或者由输入数据集中的新数据触发。
  3. 它们对一些输入进行操作,并将其转换为一组不同的输出。
  4. 它们是参数化的,这使得它们可以用于许多用例。

有趣的是,我们许多人已经在日常开发工作流中使用批处理作业。CI(Continuous Integration,持续集成)可能是这种模式最熟悉的形式。这些作业将源代码转换为可部署的工件,如二进制文件、JAR或Docker镜像。它们是由源代码存储库中的更改触发的。它们可以参数化,以允许针对不同平台的构建,并且,在当今的后Docker世界中,大多数提供程序允许用户定义要使用的容器镜像,从而允许你在自己选择的环境中运行构建。

如果我们将这个例子放大来看,就可以看到批处理作业对于自动化部署工作流的各个部分,以及补充Spinnaker的功能来提供我们需要的体验是多么有用。我们每天使用很多工具。不幸的是,这些工具中的大多数并没有彼此集成,并且需要大量的粘合代码来将一个操作,链接到另一个操作。此外,还有一些Spinnaker不支持开箱即用的用例,比如通过Terraform提供基础设施,或者与Claire一起扫描Docker镜像。这些类型的集成对软件发布过程非常重要,需要在我们的部署工具中有一个家。通过使用Run Job阶段,我们可以在容器中构建运行代码的自定义作业,并将这些过程作为管道(pipeline)的一部分执行。

让我们看一个用例,看看它在实践中是如何工作的。

用例 - 用Kaniko构建Docker镜像

Spinnaker通过Packer为你选择的云提供商构建VM镜像的阶段。虽然可以支持构建Docker镜像,但是Packer使用的方法不是最佳实践,因为它不使用镜像的Dockerfile(更多信息请参考这里)。那么,如果我们想让Spinnaker为我们构建Docker镜像,我们该怎么做呢?让我们看看如何使用Run Job(Manifest)阶段来实现这一点。

https://www.packer.io/docs/builders/docker.html

在本例中,我们将使用Kaniko,这是一个来自谷歌的开源镜像构建器,用于在Kubernetes上安全地构建Docker镜像。使用Kubernetes作业,我们将执行两个步骤

  1. 从Github中取出应用程序的源代码
  2. 构建并将Docker镜像推送到Dockerhub

下面是我们将用来完成此任务的作业规范。

apiVersion: batch/v1
kind: Job
metadata:
  name: kaniko-builder
spec:
  backoffLimit: 0
  template:
    spec:
      restartPolicy: Never
      initContainers:
        - name: git
          image: alpine/git
          env:
            - name: BRANCH
              value: master
            - name: REPO
              value: https://github.com/armory-io/demo-api
          command: [git, clone, --single-branch, --branch, $(BRANCH), $(REPO), /workspace]
          volumeMounts:
            - name: workspace
              mountPath: /workspace
      containers:
        - name: kaniko
          image: gcr.io/kaniko-project/executor:latest
          env:
            - name: DOCKERFILE
              value: Dockerfile
            - name: CONTEXT
              value: dir://workspace
            - name: DESTINATION
              value: armory-io/loadtesting
          args:
            - "--dockerfile=$(DOCKERFILE)"
            - "--context=$(CONTEXT)"
            - "--destination=$(DESTINATION)"
          volumeMounts:
            - name: workspace
              mountPath: /workspace
            - name: docker-config
              mountPath: /kaniko/.docker
      volumes:
        - name: workspace
          emptyDir: {}
        - name: docker-config
          secret:
            secretName: docker-creds

YAML一开始可能看起来有点令人困惑,所以让我们来看看Kubernetes将如何使用它。首先,我们有一个alpine/git容器,它对源repo运行git克隆,并将其内容写入共享的emptyDir卷。我们这样做是为了我们工作的下一个步骤,Kaniko构建步骤,可以访问源代码。此步骤告诉Kaniko使用dir://workspace(共享卷的挂载路径)的上下文、该上下文路径中的Dockerfile和目标来构建镜像。

现在我们有了一个可以构建镜像的任务,让我们在Spinnaker中构建一个管道来部署并启动Kubernetes中的这个任务。

我们将首先创建一个管道并添加一个Run Job(Manifest)阶段。虽然这个阶段类似于Deploy (Manifest)阶段,但是它具有不同的部署语义。Spinnaker将部署Job,并等待它完成,而Deploy(Manifest)只是等待,直到Kubernetes认为Manifest是稳定的。这种差异使我们能够运行Job,并等待它们完成后再继续我们的管道。

现在,如果我们不使用Docker镜像,那么构建它就没有任何意义。因此,在配置阶段的底部,我们将配置阶段以了解Job将生成的构件。如果你查看上面的图像,你将注意到我们正在构建应用程序的0.0.1版本,因此我们将在Produces Artifacts部分中使用该版本配置一个工件。

这将为我们提供一个可以在下游使用的工件。我们将通过Deploy (Manifest)阶段将新的Docker镜像绑定到Kubernetes部署来实现这一点。

通过使用Kubernetes和容器的强大功能,我们成功地扩展了Spinnaker的功能。当我们执行管道时,我们应该看到我们的镜像得到构建、推送和部署!

使Job可重用

Run Job阶段提供了几乎无限的灵活性,因为它允许我们使用任何语言扩展Spinnaker。但是,上述方法的缺点之一是不容易在管道之间移植。为了让用户使用我们构建的内容,他们必须将这个阶段从一个管道复制到下一个管道。幸运的是,Spinnaker提供了一个特性,可以将这些作业转换为可重用的阶段,任何人都可以使用这些阶段来构建管道。

自定义作业阶段(Custom Job Stages),也在Spinnaker 1.14中引入,允许操作人员通过在Spinnaker的配置中预先定义作业来创建自定义作业阶段。然后,这些阶段作为Spinnaker原生阶段呈现给最终用户,并且可以像添加开箱即用阶段一样添加到管道中。通过使用这个特性,我们可以封装复杂的作业,并为用户提供一个易于使用的阶段,可以跨所有管道使用。

让我们看看上面的示例作为自定义作业阶段是什么样子的。

现在,我们不是使用一般的运行作业阶段,而是每个人都可以使用的特制阶段。此外,我们看到的不是定义作业规范的一大堆YAML,而是参数的子集,这使得这个阶段更容易使用。

进入网页了解更多。

https://blog.spinnaker.io/extending-spinnaker-with-kubernetes-and-containers-5d16ec810d81

本文分享自微信公众号 - CNCF(lf_cncf),作者:LFAPAC

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-05-13

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 流水线救赎:Spinnaker如何塑造SAP卓越的交付

    作为一名负责卓越交付的现场可靠性工程师(Site Reliability Engineer,SRE),可靠的部署对我来说很重要。我已经在SAP工作了一段时间,我...

    CNCF
  • Envoy 入门简单示例

    Envoy 使用 YAML 配置文件来控制代理的行为。在下面的步骤中,我们将使用静态配置接口来构建配置,也意味着所有设置都是预定义在配置文件中的。此外 Envo...

    CNCF
  • 使用 Kind 构建离线集群安装包

    Kind(Kubernetes in Docker) 是一个 Kubernetes 孵化项目,它使用 Docker 为节点进行 Kubernetes 的快速部署...

    CNCF
  • Android UI之自定义Window Title样式

    Android提供了很多控件便于开发者进行UI相关的程序设计。但是很多时候,默认的一些UI设置不足以满足我们的需求,要么不好看,要么高度不够,亦或者是与应用界面...

    技术小黑屋
  • 动态规划的楼层算法

    简单说,就是斐波那契数列(Fibonacci sequence),又称黄金分割数列、因数学家列昂纳多·斐波那契(Leonardoda Fibona...

    sunsky
  • shell学习一变量的定义 原

    用符号$加上变量名如 $name 或${name},{}括号是为了确定变理边界,推荐使用

    用户2603479
  • mysql数据库中指定值在所有表中所有字段中的替换

    Java程序员也要new个对象
  • Struts2的常见的配置文件介绍

    1:package 定义一个包。 包作用,管理action。 (通常,一个业务模板用一个包)   常见属性及其说明:     (1)name  包的名字;以方便...

    别先生
  • 搭建SSH三大框架WEB项目过程(Struts2.3+Hibernate4.3+Spring4.1)

    <%@ taglib uri="/struts-tags" prefix="s" %>

    SmileNicky
  • 关于sturct2 ServletRequestAware无法获取request

    至于为何会如此,可以看以下博客: 刨根问底–struts–获得request-继承ServletRequestAware

    陨石坠灭

扫码关注云+社区

领取腾讯云代金券