2024-06-04 20:49:09 [✖] AWS::IAM::Role/ServiceRole: CREATE_FAILED – "Resource handler returned message: \"Encountered a permissions error performing a tagging operation, please add required tag permissions. See https://repost.aws/knowledge-center/cloudformation-tagging-permission-error for how to resolve. Resource handler returned message: \"User: arn:aws:iam::566620743708:user/hojin is not authorized to perform: iam:CreateRole on resource: arn:aws:iam::566620743708:role/eksctl-eks-work-cluster-cluster-ServiceRole-o9PL6esmhBCb because no identity-based policy allows the iam:CreateRole action (Service: Iam, Status Code: 403, Request ID: 3218d612-0915-459c-a593-168f0254df9e)\"\" (RequestToken: 3073b698-9f51-d355-9de0-cdd413cc0b44, HandlerErrorCode: UnauthorizedTaggingOperation)"
2024-06-04 20:49:09 [!] 1 error(s) occurred and cluster hasn't been created properly, you may wish to check CloudFormation console
현재 로컬에서 root 계정이 아닌 hojin 계정을 생성해 사용중인데 해당 계정에 CreateRole이 없는 모양이었다.
따라서 aws configure 명령어를 통해 user를 Administrator로 전환하고 진행했다.
그 다음에 문제는 creating CloudFormation stack "eksctl-eks-work-cluster-cluster": operation error CloudFormation: CreateStack, https response error StatusCode: 400, RequestID: bdaf29da-cce6-43f1-a9b5-3cf8565efe00, AlreadyExistsException: Stack [eksctl-eks-work-cluster-cluster] already exists
따라서 해당 stack을 제거하고 진행했다.
EKS 클러스터 구축
워커 노드 구축 이 완료됐다.
kubeconfig 설정
eksctl은 EKS 클러스터 구축 중에 kubeconfig파일을 자동으로 업데이트하는데 kubeconfig파일은 쿠버네티스 클라이언트인 kubectl이 이용할 설정 파일로 접속 대상 쿠버네티스 클러스터의 접속 정보(컨트롤 플레인 URL, 인증 정보, 쿠버네티스 네임스페이스)를 저장하고 있다.
AWS CLI를 호출해 인증하기 위한 설정을 kubeconfig에 포함할 수 있다
kubectl: 쿠버네티스 클러스터에 명령을 내리는 CLI로 쿠버네티스는 오브젝트 관리를 위해 쿠버네티스 API를 사용하는데 kubectl CLI를 사용하면 해당 명령어가 쿠버네티스 API를 호출해 관련 동작을 수행한다.
kubectl config get-contexts
출력 결과에서 컨텍스트가 활성화되어 있음을 알 수 있고, 노드 상태를 확인할 수 있다.
클러스터의 동작을 확인해보면
kubectl apply -f 02_nginx_k8s.yaml
pod/nginx-pod created
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-pod 1/1 Running 0 96s
정상적으로 pod가 생성되었음을 알 수 있다.
kubectl port-forward nginx-pod 8080:80
Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80
2.3 데이터베이스 설정
예제 애플리케이션 DB 생성, DDL 적용 등 애플리케이션에서 사용하기 위한 설정을 수행한다.
DB와 Bastion host 구축
Session Manager를 이용한 Bastion host 구축
bastion host에 필요한 도구 설치
bastion host 상에 깃 리포지터리 클론
DB 접속과 DDL 및 예제 데이터 불러오기
RDS의 PostgreSQL을 사용하고, 다중화 없이 단일 가용 영역으로 구축한다.
기존 리소스 생성과 마찬가지로 CloudFormation에 미리 준비된 템플릿을 업로드해 생성한다.
하지만 기존의 템플릿이 에러로 실행되지 않아
Resource handler returned message: "RDS does not support creating a DB instance with the following combination: DBInstanceClass=db.t2.micro, Engine=postgres, EngineVersion=11.22, LicenseModel=postgresql-license. For supported combinations of instance class and database engine version, see the documentation. (Service: Rds, Status Code: 400, Request ID: ac86e4f7-6daf-45c9-aea4-3fd0f53e7f6c)" (RequestToken: 77f0f6dc-85cc-f9de-1ede-6aa49cb7e339, HandlerErrorCode: InvalidRequest)
kubectl apply 명령으로 적용한 매니페스트 파일은 디플로이먼트라는 종류의 오브젝트를 생성하기 위한 것으로
디플로이먼트는 컨테이너를 배포, 디프로이먼트 뒤에 레플리카셋이 생성, 레플리카셋 뒤에는 파드가 생성된다. 아래에 결과가 있다.
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/backend-app-59b66ccd45-fmz8k 1/1 Running 0 9m59s
pod/backend-app-59b66ccd45-q8pxk 1/1 Running 0 9m59s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/backend-app 2/2 2 2 9m59s
NAME DESIRED CURRENT READY AGE
replicaset.apps/backend-app-59b66ccd45 2 2 2 9m59s
API 애플리케이션 외부 공개
API 애플리케이션 배포가 끝났지만 아직 외부에서는 호출이 불가능하다. 쿠버네티스는 배포된 파드를 외부에 공개하기 위해 서비스라는 리소스가 준비되어 있다. 여기서는 로드밸런서를 이용한다.
매니페스트 파일을 이용해 배포해보자
kubectl apply -f 23_service_backend-app_k8s.yaml
service/backend-app-service created
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/backend-app-59b66ccd45-fmz8k 1/1 Running 0 16m
pod/backend-app-59b66ccd45-q8pxk 1/1 Running 0 16m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend-app-service LoadBalancer 10.100.118.202 ac415c77bb14c4c45a1ad43a51570d97-482146193.ap-northeast-2.elb.amazonaws.com 8080:31069/TCP 3m2s
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/backend-app 2/2 2 2 16m
NAME DESIRED CURRENT READY AGE
replicaset.apps/backend-app-59b66ccd45 2 2 2 16m
aws s3 sync dist s3://eks-work-frontend-hj-bk-1 --delete --include "*" --acl public-read
upload: dist/.nojekyll to s3://eks-work-frontend-hj-bk-1/.nojekyll
upload: dist/index.html to s3://eks-work-frontend-hj-bk-1/index.html
upload: dist/_nuxt/870f68b.js to s3://eks-work-frontend-hj-bk-1/_nuxt/870f68b.js
upload: dist/_nuxt/41092ad.js to s3://eks-work-frontend-hj-bk-1/_nuxt/41092ad.js
upload: dist/200.html to s3://eks-work-frontend-hj-bk-1/200.html
upload: dist/_nuxt/LICENSES to s3://eks-work-frontend-hj-bk-1/_nuxt/LICENSES
upload: dist/favicon.ico to s3://eks-work-frontend-hj-bk-1/favicon.ico
upload: dist/_nuxt/d3f4395.js to s3://eks-work-frontend-hj-bk-1/_nuxt/d3f4395.js
upload: dist/v.png to s3://eks-work-frontend-hj-bk-1/v.png
upload: dist/_nuxt/b171587.js to s3://eks-work-frontend-hj-bk-1/_nuxt/b171587.js
upload: dist/_nuxt/0567ccc.js to s3://eks-work-frontend-hj-bk-1/_nuxt/0567ccc.js
upload: dist/regionDetail/index.html to s3://eks-work-frontend-hj-bk-1/regionDetail/index.html
upload: dist/_nuxt/9c2283f.js to s3://eks-work-frontend-hj-bk-1/_nuxt/9c2283f.js
왜인지 모르겠지만 cloudfront url로 접속했을때는 에러가 떴다.
2.6 배치 애플리케이션 빌드와 배포
수행할 작업은 다음과 같다.
배치 애플리케이션 빌드
배치 애플리케이션용 ECR 레포지터리 생성
배치 애플리케이션 컨테이너 이미지 푸시
배치 애플리케이션 파일 다운로드를 위한 S3 버킷 생성
배치 애플리케이션용 컨피그맵 생성
배치 애플리케이션용 시크릿 생성
배치 애플리케이션 입력 파일을 S3에 업로드
스케줄 실행을 위한 크론잡 등록
배치 애플리케이션은 자바와 스프링 부트로 구축한 애플리케이션으로 동작시 환경 변수로 설정된 S3 버킷의 파일을 다운롣하고 파일 내용을 DB에 등록하고 쿠버네티스의 크론잡을 이용해 5분에 1번 동작시키도록 설정한다.
애플리케이션 빌드 및 컨테이너 이미지 생성
소스 코드 빌드
batch-app 디렉토리로 이동해 gradle build를 실행해주고 Dockerfile을 이용해 컨테이너 이미지를 생성한다.
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/backend-app-59b66ccd45-fmz8k 1/1 Running 0 7h9m
pod/backend-app-59b66ccd45-q8pxk 1/1 Running 0 7h9m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend-app-service LoadBalancer 10.100.118.202 ac415c77bb14c4c45a1ad43a51570d97-482146193.ap-northeast-2.elb.amazonaws.com 8080:31069/TCP 6h55m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/backend-app 2/2 2 2 7h9m
NAME DESIRED CURRENT READY AGE
replicaset.apps/backend-app-59b66ccd45 2 2 2 7h9m
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/batch-app */5 * * * * False 0 <none> 101s
cron job이 실행중임을 알 수 있다.
kubectl get all
NAME READY STATUS RESTARTS AGE
pod/backend-app-59b66ccd45-fmz8k 1/1 Running 0 7h10m
pod/backend-app-59b66ccd45-q8pxk 1/1 Running 0 7h10m
pod/batch-app-28626500-lmcdm 0/1 CrashLoopBackOff 1 (14s ago) 30s
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/backend-app-service LoadBalancer 10.100.118.202 ac415c77bb14c4c45a1ad43a51570d97-482146193.ap-northeast-2.elb.amazonaws.com 8080:31069/TCP 6h57m
NAME READY UP-TO-DATE AVAILABLE AGE
deployment.apps/backend-app 2/2 2 2 7h10m
NAME DESIRED CURRENT READY AGE
replicaset.apps/backend-app-59b66ccd45 2 2 2 7h10m
NAME SCHEDULE SUSPEND ACTIVE LAST SCHEDULE AGE
cronjob.batch/batch-app */5 * * * * False 1 30s 3m7s
NAME COMPLETIONS DURATION AGE
job.batch/batch-app-28626500 0/1 30s 30s
5분 후 배치 어플리케이션이 실행됐음을 알 수 있다.
2.7 예제 애플리케이션 환경 삭제
리소스 삭제는 구축의 반대이며 쿠버네티스상의 리소스는 한 번에 삭제한다.
쿠버네티스상의 애플리케이션과 서비스 삭제
EKS 클러스터 삭제
배치 애플리케이션용 S3 버킷 비우기
프런트엔드 애플리케이션용 S3 버킷 비우기
배치 애플리케이션용 S3 버킷 삭제
프런트엔드 애플리케이션용 S3 버킷과 CloudFront 배포 삭제
데이터베이스와 배스천 호스트 삭제
기본 리소스 삭제
아래는 성공한 화면이다.
해당 를 참고하자
다음 를 보고 credsStore -> credStore로 변경해 해결하긴 했지만 원인은 파악해봐야 하겠다.