【Jenkins學習 】解決jenkins運行磁盤滿的問題

1、背景

今天有同事編譯Jenkins的相關Jobs的時候,出現了編譯成功,可是輸出產物失敗的狀況,以下圖所示:
這裏寫圖片描述java

Caused by:java.io.IOException: No space left on device
    at java.io.FileOutputStream.writeBytes(Native Method)
    at java.io.FileOutputStream.write(FileOutputStream.java:345)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1793)
    at org.apache.commons.io.IOUtils.copyLarge(IOUtils.java:1769)
    at org.apache.commons.io.IOUtils.copy(IOUtils.java:1744)
    at hudson.util.IOUtils.copy(IOTuils.java:40)
    at hudson.FilePath.readFromTar(FilePath.java:2318)
....13 more

Cause by:java.util.concurrent.ExecutionException:java.io.IOException:This archives contains unclosed entries.
...12 more

Cause by:java.io.IOException:This archives contains unclosed entries.
...

看上面圖的描述就是Jenkins服務器上的磁盤空間已經不足,致使輸出產物失敗的狀況出現。python

2、排查問題

好吧,我登陸Jenkins的服務器,去查看下磁盤空間,發現Jenkins存儲的磁盤 /data 已經百分百使用完畢。
這裏寫圖片描述apache

oot@codesrv1:/data/.jenkins/jobs# pwd
/data/.jenkins/jobs
root@codesrv1:/data/.jenkins/jobs# df
Filesystem     1K-blocks      Used Available Use% Mounted on
/dev/sda3 48750348 44294000 2014928 96% /
udev             3886836         4   3886832   1% /dev
tmpfs            1558256       260   1557996   1% /run
none                5120         0      5120   0% /run/lock
none             3895636         0   3895636   0% /run/shm
/dev/sda1        9738232    255456   8994536   3% /boot
/dev/sda5      236267580 236267580         0 100% /data
/dev/sdb1      314197776   5271856 293197332   2% /data1

查看了下 /data/.jenkins/jobs 目錄下 全部的Jenkins jobs的佔用狀況api

root@codesrv1:/data/.jenkins/jobs# du -ah --max-depth=1

使用如上命令,查看全部的Jenkins jobs的磁盤佔用狀況。ruby

這裏寫圖片描述

這裏寫圖片描述

這裏寫圖片描述

查看了大部分的Jenkins Jobs,發現IOS開發人員所擁有的IOS相關的Jenkins任務,隨隨便便都佔用1G以上的磁盤。服務器

進入一個IOS的Jenkins任務,名爲 iOS_Trunk 的Jenkins任務去查看磁盤佔用狀況微信

root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds# pwd 
/data/.jenkins/jobs/iOS_Trunk/builds
root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds# du -ah --max-depth=1
46M ./802
1.5M    ./826
0   ./lastFailedBuild
176M    ./825
166M    ./827
137M    ./810
0   ./lastUnstableBuild
137M    ./797
137M    ./819
176M    ./824
137M    ./800
36K ./822
126M    ./804
137M    ./794
137M    ./803
137M    ./795
137M    ./814
166M    ./828
137M    ./785
137M    ./806
137M    ./805
126M    ./793
0   ./legacyIds
126M    ./798
137M    ./799
126M    ./821
137M    ./783
137M    ./784
126M    ./801
137M    ./809
44K ./817
16K ./787
137M    ./796
137M    ./786
40K ./789
126M    ./813
126M    ./815
126M    ./780
126M    ./790
137M    ./807
0   ./lastUnsuccessfulBuild
0   ./lastSuccessfulBuild
137M    ./811
137M    ./788
24M ./792
176M    ./823
137M    ./820
137M    ./791
0   ./lastStableBuild
137M    ./781
126M    ./808
16K ./816
127M    ./818
178M    ./829
137M    ./812
20K ./782
5.7G    .
root@codesrv1:/data/.jenkins/jobs/iOS_Trunk/builds#

這裏寫圖片描述

這裏寫圖片描述

發現這個iOS_Trunk的Jenkins任務,每一次編譯的常務都有100多Mb,而後保留了大概50次的編譯產物,因此關這一個Jenkins任務就佔用了5.7G。可怕啊!markdown

去查看下 這個Jenkins的配置狀況,以下圖所示:架構

這裏寫圖片描述

如上圖所示,IOS的每一個任務都是 保持構建的最大個數 設置爲了50,那就表明着每個IOS的任務理論上最多都佔用5個多G的磁盤空間。測試

而其餘的Android的Jenkins任務的配置以下圖所示:

這裏寫圖片描述

Android相關的Jenkins任務都是默認最多保留3天的構建產物,這樣就能夠節省磁盤。

3、解決問題

第一步、自動丟棄構建歷史數據

把之前構建過的過期歷史數據自動清除掉,保留最近更新的天數和個數。
這裏寫圖片描述

修改策略爲

  • 保持構建的天數 3
  • 保持構建的最大個數 20

固然這個策略能夠根據本身的項目實際狀況來定。

第二步、關於之前有些Jenkins Job被刪除可是WorkSpace沒有被清理的問題

正常的刪除Jenkins Job的流程是 先清理工做空間 而後再刪除掉Jenkins Job
這裏寫圖片描述

可是有不少同事之前直接就刪除Jenkins Job,並無先清理工做空間,這樣會致使有些被刪除的Jenkins Job原來的工做空間一直存在佔用的磁盤。

搜索了下,https://my.oschina.net/donhui/blog/677935 這篇文章中的Python腳本應該是能夠解決這個問題的。

如下代碼爲轉載內容,原文連接爲 https://my.oschina.net/donhui/blog/677935

摘要: jenkins cleanup workspace after job removal
若是Jenkins使用的Master-Slave多節點架構,刪除Jenkins JOB後,相應JOB的slave節點的workspace不會被刪除

stackoverflow上有相關的問答:http://stackoverflow.com/questions/20532705/deleting-jenkins-jobs-through-gui-does-not-delete-their-workspaces-in-slaves

google groups上有相關的討論:https://groups.google.com/forum/#!topic/jenkinsci-users/SiZ3DL-UJ-8

因此須要自行處理,因而用腳本實現該功能

具體思路是:

遍歷jenkins節點的workspace,根據路徑解析得到jenkins job name
若是該job不存在(經過python jenkinsapi實現),則刪除相應的workspace
暫不考慮自定義的workspace
須要在jenkins每一個節點上進行處理(能夠在jenkins上建立job,將job綁定到相應slave上;也能夠在相應slave上直接運行腳本)
相關的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.example.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()

這個腳本暫時沒有去運行,由於將IOS全部的Jenkins任務的丟棄舊的構建的策略修改以後,目前磁盤空間徹底足夠使用!目前通過一輪清理,已經有84G的剩餘能夠可使用。

這裏寫圖片描述

並且該腳本目前暫時不敢去使用,待我在測試的Jenkins服務器上測試以後再應用到正式的Jenkins服務器。

若是要使用,請讀者將代碼中的相關參數改成本身的Jenkins服務器配置的參數再運行。jenkins_url 、jenkins_username、jenkins_password 、jenkins_workspace_path這幾個參數都得修改成真實的參數。


這裏寫圖片描述

做者:歐陽鵬 歡迎轉載,與人分享是進步的源泉!
轉載請保留原文地址:http://blog.csdn.net/ouyang_peng/article/details/79225993

若是以爲本文對您有所幫助,歡迎您掃碼下圖所示的支付寶和微信支付二維碼對本文進行隨意打賞。您的支持將鼓勵我繼續創做!

這裏寫圖片描述

相關文章
相關標籤/搜索