如今(或應該如此),自動化已成爲每個應用生命週期的一部分。人們用來實現自動化的工具往往非常擅長從源代碼調用構建系統。因此,如果我們得到一個 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
對象中。