Infra Tech Update

AWS CodePipeline으로 Amazon EKS 클러스터에 직접 파드 배포하기

AWS CodePipeline

24 min read
AWS CodePipeline으로 Amazon EKS 클러스터에 직접 파드 배포하기

2025년 2월 AWS CodePipeline에 Amazon EKS로 컨테이너 기반 애플리케이션을 직접 배포할 수 있는 기능이 추가되었습니다. 이번 포스팅에서는 AWS 입문자와 현업 개발자 및 운영자를 위해 이 기능이 추가된 이유와 이 기능이 어떤 작업 효율을 가져오는 지 실제로 테스트해본 내용을 공유합니다. 참고로 본 포스팅의 내용은 가이드가 아닙니다. 새로운 기능이 실무자들에게 어떤 업무 편의를 제공할 수 있는지에 대한 평가 의견을 공유하기 위한 목표로 작성한 내용입니다. 실제 프로덕션 환경에서 CodePipeline을 사용할 경우 최소 권한 원칙에 따라 보안에 대한 충분한 고려와 AWS의 보안 모범 사례를 따라야 합니다. 다시 본론으로 돌아와 이번 평가를 통해 느낀점을 한 줄로 요약하자면 이번에 테스트한 CodePipeline의 새로운 기능은 작업 효율과 비용 절감 측면에서 안 쓰면 손해인 그런 업데이트라 할 수 있습니다. 가상의 사례를 떠올려 보면 이런 말을 왜 하는지 바로 알 수 있습니다.

예를 들어 볼까요. 한정판 신상품의 예약 판매를 앞둔 이커머스 플랫폼의 DevOps팀을 상상해 보겠습니다. 대규모 트래픽 폭증에 대비해 예약 시작 직전까지 애플리케이션 파트(Pod)를 신속하고 유연하게 확장해야 하는 긴박한 상황입니다. 기존 방식으로는 담당자가 배스천 호스트(Bastion Host)나 별도의 CI/CD 서버에 직접 접속하여 수많은 kubectl 명령어를 실행해야 했습니다. 혹은 복잡한 젠킨스(Jenkins) 파이프라인 스크립트가 오류 없이 작동하기만을 마음 졸이며 지켜봐야 할 때도 있었습니다. 이 과정에서 kubeconfig 파일의 인증 오류나 작은 스크립트 실수가 배포 실패와 심각한 서비스 장애로 이어질 수 있다는 부담감은 온전히 담당자의 몫이었습니다. 이러한 수동적이고 오류 가능성이 높은 배포 방식은 안정적인 클러스터 운영에 큰 걸림돌이 되어 왔습니다. 이런 부담을 낮추는 데 도움이 된다면? 안 쓸 이유가 없는 것이죠.

AWS CodePipeline 소개

AWS CodePipeline은 AWS의 완전관리형 CI/CD 파이프라인 서비스입니다. AWS 사용자들에게 CodePipeline이 인기가 높은 이유는 간단합니다. 시장에는 Jenkins, GitLab CI, CircleCI와 같이 강력한 써드파티 CI/CD 도구들이 있습니다. 그런데 왜 CodePipeline에 먼저 손이 갈까요? AWS 환경에 긴밀하게 통합된 워크로드일수록 CodePipeline은 관리 효율성 측면에서 뚜렷한 강점을 보이기 때문입니다. CodeCommit, CodeBuild, CodeDeploy 같은 여러 AWS 서비스와 연계하여 소프트웨어 업데이트를 빠르고 일관되게 프로덕션 환경까지 전달할 수 있습니다.

다른 도구와 비교할 때 가장 큰 차별점은 AWS IAM(Identity and Access Management)과의 완벽한 연동성입니다. 써드파티 도구는 EKS 클러스터에 접근하기 위해 서비스 어카운트 토큰이나 별도 IAM 사용자의 액세스 키를 직접 발급하고 관리해야 합니다. 이 방식은 보안 키 유출 위험과 주기적인 교체 부담을 동반합니다. 반면에 CodePipeline은 파이프라인 자체에 IAM 역할을 부여하고, 이 역할을 aws-auth ConfigMap에 등록하기만 하면 안전하게 통제된 접근 권한을 설정할 수 있습니다. 또한, CodePipeline은 완전관리형 서버리스 서비스입니다. 따라서 별도의 CI/CD 서버를 구축하고 업데이트, 보안 패치, 스케일링 등을 직접 관리해야 하는 써드파티 도구와 달리, 인프라 운영 부담 없이 파이프라인 로직에만 집중할 수 있습니다.

EKS 직접 배포 기능 업데이트 배경

2025년 2월 20일 AWS는 CodePipeline에 Amazon EKS 배포를 위한 네이티브 지원 기능을 추가했습니다. 이제 CodePipeline 파이프라인의 배포 액션으로 Amazon EKS를 직접 선택할 수 있습니다. 풀어 설명하자면 컨테이너 애플리케이션을 별도의 중간 서버 없이 EKS 클러스터에 바로 배포할 수 있게 되었다는 말입니다.

이 기능이 추가된 이유는 무엇일까요? 많은 사용자들이 Kubernetes 애플리케이션 배포를 더 쉽게 할 수 있도록 배려한 것이 아닐까 추측해봅니다. 실제로 이 기능이 추가되면서 작업이 한결 간소화되었습니다. 이전까지 CodePipeline으로 EKS에 배포하려면 CodeBuild나 별도 EC2 인스턴스 같은 추가 컴퓨팅 환경을 구성하고, 그 안에 kubectl 등을 설치해 파이프라인에서 호출해야 했습니다. 특히 프라이빗 VPC에 있는 EKS 클러스터에 배포하려면 해당 VPC 안에서 동작하는 별도의 배포용 인스턴스나 CodeBuild 실행 환경을 유지 관리해야 했습니다. 이러한 방식은 설정이 번거롭고, 상시 가동되는 자원으로 인해 불필요한 비용도 발생했습니다.

그러던 것이 이제 상황이 달라졌습니다. CodePipeline에 새로 추가된 EKS 배포 액션을 파이프라인에 포함하고 배포 대상 EKS 클러스터 이름만 지정하면, 파이프라인이 자동으로 클러스터에 연결하여 애플리케이션을 배포합니다. 별도 인프라나 서버 구성 없이 EKS에 직접 배포할 수 있게 된 것입니다. AWS에 따르면 이런 방식은 운영 오버헤드를 크게 줄이고 배포 프로세스를 단순화한다고 합니다. 더불어 퍼블릭 클러스터뿐만 아니라 엔드포인트가 VPC 내부에만 공개된 프라이빗 클러스터까지 지원합니다. 따라서 보안상 VPC 내부에만 클러스터를 둔 경우에도 파이프라인 배포를 쉽게 적용할 수 있습니다.

 

테스트 환경 구성

안랩클라우드메이트는 멀티 클라우드를 지원하는 MSP이다 보니 주요 CSP에서 새로운 기능을 업데이트할 때마다 내부 테스트를 수행합니다. EKS 배포 기능도 발표되지 마자 테스트를 진행했습니다. 테스트 과정과 결과를 자세히 알아보겠습니다.

먼저 새로운 EKS 배포 기능을 확인하기 위해 실제와 유사한 테스트 환경을 구성했습니다. 소스 코드 저장소는 AWS의 Git 리포지토리 서비스인 CodeCommit을 사용하고, 배포 대상은 인터넷에 노출되지 않은 Amazon EKS 프라이빗 클러스터를 이용하는 환경을 우선 마련했습니다.

세부 내용을 소개하자면 먼저 CodeCommit 저장소에 Nginx 기반 샘플 애플리케이션의 Deployment와 Service를 정의한 deployment.yaml 및 service.yaml 파일을 저장했습니다. CodeCommit에 코드가 푸시되면 Webhook을 통해 파이프라인이 자동으로 실행되도록 설정했습니다.

Amazon EKS 클러스터는 이번 기능의 핵심인 프라이빗 클러스터로 생성했습니다. AWS VPC 내에 전용 서브넷을 만들고, API 엔드포인트를 외부로 노출하지 않고 VPC 내부 전용으로 설정했습니다. 노드 그룹 또한 프라이빗 서브넷에 배치했으며, 클러스터가 이미지를 내려받을 수 있도록 NAT 게이트웨이를 통해 인터넷에 접근하도록 구성했습니다.

마지막으로, Deployment 매니페스트가 참조하는 Docker 컨테이너 이미지는 사전에 Amazon ECR에 푸시해 두었습니다. 여기서는 AWS가 제공하는 샘플 이미지를 사용하여 별도의 빌드 단계 없이 즉시 배포가 가능하도록 준비했습니다.

이 환경은 소스를 CodeCommit으로 관리하고 서비스는 프라이빗 EKS 클러스터에서 운영하는, 실제 기업의 CI/CD 시나리오를 가정한 것입니다. 이 환경에서 CodePipeline을 생성하고 배포 단계를 설정하는 과정을 소개하겠습니다.

 

CodePipeline으로 EKS에 파드 배포하기

1. CodePipeline 파이프라인 생성

AWS Management Console에서 CodePipeline 서비스로 이동하여 새 파이프라인을 생성한 후 다음과 같은 과정으로 설정을 합니다.

1.1  카테고리 설정

카테고리 선택 후 다음 단계로 넘어갑니다.

1.2  파이프라인 설정

서비스 역할을 새로 만들고, 권한을 수정하였습니다.

1.3  소스 스테이지 구성: CodeCommit 연동

테스트를 위해 미리 지정한 CodeCommit을 소스 공급자로 지정했습니다.

1.4  빌드 스테이지 건너뛰기

이번 테스트는 이미 빌드된 컨테이너 이미지를 참조하는 매니페스트 파일을 배포하므로 별도의 빌드 과정이 필요 없습니다. 따라서 [빌드 스테이지 건너뛰기]를 선택합니다

1.5  배포 스테이지 설정: Amazon EKS 선택 및 Kubectl 구성

다음으로 배포 스테이지를 추가합니다. 이 단계를 완료하면 파이프라인을 생성할 수 있습니다.

2. CodePipeline 파이프라인 확인

이제 생성한 파이프라인이 정상적으로 작동을 하는 지 확인하는 과정으로 넘어갑니다.

2.1 레포에 yaml 파일 커밋

CodeCommit 레포에 nginx-pod.yaml 파일 커밋 후 파이프라인이 정상적으로 작동하는 지 확인합니다. 파일 커밋 후 Deploy 실행 내역을 확인하면 다음과 같은 에러가 발생하는 것을 확인할 수 있습니다. CodePipeline 서비스 역할에 EKS 클러스터 접근 및 kubectl 명령 실행 권한이 없기 때문에 발생하는 오류입니다.

2.2 권한 오류 해결

권한 오류 문제를 해결하려면 두 가지 영역에서 권한을 설정해야 합니다. 먼저 CodePipeline 서비스 역할(IAM) 권한 추가 작업을 합니다.

IAM 콘솔로 이동하여 파이프라인 생성 시 만들어진 CodePipeline 서비스 역할을 찾습니다. 해당 역할에 EKS 클러스터 정보를 조회하기 위한 필수 권한인 eks:DescribeCluster를 추가합니다. AWS 관리형 정책은 AmazonEC2ContainerRegistryPowerUser, AmazonEKSWorkerNodePolicy 정책을 추가해 주었습니다. 참고로 이는 테스트를 위한 목적으로 부여한 정책입니다. 실제 환경에서는 최소 권한의 원칙을 지키는 것이 매우 중요합니다. 기본적으로 IAM 정책과 함께 프라이빗 클러스터 접근에 필요한 EC2 권한도 최소 권한 원칙을 따라야 합니다.

위와 같이 권한 추가 후 재배포를 해보니 다른 유형의 에러가 발생했습니다. 이는 Deploy 단계에서 EKS 클러스터의 configmap에 CodePipeline을 등록하지 않아 생기는 문제입니다. configmap 설정은 IAM 주체(CodePipeline 역할)가 EKS 클러스터의 Kubernetes API 서버로부터 인증받고 권한을 부여받는 핵심적인 연결 고리 역할을 합니다.

Configma 설정 관련 오류는 kube-system 네임스페이스의 aws-auth ConfigMap을 수정해 해결할 수 있습니다. kubectl edit -n kube-system configmap/aws-auth 명령을 실행하여 다음과 같이 권한을 추가합니다. 이는 테스트 편의를 위한 권한 설정임을 밝힙니다. system:masters 그룹은 클러스터 전체 관리자 권한을 가집니다. 실제 운영 환경에서는 최소 권한 원칙에 따라 필요한 권한만 가진 맞춤형 Kubernetes RBAC 역할을 생성하고 매핑하는 것이 좋습니다.

apiVersion: v1
data:
  mapRoles: |
    - groups:
      - system:bootstrappers
      - system:nodes
      rolearn: arn:aws:iam::111111111111:role/eksctl-eks-cluster-nodegroup-eks-w-NodeInstanceRole-wjFrcvLfYW7y
      username: system:node:{{EC2PrivateDNSName}}
      
### 아래 부분을 추가해줍니다.
### rolearn = code build가 사용중인 역할의 arn, /service-role 부분은 제거
### username = 역할 이름
    - groups:
      - system:masters
      rolearn: arn:aws:iam::111111111111:role/AWSCodePipelineServiceRole-ap-northeast-2-acme-pipeline
      username: AWSCodePipelineServiceRole-ap-northeast-2-acme-pipeline

모든 권한 설정이 완료되면 CodeCommit 리포지토리에 변경 사항을 푸시하거나 CodePipeline 콘솔에서 수동으로 파이프라인을 재실행합니다. 배포가 성공하면 EKS 클러스터에서 kubectl get pods 명령을 실행하여 파드가 정상적으로 배포되었는지 확인합니다.

3. Pod 배포 후 테스트

CodePipelie으로 파드를 성공적으로 배포한 후 매니페스트 파일을 변경했을 때의 결과를 테스트하였습니다. 이 과정에서 kubectl apply 명령어의 동작 방식과 관련된 흥미로운 점을 관찰할 수 있었습니다. 테스트를 위해 다음과 같이 CodeCommit의 yaml 파일을 수정했습니다.

최초 배포 시 Nginx 이미지를 사용하는 nginx-pod를 배포했습니다. 이후 동일한 파일(nginx-pod.yaml)의 내용을 수정하여 Busybox 이미지를 사용하고 파드 이름도 busybox-pod로 변경한 뒤 커밋했습니다. CodePipeline은 변경을 감지하고 자동으로 재배포를 실행했습니다.

재배포 후 kubectl get pods로 확인한 결과 기존 nginx-pod는 삭제되지 않고 그대로 남아있었으며, 새로 정의한 busybox-pod가 추가로 생성되어 두 파드가 동시에 실행되고 있었습니다.

이러한 결과는 kubectl apply -f <filename.yaml> 명령어의 선언적(declarative) 특성 때문에 발생합니다. kubectl apply는 지정된 파일의 내용대로 클러스터의 리소스 상태를 만들거나 유지하려고 시도합니다.

apply 명령은 선언된 상태를 기준으로 "생성 또는 업데이트"를 수행하며, 명시적인 삭제(--prune) 옵션 없이는 현재 매니페스트에 없는 리소스를 자동으로 정리하지 않습니다. 만약 metadata.name을 nginx-pod로 유지한 채 컨테이너 이미지만 변경했다면, apply는 기존 파드를 새로운 설정으로 업데이트했을 것입니다.

이 테스트는 metadata.name이 리소스의 핵심 식별자이며, 이를 변경하는 것은 사실상 새 리소스를 선언하는 것과 같다는 점을 보여줍니다. 이는 의도치 않게 불필요한 리소스가 누적되는 원인이 될 수 있으므로, 매니페스트 관리 시 주의가 필요합니다.

4. CodePipeline은 EKS에 어떻게 파드를 배포할까?

마지막으로 CodePipeline의 EKS 배포 액션은 내부적으로 어떤 과정을 거쳐 파드를 배포하는지를 살펴보기 위한 테스트를 수행하였습니다. CodePipeline의 Deploy 로그를 분석하면 그 과정을 엿볼 수 있습니다.

[Container] 2025/03/06 01:54:18.906720 Running on CodeBuild On-demand
[Container] 2025/03/06 01:54:18.906731 Waiting for agent ping
[Container] 2025/03/06 01:54:19.108255 Waiting for DOWNLOAD_SOURCE
[Container] 2025/03/06 01:54:20.360813 Phase is DOWNLOAD_SOURCE
[Container] 2025/03/06 01:54:20.406191 CODEBUILD_SRC_DIR=/codebuild/output/src2556265344/src
[Container] 2025/03/06 01:54:20.406659 YAML location is /codebuild/readonly/buildspec.yml

분석을 해보면 배포 액션 내부적으로 AWS CodeBuild를 활용하는 것을 알 수 있습니다. 사용자가 별도 설정을 하지 않아도, CodePipeline이 관리하는 임시 CodeBuild 환경에서 배포에 필요한 스크립트를 실행합니다.

[Container] 2025/03/06 01:43:59.393124 Running command curl "https://dhqog3tnwbd3.cloudfront.net/deploy-eks-aws-1/0.1.0.tgz" -o /tmp/cp-action-source/action-archive.tgz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed

  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100 17.0M  100 17.0M    0     0  68.9M      0 --:--:-- --:--:-- --:--:-- 69.1M

[Container] 2025/03/06 01:44:00.616911 Running command tar -xvzf /tmp/cp-action-source/action-archive.tgz --strip-components=1 -C /tmp/cp-action-source
package/dist/helm/helm
package/dist/index.js
package/dist/validationUtils.js
package/package.json
package/dist/index.d.ts.map
package/dist/index.js.map
package/dist/validationUtils.d.ts.map
package/dist/validationUtils.js.map
package/dist/index.d.ts
package/dist/validationUtils.d.ts

배포 작업이 시작되면 CodePipeline은 EKS 배포용으로 준비된 패키지를 다운로드하여 압축을 해제합니다. 이 패키지 안에는 클러스터 인증, kubectl 실행 등에 필요한 도구와 스크립트가 포함되어 있습니다.

[Container] 2025/03/06 01:44:01.240359 Running command node $CODEPIPELINE_INPUT_ACTION_SOURCE_PATH/dist/index.js
Logging in to Amazon EKS cluster.
Running command: aws eks update-kubeconfig --region ap-northeast-2 --name eks-cluster
Installing kubectl...
Running command: curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" && chmod +x ./kubectl && sudo mv ./kubectl /usr/local/bin/kubectl

스크립트는 aws eks update-kubeconfig AWS CLI 명령어를 실행하여 kubeconfig 파일을 생성하고, 이를 통해 kubectl이 대상 클러스터와 안전하게 통신할 수 있도록 설정합니다. 마지막으로 사용자가 지정한 매니페스트 파일을 대상으로 kubectl apply 명령을 실행하여 리소스를 클러스터에 배포합니다.

이처럼 CodePipeline의 EKS 배포 액션은 복잡한 내부 단계를 추상화하여 사용자에게 간단한 설정 인터페이스만 제공합니다. kubeconfig 관리, kubectl 설치, 명령어 실행 등의 세부 사항은 모두 AWS가 관리하는 환경에서 자동으로 처리됩니다. 사용자는 배포 자동화의 복잡성에서 벗어나 애플리케이션 개발에 더 집중할 수 있습니다.

실무자가 체감할 수 있는 새로운 배포 액션의 장점

앞서 소개한 테스트 과정을 통해 CodePipeline의 네이티브 Amazon EKS 배포 액션은 기존 방식에 비해 여러 주목할 만한 장점을 제공함을 확인할 수 있었습니다.

가장 큰 장점은 파이프라인 구성이 매우 간편해졌다는 것입니다. 이전에는 buildspec.yaml 파일에 EKS 클러스터 인증, kubectl 설치, apply 명령어 실행 등 배포의 모든 단계를 직접 기술해야 했습니다. 새로운 액션은 이 모든 과정을 자동화하므로, 복잡한 스크립트 작성 및 유지보수 부담이 사라집니다. UI에서 매니페스트 파일 경로만 지정하면 되므로 초보자도 쉽게 Kubernetes CI/CD를 구현할 수 있습니다.

프라이빗 EKS 클러스터로의 배포가 대폭 간소화된 것도 빼놓을 수 없는 장점입니다. 예전에는 프라이빗 클러스터에 접근하기 위해 Bastion 호스트를 두거나 복잡한 네트워크 설정을 유지해야 했습니다. 이제는 CodePipeline이 VPC 내에 네트워크 인터페이스를 자동으로 생성하여 안전하게 연결하므로 복잡한 작업 없이도 보안이 강화된 클러스터에 CI/CD를 적용할 수 있습니다. 이는 엔터프라이즈 환경에서 매우 유용한 개선이라 할 수 있습니다.

이 밖에도 운영 오버헤드와 비용 감소 효과도 있을 것으로 보입니다. 배포를 위한 별도의 인프라를 관리할 필요가 없어지고, 배포에 필요한 임시 리소스는 작업 시에만 사용되므로 비용 효율성이 높습니다. 수동 배포 시 발생할 수 있는 인적 오류가 줄고 배포 프로세스가 일관성을 갖게 되어 서비스 안정성도 향상됩니다.

정리하자면 이번 업데이트를 통해 개발팀은 인프라 관리보다 핵심 비즈니스 로직 개발에 더 많은 시간을 투입할 수 있게 될 것 같습니다. AWS 네이티브 서비스만으로 "소스 → 이미지 빌드 → EKS 배포"의 전체 CI/CD 흐름을 손쉽게 구성하고, 더 빠른 업데이트와 안정적인 운영을 기대할 수 있다는 것이 이번 테스트의 결론입니다.

정리하자면 CodePipeline의 네이티브 EKS 배포 기능은 단순한 배포 자동화를 넘어 클러스터 관리 방식을 한 차원 높은 수준으로 끌어올립니다. 배포 인프라 관리라는 부수적인 업무를 AWS에 위임하여 DevOps팀은 애플리케이션의 안정성과 비즈니스 로직 개선이라는 본질적인 가치에 더 많은 역량을 집중할 수 있게 됩니다. 모든 배포 과정이 AWS 내부에서 IAM 역할 기반으로 통제되고 CodePipeline 콘솔을 통해 명확하게 추적됩니다. 그 결과 클러스터 변경 이력에 대한 가시성과 거버넌스가 크게 향상됩니다. 이는 예측 가능하고 안정적인 클러스터 운영의 핵심 요소가 되며, 장기적으로는 인적 실수를 줄이고 클러스터의 전반적인 보안 수준을 높이는 효과로 이어집니다. 따라서 이 기능을 채택하는 것은 더 효율적이고 성숙한 쿠버네티스 환경을 조성하기 위한 현명한 전략적 선택이라 할 수 있습니다.

Share This Post

Check out these related posts

Amazon EKS, 커뮤니티 애드온 살펴보기

Amazon S3 콘솔, 모든 버킷 외부 액세스 요약 표시

Database Insights, 메트릭 대시보드 사용자 정의 지원 추가