[Rundeck] 배포 개선 내용 공유
안녕하세요? 정리하는 개발자 워니즈입니다. 이번시간에는 Rundeck 을 활용하여 배포 개선
작업을 했던 내용을 공유 하려고자 합니다.
필자가 속한 프로젝트는 CD(Continuous Deploy) 툴로 Rundeck을 사용하고 있습니다. 또한, 특수한 솔루션을 사용하다보니, 기존의 Spring Framework처럼 war파일을 배포하는것이 아닌, zip파일을 해당 서버에 명령어를 활용하여 설치하는 개념으로 되어있는데요.
배포 작업 시, 이러한 zip파일이 여러개 있고, 또한 각 zip파일마다 배포되어야 할 서버들이 각기 다르다면, 이것을 런덱에서 수행하게 되면 작업자 실수
를 유발하게 됩니다.
1. 기존 배포 방식
우선 기존에 프로세스는 아래의 순서로 진행이 됩니다.
- 소스 pull
- 빌드
- 태그 생성
위의 방식으로 진행하기 위해서는 내용이 담겨있는 job이 생성이 되어있어야 하는데요. 제가 속한 프로젝트에서는 Jenkins
로 빌드를 수행하고 나온 Tag를 Rundeck
으로 보내주고 있습니다.
이렇게 한 이유는 내부 IDC에 소스를 관리하고있는데 pull + build는 내부에서 진행하고 Deploy는 AWS에 있는 서버들에 해주기 때문에 jenkins와 Deploy를 나눠놨습니다.
스프링 프레임워크와는 다르게 해당 소스만 추출하여 빌드가 가능하다 보니, 아래와같이 filter
라는 개념으로 해당 소스를 업데이트하여 hotfix
가 가능하도록 되어있습니다.
캡쳐된 이미지처럼, 입력해야될 파라미터들이 많이 있고, 직접 TYPING을 하다보니, 작업자 실수를 유발하기도 합니다.
- 빌드job
#패키지 생성
curl -s -u admin:$ADMIN_PW -X POST $IPADDRESS:$PORT/crx/packmgr/service/.json/etc/packages/HOTFIX/hotfix_${SR_NUM}_${WHO}_${TIMESTAMP}?cmd=create -d packageName=hotfix_${SR_NUM}_${WHO}_${TIMESTAMP} -d groupName=HOTFIX
echo "package create"
#패키지 필터 업데이트
curl -s -u admin:$ADMIN_PW -X POST $IPADDRESS:$PORT/crx/packmgr/update.jsp -F path=/etc/packages/HOTFIX/hotfix_${SR_NUM}_${WHO}_${TIMESTAMP}.zip -F packageName=hotfix_${SR_NUM}_${WHO}_${TIMESTAMP} -F groupName=HOTFIX -F filter="$FILTER_JSON" -F '_charset_=UTF-8'
echo "package update"
#패키지 빌드
curl -s -u admin:$ADMIN_PW -X POST $IPADDRESS:$PORT/crx/packmgr/service/.json/etc/packages/HOTFIX/hotfix_${SR_NUM}_${WHO}_${TIMESTAMP}.zip?cmd=build
echo "package build"
#패키지 다운로드
curl -s -u admin:$ADMIN_PW $IPADDRESS:$PORT/etc/packages/HOTFIX/hotfix_${SR_NUM}_${WHO}_${TIMESTAMP}.zip > /deploy/archive/build_archive/prd/hotfix/hotfix_${SR_NUM}_${WHO}_${TIMESTAMP}.zip
- deploy job
캡쳐된 이미지의 빨강 박스
에서 보듯이 Deploy job 역시 1) 해당 태그 와 2) 타겟 서버를 직접 입력해주어야 합니다. 배포 작업하는날에 단일배포면 좋겠지만, 수많은 태그와 각기 다른 타겟서버로 작업실수가 굉장히 많았습니다.
기존에는 위의 엑셀과 같이 수기로 배포 현황을 관리했으며, 작업 인수인계시에 해당 엑셀까지 같이 인수인계를 해야되는 번거로움이 있었습니다.
2. 배포 대시 보드 구축
해당 엑셀 파일과 동일한 효과를 내는 배포 대시 보드를 구축하기로 마음을 먹고 기술스택을 정리했습니다.
- Node.js
- express
- file DB
- jquery opensource (grid, ajax…)
우선 핵심은 Node.js + express로 웹사이트를 올리는것이였습니다. 그리고 front ui를 입히고 테이블처럼 만들어서, 버튼을 클릭하게 되면, Rundeck API를 호출하는 구조로 만들었습니다.
2-1. 서버
var express = require('express');
var app = express();
var bodyParser = require('body-parser')
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({extended:true}))
var router = require('./router/main')(app);
var fs = require('fs');
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.engine('html', require('ejs').renderFile);
app.use(express.static('public'));
var server = app.listen(3030, function(){
console.log("Express server has started on port 3030")
})
서버는 Node.js 로 구축을 하고 3030
포트로 웹을 올렸습니다. 그 외 필요한 부분은 Router를 이용하여 구현하였습니다.
- Router
app.get('/',function(req,res){
res.render('main.html')
});
app.post('/writeJson', function(req, res){
var json = req.body;
console.log(json);
json = JSON.stringify(json);
fs.writeFile('WriteASync.json', json ,'utf8', function(error, data){
if (error) {throw error};
console.log("ASync Write Complete");
});
return res.send('200 ok');
});
실질적으로는 html
을 전달해주고 해당 내부에 js를 심어서 동작하게 하는 간단한 웹입니다. 그 외에 API
들은 router에 붙여서 호출이 가능하도록 했고, 기능 단위는 다음과 같습니다.
- file DB update -> 엑셀로 관리하던 내용을 file DB 형식으로 변경 (추가로 light한 DB를 연동할 예정입니다.)
- AWS ELB 조
대시보드를 통해서 아마존 ELB 현황까지 체크를 할 수 있도록 하였습니다.
2-2. 프론트
앞서 이야기했듯이 Front-end 같은 경우는 html
구조로 되어있고, 이를 rendering해주는 내용입니다.
대시보드 UI를 입혀서 테이블 구조로 나타냈고, bootstable.js 를 내장하고있기때문에 그 안에서 모든 로직을 구현했습니다.
프론트 엔드에서 기능은 다음과 같습니다.
- 테이블 생성 및 삭제 / 태그 입력
- 각 타입별 타겟 서버 버튼 자동생성
- 버튼 클릭시 rundeck api 호출
- AWS ELB attach/detach
화면에 노출이 되는것은 아니나, javascript를 활용하여 다음의 기능도 가능하도록 했습니다.
- 각 타겟 단위 serial 클릭(배포) -> qa 배포/ live 배포
- 태그 생성 및 자동 입력
기존의 엑셀에서 관리하다가 태그만 입력이 되면, 배포하고 난 뒤, 색깔을 자동으로 색칠해주고, file DB를 업데이트 해주다보니, 손쉽게 배포가 가능하도록 했습니다.
2-3. 챗옵스 연결
필자가 있는 프로젝트에서는 챗옵스를 활용한 배포를 하고 있습니다. 챗옵스 플랫폼으로 Slack
을 활용하고 있고 내부적으로 custom하게 작성한 bot이 있고, 이 bot으로 일련의 처리들을 진행하고 있었습니다.
상위에서 이야기했던 배포 대시 보드
를 활용하기 위해서 ChatOps를 연결하기로 했고, 내부적으로 연결하기 위해서 bot소스 내에 Puppeteer
를 활용하여 작업을 했고, 아래의 기능을 이용했습니다.
- 태그 생성 및 자동 입력
챗옵스 -> puppeteer -> 배포 대시보드 -> Rundeck
위의 순서로 호출을 하고, 배포 결과를 다시 배포 대시 보드에 입력해줌으로써 작업자로 하여금 편리하게 구현을 해두었습니다.
- 각 타겟 단위 serial 클릭(배포) -> qa 배포/ live 배포
배포 묶음단위를 지정하게 되면 배포 대시보드
에서 해당 묶음으로 있는 버튼들에 대한 액션을 순서대로 진행합니다.
(여기서 중요한것은 Rudneck api호출후에 해당 job이 성공이 된것을 받아야 다음으로 진행하게 됩니다.)
챗옵스에게 배포 명령만 해두면, 해당 JOB이 Serial 하게 진행이 되기때문에 작업자는 그안에 다른 유익한 일을 해도 됩니다.
또한 배포가 완료되면, 유관 업무를 하는 곳에 사내 메신저로 배포 완료
에 대한 공지를 하기때문에 모든 작업들이 코드화 되어 진행되게 됩니다.
3. 효과
기존의 수작업으로 관리되던 배포에서 자동화 된 시스템을 통하여 배포를 진행하다 보니 우선 가시적으로는 시간적인 여유가 많이 생겼습니다. 또한 작업자의 실수를 줄일 수 있다보니, 장애 예방에 대한 효과도 극명하게 드러납니다. 부가적으로 챗옵스를 통하여 작업을 진행하다보니 기존의 이력이 history로 남고, 유관자에게 인수인계하기도 좋습니다.
기존 작업대비 80% 이상의 시간감소를 보이고, 정확성도 높아졌습니다. 수치적으로는 정확하게 짚을수는 없지만, 개선의 효과는 극명하게 나타납니다.