Amazon EKS 클러스터에 Karpenter를 설치하려면 어떻게 해야 합니까?
Karpenter를 사용하여 Amazon Elastic Kubernetes Service(Amazon EKS) 클러스터 내에서 워커 노드를 확장하고 싶습니다.
간략한 설명
Karpenter는 Kubernetes용으로 구축한 오픈 소스 노드 프로비저닝 프로젝트입니다. Kubernetes 클러스터에 Karpenter를 추가하면 해당 클러스터에서 워크로드를 실행하는 효율성과 비용을 크게 개선할 수 있습니다. 자세한 내용은 Karpenter 설명서를 참조하십시오.
다음 단계는 Amazon EKS 클러스터에 Karpenter를 배포하는 방법을 보여줍니다.
해결 방법
사전 조건
시작하기 전에 다음을 완료합니다.
- Helm 클라이언트 3.11.0 이상을 설치합니다. 설치 절차에 대한 자세한 내용은 Helm Docs를 참조하십시오.
- eksctl을 설치합니다. 설치 절차에 대한 자세한 내용은 eksctl 사용 설명서를 참조하십시오.
- 다음과 같은 환경 변수를 생성합니다.
export CLUSTER_NAME=your_cluster_name export KARPENTER_VERSION=your_required_version export CLUSTER_ENDPOINT="$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output text)" export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query 'Account' --output text)
참고: your_cluster_name에 대한 EKS 클러스터 이름과 your_required_version에 대한 필수 Karpenter 버전 번호를 입력합니다. Karpenter 버전은 Karpenter/배포를 확인하십시오.
Karpenter 및 Karpenter 컨트롤러용 IAM 역할 생성
1. Karpenter로 프로비저닝한 노드에 대한 AWS 자격 증명 및 액세스 관리(IAM) 역할을 생성합니다. Karpenter 노드 역할(KarpenterInstanceNodeRole)은 Amazon EKS 노드 IAM 역할과 유사합니다. Amazon EKS 노드 IAM 역할을 참조하여 AWS Management Console 또는 AWS Command Line Interface(AWS CLI)를 사용해서 KapenterInstanceNodeRole을 생성합니다.
참고: CLI 명령을 실행하는 중에 오류가 발생하는 경우 최신 버전의 AWS CLI를 사용하고 있는지 확인합니다. AWS CLI 오류 문제 해결 - AWS 명령줄 인터페이스를 참조하십시오.
2. 생성한 IAM KarpenterInstanceNodeRole에 이러한 IAM 정책을 추가합니다.
AmazonEKSWorkerNodePolicy AmazonEKS_CNI_Policy AmazonEC2ContainerRegistryReadOnly AmazonSSMManagedInstanceCore
Karpenter 컨트롤러의 IAM 역할을 구성합니다.
KarpenterControllerRole에 대한 IAM 역할을 생성합니다. Karpenter 컨트롤러는 서비스 계정(IRSA)에 IAM 역할을 사용합니다.
1. 다음 권한을 사용하여 controller-policy.json 문서를 생성합니다.
echo '{ "Statement": [ { "Action": [ "ssm:GetParameter", "iam:PassRole", "ec2:DescribeImages", "ec2:RunInstances", "ec2:DescribeSubnets", "ec2:DescribeSecurityGroups", "ec2:DescribeLaunchTemplates", "ec2:DescribeInstances", "ec2:DescribeInstanceTypes", "ec2:DescribeInstanceTypeOfferings", "ec2:DescribeAvailabilityZones", "ec2:DeleteLaunchTemplate", "ec2:CreateTags", "ec2:CreateLaunchTemplate", "ec2:CreateFleet", "ec2:DescribeSpotPriceHistory", "pricing:GetProducts" ], "Effect": "Allow", "Resource": "*", "Sid": "Karpenter" }, { "Action": "ec2:TerminateInstances", "Condition": { "StringLike": { "ec2:ResourceTag/Name": "*karpenter*" } }, "Effect": "Allow", "Resource": "*", "Sid": "ConditionalEC2Termination" } ], "Version": "2012-10-17" }' > controller-policy.json
2. 이 controller-policy.json 문서를 사용하여 IAM 정책을 생성합니다.
aws iam create-policy --policy-name KarpenterControllerPolicy-${CLUSTER_NAME} --policy-document file://controller-policy.json
3. 이 eksctl 명령을 사용하여 클러스터용 IAM OIDC ID 공급자를 생성합니다.
eksctl utils associate-iam-oidc-provider --cluster ${CLUSTER_NAME} --approve
참고: eksctl 버전이 0.32.0 이상인지 확인하십시오.
4. eksctl 명령을 사용하여 Karpenter 컨트롤러의 IAM 역할을 생성합니다. IRSA를 사용하여 Kubernetes 서비스 계정과 IAM 역할을 연결합니다.
eksctl create iamserviceaccount \ --cluster "${CLUSTER_NAME}" --name karpenter --namespace karpenter \ --role-name "$KarpenterControllerRole-${CLUSTER_NAME}" \ --attach-policy-arn "arn:aws:iam::${AWS_ACCOUNT_ID}:policy/KarpenterControllerPolicy-${CLUSTER_NAME}" \ --role-only \ --approve
서브넷 및 보안 그룹에 태그 추가
1. Karpenter가 사용할 서브넷을 알 수 있도록 노드 그룹 서브넷에 태그를 추가합니다.
for NODEGROUP in $(aws eks list-nodegroups --cluster-name ${CLUSTER_NAME} \ --query 'nodegroups' --output text); do aws ec2 create-tags \ --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \ --resources $(aws eks describe-nodegroup --cluster-name ${CLUSTER_NAME} \ --nodegroup-name $NODEGROUP --query 'nodegroup.subnets' --output text ) done
2. 보안 그룹에 태그를 추가합니다.
참고: 다음 명령은 첫 번째 노드 그룹의 보안 그룹에만 태그를 추가합니다. 여러 노드 그룹 또는 여러 보안 그룹이 있는 경우 사용자는 Karpenter에서 사용할 보안 그룹을 결정해야 합니다.
NODEGROUP=$(aws eks list-nodegroups --cluster-name ${CLUSTER_NAME} \ --query 'nodegroups[0]' --output text) LAUNCH_TEMPLATE=$(aws eks describe-nodegroup --cluster-name ${CLUSTER_NAME} \ --nodegroup-name ${NODEGROUP} --query 'nodegroup.launchTemplate.{id:id,version:version}' \ --output text | tr -s "\t" ",") # If your EKS setup is configured to use only Cluster security group, then please execute - SECURITY_GROUPS=$(aws eks describe-cluster \ --name ${CLUSTER_NAME} --query cluster.resourcesVpcConfig.clusterSecurityGroupId | tr -d '"') # If your setup uses the security groups in the Launch template of a managed node group, then : SECURITY_GROUPS=$(aws ec2 describe-launch-template-versions \ --launch-template-id ${LAUNCH_TEMPLATE%,*} --versions ${LAUNCH_TEMPLATE#*,} \ --query 'LaunchTemplateVersions[0].LaunchTemplateData.[NetworkInterfaces[0].Groups||SecurityGroupIds]' \ --output text) aws ec2 create-tags \ --tags "Key=karpenter.sh/discovery,Value=${CLUSTER_NAME}" \ --resources ${SECURITY_GROUPS}
aws-auth ConfigMap 업데이트
1. 클러스터 내 aws-auth ConfigMap을 업데이트하여 KarpenterInstanceNodeRole IAM 역할을 사용하는 노드가 클러스터에 합류하게 합니다. 다음 명령을 실행합니다.
kubectl edit configmap aws-auth -n kube-system
2. 이 예와 비슷한 섹션을 mapRoles에 추가합니다.
참고: ${AWS_ACCOUNT_ID} 변수를 계정으로 변경하되 **{{EC2PrivateDNSName}}**로는 변경하지 마십시오.
- groups: - system:bootstrappers - system:nodes rolearn: arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterInstanceNodeRole username: system:node:{{EC2PrivateDNSName}}
이제 전체 aws-auth ConfigMap에는 두 개의 그룹이 있습니다. 하나는 Karpenter 노드 역할용이며 다른 하나는 기존 노드 그룹용입니다.
Karpenter 배치
1. 다음 명령을 사용하여 배포하려는 Karpenter 배포 버전을 확인합니다.
echo $KARPENTER_VERSION
출력이 표시되지 않거나 원하는 것과 다른 버전이 표시되면 다음을 실행합니다.
export KARPENTER_VERSION=your_required_version
참고: 이 예에서는 your_required_version을 원하는 버전 번호로 변경합니다. GitHub 웹사이트에서 Karpenter 버전에 대한 aws/karpenter를 참조하십시오.
2. 차트 Helm에서 전체 Karpenter 배포 yaml 파일을 생성합니다. 시작하기 전에 Helm 클라이언트 버전이 v3.11.0 이상인지 확인하십시오.
helm template karpenter oci://public.ecr.aws/karpenter/karpenter --version ${KARPENTER_VERSION} --namespace karpenter \ --set settings.aws.defaultInstanceProfile=KarpenterInstanceProfile \ --set settings.aws.clusterEndpoint="${CLUSTER_ENDPOINT}" \ --set settings.aws.clusterName=${CLUSTER_NAME} \ --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"="arn:aws:iam::${AWS_ACCOUNT_ID}:role/KarpenterControllerRole-${CLUSTER_NAME}" > karpenter.yaml
3. Karpenter가 기존 노드 그룹 노드 중 하나에서 실행되도록 선호도를 설정합니다. 배포 어피니티 규칙을 찾은 다음 방금 생성한 karpenter.yaml 파일에서 수정합니다.
affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: karpenter.sh/provisioner-name operator: DoesNotExist - matchExpressions: - key: eks.amazonaws.com/nodegroup operator: In values: - ${NODEGROUP}
Karpenter 네임스페이스 생성
필요한 Karpenter 네임스페이스 및 프로비저너 CRD를 생성합니다. 그런 다음 나머지 Karpenter의 리소스를 배치합니다.
kubectl create namespace karpenter kubectl create -f https://raw.githubusercontent.com/aws/karpenter/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.sh_provisioners.yaml kubectl create -f https://raw.githubusercontent.com/aws/karpenter/${KARPENTER_VERSION}/pkg/apis/crds/karpenter.k8s.aws_awsnodetemplates.yaml kubectl apply -f karpenter.yaml
기본 프로비저너 생성
Karpenter가 예정되지 않은 워크로드에 대해 원하는 노드 유형을 알 수 있도록 기본 프로비저너를 생성합니다. 구체적인 예시에 대한 자세한 내용은 GitHub 웹 사이트의 aws/karpenter를 참조하십시오.
cat <<EOF | kubectl apply -f - apiVersion: karpenter.sh/v1alpha5 kind: Provisioner metadata: name: default spec: requirements: - key: karpenter.k8s.aws/instance-category operator: In values: [c, m, r] - key: karpenter.k8s.aws/instance-generation operator: Gt values: ["2"] providerRef: name: default ttlSecondsAfterEmpty: 30 --- apiVersion: karpenter.k8s.aws/v1alpha1 kind: AWSNodeTemplate metadata: name: default spec: subnetSelector: karpenter.sh/discovery: "${CLUSTER_NAME}" securityGroupSelector: karpenter.sh/discovery: "${CLUSTER_NAME}" EOF
Karpenter 크기 조정 및 검증
다음 단계를 사용하여 Karpenter 및 기타 중요한 서비스를 지원하기 위해 노드 그룹을 최소 두 개 이상의 노드로 확장합니다.
1. 스케일링 구성:
aws eks update-nodegroup-config --cluster-name ${CLUSTER_NAME} \ --nodegroup-name ${NODEGROUP} \ --scaling-config "minSize=2,maxSize=2,desiredSize=2"
2. 워크로드의 크기를 조정한 다음 Karpenter가 워크로드를 프로비저닝하기 위한 새 노드를 생성하고 있는지 확인합니다.
kubectl logs -f -n karpenter -c controller -l app.kubernetes.io/name=karpenter
참고: 컨트롤러 로그에서 webhook.DefaultingWebhook 조정 오류가 발견되면 Karpenter 포드를 재시작하여 문제를 해결합니다.
3. 다음 명령을 실행하여 노드의 상태를 확인합니다.
kubectl get nodes

eksctl로 Karpenter Controller Role생성 부분은 이렇게 바꿔주어야 합니다.
--role-name “$KarpenterControllerRole-${CLUSTER_NAME}" \
대신
--role-name “KarpenterControllerRole-${CLUSTER_NAME}" \
의견을 작성해 주셔서 감사합니다. 필요에 따라 지식 센터 문서를 검토하고 업데이트하겠습니다.
관련 콘텐츠
- 질문됨 7달 전lg...
- 질문됨 20일 전lg...
- 질문됨 3달 전lg...
- AWS 공식업데이트됨 5달 전
- AWS 공식업데이트됨 4달 전
- AWS 공식업데이트됨 6달 전