[project] DevOps section4 프로젝트 회고

BoongDev·2023년 6월 28일
0

Q. 프로젝트가 끝난 지금, 어떤가요?
A. 으아ㅏㅏㅏㅏㅏ
지금의 나의 상태. 완성? 미완성? 그 애매한 경계에서 프로젝트가 마무리가 되었다

📚Project

제공해주는 주제가 있었는데 2가지 정도는 확정 주제고(이미 시나리오와 요구사항이 있는것!) 주제 자유해서 총 3가지의 주제를 고를 수 있었다. 주제를 고르는 순서는 랜덤 프로그램을 통해 공정하게 정해졌다.
우리 조는 자유 주제를 선정했고, 자유 주제의 필수 포인트는 컨테이너 기반이었다. 컨테이너 기반으로 주제를 정해야하는 것.
무엇을 할까 하며 폭풍 회의를 하다. 평소에 방송을 실시간으로 보지는 않지만 유튜브 러버로서 트위치라는 플랫폼에서 방송하는 분들의 유튜브를 보다보니 익숙한 시스템인 미션 후원 시스템에 대해서 제안을 했다.
다른 팀원분들의 첨삭을 걸쳐 나쁘지 않다는 이야기가 나오고 얼떨결에 내가 제안한 주제로 결정되었다. 와!🙋‍♂️

📑시스템 분석 및 요구사항

다음은 팀원들과 시스템에 대해서 분석하고 요구사항에 대해서 미팅한 결과이다.

  • 프론트엔드는 일단 배제하였다 : 팀원들의 개발 레벨이 높지 않고, 완성에 집중하기 위해

프로젝트 주제: 미션 관리 서비스

  • 기능 요구사항
    • 개인 사용자와 스트리머는 로그인 기능을 통해 토큰을 발급받을 수 있다.
    • 토큰을 사용하는 로직 구현이 어렵다면 유저 데이터베이스에 접근해서 일치하는 사용자 정보가 있는 것을 확인하는 것으로 대체
    • 개인 사용자 새로운 미션을 입력 및 조회할 수 있다.
    • 스트리머는 미션에 대해 성공 및 실패를 선택할 수 있다.
    • 성공 및 실패가 결정된 경우 개인 사용자는 해당 미션의 결과에 대한 email을 받을 수 있다.
    • 미션을 수행하는 제한시간을 설정할 수 있다.
    • 캐쉬를 충전하는 기능, 미션마다 포인트 설정, 성공하면 지급되야되고 실패 시 반환된다.
    • 이미 생성된 미션에 경우 생성한 유저 이외의 유저도 캐쉬를 추가할 수 있다.
  • 추가적인 사항
    • 해당 미션에 성공할지 못할지에 대한 게임이 있다.
  • 인프라 요구사항
    • 시스템 전반에 가용성, 내결함성, 확장성, 보안성이 고려된 서비스들이 포함되어야한다.
    • 하나 이상의 컴퓨팅 유닛에 대한 CI/CD 파이프라인이 구성되어야한다.
    • 유저 데이터를 저장하고 있는 유저 데이터베이스는 다른 데이터베이스와 분리되어있어야한다.
    • 미션 데이터를 기반으로 미션 성공에 대해 처리하는 시스템은 데이터 유실을 막기 위해 느슨하게 결합되어야한다.
    • 시스템 메트릭 또는 저장된 데이터에 대한 하나 이상의 시각화된 모니터링 시스템이 구축되어야한다.

🖌 다이어그램

위의 시스템 분석과 요구사항을 토대로 다이어그램을 그렸다

아키텍처

다방면으로 생각하면서 여러 아키텍처를 구상해봤었다 중간쯤 되었을 때 당시의 아키텍처

최종 아키텍처와 비슷한 피드백중인 아키텍처 다이어그램

아키텍처를 그려보면서 아쉬웠던게 생각보다 시스템이 간단하였다. 솔직히 말해서 3티어만 해도 충분히 시스템을 만들었다. 그래서 우리조는... 온 몸을 비틀어버렸다

3티어만으로도 충분한 시스템에서 우리 조가 선택한 것은 EDA (Event Driven Architecture) 였다. 이벤트 발생을 트리거로 이벤트 브릿지를 통해 자동으로 람다를 실행하도록 짜보았다. 미션 후원 즉 돈이 중요한 시스템이기에 중복 요청 또는 요청 누락이 있어서는 안되는 점 등을 고려했다. 그래서 현금이 들어가는 빈번한 후원의 경우 nosql 에 별도의 이벤트 로그를 누적하는 방법을 채택하면서 위 다이어그램이 최종적으로 설계되었다.

DB

조금 여러 형태를 지나 나온 형태인데 최종적으로 시스템이 만들어질 때 자잘구리하게 뭔가 다 못들어갔다...

🔧 개발 시작

처음부터 문제다 문제


처음 작업했던 것은 AWS VPC 작업을 통해 네트워크 공간을 개발하는 거였다.

하지만 여기서부터 잘못 되어갔는데... 뒤에 바로 말하겠다.
AWS VPC 작업 할 때 AWS Console 작업이 아닌 바로 Terraform 으로 들어갔다. 이유는 간단했는데 한번에 리소스를 관리할 수 있기 때문이었다.

잘못은 이 프로젝트의 시스템 인프라는 증명이 안되었다는 것
컨셉 증명을 확실히 하고 시스템을 처음에는 콘솔작업으로 한땀한땀 하여 'hello world' 가 나오는 간단한 애플리케이션이라도 배포를 하고 Terraform 으로 VPC 를 만들다 보니 이후에 모든 작업을 바로바로 Terraform 으로 작업을 하게 되었다. 1부터 하여야 할 것을 10부터 진행하고 있었다. 이러한 피드백을 받았을 때 '앗' 하는 충격과 동시에 시무룩해졌었다... 잘못도 잘못이지만... 그래도 노력한 게 있었던지라

그럼에도 시무룩하고 있을 시간은 없었고 작업은 해야했다. 피드백을 적극 수용하여 이후 이미 Terraform 으로 만들어진 리소스는 어쩔 수 없다고 생각하고 AWS Console 로 최대한 증명해가면서 작업하였다.

처음 인프라 담당에서 EKS 파트를 맡았을 때 걱정이 있지만 그림과 같은 인프라 시스템을 구축하였다.

EKS 트러블 슈팅

EKS 작업 중 가장 나를 힘들게 했던것은 EKS Cluster 와 Worker Node 통신 에러 문제였다.
WorkerNode 는 Cluster 와 통신을 해야하는데 자꾸 통신 에러가 뜨면서 Bastion Host 를 통해 WorkerNode Instance 로 접속을 할 수 없었다.
그러던 중에 Worker Node 를 private subnet 중에 첫 번째 subnet 에 고정적으로 넣으면서 통신 에러 없이 Worker Node 가 잘 생성이 되면서 접속이 되었다! 이제 설정을 private subnet 전체를 지정하고 되겠지 기대하면서 다시 돌렸지만 에러가 돌아왔다.
여기서 잘 하시는 분은 바로 문제를 찾겠지만 문제는 네트워크 였었다. 통신 에러니깐 당연히 네트워크 에러가 맞지만 같은 VPC 안이라고 생각했던게 달랐었다. public host 에서 bastion host 가 있는 public subnet 은 private subnet 1번과 NAT Gateway 로 연결되어 있다.

  • bastion host (public subnet 1번) 를 통해 worker node (private subnet 1번) 접속

딱 이렇게 Bastion Host 만을 생각하고 작업을 해서 private subnet 1번에 worker node 를 배치하면 잘 되고 다른 곳은 연결이 안된다. 왜? NAT Gateway 가 private subnet 1번 하고만 연결 되어있으니깐. 또한 Worker Node Group 은 연결된 서브넷에 랜덤한 위치에 Worker Node 를 배치하기 시작한다

이 문제를 알게 되고나서 EKS 가 VPC 외부 시스템인걸 인지하게 되고 NAT 를 전부 연결하게 되면서 문제는 해결 되었다.

kubectl EKS 접속 시 사용자 등록

기본적으로 Amazon EKS 의 경우 Cluster 생성자가 사용자로 지정되어 있으며 master 권한을 가지고 있다. 외부에서 예를 들어 EKS 관리팀의 신입이 kubectl 을 통해 EKS 를 보고 싶을 때 사용자로 등록되어 있지 않다면 Cluster 를 확인할 수 없다.
AWS Cloud 환경을 우리 팀장님의 계정으로 만들었기에 추후 로드 밸런싱 작업을 위해 kubectl 접속이 필요했다. 그러기 위해 다음과 같은 사용자 추가 과정을 팀장님께 부탁을 드렸다.

  • 등록 하고자 하는 AWS IAM 사용자를 만든다.
    • IAM 사용자는 내 AWS 계정에서 만들었다.
    • 해당 IAM 사용자의 ARN 이 필요
  • 공통)
    • # AWS 권한 Config map 확인 명령어를 통해 
      kubectl get -n kube-system configmap/aws-auth
  • 방법1) eksctl 사용
    • eksctl create iamidentitymapping \
        --cluster cluster-name \ # 클러스터 네임 (자신의 AWS 에 EKS 가 존재해야함)
        --region=ap-northeast-2 \
        --arn arn:aws:iam::111122223333:user/ggamzzak \ # 아까 생성한 사용자의 ARN
        --group system:masters \
        --profile my-profile # AWS Configure 를 통해 AWS CLI Access Profile 등록되어 있어야 한다.
  • 방법2)
    • # AWS 권한 Config map 수정 명령어를 통해 수정이 가능하다. 
       kubectl edit -n kube-system configmap/aws-auth
    - ```
    # aws-auth.yml
    mapUsers: |
       - userarn: arn:aws:iam::002672955123:user/test1
         username: test1
         groups:
         - system:masters
         # 여기서 아까 생성한 ARN 을 넣어주고 
       - userarn: arn:aws:iam::002672955123:user/test2
         username: test2
         groups:
         - system:masters  # 해당 유저의 권한을 설정한다.
  • 사용자 추가후 kubectl 로 클러스터를 확인할 수 있다.
    • kubectl 은 관리자 또는 클러스터 생성자로부터 kubeconfig 파일을 받아 연결이 가능하다.

AWS LoadBalancer Controller 자격 증명

https://docs.aws.amazon.com/ko_kr/eks/latest/userguide/aws-load-balancer-controller.html 보면서 따라하였다
쿠버네티스가 직접 관리하는 사용자 계정을 의미하는 service account에 IAM role을 사용하기 위해, 생성한 클러스터(현재 실습에서의 eks-demo)에 IAM OIDC provider가 존재해야 합니다.

  • 클러스터 생성자에게 생성의뢰
# IAM OIDC(OpenID Connect) identity Provider를 생성
eksctl utils associate-iam-oidc-provider \
    --region ap-northeast-2 \
    --cluster mission-link-eks-cluster \
		--approve \
		--profile admin

AWS Load Balancer Controller의 kube-system 네임스페이스에 aws-load-balancer-controller라는 Kubernetes 서비스 계정을 생성하고 IAM 역할의 이름으로 Kubernetes 서비스 계정에 주석을 답니다.

eksctl 또는 AWS CLI 및 kubectl을 사용하여 IAM 역할 및 Kubernetes 서비스 계정을 생성할 수 있습니다.

  • 클러스터 생성자에게 생성의뢰
# Service Account 계정 생성
eksctl create iamserviceaccount \
  --cluster=mission-link-eks-cluster \
  --namespace=kube-system \
  --name=aws-load-balancer-controller \
  --role-name AmazonEKSLoadBalancerControllerRole \
  --attach-policy-arn=arn:aws:iam::123412341234:policy/AWSLoadBalancerControllerIAMPolicy \
  --profile admin \
  --approve

cert-manager다음 방법 중 하나를 사용하여 웹후크에 인증서 구성을 삽입하여 설치합니다 .

  • 노드에 컨테이너 레지스트리에 대한 액세스 권한이 있는 경우 웹후크에 인증서 구성을 삽입하도록 quay.io 설치합니다 .cert-manager
    kubectl apply \
        --validate=false \
        -f https://github.com/jetstack/cert-manager/releases/download/v1.5.4/cert-manager.yaml

AWS LoadBalancer 컨트롤러를 설치합니다.

컨트롤러 사양을 다운로드하십시오. 컨트롤러에 대한 자세한 내용은 GitHub에서 설명서를 참조하십시오.

  • EKS 에 맞는 컨트롤러 버전을 써야한다
  • 프로젝트의 경우 EKS 2.7 컨트롤러

curl -Lo v2_4_7_full.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.7/v2_4_7_full.yaml

파일에 대해 편집한 항목:

  • v2_4_7_full.yaml 파일을 다운로드 한 경우 다음 명령을 실행하여 매니페스트에서 ServiceAccount 섹션을 제거합니다. 이 섹션을 제거하지 않으면 이전 단계에서 서비스 계정에 작성한 필수 주석이 덮어씌워집니다. 이 섹션을 제거하면 컨트롤러를 삭제할 경우 이전 단계에서 생성한 서비스 계정도 유지됩니다.
    sed -i.bak -e '561,569d' ./v2_4_7_full.yaml
    다른 파일 버전을 다운로드한 경우 편집기에서 파일을 열고 다음 줄을 제거합니다.
    apiVersion: v1
    kind: ServiceAccount
    metadata:
      labels:
        app.kubernetes.io/component: controller
        app.kubernetes.io/name: aws-load-balancer-controller
      name: aws-load-balancer-controller
      namespace: kube-system
    ---
  • my-cluster를 해당 클러스터 이름으로 바꿔 파일의 Deployment spec 섹션에 있는 your-cluster-name을 해당 클러스터의 이름으로 바꿉니다.

파일을 적용합니다.

kubectl apply -f v2_4_7_full.yaml

ngressClass 및 IngressClassParams 매니페스트를 클러스터에 다운로드합니다.

curl -Lo v2_4_7_ingclass.yaml https://github.com/kubernetes-sigs/aws-load-balancer-controller/releases/download/v2.4.7/v2_4_7_ingclass.yaml

상기 과정을 다 하였을때 Ingress 를 생성하면 AWS 에서 프로비저닝된 ALB 를 생성해주면서 pod 에 접근이 가능해진다.

💭 회고

드디어 말도 많고 탈도 많은 프로젝트가 끝났다. 너무나도 하고 싶었던 팀 단위의 프로젝트. 0에서 무언가를 쌓아가는건 확실히 어렵다는 것을 알게 되었다.

부트캠프를 하겠다고 마음 먹은지가 1년이 넘는데 당연하게도 백엔드 과정을 밟을 줄 알았었는데, 설마 데브옵스 과정을 밝게 될 줄은 상상도 못했다. 계기는 다니고 있던 회사에서 노후 시스템을 업그레이드 하면서 리눅스 환경에서 서버 세팅하고 네트워크 등록하고 하는 작업이 생각보다 재밌었다. 테스트로 서버가 잘 올라갔는지 테스트 할 때 잘 올라간 걸 확인하는 순간 그 뿌듯함이란...

이번 프로젝트에서 아쉬운점이 없지는 않다. 뭔가 더 데브옵스! 하는 아키텍처를 짰으면 하는데 처음에도 글에 썼듯이 온 몸 비틀기를 한 아키텍처가 나와서 아쉬웠고... 아이디어가 더 번쩍였으면 좋았을 거고... 중간중간 정리를 하는 습관을 더 들여야겠다는 생각도 들고...
앞으로 더 잘해가야겠다고 다짐하게 되었다.

profile
욕심 많은 주니어 개발자입니다.

0개의 댓글