圖片來源: https://unsplash.com/photos/RIDhjfZZ7Ys
今天瞭解到一個名爲 ConfigurationasCode(JcasC)的插件可以來創建 Jenkins,這個插件允許你用 YAML 文件來定義 Jenkins 配置。一般我們在使用 Jenkins 的時候多少知道我們需要哪些插件或者其他配置來配合我們的 CI/CD 工作,使用 JcasC 插件,我們就可以將這些信息配置在可讀性更高的 YAML 文件中。在本文中,我們會爲大家演示如何使用 ConfigurationasCode插件來創建 Jenkins,然後使用 Git、Maven 等工具來編寫一個聲明式的 Pipeline 去構建一個 Java 應用,另外還會展示如何使用 Vault來管理一些私密數據。
使用 Vault
vault是一個密碼/證書集中式管理工具,通過 HTTP-API 對外提供統一的密碼訪問入口,並且提供權限控制以及詳細的日誌審計功能。
一個系統可能需要訪問多個帶密碼的後端:例如數據庫、通過 API keys 對外部系統進行調用,面向服務的架構通信等等。要將衆多系統中的用戶和權限對應起來已經非常困難,加上提供密鑰滾動功能、安全的存儲後端還要有詳細的審計日誌,自定義解決方案几乎不太可能。這也就是 vault 存在的意義。
爲了方便我們直接本地使用 Docker 鏡像來運行:
$ docker run -d --name=vault --cap-add=IPC_LOCK -p 8200:8200 vault:1.1.3
我們這裏使用的是最新版的 vault,需要我們使用 KV(Key-Value Secrets Engine)HTTP API V2 版本來訪問數據,因爲新版本的 ConfigurationasCode插件使用的就在 V2 版本,運行容器後,我們可以從控制檯日誌中獲取到用於對 Vault 進行身份驗證的令牌:
$ docker logs -f vault
==> Vault server configuration:
Api Address: http://0.0.0.0:8200
Cgo: disabled
Cluster Address: https://0.0.0.0:8201
Listener 1: tcp (addr: "0.0.0.0:8200", cluster address: "0.0.0.0:8201", max_request_duration: "1m30s", max_request_size: "33554432", tls: "disabled")
Log Level: info
Mlock: supported: true, enabled: false
Storage: inmem
Version: Vault v1.1.3
Version Sha: 9bc820f700f83a7c4bcab54c5323735a581b34eb
WARNING! dev mode is enabled! In this mode, Vault runs entirely in-memory
and starts unsealed with a single unseal key. The root token is already
authenticated to the CLI, so you can immediately begin using Vault.
You may need to set the following environment variable:
$ export VAULT_ADDR='http://0.0.0.0:8200'
The unseal key and root token are displayed below in case you want to
seal/unseal the Vault or re-authenticate.
Unseal Key: 5YKiMo0qe983/DqkDmQGGZmhN9Dp7JCbl0mrSyMgZ3E=
Root Token: s.vf0oCbRDGrLNvfYjRfcdcZLg
Development mode should NOT be used in production installations!
==> Vault server started! Log data will stream in below:
......
記住上面 RootToken的值,我們可以通過該 Token 來添加訪問 Jenkins Dashboard 和 Github 的用戶名和密碼信息,我們可以設置 Jenkins 賬戶通過 rootPassword來獲取密碼,Github 賬戶通過 githubPassword來獲取密碼,我們需要進入到 vault 的容器中去進行操作:
$ docker exec -it vault /bin/sh
/ # vault kv put secret/jenkins rootPassword=<替換成你的jenkins訪問密碼> githubPassword=<替換成你的github用戶密碼>
Get https://127.0.0.1:8200/v1/sys/internal/ui/mounts/secret/jenkins: http: server gave HTTP response to HTTPS client
我們通過 vault kv put來添加一組 secret 信息,會出現上面的錯誤,我們可以導入 VAULT_ADDR和 VAULT_TOKEN環境變量來解決上面的問題:
/ # export VAULT_ADDR='http://0.0.0.0:8200'
# 下面的TOKEN也需要導入,否則執行下面的命令會出現missing client token的錯誤
/ # export VAULT_TOKEN=s.vf0oCbRDGrLNvfYjRfcdcZLg
/ # vault kv put secret/jenkins rootPassword=<替換成你的jenkins訪問密碼> githubPassword=<替換成你的github用戶密碼>
Key Value
--- -----
created_time 2019-06-13T03:04:04.9804179Z
deletion_time n/a
destroyed false
version 1
# 通過命令`vault kv get secret/jenkins`驗證信息是否創建
/ # vault kv get secret/jenkins
====== Metadata ======
Key Value
--- -----
created_time 2019-06-13T03:04:04.9804179Z
deletion_time n/a
destroyed false
version 1
========= Data =========
Key Value
--- -----
githubPassword <xxxxxx>
rootPassword <xxxxxx>
配置信息
JcasC插件提供了許多配置設置,允許我們配置 Jenkins的各種組件,我們這裏主要來配置構建示例 Java 應用程序的基本配置, Jcasc插件官網文檔:https://github.com/jenkinsci/configuration-as-code-plugin 中也提供了很多其他配置的示例,有需要的可以前往查看。
我們這裏需要的是在啓動後配置一下 Jenkins 組件:
-
一組 Jenkins 插件,運行創建聲明式 Pipeline,從 Github 倉庫檢出源代碼,使用 Maven 進行構建
-
包含 Jenkins 用戶的登錄憑據,通過 Vault服務器上面的 rootPassword屬性來讀取用戶密碼
-
Maven 工具的安裝設置:默認情況下,Jenkins 中未安裝 Maven,所以我們需要設置所需的版本和工具名稱
- 用戶訪問包含應用程序源代碼的 Git 倉庫的憑據(如果是私有倉庫的話)
最終的配置信息如下:
jenkins:
agentProtocols:
- "JNLP4-connect"
- "Ping"
authorizationStrategy:
loggedInUsersCanDoAnything:
allowAnonymousRead: false
crumbIssuer:
standard:
excludeClientIPFromCrumb: false
disableRememberMe: false
mode: NORMAL
numExecutors: 2
primaryView:
all:
name: "all"
quietPeriod: 5
scmCheckoutRetryCount: 0
securityRealm:
local:
allowsSignup: false
enableCaptcha: false
users:
- id: "cnych"
password: ${rootPassword}
slaveAgentPort: 50000
views:
- all:
name: "all"
tool:
git:
installations:
- home: "git"
name: "Default"
jdk:
installations:
- home: "/docker-java-home"
name: "jdk"
maven:
installations:
- name: "maven"
properties:
- installSource:
installers:
- maven:
id: "3.5.4"
credentials:
system:
domainCredentials:
- domain :
name: "github.com"
description: "GitHub"
credentials:
- usernamePassword:
scope: SYSTEM
id: github-cnych
username: cnych
構建 Jenkins 鏡像
和 Vault 服務一樣,我們也可以直接用 Docker 容器來運行 Jenkins,但是在官方鏡像基礎上我們需要添加一個配置,比如添加 ConfigurationasCode插件,該插件需要設置一個指向 YAML 文件位置的環境變量,該變量可以指向一下內容:
-
包含一組配置文件的文件夾的路徑
-
單個配置文件的完整路徑
- 指向 Web 的一個配置文件 URL
然後我們設置 Jenkins 和 Vault 之間的通信,需要傳遞訪問 Vault 的身份令牌、密鑰的路徑和 Vault 服務器地址,這些配置都可以通過環境變量進行設置,也可以放置在一個統一文件中通過環境變量 CASC_VAULT_FILE來指向這個文件也可以,以下是定義的擴展 Jenkins 鏡像的 Dockerfile,添加了使用 JcasC 插件運行的一些參數以及從 Vault 獲取數據的信息:
FROM jenkins/jenkins:lts
ENV CASC_JENKINS_CONFIG="/var/jenkins_home/jenkins.yml"
ENV CASC_VAULT_FILE="/var/jenkins_home/vault.yml"
COPY jenkins.yml ${CASC_JENKINS_CONFIG}
COPY vault.yml ${CASC_VAULT_FILE}
USER jenkins
RUN /usr/local/bin/install-plugins.sh configuration-as-code configuration-as-code-support git workflow-cps-global-lib
其中 jenkins.yml就是上面我們準備好的配置文件, vault.yml文件內容如下所示:
CASC_VAULT_TOKEN=s.vf0oCbRDGrLNvfYjRfcdcZLg
CASC_VAULT_PATHS=secret/jenkins
CASC_VAULT_URL=http://192.168.31.9:8200
完整的 Dockerfile 文件可以在 獲取。
接下來使用上面的 Dockerfile 來構建鏡像:
$ docker build -t cnych/jenkins-casc:1.0 .
構建完成後可以直接通過下面的命令運行該容器:
$ docker run -d --name jenkins -p 8080:8080 -p 50000:50000 cnych/jenkins-casc:1.0
運行成功後可以在本地通過 8080 端口去訪問 Jenkins:
我們可以使用上面 jenkins.yml 配置文件中的用戶信息進行登錄,用戶名爲 cnych,密碼爲我們存入 Vault 中的 rootPassword:
securityRealm:
local:
allowsSignup: false
enableCaptcha: false
users:
- id: "cnych"
password: ${rootPassword}
登錄成功後可以進入 ManageJenkins頁面,在最下方可以看到 ConfigurationasCode的入口:
點擊可以進入插件的配置頁面:
我們可以在該頁面查看 Jenkins 配置信息,也可以下載配置信息、替換新的配置文件,比如我們這裏將登錄用戶名更改爲 cnych2,爲了方便我將該配置文件放置到 Github 上,地址爲:https://raw.githubusercontent.com/cnych/jenkins-casc/master/jenkins2.yml,使用該地址去替換配置源,點擊“應用新配置”,然後我們註銷後,可以嘗試使用 cnych2來進行登錄。
運行測試 Pipeline
最後,您可以爲示例應用程序創建和運行 Pipeline。下面是我這裏的一個簡單的 Pipeline 示例:
pipeline {
agent any
tools {
maven 'maven'
}
stages {
stage('Checkout') {
steps {
git url: 'https://github.com/cnych/jenkins-casc-example-service.git', credentialsId: 'github-cnych', branch: 'master'
}
}
stage('Test') {
steps {
sh 'mvn clean test'
}
}
stage('Build') {
steps {
sh 'mvn clean install'
}
}
}
}
由於我們上面的配置信息中有 maven 這個工具的配置,所以我們在 tools 中聲明 maven'maven'的時候會根據需求去下 maven 工具的:
Started by user cnych
Running in Durability level: MAX_SURVIVABILITY
[Pipeline] Start of Pipeline
[Pipeline] node
Running on Jenkins in /var/jenkins_home/workspace/test-jenkins-casc-pipeline
[Pipeline] {
[Pipeline] stage
[Pipeline] { (Declarative: Tool Install)
[Pipeline] tool
Unpacking https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip to /var/jenkins_home/tools/
......
可以看到下載的是 3.5.4版本,和上面的配置是一致的:
tool:
maven:
installations:
- name: "maven"
properties:
- installSource:
installers:
- maven:
id: "3.5.4"
相關鏈接
給大家推薦一個本人精心打造的一個精品課程,現在限時優惠中:從 Docker 到 Kubernetes 進階
掃描下面的二維碼(或微信搜索 k8s技術圈)關注我們的微信公衆帳號,在微信公衆帳號中回覆 加羣 即可加入到我們的 kubernetes 討論羣裏面共同學習。