4.6. 다른 CI 도구와 연동
어떨 때 읽는 장인가
- 이미 쓰고 있는 CI 도구를 그대로 쓰면서 COP 에 배포하고 싶을 때
- Jenkins 대신 GitLab CI, GitHub Actions 등을 쓰기로 했을 때
- 사내 표준 CI 도구가 정해져 있어 바꿀 수 없을 때
CI 도구란
CI(Continuous Integration, 지속적 통합) 는 소스를 고칠 때마다 자동으로 빌드하고 검사하는 방식입니다. CI 도구는 그 일을 대신 해 주는 프로그램으로, Jenkins·GitLab CI·GitHub Actions·Tekton 등이 있습니다.
도구마다 설정 파일 형식과 화면이 다르지만 하는 일은 같습니다. 정해진 조건이 되면(소스가 바뀌면, 시각이 되면, 사람이 누르면) 정해진 명령을 순서대로 실행합니다.
왜 도구를 바꿔도 되는가
COP 의 빌드·배포는 셸 스크립트 다섯 개로 되어 있습니다(4.5 장). CI 도구는 그 스크립트를 부르기만 합니다.
COP 가 기본으로 제공하는 Jenkins 작업(Job)도 마찬가지입니다. 빌드 작업이 실제로 담고 있는 내용은 다음이 전부입니다.
cd <설치 경로>/workspaces/apps/<네임스페이스>/<앱 이름>
./build-app.sh
./build-push.sh
배포 작업은 ./build-deploy.sh 한 줄, 되돌리기 작업은 ./build-rollback.sh 한 줄입니다.
Jenkins 문법이나 플러그인에 기대는 부분이 없습니다. 셸 명령을 실행할 수 있는 도구라면
무엇이든 같은 결과를 냅니다.
바꿔 말하면 CI 도구를 교체할 때 다시 만들어야 하는 것은 파이프라인 정의 파일 하나뿐이고, 빌드와 배포 논리는 그대로 둡니다.
연동에 쓰는 스크립트
| 스크립트 | 하는 일 | CI 단계 |
|---|---|---|
build-app.sh | 소스를 내려받고 S2I 로 이미지를 만듭니다 | build |
build-push.sh | 이미지를 레지스트리에 올립니다 | build |
build-deploy.sh | 클러스터 Deployment 의 이미지를 바꾸고 완료를 기다립니다 | deploy |
build-history.sh | 배포 이력을 출력합니다 | 확인용 |
build-rollback.sh | 직전 배포로 되돌립니다 | 실패 처리 |
각 스크립트의 자세한 동작은 4.5 장에 있습니다.
도구가 해야 할 일
CI 도구 쪽에서 준비할 것은 셋뿐입니다.
| 할 일 | 설명 |
|---|---|
| 실행 조건 정하기 | 소스 저장소에 올릴 때, 정해진 시각, 또는 사람이 누를 때 |
| 작업 디렉터리로 이동 | 스크립트가 서로를 상대 경로로 부르므로 반드시 그 디렉터리에서 실행합니다 |
| 스크립트 순 서대로 실행 | 빌드 → 올리기 → 배포. 앞 단계가 실패하면 멈춥니다 |
앞 단계가 실패했는데 다음으로 넘어가지 않도록 하십시오. 빌드가 실패했는데 배포가 실행되면 이전 이미지가 그대로 배포되어, 고친 내용이 반영되지 않은 채 "배포 성공" 으로 끝납니다. 대부분의 CI 도구는 명령이 0 이 아닌 값으로 끝나면 그 지점에서 멈춥니다.
도구별 설정 예
같은 일을 도구마다 이렇게 씁니다. 경로와 이름은 설치 구성에 맞춰 바꾸십시오.
GitLab CI (.gitlab-ci.yml)
stages: [build, deploy]
variables:
APP_DIR: /openmaru/workspaces/apps/egov/egov
build:
stage: build
script:
- cd $APP_DIR
- ./build-app.sh
- ./build-push.sh
deploy:
stage: deploy
script:
- cd $APP_DIR
- ./build-deploy.sh
GitHub Actions (.github/workflows/deploy.yml)
on: [push]
jobs:
build-deploy:
runs-on: self-hosted
env:
APP_DIR: /openmaru/workspaces/apps/egov/egov
steps:
- run: cd $APP_DIR && ./build-app.sh && ./build-push.sh
- run: cd $APP_DIR && ./build-deploy.sh
Jenkins 파이프라인 (Jenkinsfile)
pipeline {
agent any
environment { APP_DIR = '/openmaru/workspaces/apps/egov/egov' }
stages {
stage('Build') { steps { sh 'cd $APP_DIR && ./build-app.sh && ./build-push.sh' } }
stage('Deploy') { steps { sh 'cd $APP_DIR && ./build-deploy.sh' } }
}
}
COP 가 기본으로 넣어 주는 Jenkins 작업은 파이프라인이 아니라 자유형(Freestyle) 작업이라 설정 화면의 "빌드 단계 > 셸 실행" 칸에 같은 명령이 들어 있습니다(4.4 장).
실행 위치 두 가지
스크립트는 어디에서 실행되는지 가 중요합니다.
| 방식 | 설명 | 필요한 것 |
|---|---|---|
| Bastion 에서 실행 | CI 도구가 Bastion 에 접속해 명령을 내립니다 | Bastion 접속 권한(SSH) 또는 Bastion 에 설치한 실행기(agent) |
| 컨테이너에서 실행 | CI 도구가 컨테이너를 띄워 그 안에서 실행합니다 | S2I·컨테이너 도구·kubectl 이 들어 있는 이미지, 클러스터 접속 정보 |
Bastion 에서 실행하는 편이 간단합니다. 필요한 도구와 인증 정보가 이미 갖춰져 있어 추가로 준비할 것이 없습니다. 폐쇄망 환경에서는 특히 그렇습니다 — 컨테이너 방식은 빌드용 이미지를 따로 만들어 반입해야 합니다.
준비할 것
어느 도구를 쓰든 다음이 있어야 합니다.
| 항목 | 설명 |
|---|---|
| 소스 저장소 접근 | 빌드할 소스를 내려받을 수 있어야 합니다 |
| 레지스트리 계정 | 이미지를 올릴 권한. build-env.sh 가 갖고 있습니다 |
| 클러스터 접속 정보 | 배포할 네임스페이스에 Deployment 를 고칠 권한(7.1 장) |
| 라이브러리 저장소 | 폐쇄망에서는 사내 저장소를 봅니다. env.sh 가 갖고 있습니다 |
클러스터 권한은 필요한 만큼만 주십시오. 배포에 필요한 것은 그 네임스페이스의 Deployment 를 읽고 고치는 권한입니다. 클러스터 전체 관리자 권한을 CI 도구에 주면 그 도구가 뚫렸을 때 클러스터 전체가 함께 뚫립니다.
확인하는 방법
CI 도구를 바꿨더라도 결과를 확인하는 곳은 같습니다.
| 확인할 것 | 어디에서 |
|---|---|
| 새 이미지가 배포되었는가 | Console 의 Deployment 상세 — 이미지 태그(3.2 장) |
| 파드가 정상으로 떴는가 | Console 의 파드 목록(3.1 장) |
| 배포 이력이 남았는가 | Deployment 상세의 배포 히스토리(3.2 장) |
| 무엇이 잘못되었는가 | 파드 로그와 이벤트(3.1 장) |
배포 이력에는 이미지 태그가 그대로 남습니다. 태그가 <Git 태그>-<커밋 앞 7자리> 형식이라
어느 커밋이 배포되었는지 Console 화면만 보고 알 수 있습니다.
주의할 것
- 같은 애플리케이션을 두 도구에서 동시에 배포하지 마십시오. 나중에 끝난 쪽이 이깁니다. 옮기는 중이라면 한쪽을 먼저 멈추십시오.
- 이미지 태그를
latest로 고정하지 마십시오. 배포 이력에 같은 값만 남아 어느 리비전이 무엇인지 구분할 수 없고, 되돌려도 같은 이미지가 다시 받아집니다. - 스크립트를 CI 설정 파일 안으로 옮겨 적지 마십시오. 도구를 바꿀 때마다 다시 옮겨야 하고, 도구마다 내용이 조금씩 달라져 결과가 갈라집니다. 고쳐야 할 것이 있으면 스크립트를 고치십시오.
- 폐쇄망에서는 CI 도구가 외부로 나가지 못합니다. 도구가 설치할 때 인터넷에서 무언가를 내려받는다면 그 부분을 사내 저장소로 돌려야 합니다.