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 설치
- 아래 AWS 문서를 참고하여 AWS CLI를 설치한다.
- 아래 URL을 참고해 본인 운영체제에 맞는 버전으로 다운로드한다.
- 터미널을 열어 aws configure 명령어를 통해 aws cli 설정
- 테스트 환경
- 운영체제 : Window 10
- 터미널 : Git bash
- 테스트 환경

kubectl 설치
- k8s에서 cluster를 제어하기 위한 커맨드라인 도구
- 로컬에서 k8s cluster를 제어해야하여 kubectl 설치 필요
- 설치 프로세스
- 아래 AWS 문서를 참고하여 kubectl을 설치한다.
- 아래 URL 참고하여 본인 운영체제에 맞는 버전으로 다운로드 필요
- Powershell (관리자권한)으로 설치 권장
- 아래 AWS 문서를 참고하여 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 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 권한 부여
- [AWS Management Console] > [IAM] > [역할] > [역할 만들기]

EKS Worker Node_IAM 역할 생성
- 경로
- [AWS Management Console] > [IAM] > [역할] > [역할 만들기]
- [사용 사례] > [EC2]
- 적용권한
- AmazonEKSWorkerNodePolicy
- AmazonEKS_CNI_Policy
- AmazonEC2ContainerRegistryReadOnly
- 적용권한
- [사용 사례] > [EC2]
- [AWS Management Console] > [IAM] > [역할] > [역할 만들기]

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 생성
- 아래 URL을 참고하여 GitHub에서 레포지토리를 생성한다.

- 생성된 레포지토리 경로를 복사한다.
- 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 리소스 선택]
- Slack 채널





- 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 구축하기
[Git] Git Bash 설치 (Windows OS)
eksctl 설치 또는 업데이트 – Amazon EKS
Amazon EKS 클러스터 생성 – Amazon EKS
eksctl을 사용하여 EKS 클러스터 생성하기 (1.21 ver)
클러스터에 대한 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) 유형