docker jenkins ci/cd

Jenkins 是一個很老的 ci/cd 服務了,但是至今並未過時,幾乎是各種公司的首選,足見其功能強大

最近用 docker 搭建了一個 Jenkins 服務,實現了代碼提交後自動觸發測試和部署,再也不用手動發佈了,節省了大量的時間

製作 docker 鏡像

FROM jenkins/jenkins:2.191
COPY executors.groovy /usr/share/jenkins/ref/init.groovy.d/executors.groovy
USER root
RUN apt-get update
RUN apt-get install -y build-essential

這裏我在基礎鏡像上安裝了 make 工具,因爲我大部分項目都是用 make 構建

部署 jenkins 到 docker swarm

我將 jenkins 服務本身也部署到了 docker 集羣中,compose 文件內容如下:

version: "3.5"
services:
  jenkins:
    image: hatlonely/jenkins:${version}
    hostname: jenkins
    user: root
    ports:
      - "8080:8080"
      - "50000:50000"
    deploy:
      replicas: 1
      restart_policy:
        condition: on-failure
    volumes:
      - "/var/docker/jenkins/data:/var/jenkins_home"
      - "/var/docker:/var/docker"
      - "/var/run/docker.sock:/var/run/docker.sock"
      - "/bin/docker:/usr/bin/docker"
    networks:
      - jenkinsnet

networks:
  jenkinsnet:
    name: jenkinsnet

這裏主要要解決兩個問題:

jenkins 本身作爲容器在 docker 集羣環境下運行,如何訪問外部 docker 環境
volumes:

  • "/var/run/docker.sock:/var/run/docker.sock"
  • "/bin/docker:/usr/bin/docker"
    docker 是 c/s 架構,會在本地後臺啓動一個服務來管理和維護容器,客戶端通過套接字和服務通信,將套接字映射到容器內部,可以讓容器也能訪問宿主機的 docker,此外將 docker 命令本身映射到容器內部,就不需要在容器內部再安裝一個 docker 了

部署服務的數據掛載,如何掛載宿主機
volumes:

  • "/var/docker/jenkins/data:/var/jenkins_home"
  • "/var/docker:/var/docker"
    這裏我有個實踐的約定,會將所有 docker 容器的狀態映射到宿主機的 /var/docker/{service} 下面,Jenkins 的狀態保存在 /var/jenkins_home 下,這裏我們把它直接映射到 /var/docker/jenkins/data 下,另外,其他的服務需要通過容器內的 Jenkins 部署,volume 掛載的數據只能映射到 Jenkins 容器內部,而我們約定,這些數據只能在 /var/docker 下,因此,只需要再掛載這個目錄,其他服務的狀態就都能持久化到宿主機了

完整代碼參考:https://github.com/hpifu/docker-jenkins

執行 make build 完成鏡像的製作(我把 Dockerfile 中的端口映射註釋掉了,是因爲我的環境裏面所有的服務都統一用 nginx 作反向代理對外了)
執行 make deploy 即可完成 Jenkins 的部署

創建第一個流水線項目,部署 Jenkins 服務本身
部署完成之後,訪問 http://127.0.0.1:8080,按照提示很容易就可以完成初始化,初始化完成之後,/var/jenkins_home 裏面會產生很多數據,這些數據是 Jenkins 的狀態,前面我們已把這個目錄映射到了宿主機的 /var/docker/jenkins/data,這樣重啓 Jenkins 數據也不會丟失

初始化完成之後終於可以創建任務了,相比之下,這個過程可能是最簡單的

【新建任務】→【流水線】(名稱填 docker-jenkins)→【確定】

General

✔️ github 項目: [email protected]:hpifu/docker-jenkins.git
✔️ 不允許併發構建
構建觸發器

✔️ GitHub hook trigger for GITScm polling
流水線

✔️ Pipeline script
pipeline {
agent any
stages {
stage('image') {
steps {
sh 'make build'
}
}
stage('deploy') {
steps {
sh 'make deploy'
}
}
}
}
點保存之後點立即構建即可

github webhook
要實現 github push 之後自動觸發,需要在 github 設置 webhook(需要 owner 權限),另外需要 Jenkins 有對外網可見的地址

進入項目主頁,如本項目主頁:https://github.com/hpifu/docker-jenkins
點擊【Settings】→【Webhooks】→【Add webhook】
Payload URL: <https://<your jenkins server address>/github-webhook/>
Content type:<application/json>
配置完成後,可以提交下試試,在 webhooks 頁面可以看到剛剛配置的 hook,拖到最下面有最近的 hook 觸發記錄

Jenkins 第一次構建需要手動觸發,之後的構建都會自動觸發,偶爾沒有觸發,可能是 github 和你的服務之間的網絡問題,可去 github webhook 頁面檢查 hook 觸發記錄

我的最佳實踐
對項目作一些簡單的規範,能大大地簡化整個部署流程,前面創建項目的時候我們使用的是 Pipeline script,可以看到還有另一個選項 Pipeline script from SCM 支持直接從一個 git 地址獲取這個腳本,一般名爲 Jenkinsfile,這也是我推薦的一種方式,Jenkinsfile 和代碼一起維護起來,這樣不同的項目,不同的 Jenkins 環境,創建的 Jenkins 任務都是一樣的,大大簡化了創建任務的複雜度

另一方面,項目的構建,編譯,運行,打包,部署,測試等都通過 Makefile 實現,這樣所有執行的動作都變成了一條 make 命令,Jenkinsfile 的邏輯變得非常簡單,甚至可以是通用的,下面是一些示例:

go 項目: https://github.com/hpifu/go-tech/blob/master/Jenkinsfile
vue 項目: https://github.com/hpifu/vue-tech/blob/master/Jenkinsfile
通過這些示例可以看到,複雜的構建過程都被 Makefile 屏蔽了,而通過 Makefile,不同類型,不同語言的項目的構建過程也對 Jenkins 屏蔽了,達到了統一

鏈接
參考代碼: https://github.com/hpifu/docker-jenkins
docker hub: https://hub.docker.com/_/jenkins
轉載請註明出處
本文鏈接:https://tech.hatlonely.com/article/57
Golang 課程火熱招生資料找WeChat:17812796384

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