K8S結合Jenkins實現持續集成的動態配置詳情分享

前言:

Kubernetes,簡稱K8s,相信大家都不會陌生。這是一個開源的,用於管理雲平臺中多個主機上的容器化的應用。

Jenkins,是一個開源軟件項目,是基於Java開發的一種持續集成工具,用於監控持續重複的工作,旨在提供一個開放易用的軟件平臺,使軟件項目可以進行持續集成。

在程序員日常的開發當中,使用着各種不同的編程語言,流程中少不了開發、測試、打包、發佈等等的步驟,這其中的部分環節,是重複且必須的工作。所以慢慢地引入了持續集成的概念,從而減輕開發人員,運維人員的操作和時間成本,更好地服務好我們的程序猿(嗷嗷嗷 ~ 程序員太苦啦,是時候來點甜啦~)。

接下來讓我來給大家分享一下,如何結合K8S和Jenkins可以實現快速地實現以上的一些重複性且必要的工作,讓我們的攻城獅更好地專注在開發工作當中!

前置環境條件:

1、已經有部署好的K8S集羣環境;

2、已經在K8S環境中已經部署好Jenkins應用;

3、代碼倉庫(如gitlab、GitHub等)已經通過webhook等方式,和Jenkins能進行通訊;

4、jenkins添加好代碼倉庫對應的流水線作業。

 

1、登錄到Jenkins UI進行模版配置

 

登錄到Jenkins – 左菜單(系統設置) – 節點管理 – Configure Clouds,進行模版的配置

 

1.1 編輯Kubernetes模版

 

第一頁詳細配置如上圖,基本都是用默認值即可,有幾個地方需要根據實際的集羣信息進行填寫就可以啦,挺簡單的!!

 

1.2 編輯pod模版

2-1和2-2是pod模版的名稱和模版標籤

 

第二頁詳細配置如上圖,按照上圖說明即可。俗話說,工欲善其事,必先利其器,至此,jenkins的模版關鍵配置已經完成啦,接下來就是使用這些模版的時候啦,請繼續往下閱讀!!

 

2、可持續集成配置

2.1 Jenkinsfile使用詳解

這裏的lable是 上面的標籤設置的值

//模板需要修改的值:label(配置的jenkins的slave標籤),cloud:(配置的jenkins的cloud)
//定義變量
def label = "jenkins-slave-js"
//設置pod模版的信息,label是模版標籤,cloud是第一步設置的jenkins模版名
//以下操作都是在打包容器裏面進行,內容可以高度自定義,貼合不同的需求
podTemplate(label: label , cloud: 'kubernetes') {
    node(label) {
        //拉取倉庫代碼
        def myRepo = checkout scm
        def gitBranch = myRepo.GIT_BRANCH.replaceAll("origin/","").replaceAll("/","-").replaceAll("\\.","-")
        def timestamp = sh(script: "echo `date '+%Y%m%d%H%M%S'`", returnStdout: true).trim()
        def gitCommit = sh(script: "git rev-parse --short HEAD", returnStdout: true).trim()
        gitCommit = "${gitCommit}_${timestamp}"

        //鏡像標籤,這裏使用git分支名作爲鏡像的tag
        def imageTag = "${gitBranch}"
        //鏡像倉庫基礎地址
        def dockerRegistryUrl = "http://xxxxx"
        //應用服務名稱,統一用於以下各個變量名稱
        def appName = "testAbc"

        //模板需要更改的值 開始
        //helm工具發佈時,使用的名稱,這裏使用【應用名-分支名】的格式
        def helmReleaseName = "${appName}-${gitBranch}"
        //部署應用服務的命名空間
        def namespace = "${appName}"
        //鏡像的中間名稱,用於平均基礎鏡像地址
        def imageEndpoint = "${appName}/webapi"
        //模板需要更改的值 結束

        //完整鏡像地址(不包含鏡像tag)
        def image = "${dockerRegistryUrl}/${imageEndpoint}"
        //helmChart模版的倉庫名稱
        def chartName = "${appName}"
        //helmChart的版本
        def chartVersion = "1.0"
        //helmChart完整名稱
        def chartDirName = "${appName}/${appName}"
        //K8S的網絡模式,一般有Cluster(不對外訪問)、NodePort(釋放端口對外訪問)
        def serviceType = "ClusterIP"
        //如果serviceType值是NodePort,這裏可以設置指定供對外訪問的端口號,不指定則隨機,範圍詳見K8S的NodePort範圍,默認是30000-32767
        def serviceNodePort = ""
        //是否使用外部K8S存儲,是則設置true,否則設置false
        def createPvc = true
        //如果設置了使用外部存儲,則這裏需要填寫k8s的PVC資源的名稱,以便以發佈的應用服務能綁定此外部存儲
        def pvcName = "${gitBranch}-${appName}-configs-pvc"
        //設置外部存儲對應應用服務容器裏面的路徑
        def pvcMountPath = "/var/www/${appName}/storage"

        //定義不同階段,可以方便清晰地在jenkins UI上看到每個階段的耗時
        stage('單元測試階段') {
            script{

            }
        }
        stage('項目編譯階段') {
            //此處使用container指定第二步配置的容器名稱,就可以使用該容器環境的命令進行操作,如下面命令是前端node編譯代碼
            container("node"){
                sh "npm build ./main"
                sh "npm run serve"
            }
        }

        stage('構建 Docker 鏡像階段') {
            container('構建 Docker 鏡像') {
                withCredentials([[$class: 'UsernamePasswordMultiBinding',
                credentialsId: 'docker-harbor',
                usernameVariable: 'DOCKER_HUB_USER',
                passwordVariable: 'DOCKER_HUB_PASSWORD']]) {
                    //此處是引入了docker環境,進行docker的打包,推送到遠程倉庫等操作
                    container('docker') {
                        sh """
                        docker login ${dockerRegistryUrl} -u ${DOCKER_HUB_USER} -p ${DOCKER_HUB_PASSWORD}
                        docker build -t ${imageEndpoint}:${imageTag} .
                        docker tag ${imageEndpoint}:${imageTag}   ${dockerRegistryUrl}/${imageEndpoint}:${imageTag}
                        docker push ${image}:${imageTag}
                        """
                    }
                }
            }
        }
        //K8S使用了helm發佈工具進行應用服務的發佈
        stage('Helm 部署階段') {
            withCredentials([[$class: 'UsernamePasswordMultiBinding',
            credentialsId: 'docker-harbor',
            usernameVariable: 'DOCKER_HUB_USER',
            passwordVariable: 'DOCKER_HUB_PASSWORD']]) {
                container('helm') {
                    // 這裏也可以做一些其他的分支判斷是否要直接部署
                    echo "[INFO] 開始 Helm 部署"
                    echo "1 初始化helm client"
                    sh "helm init --client-only --stable-repo-url https://mirror.azure.cn/kubernetes/charts/"
                    //添加打包容器裏面的本地helm倉庫
                    sh "helm repo add --username ${DOCKER_HUB_USER} --password ${DOCKER_HUB_PASSWORD} ${chartName} http://${dockerRegistryUrl}/chartrepo/${chartName}"
                    echo "2 如果更新了chart包則需要更新repo倉庫"
                    sh "helm repo update"
                    echo "3 更新 ${helmReleaseName} 應用服務"
                    sh """
                    helm  upgrade --install ${helmReleaseName} ${chartDirName} \
                    --version ${chartVersion} \
                    --set namespace=${namespace} \
                    --set gitCommit=${gitCommit} \
                    --set gitBranch=${gitBranch} \
                    --set productionDeployment.image.repository=${image} \
                    --set canaryDeployment.image.repository=${image} \
                    --set productionDeployment.image.tag=${imageTag} \
                    --set canaryDeployment.image.tag=master \
                    --set createPvc=${createPvc} \
                    --set pvcName=${pvcName} \
                    --set pvcMountPath=${pvcMountPath} \
                    --set service.type=${serviceType} \
                    --set service.nodePort=${serviceNodePort} \
                    --namespace=${namespace}
                    """
                    echo "[INFO] Helm 部署應用成功..."
                }
            }
        }
    }
}

 

至此,我們已經完成配置好jenkins模版和jenkinsfile完整的一套可持續集成系統的工作,我們後續開發時,只需要合併好代碼,觸發webhook流水線,通知jenkins進行打包、發佈、部署的操作即可,實現真正解放我們的雙手啦!!!哈哈哈!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章