티스토리 뷰

배포

CI/CD 적용하기

도라지보다더덕 2020. 9. 4. 01:37

 

 

 

 

 

개요


DevOps

DevOps란 개발과 운영을 함께하는 소프트웨어 개발 방법론입니다. 소프트웨어 개발 시에는 개발뿐만 아니라 빌드, 테스트, 배포 등 여러 과정이 필요합니다. 따라서 기존의 회사들은 하나의 서비스를 개발과 운영팀으로 나눠 관리했습니다. 이렇게 하나의 서비스를 개발과 운영으로 나누다보니 의사결정과 소통에서 비효율적인 문제가 발생했습니다. 따라서 개발과 운영을 함께 할 수 있는 방법론인 DevOps가 탄생하였습니다.

 

하나의 서비스를 개발한 후 운영하다보면 필연적으로 그 서비스는 여러 변경사항이 생깁니다. 과거에는 이 변경된 코드를 적용하기 위해서 모든 개발자가 모여 직접 코드를 병합하였습니다.

 

최근에는 애플리케이션 배포 주기가 짧아지면서 잦은 코드 병합이 일어나고 이 때마다 여러 개발자가 모여 직접 병합할 경우 생산성 저하라는 문제가 발생되었습니다. 배포 또한 마찬가지로 여러 서버에서 배포를 진행해야한다면 수동으로 배포하기엔 실수를 할 가능성이 높아지고 특히 서버가 몇 백대라면 수동 배포에 한계가 존재하게되었습니다.

 

따라서 통합과 배포를 자동화하여 운영해주는 DevOps의 CI/CD 개념이 탄생하게되었습니다.

 

CI/CD 란?

  • CI(Contiuous Integration): 지속적 통합을 의미하는 용어로 추가되거나 수정된 코드들을 실시간으로 병합하여 안정적인 배포 파일을 만드는 과정을 의미.
  • CD(Contiuous Deployment): 지속적인 배포를 의미하는 용어로 병합된 코드를 자동으로 배포해주는 과정을 의미

 

더보기

CI란?

CI지속적 통합는 지속적으로 퀄리티 컨트롤을 적용하는 프로세스를 실행하는 것이라고 정의가 쓰여있습니다. 애플리케이션에 대한 새로운 코드 변경 사항이 정기적으로 빌드  테스트되어서 하나의 레포지토리로 관리되는 것을 의미합니다.

  • SCMSource Code Management의 과정도 CI에 속합니다.
    • Git을 사용해 Github 레포 하나로 여러명의 개발자가 소스코드를 올리고 충돌을 처리하는 모든 과정도 CI에 속합니다.
    • Git이 아닌 SVN도 마찬가지입니다.
  • 빌드 후 작성된 테스트 코드를 통해 유효성을 검증하는 것도 CI에 속합니다.
    • 아주 간단한 예시로 Pull Request를 생성했을 때, 소스코드가 Conflict나는 경우 Merge 버튼이 비활성화 되는 경험을 해보셨을 겁니다. 그것 또한 유효성 검사에서 실패한 것으로 CI에 속합니다.
    • 더 나아가, CI 툴을 사용해 소스코드가 컨벤션에 준수하는지 등을 체크하는 린터linter로 검증을 하도록 할 수 있는 등 다양한 일이 가능합니다.

CI를 하면 뭐가 좋은가요?

  • 지속적 통합을 하게되면 소스코드는 항상 Ready-to-run 상태(배포가 가능한 상태는 아닙니다.)가 됩니다. 즉, 중간에 누군가 합류를 해도 빌드가 되는 코드를 받을 수 있습니다.
    • 혼자서 개발할 때는 이런 문제를 겪어보지 못해서 중요성을 체감하지 못합니다.
    • 하지만, 회사 프로젝트나 오픈소스 프로젝트 등 여러명이서 개발을 하는 상태라면 이 문제는 더욱 중요해집니다.
      • 중간에 합류해서 새로운 기능을 개발하려고 하는데 누군가 작업하고 있는 코드가 아직 공유 레포upstream에 올라가 있어서 빌드가 안된다.
      • 이런 경우가 발생하면 그 사람과 얘기해서 해결하던가, 직접 소스코드를 보고 돌아가도록 디버깅을 하던가 해야합니다. 하지만, 이 자체로도 시간이 소요되므로 생산성이 매우매우 떨어지게 됩니다.
    • 게다가, 특정한 날을 정해서 각자 개발한 소스코드를 병합하도록 하게되면 그에 따르는 많은 시간을 소모하게 됩니다.
      • 만약, 기존 코드와 Merge한 코드가 에러가 난다면 이를 처리하는 과정에도 많은 시간이 소요될 것입니다.
  • 항상 양질의 코드 퀄리티를 유지할 수 있습니다.
    • 테스트의 자동화를 이루게되면 항상 테스트 코드를 통과하는 코드만 공유 레포에 올라갈 수 있기 때문에 상당한 퀄리티의 소스코드로 유지되게 됩니다.

CD란?

CD는 지속적 제공Continuous Delivery과 지속적 배포Continuous Deployment를 모두 의미합니다.

  • 지속적 제공Continuous Delivery : CI 과정이 모두 끝난 뒤 유효성 검증이 된 코드를 레포지토리에 올리는 것을 자동화합니다. (프로덕션 레벨로 배포하는 것과는 별개입니다.)
    • 항상 프로덕션 레벨로 배포할 수 있는 준비가 되어있는 소스코드를 자동으로 올라갈 수 있도록 합니다.
  • 지속적 배포Continuous Deployment : CI/CD 과정의 마지막 단계입니다. 지속적 제공을 통해 배포 가능한 소스코드를 프로덕션 레벨로 릴리즈하는 것을 의미합니다.

실제 사례에서 지속적 배포는 개발자가 애플리케이션을 수정한 뒤 몇 분 이내에 애플리케이션을 자동으로 실행할 수 있는 것을 의미합니다.

CD를 하면 뭐가 좋은가요?

  • 개발부터 배포까지 과정이 번거롭지 않고 간소화 되기 때문에 사용자 피드백을 빠르게 반영할 수 있습니다.
    • 장애 대응이 빨라집니다. 릴리즈를 했는데 굉장히 크리티컬한 이슈가 발견되었을 때, 개발부터 배포까지의 과정이 복잡하면 반영에 오래걸리게 됩니다.
  • 만약, 로드밸런서로 수십대의 서버를 동시에 운용한다면?
    • 자동화를 하지않으면 직접 서버에 들어가서 일일이 실행해야하기 때문에 하루종일 배포를 할 수도 있습니다.



출처: https://minz.dev/18?category=850293 [MinJunKweon 개발 블로그]

 

 

적용


지속적 통합, 지속적 배포를 프로젝트에 적용시켜 통합과 배포를 자동화시켜보도록 하겠습니다.

 

더보기

CI 도구를 도입할 것이나 사실 정확히 CI를 하고 있지는 않습니다. 왜냐하면 CI에 대한 4가지 규칙 중 테스트 자동화에 대한 내용이 충족되지 않았기 때문입니다. 정확한 CI를 하고 싶은 경우 견고한 소프트웨어를 위한 테스트 코드를 작성해주세요.

 

마틴 파울러 CI 4가지 규칙

 

  • 모든 소스 코드가 실행되고 누구든 현재 소스에 접근할 수 있는 단일 지점을 유지할 것
  • 빌드 프로세스를 자동화해서 누구든 소스로부터 시스템을 빌드하는 단일 명령어를 사용할 수 있게 할 것
  • 테스팅 자동화를 단일 명령어로 실행해 시스템에 대한 건전한 테스트 수트를 실행할 수 있게 할 것
  • 누구나 현재 실행 파일을 얻으면 지금까지 가장 완전한 실행 파일을 얻었다는 확신을 하게 할 것

 

 

 

 

Travis Ci 설정

 

Travis는 깃허브에서 제공하는 CI 서비스입니다. public repository에 한해 무료로 제공됩니다.

 

https://travis-ci.org/  로 들어갑니다.

 

Travis CI - Test and Deploy Your Code with Confidence

 

travis-ci.org

 

 

travis는 깃허브에서 제공하는 서비스로 깃허브 아이디로 연동가능합니다. 깃 허브 아이디로 로그인 한 뒤 오른쪽 위 메뉴바에서 Settings를 클릭해 들어갑니다.

 

 

 

깃허브에 등록된 repository 들 중 travis 연동을 원하는 프로젝트를 클릭합니다.

 

 

해당 Repository를 활성화시킵니다. 다음과 같이 빌드 히스토리 페이지가 나옵니다. travis 웹 사이트에서 설정은 이것으로 끝입니다. 나머지 설정은 프로젝트에서 진행합니다.

 

 

 

프로젝트 설정

프로젝트 root 디렉토리 아래에 .travis.yml 파일을 생성합니다.(build.gradle.kts 와 같은 위치)

tavis가 시작 시 해당 파일을 읽어드립니다.

 

.travis.yml

 

다음과 같이 설정합니다.

 

  • language 
    • 저는 kotlin을 사용했으므로 koltin이라고 명시하였으나 다른 언어를 사용한 경우 해당 언어를 입력해주세요.
  • 사용한 jdk를 명시합니다.
  • branches
    •  travis CI를 수행할 github branch를 설정합니다. 저는 오직 master branch에 푸쉬될 경우에만 수행하도록 설정하였습니다.
  • cache 
    • 캐시 디렉토리를 설정합니다. 같은 의존성을 받을 경우를 방지합니다.
  • script
    • master branch에 푸쉬됐을 경우 실행하는 스크립트입니다.
  • notifications
    • 푸쉬 되었을 경우 이메일로 알림이 오도록 하는 설정입니다. recipients:에 본인의 이메일을 입력해주세요.

 

 

위와 같이 설정을 마쳤으면 master branch로 푸쉬해보세요.

 

 그 다음 travis 저장소 페이지로 이동하면 현재 상태를 알 수 있습니다.

 

 

빌드가 성공하면 우측 위에 pass로 나타납니다. 마찬가지로 이메일을 확인해보면 다음과 같이 메일이 전달되었을 것입니다.

 

 

 

 

Travis + S3 연동

앞서 Travis CI를 실행하여 jar 파일을 생성했습니다. 이 생성된 jar 파일을 배포하기 위해 AWS Code Deploy 서비스를 이용합니다. 하지만 AWS Code Deploy에는 저장 기능이 따로 없기에 S3에 jar 파일을 저장하고 이 파일을 AWS Code Deploy가 가져갈 수 있게끔 하겠습니다. 

 

 

따라서 우선 AWS에 접근 관련 설정부터 진행하겠습니다.

 

 

IAM

AWS에서 제공하는 서비스는 외부 서비스가 접근할 수가 없습니다. 만약 접근하고자 할 경우에는 접근 권한을 부여 받아야합니다. 이 때 인증과 권한 부여와 같은 기능을 하는 서비스가 바로 IAM(Identity and Access Management) 입니다.

 

 

 

AWS 콘솔에 들어가 IAM을 검색하고 들어갑니다. 해당 페이지에서 사용자 -> 사용자 추가를 클릭해주세요.

 

 

 

 

생성할 사용자 이름을 입력하고 프로그래밍 방식 액세스 유형을 선택해주세요.

 

 

 

다음으로 권한을 설정합니다. 

 

저는 기존 정책 직접 연결을 통해 AmazonS3FullAccess, AWSCodeDeployFullAccess을 연결하겠습니다.

 

 

다음으로 넘어가 태그를 설정해주세요. name : "본인 설정 이름" 으로 설정합니다.

 

 

마지막으로 검토 한번 하고 사용자를 생성해줍니다.

 

 

 

 

생성하고 나면 Access ID와 Secret 키가 나타납니다. 이 키를 통해 Travis CI를 등록하겠습니다.

 

 

 

키 등록

 

travis 페이지로 돌아가 repository 설정에서 아래로 내려가보면 다음과 같이 환경변수를 설정하는 칸이 있습니다. 해당 칸에 위에 Access ID와 Secret key를 등록합니다.

 

이제 위 등록한 변수들을 .travis.yml 에서 사용가능합니다.

 

 

S3 생성

이제 S3 서버를 만들겠습니다. S3 서버란 Simple Storage Service의 줄임말로 파일을 관리하는 서버입니다. 이 S3 서버에 Travis CI가 생성한 빌드파일이 저장되도록 하겠습니다.

 

AWS 콘솔에서 S3를 검색해 S3 페이지로 입장해주세요.

 

 

버킷 생성을 클릭해 다음과 같이 버킷 이름을 작성해주세요.

 

 

옵션은 구성할 것이 없으니 바로 권한 설정으로 넘어가 퍼블릭 액세스 차단에 체크를 해주세요. 퍼블릭을 열어둘 경우 빌드된 파일이 탈취되어 중요한 정보들이 모두 탈취될 수 있습니다. 해당 옵션을 활성화해도 IAM  사용자로 발급받은 키를 사용할 수 있어 접근 가능하니 걱정 안하셔도됩니다.

 

 

모두 완료한 다음 아래와 같이 버킷이 생성되면 S3 버킷이 성공적으로 완성되었습니다.

 

.travis.yml 변경

이제 프로젝트에서 S3 서버에 연동할 수 있도록 .travis.yml을 다음과 같이 수정합니다.

 

before_deploy

  • before_deploy
    • deploy 되기 전에 실행합니다.
  • zip -r springboot2-davinci-webservice : springboot2-davnici-webservice라는 이름으로 파일을 압축합니다.
  • mkdir -p deploy : 현재 프로세스가 실행되고 있는 지점에 deploy 파일을 생성합니다.
  • mv
    • zip 파일을 뒤에 오는 인자의 경로로 이동시킵니다.

 

deploy

  • deploy
    •  외부 서비스와 연동될 행위를 선언합니다.
  • travis 환경 변수에 입력했던 key들을 변수로 사용하여 access key를 할당합니다.
  • bucket
    • S3에 생성한 버켓 이름을 입력해줍니다.
  • skip_cleanup
    •  빌드 결과물을 삭제하지 않도록 합니다.
  • acl
    • zip 파일에 대한 접근을 설정합니다.
  • local_dir
    •  해당 위치 파일을 s3로 전송합니다.

 

 

이제 github의 master branch로 푸쉬합니다. 다음과 같이 s3 버킷에 zip 파일이 전송됩니다.

s3 bucket

 

 

 

 

CodeDeploy 연결

 

CodeDeploy이는 배포를 해주는 AWS 서비스입니다. EC2 인스턴스와 연결해야하므로 IAM 설정을 먼저 합니다.

 

IAM 콘솔로 들어가 역할 - 역할 만들기를 클릭합니다.

 

 

 

AWS 서비스의 EC2 인스턴스를 선택합니다.

 

 

 

다음으로 넘어가 아래 그림과 같이 정책을 선택합니다.

 

 

 

태그에 name도 추가합니다.

 

 

마지막으로 검토 후 역할을 생성합니다.

 

 

 

 

만든 역할을 EC2 인스턴스에게 부여합니다. 부여한 뒤 인스턴스 재부팅을 한번 실행해줍니다.

 

 

 

 

 

 

이제 EC2 인스턴스에 ssh 접속하여아래와 같이 설치를 진행해주세요.

성공시 download : ~~ 가 출력되어 나타납니다.

 

install 파일이 설치되었지만 실행 권한이 없습니다. 따라서 실행파일로 변경해주세요.

 

아래와 같은 명령어 입력후 The AWS ~~ 가 출력되면 제대로 실행되고 있는 겁니다!

 

 

 

이제 다시 AWS 콘솔로 돌아가 CodeDeploy 를 검색해 해당 페이지로 들어가세요. 그 다음 애플리케이션 - 애플리케이션 생성 버튼을 클릭해 애플리케이션을 생성하도록 합니다.

 

 

 

아래와 같이 이름을 지어주고 컴퓨팅 플랫폼을 EC2/온프레미스로 설정해주세요.

 

 

 

생성한 뒤 페이지 하단에 배포 그룹 생성을 눌러주세요.

 

 

 

아까 만든 역할을 부여하고 현재 위치 배포 유형을 선택해주세요. EC2 인스턴스가 하나밖에 없으므로 괜찮습니다. 만약 두 개 이상이라면 블루/그린을 선택해주세요.

 

 

 

 

환경 구성에서는 EC2 인스턴스를 선택하고 등록한 태그를 입력해주세요.

 

 

마지막으로 배포 설정을 아래와 같이 설정하면 끝입니다! 서버가 1대이니 전체 배포 옵션을 선택합니다.

 

 

 

Travis Ci, S3, CodeDeploy 연동

 

앞서 CodeDeploy와 EC2 인스턴스를 연결했으니 이제는 Travis, S3, CodeDeploy를 연결하면 됩니다.

우선  EC2 서버에 접속해서 빌드된 Zip 파일을 저장할 디렉토리를 생성해주세요.

 

이제 프로젝트 파일로 돌아와 appspec.yml을 .travis.yml과 같은 위치에 생성해주세요. appspec.yml은 codeDeploy 설정 파일입니다.

 

아래와 같이 입력해주세요.

  • version
    • CodeDeploy 버전입니다.
  • files
    • - source: /  전체 파일 선택을 의미합니다.
    • destination:파일이 저장될 위치입니다.
    • overwrite: 파일이 이미 존재할 경우 덮어씁니다.

 

 

 

아래 설정을 .travis.yml에 추가해주세요. S3에서 jar 파일을 가져와 배포할 배포 그룹과 애플리케이션을 선택해 Codeploy에 배포 요청을 합니다.





성공적으로 배포 성공했을 경우 codedeploy 페이지에 아래와 같이 나타납니다.




JAR 배포

빌드 파일을 만들고 EC2 서버로 배포까지 했으니 이제 새로 빌드된 파일을 실행시키도록 스크립트를 변경해줍니다.

프로젝트로 들어가 scripts/deploy.sh를 아래와 같이 생성해줍니다.

 

 

생성한 뒤 .travis.yml을 아래와 같이 변경해줍니다. (배포 시 실행 파일 외 파일은 필요없지만 travis는 파일 하나만 s3로 전송하지 못합니다. 단지 디렉토리 단위로 전송할 뿐입니다. 따라서 필요한 파일만 따로 뽑아내 압축한 다음 s3로 전송해줍니다.)

 

 

마지막으로 appspec.yml을 변경해줍니다. ec2 서버로 넘겨준 파일을 ec2-user 권한을 가지도록 설정해줍니다.

그리고 배포시 ec2-user의 권한으로 deploy.sh를 실행하도록 합니다.

 

 

 

 

이 후 master branch에 push하거나 PR을 보내면 빌드와 배포가 자동으로 이뤄지고 아래와 같이 빌드, 배포가 자동적으로 이루워진 것을 확인할 수 있습니다.

 

 

Travis 홈페이지

travis

 

AWS codeDeploy 배포

codedeploy

 

외부에서 접근

외부 접근

 

 

 

 

 

 

 

 

 

reference


 


출처: https://minz.dev/18?category=850293 [MinJunKweon 개발 블로그]

 

[CI/CD] 개발부터 배포까지 자동화 - 01 개요

계기 이번에 정부에서 공적마스크 5부제를 시행하면서 판매처(약국, 우체국, 농협 하나로마트)의 재고현황을 알 수 있는 공공 API가 생겼습니다. 예상대로 공공 API를 활용해 재고현황을 알려주는

minz.dev

https://wotjd.github.io/2019/06/blogging-hugo-%EB%A1%9C-github-%EB%B8%94%EB%A1%9C%EA%B7%B8-%EC%8B%9C%EC%9E%91%ED%95%98%EA%B8%B0-5.-travis-ci-%EC%97%B0%EB%8F%99/

 

[Blogging] Hugo 로 github 블로그 시작하기 - 5. Travis CI 연동

Hosting Blog via Github Pages with Hugo on Mac, 맥에서 Hugo로 Github Pages에 블로그 호스팅하기 Git에 대한 충분한 지식이 있다는 전제하에 적은 문서이다. Travis CI 연동 Travis CI는 지속적 통합(Continuous Integration,

wotjd.github.io

스프링 부트와 AWS로 혼자 구현하는 웹 서비스

 

 



'배포' 카테고리의 다른 글

EC2에 배포하기  (0) 2020.09.01
AWS RDS 사용하기  (0) 2020.08.28
AWS 사용하기  (0) 2020.08.26
클라우드 서비스  (0) 2020.08.20
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
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
글 보관함