Q. 프로젝트가 끝난 지금, 어떤가요?
A. 으아ㅏㅏㅏㅏㅏ
지금의 나의 상태. 완성? 미완성? 그 애매한 경계에서 프로젝트가 마무리가 되었다
제공해주는 주제가 있었는데 2가지 정도는 확정 주제고(이미 시나리오와 요구사항이 있는것!) 주제 자유해서 총 3가지의 주제를 고를 수 있었다. 주제를 고르는 순서는 랜덤 프로그램을 통해 공정하게 정해졌다.
우리 조는 자유 주제를 선정했고, 자유 주제의 필수 포인트는 컨테이너 기반이었다. 컨테이너 기반으로 주제를 정해야하는 것.
무엇을 할까 하며 폭풍 회의를 하다. 평소에 방송을 실시간으로 보지는 않지만 유튜브 러버로서 트위치라는 플랫폼에서 방송하는 분들의 유튜브를 보다보니 익숙한 시스템인 미션 후원 시스템에 대해서 제안을 했다.
다른 팀원분들의 첨삭을 걸쳐 나쁘지 않다는 이야기가 나오고 얼떨결에 내가 제안한 주제로 결정되었다. 와!🙋♂️
다음은 팀원들과 시스템에 대해서 분석하고 요구사항에 대해서 미팅한 결과이다.
프로젝트 주제: 미션 관리 서비스
위의 시스템 분석과 요구사항을 토대로 다이어그램을 그렸다
아키텍처를 그려보면서 아쉬웠던게 생각보다 시스템이 간단하였다. 솔직히 말해서 3티어만 해도 충분히 시스템을 만들었다. 그래서 우리조는... 온 몸을 비틀어버렸다
3티어만으로도 충분한 시스템에서 우리 조가 선택한 것은 EDA (Event Driven Architecture) 였다. 이벤트 발생을 트리거로 이벤트 브릿지를 통해 자동으로 람다를 실행하도록 짜보았다. 미션 후원 즉 돈이 중요한 시스템이기에 중복 요청 또는 요청 누락이 있어서는 안되는 점 등을 고려했다. 그래서 현금이 들어가는 빈번한 후원의 경우 nosql 에 별도의 이벤트 로그를 누적하는 방법을 채택하면서 위 다이어그램이 최종적으로 설계되었다.
처음 작업했던 것은 AWS VPC 작업을 통해 네트워크 공간을 개발하는 거였다.
하지만 여기서부터 잘못 되어갔는데... 뒤에 바로 말하겠다.
AWS VPC 작업 할 때 AWS Console 작업이 아닌 바로 Terraform 으로 들어갔다. 이유는 간단했는데 한번에 리소스를 관리할 수 있기 때문이었다.
잘못은 이 프로젝트의 시스템 인프라는 증명이 안되었다는 것
컨셉 증명을 확실히 하고 시스템을 처음에는 콘솔작업으로 한땀한땀 하여 'hello world' 가 나오는 간단한 애플리케이션이라도 배포를 하고 Terraform 으로 VPC 를 만들다 보니 이후에 모든 작업을 바로바로 Terraform 으로 작업을 하게 되었다. 1부터 하여야 할 것을 10부터 진행하고 있었다. 이러한 피드백을 받았을 때 '앗' 하는 충격과 동시에 시무룩해졌었다... 잘못도 잘못이지만... 그래도 노력한 게 있었던지라
그럼에도 시무룩하고 있을 시간은 없었고 작업은 해야했다. 피드백을 적극 수용하여 이후 이미 Terraform 으로 만들어진 리소스는 어쩔 수 없다고 생각하고 AWS Console 로 최대한 증명해가면서 작업하였다.
처음 인프라 담당에서 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 만을 생각하고 작업을 해서 private subnet 1번에 worker node 를 배치하면 잘 되고 다른 곳은 연결이 안된다. 왜? NAT Gateway 가 private subnet 1번 하고만 연결 되어있으니깐. 또한 Worker Node Group 은 연결된 서브넷에 랜덤한 위치에 Worker Node 를 배치하기 시작한다
이 문제를 알게 되고나서 EKS 가 VPC 외부 시스템인걸 인지하게 되고 NAT 를 전부 연결하게 되면서 문제는 해결 되었다.
기본적으로 Amazon EKS 의 경우 Cluster 생성자가 사용자로 지정되어 있으며 master 권한을 가지고 있다. 외부에서 예를 들어 EKS 관리팀의 신입이 kubectl 을 통해 EKS 를 보고 싶을 때 사용자로 등록되어 있지 않다면 Cluster 를 확인할 수 없다.
AWS Cloud 환경을 우리 팀장님의 계정으로 만들었기에 추후 로드 밸런싱 작업을 위해 kubectl 접속이 필요했다. 그러기 위해 다음과 같은 사용자 추가 과정을 팀장님께 부탁을 드렸다.
# AWS 권한 Config map 확인 명령어를 통해
kubectl get -n kube-system configmap/aws-auth
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 등록되어 있어야 한다.
# 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 # 해당 유저의 권한을 설정한다.
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에서 설명서를 참조하십시오.
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년이 넘는데 당연하게도 백엔드 과정을 밟을 줄 알았었는데, 설마 데브옵스 과정을 밝게 될 줄은 상상도 못했다. 계기는 다니고 있던 회사에서 노후 시스템을 업그레이드 하면서 리눅스 환경에서 서버 세팅하고 네트워크 등록하고 하는 작업이 생각보다 재밌었다. 테스트로 서버가 잘 올라갔는지 테스트 할 때 잘 올라간 걸 확인하는 순간 그 뿌듯함이란...
이번 프로젝트에서 아쉬운점이 없지는 않다. 뭔가 더 데브옵스! 하는 아키텍처를 짰으면 하는데 처음에도 글에 썼듯이 온 몸 비틀기를 한 아키텍처가 나와서 아쉬웠고... 아이디어가 더 번쩍였으면 좋았을 거고... 중간중간 정리를 하는 습관을 더 들여야겠다는 생각도 들고...
앞으로 더 잘해가야겠다고 다짐하게 되었다.