고급 시스템 관리를 위한 Jenkins Groovy 스크립트 콘솔 마스터하기

Groovy 스크립트 콘솔을 사용하여 Jenkins 관리의 숨겨진 잠재력을 발휘하세요. 이 포괄적인 가이드는 시스템 관리자들이 대량 설정 업데이트, 즉각적인 에이전트 관리(연결 해제/재연결), 실행 중인 빌드 강제 중단과 같은 복잡한 작업을 즉시 수행할 수 있도록 전문가 수준의 실행 가능한 Groovy 스크립트를 제공합니다. Jenkins 객체 모델과 직접 상호 작용하여 비할 데 없는 효율성과 문제 해결 능력을 확보하는 방법을 배우세요.

28 조회수

고급 시스템 관리를 위한 Jenkins Groovy 스크립트 콘솔 마스터하기

Jenkins는 현대 CI/CD 파이프라인의 중추이며, 확장성 모델을 통해 탁월한 유연성을 제공합니다. 대부분의 관리자는 그래픽 사용자 인터페이스(GUI)나 선언적 파이프라인 스크립트에 의존하지만, Groovy 기반의 Jenkins 스크립트 콘솔(Jenkins Script Console)은 즉각적인 시스템 내부 조사, 구성 변경, 그리고 표준 파이프라인 단계를 넘어서는 고급 자동화를 위한 직접적인 저수준 인터페이스를 제공합니다. 이 콘솔은 프로덕션 문제 해결, 대량 업데이트 수행, 또는 Jenkins 핵심 시스템을 직접 관리해야 하는 시스템 관리자에게 필수적입니다.

이 가이드에서는 Groovy 스크립트 콘솔을 활용하여 강력한 관리 작업을 실행하고, 복잡한 수동 개입을 효율적이고 스크립트 가능한 작업으로 전환하는 방법을 안내합니다. 이 도구를 숙달하는 것은 표준 파이프라인 관리에서 진정한 Jenkins 시스템 관리로 나아가기 위한 핵심입니다.


Jenkins 스크립트 콘솔 이해하기

Jenkins 스크립트 콘솔(Jenkins 관리 -> 스크립트 콘솔)은 Jenkins가 선호하는 스크립팅 언어인 Groovy를 사용하여 실행 중인 Jenkins 마스터의 객체 모델과 상호 작용하는 직접적인 경로를 제공합니다. 이를 통해 관리자는 시스템 구성, 작업 객체, 빌드 기록, 연결된 에이전트를 포함하여 Jenkins 런타임 내의 거의 모든 객체에 접근할 수 있습니다.

스크립트 콘솔을 사용하는 이유:

  • 즉시 실행: 작업이 트리거되거나 파이프라인이 시작될 때까지 기다릴 필요 없이 스크립트를 즉시 실행합니다.
  • 시스템 디버깅: GUI를 통해 노출되지 않는 내부 상태, 로그 및 구성 세부 정보에 접근합니다.
  • 대량 작업: 전체 인스턴스에 걸쳐 여러 작업을 수정하거나, 에이전트를 재구성하거나, 오래된 데이터를 빠르게 정리합니다.
  • 스크립트 프로토타이핑: Groovy 로직을 공유 라이브러리나 선언적 파이프라인에 포함하기 전에 테스트합니다.

안전 예방 조치: 직접 접근의 힘

경고: 콘솔에서 실행되는 스크립트는 Jenkins 마스터에서 전체 관리자 권한으로 실행됩니다. 잘못 작성된 스크립트는 구성을 손상시키거나, 빌드를 삭제하거나, Jenkins 인스턴스를 충돌시킬 수 있습니다. 복잡한 스크립트는 항상 비프로덕션 환경에서 먼저 철저히 테스트하십시오.


필수 Groovy 객체 및 API 접근

콘솔의 힘은 핵심 Jenkins 객체에 직접 접근하는 데서 나옵니다. 이러한 객체는 Groovy 실행 환경 내에서 암시적으로 사용 가능합니다.

  • Jenkins.instance: 실행 중인 마스터를 나타내는 핵심 Jenkins 싱글톤 객체입니다.
  • Hudson: Jenkins의 별칭(Alias)입니다.
  • Jenkins.instance.getItemByFullName('JobName'): 특정 작업에 접근합니다.
  • Jenkins.instance.getComputer('AgentName'): 특정 에이전트(노드)에 접근합니다.

Jenkins 인스턴스에 접근하기

접근 권한이 있는지 확인하는 가장 간단한 명령은 Jenkins 버전을 출력하는 것입니다.

println "Jenkins Version: ${Jenkins.instance.version}"
println "Running as user: ${Jenkins.instance.getAuthentication().getName()}"

실용적인 관리 스크립트

다음은 스크립트 콘솔을 통해 고급 관리 제어를 보여주는 몇 가지 실행 가능한 스크립트입니다.

1. 작업 구성 대량 업데이트

이 스크립트는 기존의 모든 작업을 반복하고, 설명 변경이나 여러 프로젝트에 대한 SCM URL 업데이트와 같은 특정 구성 요소를 동시에 수정합니다. 이 예시는 모든 Freestyle 프로젝트의 설명에 표준화된 접미사를 추가합니다.

import hudson.model.FreeStyleProject

final String SUFFIX = " [Automated Update]"

def count = 0

Jenkins.instance.getAllItems(FreeStyleProject.class).each { job ->
    if (!job.getDescription().endsWith(SUFFIX)) {
        job.setDescription(job.getDescription() + SUFFIX)
        job.save()
        println "Updated description for: ${job.getName()}"
        count++
    }
}
println "\nFinished. Total jobs updated: ${count}"

2. Jenkins 에이전트(노드) 관리

관리자는 종종 유지 관리를 위해 에이전트를 오프라인 상태로 전환하거나 오작동하는 노드를 수동으로 연결 해제해야 합니다.

에이전트 일시적으로 연결 해제

이 스크립트는 에이전트를 연결 해제하여 새 빌드가 시작되는 것을 방지하지만, 실행 중인 빌드는 완료되도록 허용합니다.

import hudson.model.Computer

final String AGENT_NAME = "my-specific-agent"

def agent = Computer.instance.get(AGENT_NAME)

if (agent) {
    // Set temporarily offline
    agent.setTemporarilyOffline(true, "Maintenance started by Admin Script.")
    println "Agent '${AGENT_NAME}' set to temporarily offline."
} else {
    println "Agent '${AGENT_NAME}' not found."
}

에이전트 강제 오프라인 및 실행 중인 작업 연결 해제

에이전트를 즉시 종료해야 하는 경우, 강제로 오프라인 상태로 만들고 실행 중인 빌드를 연결 해제할 수 있으며, 이는 구성에 따라 빌드를 실패 또는 중단으로 표시합니다.

import hudson.model.Computer

final String AGENT_NAME = "unresponsive-node-01"

def agent = Computer.instance.get(AGENT_NAME)

if (agent) {
    // Force offline and disconnect running tasks immediately
    agent.doDoDisconnect()
    println "Agent '${AGENT_NAME}' forcefully disconnected."
} else {
    println "Agent '${AGENT_NAME}' not found."
}

3. 실행 중인 빌드 조작

중요한 빌드가 멈추거나 즉시 취소해야 하는 경우, 스크립트 콘솔은 가장 빠른 경로를 제공합니다.

특정 실행 중인 빌드 중단

전체 경로(예: PipelineJob/BuildNumber)로 식별된 빌드를 중단하려면:

// Example: Aborting build #5 of the job named 'CriticalDeploy'
final String JOB_NAME = "CriticalDeploy"
final int BUILD_NUMBER = 5

def job = Jenkins.instance.getItemByFullName(JOB_NAME)

def build = job.getBuild(BUILD_NUMBER)

if (build && build.isBuilding()) {
    build.doCancel()
    println "Build ${JOB_NAME}#${BUILD_NUMBER} has been cancelled."
} else {
    println "Build ${JOB_NAME}#${BUILD_NUMBER} is not running or does not exist."
}

4. 오래된 빌드 기록 정리

디스크 공간을 관리하려면 종종 오래된 빌드를 적극적으로 정리해야 합니다. 이 스크립트는 지정된 작업에 대해 30일보다 오래된 모든 빌드를 식별하고 삭제합니다.

import hudson.model.Job
import java.util.concurrent.TimeUnit

final String TARGET_JOB = "LegacyArchivingJob"
final int DAYS_TO_KEEP = 30

def job = Jenkins.instance.getItemByFullName(TARGET_JOB)

if (job instanceof Job) {
    long cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(DAYS_TO_KEEP)
    int deletedCount = 0

    job.getBuilds().each { build ->
        if (build.getTimeInMillis() < cutoffTime) {
            println "Deleting old build: ${build.getDisplayName()}"
            build.delete()
            deletedCount++
        }
    }
    println "\nCleanup complete. Deleted ${deletedCount} builds for ${TARGET_JOB}."
} else {
    println "Job '${TARGET_JOB}' not found or is not a standard Job type."
}

콘솔 스크립팅 모범 사례

시스템 수준 변경을 수행할 때는 안정성을 유지하기 위해 다음 모범 사례를 준수하십시오.

  1. .save() 사용: 구성 객체(예: Job 또는 View)를 수정할 때마다 Jenkins를 다시 시작한 후에도 변경 사항을 유지하려면 해당 객체에 대해 .save()를 호출해야 합니다. 구성은 저장될 때까지 메모리에만 보관됩니다.
  2. 객체 존재 확인: 작업 또는 에이전트 이름을 잘못 입력하여 콘솔이 충돌하는 것을 방지하기 위해 항상 API 호출을 확인(if (object) 또는 try-catch)으로 감싸십시오.
  3. 영구 루프 방지: 스크립트는 동기식으로 실행됩니다. 콘솔 UI를 차단할 수 있으므로, 빨리 완료될 것이 확실하지 않은 한 장시간 실행되는 루프나 프로세스를 콘솔에서 직접 실행하지 마십시오.
  4. 내장 메서드 활용: Jenkins Groovy 객체에는 종종 특정 헬퍼 메서드(예: doCancel() 또는 doDoDisconnect())가 있습니다. 가능한 한 내부 상태를 수동으로 조작하려고 시도하는 대신 이러한 메서드를 사용하십시오.
  5. 조용한 모드 사용 (해당되는 경우): 과도한 빌드 상태 업데이트를 생성하는 대량 작업을 수행할 때, 일시적으로 이벤트 알림 기능을 비활성화하는 것이 정당한지 고려해야 하지만, 이는 일반적으로 표준 관리보다 더 깊은 시스템 접근을 요구합니다.

Jenkins Groovy 스크립트 콘솔을 숙달하면 단순히 Jenkins를 사용하는 것에서 벗어나 Jenkins의 핵심을 능동적으로 관리하고 최적화할 수 있습니다. 이러한 기술을 연습함으로써 자동화 서버에 대한 세밀한 제어 권한을 확보하고, 복잡한 유지 관리 기간 또는 비상 상황에서 응답성을 획기적으로 향상시킬 수 있습니다.