• Jenkins 日常运维笔记


    之前已在机房部署了一套Jenkins环境,先需要将此套环境迁移到别处,对迁移过程中的一些细节以及日常维护做了如下记录:

    一、Jenkins主目录设置

    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主备模式

    比如: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进程重启后,出现job任务丢失问题

    在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任务了。

    四、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)

    五、通过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

    六、非root用户启动Jenkins服务 (tomcat程序)

    需要注意一个重要细节:
    在linux系统下,只有root用户才可以使用1024以下的端口号,非root用户只能启动1024以上的端口。
    所有如果使用非root用户启动jenkins,则端口必须配置成大于1024的,比如采用默认的8080端口,如果配置成80端口,则启动失败!

    七、当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
    

    八、下载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

    九、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的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
    

    十一、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

    十二、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()
    

    十三、Jenkins上job构建日志清理机制
    jenkins上job构建日志的清理机制是在每个job的配置里定义的,有两种清理机制:1)保留构建的天数。2)保留构建的最大个数。即超过这两种配置的数值,job构建历史里的日志就会被自动删除。

  • 相关阅读:
    Python正则表达式(3)--字符串匹配开头结尾
    Python正则表达式(2)---字符串匹配多个字符
    Python正则表达式(1) --匹配单个字符
    Navicate Premium 永久破解
    升级pip指令
    爬虫(自学)之User Agent 第三方库my_fake_useragent 和 fake_useragent
    django drf 反序列化上传图片
    git的使用
    python 爬虫 基本库使用urllib之urlopen(一)
    吉他入门第三讲~~~~~和弦
  • 原文地址:https://www.cnblogs.com/kevingrace/p/8076488.html
Copyright © 2020-2023  润新知