如今(或应该如此),自动化已成为每个应用生命周期的一部分。人们用来实现自动化的工具往往非常擅长从源代码调用构建系统。因此,如果我们得到一个 docker 镜像,并且构建代理中的环境与开发人员自己的环境充分配合,这可能就足够了。向 Docker 注册表进行身份验证可能是最大的挑战,但是所有自动化工具中都有一些功能可以帮助实现这一点。
但是,有时最好将容器创建完全留给自动化层,在这种情况下,可能不需要污染用户的代码。容器创建非常棘手,开发人员有时并不真正在意它。如果用户代码更简洁,则其他工具更有可能 “做正确的事”,应用安全修复程序,优化缓存等。有多种自动化选项,并且现在它们都具有与容器相关的某些功能。我们只看其中几个。
Concourse
Concourse 是基于流水线的自动化平台,可用于 CI 和 CD。它在 Pivotal 内部被大量使用,该项目的主要作者在那里工作。除 CLI 外,Concourse 中的所有内容都是无状态的,并且所有内容都在容器中运行。由于运行容器是自动化流水线的主要业务顺序,因此很好地支持创建容器。如果它是容器镜像,则 Docker Image Resource 负责使构建的输出状态保持最新。
这是一个示例流水线,为上面的示例构建一个 docker 镜像,假设它位于 myorg/myapp
的 github 中,并且在根目录下有一个 Dockerfile
,并且在 src/main/ci/build.yml
中有一个构建任务声明:
resources:
- name: myapp
type: git
source:
uri: https://github.com/myorg/myapp.git
- name: myapp-image
type: docker-image
source:
email: {{docker-hub-email}}
username: {{docker-hub-username}}
password: {{docker-hub-password}}
repository: myorg/myapp
jobs:
- name: main
plan:
- task: build
file: myapp/src/main/ci/build.yml
- put: myapp-image
params:
build: myapp
流水线的结构非常具有声明性:我们定义 “资源”(输入或输出或两者兼有)和 “作业”(使用并向资源应用操作)。如果任何输入资源发生更改,则会触发新的构建。如果作业期间任何输出资源发生变更,则将对其进行更新。
可以在与应用源代码不同的位置定义流水线。对于一般的构建搭建,任何声明也可以集中或外部化。如果我们采用这种方式,则可以将开发和自动化之间的关注点区分开。
Jenkins
Jenkins 是另一种流行的自动化服务器。它具有广泛的功能,但此处最接近其他自动化示例的功能是 pipeline 功能。这是 Jenkinsfile
,该文件使用 Maven 构建 Spring Boot 项目,然后使用 Dockerfile
构建镜像并将其推送到存储库:
Jenkinsfile
node {
checkout scm
sh './mvnw -B -DskipTests clean package'
docker.build("myorg/myapp").push()
}
对于需要在构建服务器中进行身份验证的(现实的)Docker 存储库,我们可以使用 docker.withCredentials(...)
将凭据添加到上述 docker
对象中。