Final Project 시작

DevOps부트캠프의 파이널 프로젝트가 시작됐다.

프로젝트의 첫단계인 시나리오 선정과 요구사항 분석, 설계에 대해서 정리했다.

 

시나리오 선정 및 요구사항

팀원들과 의논하는 과정을 거쳐서 우리는 작업 관리 시스템 시나리오를 선택했다. 

시나리오 분석

DDD 설계 

 

 엔지니어님의 조언과 요구사항을 참고해 도메인 이벤트를 붙이고 이후에 액터, 커멘드 포스트잇을 붙여서 프로젝트를 구현할 때 어떤 부분에 대해서 미리 팀원들간의 토의를 해야하는지 파악하고 기록해뒀다. 
 외부시스템은 사용하지 않을 것이기에 제외했고, 에그리거트와 정책으로 도메인들을 분리하고 연결했다.

 

그렇게 사용자의 인증을 담당하는 User Management, 작업을 관리하는 Task Management Service, 그리고 작업과 시스템의 변동사항을 기록하고 변동사항에 알맞는 알림을 보내주는 Log Mornitoring System으로 분리했다.

 

ERD 설계

각 분리된 서비스 별로 사용할 데이터베이스의 기술 스택을 정했다.

 Log Mornitoring System와 User Management 파트에서는 차후 유연성 및 분산환경에서 확장성, 내결함성을 더 잘 지원할 수 있는 NoSQL을 사용하고,

 사용자로부터 가장 많은 요청을 처리해야하는 Task Management Service 파트에서는 MySQL을 사용하기로 결정했다.

 

 ERD를 작성하면서 Task에 반영되는 User 역할을 어떻게 구분할 것인가에 대한 논의를 한 결과 Task에서 Supervisor_email과 PIC_email 속성을 만들어 User table을 참조하도록 만들기로 했다.

 그리고 우린 백엔드 프로젝트를 진행하는 것이 아니기 때문에 Users 테이블에는 인증을 위한 최소한의 데이터만 사용도록 했다.

 

기술 스택

CRUD 문서 작성

 엔지니어께 CRUD 문서를 작성해 실제 구현단계에서의 실수를 방지하는 것이 좋다는 조언을 듣고, 구현할 api의 CRUD 문서를 작성했다. 문서를 팀원들과 정리하며 정말 필요한 기능이 무엇인지 생각해볼 수 있었고, 정말 필요한 기능들이 무엇인지 파악해 CRUD문서를 작성했다. 


요구사항 분석, 설계를 진행하며..

2023.04.05 - [DevOps] - [DevOps] 부트캠프 1차 팀프로젝트 회고

 이전 1차 팀프로젝트를 진행하면서 깨달은 초반 프로젝트 방향성을 확실하게 정리해야한다는 점을 마음에 세기고 도메인 주도 설계, 시나리오 분석을 하는 과정에서 팀원들과 최대한 많은 논의를 거쳐 프로젝트의 구조를 구체화 시키고 그 내용을 팀원들과 나누려고 노력했다.

 그 결과 GitHub에서는 최대한 코드 충돌을 줄이기 위해서 추후 CI/CD를 해야할 부분별로 브랜치를 나눠 Task, Auth, Front, Log 4개 Branch로 나눠 개발을 진행한 후 브랜치를 병합할 때 코드리뷰를 진행해 혹시모를 불상사를 예방하기로 했다.

 그 뒤에 1차적인 코드구현이 끝나고 클라우드 리소스에서 구상한 서비스가 작동하고있는 상태가 되면, 기존 브랜치들을 통합한 뒤에 실제 서비스 제공의 목적을 가진 production 브랜치와 개발되고있는 서비스의 코드가 올라가는 dev브랜치로 분리하기로 했다.

모니터링의 목표

CI/CD 파이프라인 마지막 Stage는 운영이다. 서비스에 생길 수 있는 현황을 파악하고 문제를 모니터링하는 과정으로 대표된다. 그렇다면 어떤 지표를 수집하고, 어떤 메트릭을 기준으로 삼아야 하지?

메트릭?

메트릭은 시간에 따라 측정한 결과값이다. 

예를 들어서 시간당 CPU 사용률, 연간 순매출처럼 시간이라는 차원이 함께 적용되어야 한다. 시간이 아닌 다른 차원(예를 들어, 서비스 별 매출)을 기준으로 삼을 수도 있다.

모니터링의 목표

모니터링을 통해 얻고자 하는 것은 다음과 같다.

  • 시간을 기준으로 측정되는 주요 메트릭을 최소화하여 고가용성 달성
  • 사용량을 추적하여, 배포에 앞서 세운 가설을 검증하고 개선

주요 벤더들이 이야기하는 모니터링의 목표와 메트릭

구글이 이야기하는 모니터링의 목표는 다음과 같다.

  • 장기적인 트렌드 분석
    • 데이터베이스가 얼마만큼의 용량을 차지하며, 얼마나 빨리 용량이 증가하는가?
    • DAU(일간 활성 사용자수)는 얼마나 빨리 증가하는가?
  • 시간의 경과 및 실험 그룹 간의 비교
    • 어떤 데이터베이스를 썼을 때 쿼리가 빠른가?
    • 캐시용 노드를 추가했을 때, 캐시 적중률(hit rate)이 얼마나 향상되는가?
    • 지난주보다 사이트가 얼마나 느려졌는가?
  • 경고
    • 인프라의 어떤 부분이 고장 났는가? 혹은 고장 날 수 있는가?

레퍼런스: http://docs.microsoft.com/ko-kr/azure/data-explorer/using-metrics

 

메트릭을 사용하여 Azure Data Explorer 성능, 상태 및 모니터링 - Azure Data Explorer

Azure Data Explorer 메트릭을 사용하여 클러스터의 성능, 상태 및 사용량을 모니터링하는 방법을 알아봅니다.

learn.microsoft.com

마이크로소프트에서는 어떤 메트릭을 볼까? 위 레퍼런스에서 알려주는 Azure 서비스에서 측정하는 메트릭의 주요 예는 다음과 같다.

  • 캐시 사용률
  • CPU, Memory
  • 인스턴스의 개수
  • 연결 유지

레퍼런스: docs.microsoft.com/ko-kr/azure/data-explorer/using-metrics

 

Google - Site Reliability Engineering

Monitoring Distributed Systems Written by Rob EwaschukEdited by Betsy Beyer Google’s SRE teams have some basic principles and best practices for building successful monitoring and alerting systems. This chapter offers guidelines for what issues should in

sre.google

앞서 살펴본 바와 같이 주요 메트릭은,

단일 노드일 경우 리눅스를 통해 측정할 수 있다. 클러스터 형태, 즉 여러 대의 노드로 구성되어 있는 경우, AWS 콘솔(CloudWatch 등)을 통해 이미 제공되고 있는 경우가 많다. 이번 유닛에서는 단일 노드에서의 측정과 함께, 쿠버네티스 클러스터 상에서의 모니터링 과정을 살펴본다.

모니터링 구분

어떠한 서비스가 제대로 작동되는지 확인하려면, 서비스 또는 시스템과 관련한 모든 변수들을 모니터링해야 한다.

하지만 우리가 서비스 모니터링을 위해 날씨나 데이터센터의 전력 공급에 신경 쓰지 않는다. 반대로, 발생하는 모든 메트릭을 모니터링하지 않는다. 모든 메트릭을 실시간으로 보는 것은 불가능하고, 너무 많은 메트릭을 모니터링하다 보면, 중요한 신호를 발견하기도 어렵다.

따라서 모니터링할 때에는 단계를 구분해서 계층적으로 해야 한다.

블랙박스 모니터링과 화이트박스 모니터링

블랙박스와 화이트박스의 구분은 박스를 기준으로 관찰자가 밖에서 바라보느냐, 안에서 바라보느냐의 차이다. 박스는 애플리케이션이 될 수도 있고, 쿠버네티스 시스템이 될 수도 있다.

  • 블랙박스 모니터링은 CPU/메모리/스토리지 등 인프라 수준의 모니터링에 유용하다. 쿠버네티스 시스템의 경우, 클러스터 정상 작동 여부 등 쿠버네티스 컴포넌트 그 자체를 모니터링하는 것도 블랙박스 모니터링에 해당한다.
  • 그러나, 애플리케이션 로직과 관련된 문제나 애플리케이션 내부 로직에 대한 세부적인 모니터링을 할 때는 화이트박스 모니터링이 더 효과적이다.

이렇게 서비스의 건강과 성능을 파악하고 개선하기 위해 모니터링은 필수적이다. 주요 메트릭을 잘 파악하고 적절한 도구와 전략을 사용하면 서비스의 품질을 획기적으로 향상시킬 수 있다.

AWS 버스트 가능 성능 인스턴스 메커니즘

 

AWS는 사용자에게 탁월한 유연성과 효율성을 제공하도록 설계된 많은 서비스와 기능을 제공합니다. 그 중 하나가 AWS 버스트라고 부르는 '버스트 가능 성능 인스턴스'다. 이 서비스는 시스템에 가끔이나 부정기적으로 부하가 발생하는 경우 매우 유용하다고 할 수 있다. 그렇다면 '버스트 가능 성능 인스턴스'는 어떤 원리로 작동하는 것인지 한번 알아보자.


버스트 가능 성능 인스턴스

버스트 가능 성능 인스턴스는 일반적인 작업량에는 낮은 CPU 성능을 제공하지만, 필요한 경우 잠시 높은 성능을 제공할 수 있는 EC2 인스턴스 유형이다.. 이 기능은 "CPU 크레딧"이라는 개념을 이용해 CPU 성능을 관리한다.

CPU 크레딧

CPU 크레딧은 인스턴스가 가용한 CPU 성능을 측정하는 단위인데, vCPU 시간의 단위로 표현된다.
 예를 들어, CPU 크레딧 1개는 vCPU 1개를 1분 동안 100% 사용하는 것을 말한다.

획득 크레딧 및 소비 크레딧

인스턴스가 실행 중일 때, 계속해서 CPU 크레딧이 적립된다. 이를 '획득 크레딧'이라고 하는데, 반대로 인스턴스가 실행 중일 때 CPU를 사용할 때 적립돼있는 CPU 크레딧을 소비한다. 이렇게 소비되는 크레딧을 '소비 크레딧'이라고 한다.


기준 사용률

'기준 사용률'은 인스턴스가 CPU 크레딧을 얻는 속도와 사용하는 속도가 같을 때, 인스턴스가 사용할 수 있는 CPU 수준을 말한다. 기본적으로 각 인스턴스 유형은 미리 정의된 기준 사용률을 가지고 있어서 해당 기준을 준수하는 방식으로 작동한다.


크레딧 누적 한도 및 시작 크레딧

각 인스턴스는 일정 시간 동안 누적할 수 있는 CPU 크레딧에 한도가 있는데, 이를 '크레딧 누적 한도'라고 한다. 그리고 새로 생성된 인스턴스는 일정량의 '시작 크레딧'을 가지고, 이 크레딧은 인스턴스가 처음 실행될 때 기준 이상으로 버스트하는 데 쓰인다.

무제한 모드와 스탠다드 모드

AWS는 무제한 모드와 스탠다드 모드라는 두 가지 크레딧 구성 모드를 제공한다. 스탠다드 모드에서는 크레딧 잔액에 적립된 크레딧을 사용하여 인스턴스를 기준 이상으로 버스트할 수 있는 반면, 무제한 모드에서는 필요한 경우 언제든지 기준 이상으로 인스턴스를 버스트할 수 있다. 당연하게도, 이 경우 추가 요금이 발생할 수 있다.


마치며

버스트 가능 성능 인스턴스를 알아봤는데 AWS가 제공하는 매우 유용한 기능이다. 이것을 이해하고 제대로 활용한다면, 부하가 일시적으로 높아지는 시스템에서 돈 낭비 없이 효율성과 성능을 얻을 수 있을 것이다. 

[주제 1] 람다를 모니터링 하려는 경우, 메트릭을 활용해 어떤 질문이 나올 수 있을까요? 

AWS 람다를 모니터링하기 위해 주목해야 할 메트릭은 크게 5가지로 나눌 수 있다.

 

실행시간(duration): 함수가 작동하는데 어느정도의 시간이 걸리는지 알면 함수의 전체적인 성능이 어떤지 파악할 수 있다.


 호출(Invocations): 함수가 얼마나 자주 호출되는지를 알면 애플리케이션 활동과 함수의 전체적인 성능 추이가 어떻게 되는지 파악할 수 있다. 서비스 중단이나 AWS 서비스 문제 등이 있다면 호출 횟수가 갑자기 감소하는 현상을 볼 수도 있다.

 죽은 편지 에러(Dead-letter Errors): 비동기적으로 호출되거나 이벤트 소스 맵핑에서 호출되는 함수는 처리되지 않은 이벤트를 처리하기 위해 데드-레터 큐(DLQ)를 사용하는데, 여기서 데드-레터 에러 메트릭은 람다가 이벤트를 DLQ에 보낼 수 없는 횟수를 추적한다.

 동시성(Concurrency): 동시성 메트릭을 모니터링하면 과다 프로비저닝된 함수를 관리하고, 애플리케이션 트래픽의 흐름을 지원하기 위해 함수를 확장할지 안할지를 결정할 수 있다.


 프로비저닝된 동시성(Provisioned Concurrency): 람다는 필요할 때만 코드를 실행하기 때문에, 함수가 오랜 시간 동안 사용되지 않은 경우 추가적인 대기 시간(콜드 스타트)이 발생할 수 있다는 단점이 있다. 이 문제를 해결하기 위해 프로비저닝된 동시성을 사용하여 함수를 미리 초기화하면, 미리 요청 처리 준비를 할 수 있다.

 스로틀(Throttles): 요청이 들어오면, 함수는 미리 프로비저닝된 동시성 풀 또는 그 이상에서 스케일링하여 수요를 감당한다. 이때, 동시성 풀을 전부 사용해버리면 람다는 그 지역의 모든 함수를 스로틀링하고 들어오는 모든 요청을 거부한다.

 


나올 수 있는 질문들


람다를 효과적으로 모니터링하려면 이러한 메트릭을 이해하고 관찰해야 한다. 그래서 각 메트릭이 어떤 정보를 제공하고 어떻게 사용되는지에 대해 알면 알수록 문제가 발생했을 때 더 적절한 대처를 할 수 있다.

 

그래서 중요 메트릭에 대해서 간단하게 알아보았으니 어떤 질문들이 나올 수 있는지 한번 생각해봤다.

 


 

1. 특정 함수의 실행시간이 얼마나 되는가? : 당연하게도 함수의 성능을 파악하는데 매우 중요한 지표기 때문에, 실행 시간을 직접 관찰하면서 해당 람다에 추가적인 최적화 작업이 필요한지 알아볼 수 있다.

 

2. 함수가 얼마나 호출되고 있는가? : 함수가 얼마나 자주 호출되는지를 알면 애플리케이션 활동과 함수의 전체적인 성능 추이가 어떻게 되는지 파악할 수 있다. 서비스 중단이나 AWS 서비스 문제 등이 있다면 호출 횟수가 갑자기 감소하는 현상을 볼 수도 있다. 

 

3. 데드레터 큐로 이동하지 못한 이벤트의 수(dead-letter errors)는 얼마나 되는가? : 람다가 이벤트를 DLQ로 보내는데 실패한 갯수다. 이것을 파악하면 시스템에서 문제가 발생하는 부분을 찾는데 중요한 단서로 사용할 수 있다.

 


 

[주제 2] 쿠버네티스에 어떤 파드가 Pending 상태에 머물러있다면, 어떤 계층부터 살펴보아야 할까요? 이 경우는 파드가 Running 상태인데 잘 작동하지 않는 경우랑은 어떻게 다른가요?

파드 상태: 'Pending' vs 'Running'

먼저, 쿠버네티스 파드의 'Pending' 상태와 'Running' 상태에 대해 이해할 필요가 있다.

'Pending' 상태는 파드가 쿠버네티스 시스템에 의해 스케줄되었지만, 아직 하나 이상의 컨테이너가 노드에 배포되지 않은 상태를 말한다. 이는 일반적으로 리소스 부족, 볼륨 마운트 문제, 허용된 톨러레이션 미달 등과 같은 이슈 때문에 발생한다.

반면에, 'Running' 상태는 모든 파드의 컨테이너가 성공적으로 스케줄링되고 시작된 상태를 의미하는데, 'Running' 상태의 파드가 정상적으로 작동하지 않는다면, 일반적으로 애플리케이션 수준의 오류나 컨테이너 실행 환경 문제 등이 원인일 가능성이 높다.

그래서 파드가 'Pending' 상태에 머물러 있는 경우와 'Running' 상태인데 잘 작동하지 않는 경우는 문제를 해결하기 위해 검사해야 하는 부분이 다르다고 볼 수 있다.

 


 

파드 'Pending' 상태 문제 분석

'Pending' 상태의 파드를 해결하려면 아래 요소들을 확인해봐야한다.

1. 클러스터 및 노드 상태 확인:
쿠버네티스 클러스터와 노드가 정상적으로 작동하고 있는지 확인해야 한다. kubectl get nodes 명령어를 사용하여 노드 상태를 확인할 수 있고, 충분한 리소스(CPU, 메모리, 스토리지 등)가 있는지 확인해야 한다.

2. 파드 스케줄링 및 톨러레이션 확인:
파드의 스케줄링 정책과 톨러레이션을 확인해야 한다. 노드 셀렉터, 노드 어피니티, 테인트 및 톨러레이션 등이 올바르게 설정되어 있는지 확인해주면 된다.

3. 파드 볼륨 및 컨피그맵 확인:
파드가 필요로 하는 볼륨이나 컨피그맵이 존재하는지, 올바르게 마운트되어 있는지 확인해야 한다.

4. 파드 이벤트 로그 분석:
마지막으로, 파드의 이벤트 로그를 분석해줘야한다. kubectl describe pod <파드 이름> 명령어를 사용하여 파드의 상세 정보와 이벤트 로그를 확인할 수 있다.

'DevOps' 카테고리의 다른 글

[DevOps] 최종 프로젝트 회고 - 요구사항 분석  (0) 2023.06.12
[DevOps] 모니터링  (0) 2023.06.08
[DevOps] DOB - Project3  (0) 2023.05.30
[DevOps] 5/4 TIL : 마이크로서비스 Domain  (1) 2023.05.07
[DevOps] 프로젝트 2 진행  (0) 2023.04.30

요구사항과 시나리오

시나리오

<도넛-스테이츠>는 온라인으로 도넛을 판매합니다. 웹사이트를 통해서 주문 버튼을 누르는 것으로 구매(Sales API)가 가능합니다. 창고에 재고가 있다면 재고가 감소하고 구매가 완료됩니다. 유튜브스타 hoyong.LEE가 도넛-스테이츠의 도넛이 맛있다고 영상을 올렸습니다. 그를 따르는 데브옵스 수강생들이 몰려듭니다. 주문이 급등합니다. 창고에 재고가 없기 때문에 구매가 불가능한 경우가 발생합니다. 창고의 도넛의 재고가 다 떨어지면 제조 공장에 알려서 다시 창고를 채우는 시스템을 구축해야 합니다. 제조 공장인 <팩토리-스테이츠>에 주문을 요청(Leagcy Factory API)할 수 있습니다. 주문이 요청되면 일정 시간이 지난 후 창고에 재고가 증가합니다.

상황

비효율적인 레거시 시스템 때문에 고객의 불만사항이 접수되고 있습니다. 제품별 재고부족 요청이 빈번하게 발생되고 있지만 전달 과정에서 지연과 누락 등 문제 상황이 발생하고 있습니다. 안정적으로 요청이 전달 될 수 있도록 시스템을 개선해야합니다. 비정상적으로 처리된 요청의 경우 운영팀에 상황을 알려야합니다.



요구사항 1 : 재고부족으로 인한 구매실패에 대한 조치

  1. Sales API 를 통해 요청을 받은 서버가 데이터베이스에서 재고 상황을 확인합니다.
  2. 재고가 있다면 감소시키고 응답으로 판매완료 내용을 전달합니다.
  3. 재고가 없는 경우 공장에 주문을 진행합니다
  4. 재고가 없다는 내용을 담은 메세지 페이로드와 함께 SNS topic이 생성됩니다.
  5. 메시지가 SQS로 구현된 stock_queue에 수신됩니다.

 

요구사항 2 : 메시지 누락 상황에 대한 조치

  1. 빈번한 요청으로 메시지 누락이 발생합니다.
  2. SQS에서 처리완료되지 않은 메시지들을 체계적으로 관리할 dead_letter_queue를 생성해야합니다.
  3. stock_queuedead_letter_queue를 연결합니다.

 

요구사항 3 : Legacy 시스템(Factory → Warehouse) 성능문제에 대한 조치

  1. 안정적으로 이벤트가 전달 될 수 있는 시스템을 구축해야합니다.
  2. stock_queue 의 메시지를 소비하는 stock_lambda에 의해 Factory API가 호출됩니다.
  3. Factory의 생산 완료 메시지를 수신한 stock_inc_lambdaDB에 상품 재고를 증가시킵니다.

Day1 : 리소스 다이어그램

작성한 리소스 다이어그램

먼저 USER가 sales api로 도넛 구매요청을 한다.

 만약, 도넛의 남은 재고가 없다면, SNS를 통해서 SQS로 "재고가 없어용 채워야해용" 메시지를 전송하고 SQS에 새 메시지가 들어오는 것을 트리거로 작동하는 Lambda함수를 통해 도넛공장 api로 도넛을 더 구워달라는 요청을 보낸다.

 그리고 도넛공장 api에서 제빵 완료라는 응답을 받은 Lambda는 DB의 남은 도넛의 재고를 증가시키는 매커니즘이다.

 


 

Day2 : 구현

 

 만들어둔 sales API와 재고 DB를 환경변수로 연결 정보를 설정해서 서로 연결해 DB연결이 잘 되는지 확인한다. 그렇게 문제가 없다고 생각해서 SALES API를 Lambda로 배포하고 SNS, SQS를 만들어준다. 그리고 재고부족요청을 POSTMAN으로 보냈는데 SNS로 메시지가 넘어가지 않는다. 그래서 CloudWatch 로그를 뒤적여보니 SNS 권한이 없단다. 그래서 먼저 SNSFullAccess 권한을 Lambda에 부여해주고 테스트를 한다음, 더 작은 권한인 SNS publish 권한을 부여했다. 

 

 그리고 SQS를 트리거로 하는 stock-lambda 람다가 SQS에 들어온 메시지를 가져가서 소비하는지 확인해봤다. 그런데 이번에도 권한이 없다는 메시지를 받아서 해당 Lambda함수의 역할에 SQS메시지 실행권한을 넣어줬더니 아주 잘 작동하는 것을 확인할 수 있었다.

 

 마지막으로 콘솔에서 했던 SNS, SQS 작업들을 serverless에서도 할 수 있도록 serverless.yaml 파일을 작성해줬다. 

service: sales-api
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x
  region: ap-northeast-2 #리전 설정.(default: us-east-1)
  iam: #iam으로 부여할 권한을 설정해준다.
    role:
      statements:
        - Effect: 'Allow'
          Action:
            - 'SNS:Publish' 
          Resource: !Ref stockTopic
  timeout: 15

constructs:
  stockQueue:
    type: queue
    worker:
      handler: stock.handler #핸들러 매핑시켜주기

functions:
  api:
    handler: api.handler
    events:
      - httpApi: '*'


resources:
  Resources:
    stockTopic: #SNS 토픽 설정
      Type: AWS::SNS::Topic
      Properties:
        TopicName: stock_empty
    stockSub: #SNS 토픽 구독 설정
      Type: AWS::SNS::Subscription
      Properties:
        TopicArn: !Ref stockTopic
        Endpoint: ${construct:stockQueue.queueArn}#큐의 ARN
        Protocol: sqs
        RawMessageDelivery: true

    stockQueuePolicy: #SQS에 접근할 수 있도록 권한을 부여한다.
      Type: AWS::SQS::QueuePolicy
      Properties:
        PolicyDocument:
          Version: '2012-10-17'
          Statement:
            - Effect: Allow
              Principal:
                Service: sns.amazonaws.com
              Action: 'sqs:SendMessage'
              Resource: ${construct:stockQueue.queueArn}
              Condition:
                ArnEquals:
                  aws:SourceArn: !Ref stockTopic
        Queues:
          - ${construct:stockQueue.queueUrl} #해당 큐의 URL

plugins:
  - serverless-lift

 


Day3 : 구현 및 추가 요구사항에 대한 다이어그램 작성

받아온 Stock empty 함수에서 Factory API에 원할하게 도넛생산요청을 보내고 Factory API의 응답에 따라서 stock increase function이 재고DB에 재고를 추가한다. 아래는 간단하게 작성해본 stock empty 함수 배포용 serverless.yaml이다. js코드만 잘 작성해주니 오류없이 편안하게 작동한다 ㅎㅎㅎ

service: stock-lambda
frameworkVersion: '3'

provider:
  name: aws
  runtime: nodejs14.x
  region: ap-northeast-2

functions:
  consumer:
    handler: index.consumer
    events:
      - sqs: arn:aws:sqs:ap-northeast-2:비밀이에요 ㅎㅎ:stock_empty

plugins:
  - serverless-lift

추가 요구사항

  • 추가 시나리오에 대한 아키텍처를 구성해야 합니다.
    • 실제 구현하지 않아도 아키텍처상에 리소스 추가 배치
  • 확장된 아키텍처를 가지고 팀의 의견을 제시할 수 있어야 합니다.

a. 광고 중단 요청 진행 시나리오

재고가 없는 상황에서도 광고가 계속 진행되고 있습니다. 광고 비용 절감과 고객불만을 낮추기 위한 조치가 필요합니다. 메시지가 유실되는 상황을 막기 위해 내구성을 갖춘 시스템이 필요합니다.

  • 요구사항
    • 재고를 채우기 위한 과정이 진행될 때 광고 담당자에게 광고 중단 요청 내용을 담은 이메일이 전송되어야 합니다.
    • 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 합니다.
    • AWS SES 서비스를 이용해서 이메일을 전송해야 합니다.

b. VIP 고객관리 프로세스 추가 시나리오

모니터링 결과 대량 주문을 하는 일부 고객들이 확인되었습니다. 대량 구매 고객들의 사용자 정보를 식별할 수 있어야 합니다. 고객정보는 별도의 서버(EC2)와 데이터베이스(RDS)에서 관리되고 있습니다. 데이터베이스 기록과 외부 마케팅 시스템으로의 연결과정의 오류를 대비하기 위한 내구성 갖춘 시스템이 필요합니다.

  • 요구사항
    • 100개 이상 구매가 발생 시 해당 유저의 타입이 normal에서 Vip로 변경되어야 합니다.
    • 메시지에 대한 내구성을 강화하기 위해 메시지 Queue가 사용되어야 합니다.
    • 고객관리는 별도의 데이터베이스(RDS)로 관리되고 있기 때문에 해당 데이터베이스에 접근해서 정보를 수정해야 합니다.

추가 요구사항 반영한 다이어그램

추가 시나리오  a. 광고중단

재고주문알림의 메시지에 광고주에 대한 정보도 담아서 SQS에 메시지를 전달하면 해당 메시지를 받은  Stock Lambda가 메시지를 처리해 SES서비스를 통해 광고주에게로 광고중단메일을 송신한다.

추가 시나리오  b. 고객관리

먼저 100개 이상 주문하는 고객이 생기면 sales api에서 sns를 통해 VIP 고객관리 태그에 속한 SQS로 메시지를 보낸다. SQS를 트리거로 하는 Lambda가 해당 메시지를 받아서 EC2로 넘기게 된다. 그렇게 되면 EC2는 해당 메시지를 처리해 RDS에 담겨있는 고객 정보를 수정한다.

여기서 어째서 컴퓨팅 리소스를 EC2와 람다 2개를 같이 붙여서 사용하는지에 대한 의문이 들 수 있다. SQS에서 EC2가 메시지를 곧바로 받아오기 위해선 SQS를 풀링하는 코드를 실시간으로 실행해야하는데, Lambda의 트리거 기능을 사용하면 EC2에서 계속 풀링할 필요가 없어지기 때문에 EC2의 리소스를 절약하기 위해서 Lambda를 사용했다.

 

 


마치며..

이번 프로젝트는 내가 어떤 작업을 해야할지 명확하게 파악할 수 있도록 가이드라인을 만들어서 진행과정 중에 혼선이 적었다. 역시 프로젝트 초기 단계에서 방향성을 명확하게 하는 것이 아주 중요하다는 것을 다시한번 마음에 세길 수 있었고, IaC작업은 여전히 신기하고 흥미롭다 ㅎㅎㅎ. 아직은 리소스 하나를 작성하는데에도 많은 문서를 뒤적여야하는 응애이지만, 잘 쓸 수만 있다면 손쉽게 배포를 자동화시킬 수 있는 해피한 엔지니어가 될 수 있을 거라 믿는다.

 


도메인은 지식, 영향력 또는 활동 영역을 말하며, 개발 분야에서는 소프트웨어로 해결하려는 문제의 영역을 의미한다.

도메인을 표현하는 대표적인 사례 : 객체 지향 프로그래밍

  • 객체 지향 프로그래밍에서는 도메인이 클래스(상태, 동작을 가지는 객체)로 표현된다.
  • 어떤 도메인을 개념적으로 표현하는 방법 : 객체 지향 설계, ERD 등

도메인 주도 설계 (Donaim Driven Design)

  • 도메인 내부에서 문제 해결이 가능한 형태로 도메인을 모델링 하는 기법.
  • 하나의 도메인 모델에 대한 이해관계가 각자 다름을 인정하고,
  • 각 팀에 적합한 하위 도메인을 설정하고,
  • 해당 하위 도메인에 대한 맥락을 알고 있는 사람이 따라야 할 비즈니스 규칙에 대한 경계를 설정하는 설계 방식이다.
  • 따라서 마이크로서비스와 궁합이 좋다.

보편 언어 (ubiquitous language)

  • 도메인의 특정 업무와 관련된 사람들 사이에서 통용되는 개념
  • 페이먼츠 팀 : 고객이 '결제' 했어요
  • 배달 팀 : '배달' 건수가 생겼어요
  • 가맹점 팀 : '주문서'가 도착했어요

한정된 맥락 (bounded context)

  • 요구사항을 모놀리틱(단일 프로그램) 아키텍처로 구성하면 클래스 이름 정의하기도 쉽지 않다.
  • 이름을 지었다 한들 클래스가 매우 비대해질 우려가 있다. ("클래스는 하나의 책임만 가져야 한다"는 단일 책임 원칙 위배)
  • 다른 목적을 갖도록 클래스를 분리했다 하더라도, 의존 관계를 신경써야 한다.
  • 모델의 경계를 분명하게 구분짓고, 업무 범위 내로만 아키텍처를 구성하면 된다.
  • 업무 범위를 나누어 타당한 클래스 이름 짓기가 가능해지고, 모든 도메인에 용어를 맞추기 위해 모호한 단어를 쓸 필요가 없다.

DDD를 실천하기에 딱 맞는 마이크로서비스 아키텍처를 도입하려면,

  1. 도메인 지식을 가진 엔지니어가 팀 마다 있어야 자연스럽게 기능 조직이 아니라 목적 조직화 된다.
  2. 여러 서비스가 잘 결합할 수 있게 디자인해야 한다. 하지만, 동시에 다른 서비스에 지나치게 의존해서도 안된다.
  3. 서비스를 오케스트레이션 해야한다. 오케스트레이터는 각 서비스가 죽는지 안죽는지 여부, 트래픽이 수용 가능한지 아닌지 여부, 인프라 유지보수 (업그레이드, 패치 등) 업무 등에만 집중한다.

따라서 마이크로서비스로 소프트웨어를 작성할 때에는, 소프트웨어 작성에 앞서 팀의 일하는 방식을 보다 독립적으로 만들어내야 한다. 반대로 마이크로서비스 아키텍처를 통해, 팀의 일하는 방식이 보다 독립적으로 만들어질 수 있다. 즉, 문화로서의 DevOps를 실천해야만 가능하다.

 

DDD 주요 용어


  • 도메인 이벤트: 발생한 사건
  • 커맨드: 도메인 이벤트를 트리거하는 명령
  • 외부 시스템: 도메인 이벤트가 호출하거나 관계가 있는 레거시 또는 외부 시스템
  • 액터: 개인 또는 조직의 역할
  • 핫스팟: 의문사항, 결정하기 힘든 사항
  • 애그리거트: 도메인 이벤트와 커맨드가 처리하는 데이터, 상태가 변경되는 데이터
  • 정책: 이벤트 조건에 따라 진행되는 결정, “이벤트”가 발생할 때, “커맨드”를 실행한다
  • 정보: 액터에게 제공되는 데이터, 결정을 내리는데 영향을 주는 정보

DDD 제작 순서

  1. 도메인 이벤트 찾기
  2. 외부 시스템/외부
  3. 프로세스 찾기
  4. 커맨드 찾기
  5. 액터 찾기
  6. 애그리거트 정의
  7. 바운디드 컨텍스트 정의
  8. 컨텍스트 매핑

예시로 DDD를 만들어 보았다.

중앙방역대책본부에는 다양한 팀(DDD의 관점에서는 Actor)이 있지만, 대중에게 가장 잘 알려진 다음의 네 팀의 업무만을 이해해 보도록 하자.

 

  •  


 


 


 



miro를 사용해 다이어그램 형식으로 작성했다.

프로젝트 2를 진행하면서 해결해야할 여러 문제상황들을 마주했다.

그래서 주요 문제상황과 그 상황을 어떻게 해결했는지 기록했다.


ISSUE SOLUTION LOG

📝 문제 1 : 아마존 ECR IAM ROLE 생성

  1. IAM 자격 증명 공급자 리소스를 생성

https://blog.kakaocdn.net/dn/2mAFv/btsdi2512RZ/B0MzOft5l5iFMriNbkjbYK/img.png

  1. 웹 자격 증명 또는 OIDC를 위한 역할 생성

https://blog.kakaocdn.net/dn/C9iJ5/btsdlJSEoG1/9zhjPgGCnIjVvgiirVkkd1/img.png

  1. 탐색 창에서 역할(Roles)을 선택한 후 역할 생성(Create role)을 선택
  2. 웹 ID(Web Identity) 역할 유형을 선택
  3. 자격 증명 공급자(Identity provider)에서 역할의 IdP를 선택
  4. Audience에서 지정한 자격증명 공급자의 대상 선택
  5. 권한 정책을 사용하기 위한 정책을 선택하거나 정책 생성(Create policy)을 선택하여 새 브라우저 탭을 열고 완전히 새로운 정책을 생성할 수 있음(자세한 내용은 IAM 정책 생성 섹션을 참조)
    • 웹 ID 사용자에게 부여하려는 권한 정책 옆의 확인란을 선택 원할 경우, 여기서 정책을 선택하지 않고 나중에 정책을 만들어서 역할에 연결할 수 있음 (기본적으로 역할은 권한이 없음)
  6. 역할 이름(Role name)에 역할 이름을 입력
    • 역할 이름은 AWS 계정 내에서 고유해야하며 대소문자를 구분하지 않음
    • 다른 AWS 리소스가 역할을 참조할 수 있기 때문에 역할을 생성한 후에는 역할 이름을 편집할 수 없음
  7. 역할에 대한 사용 사례와 권한을 편집하려면 1단계: 신뢰할 수 있는 엔터티 선택(Step 1: Select trusted entities) 또는 2단계: 권한 추가(Step 2: Add permissions) 섹션에서 편집(Edit)을 선택
  8. 역할을 검토한 다음 [Create role]을 선택
  9. GitHub OIDC ID 제공자의 역할 구성
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": { # OIDC Role ARN
                "Federated": "arn:aws:iam::123456123456:oidc-provider/token.actions.githubusercontent.com"
            },
            "Action": "sts:AssumeRoleWithWebIdentity",
            "Condition": {
                "StringLike": {
                    "token.actions.githubusercontent.com:sub": "repo:<GitHub 조직명>/<레파지토리명>:*"
                },
                "StringEquals": {
                    "token.actions.githubusercontent.com:aud": "sts.amazonaws.com"
                }
            }
        }
    ]
}
클레임 클레임 유형 설명
aud 사용자 - 기본적으로 리포지토리를 소유하는 organization 같은 리포지토리 소유자의 URL- 사용자 지정할 수 있는 유일한 클레임도구 키트 명령- https://www.npmjs.com/package/@actions/core/v/1.6.0을 사용하여 사용자 지정 대상 그룹을 설정 가능
iss 발급자 -OIDC 토큰 발급자: https://token.actions.githubusercontent.com/
sub 제목 - 클라우드 공급자가 유효성을 검사할 주체 클레임을 정의- 이 설정은 액세스 토큰이 예측 가능한 방식으로만 할당되도록 하는 데 필수
  1. ECR 로그인을 위한 권한 부여

4-1. ECR Private에 로그인하기 위한 최소 권한 집합

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "GetAuthorizationToken",
      "Effect": "Allow",
      "Action": [
        "ecr:GetAuthorizationToken"
      ],
      "Resource": "*"
    }
  ]
}

4-2. ECR 프라이빗 리포지토리에서 이미지를 가져오기 위한 최소 권한

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPull",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:GetDownloadUrlForLayer"
      ],
      "Resource": "arn:aws:ecr:<리전>:<AWS 계정 ID>:repository/<레파지토리명>"
    }
  ]
}

4-3. ECR 프라이빗 리포지토리에서 이미지를 푸시하고 풀링하기 위한 최소 권한

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "AllowPushPull",
      "Effect": "Allow",
      "Action": [
        "ecr:BatchGetImage",
        "ecr:BatchCheckLayerAvailability",
        "ecr:CompleteLayerUpload",
        "ecr:GetDownloadUrlForLayer",
        "ecr:InitiateLayerUpload",
        "ecr:PutImage",
        "ecr:UploadLayerPart"
      ],
      "Resource": "arn:aws:ecr:<리전>:<AWS 계정 ID>:repository/<레파지토리명>"
    }
  ]
}

📝 문제 2 : 빌드 후 ECR에 이미지가 배포되었을 때 자동으로 서비스에 배포하는 workflow 실행 시 ECR 배포 실패

{
   "Version":"2012-10-17",
   "Statement":[
      {
         "Sid":"RegisterTaskDefinition",
         "Effect":"Allow",
         "Action":[
            "ecs:RegisterTaskDefinition"
         ],
         "Resource":"*"
      },
      {
         "Sid":"PassRolesInTaskDefinition",
         "Effect":"Allow",
         "Action":[
            "iam:PassRole"
         ],
         "Resource":[
            "arn:aws:iam::<aws_account_id>:role/<task_definition_task_role_name>",
            "arn:aws:iam::<aws_account_id>:role/<task_definition_task_execution_role_name>"
         ]
      },
      {
         "Sid":"DeployService",
         "Effect":"Allow",
         "Action":[
            "ecs:UpdateService",
            "ecs:DescribeServices"
         ],
         "Resource":[
            "arn:aws:ecs:<region>:<aws_account_id>:service/<cluster_name>/<service_name>"
         ]
      }
   ]
}

📝 문제 3 : 컨테이너로 WAS와 DB를 따로 기동 후 WAS에서 DB 접근 불가

  • 원인
    1. compose로 함께 기동하지 않고 따로 기동할 경우 브릿지가 생성되지 않았다.
    2. container는 독립된 네트워크로 동작하므로 두 서버가 동일한 서브넷에 속해있지 않았기 때문에 애초에 통신이 불가능했다.
$ docker run --name servertest -p 3000:3000 --env MONGO_PASSWORD=secret --env MONGO_HOSTNAME=172.22.0.2 --env MONGO_USERNAME=root --network devops-04-s2-team9_default ohrory218/helloworld:1.1

> helloworld-was@1.0.0 start
> fastify start -l info app.js --address 0.0.0.0

[INFO] app.js file processing
[INFO] app.js file done
[DB CONNECTION STRING] mongodb://root:secret@172.22.0.2:27017/?authMechanism=DEFAULT
MongoServerSelectionError: connect ECONNREFUSED 172.22.0.2:27017
    at Timeout._onTimeout (/app/node_modules/@fastify/mongodb/node_modules/mongodb/lib/sdam/topology.js:277:38)
    at listOnTimeout (node:internal/timers:569:17)
    at process.processTimers (node:internal/timers:512:7) {
  reason: TopologyDescription {
    type: 'Unknown',
    servers: Map(1) { '172.22.0.2:27017' => [ServerDescription] },
    stale: false,
    compatible: true,
    heartbeatFrequencyMS: 10000,
    localThresholdMS: 15,
    setName: null,
    maxElectionId: null,
    maxSetVersion: null,
    commonWireVersion: 0,
    logicalSessionTimeoutMinutes: null
  },
  code: undefined,
  [Symbol(errorLabels)]: Set(0) {}
}
  • 트러블 슈팅
    • 기동된 mongodb 컨테이너 네트워크를 확인해서 환경 변수의 HOSTNAME에 IP주소를, network에 networks명을 집어넣는다.
$ docker container inspect mongodb
[
    {
#... 중략 ...#
            "Networks": {
                "devops-04-s2-team9_default": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": [
                        "mongodb",
                        "mongo",
                        "223966663fe2"
                    ],

# ... 중략 ....#
                    "IPAddress": "172.22.0.2",
# ... 하략 ....#

                }
            }
        }
    }
]
  • 해결 방법
    1. mongo DB의 config를 변경해 외부 네트워크에서 접근 가능하도록 설정
    2. (채택) WAS 컨테이너를 실행할 때 DB 컨테이너가 실행된 네트워크에서 실행되도록 수정
$ docker run --name servertest -p 3000:3000 --env MONGO_PASSWORD=secret --env MONGO_HOSTNAME=172.22.0.2 --env MONGO_USERNAME=root --network devops-04-s2-team9_default ohrory218/helloworld:1.1

> helloworld-was@1.0.0 start
> fastify start -l info app.js --address 0.0.0.0

[INFO] app.js file processing
[INFO] app.js file done
[DB CONNECTION STRING] mongodb://root:secret@172.22.0.2:27017/?authMechanism=DEFAULT
{"level":30,"time":1682772429521,"pid":18,"hostname":"87140ace8e46","msg":"Server listening at http://0.0.0.0:3000"}

📝 문제 4 : 웹 서버 자동화 파이프라인 구성 시 Source에서 권한 부족 문제 발생

https://blog.kakaocdn.net/dn/pxjSc/btsdeINuaLN/dCNjYYUG9AyKKCfagbAqXk/img.png

The provided role cannot be assumed: 'Access denied when attempting to assume the role 'arn:aws:iam::123456789012:role/service-role/AWSCodePipelineServiceRole-ap-northeast-2-helloworld-web''

https://blog.kakaocdn.net/dn/2Sodk/btsdemw3u1c/739Qz5wBN8TLSdk1nFy1y1/img.png

 

* 1. 검색 창에 EC2를 검색하여 들어간 후 EC2를 생성(EC2에 서버구동을 위한패키지 설치, 포트설정은 되어있어야한다.)*

> 작업 -> 인스턴스 설정 -> 태그 관리 클릭

태그를 생성하는 이유:

* > AWS에서 사용하는 리소스들을 태그별로 분류해 관리하기 위함(비용적, 유지보수적 측면에서 유리)*

2. 새로운 태그 추가

3. **_IAM 역할 수정_**

> 작업 -> 보안 -> IAM 역할 수정 클릭

IAM 역할 수정하는 이유:

* > 인스턴스가 다른 AWS 서비스와 통신할 때, 접근 권한을 주기 위함*

4. 새 IAM 역할 생성 클릭

5. 역할 만들기 클릭

6. AWS Deploy를 이용하여 EC2에 작업할 것이므로 AWS 서비스 선택

> EC2 선택

7. CodeDeploy가 S3에 있는 코드를 사용할 것이므로 'AmazonS3 FullAcess' 선택, **_EC2에 Agent를 설치하기 위해서 'AmazonSSMFullAccess' 도 선택해준다. 그리고 마지막으로 'AWSCodeDeployRole' 까지 선택해준다._**

AWSCodeDeployRole 사용 이유

> CodeDeploy에서 배포하는 애플리케이션을 관리하는 데 필요한 권한을 제공

> CodeDeploy 배포 그룹을 만들 때 사용됩니다. 배포 그룹은 배포할 대상을 지정하는 데 사용

8. 역할 이름 지정하고 '역할 생성' 클릭

https://blog.kakaocdn.net/dn/drEvVX/btsb60a8Fad/x4e4vYXvl9Guw7mJWmLtq0/img.png

9. ec2 뿐만아니라 aws 서비스인 codedeploy도 리소스에 접근할 수 있도록 추가

https://blog.kakaocdn.net/dn/bdldXH/btscvZ9HbL9/yUPWvG9QZqWudzBdweJE9K/img.png

10. 실습에 활용할 로컬 파일에 appspec.yml파일을 추가한다. 그리고 각 hook에 해당하는 파일들도 작성해준다.

> 소스코드의 위치를 지정하고, 각 hook에 해당하는 파일의 위치와 실행할 계정을 지정해준다.

> 배포 그룹 생성

11. AWS CodeDeploy 대시보드로 이동해 애플리케이션으로 이동하고 **_[ 애플리케이션 생성 ] 버튼을 클릭_**

12. 애플리케이션의 이름을 임의로 입력하고, 컴퓨팅 플랫폼을 'EC2/온프레미스'로 선택한 뒤, [ 애플리케이션 생성 ] 버튼을 클릭

13. 애플리케이션이 생성되면, 생성한 애플리케이션의 배포 그룹 탭을 클릭하여 [ 배포 그룹 생성 ] 버튼을 클릭

14. 배포 그룹의 이름을 임의로 입력하고, 서비스 역할 영역을 클릭한 후 전에 생성했던 'EC2Role'을 선택

15. 환경 구성 중 'Amazon EC2 인스턴스'를 선택하고, 태그 그룹에 EC2 인스턴스에 설정해놓았던 태그 키와 값을 선택

16. 로드 밸런싱 활성화 체크 해제 후, [ 배포 그룹 생성 ] 버튼을 클릭

> 배포 파이프라인 생성

17. CodePipeline 대시보드로 이동 후, [ 파이프라인 생성 ] 버튼을 클릭한다. 그리고 파이프라인 이름을 임의로 입력 후, [ 다음 ] 버튼을 클릭

18. 앞서 클라이언트에서 했던 파이프라인 생성과정을 진행해주고, GitHub연결을 이미 했으므로 생성해둔 GitHub연결을 가져온다.

19. 우리가 이용하는 서버 코드(애플리케이션)는 코드의 컴파일과 빌드 과정이 필요 없고 테스트 코드도 없으므로, [ 빌드 스테이지 건너뛰기 ] 버튼을 눌러 빌드 단계를 생략

20. 배포 스테이지의 각 항목을 적절하게 생성해준다. 이번엔 CodeDeploy를 사용하므로 CodeDeploy를 선택해준다.

21. 잘못된 것이 있는지 확인 후 파이프라인 생성

결과

> 환경변수 설정.

  1. 환경 변수를 AWS System Manager Parameter Store에서 설정할 것이기 때문에 AWS CLI를 먼저 EC2 instance에 설치해야 한다. 밑에 명령어를 차례대로 입력

https://blog.kakaocdn.net/dn/quCpo/btscyYWQXbO/LxFcp3TAJ0kcyxMLlTZyx1/img.pnghttps://blog.kakaocdn.net/dn/c2dKMz/btscoE6zhFc/YtDNkCmub6fGwo9dwVDCl1/img.pnghttps://blog.kakaocdn.net/dn/btAm31/btscfDfZnIM/lxkfC4njXXCVxdtAVFXAmK/img.png

AWS CLI를 다운로드 하기 위한 명령어

https://blog.kakaocdn.net/dn/Bs8T6/btscoE6zlvX/1KWbQNLk1cmSbSjZDClU81/img.png

AWS 버전을 확인

이렇게 되면 aws CLI는 설치가 완료된 것이다

  1. RDS 생성

검색 창에 RDS 입력 후 데이터베이스 생성을 클릭

https://blog.kakaocdn.net/dn/2IeE7/btscyGWle6G/lFwk4BBcuzzJDYMKLyr5e0/img.png

엔진 옵션에 원하는 데이터베이스 소프트웨어를 선택

https://blog.kakaocdn.net/dn/ci7Yym/btscwnpAuul/a5hKRQQ2DX7ro0lckYQEHK/img.png

탬플릿은 사용 용도에 따라 선택하면 되는데, 비용이 제일 싼 걸 선택했다

https://blog.kakaocdn.net/dn/bc8IQr/btscwESdMO1/D3ml77BrEqrj4XKUGkFSi1/img.png

스크롤을 내려 DB 인스턴스 식별자, 마스터 사용자 이름, 암호를 기입

https://blog.kakaocdn.net/dn/bEKDhE/btscjiJvjwG/ovCRg8S6jYFLPb6E5neMek/img.png

컴퓨터 리소스는 기존 EC2에 연결하고 싶으면 오른쪽을 아니면 왼쪽을 클릭

VPC는 기존 EC2 VPC에 연결할 수 있음

DB 서브넷 그룹도 기존 존재하던 것에 연결할 수 있음

https://blog.kakaocdn.net/dn/bFYleb/btscmLkpQBe/ac0qysqftUOsomh6kh1VB0/img.png

보안 그룹도 기존에 존재하던 거와 연결할 수 있으며, 데이터베이스 인증 방식은 암호 인증 선택

https://blog.kakaocdn.net/dn/bgwzrF/btscCA82W3p/1dLE32ttVbtV6eDFS7wkTK/img.png

데이터베이스 생성 클릭

https://blog.kakaocdn.net/dn/Qegg7/btscvZh5T1j/BiqGkxk0vfXTMCex6oZkB1/img.png

  1. Parameter Store에 환경 설정

검색 창에 Parameter Store 입력 후 오른쪽 상단에 파라미터 생성 클릭

 

이름 -> appspec.yml가 실행할 스크립트에 있는 환경 변수 이름 기입

값 -> 이전에 생성한 RDS 값 입력

> 이후 파라미터 생성 클릭

예)

이름 : DETABASE_HOST

생성 완료 시 밑에 사진처럼 생성

https://blog.kakaocdn.net/dn/dcSWRO/btscxmjrzd2/k6yoabsodR5vfXQs0hRIcK/img.png

  1. 깃허브에 appspec.yml이 인식할 수정한 스크립트 파일 push

https://blog.kakaocdn.net/dn/d7Yuh8/btscwFDDgHe/Tmgb6oJReMhBqtPxIGeaUK/img.png

> 환경 변수 이름은 Parameter Store에 추가한 이름,

> 값은 AWS SSM 파라미터 스토어에서 값을 가져와 환경 변수를 내보내는 셸 명령어

  1. 결과

AWS Parameter Store 장점

1. 보안: Parameter Store는 데이터를 안전하게 저장하기 위한 다양한 기능을 제공합니다. 예를 들어, AWS KMS를 사용하여 데이터를 암호화하고, IAM을 사용하여 액세스 권한을 관리할 수 있습니다.

2. 중앙 집중화된 관리: Parameter Store를 사용하면 설정 데이터를 중앙 집중화하여 관리할 수 있습니다. 이를 통해 여러 시스템에서 사용되는 설정 데이터를 효율적으로 관리할 수 있습니다.

3. 확장성: Parameter Store는 대규모 인프라스트럭처에서도 높은 확장성을 제공합니다. 필요에 따라 설정 데이터를 추가하거나 업데이트할 수 있습니다.

4. 유연성: Parameter Store는 다양한 데이터 형식을 지원합니다. 예를 들어, 문자열, JSON, 암호화된 문자열 등을 저장할 수 있습니다.

5. AWS 서비스와의 통합: Parameter Store는 AWS에서 제공하는 다양한 서비스와 통합됩니다. 예를 들어, AWS Lambda 함수에서 Parameter Store의 데이터를 사용할 수 있습니다.

AWS CLI

AWS Command Line Interface(AWS CLI)는 AWS 서비스를 관리하는 통합 도구입니다.

AWS CLI를 사용하면 AWS 서비스를 명령어로 실행하고 사용할 수 있습니다.

 

AWS CLI 설치

AWS CLI를 설치하는 법은 간단합니다. 아래 3개의 명령어를 연달아 사용해주면 됩니다.

 

$ curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
$ unzip awscliv2.zip
$ sudo ./aws/install

각 명령어는 순서대로 AWS로부터 AWS CLI 설치 패키지 압축파일을 받아오고, 압축을 푼 뒤에, 설치를 하는 명령어입니다.

 

그렇게 전부 설치 한 뒤에 aws --version 명령어로 확인해주면

어떤 버전이 설치됐는지 확인할 수 있습니다.

'Linux' 카테고리의 다른 글

[Linux] vi 에디터 사용법  (0) 2023.03.27
[Linux] nslookup 명령어  (0) 2023.03.15
[Linux] read, write, execute 권한  (1) 2023.03.14
[Linux] 파일 내용 필터링 명령어 : grep  (0) 2023.03.14
[Linux] 데몬(demon)과 서비스(service)  (0) 2023.03.13

클라이언트 배포 파이프라인

https://blog.kakaocdn.net/dn/cvVk1D/btsbVcpl2P9/xzI4DlwVtNbg8vHHxd83AK/img.jpg

요구사항

  • AWS 개발자 도구 서비스를 이용해서 배포 자동화 파이프라인을 구축.
    • CodePipeline을 이용해서 각 단계를 연결하는 파이프라인을 구축.
    • Source 단계에서 소스 코드가 저장된 GitHub 리포지토리를 연결.
    • Build 단계에서 CodeBuild 서비스를 이용하여 수동으로 진행했던 build 과정을 자동으로 진행.
    • Deploy 단계에서 결과물을 S3 버킷에 자동으로 전달.
  • 나중에 변경 사항을 GitHub 리포지토리에 반영했을 경우, 배포 과정이 자동으로 진행되어야 함.
  • 배포 과정에서 오류가 생길 경우, log 파일을 참조하여 문제점을 확인할 수 있어야 함 .

클라이언트 배포 자동화 파이프라인

1. buildspec.yml 작성

2. 파이프라인 구성

1. 검색 창에 CodePipeline 클릭 후 파이프라인 생성 클릭

2. 이름과 서비스 역할에서 새 서비스 역할 클릭 후 다음 클릭

3.

> 소스 공급자를 클릭해서 GitHub를 선택(build 할 데이터가 있는 곳을 선택하면 됨)

> 만약 GitHub를 선택했으면, GitHub 연결을 클릭 > 내 GitHub의 리파지토리와 연결을 위해서

https://blog.kakaocdn.net/dn/dfeSH5/btscvYvQR7p/8AOWNK5nzoksCGQc979LLk/img.png

4. 이름은 아무거나 입력

https://blog.kakaocdn.net/dn/Z6Nqy/btsb2TiDUYJ/5s9vwkS2xWaJRO3Z10Jfc0/img.png

5. github에 연결 클릭 하면 GitHub 앱의 새 앱 설치 클릭

https://blog.kakaocdn.net/dn/bKJH0p/btsctLQ8esi/fZpVPFOoMAX1RND4S35YsK/img.png

6. aws와 연결할 github 아이디 선택하고 연결

7.

> 실행할 소스 코드가 있는 자신의 리파지토리 선택

> install 버튼 클릭

8. 생성한 GitHub 앱 선택 후 연결 클릭

https://blog.kakaocdn.net/dn/bp0nyM/btsb60ofzCh/QRNEa78MMrkWPANmE3H0y1/img.png

9. 리파지토리 이름과 , 해당 리파지토리의 main 브랜치를 선택한 뒤 다음 버튼 클릭

10.

> 빌드 단계에서 codeBuild 프로젝트 생성

> 소스 단계를 통해 전달받은 코드를 테스트하거나 빌드하여 배포 단계로 전달하는 역할

11. 빌드 프로젝트 이름은 마음대로 지음

https://blog.kakaocdn.net/dn/bns4BO/btscvx6lPre/IJK4vr7oazvHYAKO5rrlkk/img.png

12.

> Ubuntu 운영체제를 선택

> 다른 운영체제를 선택할 시 yml 파일이 오류를 일으킬 수 있음

https://blog.kakaocdn.net/dn/cowbv3/btsbV7BLTU5/hKtszGMp0H8yVnrbTvZPnK/img.png

13.

> 로그 파일을 저장하는 서비스로 CloudWatch 혹은 S3를 이용

> S3에는 정적 웹 호스팅을 위한 버킷이 이미 생성

> 버킷의 수가 많아지면 과금이 될 가능성이 다소 커질 수 있기에, CloudWatch 서비스를 빌드 출력 로그 저장을 위한 서비스로 선택하여 리소스를 분산

https://blog.kakaocdn.net/dn/xE4Lj/btscwmQUPdr/BaZ11NZvLnIU1D1Iyduf5k/img.png

14. 다음 클릭

15. 최종적으로 만들어진 결과물을 전달 및 반영할 위치를 선택, client이므로 s3를 선택

https://blog.kakaocdn.net/dn/cLZjla/btsb2TXeI1O/7GBdMtMlIJUXnMS34RSHP0/img.png

16. s3를 만들었을 때 사용한 버킷 이름을 선택

17. 검토한 후 다 맞다면 파이프라인 생성 클릭

결과

> 배포가 성공하는 것을 확인할 수 있다

환경변수 설정

  1. AWS 검색창에 CodeBuild를 검색하여 클릭

https://blog.kakaocdn.net/dn/YnJ2h/btscFEwBMEd/zcbK0HxKw3NwM0fJt6KqBk/img.png

  1. 원하는 빌드 프로젝트 선택 후 오른쪽 상단에 편집 -> 환경 클릭

https://blog.kakaocdn.net/dn/b5eIMX/btscyYo2c6z/qtKgoW52Atb6raBuxspFOK/img.png

  1. 밑으로 스크롤을 쭉 내려 추가 구성을 클릭

https://blog.kakaocdn.net/dn/bGWNbh/btsczK5egx9/BJ19U4DeAI10uuw6f1Frk0/img.png

  1. 추가 구성을 클릭하면 새로 선택지가 나옴, 스크롤을 내려 환경 변수에 환경 변수 이름과 서버의 주소를 넣음 -> 환경 업데이트 클릭

https://blog.kakaocdn.net/dn/d8pleY/btscBDELWdL/3nY0GggzwCbxTI8Oe4AyM1/img.png

  1. 파이프라인에 변경사항 릴리스를 클릭

https://blog.kakaocdn.net/dn/bIlzST/btscAq6Eqn0/95XKFBLiVCThYqrO4GzEgK/img.png

결과

> 이렇게 나온다면 클라이언트와 서버의 연결이 성공한 것이다 . 물론, 서버가 이미 열려있는 상태여야 가능하다.<

+ Recent posts