
📌 CI/CD
`CI`(Continuous Integration)란 개발자가 변경한 코드를 자주 통합하고, 전체 시스템과 잘 어우러지도록 자동으로 테스트하는 프로세스이다. 코드 변경시마다 빌드 및 테스트를 수행하여 문제를 조기 발견할 수 있다!
`CD` (Continuous Delivery)란 자동으로 배포하는 프로세스를 포함한다. 코드 변경이 통합되고 테스트 되면, 이를 자동으로 스테이징, 프로덕션 환경에 배포한다.
💡 CI/CD의 장점
- 빠른 피드백
- 자동화된 프로세스
- 일관된 배포
- 높은 품질 유지
- 개발 속도 향상
📌 CI/CD 도구
- GitHub Actions
- GitHub 저장소에 통합되어 있는 CI/CD 도구로, YAML 파일을 사용하여 워크플로우 정의
- 무료 사용 가능 (제한된 런타임)
- Jenkins
- 오픈 소스 CI/CD 도구
- 높은 커스터마이징
- 다양한 플러그인
- GitLab CI
- GitLab과 통합된 CI/CD 도구로, GitLab 저장소를 기반으로 CI/CD 파이프라인 설정
- 강력한 파이프라인 편집기 제공
📌 Amazon ECS
`Amazon ECS` (Elastic Container Service) 는 `Docker` 어플리케이션을 쉽게 배포하고 운영할 수 있도록 지원하는 완전관리형 서비스이다. `Kubernetes`와 같은 서비스이고 보다 사용하기 쉽고, 비용적으로도 저렴하다.
또한 `Serverless`로 구성할 수 있어 인스턴스를 구성하고 관리할 필요가 없다.
💡 AWS ECS의 구조
`ECS`는 크게 `ECR` `ECS Cluster` `ECS Service` `ECS Task`로 이루어진다.
- `ECR`: Docker image 저장소
- `ECS Cluster`: 컨테이너를 실행하기 위한 Cluster로 여러 인스턴스로 구성, 인스턴스에 Docker Container가 분산 실행됨, `Serverless`의 경우 인스턴스도 필요없음
- `ECS Server`: Docker 어플리케이션의 실행 그룹
- `ECS Task`: `ECS Server`에 실제 실행되는 Docker Container들 (Docker 어플리케이션)
Service는 Task가 두 개 이상 모인것
📌 실습
`GitLab`을 이용해서 CI/CD 환경을 구축하고 CI 과정을 자동화 한다.

- GitLab 프로젝트에 개발한 어플리케이션 코드를 올린다.
- GitLab은 코드를 확인하고 Docker Image를 생성하여 ECR에 등록한다.
- 해당 Docker Image로부터 Docker Container를 ECS에 실행한다.
먼저 GitLab 사이트에 가입하고 Group을 생성한 뒤 프로젝트를 생성한다.

그 뒤 우리가 만든 스프링 프로젝트를 GitLab과 연동한다.

Clone with HTTPS 주소를 복사하여 스프링 프로젝트의 원격 저장소에 붙여 넣어 연동한다.
그 뒤 프로젝트를 PULL 받는다!
FROM openjdk:17-jdk-slim
VOLUME /tmp
ARG JAR_FILE=build/libs/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
프로젝트 루트에 Docker Image 생성을 위한 `DockerFile`도 생성했다.
그 다음엔 외부에서 컨테이너에 접속할 수 있도록 포트를 열어 AWS 보안 그룹을 추가한다.

인바운드 규칙 편집에서 8080 포트와 80 포트를 추가하였다.
이제 AWS에 접속하여 Elastic Container Registry로 들어간다.
배포하기 위해서는 일단 ECR에 이미지를 등록해야 한다.

리포지토리 생성을 누르고 리포지토리 이름에 우리가 이전에 만들었던 GitLab 프로젝트 이름을 입력한다.

예시!!
그리고 리포지토리 생성을 누른다.

생성 후에 푸시 명령 보기를 누르면 `GitLab CI/CD`에서 사용될 명령어들을 볼 수 있다.
AWS ECS 대시보드에 접속하여 클러스터 생성을 클릭한다.
이름만 설정 후에 인프라는 서버리스로 선택 후 생성한다.
`ECS`는 Docker 컨테이너를 쉽게 실행, 정지, 관리할 수 있게 도와준다.


그 뒤 태스크 정의에 들어가 새 태스크 정의 생성을 누른다!

이미지 URI는 이전에 생성한 ECR의 리포지토리 URL을 입력하고 포트를 8080으로 수정한다.
그리고 생성을 누른다.
마지막으로 서비스 생성이다!
이전에 생성하였던 클러스터로 들어가서 서비스 쪽에 생성을 누른다.


배포 구성에서 우리가 이전에 만든 task를 선택하고 서비스 이름을 지정해준다.

그리고 네트워킹에서는 이전에 우리가 생성한 보안 그룹을 선택하고

로드밸런싱은 어플리케이션 로드 밸런싱을 선택하고 이름을 입력한다.
포트는 그대로 80으로 두면 된다!!

이렇게 서비스를 생성하면 생성은 성공하고
우리가 아직 도커 이미지로 컨테이너 빌드(?)를 안 했기 때문에 배포는 실패할것이다.
(ContainerPull 어쩌구 오류가 난다.)
난 여기서 뭔가 잘못된 줄 알고 3번이나 재시도를 했었는데..
원래 안되는 게 정상이었다!!!!!!!!!!!!!!!!!! 다들.. 시간 낭비 하지 마시길..
이제 `AWS IAM`에 접속하여 사용자 생성 클릭 후
직접 정책 연결을 클릭하고 AdministratorAccess 권한을 부여하여 사용자를 생성한다.
생성한 사용자 상세페이지에 접속하여 액세스 키 만들기를 클릭한다.

기타를 클릭 후 .csv 파일을 다운로드하여 잘 간직한다..... 나중에 쓸 것이다!
다시 깃랩에 접속하여 이전에 만든 Project의 Settings > CI/CD > Variables를 클릭하고
2개의 변수를 추가한다.
`AWS_ACCESS_KEY_ID`
`AWS_SECRET_ACCESS_KEY`
이 두 키의 값은 아까 AWS IAM 에서 다운받은 csv 에 있다! 복사하여 붙여넣어준다.
프로젝트 루트 폴더에 `.gitlab-ci.yml` 파일을 생성한다.
스크립트는 아까 ECR에서 언급한 푸시 명령 보기를 참고하여 작성한다.
deploy 안에 있는 항목들은 우리가 생성한 ECS의 항목들 이름으로 설정한다.
services:
- docker:stable-dind
stages:
- build jar
- build and push docker image
- deploy
variables:
APPLICATION_NAME: "01"
TAG_NAME: "latest"
DOCKER_IMAGE: "group-18934028/project-01"
build:
image: openjdk:17-jdk-slim
stage: build jar
script:
- chmod +x gradlew
- ./gradlew clean build
artifacts:
paths:
- build/libs/*.jar
docker build:
image: docker:latest
stage: build and push docker image
rules:
- if: $CI_COMMIT_BRANCH == "main" || $CI_COMMIT_REF_NAME == "main"
variables:
TAG_NAME: "latest"
- if: $CI_COMMIT_BRANCH == "develop" || $CI_COMMIT_REF_NAME == "develop"
variables:
TAG_NAME: "develop"
script:
- apk add --update --no-cache curl py3-pip py3-virtualenv
- python3 -m venv /tmp/venv
- source /tmp/venv/bin/activate
- pip install awscli
- aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws configure set region ap-northeast-2
- docker build -t $DOCKER_IMAGE .
- docker tag $DOCKER_IMAGE:latest 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com/$DOCKER_IMAGE:$TAG_NAME
- aws ecr get-login-password --region ap-northeast-2 | docker login --username AWS --password-stdin 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com
- docker push 730335597998.dkr.ecr.ap-northeast-2.amazonaws.com/$DOCKER_IMAGE:$TAG_NAME
deploy:
image: python:3.9-slim
stage: deploy
script:
- python3 -m venv /tmp/venv
- source /tmp/venv/bin/activate
- pip install awscli
- aws configure set aws_access_key_id $AWS_ACCESS_KEY_ID
- aws configure set aws_secret_access_key $AWS_SECRET_ACCESS_KEY
- aws configure set region ap-northeast-2
- aws ecs update-service --cluster project-cluster --service project-01-service --task-definition project-01-task:1 --force-new-deployment
IDE에서 프로젝트를 커밋, 푸시하여 반영한다.

GitLab 프로젝트의 `Build` > `Pipelines` 을 보면 우리가 Push 한 코드들을 가지고 빌드를 하고 있다!
스테이지가 모두 성공하지 않으면 실패한 스테이지를 클릭하여 오류 내용을 확인한다.
난 처음에 `no basic auth credentials` 오류가 났었는데 script 부분 aws ecr get 명령어를 잘못 입력해서 그랬다.....
제대로 따라하자고!!!!!!!!!!!!!
이제 접속해볼것이다!
ECS 대시보드에서 클러스터를 클릭하고 상세 페이지 접속 후 로드 밸런서 보기 버튼을 클릭한다.

로드 밸런서 페이지의 DNS 이름을 복사하여 주소에 입력하고 프로젝트의 엔드 포인트에 접속해본다!!
접속이 잘 될 것이당 ㅎ.ㅎ
프로젝트 내용을 수정 후 자동으로 적용 및 배포가 다시 되는지도 확인한다.
잘 된다~~~~
실습을 따라하면서 오류가 엄청나게!!!!!!!!!! 많이 났었는데..
역시 제대로 따라하면 되긴 한다..!!!!
다음엔 GitHub Action 으로도 해봐야지
'공부 > DevOps' 카테고리의 다른 글
| [Docker] Docker란? Docker와 Docker Compose 알아보기 (실습) (0) | 2024.08.08 |
|---|