玩轉 CICD 之 使用 Jenkins Pipeline 實現構建和遠程部署

這是我參與更文挑戰的第3天,活動詳情查看:更文挑戰git

本文記錄瞭如何使用 Jenkins Pipeline 實現構建和遠程部署。github

自動化流程

企業裏常見的項目自動化流程應該構建機從代碼倉拉取代碼進行構建,構建完成後會將產物推送到製品庫中,好比鏡像倉, 而後中間會有測試環境,用於進行自動化測試或人工測試,最後進行遠程部署。golang

項目結構

這裏咱們用的 Go 的項目結構,它大概的結構應該是下面這樣的:web

|-- my-app
    |-- .gitignore
    |-- README.md
    |-- LICENSE
    |-- go.mod
    |-- go.sum
    |-- main.go
    |-- pkg
        |-- ...
複製代碼

項目構建

由於這裏構建的是 Go 的項目,若是用到私有庫,在 go mod tidy 時會要求提供 Git 憑證,咱們能夠如今 Jenkins 的憑證管理中建立 Username with password 類型的憑證,其中 Username 就是 GitHub 的用戶名,password 則是 GitHub 的 AccessToken,這裏主要用到的是 AccessTokenUsername 其實並不須要。docker

但在 Jenkins Pipeline 中使用 usernamePassword 時要求同時定義用戶名變量名 usernameVariable 和 密碼變量名 passwordVariablebash

stage('Build') {
    steps {
        withCredentials(bindings: [
            usernamePassword(credentialsId: 'GITHUB_CREDENTIAL',
                usernameVariable: 'GITHUB_USER',
                passwordVariable: 'GITHUB_ACCESS_TOKEN'
            )
        ]) {
            sh ''' git config --global url."https://${GITHUB_ACCESS_TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/" go mod tidy go build -o bin/my-app main.go '''
        }
    }
}
複製代碼

遠程部署

在構建完成後,咱們會將構建產物推送到製品庫,而後咱們能夠從製品庫中拉取構建產物進行部署測試環境並進行測試,在驗證經過後,會從製品庫中拉取驗證經過的產物進行部署上線。服務器

但在本文中,咱們的應用相對簡單,能夠忽略推送產物到製品庫以及中間的測試驗證環節,目標是實現構建後當即部署上線。markdown

通常來講,線上環境和構建環境不會是同一臺機器,因此這個時候咱們須要將構建產物複製到另外一臺服務器上,而後在另外一臺服務器上進行部署。app

因爲須要對另外一臺服務器進行操做,因此咱們須要在 Jenkins 上配置 DEPLOY_HOSTDEPLOY_PORTSSH_CREDENTIAL 三個憑證,其中 DEPLOY_HOSTDEPLOY_PORTSecret text 類型的憑證,SSH_CREDENTIALSSH Username with private key 類型的憑證。ssh

stage('Deploy') {
    environment {
        DEPLOY_HOST = credentials('DEPLOY_HOST')
        DEPLOY_PORT = credentials('DEPLOY_PORT')
    }
    steps {
        withCredentials([
            sshUserPrivateKey(credentialsId: 'SSH_CREDENTIAL',
                keyFileVariable: 'SSH_KEY',
                usernameVariable: 'SSH_USERNAME'),
        ]) {
            sh """ mkdir -p ~/.ssh && chmod 700 ~/.ssh echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config cat ${SSH_KEY} > ~/.ssh/id_rsa && chmod 400 ~/.ssh/id_rsa scp -P ${DEPLOY_PORT} bin/my-app ${SSH_USER}@${DEPLOY_HOST}:/data/my-app ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} \"nohup /data/my-app >> /data/my-app.log 2>&1 &\" """
        }
    }
}
複製代碼

部署的步驟主要包括:

  1. 複製構建產物到部署服務器
  2. 在部署服務器上執行部署命令,好比 nohup /data/my-app >> /data/my-app.log 2>&1 &

其中簡化了一些細節,好比在部署前,咱們須要先備份數據。因此這裏咱們能夠寫一個複雜的部署腳本 deploy.sh 放在項目中,而後在 Jenkins Pipeline 中使用 scp 將部署腳本文件複製到部署服務器,假設放在 /data/deploy.sh,最後只需 ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} /bin/bash /data/deploy.sh 便可。

完整的 Jenkins Pipeline

pipeline {
    agent {
        docker {
            image 'golang:1.15-alpine'
            args '-v /data/my-app-cache:/go/.cache'
        }
    }

    options {
        timeout(time: 20, unit: 'MINUTES')
        disableConcurrentBuilds()
    }

    stages {
        stage('Build') {
            steps {
                withCredentials(bindings: [
                    usernamePassword(credentialsId: 'GITHUB_CREDENTIAL',
                        usernameVariable: 'GITHUB_USER',
                        passwordVariable: 'GITHUB_ACCESS_TOKEN'
                    )
                ]) {
                    sh ''' git config --global url."https://${GITHUB_ACCESS_TOKEN}:x-oauth-basic@github.com/".insteadOf "https://github.com/" go mod tidy go build -o bin/my-app main.go '''
                }
            }
        }

        stage('Deploy') {
            environment {
                DEPLOY_HOST = credentials('DEPLOY_HOST')
                DEPLOY_PORT = credentials('DEPLOY_PORT')
            }
            steps {
                withCredentials([
                    sshUserPrivateKey(credentialsId: 'SSH_CREDENTIAL',
                        keyFileVariable: 'SSH_KEY',
                        usernameVariable: 'SSH_USERNAME'),
                ]) {
                    sh """ mkdir -p ~/.ssh && chmod 700 ~/.ssh echo 'StrictHostKeyChecking no' >> /etc/ssh/ssh_config cat ${SSH_KEY} > ~/.ssh/id_rsa && chmod 400 ~/.ssh/id_rsa scp -P ${DEPLOY_PORT} bin/my-app ${SSH_USER}@${DEPLOY_HOST}:/data/my-app ssh -p ${DEPLOY_PORT} ${SSH_USER}@${DEPLOY_HOST} \"nohup /data/my-app >> /data/my-app.log 2>&1 &\" """
                }
            }
        }
    }
}
複製代碼

感謝閱讀

筆者不才,很是歡迎你們對本文的內容進行指正,或者與筆者進行探討!

我的博客

k8scat.com/posts/remot…

相關文章
相關標籤/搜索