1. 程式人生 > >實戰docker+jenkins+git構建持續集成環境

實戰docker+jenkins+git構建持續集成環境

docker jenkins docker+jenkins+git git

本文重點介紹jenkins以及讓jenkins如何實現在docker容器中運行。jenkins和docker私有倉庫又是怎麽結合的。docker說明及安裝和git說明及安裝在本文中不會特別詳細的介紹。

?並且,在本文中不著重介紹原理性的東西,比如不會介紹什麽是持續集成、持續構建等等。本文的重點是實戰為主。對持續集成、持續交互、持續部署不太了解的朋友可以參考這篇文章了解一下:https://www.zhihu.com/question/23444990

1.背景說明

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

先來了解一下比較典型的java項目發布工作流程:
1.java項目開發 >> 2.提交項目代碼到(git或svn) >> 3. 拉取項目代碼(jenkins或手動) >> 4.編譯項目代碼(jenkins或手動) >> 5.發布項目到tomcat,並運行tomcat服務 >> 6.測試
技術分享圖片

在來看看用docker+jenkins+git發布java項目流程又是怎樣的呢:
1.java項目開發 >> 2.提交項目代碼git容器 >> 3.jenkins容器拉取項目代碼 >> 4.maven編譯構建項目 >> 5.jenkins發布項目到tomcat容器 >> 6.測試

技術分享圖片

看到上面的流程後,在沒有jenkins的情況下這些步驟都是手工完成的,有了Jenkins的幫助,在這6步中,除了第1步,後續的5步都是自動化完成的。當你完成了提交,Jenkins會自動運行你的編譯腳本,編譯成功後,再運行你的測試腳本,這一步成功後,接著它會幫你把新程序發布出去,特別的,在最後一步,你可以選擇手動發布,或自動發布。

2.環境描述

1、服務器部署信息

服務器 主機名 IP 運行服務
jenkins服務器 jenkins 172.18.18.32 安裝docker、 運行jenkins容器、git客戶端、jdk、maven
docker服務器 docker 172.18.18.33 安裝docker、創建鏡像運行java項目:tale
Git和私有倉庫服務器 git_registry 172.18.18.34 安裝docker、git服務、運行registry私有倉庫容器

說明:

  • 本文中完全是模擬生產環境中服務器的規劃:git單獨部署、jenkins單獨部署。如果你沒有這麽多服務器,可以把git服務器和jenkins服務器放在一起來測試。前提是不要搞暈了就可以。
  • tale是一個java寫的開源博客系統,這個項目沒有任何依賴,所以在此次測試中可以用它做為構建、部署的對象。當然如果你有其它的java項目也可以不用它來測試。
  • tale訪問地址:https://github.com/otale/tale.git

2、版本信息

名稱 版本 軟件包 說明
服務器 Centos 7.4 linux系統
docker 17.12.0-ce yum安裝 docker引擎服務
jdk 1.8.0_45 jdk-8u45-linux-x64.tar.gz 運行jenkins需要的JDK環境
maven 3.5.0 apache-maven-3.5.0-bin.tar.gz 構建java項目需要的工具
jenkins 最新版本 docker hub下載最新jenkins鏡像 持續集成工具
registry 最新版本 docker hub下載最新registry鏡像 docker私有倉庫

jdk官方下載地址:http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk8-downloads-2133151-zhs.html
maven官方下載地址:https://maven.apache.org/download.cgi
jenkins官方鏡像地址:https://hub.docker.com/_/jenkins/
registry官方鏡像地址:https://hub.docker.com/_/registry/

3.部署環境

3.1 部署git服務

註意:這個步驟在 git_registry 服務器上操作

1、安裝git:

[root@git_registry ~]# yum -y install git

2、創建git用戶:

[root@git_registry ~]# useradd  git
[root@git_registry ~]# passwd git
Changing password for user git.
New password: 
BAD PASSWORD: The password is shorter than 8 characters
Retype new password: 
passwd: all authentication tokens updated successfully.

3、創建倉庫:
創建app.git倉庫,倉庫名自定義,這一步需要切換剛才創建的git用戶操作

[git@git_registry root]$ cd /home/git/
[git@git_registry ~]$ cd app.git/
[git@git_registry app.git]$ git --bare init
Initialized empty Git repository in /home/git/app.git/
#然後用ls查看一下app.git倉庫初始化完成了:
[git@git_registry app.git]$ ls
branches  config  description  HEAD  hooks  info  objects  refs

3.2 驗證git服務

註意:這個步驟在 jenkins 服務器上操作

正常來說,開發用自己的電腦把寫好的代碼push到git倉庫就算完成驗證,在本文中去github裏下載一個java項目(tale)來驗證,我們就用jenkins這臺服務器做為git客戶端吧:
1、下載git客戶端

[root@jenkins ~]# yum -y install git

2、下載tale項目包

#先創建個目錄來存放tale包,隨便放在哪個空目錄下都行,後面我們還需要把它移走
[root@jenkins ~]# mkdir /tale
[root@jenkins ~]# git  clone  https://github.com/otale/tale.git
#在查看下載好的tale項目
[root@jenkins tale]# ls
bin  LICENSE  package.xml  pom.xml  README.md  README_ZH.md  src

3、生成公鑰,拷貝到git服務器

[root@jenkins tale]# ssh-keygen  -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): 
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:S6qxaVNuJ5inLxGDdrqqlpNsG4AsmcXH88dXckHdIOI root@jenkins
The key‘s randomart image is:
+---[RSA 2048]----+
|          ..+..o |
| . .     . . o. .|
|  o.+     E o    |
|o+o.+o .   +     |
|*o o o. S .      |
|o . . .+ o       |
|..o..*. .        |
| Bo *== .        |
|*oo.=B.o         |
+----[SHA256]-----+

#把公鑰拷貝到git服務器,註意用剛才的git用戶
[root@jenkins tale]# ssh-copy-id  [email protected]
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
[email protected]‘s password: 

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh ‘[email protected]‘"
and check to make sure that only the key(s) you wanted were added.

4、用git clone驗證

#先創建個目錄,目錄名隨便定義,用於拉取git服務器上創建的app.git倉庫
[root@jenkins tale]# mkdir /git
[root@jenkins tale]# cd /git/

#配置下git客戶端的用戶信息
[root@jenkins git]# git config --global  user.email "[email protected]"
[root@jenkins git]# git config --global user.name "test"

#在來git clone,由於app.git倉庫是空的,所以會很快
[root@jenkins git]# git clone  [email protected]:/home/git/app.git
Cloning into ‘app‘...
warning: You appear to have cloned an empty repository.

5、把之前下載的tale項目push到app.git倉庫中

#先移動至剛才/git目錄下
[root@jenkins git]# mv /tale/* /git/app/
[root@jenkins git]# cd /git/app/
[root@jenkins app]# ls
bin  LICENSE  package.xml  pom.xml  README.md  README_ZH.md  src

#然後提交到git倉庫
[root@jenkins app]# git add .
[root@jenkins app]# git commit  -m "add project tale"
[root@jenkins app]# git push  origin master
Counting objects: 297, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (255/255), done.
Writing objects: 100% (297/297), 6.35 MiB | 0 bytes/s, done.
Total 297 (delta 22), reused 0 (delta 0)
To [email protected]:/home/git/app.git
 * [new branch]      master -> master

3.3 部署docker私有倉庫

註意:這個步驟在 git_registry 服務器上操作

我們還是用官方的鏡像來創建docker私有倉庫:

[root@git_registry /]# docker run -d -v /opt/registry:/var/lib/registry -p 5000:5000 --restart=always --name rregistry registry

查看一下私有倉庫已經起來了:

[root@git_registry /]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
4ac357e4b6dd        registry            "/entrypoint.sh /etc…"   7 seconds ago       Up 7 seconds        0.0.0.0:5000->5000/tcp   rregistry

3.4 配置docker服務器

註意:這個步驟在 docker服務器上操作

這臺服務器就是在docker中運行剛才的tale 這個java項目的服務器,所以我們要在這臺服各器上安裝下docker。

1、安裝Docker

[root@docker ~]# yum install -y yum-utils device-mapper-persistent-data lvm2
[root@docker ~]# yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
[root@docker ~]# yum install docker-ce

2、配置鏡像源為國內官方源

[root@docker ~]# vim /etc/docker/daemon.json
{
  "registry-mirrors": [ "https://registry.docker-cn.com"],
  "insecure-registries": [ "172.18.18.34:5000"]
}

註意書寫格式為json格式,有嚴格的書寫要求;第1行是國內鏡像源,第2行是docker私有倉庫地址。172.18.18.34就是docker私有倉庫的地址,添加後連接docker私有倉庫就是用http協議了。

3、啟動dokcer服務

[root@docker ~]# systemctl restart docker

4、部署JDK
由於後面運行java容器需要jdk環境,jdk如果放在容器中運行容器又相當重,所以就在宿主機上部署jdk,後面創建java容器的時候把宿主機的jdk路徑掛載到容器就去。部署jdk很簡單,解壓就行:

[root@jenkins /]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/

我們把它解壓在宿主機的/usr/local目錄中。

5、構建tale開源博客的基礎鏡像
其實,這個鏡像隨便在哪臺服務器上構建都行,我這裏就直接在這臺docker服務器構建了:

[root@docker /]# mkdir dockerfile_tale
[root@docker /]# cd dockerfile_tale/
[root@docker dockerfile_tale]# vim Dockerfile
FROM centos:7
RUN yum install epel-release -y
RUN yum install nginx supervisor -y && yum clean all
RUN sed -i ‘47a proxy_pass http://127.0.0.1:9000;‘ /etc/nginx/nginx.conf
COPY supervisord.conf /etc/supervisord.conf
ENV PATH /usr/local/jdk/bin:$PATH
WORKDIR /tale
CMD ["/usr/bin/supervisord"]

說明:此Dockerfile以centos7為基礎鏡像,通過yum安裝nginx、supervisor服務。定義jdk的環境變量,並通過supervisord來啟動nginx和java項目。下面來看下supervisord.conf配置。

[root@docker dockerfile_tale]# ls /dockerfile_tale/
Dockerfile  supervisord.conf
[root@docker dockerfile_tale]# cat supervisord.conf 
[supervisord]
nodaemon=true
[program:tale]
command=/usr/local/jdk/bin/java -jar /tale/tale-least.jar
autostart=true
autorestart=true
[program:nginx]
command=/usr/sbin/nginx -g "daemon off;"
autostart=true
autorestart=true

上面的配置都是基礎配置,分別是通過java -jar啟動tale-least:jar包,nginx -g 啟動nginx服務。

然後,構建鏡像:

[root@docker dockerfile_tale]#docker build  -t tale:base .
[root@docker dockerfile_tale]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
tale                base                b6d5028ecc3b        2 seconds ago       372MB
centos              7                   2d194b392dd1        6 days ago          195MB

對tale:base鏡像打tag,並上傳到registry私有倉庫:

[root@docker /]#docker tag tale:base  172.18.18.34:5000/tale:base
[root@docker /]#docker push 172.18.18.34:5000/tale:base

3.5 部署jenkins

註意:這個步驟在 jenkins 服務器上操作

1、部署JDK
由於jenkins需要jdk環境,jdk如果放在容器中運行容器又相當重,所以就在宿主機上部署jdk,後面創建jekins容器的時候把宿主機的jdk路徑掛載到容器就去。部署jdk很簡單,解壓就行:

[root@jenkins /]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/

我們把它解壓在宿主機的/usr/local目錄中。

2、部署maven
由於本文後期是通過jenkins運行java項目,所以我們還需要maven工具,maven也和jdk部署一樣,也不想在容器中運行maven,所以也是部署在宿主機上然後掛載到容器中。也是直接解壓:

[root@jenkins local]# tar -zxvf apache-maven-3.5.0-bin.tar.gz  -C /usr/local/

查看一下這兩個源碼軟件是否解壓:
技術分享圖片

3、生成jenkins鏡像:
在本文中我們引用docker hub中的官方鏡像來編寫個Dockerfile文件:

#說明:下面我創建個目錄來放置jenkins的Dockerfile文件,這個文件隨便放在哪個目錄都行
[root@jenkins /]# mkdir /Dockerfile_jenkins
[root@jenkins /]# cd Dockerfile_jenkins/
[root@jenkins Dockerfile_jenkins]# vim Dockerfile
FROM jenkins
USER root
RUN echo ‘‘ > /etc/apt/sources.list.d/jessie-backports.list && wget http://mirrors.163.com/.help/sources.list.jessie -O /etc/apt/sources.list
RUN apt-get update && apt-get install -y git

Dockerfile說明:第1行FROM引用了官方鏡像jenkins,這個jenkins是基於debiant系統構建的。第2行USER使用root用戶來運行。第3行RUN更改了apt-get源為國內163的源。第4行RUN是安裝git客戶端,由於官方的jenkins鏡像沒有安裝git客戶端,我們需要在jenkins容器中調用git命令,所以在此需要安裝下git客戶端,當然你也可以啟動jenkins容器後在容器中安裝;不過筆者建議需要安裝的東西最好的Dockerfile中就弄好。

4、構建jenkins鏡像:

[root@jenkins Dockerfile_jenkins]# docker build -t jenkins:v1 .

查看一下構建的鏡像:
技術分享圖片

5、創建jenkins鏡像:

[root@jenkins / ]#docker run -d --name jenkins -p 8080:8080 -v /var/jenkins_home/:/var/jenkins_home -v /usr/local/apache-maven-3.5.0:/usr/local/maven -v /usr/local/jdk1.8.0_45:/usr/local/jdk -v ~/.ssh:/root/.ssh jenkins:v1

參數說明,上面的參數都是最常用的,都比較很簡單很好理解
-d:在後臺運行容器;
-p:映射端口;
-v:宿主機的目錄掛載到容器;/var/jenkins_home 這個目錄在宿主機中空的,這是把容器中的jenkinis主目錄綁定到宿主機中來,其它的兩個目錄是之前解壓的工具;

來查看jenkins運行狀態:

[root@jenkins Dockerfile_jenkins]# docker top  jenkins 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                25304               25289               0                   10:10               ?                   00:00:00            /bin/tini -- /usr/local/bin/jenkins.sh
root                25335               25304               1                   10:10               ?                   00:00:17            java -jar /usr/share/jenkins/jenkins.war
[root@jenkins Dockerfile_jenkins]# docker ps -l
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                               NAMES
0c10bec5812e        jenkins:v1          "/bin/tini -- /usr/l…"   18 minutes ago      Up 18 minutes       0.0.0.0:8080->8080/tcp, 50000/tcp   jenkins

上面的兩個狀態顯示jenkins容器運行都是OK的!!!

4.配置jenkins

4.1 初始化配置

  • 通過http://ip:8080 來訪問jenkins服務;
    技術分享圖片
    從上圖給出的提示,需要從/var/jenkins_home/secrets/initialAdminPassword獲取密碼

    [root@jenkins /]# cat /var/jenkins_home/secrets/initialAdminPassword
    dff1d41be2254f87ad80a65eac621cb8
  • 登錄成功後回讓你選擇插件的安裝,可以選擇建議的安裝也可以自己進行選擇,不清楚的話可以使用建議的安裝。由於建議安裝的插件比較多,安裝的過程有點慢,多等待一會;
    技術分享圖片

技術分享圖片

  • 安裝完成後最好新創建一個管理員賬戶代替之前的臨時自動生成的密碼賬戶;
    技術分享圖片

4.2 系統設置

進入“系統管理” -- “系統設置”,主要是把docker這臺服務器通過ssh的形式添加進來,後期部署dokcer容器,如下圖:
技術分享圖片
參數說明:
Name:172.18.18.33-docker
Hostname:172.18.18.33
Username:root
Remote Directory:/data 這個意思是把代碼發布到172.18.18.83 /data目錄中,需要手動創建個目錄
Use password authentication, or use a different key:勾選它
?Passphrase / Password:輸入172.18.18.83這臺docker服務器的密碼

4.3 配置Maven、jdk、git環境

1、jdk配置
進“系統管理” -- "Global Tool Configuration",添加jdk安裝,如下圖:
技術分享圖片
參數說明:
別名:自定義就行;
JAVA_HOME:這個是你jenkins容器裏的JDK路徑,不是宿主機的JDK路徑;

2、maven配置
進“系統管理” -- "Global Tool Configuration",添加maven安裝,如下圖:
技術分享圖片
參數說明:和jdk一樣,MAVEN_HOME 的路徑也是指向jenkins容器裏的maven路徑;

3、git配置
這裏我沒有動git的配置,讓它為默認配置,如下圖:
技術分享圖片

4.4 配置java項目

1、構建maven項目
點擊“新建” -- “構建一個maven項目,項目名稱定為java-tale,如下圖:
技術分享圖片

2、源碼管理
在“源碼管理”項中選擇Git,只需要配置git倉庫的地址 “Repository URL”,之前我們在jenkins服務器上把公鑰傳輸到了git服務器上了,所以不需要做認證,如下圖:
技術分享圖片

3、構建觸發器
在“構建觸發器”選項中,選上“Poll SCM”,日程表 * ,每分鐘都去撿查代碼,這個和linux crontab是一樣的含義。這一項你也可以不用測試,如下圖:
技術分享圖片

4、build配置
在“Build”選項中,Goals and options輸入:clean package。如下圖:
技術分享圖片

5、構建後的配置
在“Post Steps”選項中,配置如下操作:
技術分享圖片

6、測試
配置上之後,構建此項目:
技術分享圖片

查看控制臺輸出日誌:
技術分享圖片
技術分享圖片
看到最上面完成的狀態,就可以進行測試了,如果是第一次構建時間會比較久,它需要下載maven相關的依賴包。

然後登錄docker服務器查看一下運行的容器:

[root@docker /]# docker ps 
CONTAINER ID        IMAGE                         COMMAND                  CREATED             STATUS              PORTS                NAMES
83b29455b2c5        172.18.18.34:5000/tale:base   "/usr/bin/supervisord"   6 minutes ago       Up 6 minutes        0.0.0.0:80->80/tcp   tale-test

[root@docker /]#docker  top tale-test 
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                815                 797                 0                   20:03               pts/0               00:00:00            /usr/bin/python /usr/bin/supervisord
root                862                 815                 0                   20:03               pts/0               00:00:02            /usr/local/jdk/bin/java -jar /tale/tale-least.jar
root                863                 815                 0                   20:03               pts/0               00:00:00            nginx: master process /usr/sbin/nginx -g daemon off;
polkitd             869                 863                 0                   20:03               pts/0               00:00:00            nginx: worker process
polkitd             870                 863                 0                   20:03               pts/0               00:00:00            nginx: worker process
polkitd             871                 863                 0                   20:03               pts/0               00:00:00            nginx: worker process
polkitd             872                 863                 0                   20:03               pts/0               00:00:00            nginx: worker process
root                962                 797                 0                   20:04               ?                   00:00:00            bash

最後,通過用瀏覽器來訪問一下這個用java寫的tale開源博客項目:
技術分享圖片
從上面可以看到,我是通過docker那個服務器IP來訪問的,訪問是OK的。到此,實戰docker+jenkins+git構建持續集成環境就結束了。

5.總結

1、首先要對整個流程熟悉,思路不能亂,規劃好服務器數量和部署的應用服務。
2、本文中用的jar包來測試的,一般jar包直接用jar命令運行、也可以部署在tomcat容器中。jar包不依賴tomcat,所以本文在基礎鏡像172.18.18.34:5000/tale:base中只是安裝了nginx,並沒有安裝tomcat。如果大家用war包,那麽這個基礎鏡像就要重新制作了。
3、在4.4步的第5小步中“構建後的操作”,是不是有一堆命令,其實也可以把它寫成一個shell腳本,直接調用一執行,看個人操作習慣。
4、還有就是用Dockferfile構建基礎鏡像中,這些服務都是通過yum來安裝的,我們也可以把它換成源碼安裝,大家可以自行測試一下。
5、遇到錯誤的時候自己先排錯,不要急於百度或問別人答案,容器這一塊的錯誤通過docker logs 容器、docker ps 、docker top 容器等命令可以很好的定位錯誤。並且可以很方便的用“docker exec -it 容器 bash ”進入容器直接排查錯誤。

喜歡我的文章,請點擊最上方右角處的《關註》支持一下!

實戰docker+jenkins+git構建持續集成環境