Jenkins 平常運維筆記 - 主目錄/主備模式/遷移/job覆蓋/maven構建/日誌處理

 

以前已在機房部署了一套Jenkins環境,先須要將此套環境遷移到別處,對遷移過程當中的一些細節以及平常維護作了以下記錄:html

1、Jenkins主目錄設置java

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。

2、Jenkins主備模式python

好比:192.168.10.60和192.168.10.61是兩臺jenkins機器,分別爲jenkins0一、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"->"系統管理"->"系統設置"linux

3、Jenkins進程重啓後,出現job任務丟失問題nginx

在Jenkins服務進程重啓後,可能會出現job任務丟失現象,或者說以前的job任務數據在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後發現原來的job任務都沒有了。
數據丟失了?這是爲何????
 
最後發現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,使用原來的帳號登陸,就能看到以前的job任務了。

4、Jenkins服務遷移git

遷移步驟爲:
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)

5、經過SSH方式下載Gitlab代碼到Jenkins本機web

通常來講,會在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

6、非root用戶啓動Jenkins服務 (tomcat程序)shell

須要注意一個重要細節:
在linux系統下,只有root用戶纔可使用1024如下的端口號,非root用戶只能啓動1024以上的端口。
全部若是使用非root用戶啓動jenkins,則端口必須配置成大於1024的,好比採用默認的8080端口,若是配置成80端口,則啓動失敗!

7、當SSH是非標準的22端口時,如何經過"git clone"下載gitlab代碼?apache

如上,將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

8、下載gitlab上非master分支代碼bootstrap

好比將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

9、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的備機操做了。

10、Jenkins的maven構建:基於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

11、Jenkins日誌爆滿問題處理

Jenkins日誌文件過大,將磁盤打滿!一般查看jenkins日誌文件"/var/log/jenkins/jenkins.log",發現幾分鐘就會產生幾十G的日誌,而且,jenkins.log日誌一直在增加中!

內容以下:
[root@localhost jenkins]# tail -f /var/log/jenkins/jenkins.log 
..........
120: 31303040312e312e 312e313e0d0a436f 6e746163743a2073 69703a3130304031     100@1.1. 1.1>..Co ntact:.s ip:100@1
 140: 32372e302e312e31 3a353236370d0a43 5365713a2031204f 5054494f4e530d0a     27.0.1.1 :5267..C Seq:.1.O PTIONS..
 160: 43616c6c2d49443a 2032333736353733 3036343830373737 3236373837343730     Call-ID: .2376573 06480777 26787470
 180: 300d0a4d61782d46 6f7277617264733a 2037300d0a0d0a                        0..Max-F orwards: .70....
 
Nov 26, 2019 10:23:45 PM javax.jmdns.impl.DNSIncoming$MessageInputStream readName
SEVERE: bad domain name: possible circular name detected. Bad offset: 0xffffffff at 0x195
Nov 26, 2019 10:23:45 PM javax.jmdns.impl.constants.DNSRecordType typeForIndex
SEVERE: Could not find record type for index: -1
Nov 26, 2019 10:23:45 PM javax.jmdns.impl.DNSIncoming readAnswer
SEVERE: Could not find record type. domain:
dns[query,62.210.116.113:5267, length=407, id=0x4f50, flags=0x5449:aa, questions=20302
questions:
        [DNSQuestion@1698506285 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: 00@101.200.87.125 SIP/2.0
Via: SIP/2.0/UDP 127.0.1.1:5267;branch=z9hG4bK-1805463161;rport
Cont.Length: 0
From: "sipvicious"<sip:100@1.1.1.1.;tag=3635633835373764313465390132303839373931373930
Accept: a.sdp
User-Agent: friendly-scanner
To: "sipvici.<sip:100@1.1.1.1>
Contact: sip:10.@127.0.1.1:5267
CSeq: 1 OPTIONS
Call-ID: 23765.306480777267874700
Max-Forwards: 70
 
ϿϿϿϿϿϿϿϿ.]
        [DNSQuestion@690369214 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        [DNSQuestion@1821236921 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        [DNSQuestion@1695940198 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        [DNSQuestion@1763025063 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]
        [DNSQuestion@1908329721 type: TYPE_IGNORE index 0, class: CLASS_UNKNOWN index 0, name: ]

既然定位到了問題,那麼就將該日誌文件清理下, 刪除或者清空它。
[root@localhost jenkins]# du -sh /var/log/jenkins/jenkins.log 
107G    /var/log/jenkins/jenkins.log

[root@localhost jenkins]# rm -f /var/log/jenkins/jenkins.log   
或者,清空該日誌文件
[root@localhost jenkins]# > /var/log/jenkins/jenkins.log  

可是發現清空了jenkins日誌後,磁盤空間仍然沒有釋放出來!這是爲何呢??接下來就須要進一步分析這其中更深層次的問題了。

在Linux系統中,經過rm或者文件管理器刪除文件將會從文件系統的文件夾結構上解除連接(unlink),可是若是刪除的文件是被打開的(有一個進程正在使用)狀態,
那麼進程將仍然可以讀取該文件,磁盤空間也一直被佔用她!

上面刪除的是jenkins的日誌文件,若是jenkins服務沒有中止,那麼此時刪除jenkins日誌文件將並不會起到什麼做用!!
由於刪除日誌文件的時候,該文件正在被使用,當linux打開一個文件的時候, Linux內核會爲每一個進程在/proc(/proc/進程pid/fd/文件夾)下創建一個以其pid爲名
的文件夾用來保存進程的相關信息,而其子文件夾fd保存的是該進程打開的所有文件的fd(fd是文件描述符)。

kill進程是經過截斷proc文件系統中的文件可以強制要求系統回收分配給正在使用的的文件,這是一項高級技術,僅在系統管理員肯定不會對執行中的進程形成影響時使用。
應用程序對這樣的方式支持的並很差,當一個正在使用的文件被截斷後可能會引起不可預知的問題,因此這種狀況下最好仍是經過中止應用進程來解決。

由於,最終的解決方法:
1)刪除jenkins的log文件。
2)中止jenkins服務進程。

通常狀況下,jenkins經常使用的部署方式:
1)經過系統服務安裝並啓動,進程啓停命令"service jenkins start/stop/restart",此時可經過stop命令來中止jenkins服務進程;
2)將war包部署至tomcat中,此時stop tomcat服務器便可。

=============================================================================================
總結一下:
1)在Linux系統中,當一個文件正在被一個進程使用時,用戶刪除此文件,文件只會從目錄結構中刪除,但並無真正從磁盤刪除。
   只有當使用這個文件的進程結束後,文件纔會真正的從磁盤刪除,釋放佔有的空間。
2)所以,在平常運維工做中,發現系統磁盤剩餘空間比較少時,在追查到一些大的臨時文件或log文件並刪除它們後,若是刪除它們
   以後會發現磁盤空間並未減小,一般可使用"lsof"命令去查看正常使用這些文件的進程,而後重啓該服務進程,這樣這些被刪除
   文件就會真正從磁盤空間釋放出來了!

=============================================================================================
此外,還須要注意的是:
1)在腳本中若是涉及到啓動進程的話,須要加入BUILD_ID,不然該進行啓動後就會被kill掉!!
   [Jenkins的BUILD_ID就是job構建ID,就是jenkins界面裏"構建歷史"列表裏#後面的數字,這個能夠在job的"Esecute Shell"腳本里
   經過"echo $BUILD_ID"打印出來,jnekins會自動識別$BUILD_ID這個環境變量]
2)若是不設置BUILD_ID,則jenkins在結束本身的腳本執行時會將建立的全部subprocess kill掉,BUILD_ID是Jenkins的一個環境變量,
   若是不設置這個變量值,那麼jenkins執行完全部腳本就會退出,帶着subprocess一塊兒死掉。

上面jenkins日誌暴增,日誌文件信息裏主要是由於DNS查詢錯誤,返回了全部的日誌數據。這個問題的解決方法:Jenkins界面 -> 系統管理 -> System log -> 日誌級別 -> 配置級別 -> 名稱: javax.jmdns , 級別:off

12、Jenkins刪除job後,如何清理slave機器上對應的workspace

若是Jenkins部署的是master-slave架構模式,則在master上刪除job後,slave節點上對應job的workspace不會被刪除,這個須要另行處理。

那麼如何實現:master節點刪除job後,slave節點對應workspace也被自動刪除的功能呢?方法有下面兩種:
1)master->slave單向的rsync同步腳本
按照上面記錄所說,master到slave節點之間有同步腳本,刪除master節點上的job後,執行同步腳本,則slave節點上對應job的workspace也將會被刪除。

2)經過python腳本實現該功能,具體思路是:
1. 遍歷jenkins節點的workspace,根據路徑解析得到jenkins job name。
2. 若是該job不存在(經過python jenkinsapi實現),則刪除相應的workspace。
3. 暫不考慮自定義的workspace。
4. 須要在jenkins每一個節點上進行處理(能夠在jenkins上建立job,將job綁定到相應slave上;也能夠在相應slave上直接運行腳本)

python腳本內容以下:
----------------------------------------------------------------------------------

#!/usr/bin/env python
# -*- coding: UTF-8 -*-
import os
import shutil
import logging
 
from jenkinsapi.jenkins import Jenkins
 
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__file__)
 
 
def get_jenkins_instance():
    jenkins_url = "http://jenkins.kevin.com"
    jenkins_username = "username"
    jenkins_password = "password"
    return Jenkins(jenkins_url, username=jenkins_username, password=jenkins_password)
 
 
def clean_workspace():
    jenkins_instance = get_jenkins_instance()
 
    jenkins_workspace_path = "/opt/JENKINS_HOME/workspace/"
 
    for dirpath, dirnames, filenames in os.walk(jenkins_workspace_path):
        if dirpath == jenkins_workspace_path:
            for dirname in dirnames:
                jenkins_job_name = dirname
                # 若是job被刪除,則清理相應的workspace
                if not jenkins_instance.has_job(jenkins_job_name):
                    logger.info("removing workspace dir of job:%s" % dirname)
                    shutil.rmtree(os.path.join(dirpath, dirname))
 
 
if __name__ == "__main__":
    clean_workspace()

十3、Jenkins上job構建日誌清理機制
jenkins上job構建日誌的清理機制是在每一個job的配置裏定義的,有兩種清理機制:1)保留構建的天數。2)保留構建的最大個數。即超過這兩種配置的數值,job構建歷史裏的日誌就會被自動刪除。

相關文章
相關標籤/搜索