EKS 및 CodePipeline 활용 CI/CD 환경 구축

1. CI/CD 프로젝트 개요

1.1) CI/CD란?

CI (Continuous Integration)

  • 어플리케이션의 새로운 코드 변경사항이 정기적으로 빌드 및 테스트되어 공유 레포지토리에 통합되는 것

CD (Continuous Delivery & Continuous Deployment)

  • Continuos Delivery : 공유 레포지토리에 자동으로 Release 되는 것
  • Continuous Deployment : Production 레벨까지 자동으로 배포하는 것

1.2) 프로젝트 목적

  • Git Hub와 CodeBuild를 활용한 CodePipeline를 통해 CI(Continuous Integration) 환경을 구축한다.
  • CodeBuild시 생성되는 도커 이미지를 ECR에 저장하고 해당 이미지를 EKS 환경에 배포하여 CD(Continuous Delivery&Continuous Deployment) 환경을 구축한다.
    • 이때 EKS 환경은 eksctl을 활용하여 구축한다.
  • CodePipeline에 상태 변화 트리거 설정을 통해 Slack 모니터링 시스템을 구축한다.

1.3) 프로젝트 구성도

2. Hands On 실습

2.1) 사전 준비 환경

AWS CLI 설치

kubectl 설치

  • k8s에서 cluster를 제어하기 위한 커맨드라인 도구
  • 로컬에서 k8s cluster를 제어해야하여 kubectl 설치 필요
  • 설치 프로세스
# 1.26 버전
$ curl.exe -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.26.9/2023-10-17/bin/windows/amd64/kubectl.exe

# 1.23 버전
$ curl.exe -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.23.17/2023-11-14/bin/windows/amd64/kubectl.exe

# 1.28 버전
$ curl.exe -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.28.3/2023-11-14/bin/windows/amd64/kubectl.exe

  • kubectl 설치 이상유무 확인
  • # kubectl 버전
    $ kubectl version

    eksctl 설치

    • eksctl cli를 활용한 EKS 인프라 환경 구성 목적
    • Powershell (관리자 권한)으로 설치 권장
    # chocolate 명령어 사용할 수 있도록 사전작업 필요
    $ choco install -y eksctl
    • eksctl 설치 확인
    # gitbash에서 설치확인 명령어 입력
    $ eksctl version
    

    2.2) EKS 인프라 구성

    EKS Cluster_IAM 역할 생성

    • 경로
      • [AWS Management Console] > [IAM] > [역할] > [역할 만들기]
        • [사용 사례] > [EKS] > [EKS – Cluster] 선택
        • AmazonEKSClusterPolicy 권한 부여

    EKS Worker Node_IAM 역할 생성

    • 경로
      • [AWS Management Console] > [IAM] > [역할] > [역할 만들기]
        • [사용 사례] > [EC2]
          • 적용권한
            • AmazonEKSWorkerNodePolicy
            • AmazonEKS_CNI_Policy
            • AmazonEC2ContainerRegistryReadOnly

    workernode 생성용 키페어 생성

    # /home/[관리자명]/.ssh 폴더 이동
    cd /home/[관리자명]/.ssh
    
    # 키생성
    $ ssh-keygen
    

    공개키 파일 AWS 인프라상 업로드

    $ aws ec2 import-key-pair --key-name "[생성할 키페어명]" --public-key-material fileb://~/.ssh/[생성된 공개키]
    

    eks cluster 및 workernode 생성

    • eksctl cli 활용해 EKS Cluster 및 Workernode 생성
    • 해당 리소스들은 Cloudformation을 통해 자동 생성된다.
    # EKS 클러스터 및 워커노드 생성
    $ eksctl create cluster --name [클러스터명] --region ap-northeast-2 --nodegroup-name [노드그룹명] --node-type t3.medium --nodes [워커노드 기본값] --nodes-min [워커노드 최소값] --nodes-max [워커노드 최대값] --ssh-access --ssh-public-key [공개키명] --managed
    

    K8S-AWS EKS 연동

    • EKS Cluster와 K8S간 연동을 위해선 아래의 명령어로 Synchronize 작업이 필요하다.
    $ aws eks --region [eks 생성리전] update-kubeconfig --name [생성한 eks cluster명]
    
    • K8S-AWS EKS Cluster간 연동 확인
    # EKS 모든 Pod 정보조회
    $ kubectl get pod --all-namespaces
    
    • K8S-AWS EKS Worker Node간 연동 확인
    # EKS Worker Node 조회
    $ kubectl get node
    

    2.3) AWS Pipeline 활용 CI/CD 구축

    Git Repository 생성

    • 생성된 레포지토리 경로를 복사한다.
      • CodeBuild 설정 시 GitHub간 연동을 위해 사용

    AWS Code Build 설정

    • 경로
      • [AWS Console] > [CodeBuild] > [Build Projects] > [Create Build Project]
    • 설정
      • 프로젝트 이름 : [프로젝트명]
      • 리포지토리 : OAuth를 사용하여 연결
        • GitHub에 연결 Click
    • GitHub 대상 AWS CodeBuild 인증
    • 설정
      • 소스 공급자 : GitHub
      • 리포지토리 : 본인 GitHub 계정의 리포지토리 Click
      • GitHub 리포지토리 : [GitHub에서 생성한 리포지토리 URL 붙여넣기]
    • 설정
      • 환경
        • 관리형 이미지
        • 운영체제 : Amazon Linux
        • 런타임 : Standard
        • 이미지 : amazonlinux2-aarch64-standard:2.0
        • 이미지 버전 : 최신 이미지 사용
        • 권한있음 : 도커 이미지를 활횽한 빌드 진행을 위해 체크
        • 서비스 역할 : 새 서비스 역할
    • 설정
      • 추가구성
        • VPC : EKS에 사용되는 VPC Click
        • Subnet : EKS에 사용되는 Subnet Click
        • 보안그룹 : deafault sg
    • 설정
      • 환경변수
    # buildspec.yaml 파일 빌드 시 사용되는 변수값 설정
    AWS_DEFAULT_REGION : [기본 리전명]
    IMAGE_REPO_NAME : [레포지토리 이미지명]
    IMAGE_TAG : [이미지 태그명]
    AWS_ACCOUNT_ID : [Account ID]
    AWS_ACCESS_KEY_ID : [AWS CONFIG 설정을 위한 액세스키값]
    AWS_SECRET_ACCESS_KEY : [AWS CONFIG 설정을 위한 시크릿키값]
    
    • 설정
      • 빌드사양 : buildspec 파일 사용
      • 빌드스펙 파일명 : buildspec.yaml

    Amazon ECR 생성

    • 빌드 시 생성되는 도커 이미지를 저장할 ECR 레포지토리를 미리 생성한다.
    • 경로
      • [AWS Console]> [Amazon ECR] > [리포지토리] > [리포지토리 생성]
    • 설정
      • 일반설정
        • 표시 여부 설정 : [프라이빗]
        • 리포지토리 이름 : [ECR에서 사용할 리포지토리명]

    AWS CodePipeline 생성

    • 경로
      • [AWS Console] > [개발자 도구] > [CodePipeline] > [파이프라인 생성]
    • 설정
      • 파이프라인 유형 : V2
      • 서비스 역할 : 새 서비스 역할 Click
    • 설정
      • 소스 스테이지 추가
        • 소스 공급자 : [GitHub(버전1)]
        • GitHub에 연결 Click 후 연동설정 허용
        • 리포지토리 : [GitHub에 연결된 리포지토리] 선택
        • 브랜치 : [GitHub에 연결된 브랜치] 선택
        • 변경 감지 옵션 : [GitHub 웹후크(권장)]
    • 설정
      • 빌드 스테이지 추가
        • 빌드 공급자 : [빌드 서비스 선택]
        • 리전 : [빌드할 리전 선택]
        • 프로젝트 이름 : [빌드 프로젝트명 기재]

    GitHub 레포지토리에 빌드할 파일 업로드

    • GitHub-GitBash간 연동
    # git bash 명령어
    $ git remote add origin [github 레포지토리주소]
    
    • 소스 반영
    # git stage 추가
    $ git add [파일명]
    
    # stage 추가된 파일 commit
    git commit -m "[커밋내용]"
    
    # 추가된 파일 브랜치에 반영
    git push origin [branch명]
    

  • 배포 파일 세부정보
  • # buildspec.yaml (경로 : Git 레포지토리 root 디렉토리상 업로드)
    
    version: 0.2
    phases:
      install:
        runtime-versions:
          docker: 19
        commands:
          - AWS_ACCESS_KEY_ID=$AWS_ACCESS_KEY_ID
          - AWS_SECRET_ACCESS_KEY=$AWS_SECRET_ACCESS_KEY
          - AWS_ACCOUNT_ID=$AWS_ACCOUNT_ID
          - AWS_REGION=$AWS_DEFAULT_REGION
          - curl -O https://s3.us-west-2.amazonaws.com/amazon-eks/1.27.6/2023-10-17/bin/linux/arm64/kubectl
          - chmod +x ./kubectl
          - mv ./kubectl /usr/local/bin/kubectl
          - mkdir ~/.kube
          - aws eks --region $AWS_DEFAULT_REGION update-kubeconfig --name eks
          - kubectl get pod --all-namespaces
      pre_build:
        commands:
          - 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 Building the Docker image
          - docker build -t $IMAGE_REPO_NAME:$IMAGE_TAG .
          - docker tag $IMAGE_REPO_NAME:$IMAGE_TAG $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
          - docker push $AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
    
      post_build:
        commands:
          - AWS_ECR_URI=$AWS_ACCOUNT_ID.dkr.ecr.$AWS_DEFAULT_REGION.amazonaws.com/$IMAGE_REPO_NAME:$IMAGE_TAG
          - DATE='date'
          - echo Build completed on $DATE
          - sed -i.bak 's#AWS_ECR_URI#'"$AWS_ECR_URI"'#' ./EKS/Deployment.yaml
          - sed -i.bak 's#DATE_STRING#'"$DATE"'#' ./EKS/Deployment.yaml
          - kubectl apply -f ./EKS/Deployment.yaml
          - kubectl apply -f ./EKS/Service.yaml
    
    # Dockerfile (경로 : Git 레포지토리 root 디렉토리상 업로드)
    
    FROM ubuntu:18.04
    RUN apt-get update
    RUN apt-get install apache2 -y
    ADD index.html /var/www/html/index.html
    EXPOSE 80
    CMD ["apachectl", "-D", "FOREGROUND"]
    # index.html (경로 : Git 레포지토리 root 디렉토리상 업로드)
    
    <html>
    <body>
    <h1>KICO CICD Test</h1>
    <h2>KICO Cloud Team MSP</h2>
    </body>
    </html>
    # Deployment.yaml (경로 : /EKS/Deployment.yaml)
    
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: eks-deploy
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: eks-test
      template:
        metadata:
          labels:
            app: eks-test
        spec:
          containers:
            - name: eks-test
              image: AWS_ECR_URI
              ports:
                - containerPort: 80
              imagePullPolicy: Always
              env:
                - name: DATE
                  value: 'DATE_STRING'
    # Service.yaml (경로 : /EKS/Service.yaml)
    
    apiVersion: v1
    kind: Service
    metadata:
      name: eks-svc
    spec:
      ports:
        - name: "80"
          port: 80
          targetPort: 80
          
      selector:
        app: eks-test
      type: LoadBalancer
    

    CodePipeline 이상여부 모니터링

    • EKS 클러스터 환경 내 이상여부 확인
    # EKS 클러스터 배포상태 확인
    $ kubectl get deploy
    
    # EKS 클러스터 서비스 상태 확인
    $ kubectl get svc
    
    # EKS 클러스터 파드상태 확인
    $ kubectl get pod
    

    2.4) Slack 활용 모니터링 시스템 구축

    SNS 주제 생성

    AWS Chatbot 생성 및 SNS 연동

    • 경로
      • [AWS Console] > [AWS Chatbot] > [구성된 클라이언트] > [새 클라이언트 구성]
    • 설정
      • 클라이언트 유형 : [Slack]
      • Slack WorkSpace간 연동설정
    • 새 채널 구성
      • Slack 채널
        • 채널 유형 : [Slack에서 생성된 Channel 유형선택]
      • 권한 : [기본 설정 그대로 설정
      • SNS 주제 : [생성한 SNS 리소스 선택]
    • SNS 구독추가 여부 확인

    AWS Pipeline 알림 설정

    • 경로
      • [개발자 도구] > [CodePipeline] > [Pipeline] > [생성된 pipeline] > [알림] > [알림 규칙 생성]
    • 설정
      • 알림 규칙 설정
        • 알림 이름 : [알림명]
        • 세부 정보 유형 : [가득 참]
        • 알림 트리거 이벤트 : [알림 받기를 원하는 트리거 선택]
        • 대상 : [생성한 Chabot(Slack) 선택]

    Slack 모니터링 시스템 이상여부 확인

    • CodePipeline Release 후 알람 수신 이상여부 확인

    3. 참조문서

    최신 버전의 AWS CLI 설치 또는 업데이트 – AWS Command Line Interface

    Installing or updating kubectl – Amazon EKS

    [Code Pipeline] EKS와 Code Pipeline를 사용하여 CI/CD 구축하기

    [EKS] AWS EKS를 사용하여 클러스터 구성하기

    [Git] Git Bash 설치 (Windows OS)

    [쿠버네티스] AWS-EKS & eksctl

    Installing Chocolatey

    eksctl 설치 또는 업데이트 – Amazon EKS

    Installation – eksctl

    eksctl 설치 – Amazon EMR

    [GitHub ]초보자도 할 수 있는 깃허브 사용법

    Amazon EKS 클러스터 생성 – Amazon EKS

    eksctl을 사용하여 EKS 클러스터 생성하기 (1.21 ver)

    AWS CodeBuild로 ECR로 이미지 업로드

    AWS CodeBuild로 EKS에 배포해 보자

    클러스터에 대한 IAM 보안 주체 액세스 사용 – Amazon EKS

    docker push with AWS CodeBuild fails with exit status 1

    AWS CodePipeline을 사용하여 ECR에 Docker 이미지를 배포해 보기 | DevelopersIO

    AWS에서 CI/CD 환경 구성 #3 – 코드 빌드, CodeBuild

    [Kubernetes] 쿠버네티스 서비스(Service) Deep Dive – (4) Nodeport

    [CI/CD] codecommit, codebuild연동

    쿠버네티스(kubernetes) 이미지 업데이트(update) 또는 이미지 자동 업데이트 막는 방법

    kubernetes에서 배포 이미지 생성시 유의 사항 – imagePullPolicy

    EKS + CI/CD 구성하기 (1) – CodeBuild 생성

    쿠버네티스에서 반드시 알아야 할 서비스(Service) 유형

    Kubernetes 리소스 Service에 대해 이해하고 실습해보기

    [Kubernetes] Service : Load Balancer

    댓글 달기

    이메일 주소는 공개되지 않습니다. 필수 항목은 *(으)로 표시합니다