前言
隨著越來越多公司導入 DevOps 、Agile、Scrum 開發模式,作為基礎設施的 CI / CD Pipeline 也越來越被需要。但是導入的過程中,
總會遇到一些問題:
CI / CD Pipeline 該怎麼建 !?
Pipeline 工具該怎麼選擇 !?
該找誰負責 Devs、QAs、Ops !?
總之,不知道該怎麼辦的時候只好問天 XD
老天 : 去看書 !
掌握 DevOps 以下三個要點:
自動化、可視化、快速回饋
CI / CD 常見的工具有:
- Jenkins
- GitLab CI
- AWS CodePipeline
- Azure DevOps
- Travis CI
- Circle CI
- Drone CI
- …
該選誰呢...?
不管了 !!
先從最老工具的開始練習~~
持續整合一哥 --------- Jenkins
來建一條 Pipeline 吧 !
Environment Requirements :
- Jenkins + Ansible (Ubuntu 16.04)
- Remote Host ( Windows 10 )
由於測試環境需求,需要遠端控制一台或多台 Windows VM,如果透過 Jenkins Slave 來控制遠端電腦,在以往的經驗中,若是網路斷線或是 VM Snapshot Revert 的環境中常常造成 Jenkins 主控端與遠端不同步的狀況,必須靠著各種 Workaround 來排除困難。
這次的實驗,我想用 Jenkins + Ansible 來搭建測試環境的 Pipeline,因 Ansible 僅支援 Linux 作業系統,所以我選擇將 Jenkins 安裝在 Ubuntu 上。
======== 實驗開始 ========
Jenkins Installation
可以將以下 commands 存成 jenkins_install.sh,將 shell script 版控處理。
執行完成後,會印出一組初始的 Admin Password,打開瀏覽器連結至Jenkins Console ( https://localhost:8080 ),將初始密碼貼上後安裝官方建議 Plugins。
P.S. 若環境有任何防火牆,請記得把來源加入白名單
jenkins-ci.org
jenkins.io
pkg.jenkins.io
等待一切都安裝完成後,進到 Jenkins > Manage Jenkins > Manage Plugin 選 Available 安裝以下 Plugins:
Blue Ocean --- Pipeline可視化
AnsiColor --- Logging colors display
Ansible-plugin
接著,點選 Blue Ocean 進入設定 --- [
More]
讓 Jenkins account 擁有 sudo 權限 ( 不須可跳過 )
開啟 Linux Terminal 完成下列步驟後儲存離開。
1. sudo vim /etc/sudoers
2. add "Jenkins ALL=(ALL) NOPASSWPRD: ALL"
Jenkins 安裝的部分,暫時告一個段落,接著安裝 Ansible。
Ansible 是一個 Base on Python 的自動化組態管理工具,經由執行 YAML 管裡設定,格式編寫容易,容易上手與維護簡單,不需要透過代理或安裝 Client 來控制遠端機器,僅透過 SSH ( Linux ) 與 Winrm ( Windows )來執行遠端程序,
2015 年由 Red Hat 收購。
Ansible 2.9.0 Installation
安裝 Windows Remote Control Packages
pip install pywinrm
開始建立 Ansible 專案
# create ansible folder
mkdir ansible
cd ansible
編輯 Ansible 設定檔 ansible.cfg,指定 inventory 與 ansible.log
vim ansible.cfg
[defaults]
inventory = inventory
log_path = ansible.log
這次的實驗我們需要一台 Windows 遠端主機,
Windows 遠端主機需要有 PowserShell 3.0 以上的版本。
PowserShell 權限必須設置為 RemoteSigned 或 Unrestricted 並開啟 WinRm 相關設定。以系統管理員身分執行 PowerShell,確認 PowserShell 權限,若權限不為上述兩項,可以更改權限 Set-ExecutionPolicy RemoteSigned
PS C:\Users\Wis> Get-ExecutionPolicy
RemoteSigned
開啟 WinRm Service 進行基礎配置
winrm quickconfig
# Enable WinRm Auth
winrm set winrm/config/service/auth '@{Basic="true"}'
# Enable Allow Un-encrypt
winrm set winrm/config/service '@{AllowUnencrypted="true"}'
# Verify WinRm Listener
winrm enumerate winrm/config/listener
接著,編輯 inventory 檔,將遠端 Windows Host 資訊填入
vim inventory
[windows] # group name
win10 ansible_host=10.1.2.1
[windows:vars] # define variable for windows group
ansible_user=win_user
ansible_password=win_password
ansible_port=5985
ansible_connection=winrm
ansible_winrm_server_cert_validation=ignore
測試一下 Ansible 連線
$> ansible windows -m win_ping
win10 | SUCCESS => {
"changed": false,
"ping": "pong"
}
連線成功囉!!
Ansible - 資料夾結構
- Jenkinsfile
- ansible
- ansible.cfg
- inventory
- playbook.yml
- remote_run.py
接下來,把想做的程序寫進 playbook.yml 裡,預期在遠端 Windows Host 執行 Python 程式 remote_run.py
vim playbook.yml
- hosts: windows
gather_facts: no
vars:
py_src_name: remote_run.py
py_dst_dir: C:\temp\ansible
tasks:
- name: Create folder on remote host
win_file:
path: '{{ py_dst_dir }}'
state: directory
- name: Copy python file to remote host
win_copy:
src: '{{ py_src_name }}'
dest: '{{ py_dst_dir }}\{{ py_src_name }}'
- name: Execute python program
win_shell: python '{{ py_dst_dir }}\{{ py_src_name }}'
簡單的寫一個執行5秒的 Python 程式,給遠端 Windows Host 執行 ---remote_run.py
vim remote_run.py
import time
for i in range(5):
print("this is loop [{}]".format(i))
time.sleep(1)
測試一下 Ansible Playbook
# 最後補上 -vvv 可顯示 debug info
ansible-playbook playbook.yml
Blue Ocean 會在 Jenkins console 上建立一個可視的 Pipeline,而設定完與 GitHub 連線, Jenkinsfile 會放在 Git repository 最上層 ( 可任意改變位置,Jenkins 也須跟著調整 Jenkinsfile Path )。
Jenkinsfile 內容如下:
pipeline {
agent any
stages {
stage('Windows Host Step') {
steps{
dir(path: 'ansible') {
ansiColor(colorMapName: 'xterm') {
ansiblePlaybook(
playbook: 'playbook.yml',
inventory: 'inventory',
colorized: true)
}
}
}
}
}
}
最後,將修改的檔案推上 GitHub, 就完成囉~!
- 自動化 - 未來加入更多自動化測試與工作流程。
- 工作流程可視化 - 藉由 Blue Ocean 的介面,可以得知 Pipeline 的狀態。
- 快速回饋 - 藉由每次的 Code Commit 觸發一個 Jenkins CI Run 達成快速回饋的機制。
Reference: