使用 Jenkins + Ansible 實現自動化部署 Nginx

首發於:Jenkins 中文社區nginx

本文介紹如何使用 Jenkins + Ansible 實現對 Nginx 的自動化部署。最終達到的效果有以下幾點:git

  1. 只要你將 Nginx 的配置推送到 GitHub 中,Jenkins 就會自動執行部署,而後目標服務器的 Nginx 配置自動生效。這個過程是冪等(idempotent)的,只要代碼不變,執行多少遍,最終效果不變。
  2. 若是目標機器沒有安裝 Nginx,則會自動安裝 Nginx。
  3. 自動設置服務器防火牆規則。

1. 實驗環境介紹

本次實驗使用 Docker Compose 搭建 Jenkins 及 Jenkins agent。使用 Vagrant 啓動一臺虛擬機,用於部署 Nginx。使用 Vagrant 是可選的,讀者可使用 VirtualBox 啓動一個虛擬機。使用 Vagrant 徹底是爲了自動化搭建實驗環境。github

如下是整個實驗環境的架構圖:docker

注意,圖中的 5123 <-> 80 表明將宿主機的 5123 端口請求轉發到虛擬機中的 80 端口。shell

  • Vagrant:虛擬機管理工具,經過它,咱們可使用文原本定義、管理虛擬機。
  • Ansible:自動化運維工具
  • Docker Compose:它是一個用於定義和運行多容器 Docker 應用程序的工具。可使用 YAML 文件來配置應用程序的服務。

2. 啓動實驗環境

  1. 克隆代碼並進入文件夾
    git clone https://github.com/zacker330/jenkins-ansible-nginx.git
    cd jenkins-ansible-nginx
    複製代碼
  2. 構建 Jenkins agent 的鏡像 須要自定義 Jenkins agent 鏡像有兩個緣由:
    1. 本次實驗,使用 Swarm 插件實現 Jenkins master 與 agent 之間的通訊,因此 Jenkins agent 須要啓動 swarm 客戶端。
    2. Jenkins agent 必須支持 Ansible。
    docker build -f JenkinsSlaveAnsibleDockerfile -t jenkins-swarm-ansible .
    複製代碼
  3. 啓動 Jenkins master 及 Jenkins agent
    docker-compose up -d
    複製代碼
    經過 http://localhost:8080 訪問 Jenkins master,若是出現「解鎖密碼」頁面,以下圖,則執行命令 docker-compose logs jenkins 查看 Jenkins master 啓動日誌。將日誌中的解鎖密碼輸入到表單中。而後就一步步按提示安裝便可。

  1. 安裝 Jenkins 插件 本次實驗須要安裝如下插件:
  2. 配置 Jenkins master 不執行任務 進入頁面:http://localhost:8080/computer/(master)/configure,以下圖所示設置:

  1. 確認 Jenkins 安全配置有打開端口,以供 Jenkins agent 鏈接。 咱們設置 Jenkins master 開放的端口,端口能夠是固定的 50000 ,也能夠設置爲隨機。設置連接:http://localhost:8080/configureSecurity/

  1. 啓動目標機器,用於部署 Nginx 在命令行中執行如下命令:
    vagrant up 
    複製代碼
    注意,Vagrantfile 文件中的 config.vm.box 值必須改爲你的 vagrant box 。

至此,實驗環境已經搭建好了。接下來就能夠新建 Jenkins 任務了。安全

3. 在 Jenkins 上建立部署任務

  1. 新建流水線任務

  1. 配置流水線 配置 Jenkins 任務從遠程倉庫拉取 Jenkinsfile,以下圖所示:

除此以外,不須要其它配置了,是否是很簡單?
複製代碼

4. 手工觸發一次自動化構建

點擊「當即構建」:bash

最終執行日誌以下:服務器

至此,部署已經完成。之後修改 Nginx 的配置,只須要修改代碼,而後推送到遠程倉庫,就會自動化部署。不須要手工登陸到目標機器手工修改了。架構

最後,咱們能夠經過訪問 http://localhost:5123,若是出現以下頁面說明部署成功:運維

5. 代碼講解

以上步驟並不能看出自動化部署真正作了什麼。那是由於咱們全部的邏輯都寫在代碼中。是的,能夠說是 everything is code

接下來咱們介紹代碼倉庫。

% tree -L 2
├── JenkinsSlaveAnsibleDockerfile # Jenkins agent 鏡像 Dockerfile
├── Jenkinsfile  # 流水線邏輯
├── README.md
├── Vagrantfile # Vagrant 虛擬機定義文件
├── docker-compose.yml # Jenkins 實現環境
├── env-conf # 全部應用配置
│   └── dev   # dev 環境的配置
├── deploy  # Ansible 部署腳本所在文件夾
│   ├── playbook.yaml
│   └── roles
└── swarm-client.sh # Jenkins swarm 插件的客戶端
複製代碼

5.1流水線邏輯

Jenkinsfile 文件用於描述整條流水線的邏輯。代碼以下:

pipeline{
  // 任務執行在具備 ansible 標籤的 agent 上
  agent { label "ansible"}
  environment{
     // 設置 Ansible 不檢查 HOST_KEY 
    ANSIBLE_HOST_KEY_CHECKING = false
  }
  triggers {
     pollSCM('H/1 * * * *')
  }
  stages{
    stage("deploy nginx"){
      steps{
        sh "ansible-playbook -i env-conf/dev deploy/playbook.yaml"
      }
}}}
複製代碼
  • environment 部分:用於定義流水線執行過程當中的環境變量。
  • triggers 部分:用於定義流水線的觸發機制。pollSCM 定義了每分鐘判斷一次代碼是否有變化,若是有變化則自動執行流水線。
  • agent 部分:用於定義整條流水線的執行環境。
  • stages 部分:流水線的全部階段,都被定義在這部分。

以上只是定義流水線是如何執行的,目前整條流水線只有一個 deploy nginx 階段,而且只執行了一條 ansible-playbook 命令。可是它並無告訴咱們部署邏輯是怎麼樣的。

5.2 部署邏輯

全部的部署邏輯,包括 Nginx 的安裝啓動、配置的更新以及加載,都放在 Ansible 腳本中。對 Ansible 不熟的同窗,能夠在本文末尾找到介紹 Ansible 的文章。

整個部署邏輯的入口在 deploy/playbook.yaml,代碼以下:

---
- hosts: "nginx"
 become: true
 roles:
    # Nginx 的部署
 - ansible-role-nginx
    # 對防火牆的設置
 - ansible-role-firewall
複製代碼
  • hosts:定義了 playbook 部署的目標主機分組名爲 nginx
  • roles:包含了兩個執行具體部署動做的 role,至於 role 內部邏輯,不在本文討論範圍,有興趣的同窗閱讀源碼。

5.3 配置管理

談到部署,就不得不談配置管理。

回顧前文中流水線中執行的 shell 命令:ansible-playbook -i env-conf/dev deploy/playbook.yaml 咱們經過 -i 參數指定部署時所使用的環境配置。經過這種方式實現環境配置與執行腳本的分離。這樣帶來如下幾個好處:

  1. 新增環境時,只須要複製現有的環境,而後將裏面的變量的值改爲新環境的便可。好比,要對測試環境進行部署,只須要將 -i 參數值改爲:env-conf/test
  2. 對配置版本化控制。

本次實驗中,各個環境的配置放在 env-conf 目錄中,目前只有 dev 環境,如下是 env-conf/ 目錄結構:

% cd env-conf/
% tree
└── dev
    ├── group_vars
    │   └── nginx.yaml
    ├── host_vars
    │   └── 192.168.52.10
    └── hosts
複製代碼
  • hosts文件:Ansible 中經過「分組」來實現對主機的管理。hosts 文件內容以下:
    [nginx]
    192.168.52.10
    複製代碼
  • host_vars 目錄:用於存放主機級別的配置變量,本例中 192.168.52.10 是一個 YAML 格式文件。注意文件名是該主機的 IP。咱們在文件中放主機相關的配置,好比 Ansible 鏈接主機時使用到的用戶名和密碼。
  • group_vars 目錄:用於存放組級別的配置變量。好比 nginx.yaml 對應的就是 nginx 這個組的的配置變量。文件名與 hosts 中的組名對應。

總結

到此,咱們完整的自動化部署已經講解完成。可是還遺留下一些問題:

  1. 本文只是安裝了一個「空」的 Nginx,可是沒有介紹 Nginx 真正配置。
  2. 目前主機的鏈接信息(SSH 密碼)是明文寫在 host_vars/192.168.52.10 文件中的,存在安全風險。
  3. 沒有介紹如何當 Java 應用部署時,如何自動更新 Nginx 的配置。

本文屬於使用 Jenkins + Ansible 實現自動化部署的入門文章,筆者將根據讀者的反饋決定是否寫續集。

若是以爲本文講的 Jenkins 流水線邏輯部分不夠過癮,能夠考慮入手一本最近纔出版的《Jenkins 2.x實踐指南》。長按下圖進行掃碼購買。

附錄

做者:翟志軍

相關文章
相關標籤/搜索