아마존 웹 서비스(AWS) CodePipeline 팀은 개발자와 DevOps 엔지니어의 운영 오버헤드를 단순화하고, EKS 클러스터에 직접 배포할 수 있는 CodePipeline 액션을 도입하여 배포 과정을 간소화했습니다.
왜 그게 너한테 중요해?
예전에는 DevOps 방식으로 EKS에 자원을 배포해야 할 때, codebuild 프로젝트, eks 접근 권한, kubectl, helm 명령어, 그리고 다른 끔찍한 shell 명령어들을 관리해야 했는데도 한 번에 완벽하지는 않았습니다.
오늘 이 방법을 시도해봤으니, EKS 배포 파이프라인을 100% 단순화하는 방법을 보여드리겠습니다. 코드빌드는 이제 그만두고 복잡한 프로세스, 스크립트, 명령어를 모두 제거하세요!!
건축

선수 조건
- 공개 엔드포인트를 가진 EKS 클러스터.
- deployment.yaml 파일과 같은 Kubernetes 자원
- 원한다면 차트 조종도 할 수 있습니다.
참고: EKS 프라이빗 엔드포인트로 이 업데이트를 시도해보고 싶다면 AWS 히어로 Arshad Zackeriya의 블로그를 확인해 보세요.
원하는 대로 이 저장소에 helm chart와 deployment.yaml을 모두 제공했습니다.
비하인드 신
쿠버네트 명단 파일 사용 시

- 이 동작은 eks 클러스터에 로그인, kubeconfig context 설정에 해당합니다.
- kubectl 설치
- 쿠버네티스 매니페스트 적용
- 롤아웃 리소스
조타 차트의 경우
- 이 동작은 eks 클러스터에 로그인, kubeconfig context 설정에 해당합니다.
- 인스타르 헬름
- 인스탈 헬름 차트
EKS 클러스터 생성
클러스터는 퍼블릭 또는 프라이빗(프라이빗 VPC 포함)일 수 있습니다. 파이프라인은 추가 인프라 없이도 자동으로 프라이빗 네트워크에 연결하여 컨테이너 애플리케이션을 배포합니다.
- 저는 EKS Auto를 사용해 Terraform eks 모듈을 사용했는데, EKS 엔드포인트를 공개 상태로 두면 빠르고 쉽습니다.
eks.tf
# EKS 클러스터 모듈 "EKS" { source = "terraform-aws-modules/eks/aws" version = "~> 20.31" cluster_name = local.cluster_name cluster_version = "1.32" cluster_endpoint_public_access = 참 vpc_id = module.vpc.vpc_id subnet_ids = module.vpc.private_subnets cluster_compute_config = { enabled = 참 node_pools = ["범용"] } # 클러스터 액세스 진입 # 현재 발신자 신원을 관리자로 추가하기 enable_cluster_creator_admin_permissions = 참 태그 = { 환경 = "개발" 테라포름 = "진리" } }
vpc.tf
모듈 "VPC" { source = "terraform-aws-modules/vpc/aws" 버전 = "5.19.0" 이름 = "codepipeline-eks-action" cidr = "10.0.0.0/16" azs = ["us-east-1a", "us-east-1b"] private_subnets = ["10.0.1.0/24", "10.0.2.0/24"] public_subnets = ["10.0.4.0/24", "10.0.5.0/24"] enable_nat_gateway = 참 single_nat_gateway = 참 one_nat_gateway_per_az = 거짓 enable_dns_hostnames = 참 enable_dns_support = 참 public_subnet_tags = { "kubernetes.io/role/elb" = "1" } private_subnet_tags = { "kubernetes.io/role/internal-elb" = "1" } 태그 = { 환경 = "테라포밍-놀이터" } }
포드_identity.tf
데이터 "aws_iam_policy_document" "allow_pod_identity" { 진술서 { 효과 = "허용" 원칙들 { type = "서비스" 식별자 = ["pods.eks.amazonaws.com"] } 행동 = [ "sts:AssumeRole", "sts:TagSession" ] } } 리소스 "aws_iam_role" "read_ecr" { 이름 = "read-ecr-role" assume_role_policy = data.aws_iam_policy_document.allow_pod_identity.json } 리소스 "aws_iam_role_policy_attachment" "read_ecr" { role = aws_iam_role.read_ecr.name policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly" } 리소스 "aws_eks_pod_identity_association" "read_ecr" { cluster_name = local.cluster_name 네임스페이스 = "기본값" service_account = "ecr-sa" role_arn = aws_iam_role.read_ecr.arn }
참고: 저는 pod identity와 ecr 저장소 권한을 사용하여 deploy.yaml용 ecr 이미지를 얻고 있습니다.
클러스터 전체 코드를 원한다면 이 저장소를 따라가면 됩니다
EKS 배포 동작으로 파이프라인 생성
사례 1: kubectl 구성이 사용되는 경우.
저는 소스 소스를 GitHub로 사용하고, 코드 시작(code, start) 연결을 사용하고 있으며, 코드는 이 저장소에 있습니다.
- 클러스터 선택
- deployment.yaml 파일 경로(제 경우는 deployment.yaml 파일)를 제공하세요.
사례 2: 헬름 차트 사용 시
- 발매 제목을 입력하세요
- 헬름 차트를 입력하세요 (제 경우는 테스트 차트입니다)
중요한 단계야
참고: 파이프라인이 생성되면 오류를 피하려면 파이프라인 서비스 역할을 편집하거나 기존 역할을 업데이트하고 다음 권한을 추가해야 합니다.
{ "성명": [ { "액션": [ "iam:PassRole" ], "자원": "*", "효과": "허용", "조건": { "StringEqualsIfExists": { "iam:PassedToService": [ "cloudformation.amazonaws.com", "elasticbeanstalk.amazonaws.com", "ec2.amazonaws.com", "ecs-tasks.amazonaws.com" ] } } }, { "액션": [ "codecommit:CancelUploadArchive", "codecommit:GetBranch", "codecommit:GetCommit", "codecommit:GetRepository", "codecommit:GetUploadArchiveStatus", "codecommit:업로드 아카이브" ], "자원": "*", "효과": "허용" }, { "액션": [ "codedeploy:CreateDeployment", "codedeploy:GetApplication", "codedeploy:GetApplicationRevision", "codedeploy:GetDeployment", "codedeploy:GetDeploymentConfig", "codedeploy:RegisterApplicationRevision" ], "자원": "*", "효과": "허용" }, { "액션": [ "codestar-connections:UseConnection" ], "자원": "*", "효과": "허용" }, { "액션": [ "elasticbeanstalk:*", "ec2:*", "elasticloadbalancing:*", "자동 스케일링:*", "cloudwatch:*", "s3:*", "sns:*", "cloudformation:*", "rds:*", "sqs:*", "ecs:*" ], "자원": "*", "효과": "허용" }, { "액션": [ "lambda:InvokeFunction", "lambda:ListFunctions" ], "자원": "*", "효과": "허용" }, { "액션": [ "opsworks:CreateDeployment", "opsworks:DescribeApps", "opsworks:DescribeCommands", "opsworks:DescribeDeployments", "opsworks:DescribeInstances", "opsworks:DescribeStacks", "opsworks:UpdateApp", "opsworks:UpdateStack" ], "자원": "*", "효과": "허용" }, { "액션": [ "cloudformation:CreateStack", "cloudformation:DeleteStack", "cloudformation:DescribeStacks", "cloudformation:UpdateStack", "cloudformation:CreateChangeSet", "cloudformation:DeleteChangeSet", "cloudformation:DescribeChangeSet", "cloudformation:ExecuteChangeSet", "cloudformation:SetStackPolicy", "cloudformation:ValidateTemplate" ], "자원": "*", "효과": "허용" }, { "액션": [ "codebuild:BatchGetBuilds", "codebuild:StartBuild", "codebuild:BatchGetBuildBatches", "codebuild:StartBuildBatch" ], "자원": "*", "효과": "허용" }, { "효과": "허용", "액션": [ "devicefarm:ListProjects", "devicefarm:ListDevicePools", "devicefarm:GetRun", "devicefarm:GetUpload", "devicefarm:CreateUpload", "devicefarm:ScheduleRun" ], "자원": "*" }, { "효과": "허용", "액션": [ "servicecatalog:ListProvisioningArtifacts", "servicecatalog:CreateProvisioningArtifact", "servicecatalog:DescribeProvisioningArtifact", "servicecatalog:DeleteProvisioningArtifact", "servicecatalog:UpdateProduct" ], "자원": "*" }, { "효과": "허용", "액션": [ "cloudformation:ValidateTemplate" ], "자원": "*" }, { "효과": "허용", "액션": [ "ecr:DescribeImages" ], "자원": "*" }, { "효과": "허용", "액션": [ "states:DescribeExecution", "states:DescribeStateMachine", "states:StartExecution" ], "자원": "*" }, { "효과": "허용", "액션": [ "appconfig:StartDeployment", "appconfig:StopDeployment", "appconfig:GetDeployment" ], "자원": "*" }, { "효과": "허용", "액션": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents" ], "자원": [ "arn:aws:logs:us-east-1:xxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline", "arn:aws:logs:us-east-1:xxxxx:log-group:/aws/codepipeline/eks-deploy-codepipeline:log-stream:*" ] }, { "Sid": "EksClusterPolicy", "효과": "허용", "Action": "eks:DescribeCluster", "자원": [ "*" ] }, { "Sid": "EksVpcClusterPolicy", "효과": "허용", "액션": [ "ec2:DescribeDhcpOptions", "ec2:DescribeNetworkInterfaces", "ec2:DescribeRouteTables", "ec2:서브넷 설명", "ec2:DescribeSecurityGroups", "ec2:DescribeVpcs" ], "자원": [ "*" ] }, { "효과": "허용", "Action": "ec2:CreateNetworkInterface", "자원": "*", "조건": { "StringEqualsIfExists": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:292170836962:subnet/subnet-example1", "arn:aws:ec2:us-east-1:292170836962:subnet/subnet-example2" ] } } }, { "효과": "허용", "액션": "ec2:CreateNetworkInterfacePermission", "자원": "*", "조건": { "ArnEquals": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example1", "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2" ] } } }, { "효과": "허용", "액션": "ec2:DeleteNetworkInterface", "자원": "*", "조건": { "StringEqualsIfExists": { "ec2:Subnet": [ "arn:aws:ec2:us-east-1:xxxxx:subnet/subnet-example1", "arn:aws:ec2:us-east-1:xxxx:subnet/subnet-example2" ] } } } ], "Version": "2012-10-17" }
- 위 코드파이프라인 서비스 역할에 대해 AmazonEKSClusterAdminPolicy로 eks 클러스터에 접근 항목을 생성합니다.
파이프라인을 돌려라
쿠벡틀 매니페스트가 업데이트되는 경우입니다
(base) jatin.mehrotra@CK0662-001 codepipeline-eks-deployment-no-github % kubectl get pods 이름 준비 상태 재시작 연령 hello-k8s-74fd98b69b-2pwrv 1/1 러닝 0 2분 37초 hello-k8s-74fd98b69b-g876f 1/1 Running 0 2m37s hello-k8s-74fd98b69b-phs77 1/1 런닝 0 2m37s
조타도 매니큐멘트가 업데이트되는 경우입니다
(base) jatin.mehrotra@CK0662-001 codepipeline-eks-deployment-no-github % kubectl get pods 이름 준비 상태 재시작 연령 test-67cbfddc66-2gcvj 1/1 running 0 10m
개발자, DevOps 관점에서
- 이번 업데이트로 코드빌드 프로젝트나 어떤 종류의 컴퓨팅 환경을 관리하거나 복잡한 스크립트, 권한, 도구 설치를 관리할 필요가 없어졌습니다.
- 다음은 이 업데이트 이전에 Codebuild로 사용했던 설정 이미지입니다. 정말 복잡한 난장판입니다.
- 이는 비즈니스 문제, 애플리케이션, 모니터링 및 확장과 같은 쿠버네티스 이슈에 집중하고자 하는 개발자, 데브옵스 엔지니어, 인프라 엔지니어에게 분명히 게임 체인저가 될 것입니다.
이것은 Flux/ArgoCD가 따르는 GitOps 방식이 아니지만, 제 생각에 EKS 클러스터에서 가장 좋은 DevOps 접근법입니다.
저는 매일 Linkedin, * X에서 DevOps, Kubernetes, GenAI 관련 놀라운 AWS 업데이트를 공유합니다. 저를 팔로우해 주세요. 여러분의 삶을 더 편하게 만들어 드리겠습니다.