作者:Ethan Rogers
Kubernetes和容器完全改变了我们对完成工作所使用的工具的看法。扩展自动化平台需要通过fork开发定制扩展,并决定是否应该贡献上游的日子已经一去不复返了。对于大多数组织来说,是否使用平台或工具的选择取决于它的可扩展性。
Spinnaker的设计初衷是可扩展。如果你的部署或发布工作流不受开箱即用阶段的支持,你可以使用许多选项来处理这些用例。这些包括:
在这篇博客文章中,我们将讨论运行作业阶段,以及它如何使团队能够使用Kubernetes和容器的功能扩展Spinnaker。
关于批处理作业
当涉及到自动化工作流中的任务时,批处理作业是一个强大的工具。批处理作业通常用于处理大量数据,可以用于任何需要定期或突发运行的任务,而传统的“持久”工作负载则需要始终可用。批处理作业具有一些特性,使它们不仅仅适合数据处理。
有趣的是,我们许多人已经在日常开发工作流中使用批处理作业。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作业,我们将执行两个步骤
下面是我们将用来完成此任务的作业规范。
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