문제점: EKS 클러스터에 애플리케이션을 배포하는 과정은 [코드 변경] -> [수동 빌드] -> [Docker 이미지 생성] -> [Docker Hub/ECR 푸시] -> [EKS 접속] -> [kubectl 명령어 실행] 등 복잡하고 수동적인 단계를 거칩니다. 이는 시간이 오래 걸리고, 휴먼 에러를 유발하며, '지속적 배포'라고 부를 수 없습니다.
해결책(청사진): 개발자가 Git에 코드를 Push하는 순간, 이 모든 과정이 자동으로 실행되어 EKS에 즉시 배포되는 "Push-to-Deploy" 파이프라인을 구축합니다.
자동화 시나리오 (Grand Design):
git push 명령어로 GitHub에 코드를 올립니다.kubectl 명령어로 접근하여, 방금 Push한 새 이미지 태그로 Kubernetes Deployment를 업데이트합니다.문제점: Jenkins 컨트롤러(마스터)는 오케스트라의 '지휘자'입니다. 지휘자가 직접 바이올린, 트럼펫, 드럼을 모두 연주(빌드, 테스트, 배포 실행)하면 과부하가 걸리고, 각종 도구(Java, Node.js, Python, Docker, Kubectl...)가 컨트롤러에 뒤섞여 관리가 불가능해집니다.
해결책: Jenkins Agent(Node)라는 '연주자(만능 팔다리)'를 고용하여 실제 작업을 위임합니다.
Jenkinsfile에 적힌 실제 작업(sh 'npm install', sh 'docker build ...')을 수행합니다.docker, kubectl, aws-cli 등 필요한 도구들을 미리 설치한 깨끗한 실행 환경을 이미지로 만들어 두고 필요할 때마다 재사용할 수 있습니다.EKS 환경에서의 고급 전략 (Dynamic Agents):
목표: Git에 푸시된 소스 코드를 실행 가능한 Docker 이미지로 만들어 원격 레지스트리(예: Docker Hub, AWS ECR)에 저장합니다.
Jenkinsfile (CI 단계): Jenkinsfile 내에 CI(지속적 통합)를 담당하는 stage를 정의합니다.
// (Jenkinsfile 예시)
pipeline {
agent any // (또는 agent { label 'docker-agent' } 등 지정)
stages {
// ... (Checkout 단계) ...
// 1. 애플리케이션 빌드 (예: Node.js)
stage('Build App') {
steps {
sh 'npm install'
sh 'npm run build'
}
}
// 2. Docker 이미지 빌드 및 푸시
stage('Build & Push Image') {
steps {
script {
// 이미지 이름 정의 (빌드 번호로 태그 지정)
def imageName = "my-username/my-app:${env.BUILD_NUMBER}"
// (1) Docker 이미지 빌드
sh "docker build -t ${imageName} ."
// (2) Docker Hub 로그인 (Credentials 플러그인 사용)
// 'dockerhub-creds'는 Jenkins Credentials에 등록한 ID
withCredentials([usernamePassword(credentialsId: 'dockerhub-creds', usernameVariable: 'DOCKER_USER', passwordVariable: 'DOCKER_PASS')]) {
sh "docker login -u $DOCKER_USER -p $DOCKER_PASS"
}
// (3) 이미지 푸시
sh "docker push ${imageName}"
// (4) (중요) 다음 단계를 위해 이미지 이름 저장
env.IMAGE_NAME_WITH_TAG = imageName
}
}
}
// ... (배포 단계로 이어짐)
}
}
Credentials 플러그인을 사용하여 민감한 Docker Hub 비밀번호를 스크립트에서 숨기고, env.BUILD_NUMBER 같은 환경 변수를 활용해 이미지 태그를 동적으로 생성합니다.목표: CI 단계에서 ECR/Docker Hub에 올린 최신 이미지를 가져와, EKS 클러스터의 Deployment에 적용(배포)합니다.
사전 준비: Jenkins Agent는 kubectl과 aws-cli를 설치하고 있어야 하며, EKS 클러스터에 접근할 수 있는 권한(IAM Role 또는 kubeconfig)이 설정되어 있어야 합니다.
Jenkinsfile (CD 단계):
// (Jenkinsfile 예시 - 계속)
// ... (CI 단계 이후) ...
// 3. EKS 클러스터에 배포
stage('Deploy to EKS') {
steps {
script {
// (1) EKS 클러스터 인증 (AWS Credentials 필요)
// 'aws-creds' ID로 인증 후 kubeconfig 업데이트
withCredentials([aws(credentialsId: 'aws-creds')]) {
sh 'aws eks update-kubeconfig --name my-eks-cluster --region ap-northeast-2'
}
// (2) Deployment의 이미지 업데이트
// 'kubectl set image' 명령어로 롤링 업데이트 트리거
// (Deployment 이름: my-app-deploy, 컨테이너 이름: my-app-container)
sh "kubectl set image deployment/my-app-deploy my-app-container=${env.IMAGE_NAME_WITH_TAG} --record"
// (3) 배포 상태 확인
sh "kubectl rollout status deployment/my-app-deploy"
}
}
}
} // stages 끝
} // pipeline 끝
kubectl apply -f deployment.yaml 방식은 YAML 파일의 이미지 태그를 직접 수정해야 하는 번거로움이 있습니다. 반면 kubectl set image 명령어는, YAML 파일을 건드리지 않고도 **"어떤 Deployment의 어떤 컨테이너 이미지를 이 태그로 바꿔줘"**라고 EKS에 직접 명령할 수 있어 CD 파이프라인에 매우 유용합니다.문제점: 파이프라인을 완성했지만, Jenkins가 Git 저장소의 변경을 감지하는 방식이 Poll SCM(주기적 확인)이면, 1분마다 "변경된 거 있어?"라고 물어봐야 하므로 비효율적이고 배포가 즉각적이지 않습니다.
해결책: GitHub Webhook을 사용하여, GitHub가 Jenkins에게 **"지금 Push 왔어!"**라고 능동적으로 알려주게 만듭니다.
Jenkins 설정:
GitHub hook trigger for GITScm polling 옵션을 체크합니다. (이름은 Polling이지만, 실제로는 Webhook을 '수신'하겠다는 의미입니다.)GitHub 설정:
http://[내 Jenkins 서버 주소]/github-webhook//github-webhook/ 경로와 마지막 /까지 정확히 입력해야 합니다.)application/jsonJust the push event. (기본값)git push를 하면, GitHub가 즉시 Jenkins의 Webhook URL을 호출하고, Jenkins는 GitHub hook trigger 옵션에 따라 파이프라인을 자동으로 실행시켜 CI(빌드/푸시)와 CD(EKS 배포) 전 과정을 논스톱으로 완료합니다.Jenkinsfile의 stage를 통해 소스 코드를 빌드하고 docker build, docker push를 실행하여 Docker 이미지를 레지스트리에 저장합니다. (이때 Credentials가 필수입니다.)kubectl set image 명령어를 사용하여, EKS 클러스터의 Deployment 이미지를 최신 버전으로 교체하도록 명령합니다.