구축 환경
CI: GitHub, Jenkins
CD: Codedeploy
Language: Go
CI/CD 흐름
1. 개발자가 Git Push를 하게 되면 GitHub에서 Jenkins 서버로 webhook을 발생시킵니다
2. Jenkins가 Push 이벤트가 발생했음을 인지합니다
3. Jenkins가 빌드 및 테스트를 실행합니다
4. build가 성공적으로 마무리되면 애플리케이션 파일과 appspec.yml 파일을 zip으로 압축하여 S3에 업로드합니다
5. Jenkins가 CodeDeploy에게 배포를 요청합니다
6. CodeDeploy는 appspec.yml에 따라서 배포를 수행하며, 배포할 서버내에서 쉘 스크립트를 수행합니다.
구축 순서
1. github repository에 스크립트 파일을 올립니다
2. Codedeploy의 개정(revision) 저장소로써 S3 bucket 생성합니다
3. Jenkins 서버와 어플리케이션이 배포 될 EC2를 구축합니다
4. Codedeploy 구축합니다
5. Jenkins 프로젝트 설정합니다
6. github WebHook 설정합니다
1. github repository
저는 위의 해당하는 스크립트 파일을 깃허브에 올렸습니다
CodeDeploy를 위한 appspec.yml 파일은 root 위치에 생성해야 합니다
어플리케이션 언어로는 go언어를 선택했습니다
appspce.yml 파일은 공식문서를 보면서 작성하시면 됩니다
https://docs.aws.amazon.com/codedeploy/latest/userguide/reference-appspec-file.html#appspec-reference-server
https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/reference-appspec-file-structure-hooks.html#appspec-hooks-server
2. S3 bucket 생성
통합 및 빌드된 app과 appspec.yml, shellscript 들이 함께 번들링된 파일이 업로드될 S3 버킷을 생성해야합니다.
* 공식 문서
CodeDeploy 에서 개정은 CodeDeploy가 인스턴스에 배포할 소스 파일의 버전을 포함하거나 CodeDeploy가 인스턴스에서 실행될 스크립트를 포함합니다.
https://docs.aws.amazon.com/ko_kr/codedeploy/latest/userguide/application-revisions.html
3. Jenkins 서버와 어플리케이션이 배포 될 EC2 구축
3-1. Jenkins 서버 구축
- CI를 위한 Jenkins Server를 구축하겠습니다.
docker 설치(ubuntu)
https://docs.docker.com/engine/install/ubuntu/
Jenkins 설치
$ docker run -itd --name jenkins -p 8080:8080 -p 50000:50000 -v /docker/jenkins:/var/jenkins_home -v /var/run/docker.sock:/var/run/docker.sock -e TZ=Asia/Seoul -u root jenkins/jenkins:latest
옵션 설명
-v /var/run/docker.sock:/var/run/docker.sock
docker in docker를 구현하기 위해 사용하는 옵션
URL에 Jenkins가 동작중인 Server의 IP:8080를 입력합니다.
컨테이너에 들어가서 password의 경로를 들어가도 되지만,
docker container logs {CONTAINER_NAME} 을 입력하면 관리자 비밀번호가 나옵니다
비밀번호를 복사하여 브라우저에 붙여넣기해서 install suggested plugins을 진행합니다.
CodeDeploy plugin, GO plugin 설치
jenkins관리 > 플러그인 관리
저는 이렇게 두개의 플러그인을 설치했습니다
Go 설정
Jenkins 관리 > Global Tool Confiuration 선택
적당한 이름을 입력하고 설치할 버전을 선택합니다.
3-2. APP Server 구축
- EC2 두개를 서로 다른 가용영역에 생성하고 Application LoadBalancer를 연결하겠습니다
IAM Role 생성
신뢰할 수 있는 유형의 개체 선택 AWS 서비스 > EC2 선택
정책은 위의 두개를 넣어주세요
EC2 생성
저는 ubuntu 18.04를 선택했습니다
인스턴스 세부 정보 구성에서 IAM 역할에 위에서 생성한 역할을 넣어주세요
#!/bin/bash
# golang 설치
sudo apt install golang-go -y
# codedeploy agent 설치
sudo apt update
sudo apt install ruby-full -y
sudo apt install wget -y
wget https://aws-codedeploy-ap-northeast-2.s3.ap-northeast-2.amazonaws.com/latest/install
sudo chmod +x ./install
sudo ./install auto
사용자 데이터에 GO언어와 CodeDeploy Agent 설치하는 명령어를 넣습니다
태그에 가서 CodeDeploy 구성에서 알아볼 수 있도록 이름태그를 달아야 합니다
나머지 EC2 한개는 다른 가용영역에 생성하고 이름태그는 cicd-2로 넣겠습니다
그리고 ALB를 연결해 주세요
4. CodeDeploy 구축
IAM Role 생성
신뢰할 수 있는 유형의 개체 선택 AWS 서비스 > CodeDeploy 선택하여 역할을 생성합니다.
배포 구성 생성
배포 구성은 배포 과정에서 성공 실패 여부를 결정하는 규칙 셋을 의미합니다.
배포 과정에서 최소 1개의 인스턴스가 서비스 가능한 상태를 유지하도록 숫자를 선택하고 값은 1로 설정하겠습니다.
어플리케이션 생성
배포 그룹 생성
애플리케이션을 생성했으면 배포 그룹을 생성해야 합니다
위에서 만든 역할을 넣어줍니다.
현재 위치 배포를 통해서 무중단 배포를 하겠습니다.
https://devlog-wjdrbs96.tistory.com/304?category=885022
배포가 실행 될 앞에서 생성한 APP Server 두개를 선택합니다
앞에서 만든 배포 구성을 선택하고, ALB를 선택합니다.
5. Jenkins 프로젝트 설정
새로운 Item > Freestyle project 선택
소스 코드 관리에서 Git 선택하고 코드들이 저장되어 있는 레포지터리 url 입력합니다
빌드 유발에서 GitHub hook trigger for GITScm polling을 선택합니다
빌드 환경에서 위에서 설정한 Go 버전을 선택합니다
저는 Build 에서 Excute shell 을 선택하여 명령줄을 넣었습니다.
(기존에 존재하는 파일은 deploy과정에서 install전에 삭제하도록 했으니 여기에서는 넣지 않았습니다.)
빌드 후 조치 추가에서 CodeDeploy를 선택합니다
위에서 생성해 놓은 CodeDeploy 정보들을 넣습니다.
또한 미리 생성해 놓은 S3 Bucket 정보를 넣고 저는 jenkins 폴더를 만들어 그곳에 번들링한 파일을 저장하겠습니다.
Include Files는 번들링하여 S3에 저장 될 차일을 선택하는 란입니다. 저는 go application인 app파일, appspec.yml, sh파일들이 저장된 codedeploy 디렉터리를 넣었습니다.
저는 admin계정이 있어서 해당 access키와 secret키를 넣겠습니다
** 참고 : 소스코드는 /var/jenkins_home/workspace/${PROJECT_NAME} 위치에 저장됩니다.
6. GitHub WebHook 추가
- github에 개발자가 코드를 push하면, Jenkins에게 hook을 하는 기능입니다.
Github Repository > Settings > Webhooks > Add webhook을 선택합니다.
Jenkins가 동작중인 Server의 IP:8080/github-webhook/ 을 입력하고, Content type은 application/json으로 변경합니다.
테스트
github에 commit 하고 push 해보겠습니다.
Jenkins에서 build 가 성공했습니다.
S3에 파일이 업로드 되었습니다.
CodeDeploy > 배포에서 해당 배포가 성공이 된 것을 확인할 수 있습니다.
로드발란서의 주소/ping 를 입력하면 정상적으로 pong이 나옵니다
수고하셨습니다~~
참고
https://plugins.jenkins.io/golang/
https://galid1.tistory.com/747
'DevOps > CICD' 카테고리의 다른 글
GitOps, ArgoCD Overview (0) | 2023.10.11 |
---|---|
Argocd를 사용하여 helm chart 배포 및 주의사항 (1) | 2022.04.25 |
argoCD App of Apps 패턴을 사용한 서비스 배포 (7) | 2022.03.11 |
Github, Jenkins, argoCD를 사용하여 CI/CD 구축 (0) | 2022.01.24 |
Jenkins Pipeline Github Private Token 사용하여 연동 (0) | 2022.01.03 |