關於jenkins的文章比較多,筆者決定寫一篇比較詳細的利用容器來構建jenkins+git+registry的文章來和你們共同討論。文章比較長,須要有點耐心慢慢看完,若是你們在實驗的過程當中遇到問題,能夠留言一塊兒討論或者加我QQ一塊兒討論都行。html
本文重點介紹jenkins以及jenkins如何在docker容器中運行,jenkins和docker私有倉庫又是怎麼玩的。docker說明、安裝和git說明、安裝在本文中不會特別詳細的介紹。java
而且,在本文中不着重介紹原理性的東西,好比不會介紹什麼是持續集成、持續構建等等。本文的重點是實戰爲主。對持續集成、持續交付、持續部署等概念不太瞭解的朋友能夠參考這篇文章瞭解一下:https://www.zhihu.com/question/23444990python
Jenkins是一個開源軟件項目,是基於Java開發的一種持續集成工具,用於監控持續重複的工做,旨在提供一個開放易用的軟件平臺,使軟件的持續集成變成可能。linux
先來了解一下比較典型的java項目發佈工做流程:
1.java項目開發 >> 2.提交項目代碼到(git或svn) >> 3. 拉取項目代碼(jenkins或手動) >> 4.編譯項目代碼(jenkins或手動) >> 5.發佈java項目,並運行java項目 >> 6.測試nginx
在來看看用docker+jenkins+git發佈java項目流程又是怎樣的呢:
1.java項目開發 >> 2.提交項目代碼git容器 >> 3.jenkins容器拉取項目代碼 >> 4.maven編譯構建項目 >> 5.jenkins發佈項目到tomcat容器 >> 6.測試git
看到上面的流程後,在沒有jenkins的狀況下這些步驟都是手工完成的,有了Jenkins的幫助,在這6步中,除了第1步,後續的5步都是自動化完成的。當你完成了提交,Jenkins會自動運行你的編譯腳本,編譯成功後,再運行你的測試腳本,這一步成功後,接着它會幫你把新程序發佈出去,特別的,在最後一步,你能夠選擇手動發佈,或自動發佈。github
一、服務器部署信息docker
服務器 | 主機名 | 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私有倉庫容器 |
說明:shell
二、版本信息apache
名稱 | 版本 | 軟件包 | 說明 |
---|---|---|---|
服務器 | 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/
注意:這個步驟在 git_registry 服務器上操做
一、安裝git
[root@git_registry ~]# yum -y install git
二、建立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. #記得切換建立的git用戶操做: [root@git_registry ~]#su - git
三、建立倉庫
建立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
注意:這個步驟在 jenkins 服務器上操做
正常來講,開發用本身的電腦把寫好的代碼push到git倉庫就算完成驗證,在本文中去github裏下載一個java項目(tale)來驗證,咱們就用jenkins這臺服務器作爲git客戶端吧:
一、下載git客戶端
[root@jenkins ~]# yum -y install git
二、下載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
三、生成公鑰,拷貝到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 git@172.18.18.34 /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 git@172.18.18.34's password: Number of key(s) added: 1 Now try logging into the machine, with: "ssh 'git@172.18.18.34'" and check to make sure that only the key(s) you wanted were added.
四、用git clone驗證
#先建立個目錄,目錄名隨便定義,用於拉取git服務器上建立的app.git倉庫 [root@jenkins tale]# mkdir /git [root@jenkins tale]# cd /git/ #配置下git客戶端的用戶信息 [root@jenkins git]# git config --global user.email "test@qq.com" [root@jenkins git]# git config --global user.name "test" #在來git clone,因爲app.git倉庫是空的,因此會很快 [root@jenkins git]# git clone git@172.18.18.34:/home/git/app.git Cloning into 'app'... warning: You appear to have cloned an empty repository.
五、把以前下載的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 git@172.18.18.34:/home/git/app.git * [new branch] master -> master
注意:這個步驟在 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
對registry私有倉庫不太瞭解的朋友能夠參考筆者的這篇文章 《docker:用registry快速搭建私有鏡像倉庫》
注意:這個步驟在 docker服務器上操做
這臺服務器就是在docker中運行剛纔的tale 這個java項目的服務器,因此咱們要在這臺服各器上安裝下docker。
一、安裝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
二、配置鏡像源爲國內官方源
[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協議了。
三、啓動dokcer服務
[root@docker ~]# systemctl restart docker
四、部署JDK
因爲後面運行java容器須要jdk環境,jdk若是放在容器中運行容器又至關重,因此就在宿主機上部署jdk,後面建立java容器的時候把宿主機的jdk路徑掛載到容器就去。部署jdk很簡單,解壓就行:
[root@docker ~]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/
咱們把它解壓在docker這臺宿主機的/usr/local目錄中。
五、構建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
注意:這個步驟在 jenkins 服務器上操做
一、部署JDK
因爲jenkins須要jdk環境,jdk若是放在容器中運行容器又至關重,因此就在宿主機上部署jdk,後面建立jekins容器的時候把宿主機的jdk路徑掛載到容器就去。部署jdk很簡單,解壓就行:
[root@jenkins /]# tar -zxvf jdk-8u45-linux-x64.tar.gz -C /usr/local/
咱們把它解壓在宿主機的/usr/local目錄中。
二、部署maven
因爲本文後期是經過jenkins運行java項目,因此咱們還須要maven工具,maven也和jdk部署同樣,也不想在容器中運行maven,因此也是部署在宿主機上而後掛載到容器中。也是直接解壓:
[root@jenkins local]# tar -zxvf apache-maven-3.5.0-bin.tar.gz -C /usr/local/
查看一下這兩個源碼軟件是否解壓:
三、生成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說明:
四、構建jenkins鏡像
[root@jenkins Dockerfile_jenkins]# docker build -t jenkins:v1 .
查看一下構建的鏡像:
五、建立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的!!!
經過http://ip:8080 來訪問jenkins服務;
從上圖給出的提示,須要從/var/jenkins_home/secrets/initialAdminPassword獲取密碼
[root@jenkins /]# cat /var/jenkins_home/secrets/initialAdminPassword dff1d41be2254f87ad80a65eac621cb8
進入「系統管理」 -- 「系統設置」,主要是把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服務器的密碼
一、jdk配置
進「系統管理」 -- "Global Tool Configuration",添加jdk安裝,以下圖:
參數說明:
別名:自定義就行;
JAVA_HOME:這個是你jenkins容器裏的JDK路徑,不是宿主機的JDK路徑;
二、maven配置
進「系統管理」 -- "Global Tool Configuration",添加maven安裝,以下圖:
參數說明:和jdk同樣,MAVEN_HOME 的路徑也是指向jenkins容器裏的maven路徑;
三、git配置
這裏我沒有動git的配置,讓它爲默認配置,以下圖:
一、構建maven項目
點擊「新建」 -- 「構建一個maven項目,項目名稱定爲java-tale,以下圖:
二、源碼管理
在「源碼管理」項中選擇Git,只須要配置git倉庫的地址 「Repository URL」,以前咱們在jenkins服務器上把公鑰傳輸到了git服務器上了,因此不須要作認證,以下圖:
三、構建觸發器
在「構建觸發器」選項中,選上「Poll SCM」,日程表 * ,每分鐘都去撿查代碼,這個和linux crontab是同樣的含義。這一項你也能夠不用測試,以下圖:
四、build配置
在「Build」選項中,Goals and options輸入:clean package。以下圖:
五、構建後的配置
在「Post Steps」選項中,配置以下操做:
配置說明:
Nmae:選擇須要部署的docker服務器,前面咱們SSH增長了一臺,因此這裏能夠直接選擇;
source files:須要部署到目標服務的打包成果路徑
Remove prefilx: 「Source files」配置的路徑中要移除的前綴
Remote directory:成果要發送到的遠程目標服務目錄路徑,這個路徑與第一步配置中的Remote Directory對應。
Exec command:成果發送完成後,須要執行的命令,具體以下
docker rm -f tale-test docker rmi -f 172.18.18.34:5000/tale:base docker run -itd \ --name tale-test \ -p 80:80 \ -v /usr/local/jdk1.8.0_45:/usr/local/jdk \ -v /data/tale:/tale \ 172.18.18.34:5000/tale:base
在Exec command執行中的命令都是在構建代碼完成後的操做,會在172.18.18.33-docker這臺服務器上執行。
第1/2條命令:其實這兩步你先能夠不用加上,到了下一次構建的時候你測試一下不加這兩條命令會有什麼結果。若是構建失敗,你在加上這兩條命令,其實這兩條命令是事先刪除容器和鏡像文件,而後經過第3條命令運行全新的容器。
第3條命令:就是經過docker run來運行tale-test容器了,並把172.18.18.33-docker這臺服務器的jdk和tale目錄掛載到容器中。
六、測試
配置上以後,構建此項目:
查看控制檯輸出日誌:
看到最上面完成的狀態,就能夠進行測試了,若是是第一次構建時間會比較久,它須要下載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構建持續集成環境就結束了。
一、首先要對整個流程熟悉,思路不能亂,規劃好服務器數量和部署的應用服務。
二、本文中用的jar包來測試的,通常jar包直接用jar命令運行、也能夠部署在tomcat容器中。jar包不依賴tomcat,因此本文在基礎鏡像172.18.18.34:5000/tale:base中只是安裝了nginx,並無安裝tomcat。若是你們用war包,那麼這個基礎鏡像就要從新制做了。
三、在4.4步的第5小步中「構建後的操做」,是否是有一堆命令,其實也能夠把它寫成一個shell腳本,直接調用一執行,看我的操做習慣。
四、還有就是用Dockferfile構建基礎鏡像中,這些服務都是經過yum來安裝的,咱們也能夠把它換成源碼安裝,你們能夠自行測試一下。
五、遇到錯誤的時候本身先排錯,不要急於百度或問別人答案,容器這一塊的錯誤經過docker logs 容器、docker ps 、docker top 容器等命令能夠很好的定位錯誤。而且能夠很方便的用「docker exec -it 容器 bash 」進入容器直接排查錯誤。
喜歡個人文章,請點擊最上方右角處的《關注》支持一下!