ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [CI/CD] 젠킨스 구축 3. 젠킨스 설정 및 배포 자동화
    IT 발자취.../CI CD 2018. 12. 9. 03:02

    젠킨스를 사용하여
    자동 배포 환경을 만들어 보겠습니다.

    작업환경
    ● Raspbian GNU/Linux version 8
    ● Jenkins 2.107.3
    ● GitHub plugin 1.3.1
    ● Publish Over SSH 1.19.1
    ※ 서버가 총 한대로, Jenkins와 웹서비스가 구동되는 서버가 함께 있는 환경 (Spring boot사용)
    두 대의 다른 서버로 구축하려면 아래 글을 참고해주세요.

    자동배포 시나리오 (시나리오에 따라 설정이 바뀔 수 있다)
    1. 누군가 hook branch에 변경사항을 푸시한다.
    2. GitHub가 푸시 이벤트를 감지하고 Jenkins에 WebHook을 보낸다.
    3. Jenkins의 Job(아이템)이 신호를 받는다.
    4. Job은 해당 branch의 최신 소스를 받고 빌드해 war를 만든다.
    5. 이어서 SSH 통신으로 remote 서버에 war 파일을 전송한다.
    6. 전송 후 명령 스크립트로 기존 war 파일을 방금 빌드한 war로 교체한다.
    7. 서버 환경에 따라 적절히 마무리한다.

    1. Jenkins 플러그인 설치
    Jenkins 관리 > 플러그인관리 에서 다음의 플러그인을 설치해야 합니다. 플러그인이 설치되지 않을 경우 특정 메뉴가 보이지 않으므로 필요한 플러그인들은 설치해야합니다.

        1) GitHub plugin : 젠킨스와 GitHub 통합을 지원하는 플러그인이다.
        2) Publish Over SSH plugin (Publish Over A) : 젠킨스가 빌드한 파일을 A를 통해 보내준다.
        3) Deploy to container Plugin : 빌드가 된 war/ ear 파일을 remote 서버로 배포한다.

    2. Jenkins job이 GitHub의 푸시 이벤트 받기
    GitHub plugin은 jenkins가 GitHub의 Hook을 받을 수 있도록 수동 모드와 자동모드를 제공한다. 수동모드는 사용자가 Git Repository setting으로 가서 Hooks & Services을 직접 등록해 사용하는 것잉고, 자동 모드는 사용자의 GitHub OAuth 토큰을 이용해 Jenkins가 자동으로 Hooks & Service를 등록한다.
     2.1 GitHub OAuth 등록
    Jenkins에 사용자의 GitHub OAuth 토큰을 먼저 등록합니다. Jenkins 관리 > 시스템설정 에서 GitHub 세팅을 찾는다.

    Name : 적절한 이름을 지어준다
    API URL : 자신이 사용하는 GitHub 주소에 /api/v3를 붙이면 된다.
                    Hook을 받을 때 수동을 받을려면 그대로 둬도 되는것 같다(?)
    Credentials 오른편의 Add를 눌러 GitHub Personal access 토큰을 입력합니다. 토큰은 자신의 GitHub계정의 Settings > Developer Settings > Personal access tokens 에서 Generate new token으로 토큰을 생성합니다.

    repo와 admin:rep_hook을 선택하고 토큰을 생성합니다.

    kind는 Secret text로 두고
    Secret : 토큰값
    ID와 Description은 인증정보를 구별할 수 있는 적당한 값으로 입력합니다.

    2. 2 Jenkins Job 생성
    프로젝트를 Freestyle project job로 생성합니다.

    이름을 적절히 설정해 주고 GitHub project를 체크하여 project url을 기입합니다.

    소스코드 관리에서 Git을 선택하고 레파지토리 URL과 계정, 그리고 자동배포한 branch를 입력합니다.
    Default로는 mater개정으로 지정되며 mater 브랜치에 누군가 푸시할 때 해당 Job이 동작하게 됩니다.

    빌드 유발에서 GitHub hook trigger for GITScm polling 항목을 선택한다.
    젠킨스가 repo부터 GitHub hook Push를 받습니다.

    설정을 세팅한후 저장을 하고, Git repository setting의 Hook & Service에 들어가면 Jenkins가 자동으로 등록한 Webhooks를 볼수 있습니다.

    위와 같이 정상적으로 WebHook이 만들어지거나
    아래와 같이 오류가 생길 수가 있습니다.

    오류가 생겼거나 자동으로 Webhook이 만들어지지 않았을 경우 수동으로 Webhook을 만들어줍니다.
    Integrations & Service 에서 Add service에 Jenkins(GitHub plugin)을 선택해줍니다.

    아래에 설치한 젠킨스주소/github-webhook/ 을 넣고 저장해줍니다.
    하지만,  여기서 hocalhost를 입력하거나 내부 IP를 입력하면 Github 서버의 localhost나 내부ip로 인식하게 되니, 젠킨스가 외부 IP를 가지게 해야합니다. 이를 도와주기 위해 ngrok이라는 것을 사용하였는데, 보안상 문제가 될 수도 있으니 참고해서 사용하시기 바랍니다.

    ## ngrok을 사용했다면 Jenkins 설정 > Jenkins Location URL을 바꿔줍니다.

    생성된 webhook을 참고하면 실패 또는 성공 여부를 json형식의 response로 받아 볼 수 있습니다.

    이제 Jenkins Job에는 GitHub Hook Log라는 메뉴가 생기고 branch에서 푸시하면 hook 이벤트를 수신한 것을 직접 볼 수 있습니다.

    3. 빌드
    Settings 에서 Build를 찾아 빌드를 추가해줍니다. (Maven 프로젝트 예시)

    Jenkins는 빌드 후 war를 $JENKINS_HOME/jobs/$Job_name/workspace 에 저장합니다. 
    Goals : clean packge
    POM : pom.xml (pom.xml 위치 입력)

    빌드 후 WAS 컨테이너에 배포를 하기 위해 정보를 입력합니다.
    이 경우는 war를 해당 container에 배포하는 것이므로 tomcat에서 .war 파일이 복사 된 후에 자동 적용이 된다.
    만약 comcat을 restart하기 원할 경우 빌드 후 조치를 사용하지 말고 build에서 Add Build Step > Excute Shell을 추가해서 스크립트를 입력하면 된다.

    4. remote 서버로 SSH 통신을 이용해 war 전송하기
    먼저 jenkins에 remote서버의 ssh 인증을 등록한다. 
    Jenkins Settings > 시스템 설정에서 Pulish over SSH로 간다.
    본인이 작업하고 있는 환경에 따라 설정이 바뀌므로 여러가지 방법을 적어보겠습니다.

    · Passphrase : 기존에 적혀있습니다. 비워 놓아도 무방합니다.
    · Path to key : Jenkins 서버의 id_rsa 파일이 있는 위치. (private key, Path는 절대경로, $JENKINS_HOME 기준 상대 경로로 적어줍니다)
    · Key : Path to key에 id_rsa 파일의 위치를 넣어도 되고 Key에 파일의 내용을 가져와 붙여 넣어도 됩니다. 둘다 입력 시 우선 순위는 Path to Key가 더 높다고 합니다.
    · Name : 적당히 서버의 이름을 입력
    · Hostname : remote 서버의 IP
    · Username : remote 서버의 계정명을 입력해야 합니다.
    · Remote Directory : 배포할 서버의 기본 workspace라 보면 됩니다. 파일 전송 시 디렉토리를 정해 주지 않으면 여기로 가게 됩니다.

    라즈비안에 Jenkins와 WAS를 함께 사용하고 있을 경우 

    jenkins.plugins.publish_over.BapPublisherException: Failed to connect session for config myconfig. Message [Auth fail]

    위의 오류가 발생하여 인증 처리가 되지 않았습니다 . 
    해결법으로는 

    1. Remote 서버의 authorized_keys에 Jenkins 서버의 id_rsa.pub의 공개키를 넣어두면 된다. 참고로.ssh파일의 권한은 700 authorized_keys는 600 이 아니면 ssh 인증이 동작하지 않는다. 
    2. Use password authentication , or use a different key 체크박스를 선택하고, Passphase/ password에 사용자 비밀번호를 적어줍니다. (저의 경우 pi의 비밀번호를 넣었습니다.)

    SSH를 설정하였다면 Send files or excute commands over SSH 를 통해 빌드 후 파일 전송을 할 수 있습니다.
    Source files : 아까 Jenkins는 빌드 후 JENKINS_HOME/jobs/$Job_name/workspace에 저장한다고 했는데, 해당 디렉토리 기준으로 전송할 파일의 위치를 작성한다.
    Remove prefix : 위 예제처럼 디렉토리 안에 파일이 있는 경우 디렉토리까지 다 전송되게 되는데 이곳에 디렉토리를 명시하면 해당 디렉토리는 전송되지 않고 안의 파일만 전송된다.
    Remote directory : 아까 설정한 remote server의 workspace 기준으로 어디다 전송할 것인지.
    Exec command : 파일을 전송한 후 실행할 리눅스 명령어. remote 서버에 배포관련 script를 미리 가따놓고 여기서 실행하면 된다. 안적어도 된다. 빨간색으로 오류가 적히는 것은 젠킨스 어느 버전 이후로의 버그라고 한다.

    ## 개인프로젝트를 진행하고 있으므로 깃허브의 branch는 master로만 사용하고 있어 IDE에서 master 브랜치로로 push를 하면 GitHub의 Webhook이 변경을 감지하고 자동으로 Jenkins를 이용하여 배포를 하게 됩니다. 실제 프로젝트에서 master 브랜치는 최종 승인자가 될 것입니다. 
    또는 아침 점심 저녁 이렇게 정해진 시간에 배포를 하여 팀원들이 정해진 시간내에 부담감(?)을 가지고 자유롭게 개발을 할 수 있게 됩니다.
    추후로 젠킨스를 이용해서 서비스 받을 수 있는 슬랙을 연결하든 카카오 챗봇을 이용해서 결과 전송을 받는 등으로 포스팅을 이어가려고합니다.

    댓글

Designed by Gintire