AWS EKS와 CodeCommit으로 CI/CD 구축하기

김철기·2022년 7월 5일
1

Kubernetes

목록 보기
4/5
post-thumbnail

안녕하세요. Gameeye에서 deeplol.gg 서비스를 개발 중인 김철기입니다.
클라우드 서버 인프라 구축, 백엔드 개발, 딥러닝 모델 연구를 담당하고 있습니다.

목차

EKS 접근 권한 설정

  • EKS 접근을 위한 IAM Role 생성
  • aws-auth에 권한 추가

CodeCommit

  • 파일 생성 및 업로드
  • AWS CodeBuild 생성
  • AWS CodePipeline 생성

결과 확인

  • 배포 성공화면
  • 웹서비스 화면

이번 포스팅에서는 자동으로 소스를 빌드하고 AWS ECR에 푸쉬한 뒤 쿠버네티스에 배포하는 내용을 다루겠습니다. 쿠버네티스 환경 세팅과 도메인 관리, AWS ECR 사용법은 이전 포스팅에서 다뤘으니 참고해주시기 바랍니다.

EKS 접근 권한 설정

EKS 접근을 위한 IAM Role 생성

CodeBuild에서 EKS에 접근하기 위해서는 권한이 필요합니다. CodeBuild 생성 단계에서 자동으로 생성하게 할수도 있으나 해당 포스팅에서는 미리 생성 후 진행하도록 하겠습니다.
인라인 정책과 신뢰 관계에 아래 내용을 설정하여 Role을 생성해줍니다.

  • 인라인 정책
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": "eks:DescribeCluster",
            "Resource": "*"
        }
    ]
}
  • 신뢰 관계
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Principal": {
                "Service": "codebuild.amazonaws.com"
            },
            "Action": "sts:AssumeRole"
        }
    ]
}

aws-auth에 권한 추가

이제 위에서 생성한 권한을 EKS에게 알려줘야합니다.
아래 명령어로 aws-auth를 수정합니다.

kubectl -n kube-system edit cm aws-auth

기존 내용을 아래 내용으로 수정해줍니다.
🚨 위에서 생성한 Role은 Service Role이지만 service-role을 제외한 arn을 입력해줘야합니다.
arn:aws:iam::{account_id}:role/service-role/codebuild-EKS-DEPLOY-service-role (x)
arn:aws:iam::{account_id}:role/codebuild-EKS-DEPLOY-service-role (o)

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::${ACCOUNT_ID}:role/myAmazonEKSNodeRole
      username: system:node:{{EC2PrivateDNSName}}
    - groups:
        - system:masters
      rolearn: 위에서 생성한 Role의 ARN
      username: 위에서 생성한 Role의 NAME
kind: ConfigMap
metadata:
  annotations:
  name: aws-auth
  namespace: kube-system
  uid: xxxx-xxxx-xxxx-xxxx-xxxx

CodeCommit

파일 생성 및 업로드

AWS CodeCommit 콘솔에서 리포지토리를 생성합니다.

buildspec.yml 파일을 작성합니다.
kubectl 설치, ecr 로그인, docker 빌드, eks deploy 과정이 포함되어 있습니다.
(해당 포스팅에서는 dockerfile을 따로 작성하지 않고 예제로 사용해온 슈퍼마리오 이미지를 사용합니다. 직접 dockerfile을 만들어서 빌드하실 분은 주석처리된 2줄을 사용하시면 됩니다.)

version: 0.2

phases:
  install:
    runtime-versions:
      docker: 19
    commands:
      - echo Install Kubectl
      - echo ---------------------------------
      - curl -o kubectl https://amazon-eks.s3.us-west-2.amazonaws.com/1.19.6/2021-01-05/bin/linux/amd64/kubectl
      - chmod +x ./kubectl
      - mv ./kubectl /usr/local/bin/kubectl
      - mkdir ~/.kube
      - aws sts get-caller-identity
      - aws eks --region ap-northeast-2 update-kubeconfig --name {cluster_name}
      - echo ---------------------------------
  pre_build:
    commands:
      - echo ENV Values
      - echo ---------------------------------
      - echo $AWS_DEFAULT_REGION
      - echo $AWS_ACCOUNT_ID
      - echo $IMAGE_REPO_NAME
      - echo $IMAGE_TAG
      - echo $CODEBUILD_BUILD_NUMBER
      - echo ---------------------------------
      - echo Logging in to Amazon ECR...
      - aws ecr get-login-password --region $AWS_DEFAULT_REGION | docker login --username AWS --password-stdin $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com
   build:
     commands:
      - echo Build started on `date`
      - echo Application Build
      - echo ---------------------------------
      - echo GO Build Start
      - echo Go Build Code In here
      - echo GO Build Stop
      - echo ---------------------------------
      - echo Start Docker
      - docker version
      - echo ---------------------------------
      - echo Building the Docker image...   
      - echo ---------------------------------
      - docker pull pengbai/docker-supermario
      - docker tag pengbai/docker-supermario $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER
#      - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER .
#      - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER
      - echo ---------------------------------
      - echo Pushing the Docker image...
      - echo ---------------------------------
      - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER
  post_build:
    commands:
      - AWS_ECR_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG-$CODEBUILD_BUILD_NUMBER
      - DATE=`date`
      - echo Build completed on $DATE
      - sed -i 's#AWS_ECR_URI#'"$AWS_ECR_URI"'#' ./eks-app-deploy.yml
      - kubectl apply -f ./eks-app-deploy.yml

eks-app-deploy.yml 파일을 작성합니다. AWS_ECR_URI 부분은 buildspec.yml 파일에서 ECR URI로 치환해줍니다.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: mario
  labels:
    app: mario
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mario
  template:
    metadata:
      labels:
        app: mario
    spec:
      containers:
      - name: mario
        image: AWS_ECR_URI
---
apiVersion: v1
kind: Service
metadata:
   name: mario
   annotations:
     external-dns.alpha.kubernetes.io/hostname: {도메인명}
spec:
  selector:
    app: mario
  ports:
  - port: 80
    protocol: TCP
    targetPort: 8080
  type: LoadBalancer

dev 브랜치를 생성해줍니다.

CodeBuild 생성

CodeBuild 프로젝트를 생성해줍니다.
프로젝트 이름을 정해주고,

빌드할 소스의 위치와 브랜치 조건을 설정합니다.

환경은 관리형 이미지, 리눅스, 최신 버전이미지를 선택하고 앞에서 생성한 역할 ARN을 설정해줍니다.
🚨 이미지를 aws/codebuild/amazonlinux2-x86_64-standard:4.0으로 사용할 때 docker version을 19로 설정하지 못하는 이슈가 있었습니다. 3.0으로 바꿔 19로 사용해주시거나 4.0으로 20버전을 사용해주세요.
(buildspec.yml 파일의 docker: 19 부분입니다.)

phases:
  install:
    runtime-versions:
      docker: 19

추가 구성에서 환경 변수를 설정해줍니다. region과 id는 본인 계정값으로 입력하시면 됩니다.

마지막으로 Buildspec 부분은 buildspec 파일 사용을 선택하시고 빌드 프로젝트 생성 버튼을 누르시면 됩니다.

AWS CodePipeline 생성

콘솔에서 파이프라인 생성 버튼을 눌러 파이프라인을 생성해줍니다.
먼저 파이프라인 이름을 입력 후 다음 버튼을 클릭합니다.

소스 공급자를 CodeCommit으로 설정하고 앞서 생성한 리포지토리와 브랜치를 선택해줍니다.

빌드 스테이지에는 CodeBuild 프로젝트를 선택해줍니다.

CodeBuild에 배포 단계가 포함되어 있으므로 배포 스테이지는 건너뛰기 해줍니다.

검토 페이지에서 파이프라인 생성 버튼을 클릭하는 것으로 파이프라인 생성을 완료합니다.

결과 확인

배포 성공 화면

배포에 성공하면 CodeBuild 프로젝트의 빌드 상태가 성공함으로 변경되고 성공 로그가 출력됩니다.

파이프라인에서도 성공이라는 표시가 출력됩니다.

웹서비스 화면

설정한 도메인으로 접근하면 빌드된 이미지의 서비스가 정상적으로 출력되는 것을 확인할 수 있습니다.

마무리

드디어 CI/CD까지 해보았습니다👍 포스팅에는 테스트 단계가 누락되어서 CI까지 완벽하게 수행했다고 보기는 어렵지만 코드 병합과 디플로이 자동화는 해당 포스팅으로 충분히 따라해보실 수 있습니다.
이후로는 오토스케일링을 이용한 Node, Pod 리소스 관리와 대시보드, airflow 또는 kubeflow를 이용한 배치 관리를 정리해볼 생각입니다. 아직도 갈길이 멀지만 차근차근 정리해보도록 하겠습니다.
포스팅 내용중 문제가 있거나 궁금한 부분이 있으시면 답글 남겨주세요🙏

profile
Deepveloper, deeplol.gg, fleaman.shop

0개의 댓글