用安裝在 Docker 中的 jenkins 執行 Docker 任務
題目有點繞,我先嚐試翻譯成人話——首先安裝一個 jenkins,這個 jenkins 是通過 docker 安裝的,然後要用這個 jenkins 來執行自動化的專案,專案中會用到 docker 命令。而這種工作場景,採用預設的配置,是完成不了的。
緣起
故事的緣起是這個部落格,他是基於 Github Pages 的,使用的過程就是用 MarkDown 寫文章,通過 HEXO 系統來構建,然後 push 到 github 上。
整體的流程實際上也不算複雜,但是作為一個程式員,總覺得會有更加智慧和省事的方法(實際上就是不折騰不舒服而已)。
所以我想構建一個系統,來達到部落格的自動構建和釋出的效果。鑑於這部分跟主題的關係不是特別大,還是不再贅述部落格的事了,也許以後回寫一篇部落格自動構建的文章,這裡就不展開了。
思路
提到自動構建,很自然的想到了jenkins;然後恰好我有一臺群暉的NAS,上邊可以跑Docker,所以又很自然的想到了通過Docker來安裝jenkins;有了jenkins,當然還要通過jenkins來執行自動化的任務,執行任務最簡單且對NAS系統侵入最小的方式是通過Docker執行任務。
問題
上面的思路看似很順暢,但是認真思考一下會發現,因為jenkins本身是執行在一個容器裡的,所以我們在建立任務的時候給出的指令碼或命令,都是在這個容器內執行的,這就出現了一個問題,這個容器內部是沒有docker環境的,所以執行不了docker命令,也就是說,必須想辦法來讓這個容器內部可以執行docker任務。
方案
經過一番搜尋之後,我找到了了這篇文章:ofollow,noindex">在(Docker裡的)Jenkins裡執行Docker 。
最終我選擇了文中提到的DooD(Docker-outside-of-Docker)
方案。
也就是所想辦法讓jenkins容器可以執行宿主機上的docker命令。
因為需要給予jenkins使用者sudo許可權,然而官方的映象jenkins預設是沒有sudo使用者許可權的,所以我在官方映象的基礎上新建了一個映象,預設給jenkins使用者sudo許可權。
改動的內容如下:
FROM jenkins:2.60.3 MAINTAINER andyzhshg <andyzhshg@gmail.com> USER root RUNapt-get update \ && apt-get install -y sudo \ && rm -rf /var/lib/apt/lists/* RUNecho"jenkins ALL=NOPASSWD: ALL">> /etc/sudoers USER jenkins
執行這個映象的容器很簡單:
docker run -d \ -v /var/run/docker.sock:/var/run/docker.sock \ -v $(which docker):/usr/bin/docker -p 8080:8080 \ andyzhshg/jenkins
需要重點關注帶有-v
引數的兩行:
第1行是將宿主機的/var/run/docker.sock
對映到容器中,這樣在容器中執行的docker命令,就會在宿主機上來執行。
第2行是將宿主機的docker
程式對映進容器中,這樣本省沒有安裝docker的jenkins容器就可以執行docker命令了(事實上容器裡是沒有執行docker的服務的,我們只是用這個對映進容器的docker來作為客戶端傳送docker的指令到/var/run/docker.sock
而已,兒/var/run/docker.sock
已經被連結到宿主機了)。
至此,我們的jenkins就準備就緒了。
當然,通常情況下我們還需要把jenkins自身的資料目錄連結到宿主機的目錄中,以保證容器被銷燬後還能夠再啟動新的資料而資料可以得到保留,這些可以參考jenkins官方映象的說明。
比如在docker run
加上-v your_jenkins_data_path:/var/jenkins_home
引數。
初始化jenkins的配置之後,我們就可以在jenkins上來新建一個自動化的構建專案了,比如我的blog自動構建專案的自動化指令碼大概就是這個樣子:
echo "new blogs posted, begin auto build." # 從gitlab拉取內容更新,構建並推送到github pages sudo docker run --rm -v /volume1/docker/blog/key/:/root/.ssh -v /volume1/docker/blog/up4dev:/blog andyzhshg/hexo # 推送一份內容原文到github做備份 sudo docker run --rm -v /volume1/docker/blog/key/:/root/.ssh -v /volume1/docker/blog/up4dev:/blog andyzhshg/hexo /blog/backup2github.sh echo "auto build done."
這雖然是一個特例化的應用場景,但是其他的專案也大同小異,只要準備好docker的映象,然後再jenkins執行docker run
就可以了。
需要注意的是,這裡的docker run
一定是要以sudo許可權執行的。