Jenkins日常運維筆記-重啟資料覆蓋問題、遷移、基於java程式碼發版(maven構建)

散盡浮華發表於2017-12-21

 

之前在公司機房部署了一套jenkins環境,現需要遷移至IDC機房伺服器上,遷移過程中記錄了一些細節:
1)jenkins預設的主目錄放在當前使用者家目錄路徑下的.jenkins目錄中。如jenkins使用root使用者啟動,則主目錄為/root/.jenkins

[root@code-server ~]# ll -d /root/.jenkins/
drwxr-x--- 14 root root 4096 Dec 18 15:22 /root/.jenkins/

2)可以在系統環境變數裡手動設定jenkins的主目錄,這樣啟動jenkins後,jenkins資料就會寫入到手動設定的主目錄裡。

root使用者可以在/etc/profile檔案裡設定
[root@jenkins01 ~]# vim /etc/profile
......
JENKINS_HOME="/data/jenkins"
export JENKINS_HOME
 
[root@jenkins01 ~]# source /etc/profile
 
===========================================================
如果是非root使用者,就在使用者家目錄的.bashrc檔案裡設定
[app@jenkins01 ~]$ vim .bashrc
......
JENKINS_HOME="/data/jenkins"
export JENKINS_HOME
 
[app@jenkins01 ~]$ source .bashrc
[app@jenkins01 ~]$ echo $JENKINS_HOME
/data/tomcat8.5/webapps/jenkins
[app@jenkins01 ~]$ env
.......
JENKINS_HOME=/data/jenkins
==========================================================

溫馨提示:
最好別將jenkins主目錄指定到tomcat/webapps/jenkins,因為如果有其他同名的tomcat專案啟動,容易造成資料覆蓋!
所以最好將jenkins主目錄指定到其他地方,比如指定到/data/jenkins。

=================================================================
jenkins主備雙機模式:前面一個nginx代理層,提供一個域名代理到後面的jenkins上

比如:192.168.10.60和192.168.10.61是兩臺jenkins機器,分別為jenkins01、jenkins02

[root@inner-lb02 ~]# cat /data/nginx/conf/vhosts/jenkins.kevin.com.conf 
upstream 8080-inc {
      server 192.168.10.60:8080 max_fails=3 fail_timeout=10s;
      #server 192.168.10.61:8080 max_fails=3 fail_timeout=10s;
}
          
  server {
      listen      80;
      server_name jenkins.kevin.com;
    
      access_log  /data/nginx/logs/jenkins.kevin.com-access.log main;
      error_log  /data/nginx/logs/jenkins.kevin.com-error.log;
    
 location ^~ /jenkins/ {
         proxy_pass http://8080-inc;
         proxy_redirect off ;
         proxy_set_header Host $host;
         proxy_set_header X-Real-IP $remote_addr;
         proxy_set_header REMOTE-HOST $remote_addr;
         proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
         proxy_connect_timeout 300;
         proxy_send_timeout 300;
         proxy_read_timeout 600;
         proxy_buffer_size 256k;
         proxy_buffers 4 256k;
         proxy_busy_buffers_size 256k;
         proxy_temp_file_write_size 256k;
         proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504 http_404;
         proxy_max_temp_file_size 128m;
         #proxy_cache mycache;
         #proxy_cache_valid 200 302 1h; 
         #proxy_cache_valid 301 1d;
         #proxy_cache_valid any 1m;
        }
}


jenkins01和jenkins02兩臺機器:
1)jenkins服務部署目錄是/data/tomcat8.5,jenkins的程式包存放目錄是/data/tomcat8.5/webapps/jenkins
2)jenkins的家目錄是/data/jenkins。

由於訪問http://jenkins.kevin.com/jenkins是代理負載到192.168.10.60機器上(即是jenkins01機器)的,所以需要同步jenkins01的相關資料
到jenkins02上,以防當jenkins01機器掛掉的時候,將負載域名調整到jenkins02上。

同步指令碼如下:
[app@jenkins01 ~]$ cat /data/rsync_jenkins.sh 
#!/bin/bash
#首次同步前,可以先備份下jenkins02機器的/data/jenkins目錄
rsync -e "ssh -p6666" -avpgolr /data/jenkins/ app@192.168.10.61:/data/jenkins/

#當真正切換到jenkins02時,才執行下面的重啟jenkins服務的動作,只要重啟後,同步到的資料才能在jenkins介面展示處理。
#ssh -p6666 app@192.168.10.61 "ps -ef|grep tomcat|grep -v grep|awk '{print $2}'|xargs kill -9"
#ssh -p6666 app@192.168.10.61 "/data/tomcat8.5/bin/startup.sh"

授執行許可權,每十分鐘執行一次
[app@jenkins01 ~]$ ll /data/rsync_jenkins.sh
-rwxr-xr-x. 1 app app 470 Sep 19 11:42 /data/rsync_jenkins.sh

[app@jenkins01 ~]$ crontab -l
*/10 * * * * /bin/bash -x /data/rsync_jenkins.sh > /dev/null 2>&1

jenkins主目錄設定之後,可以登入jenkins介面檢視它的主目錄路徑,依次點選"Jenkins"->"系統管理"->"系統設定"

==============jenkins重啟後資料丟失案例分析=================

jenkins安裝路徑:/data/tomcat8
jenkins的預設的主目錄放在當前使用者家目錄路徑下的.jenkins目錄中,比如:
root使用者啟動的jenkins主目錄就是/root/.jenkins,jenkins的所有資料就是放在這個主目錄下。
app使用者啟動的jenkins主目錄就是/home/app/.jenkins,jenkins的所有資料就是放在這個主目錄下。

由於jenkins服務是在app賬號下啟動的,並且修改了主目錄路徑:
[app@uatjenkins01 ~]$ pwd
/home/app
[app@uatjenkins01 ~]$ cat .bashrc 
......
JENKINS_HOME="/data/jenkins"
export JENKINS_HOME
[app@uatjenkins01 ~]$ source .bashrc

所以jenkins的使用者資料和jobs資料都放在了/data/jenkins主目錄下了。
[app@uatjenkins01 ~]$ ll -d /data/jenkins/
drwxr-x--- 16 app app 4096 Aug 10 20:09 /data/jenkins/

由於伺服器當機,在機器啟動後,jenkins的tomcat程式也重啟了,最後發現使用原來的賬號登入不了jenkins,或者登入jenkins後發現原來的project工程都沒有了。
資料丟失了?這是為什麼????

最後發現jenkins的tomcat程式是用root賬號啟動的,那麼jenkins載入的資料自然就是預設的/root/.jenkins主目錄裡面的資料了,而不是之前定義的/data/jenkins
目錄裡面的資料了(這是在app賬號下定義的jenkins主目錄)

解決辦法:
關閉root賬號下的jenkins,在app賬號下重啟jenkins服務即可!

[root@uatjenkins01 ~]# ps -ef|grep tomcat
root       4059     1  0 18:28 ?        00:02:12 /usr/java/jdk1.7.0_79/bin/java -Djava.util.logging.config.file=/data/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms8192m -Xmx8192m -XX:PermSize=2048M -XX:MaxNewSize=4096m -XX:MaxPermSize=4096m -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /data/tomcat8/bin/bootstrap.jar:/data/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/data/tomcat8 -Dcatalina.home=/data/tomcat8 -Djava.io.tmpdir=/data/tomcat8/temp org.apache.catalina.startup.Bootstrap start
root      9042  8871  0 22:46 pts/2    00:00:00 grep tomcat

[root@uatjenkins01 ~]# kill -9 4059

[root@uatjenkins01 ~]# su - app
[app@uatjenkins01 ~]$ /data/tomcat8/bin/startup.sh 
[app@uatjenkins01 ~]$ ps -ef|grep tomcat
app       5089    1  0 18:28 ?        00:02:13 /usr/java/jdk1.7.0_79/bin/java -Djava.util.logging.config.file=/data/tomcat8/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Xms8192m -Xmx8192m -XX:PermSize=2048M -XX:MaxNewSize=4096m -XX:MaxPermSize=4096m -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -classpath /data/tomcat8/bin/bootstrap.jar:/data/tomcat8/bin/tomcat-juli.jar -Dcatalina.base=/data/tomcat8 -Dcatalina.home=/data/tomcat8 -Djava.io.tmpdir=/data/tomcat8/temp org.apache.catalina.startup.Bootstrap start
app       9071  9044  0 22:46 pts/2    00:00:00 grep tomcat

這樣訪問jenkins,使用原來的賬號登入,就能看到之前的project工程了。

3)jenkins遷移

遷移步驟為:
1)先關閉新老伺服器的tomcat程式,確保遷移時新老機器的jenkins都處於關閉狀態。jenkins程式關閉最好是直接kill掉jenkins的tomcat程式pid。
2)將老伺服器jenkins主目錄下的config.xml檔案以及jobs、users、workspace、plugins四個目錄拷貝到新機器的jenkins主目錄下。
3)重啟新伺服器jenkins的tomcat程式。

遷移的時候可以直接將jenkins主目錄資料整個拷貝過去,也可以單獨拷貝jenkins主目錄下的config.xml檔案以及jobs、users、workspace、plugins四個目錄(這是主要的遷移資料)。一般來說,手動設定好jenkins主目錄路徑,啟動jenkins後就會自動生成(但要確保jenkins使用者有許可權建立這個主目錄,最好是提前手動建立並賦予jenkins啟動使用者的許可權)

關閉老機器的jenkins程式
[root@code-server ~]# lsof -i:8080
COMMAND    PID USER   FD   TYPE  DEVICE SIZE/OFF NODE NAME
bundle   13481  git   15u  IPv4 2839661      0t0  TCP localhost:webcache (LISTEN)
[root@code-server ~]# kill -9 13481

新機器的jenkins程式也要同樣關閉 

拷貝老伺服器的jenkins主目錄或者上面說的那幾個重要資料到新機器的jenkins主目錄下
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr --delete /data/jenkins/ root@10.0.8.60:/data/jenkins/

或者
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr /data/jenkins/config.xml root@10.0.8.60:/data/jenkins/
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr --delete /data/jenkins/users/ root@10.0.8.60:/data/jenkins/users/
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr --delete /data/jenkins/plugins/ root@10.0.8.60:/data/jenkins/plugins/
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr --delete /data/jenkins/jobs/ root@10.0.8.60:/data/jenkins/jobs/
[root@code-server ~]# rsync -e "ssh -p22" -avpgolr --delete /data/jenkins/workspace/ root@10.0.8.60:/data/jenkins/workspace/

尤其是plugins目錄,最好保證新機器下的這個目錄和老機器下的這個目錄資料保持一致。否則容易造成新機器的jenkins訪問報錯

最後啟動新機器的jenkins服務
[root@jenkins01 ~]$ /data/tomcat8.5/bin/startup.sh
[app@jenkins01 ~]$ lsof -i:8080
COMMAND    PID USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
java    101037  app   46u  IPv6 498942      0t0  TCP *:webcache (LISTEN)

4)通過ssh方式下載gitlab程式碼到jenkins本機

一般來說,會在jenkins介面裡建立工程,在工程裡配置gitlab的地址,將gitlab程式碼下載到jenkins本機,然後通過指令碼自動發版。
安全考慮,通過ssh方式下載gitlab程式碼。這就需要將jenkins本機的id_rsa.pub公鑰上傳到gitlab裡。
1)如果jenkins程式通過root使用者啟動,則需要將root使用者下的id_rsa.pub公鑰上傳到gitlab的SSH Keys裡。
2)如果jenkins程式通過非root使用者啟動,則需要將非root使用者的id_rsa.pub公鑰上傳到gitlab的SSH Keys裡。

比如jenkins程式是通過app使用者啟動的
[app@jenkins01 ~]$ cat ~/.ssh/id_rsa.pub 
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAw/I9657ZRmducrkbagPfptLwRaCmJIIQIcQ3VljBLBlwyNFBYg6KfiktMB4KHlvu4WCrGpDjVtWf7gQy
Ey+iJNsL7TyiIZdg0RRGpssu93w6IhgoHtRZni/775MrdjLQpi7hhB6wiX+eCfU7duqXT+arnEUonAF+27HegVbXuqz+oeDS/1QBzKsOoMg0K4nA7Btl
GNIn1ljvvQzyHxIJevWM0UUhFl8lv9+RCcT0cyHmjSrw/9+gr4AYZmYaqlVmCWHmwuAixx7bt3Mh3ri+BK385qAUxaVVsw3kg/vHbJEg+JYn/Xm4pdnw
j+CLn6OpQAMZm+bEx12Iwd3gazBy+Q== app@jenkins01.kevin.cn

5)非root使用者啟動jenkins的tomcat程式

需要記住的一個細節:
在linux系統下,只有root使用者才可以使用1024以下的埠號,非root使用者只能啟動1024以上的埠。
所有如果使用非root使用者啟動jenkins,則埠必須配置成大於1024的,比如採用預設的8080埠,如果配置成80埠,則啟動失敗!

6)當ssh是非標準的22埠時,進行git clone下載gitlab程式碼

如上,將jenkins本機的id_rsa.pub公鑰拷貝到gitlab的SSH Keys裡。

1)如果jenkins機器和gitlab機器ssh都採用預設的22埠,則就可以直接git clone下載git程式碼了。
[app@jenkins01 ~]$ mkdir /data/git_data/
[app@jenkins01 ~]$ cd /data/git_data/
[app@jenkins01 git_data]$ git init .
Reinitialized existing Git repository in /data/git_data/.git/

[app@jenkins01 git_data]$ git clone git@172.16.50.25:fanglianchao/dbops.git
Initialized empty Git repository in /data/git_data/dbops/.git/
Warning: Permanently added '172.16.50.25' (RSA) to the list of known hosts.
remote: Counting objects: 1224, done.
remote: Compressing objects: 100% (812/812), done.
remote: Total 1224 (delta 379), reused 1220 (delta 377)
Receiving objects: 100% (1224/1224), 9.50 MiB, done.
Resolving deltas: 100% (379/379), done.

[app@jenkins01 git_data]$ ls
dbops

====================================================================
2)如果jenkins機器和gitlab機器ssh採用的埠不一致,這就需要在jenkins本機的.ssh目錄下手動建立config檔案,在config檔案中指定
連線gitlab時的資訊。

例如:jenkins本機的ssh埠是6666,jenkins本機(172.16.50.25)的ssh埠是22,則在jenkins本機的操作如下:
[app@jenkins01 ~]$ mkdir /data/git_data/
[app@jenkins01 ~]$ cd /data/git_data/
[app@jenkins01 git_data]$ git init .
Reinitialized existing Git repository in /data/git_data/.git/

[app@jenkins01 ~]$ cat ~/.ssh/config 
Host "172.16.50.25"
Port 22

注意:config檔案必須是600許可權
[app@jenkins01 git_data]$ sudo chmod 600 ~/.ssh/config
[app@jenkins01 git_data]$ ll ~/.ssh/config
-rw-------. 1 app app 28 Dec 20 23:26 /home/app/.ssh/config

然後就可以正常git clone下載程式碼了
[app@jenkins01 git_data]$ git clone git@172.16.50.25:qwfss/qwfss.git
Initialized empty Git repository in /data/git_data/qwfss/.git/
remote: Counting objects: 110, done.
remote: Compressing objects: 100% (59/59), done.
remote: Total 110 (delta 23), reused 0 (delta 0)
Receiving objects: 100% (110/110), 19.99 KiB, done.
Resolving deltas: 100% (23/23), done.
[app@jenkins01 git_data]$ ls
qwfss

7)下載gitlab上非master分支程式碼

比如將gitlab上的git@172.16.50.25:qwfss/qwfss.git下develop分支程式碼下載到jenkins本機,操作如下:

[app@jenkins01 git_data]$ git clone git@172.16.50.25:qwfss/qwfss.git
Initialized empty Git repository in /data/git_data/qwfss/.git/
remote: Counting objects: 110, done.
remote: Compressing objects: 100% (59/59), done.
remote: Total 110 (delta 23), reused 0 (delta 0)
Receiving objects: 100% (110/110), 19.99 KiB, done.
Resolving deltas: 100% (23/23), done.

[app@jenkins01 git_data]$ ls
qwfss
[app@jenkins01 git_data]$ cd qwfss/
[app@jenkins01 qwfss]$ 

檢視分支詳細情況 (推薦這種方式)
[app@jenkins01 qwfss]$ git branch 
* develop
[app@jenkins01 qwfss]$ git branch -av
* develop                29e5e1f fix(fss): 測試環境配置檔案同步
  remotes/origin/HEAD    -> origin/develop
  remotes/origin/develop 29e5e1f fix(fss): 測試環境配置檔案同步

切換到develop分支下
[app@jenkins01 qwfss]$ git checkout -b develop origin/develop
fatal: git checkout: branch develop already exists
====================================================================
或者
[app@jenkins01 qwfss]$ git checkout -b testapp remotes/origin/develop
====================================================================

[app@jenkins01 qwfss]$ git branch 
* develop
[app@jenkins01 qwfss]$ git branch -av
* develop                29e5e1f fix(fss): 測試環境配置檔案同步
  remotes/origin/HEAD    -> origin/develop
  remotes/origin/develop 29e5e1f fix(fss): 測試環境配置檔案同步

=====================================================================
git分支的日常操作可以參考:http://www.cnblogs.com/kevingrace/p/5690820.html

8)jenkins備機環境

部署jenkins備機時,只需要定期將master機器上jenkins主目錄資料拷貝到本機上即可。
   
比如:
jenkins master:10.0.8.60   jenkins01
jenkins slave:10.0.8.61    jenkins02
   
兩臺機器的jenkins主目錄都是:/data/jenkins
[app@jenkins01 ~]$ vim /etc/profile
JENKINS_HOME="/data/jenkins"
export JENKINS_HOME
[app@jenkins01 ~]$ source /etc/profile

手動指定jenkins主目錄後,待jenkins啟動後,該主目錄會自動生成。
但是要注意的是:jenkins啟動使用者要有許可權生成主目錄(可以提前手動建立該目錄,並將許可權設定成jenkins啟動使用者的許可權)
   
那麼只需要定期將master機器10.0.8.60上的/data/jenkins目錄下的檔案拷貝到10.0.8.61機器/data/jenkins下即可!
  
10.0.8.61上寫備份指令碼(兩臺機器提前做app賬號下的ssh無密碼登陸的信任關係):
[app@jenkins01 ~]$ cat /data/script/rsync_jenkins02.sh          (如下指令碼,如果不新增--delete引數,則只會同步增加的資料,刪除的資料不會同步)
#!/bin/bash
/usr/bin/rsync -e "ssh -p6666" -avpgolr --delete /data/jenkins/ app@10.0.8.61:/data/jenkins/

/usr/bin/ssh -p6666 app@10.0.8.61 "/bin/bash -x /home/app/kill_tomcat.sh"
/usr/bin/ssh -p6666 app@10.0.8.61 "/data/tomcat8.5/bin/startup.sh"
  
10.0.8.61上的指令碼:
[app@jenkins02 ~]$ cat /home/app/kill_tomcat.sh
#!/bin/bash
ps -ef|grep java|grep -v grep|awk '{print $2}'|xargs kill -9
  
如上指令碼準備好後,只需要每天定時去執行10.0.8.60機器上的同步指令碼/data/script/rsync_jenkins02.sh,即可完成jenkins的備機操作了。

==============Jenkins基於java程式碼發版: Jenkins+Gitlab+Maven+Nexus=============
Jenkins(提前安裝maven環境)針對Java程式碼的發版基本可以分為下面幾個步驟:
1)安裝部署Jenkins、Gitlab、Nexus。安裝過程在之前的文章中已經提到過了,這裡就省略了。
2)將相關程式碼上傳到Gitlab裡進行託管,上傳內容需要包括pom.xml檔案、src目錄。其中pom.xml檔案裡需要配置連線Nexus的相關資訊src目錄裡包括java編譯需要的程式碼文件。如下截圖:

 pom.xml檔案裡配置的是nexus的連線資訊

一般而言,pom.xml檔案最好放到Gitlab相關project工程的根目錄下,這樣在jenkins裡配置時直接寫"pom.xml"即可,maven讀取該檔案進行編譯;如果pom.xml檔案不放到project工程的根目錄下,則在jenkins裡配置時就需要寫相對路徑下。比如pom.xml檔案放到http://gitlab.kevin.com/test.git下面的a/b/pom.xml位置,則在jenkins裡配置的時候需要寫"a/b/pom.xml"的相對路徑。

3)Jenkins配置。構建project工程的時候,選擇“構建一個maven專案”。

上面填寫專案構建引數(與開發人員有關),基礎引數為“clean package”。然後在Execute shell裡編寫指令碼,將該工程執行並編譯後的jar或war包同步到需要發版的目標伺服器上,並重啟java服務。

點選"立即構建",就會依次執行:從gitlab拉取程式碼,maven進行編譯,然後通過指令碼將編譯後jar或war包同步到上線的伺服器上,並重啟java程式。

如下,點選"工作區"可以看到編譯後的jar或war包。

錄jenkins伺服器,加入jenkins的根目錄是/data/jenkins。則可以到jenkins伺服器的/data/jenkins/jobs下找對應的project工程目錄,在這個工程目錄的workspace裡可以看到從gitlab上拉取下面的程式碼,發現jenkins執行構建成功後,這些程式碼裡會多了一個target目錄,而target目錄下就會有編譯後的jar或war包,將這裡面的jar或war包通過jenkins發版的指令碼同步到上線的目標伺服器上即可。

[root@uatjenkins01 gw-anshuo]# pwd
/data/jenkins/jobs/uat-gw-anshuo/workspace/qwgateway/gw-anshuo

[root@uatjenkins01 gw-anshuo]# ls             #發現在gitlab上只有pom.xml和src,通過jenkins構建工程,maven編譯後這裡多了一個target目錄。
pom.xml  src  target

[root@uatjenkins01 gw-anshuo]# ls target/     #target目錄下有編譯後的jar包,將這個jar包通過jenkins指令碼同步到上線伺服器上。
classes  generated-sources  generated-test-sources  gw-anshuo-1.0.0.release.jar  maven-archiver  maven-status  test-classes

相關文章