Docker 기반 CI·CD 파이프라인 구축

CI/CD - GitLab으로 AWS Cloud로의 지속적인 배포 (CD) - (4) / ECS로 Docker Application 배포 (Automation by GitLab - AWS CLI) /

wy-family 2024. 12. 8. 23:31

GitLab-runner 가 배포를 하게 될 것이다.

Gitlab-runner가 배포하는 방식은 gitlab-runner에서 aws 명령어를 실행하게 될 것이다.

aws cli, 설치를 안 했으면 하면 된다.

aws cli 명령 중에서는 ecs를 컨트롤할 수 있는 명령을 제공한다.

ecs의 cluster를 만들거나 service를 새로 실행(running)하거나 하는 등의 작업을 수행할 수 있다.

ECR에 새로운 어플리케이션이 올라가있는데, 거기에 코드 내용을 수정하고 새로운 버전의 docker image를 올리고

그리고 service를 새로 실행(running)하게 될 것이다.

service를 새로 실행하게 되면은 새로 만들어진 docker image를 가지고 와서 service가 올라오게 될 것이다.

이 과정을 테스트 해볼 것이다.

그럴려면, gitlab-runner가 aws cli를 통해서 ecs를 컨트롤해야 하는데 그러기 위해서는 ecs를 제어하기 위한 리소스에 대한 권한을 가지고 있어야 한다.

권한 설정은 IAM에서 한다고 했었다.

IAM에서 새로운 user를 만든적이 있었다. 

 

aws cli를 사용하기 위해서 ecr-user를 만들었었다.

 

이 ecr-user의 권한을 보면은, 권한을 Admin으로 했었다. 모든 권한을 가지는 superuser.

 

그러니까 지금 상태에서도 ecs를 컨트롤 할 수 있어야 한다.

ecs의 cluster 정보를 가지고 와보자.

 

뭔가를 잘못입력했더니 이렇게 명령어 입력 방법을 알려주고 있다.

 

심지어 어디가 잘못되었고 올바르게 하는 방법까지 알려주고 있다.

다시 해보자. s 를 빼먹었었네.

 

정보를 가지고 오고 있다. 최소한 읽기 권한은 있다는 것.

 

자세히 읽어보면, 제대로 정보를 가지고 오고 있다는 걸 확인할 수 있다.

 

이제 ECS 서비스를 새로 시작하는 aws ecs 명령을 실행해보자.

aws ecs update-service \             #  업데이트 서비스를 하라. 어떤 걸?
--cluster test-app-cluster \             #  test-app-cluster 라는 이름의 cluster
--service sparta-app-srv \             #  sparta-app-srv 라는 이름의 service
--task-definition test-app:1 \             # test-app이라는 이름의 task-definition
--force-new-deployment             #  지금 즉시 재배포하라 라는 명령.

 

명령을 실행하고 나면은 잘 진행이 될 것인데, 터미널에서 확인하기 보다는 

웹 콘솔 (aws console)에서 확인을 해보자.

 

 

''

잘 보면, tasks 에서, 과거의 2개는 사라지고 새로운 2개가 공간을 차지하게 된다.

그런데, 그렇게 차지하게 될때, 과거의 2개가 바로 사라져서 잠깐 아무것도 없는 상태가 되는게 아니라,

과거의 2개와 새로운 2개가 공존하다가, 새로운 2개가 정상적으로 작동하게 되면, 그때 과거의 2개가 사라지는 방식이다.

(스크린샷을 못 찍었지만, task의 갯수가 4개가 되었던 순간이 있었다. 하지만 그건 금방 지나갔다.)

롤링 업데이트(Rolling Update):

  • 당신의 설명과 가까운 방식
    기존의 작업(Task)을 점진적으로 새로운 작업으로 교체합니다.
    새로운 작업이 성공적으로 배포되고 안정적으로 작동한다고 확인되면, 그때 기존 작업이 종료됩니다.
    • 점진적인 전환: 한 번에 일부 작업만 교체됩니다. 따라서 새로운 작업과 기존 작업이 일정 시간 동안 공존합니다.
    • 무중단 배포: 서비스는 계속 실행되며, 트래픽은 기존 작업과 새로운 작업 사이에서 분배됩니다.
    • 자원 효율성: 블루-그린 배포와 달리 완전히 별도의 환경을 준비할 필요가 없습니다.
    시나리오 예시:
    • 기존 작업(Task 1, Task 2)이 실행 중.
    • 새로운 작업(Task 3, Task 4)을 추가로 배포.
    • Task 3, 4가 정상적으로 작동하는지 확인.
    • 이후 Task 1, 2를 제거.
    → 당신이 설명한 "기존의 2개와 새로운 2개가 공존하다가, 새로운 2개가 정상적으로 작동하면 기존 2개가 제거되는 방식"은 롤링 업데이트의 전형적인 동작입니다.
  • 특징:

블루-그린 배포(Blue-Green Deployment):

  • 새로운 버전을 완전히 분리된 환경에서 준비합니다.
    예를 들어, 현재의 Blue 환경과 별도로 Green 환경을 만들어 새로운 버전을 배포한 후, 트래픽 전체를 한 번에 Green 환경으로 전환합니다.
    • 완전한 분리: 두 환경이 동시에 존재하지만, 하나의 환경만 트래픽을 처리합니다.
    • 한 번에 전환: 트래픽이 Blue에서 Green으로 전환되는 순간 기존 Blue 환경은 더 이상 사용되지 않습니다.
    • 더 많은 자원 필요: 완전히 독립된 환경을 유지해야 하므로 자원이 더 많이 필요합니다.
    시나리오 예시:
    • Blue 환경(Task 1, Task 2)이 실행 중.
    • Green 환경(Task 3, Task 4)을 준비하고 테스트.
    • 트래픽을 한 번에 Green으로 전환.
    • Blue 환경(Task 1, Task 2)을 제거.
  • 특징:

정리:

  • 롤링 업데이트: 기존과 새로운 작업이 공존하며, 점진적으로 전환. (당신의 설명과 가장 가까움)
  • 블루-그린 배포: 완전히 분리된 두 환경에서 한 번에 전환.

당신의 설명은 롤링 업데이트를 더 정확히 묘사하고 있으며, 이를 통해 "무중단 배포"가 가능하다는 것을 잘 표현한 것으로 보입니다.


ECS 서비스를 새로 시작하는 aws ecs 명령을 실행했으니,

이제 CI/CD pipeline에 적용을 해보겠다.

test-app 에서 Makefile 에서 하나의 rule, 규칙을 추가할 것이다.

deply (make deploy를 하기 위한) 를 추가해줘야 한다.

(사실 나는 원래 작성되어 있었던 상황이긴 하다)

(GitLab - pipeline editor에서 make deploy를 빼놓았었던 것일뿐.)

 

그래도, Makefile에 deploy 라는 규칙을 추가했다고 해보자.

그러면 이 코드를 업데이트를 해줘야 한다.

먼저, git pull 을 해서 변경된 것들이 있는지 확인해서 받아오자.

그리고 나서 git add .

git commit -m "Update deploy rule" 

이라고 하자.

그리고 나서 git push (나는 수정한 게 없으니 커밋할 것도 없고 푸쉬했더니 넌 이미 모두 최신버전이야 라는 메시지가 나온다)

 

그러니까 그냥, 띄어쓰기 하나라도 수정해서 GitLab에 commit 표시가 되도록 해보자.

 

GitLab에서 보면, Makefile이 commit-push 된 걸 확인할 수 있고, 새로운 업데이트가 있었으니 그게 트리거가 되어서 pipeline이 작동하는 것도 확인가능하다.

pipeline editor에 이제 추가를 해주고 commit changes 를 해주면 된다.

 

deploy 까지 잘 작동해서, ecr cluster service 까지 작동하고 있다는 걸 확인했다.

그리고 아까 봤던 task 의 이름과 새롭게 만들어진 task 의 이름을 확인해보면, 바뀌었다는 걸 확인할 수 있다.

 

Deactivating 되고 있는 걸 포착!

 

 

새로운 task 2개로 업데이트 된 걸 확인할 수 있다.

 

자, 이제 마지막으로 할 것은, 실제 코드를 수정하고 수정한 코드가 반영되는지만 확인해보면 된다.

ec2, load balancer에서 dns name 으로 복사를 한 뒤에 웹 주소창에 붙여넣기 해서 명령을 내려보면,

현재 어떤 메세지가 나오는지 확인할 수 있다.

그래서 저기 메세지에 해당하는 부분을 수정해보고, 자동으로 적용이 되는지 테스트를 해보자.

((코드 수정을 하기 전에, git pull 을 해서 최신 버전을 다 다운로드를 해주자.))

 

app.py 에서 코드 수정을 해주자.

수정을 해주고 나서 git status 를 해주면, 뭔가 수정했는지를 알려준다.

그러니까, git add . /git commit -m "commit message" / git push 를 해줘야 한다.

push가 완료되고 나면,

gitlab에서는 pipeline이 작동을 할 것이다.

build, test, deploy 까지 모두 실행되고 나면,

ecs - cluster - service 에서 확인을 해보면 롤링 업데이트가 될 것이다.

service를 들어가서 배포가 이루어지고 있는 걸 확인할 수 있다.

 

배포가 다 끝났으면, ec2 - loadbalancer - DNS name을 복사했던 걸 다시 붙여넣기해서 테스트를 해보자.

코드 변경이 완료되서 새로운 버전의 어플리케이션이 올라온 걸 확인할 수 있다.

이렇게 해서 CICD pipeline 개발환경의 기본적인 구성은 다 끝이 났다.

개발자가 코딩을 하게 된다.

코딩을 해서 코드를 push 하게 되면 gitlab 에 들어가게 된다. 저장소에 들어가게 된다.

그러면 코드 변경 사항이 발생하게 된다.

gitlab runner는 코드 변경 사항을 확인하고, 저장소에서 변경된 가장 최근의 코드를 읽어오게 된다.

그리고 pipeline을 시작한다.

- 여기서의 pipeline은 build를 가장 먼저 시작했다. make build 스크립트를 실행해서 docker image를 ecr에 push 한다.

- 그 다음에 test를 시작한다. make test 스크립트를 실행한다. (여기서는 echo 만 실행된거라 실질적인 test는 없었다.)

- 마지막으로 deploy를 진행한다. 여기서는 aws cli를 이용해서 ECS에 새로 실행하라는 명령을 내리게 되고 ECS는 ecr에 있는 docker image를 가지고 와서 새로 service 를 실행하는 걸로 전체 프로세스가 마무리 되었다.

GitLab을 이용해서 이 전체 과정을 자동화했다. 이렇게 해서 CI, CD 두 개의 과정을 마무리했다.