- 적용한 젠킨스 사이트( 비 로그인 시 ReadOnly )
- [ 배경 ]
- 중고거래 프로젝트가 완성되어 갈 때쯤 배포와 테스트 자동화의 필요성을 느꼈습니다. 자동화 전에는 빌드 도구로 java -jar 후 결과물인 jar파일을 직접 배포 서버에 FTP로 옮긴 후 실행시켰습니다. 간단한 변경사항이 생겨도 또다시 빌드 - FTP로 결과물 옮기기 - 직접 실행을 반복해야 했습니다. 그리고 간단한 테스트까지 직접 URL로 사이트에 들어가서 확인해야 안심이 됐었는데, 테스트까지 반복하는 게 상당히 귀찮았습니다.
- 최근 Github에 commit을 psuh 하면 자동으로 소스코드를 통합하여주고, 배포까지 할 수 있는 편리한 툴인 Jenkins에 대해 알아보겠습니다.
- CI/CD를 도입하기 전에 먼저 정의부터 알아보겠습니다.
- 정의
- CI는 지속적 통합(Continuous Integration)으로, 모든 개발이 끝난 이후에 코드 품질을 관리하는 고전 적 방식의 단점을 해결하기 위해 나온 개념입니다. 말 그대로 '코드에 대한 통합'을 '지속적'으로 진행함으로써 품질을 유지 하자는 것입니다.
CI (지속적 통합)를 구현하면 코드 오류를 줄이고 개발 주기를 단축하며 팀이 소프트웨어를 더 빨리 제공할 수 있습니다. - CD는 지속적 배포(Continuous Deploy)로써, 소프트웨어가 항상 신뢰 가능한 수준에서 배포될 수 있도록 지속적으로 관리하자는 개념입니다. CD는 사용자 피드백, 시장 변화 및 비즈니스 전략 변경을 통합하여 소프트웨어를 지속적으로 적용할 수 있게 하였습니다.
- CI는 지속적 통합(Continuous Integration)으로, 모든 개발이 끝난 이후에 코드 품질을 관리하는 고전 적 방식의 단점을 해결하기 위해 나온 개념입니다. 말 그대로 '코드에 대한 통합'을 '지속적'으로 진행함으로써 품질을 유지 하자는 것입니다.
- 정의
- 중고거래 프로젝트가 완성되어 갈 때쯤 배포와 테스트 자동화의 필요성을 느꼈습니다. 자동화 전에는 빌드 도구로 java -jar 후 결과물인 jar파일을 직접 배포 서버에 FTP로 옮긴 후 실행시켰습니다. 간단한 변경사항이 생겨도 또다시 빌드 - FTP로 결과물 옮기기 - 직접 실행을 반복해야 했습니다. 그리고 간단한 테스트까지 직접 URL로 사이트에 들어가서 확인해야 안심이 됐었는데, 테스트까지 반복하는 게 상당히 귀찮았습니다.
- [ 과정 ]
- Cloud Server 선택
- 언제 어디서나 자동으로 통합, 배포하기 위해 24시간 돌아가는 저만의 서버가 필요했습니다.
- 이전 프로젝트인 도장 추천 사이트를 ruby on rails으로 개발했었는데 aws의 ec2 서버 환경에 배포한 적이 있습니다.
- 멋쟁이 사자처럼 단체에서 받은 크레딧이 마침 남아 있어서 aws ec2 환경에 CI설정을 하자고 마음을 먹었습니다. (멋쟁이 사자처럼 도장 추천 사이트 개발기)
- 클라우드 서버를 AWS로 정하고 진행했던 순서는 아래와 같습니다.
- AWS의 ubuntu linux 18.04 인스턴스를 프리티어 버전인 t2.micro로 생성하였습니다.
- 접속 포트를 열어주었습니다.
- AWS 보안 그룹에서 생성한 인스턴스에 대한 Key Pair를 발급했습니다.
- Putty Key Generate를 이용해 ubuntu.ppk 파일을 생성했습니다.
- Putty Configuration에 발급받은 ppk파일과 ip, port정보를 입력 후 실제 인스턴스에 접속하였습니다.
- CI 서버인 ubuntu 환경에 접속한 후 진행했던 순서는 아래와 같습니다.
- 1. jdk 설치
- 2. 톰캣 설치
- 3. git 설치
- 4. 젠킨스 설치 (톰캣 경로 webapps 안에 넣어 설치)
- 5. 메이븐 설치
- 6. 젠킨스 내부 세팅 ( jdk, git, maven 경로 설정)
- 7. 톰캣 내부 설정 ( 캐시 사이즈, 유저 정보 추가 )
- 8. Github Webhook 설정하기
- 9. 젠킨스 프로젝트 만들고 설정 및 빌드하기 ( Git Parameter, Git source,
빌드 유발 Webhook Trigger, 빌드 Clean compile test, 빌드 후 깃허브에 결과물 전송 등 )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
|
- 1. jdk 설치
$ sudo apt-get update
$ sudo apt-get install openjdk-8-jdk
$ sudo apt-get install openjdk-8-jre
$ java -version
$ javac -version
- 2. 톰캣 설치
-- download tomcat tar file
$ wget https://archive.apache.org/dist/tomcat/tomcat-8/v8.5.53/bin/apache-tomcat-8.5.53.tar.gz
-- unzipped tomcat tar file
$ tar xvf apache-tomcat-8.5.53.tar.gz
-- make custom folder
$ cd /home/ubuntu
$ mkdir myJenkins
-- move tomcat folder to custom folder
$ mv apache-tomcat-8.5.53 /home/ubuntu/myJenkins
[톰캣 시작과 로그 확인하기]
$ /home/ubuntu/myJenkins/apache-tomcat-8.5.53/bin/startup.sh;
[톰캣 기본 페이지 접속 확인]
http://IP:8080
- 3. git 설치
$ sudo apt update
$ sudo apt install git
$ git --version
[git 경로]
which git.
/usr/bin/git
- 4. 젠킨스 설치 (톰캣 경로 webapps 안에 넣어 설치)
$ wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
$ cp -rv jenkins.war /home/ubuntu/myJenkins/apache-tomcat-8.5.53/webapps
[톰캣 재시작]
$ /home/ubuntu/myJenkins/apache-tomcat-8.5.53/bin/shutdown.sh;
$ /home/ubuntu/myJenkins/apache-tomcat-8.5.53/bin/startup.sh;
[젠킨스 페이지 확인]
http://IP:8080/jenkins
[젠킨스 초기 비밀번호 확인]
cat /root/.jenkins/secrets/initialAdminPassword
- 5. 메이븐 설치
$ sudo apt update
$ sudo apt install maven
$ mvn -version
|
cs |
- 6. 젠킨스 내부 세팅 ( jdk, git, maven 경로 설정)
- Jenkins관리 > 플러그인 관리 > git, maven integration, Deploy to container plugin 설치한다.
- 다음으로 Jenkins 관리 > Global Tool Configuration으로 들어가 jdk, git, maven 경로를 전역으로 잡아준다.
- [jdk 경로] /usr/lib/jvm/java-8-openjdk-amd64
- [git 경로] /usr/bin/git
- [메이븐 경로] /usr/share/maven톰캣 내부 설정 ( 캐시 사이즈, 유저 정보 추가 )
- 7. 톰캣 내부 세팅
- 8. Github Webhook 설정하기
- webhook Trigger 파라미터 설정을 통해 git commit, git push, git PR merge시 이벤트 발생
- 9. 젠킨스 프로젝트 만들고 설정 및 빌드하기
- 며칠에 걸친 수많은 삽질과 공부로 결국은 자동화된 CI 설정을 성공할 수 있었습니다.
- 설정 과정 중 발생했던 에러들
- log4j2 에러...
2020-08-12 09:26:53,593 main ERROR appender Console has no parameter that matches element Policies 2020-08-12 09:26:53,600 main ERROR appender File has no parameter that matches element Policies 2020-08-12 09:26:53,604 main ERROR Unable to locate appender "File" for logger config "root" - Redis 에러..
2020-08-12 16:14:56 INFO Finished Spring Data repository scanning in 42ms. Found 0 Redis repository interfaces. - 윈도우환경에서 미리 젠킨스를 구성해서 빌드 배포해보았는데 잘되어서
리눅스에서도 별 이슈 없이 구동될 거라고 생각했다. - AWS EC2 중 가장 낮은 t2.nano로 서버를 구동했는데 java, maven, jenkins
모두 올려보았으나 메모리가 부족하여 서버 속도가 너무 느렸고
java heap size 부족하다는 오류, maven 컴파일 오류 등 많은 오류를 접했다. - 여러 설정을 변경해서 올리기는 성공했다.
하지만 젠킨스로 빌드 속도가 평균 1~2분 걸리는 것이 10분이 넘게 걸리고
동시에 두 개의 프로젝트를 운용하기 어렵다는 것을 확인해 t2.small로 서버를 교체했다.
- log4j2 에러...
- [ 결과 ]
- AWS 우분투 환경에서 젠킨스를 설치하였고 JDK, Tomcat, Maven 등의 환경 설정을 하였습니다.
- push, merge 이벤트 발생 시 Github에서 젠킨스 서버로 hook을 전송하도록 설정하였습니다.
- 젠킨스에서는 프로젝트 소스 코드 접근을 위해 배포 Key 설정하였습니다.
- Maven 빌드 시 컴파일한 소스 코드로 단위 테스트 후 결과를 Github 프로젝트에 코멘트를 남기게 하였고, 메 일로 수신되게 설정하였습니다.
- CI는 빌드 , 유닛 및 통합 테스트, 유효한 코드를 브랜치 별 merge 하여 지속적으로 통합하였습니다.
- CD는 CI에서 머지한 코드를 Package 하여 결과물을 만들고 실제 사용할 프로덕션 서버에 지속적으로 릴리즈 하였습니다.
- AWS 우분투 환경에서 젠킨스를 설치하였고 JDK, Tomcat, Maven 등의 환경 설정을 하였습니다.
- [ 성과 ]
- CI 설정을 통해 코드 오류를 줄이고 개발 주기를 단축하였고 중고거래 프로젝트를 더 빨리 개발할 수 있게 되었습니다.
- 설정하는 과정에서 maven 라이프 사이클 이해, log4j2 설정 에러 해결, Redis 설정 에러를 해결하였습니다.
- 결과적으로 단순 반복 작업을 자동화함으로써 생산성이 높아짐을 몸소 느꼈습니다.
- CI 설정을 통해 코드 오류를 줄이고 개발 주기를 단축하였고 중고거래 프로젝트를 더 빨리 개발할 수 있게 되었습니다.
- used-market-server 중고거래 프로젝트 코드는 아래에서 확인하실 수 있습니다.
- [ 참고 ]
- AWS Ubuntu-1.8.4 Maven : https://shlee0882.tistory.com/267
- Maven LifeCycle : https://javacan.tistory.com/entry/MavenBasic
- Maven 운영환경에 맞게 Profile 하기 : https://www.lesstif.com/java/maven-profile-14090588.html
- Maven Apache 공식문서 : https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
- CI/CD 예시 : developers.redhat.com/blog/2017/05/03/achieving-deployment-excellence-with-red-hat-openshift-io/
- CI 정의 : resources.github.com/whitepapers/practical-guide-to-CI-with-Jenkins-and-GitHub/
- Spring-boot Redis 환경 구축: https://jojoldu.tistory.com/297
- webhook: https://yaboong.github.io/jenkins/2018/05/14/github-webhook-jenkins/
'used-market-server Project' 카테고리의 다른 글
로그인 확인 코드 AOP 적용하기 (0) | 2020.09.09 |
---|---|
Log4j2 Logback Log4j 차이 및 적용 (0) | 2020.09.09 |
대용량 트래픽 환경에서 게시글 검색시 캐싱 적용하기 (0) | 2020.09.09 |
Junit을 이용한 테스트 코드 작성하기 (0) | 2020.09.09 |
로그인 상태 정보인 세션 객체를 분산 서버환경에서 트러블 슈팅 (0) | 2020.09.02 |