본문 바로가기

Build/Jenkins

[Infrastructure/Jenkins] SSH Pipeline Steps 플러그인을 사용한 원격 호스트 제어

파이프라인 스크립트를 작성하다보면 Steps에서 처리해야하는 작업이 Jenkins 호스트가 아닌 원격 호스트인 경우가 있습니다. 예를 들면 젠킨스에서 애플리케이션 배포 후 원격 호스트에서 애플리케이션을 실행하는 등의 작업이 필요 할 수 있습니다.

SSH Pipeline Steps 플러그인

SSH Pipeline Steps는 파이프라인에서 원격 호스트에 접속하여 제어하기 위한 플러그인입니다. 지속적인 전달(CD)를 위한 파일 전송 및 SSH 기능을 제공합니다. 자세한 정보는 ssh-steps-plugin GitHub에서 확인 할 수 있습니다. 

사전 요구 사항

2.0.0 버전 기준 다음 요구 사항을 만족해야합니다. 플러그인 설치 관련해서는 다음 문서를 참고합니다.

  • Pipeline: Step API 플러그인 2.19 버전 이상

Remote

원격 노드에 대한 설정을 담기 위해 Map 자료 구조를 사용합니다. 예시의 파이프라인 스크립트는 원격 노드에 대한 설정을 지정하는 방식을 보여줍니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        sshCommand remote: remote, command: "ls -lrt"
        sshCommand remote: remote, command: "for i in {1..5}; do echo -n \"Loop \$i \"; date ; sleep 1; done"
    }
}

​예시에서 def remote = [:]는 빈 Map 자료 구조를 초기화하는 Groovy 구문입니다. 다음 표는 원격 노드 설정에 자주 사용되는 옵션을 키-값에 대해서 정리한 내용입니다(*는 필수 옵션).

비고
*name string 원격 노드 이름, 일반적으로 host와 같은 값을 입력
*host string 원격 노드에 대한 도메인 또는 IP 주소
port int 원격 노드에 대한 SSH 포트(디폴트:22)
*user string 원격 노드 사용자 이름
password string 원격 노드 사용자 비밀번호(*password, identity, identityFile 중 하나는 필수로 입력)
identity string 퍼블릭 키 증명을 위한 프라이빗 키(*password, identity, identityFile 중 하나는 필수로 입력)
identityFile string 퍼블릭 키 증명을 위한 프라이빗 키 파일 경로(*password, identity, identityFile 중 하나는 필수로 입력)
*knownHost boolean known hosts 파일 경로
allowAnyHosts boolean *이 옵션을 true로 지정하면 knownHost 옵션을 Optional로 변경(디폴트:false)
pty boolean 이 옵션을 true로 지정하면 PTY(presudo-terminal)로 할당(디폴트:false)

Pipeline Steps

이 플러그인에서 제공하는 파이프라인 Steps은 이전 섹션에서 소개한 def remote = [:]로 지정된 환경 설정과 함께 호출됩니다.

  • sshCommand
    원격 노드에 지정된 명령 실행하고 표준 출력을 응답합니다.
  • sshScript
    로컬 호스트의 스크립트 파일을 원격 노드에서 실행하고 표준 출력을 응답합니다.
  • sshPut
    로컬 호스트의 파일 또는 디렉토리를 원격 노드에 전송합니다.
  • sshGet
    원격 노드의 파일 또는 디렉토리를 로컬 호스트로 전송합니다.
  • sshRemove
    원격 노드의 파일 또는 디렉토리를 삭제합니다.

sshCommand

원격 노드에 지정된 명령 실행하고 표준 출력을 응답합니다.

sshCommand remote:[원격 노드 환경 설정], command:[명령문], sudo:[true|false], failOnError:[true|false], dryRun:[true|false]

다음은 사용되는 옵션에 대한 설명입니다(*는 필수 옵션).

비고
*remote variable 원격 노드 환경 설정
*command string 실행 명령문
sudo boolean 실행 명령문을 sudo 모드로 실행. *이 옵션을 true로 지정하려면 원격 노드 환경 설정에서 pty:true로 지정 필요(디폴트:false)
failOnError boolean 이 옵션을 false로 지정하면 오류가 발생하더라도 출력하지 않음(디폴트:true)
dryRun boolean 이 옵션을 true로 지정하면 노드와의 실제 연결 및 실행이 발생하지 않음(디폴트:false)

파이프라인 스크립트에서는 다음과 같이 사용 될 수 있습니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        sshCommand remote: remote, command: "ls -lrt"
        sshCommand remote: remote, command: "for i in {1..5}; do echo -n \"Loop \$i \"; date ; sleep 1; done"
    }
}

sshScript

로컬 호스트의 스크립트 파일을 원격 노드에서 실행하고 표준 출력을 응답합니다.

sshScript remote:[원격 노드 환경 설정], script:[로컬 호스트 경로], failOnError:[true|false], dryRun:[true|false]

다음은 사용되는 옵션에 대한 설명입니다(*는 필수 옵션).

비고
*remote variable 원격 노드 환경 설정
*script string 로컬 호스트에서의 스크립트 파일 경로
failOnError boolean 이 옵션을 false로 지정하면 오류가 발생하더라도 출력하지 않음(디폴트:true)
dryRun boolean 이 옵션을 true로 지정하면 노드와의 실제 연결 및 실행이 발생하지 않음(디폴트:false)

파이프라인 스크립트에서는 다음과 같이 사용 될 수 있습니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        writeFile file: 'abc.sh', text: 'ls -lrt'
        sshScript remote: remote, script: "abc.sh"
    }
}

sshPut

로컬 호스트의 파일 또는 디렉토리를 원격 노드에 전송합니다.

sshScript remote:[원격 노드 환경 설정], from:[원격 노드 경로], into:[로컬 호스트 경로], filterBy:[파일 필터], filterRegex:[파일 정규표현식], failOnError:[true|false], dryRun:[true|false]

다음은 사용되는 옵션에 대한 설명입니다(*는 필수 옵션).

비고
*remote variable 원격 노드 환경 설정
*from string 원격 노드의 파일 또는 디렉토리 경로
*into string 로컬 호스트의 파일 또는 디렉토리 경로
filterBy string 파일 필터. Java의 File 객체의 인자를 사용(디폴트:name)
filterRegex string Groovy 구문에 따른 파일 정규표현식 필터(e.g. /\.xml$/는 .xml 확장자를 필터).
failOnError boolean 이 옵션을 false로 지정하면 오류가 발생하더라도 출력하지 않음(디폴트:true)
dryRun boolean 이 옵션을 true로 지정하면 노드와의 실제 연결 및 실행이 발생하지 않음(디폴트:false)

파이프라인 스크립트에서는 다음과 같이 사용 될 수 있습니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        writeFile file: 'abc.sh', text: 'ls -lrt'
        sshPut remote: remote, from: 'abc.sh', into: '.'
    }
}

sshGet

원격 노드의 파일 또는 디렉토리를 로컬 호스트로 전송합니다.

sshScript remote:[원격 노드 환경 설정], from:[로컬 호스트 경로], into:[원격 노드 경로], filterBy:[파일 필터], filterRegex:[파일 정규표현식], failOnError:[true|false], dryRun:[true|false]

다음은 사용되는 옵션에 대한 설명입니다(*는 필수 옵션).

비고
*remote variable 원격 노드 환경 설정
*from string 로컬 호스트의 파일 또는 디렉토리 경로
*into string 원격 노드의 파일 또는 디렉토리 경로
filterBy string 파일 필터. Java의 File 객체의 인자를 사용(디폴트:name)
filterRegex string Groovy 구문에 따른 파일 정규표현식 필터(e.g. /\.xml$/는 .xml 확장자를 필터).
failOnError boolean 이 옵션을 false로 지정하면 오류가 발생하더라도 출력하지 않음(디폴트:true)
dryRun boolean 이 옵션을 true로 지정하면 노드와의 실제 연결 및 실행이 발생하지 않음(디폴트:false)

파이프라인 스크립트에서는 다음과 같이 사용 될 수 있습니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        sshGet remote: remote, from: 'abc.sh', into: 'abc_get.sh', override: true
    }
}

sshRemove

원격 노드의 파일 또는 디렉토리를 삭제합니다.

sshScript remote:[원격 노드 환경 설정], path:[원격 노드 경로], failOnError:[true|false], dryRun:[true|false]

다음은 사용되는 옵션에 대한 설명입니다(*는 필수 옵션).

비고
*remote variable 원격 노드 환경 설정
*path string 원격 노드의 파일 또는 디렉토리 경로
failOnError boolean 이 옵션을 false로 지정하면 오류가 발생하더라도 출력하지 않음(디폴트:true)
dryRun boolean 이 옵션을 true로 지정하면 노드와의 실제 연결 및 실행이 발생하지 않음(디폴트:false)

파이프라인 스크립트에서는 다음과 같이 사용 될 수 있습니다.

node {
    def remote = [:]
    remote.name = 'test'
    remote.host = 'test.domain.com'
    remote.user = 'root'
    remote.password = 'password'
    remote.allowAnyHosts = true
    stage('Remote SSH') {
        sshRemove remote: remote, path: "abc.sh"
    }
}