EKS’te Karpenter’ı Terraform ile Etkinleştirmek: Neden Gerekli ve Nasıl Yapılır?
Kubernetes kümelerinde kaynak yönetimi ve maliyet optimizasyonu, modern bulut altyapılarının en kritik bileşenlerinden biri haline geldi. Amazon EKS (Elastic Kubernetes Service) üzerinde dinamik ve verimli bir node sağlama mekanizması arayanlar için Karpenter, Terraform ile entegre edildiğinde güçlü ve dönüştürücü bir çözüm sunar. Bu makalede, Karpenter’ın ne olduğunu, EKS ortamında neden bu kadar önemli olduğunu ve altyapıyı kod olarak yönetme (Infrastructure as Code – IaC) yaklaşımının bir parçası olarak Terraform kullanarak adım adım nasıl kurulacağını derinlemesine inceleyeceğiz. Amacımız, hem yeni başlayanların konuyu temelden anlamasını sağlamak hem de deneyimli kullanıcılar için pratik kurulum adımları ve gelişmiş ipuçları sunmaktır.
Günümüzün hızla değişen dijital dünyasında, uygulamaların anlık taleplere göre ölçeklenebilmesi hayati önem taşır. Geleneksel yöntemlerle bu ölçeklenebilirliği sağlamak hem maliyetli hem de operasyonel olarak karmaşık olabilir. İşte tam da bu noktada Karpenter gibi akıllı bir node sağlayıcı devreye giriyor. Özellikle AWS ekosisteminde, EKS kümelerinizdeki pod’ların ihtiyaçlarına göre en uygun EC2 instance’larını otomatik ve hızlı bir şekilde temin ederek, hem performans artışı hem de önemli ölçüde maliyet tasarrufu vaat ediyor. Terraform ile bu kurulumu otomatize etmek ise, altyapınızın tutarlılığını ve yönetilebilirliğini artırarak size büyük bir kolaylık sunar.
Karpenter Nedir ve Geleneksel Otomatik Ölçeklendirmeden Farkı Ne?
Karpenter, AWS tarafından geliştirilen, Kubernetes kümeleri için yüksek performanslı, esnek ve maliyet optimize edilmiş bir node sağlayıcıdır. Geleneksel Kubernetes Cluster Autoscaler (Küme Otomatik Ölçeklendiricisi) ile karşılaştırıldığında, Karpenter’ın çalışma mantığı ve sunduğu avantajlar onu öne çıkarır. Cluster Autoscaler, pod’ların planlanamadığı durumlarda mevcut node gruplarındaki node sayısını artırarak çalışır. Bu, genellikle önceden tanımlanmış node gruplarına bağlıdır ve yeni bir node’un başlatılması için belirli bir bekleme süresi gerektirebilir. Ayrıca, farklı iş yükleri için farklı node grupları tanımlamak operasyonel karmaşıklığı artırır. Karpenter ise bu süreci çok daha dinamik ve verimli bir şekilde ele alır.
Karpenter’ın temel farkı, pod’ların bekleyen durumlarını doğrudan gözlemlemesi ve bu pod’ların gereksinimlerini (CPU, bellek, GPU, depolama, mimari vb.) karşılayacak en uygun EC2 instance’ını AWS API’leri aracılığıyla anında sağlamasıdır. Bu “tam zamanında (just-in-time)” provisioning (kaynak sağlama) yaklaşımı, node’ların gereksiz yere bekletilmesinin veya yanlış boyutlandırılmasının önüne geçer. Örneğin, bir pod sadece 1 CPU ve 2GB bellek istiyorsa, Karpenter tam da bu gereksinimleri karşılayacak en küçük ve uygun maliyetli instance’ı bulmaya çalışır. Bu, özellikle Spot Instance’lar (kesintiye uğrayabilen, daha uygun maliyetli EC2 instance’ları) ve farklı mimariler (Graviton gibi) kullanıldığında büyük maliyet avantajları sağlar.
Karpenter’ın sunduğu başlıca faydalar şunlardır:
- Daha Hızlı Ölçeklenme: Pod’ların bekleyen durumlarını anında algılar ve saniyeler içinde yeni node’ları devreye alır. Bu, uygulamaların ani yük artışlarına çok daha hızlı yanıt vermesini sağlar.
- Gelişmiş Maliyet Optimizasyonu: En uygun instance tipini, Spot Instance’ları ve farklı Availability Zone’ları (Erişim Alanları) akıllıca seçerek maliyetleri önemli ölçüde düşürür. Gereksiz kaynakların önüne geçer.
- Basitleştirilmiş Yönetim: Önceden tanımlanmış node grupları (Managed Node Groups veya Self-Managed Node Groups) yönetme ihtiyacını ortadan kaldırır. Tüm node provisioning süreci tek bir kontrol düzlemi üzerinden yönetilir.
- Akıllı Konsolidasyon: Kullanılmayan veya düşük kullanılan node’ları otomatik olarak tespit eder, üzerindeki pod’ları başka node’lara taşıyarak gereksiz node’ları sonlandırır. Bu da sürekli maliyet optimizasyonu sağlar.
- Esneklik: İş yüklerinizin gereksinimlerine göre farklı instance tipleri, mimariler ve Availability Zone’lar arasında sorunsuz geçiş yapabilir.
Özetle, Karpenter, EKS kümelerinizde otomasyonu bir adım öteye taşıyarak, daha çevik, daha maliyet-etkin ve daha az operasyonel yükle yönetilebilir bir altyapı sunar. Geleneksel Cluster Autoscaler’ın aksine, node gruplarına bağlı kalmadan doğrudan pod taleplerine yanıt vermesi, onu modern Kubernetes ortamları için vazgeçilmez bir araç haline getirir.
EKS Ortamında Karpenter Neden Bu Kadar Değerli?
Amazon EKS, işletmelere esneklik ve ölçeklenebilirlik sunsa da, kaynak yönetimi ve maliyet kontrolü her zaman bir meydan okuma olmuştur. Karpenter, EKS ortamının doğasında bulunan bu zorluklara doğrudan yanıt vererek, bulut altyapınızdan en iyi şekilde yararlanmanızı sağlar. Özellikle dinamik iş yüklerine sahip uygulamalar için Karpenter’ın sağladığı avantajlar paha biçilmezdir.
Maliyet Optimizasyonu Nasıl Sağlanır?
Karpenter’ın EKS’teki en büyük değer önerilerinden biri, maliyet optimizasyonudur. Geleneksel yöntemlerde, genellikle en kötü senaryoyu düşünerek fazla kaynak ayırma eğilimi vardır. Karpenter ise bu israfı ortadan kaldırır:
- Spot Instance’lardan Maksimum Fayda: Karpenter, uygun maliyetli Spot Instance’ları akıllıca kullanma yeteneğine sahiptir. Pod’larınızın toleranslarına ve kesinti toleransına göre Spot Instance’ları tercih ederek, On-Demand (İsteğe Bağlı) fiyatlarına kıyasla %70-90’a varan tasarruflar sağlayabilir. Spot Instance’lar kesintiye uğradığında, Karpenter pod’ları otomatik olarak başka bir node’a taşır ve yeni bir Spot veya On-Demand node sağlar.
- Doğru Instance Tipi Seçimi: İş yüklerinizin CPU, bellek ve diğer kaynak gereksinimlerine en uygun EC2 instance tipini dinamik olarak seçer. Örneğin, yoğun işlem gücü gerektirmeyen uygulamalar için daha küçük, daha uygun maliyetli instance’ları tercih edebilir. Ayrıca, ARM tabanlı Graviton işlemcili instance’ları kullanarak ek maliyet avantajları sunabilir.
- Hızlı Ölçeklenme ile Gereksiz Kaynakların Önüne Geçme: Uygulamalarınızın anlık taleplerine göre hızlıca ölçeklenmesi, boşta duran veya düşük kullanılan node’ların sayısını minimize eder. Talep düştüğünde ise Karpenter, node’ları hızla konsolide eder ve gereksiz olanları sonlandırır, böylece sürekli bir maliyet optimizasyonu döngüsü sağlar.
Performans ve Hız Avantajları Nelerdir?
Maliyetin yanı sıra, performans ve hız da Karpenter’ın EKS’e kattığı önemli değerlerdir:
- Pod’ların Hızlıca Planlanması: Cluster Autoscaler’ın node gruplarını ölçeklendirme ve yeni node’ların devreye girmesi için geçen süreyi önemli ölçüde kısaltır. Karpenter, pod’ların bekleyen durumunu görür görmez, doğrudan AWS API’leri ile iletişime geçerek saniyeler içinde yeni bir EC2 instance’ı başlatır ve Kubernetes kümesine dahil eder.
- Talebe Göre Anında Node Sağlama: Yoğun trafik dönemlerinde veya anlık iş yükü artışlarında, uygulamalarınızın kesintisiz çalışmasını sağlar. Yeni pod’lar için node beklemek zorunda kalmazsınız, bu da kullanıcı deneyimini iyileştirir ve iş sürekliliğini artırır.
- Uygulama Başlatma Sürelerinin Kısalması: Yeni node’ların hızla devreye alınması, yeni uygulamaların veya mikroservislerin daha hızlı başlatılmasına olanak tanır. Bu, özellikle CI/CD (Sürekli Entegrasyon/Sürekli Teslimat) süreçlerinde ve kısa ömürlü iş yüklerinde (örneğin, batch processing) büyük avantaj sağlar.
Operasyonel Yükü Nasıl Azaltır?
Karpenter, EKS’teki operasyonel karmaşıklığı azaltarak DevOps ekiplerinin hayatını kolaylaştırır:
- Node Group Yönetimi Karmaşasını Ortadan Kaldırma: Geleneksel EKS kurulumlarında, farklı iş yükleri için farklı node grupları oluşturmak, bunları manuel olarak veya Cluster Autoscaler ile yönetmek operasyonel bir yük getirir. Karpenter, tek bir kontrol düzlemiyle tüm node provisioning’i yöneterek bu karmaşayı ortadan kaldırır. Artık node gruplarının boyutunu, instance tiplerini veya AMI’lerini (Amazon Machine Image) sürekli olarak güncellemenize gerek kalmaz.
- Basitleştirilmiş Konfigürasyon: Karpenter, Custom Resource Definition (CRD) olarak tanımlanan Provisioner kaynakları aracılığıyla basit ve deklaratif bir konfigürasyon sunar. Bu, node sağlama politikalarınızı kod olarak yönetmenizi ve sürüm kontrolüne almanızı kolaylaştırır.
Gerçek Dünya Senaryosu: E-ticaret Sitesinin Anlık Kampanya Dönemleri
Bir e-ticaret sitesinin Kara Cuma veya Sevgililer Günü gibi özel kampanya dönemlerinde trafik yoğunluğunda %500’e varan artışlar yaşadığını düşünelim. Geleneksel bir EKS kurulumunda, bu ani yük artışını karşılamak için ya önceden çok fazla kaynak ayırmak (ve kampanya dışında boşta bırakmak) ya da Cluster Autoscaler’ın yavaş ölçeklenmesi nedeniyle performans sorunları yaşamak gerekebilir. Karpenter ile bu sorun ortadan kalkar. Kampanya başladığında, yeni gelen pod’lar için Karpenter anında uygun Spot Instance’ları sağlayarak, sitenin kesintisiz ve yüksek performansla çalışmasını garanti eder. Kampanya bittiğinde ise, kullanılmayan node’ları otomatik olarak sonlandırarak maliyetleri optimize eder. Bu sayede, hem müşteri memnuniyeti artar hem de gereksiz bulut harcamalarının önüne geçilir.
Karpenter’ı EKS’e Kurmadan Önce Neleri Bilmelisiniz?
Karpenter’ı Amazon EKS kümenize entegre etmek, doğru bir planlama ve ön hazırlık gerektirir. Kuruluma başlamadan önce belirli ön koşulları anlamak ve gerekli araçları hazırlamak, sorunsuz bir geçiş için kritik öneme sahiptir. Terraform ile bu süreci otomatize etmek, altyapınızın tutarlılığını ve yönetilebilirliğini sağlarken, aynı zamanda tekrarlanabilir bir dağıtım modeli sunar.
Ön Koşullar ve Gerekli AWS İzinleri
Karpenter’ın EKS üzerinde verimli bir şekilde çalışabilmesi için bazı temel gereksinimler bulunmaktadır:
- Mevcut Bir EKS Kümesi: Karpenter, üzerinde çalışacağı bir EKS kümesine ihtiyaç duyar. Bu küme,
kubectlile erişilebilir durumda olmalıdır. - IAM Rolleri ve Politikaları: Karpenter’ın AWS kaynaklarını (EC2 instance’ları, Launch Template’ler, Spot Fleet’ler vb.) yönetebilmesi için belirli AWS IAM (Identity and Access Management) izinlerine sahip olması gerekir. Bu izinler, Karpenter Controller için bir IAM rolü ve Karpenter tarafından başlatılacak EC2 node’ları için bir IAM instance profili aracılığıyla sağlanır. Özellikle, Karpenter’ın EC2 instance’larını başlatma, sonlandırma, etiketleme ve yönetme yetkisine sahip olması şarttır.
- VPC ve Subnet Etiketleme: Karpenter, node’ları başlatırken hangi VPC (Virtual Private Cloud) ve subnet’leri kullanacağını anlamak için belirli etiketlere ihtiyaç duyar. Bu etiketler, Karpenter’ın doğru ağ kaynaklarını hedeflemesini sağlar. Genellikle
kubernetes.io/cluster/<cluster-adı>: ownedvekarpenter.sh/discovery: <cluster-adı>gibi etiketler kullanılır. - EKS OIDC Sağlayıcısı: Karpenter Controller’ın AWS API’leriyle güvenli bir şekilde iletişim kurabilmesi için EKS kümenizin bir OpenID Connect (OIDC) sağlayıcısına sahip olması gerekir. Bu, Kubernetes Service Account’larına AWS IAM rolü atamayı (IRSA – IAM Roles for Service Accounts) mümkün kılar.
- Kubeconfig Erişimi: Terraform’un Kubernetes kaynaklarını yönetebilmesi için EKS kümenize erişim sağlayan bir
kubeconfigdosyasına veya uygun kimlik doğrulama mekanizmalarına sahip olması gerekir.
Terraform’un Rolü ve Avantajları
Terraform, Karpenter’ın EKS üzerindeki kurulumunu otomatize etmek için ideal bir araçtır. Altyapıyı Kod Olarak (IaC) yönetme yaklaşımını benimseyerek birçok avantaj sunar:
- Tekrarlanabilirlik ve Tutarlılık: Terraform kodunuzu kullanarak Karpenter’ı ve bağımlılıklarını birden fazla EKS kümesinde veya farklı ortamlarda (geliştirme, test, üretim) tutarlı bir şekilde dağıtabilirsiniz. Bu, manuel yapılandırma hatalarını en aza indirir.
- Versiyonlama ve Denetlenebilirlik: Tüm altyapı yapılandırmanız kod olarak saklandığı için, versiyon kontrol sistemleriyle (Git gibi) yönetilebilir. Bu, değişiklikleri izlemenizi, geri almanızı ve kimin ne zaman hangi değişikliği yaptığını denetlemenizi sağlar.
- Hata Azaltma: Manuel kurulum adımları sırasında oluşabilecek insan hatalarını ortadan kaldırır. Terraform, tanımladığınız nihai duruma ulaşmak için en uygun yolu otomatik olarak planlar ve uygular.
- Tüm Bağımlılıkları Tek Bir Yerden Yönetme: Karpenter’ın kendisi, IAM rolleri, politikalar, VPC etiketlemeleri ve Helm chart dağıtımı gibi tüm bağımlılıkları tek bir Terraform projesi içinde yönetebilirsiniz. Bu, kurulum ve bakım sürecini büyük ölçüde basitleştirir.
Gerekli Araçlar
Kuruluma başlamadan önce sisteminizde aşağıdaki araçların yüklü ve yapılandırılmış olduğundan emin olun:
- AWS CLI (Komut Satırı Arayüzü): AWS kaynaklarını yönetmek ve kimlik doğrulaması yapmak için gereklidir.
- kubectl: Kubernetes kümeleriyle etkileşim kurmak ve Karpenter’ın dağıtımını doğrulamak için kullanılır.
- Terraform: Altyapıyı kod olarak dağıtmak için ana aracımız.
- Helm (isteğe bağlı ama önerilir): Karpenter’ı Kubernetes’e Helm chart olarak dağıtmak için kullanılır. Terraform’un Helm provider’ı aracılığıyla da yönetilebilir.
Bu ön koşulları yerine getirerek ve gerekli araçları hazırlayarak, Karpenter’ı EKS kümenize Terraform ile başarılı bir şekilde entegre etmek için sağlam bir temel oluşturmuş olursunuz. Bir sonraki bölümde, bu adımları pratik kod örnekleriyle detaylandıracağız.
Karpenter’ı Terraform ile EKS Üzerinde Adım Adım Kurulumu
Karpenter’ı EKS kümenize Terraform ile entegre etmek, birkaç ana adımdan oluşur: gerekli IAM rollerini ve politikalarını oluşturmak, VPC ve subnet’lerinizi etiketlemek, Karpenter Helm chart’ını dağıtmak ve son olarak Karpenter Provisioner kaynaklarını tanımlamak. Bu adımları sırasıyla uygulayarak, otomatik ölçeklenen ve maliyet-etkin bir Kubernetes altyapısı kurabilirsiniz.
Bu bölümde, adım adım Terraform kod blokları ile Karpenter kurulumunu gerçekleştireceğiz. Lütfen <YOUR_CLUSTER_NAME>, <YOUR_AWS_REGION> ve <YOUR_ACCOUNT_ID> gibi yer tutucuları kendi ortamınıza göre güncellemeyi unutmayın.
1. IAM Rolleri ve Politikaları Oluşturma
Karpenter’ın AWS kaynaklarıyla etkileşim kurabilmesi için iki ana IAM rolüne ihtiyacımız var: Karpenter Controller için bir rol ve Karpenter tarafından başlatılacak EC2 node’ları için bir instance profili. Bu rol ve profiller, gerekli izinleri içermelidir.
# main.tf
# Karpenter Controller için IAM Rolü ve Politikası
resource "aws_iam_role" "karpenter_controller_role" {
name = "KarpenterControllerRole-${var.cluster_name}"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Federated = "arn:aws:iam::${data.aws_caller_identity.current.account_id}:oidc-provider/${replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")}"
},
Action = "sts:AssumeRoleWithWebIdentity",
Condition = {
StringEquals = {
"${replace(data.aws_eks_cluster.cluster.identity[0].oidc[0].issuer, "https://", "")}:sub" = "system:serviceaccount:karpenter:karpenter"
}
}
}
]
})
}
resource "aws_iam_role_policy_attachment" "karpenter_controller_policy_attach" {
policy_arn = "arn:aws:iam::aws:policy/KarpenterControllerPolicy" # Bu politikayı manuel olarak veya başka bir Terraform resource ile oluşturmanız gerekebilir.
role = aws_iam_role.karpenter_controller_role.name
}
# Karpenter Controller için gerekli özel izinler (örnek)
resource "aws_iam_policy" "karpenter_controller_custom_policy" {
name = "KarpenterControllerCustomPolicy-${var.cluster_name}"
description = "Karpenter Controller için özel izinler"
policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Action = [
"ec2:CreateLaunchTemplate",
"ec2:CreateFleet",
"ec2:RunInstances",
"ec2:CreateTags",
"ec2:TerminateInstances",
"ec2:DeleteLaunchTemplate",
"ec2:DescribeLaunchTemplates",
"ec2:DescribeInstances",
"ec2:DescribeImages",
"ec2:DescribeSubnets",
"ec2:DescribeSecurityGroups",
"ec2:DescribeInstanceTypes",
"ec2:DescribeInstanceTypeOfferings",
"ec2:DescribeAvailabilityZones",
"ssm:GetParameter" # Eğer SSM parametrelerinden AMI çekiyorsanız
],
Resource = "*"
},
{
Effect = "Allow",
Action = "iam:PassRole",
Resource = aws_iam_role.karpenter_node_role.arn # Node Instance Profile rolünü burada referans veriyoruz
}
]
})
}
resource "aws_iam_role_policy_attachment" "karpenter_controller_custom_policy_attach" {
policy_arn = aws_iam_policy.karpenter_controller_custom_policy.arn
role = aws_iam_role.karpenter_controller_role.name
}
# Karpenter Node'ları için IAM Rolü (Instance Profile)
resource "aws_iam_role" "karpenter_node_role" {
name = "KarpenterNodeRole-${var.cluster_name}"
assume_role_policy = jsonencode({
Version = "2012-10-17",
Statement = [
{
Effect = "Allow",
Principal = {
Service = "ec2.amazonaws.com"
},
Action = "sts:AssumeRole"
}
]
})
}
resource "aws_iam_instance_profile" "karpenter_node_instance_profile" {
name = "KarpenterNodeInstanceProfile-${var.cluster_name}"
role = aws_iam_role.karpenter_node_role.name
}
# Node'lar için gerekli politikalar (örnek)
resource "aws_iam_role_policy_attachment" "karpenter_node_amazon_eks_worker_node_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKSWorkerNodePolicy"
role = aws_iam_role.karpenter_node_role.name
}
resource "aws_iam_role_policy_attachment" "karpenter_node_amazon_eks_cni_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy"
role = aws_iam_role.karpenter_node_role.name
}
resource "aws_iam_role_policy_attachment" "karpenter_node_amazon_ec2_container_registry_readonly_policy" {
policy_arn = "arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryReadOnly"
role = aws_iam_role.karpenter_node_role.name
}
# EKS Cluster ve Caller Identity verilerini çekme
data "aws_eks_cluster" "cluster" {
name = var.cluster_name
}
data "aws_caller_identity" "current" {}
Yukarıdaki kod bloğu, Karpenter Controller için bir IAM rolü ve bir de Karpenter tarafından başlatılacak EC2 instance’ları için bir IAM rolü (instance profile) tanımlar. Controller rolü, OIDC sağlayıcısı üzerinden Kubernetes Service Account’ı ile ilişkilendirilirken, node rolü EC2 instance’larının üzerine atanır.
2. VPC ve Subnet Etiketlemesi
Karpenter’ın doğru VPC ve subnet’leri bulabilmesi için bu kaynaklara belirli etiketler eklememiz gerekiyor. Bu etiketler, Karpenter’ın ağ yapılandırmanızı otomatik olarak keşfetmesini sağlar.
# main.tf
# VPC Etiketlemesi
resource "aws_vpc" "eks_vpc" {
# ... mevcut VPC tanımınız veya yeni VPC oluşturma ...
tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "owned"
}
}
# Subnet Etiketlemesi (Örnek olarak public subnet'ler)
resource "aws_subnet" "public_subnet_a" {
# ... mevcut subnet tanımınız veya yeni subnet oluşturma ...
vpc_id = aws_vpc.eks_vpc.id
cidr_block = "10.0.1.0/24"
availability_zone = "${var.aws_region}a"
tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "owned"
"karpenter.sh/discovery" = var.cluster_name
}
}
resource "aws_subnet" "public_subnet_b" {
# ... mevcut subnet tanımınız veya yeni subnet oluşturma ...
vpc_id = aws_vpc.eks_vpc.id
cidr_block = "10.0.2.0/24"
availability_zone = "${var.aws_region}b"
tags = {
"kubernetes.io/cluster/${var.cluster_name}" = "owned"
"karpenter.sh/discovery" = var.cluster_name
}
}
# Özel subnet'ler için de benzer etiketlemeler yapılmalıdır.
# Örneğin, özel subnet'ler için "kubernetes.io/role/internal-elb" etiketi ekleyebilirsiniz.
Bu etiketler, Karpenter’ın hangi VPC ve subnet’leri kullanarak EC2 instance’larını başlatacağını belirlemesine yardımcı olur. Özellikle karpenter.sh/discovery etiketi, Karpenter için kritik öneme sahiptir.
3. Karpenter Helm Chart’ı Kurulumu
Karpenter, Kubernetes kümesine bir Helm chart olarak dağıtılır. Terraform’un Helm provider’ını kullanarak bu dağıtımı otomatize edebiliriz. Bu adımda, önceki adımlarda oluşturduğumuz IAM rolünü ve diğer küme bilgilerini Helm chart’ına parametre olarak geçireceğiz.
# main.tf
# Helm provider tanımı (eğer daha önce yapmadıysanız)
provider "helm" {
kubernetes {
host = data.aws_eks_cluster.cluster.endpoint
cluster_ca_certificate = base64decode(data.aws_eks_cluster.cluster.certificate_authority[0].data)
exec {
api_version = "client.authentication.k8s.io/v1beta1"
command = "aws"
args = ["eks", "get-token", "--cluster-name", var.cluster_name, "--region", var.aws_region]
}
}
}
# Karpenter Helm Chart Kurulumu
resource "helm_release" "karpenter" {
name = "karpenter"
repository = "oci://public.ecr.aws/karpenter/karpenter"
chart = "karpenter"
namespace = "karpenter"
create_namespace = true
version = "0.33.0" # Kullandığınız Karpenter versiyonunu belirtin
set {
name = "serviceAccount.annotations.eks\\.amazonaws\\.com/role-arn"
value = aws_iam_role.karpenter_controller_role.arn
type = "string"
}
set {
name = "settings.aws.clusterName"
value = var.cluster_name
type = "string"
}
set {
name = "settings.aws.defaultInstanceProfile"
value = aws_iam_instance_profile.karpenter_node_instance_profile.name
type = "string"
}
set {
name = "settings.aws.interruptionQueueName"
value = "karpenter-${var.cluster_name}" # Opsiyonel: Spot kesinti bildirimleri için SQS kuyruğu
type = "string"
}
}
Bu Helm chart dağıtımı, Karpenter Controller’ı EKS kümenize kurar ve Controller’ın hangi IAM rolünü kullanacağını, hangi küme adı için çalıştığını ve node’ları başlatırken hangi instance profilini kullanacağını belirtir.
4. Provisioner Kaynağı Tanımlama
Karpenter’ın nasıl node sağlayacağını belirleyen ana konfigürasyon, bir Custom Resource Definition (CRD) olan Provisioner kaynağıdır. Bu kaynak, hangi instance tiplerinin kullanılabileceği, hangi Availability Zone’larda çalışılacağı, Spot veya On-Demand tercihi gibi kuralları tanımlar. Terraform’da bu kaynağı kubernetes_manifest kaynağını kullanarak tanımlayabiliriz.
# provisioner.tf
resource "kubernetes_manifest" "default_provisioner" {
provider = kubernetes
manifest = {
apiVersion = "karpenter.sh/v1beta1"
kind = "Provisioner"
metadata = {
name = "default"
}
spec = {
requirements = [
{
key = "karpenter.k8s.aws/instance-category"
operator = "In"
values = ["c", "m", "r"] # Compute, Memory, General Purpose instance kategorileri
},
{
key = "topology.kubernetes.io/zone"
operator = "In"
values = ["${var.aws_region}a", "${var.aws_region}b", "${var.aws_region}c"] # Kullanılacak AZ'ler
},
{
key = "kubernetes.io/arch"
operator = "In"
values = ["amd64"] # Veya ["arm64"] Graviton için
},
{
key = "karpenter.sh/capacity-type"
operator = "In"
values = ["spot", "on-demand"] # Spot veya On-Demand tercihleri
},
]
limits = {
resources = {
cpu = "1000" # Kümenin toplam CPU limiti
memory = "1000Gi" # Kümenin toplam bellek limiti
}
}
providerRef = {
name = "default" # AWSNodeTemplate için referans
}
ttlSecondsAfterEmpty = 30 # Node boşaldıktan 30 saniye sonra sonlandır
ttlSecondsUntilExpired = 2592000 # 30 gün sonra node'ları yenile (güvenlik güncellemeleri için)
}
}
}
resource "kubernetes_manifest" "aws_node_template" {
provider = kubernetes
manifest = {
apiVersion = "karpenter.k8s.aws/v1beta1"
kind = "AWSNodeTemplate"
metadata = {
name = "default"
}
spec = {
subnetSelector = {
"karpenter.sh/discovery" = var.cluster_name
}
securityGroupSelector = {
"kubernetes.io/cluster/${var.cluster_name}" = "owned"
}
instanceProfile = aws_iam_instance_profile.karpenter_node_instance_profile.name
# Eğer özel bir AMI kullanmak isterseniz:
# amiSelector = {
# "karpenter.k8s.aws/instance-family" = "al2023" # Veya "bottlerocket", "ubuntu"
# }
}
}
}
Bu Provisioner ve AWSNodeTemplate kaynakları, Karpenter’a hangi tür EC2 instance’larını, hangi kısıtlamalarla ve hangi ağ ayarlarıyla başlatması gerektiğini söyler. Örneğin, requirements bölümünde instance kategorilerini, Availability Zone’ları ve kapasite tiplerini belirleyebilirsiniz. ttlSecondsAfterEmpty gibi parametreler ise node’ların ne zaman sonlandırılacağını kontrol eder.
Tüm bu Terraform dosyalarını oluşturduktan sonra, projenizin kök dizininde aşağıdaki komutları çalıştırarak Karpenter’ı EKS kümenize dağıtabilirsiniz:
terraform init
terraform plan
terraform apply --auto-approve
Bu adımlar tamamlandığında, Karpenter EKS kümenizde etkinleştirilmiş ve pod’larınızın ihtiyaçlarına göre dinamik olarak node sağlamaya hazır hale gelmiş olacaktır.
Karpenter’ı Test Etme ve Doğrulama
Karpenter’ın kurulumunu tamamladıktan sonra, sistemin beklendiği gibi çalıştığından emin olmak için test etmek ve doğrulamak önemlidir. Bu bölüm, Karpenter’ın otomatik ölçeklenme yeteneklerini nasıl gözlemleyeceğinizi ve node azaltma (deprovisioning) mekanizmasının nasıl çalıştığını açıklar.
İlk Pod’u Dağıtma ve Ölçeklenmeyi Gözlemleme
Karpenter’ın çalışıp çalışmadığını test etmenin en iyi yolu, mevcut node’larınızda yer bulamayan, yüksek kaynak talebi olan bir Kubernetes Deployment (Dağıtım) oluşturmaktır. Bu, Karpenter’ın yeni bir node başlatmasını tetikleyecektir.
Öncelikle, kümenizde yeterli kaynak olmadığından emin olun. Ardından, aşağıdaki gibi bir Deployment tanımı oluşturun. Bu örnek, her biri 1 CPU ve 1GB bellek isteyen 50 adet NGINX pod’u başlatmaya çalışacaktır. Eğer kümenizde bu kadar kaynağı karşılayacak boş bir node yoksa, Karpenter devreye girecektir.
# test-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: high-resource-app
spec:
replicas: 50
selector:
matchLabels:
app: high-resource-app
template:
metadata:
labels:
app: high-resource-app
spec:
containers:
- name: nginx
image: nginx
resources:
requests:
cpu: "1"
memory: "1Gi"
limits:
cpu: "1"
memory: "1Gi"
Bu Deployment’ı kümenize uygulayın:
kubectl apply -f test-deployment.yaml
Şimdi Karpenter’ın davranışını gözlemleyin:
- Pod Durumlarını Kontrol Edin:
kubectl get pods -wBazı pod’ların
Pending(Beklemede) durumunda olduğunu görmelisiniz. Kısa süre sonra, Karpenter yeni node’ları sağlamaya başladıkça bu pod’larRunning(Çalışıyor) durumuna geçecektir. - Node’ları Kontrol Edin:
kubectl get nodes -wKarpenter’ın yeni EC2 instance’larını başlatıp Kubernetes kümesine eklediğini görmelisiniz. Yeni node’lar genellikle
karpenter.sh/provisioner-name: defaultgibi etiketlere sahip olacaktır. - Karpenter Loglarını Kontrol Edin:
kubectl logs -f -n karpenter $(kubectl get pods -n karpenter -l app.kubernetes.io/name=karpenter -o name)Bu komut, Karpenter Controller’ın loglarını gösterir. Loglarda “provisioning” veya “launching instance” gibi mesajlar görmelisiniz, bu da Karpenter’ın aktif olarak çalıştığını gösterir.
Node Azaltma (Deprovisioning) Mekanizması
Karpenter, sadece ölçeklenmekle kalmaz, aynı zamanda kaynak kullanımı düştüğünde gereksiz node’ları akıllıca sonlandırarak maliyet tasarrufu sağlar. Bu süreci gözlemlemek için oluşturduğumuz Deployment’ı silebiliriz:
kubectl delete -f test-deployment.yaml
Deployment silindikten sonra, Karpenter’ın node’ları nasıl boşalttığını ve sonlandırdığını gözlemleyin:
- Pod Durumlarını Kontrol Edin: Tüm
high-resource-apppod’larının sonlandığını görmelisiniz. - Node’ları Kontrol Edin:
kubectl get nodes -wKarpenter’ın başlattığı node’ların bir süre sonra
NotReadydurumuna geçip daha sonra listeden kaybolduğunu görmelisiniz. Karpenter,ttlSecondsAfterEmpty(boşaldıktan sonra yaşam süresi) vettlSecondsUntilExpired(süresi dolana kadar yaşam süresi) gibi Provisioner ayarlarınıza göre node’ları sonlandıracaktır. Konsolidasyon mekanizması sayesinde, birden fazla küçük node yerine tek bir büyük node’a geçiş gibi optimizasyonlar da yapabilir. - Karpenter Loglarını Kontrol Edin: Loglarda “deprovisioning” veya “terminating instance” gibi mesajlar arayın. Bu, Karpenter’ın node’ları aktif olarak temizlediğini gösterir.
Bu testler, Karpenter’ın hem yukarı (scale-up) hem de aşağı (scale-down) yönde otomatik ölçeklenme yeteneklerini başarıyla doğrulamanıza yardımcı olacaktır. Artık EKS kümeniz, dinamik iş yüklerine çok daha esnek ve maliyet-etkin bir şekilde yanıt verebilir.
Gelişmiş Karpenter Kullanım Senaryoları ve İpuçları
Karpenter’ın temel kurulumu ve doğrulaması önemli bir adım olsa da, gerçek dünya senaryolarında daha karmaşık ihtiyaçları karşılamak için gelişmiş özelliklerini kullanmak, maliyet ve performans avantajlarını daha da artırabilir. Bu bölümde, deneyimli kullanıcılar için Karpenter’ın daha ileri düzey kullanım senaryolarını ve ipuçlarını ele alacağız.
Farklı Provisioner Profilleri ile Esneklik
Tek bir Provisioner kaynağı genellikle yeterli olsa da, farklı iş yükleri için özelleştirilmiş node sağlama davranışları gerekebilir. Örneğin, kesintiye toleranslı batch işleri için Spot Instance’ları zorunlu kılarken, kritik öneme sahip durum bilgisi olan uygulamalar için On-Demand Instance’ları tercih edebilirsiniz.
- Spot, On-Demand, Graviton için Ayrı Profiller: Birden fazla
ProvisionerveAWSNodeTemplatetanımlayarak, farklı kapasite tipleri (Spot/On-Demand), instance aileleri (c5,m5,r5) veya mimariler (amd64,arm64– Graviton) için ayrı profiller oluşturabilirsiniz. Pod’larınızdanodeSelectorveyaaffinitykullanarak hangi Provisioner’ın kullanılacağını belirleyebilirsiniz. - Özel İş Yükleri için Etiketleme ve Tolerasyonlar: GPU gerektiren iş yükleri veya belirli donanım özellikleri isteyen uygulamalar için özel etiketler ve tolerasyonlar tanımlayarak, Karpenter’ın sadece bu iş yükleri için uygun instance’ları başlatmasını sağlayabilirsiniz. Örneğin,
karpenter.k8s.aws/instance-gpu-count: "1"gibi bir gereksinim ekleyebilirsiniz.
# gpu-provisioner.tf
resource "kubernetes_manifest" "gpu_provisioner" {
provider = kubernetes
manifest = {
apiVersion = "karpenter.sh/v1beta1"
kind = "Provisioner"
metadata = {
name = "gpu-workloads"
}
spec = {
requirements = [
{ key = "karpenter.k8s.aws/instance-gpu-count", operator = "Gt", values = ["0"] },
{ key = "karpenter.sh/capacity-type", operator = "In", values = ["on-demand"] }, # GPU genellikle Spot'ta daha riskli olabilir
# ... diğer gereksinimler ...
]
providerRef = { name = "gpu-node-template" }
ttlSecondsAfterEmpty = 300 # Daha uzun süre boşta kalabilir
}
}
}
resource "kubernetes_manifest" "gpu_node_template" {
provider = kubernetes
manifest = {
apiVersion = "karpenter.k8s.aws/v1beta1"
kind = "AWSNodeTemplate"
metadata = {
name = "gpu-node-template"
}
spec = {
instanceProfile = aws_iam_instance_profile.karpenter_node_instance_profile.name
# ... subnetSelector, securityGroupSelector ...
# amiSelector ile GPU destekli bir AMI belirleyebilirsiniz.
}
}
}
Maliyet Yönetimi ve Gözetim
Karpenter’ın maliyet optimizasyon yeteneklerinden tam olarak yararlandığınızdan emin olmak için izleme ve analiz araçlarını kullanmak önemlidir:
- Karpenter Metriklerini İzleme: Karpenter, Prometheus uyumlu metrikler yayınlar. Bu metrikleri Prometheus ve Grafana gibi araçlarla toplayarak, node sağlama hızlarını, konsolidasyon olaylarını ve node yaşam döngüsünü görselleştirebilirsiniz. Bu, Karpenter’ın ne kadar verimli çalıştığını anlamanıza yardımcı olur.
- AWS Cost Explorer ile Maliyet Analizi: AWS Cost Explorer’ı kullanarak Karpenter tarafından başlatılan EC2 instance’larının maliyetlerini takip edin. Karpenter tarafından etiketlenen kaynakları filtreleyerek, maliyet tasarruflarını net bir şekilde görebilirsiniz. Karpenter, node’lara otomatik olarak
karpenter.sh/provisioner-namevekarpenter.sh/provisioner-familygibi etiketler ekler, bu da maliyet analizinizi kolaylaştırır.
En İyi Uygulamalar
- Minimum ve Maksimum Kaynak Kısıtlamaları:
Provisionerkaynaklarınızdalimits.resourcesalanını kullanarak kümenizin toplam CPU ve bellek limitlerini belirleyin. Bu, Karpenter’ın çok fazla kaynak sağlamasını veya kümenizin beklenenden daha büyük olmasını engeller. - NodeSelector ve Toleration’lar ile Entegrasyon: Uygulama pod’larınızda
nodeSelectorvetolerationkullanarak, Karpenter’ın belirli iş yükleri için en uygun node’ları seçmesini sağlayın. Örneğin, kesintiye toleranslı pod’lar için Spot Instance’lara özel tolerasyonlar ekleyin. - Cluster Autoscaler ile Birlikte Kullanım (Geçiş Senaryoları): Mevcut EKS kümelerinde Cluster Autoscaler’dan Karpenter’a geçiş yaparken, her iki aracı bir süre paralel olarak çalıştırmak iyi bir strateji olabilir. Karpenter’ın daha agresif ve hızlı ölçeklenme davranışını gözlemleyerek, yavaş yavaş Cluster Autoscaler’ın kontrolündeki node gruplarını küçültebilirsiniz.
- AMI Yönetimi: Karpenter, genellikle AWS EKS optimize edilmiş AMI’lerini veya Bottlerocket gibi minimal AMI’leri kullanır. Eğer özel bir AMI kullanmanız gerekiyorsa,
AWSNodeTemplateiçindeamiSelectoralanını kullanarak belirtebilirsiniz. AMI’lerinizi düzenli olarak güncel tutmak, güvenlik yamaları ve performans iyileştirmeleri için önemlidir.
Vaka Analizi: Büyük Bir Veri İşleme Platformunun Maliyet Optimizasyonu
Büyük bir veri analizi şirketi, günde terabaytlarca veriyi işleyen Spark tabanlı bir platformu EKS üzerinde çalıştırıyordu. Geleneksel Cluster Autoscaler ile, Spark işlerinin ani kaynak talepleri nedeniyle genellikle büyük ve pahalı On-Demand node’lar önceden sağlanmak zorunda kalınıyordu. Bu da önemli ölçüde boşta kaynak ve yüksek bulut faturaları anlamına geliyordu. Şirket, Karpenter’ı devreye alarak, Spark işlerinin taleplerine göre anında Spot Instance’ları temin etmeye başladı. Karpenter’ın akıllı konsolidasyon mekanizması sayesinde, işler tamamlandığında node’lar hızla sonlandırıldı. Sonuç olarak, şirketin EC2 maliyetlerinde %30’un üzerinde bir düşüş yaşandı ve Spark işlerinin başlangıç süreleri de önemli ölçüde kısaldı. Bu, Karpenter’ın hem maliyet hem de performans açısından ne kadar dönüştürücü olabileceğinin somut bir örneğidir.
Sonuç ve Sıkça Sorulan Sorular
Karpenter’ı Amazon EKS kümenize Terraform ile entegre etmek, bulut altyapınızın yönetimini kökten değiştiren güçlü bir adımdır. Bu makalede, Karpenter’ın ne olduğunu, geleneksel otomatik ölçeklendirme çözümlerinden farklarını, EKS ortamında neden bu kadar değerli olduğunu ve Terraform kullanarak adım adım nasıl kurulacağını detaylı bir şekilde ele aldık. Gelişmiş kullanım senaryoları ve en iyi uygulamalarla, Karpenter’ın tüm potansiyelini nasıl ortaya çıkarabileceğinizi gösterdik.
Sonuç olarak, Karpenter, EKS kümelerinizde hızlı, maliyet-etkin ve operasyonel yükü azaltan bir node sağlama mekanizması sunar. Terraform ile bu kurulumu otomatize etmek, altyapınızın tutarlılığını, tekrarlanabilirliğini ve sürüm kontrolünü sağlayarak DevOps süreçlerinizi güçlendirir. Modern bulut uygulamalarının dinamik doğasına uyum sağlamak ve bulut harcamalarınızı optimize etmek isteyen her kuruluş için Karpenter, düşünülmesi gereken kritik bir araçtır.
Sıkça Sorulan Sorular
Karpenter Cluster Autoscaler’ın yerine mi geçiyor?
Evet, çoğu senaryoda Karpenter, Cluster Autoscaler’ın yerini almak üzere tasarlanmıştır. Cluster Autoscaler’ın aksine, Karpenter node gruplarına bağlı kalmaz ve pod taleplerine göre doğrudan EC2 instance’larını sağlar, bu da daha hızlı ölçeklenme ve daha iyi maliyet optimizasyonu sunar. Ancak, geçiş senaryolarında bir süre paralel olarak kullanılabilirler.
Karpenter sadece AWS EKS ile mi çalışır?
Karpenter, AWS tarafından geliştirildiği için öncelikli olarak AWS EKS ile entegre olacak şekilde tasarlanmıştır ve AWS’in EC2, Spot Instances gibi hizmetlerinden tam olarak yararlanır. Şu an için sadece AWS ekosisteminde desteklenmektedir.
Karpenter ile hangi instance tiplerini kullanabilirim?
Karpenter, EC2 instance kataloğundaki neredeyse tüm instance tiplerini (C, M, R, T, G serileri dahil) kullanabilir. Provisioner kaynaklarınızda requirements alanını kullanarak belirli instance ailelerini, mimarileri (amd64, arm64) ve kapasite tiplerini (spot, on-demand) tercih edebilirsiniz.
Karpenter node’ları ne zaman sonlandırır?
Karpenter, node’ları iki ana durumda sonlandırır:
- Boşta Kalma Süresi Dolduğunda (TTL After Empty): Bir node üzerindeki tüm pod’lar silindiğinde veya başka node’lara taşındığında,
ttlSecondsAfterEmptyparametresinde belirtilen süre (varsayılan 30 saniye) dolduktan sonra node’u sonlandırır. - Süresi Dolduğunda (TTL Until Expired):
ttlSecondsUntilExpiredparametresinde belirtilen yaşam süresi (varsayılan 7 gün) dolduğunda, güvenlik güncellemeleri veya daha yeni AMI’lere geçiş için node’u sonlandırır ve yerine yenisini sağlar.
Karpenter’ın maliyetleri nasıl optimize ettiğini nasıl takip edebilirim?
Karpenter’ın maliyet optimizasyonunu takip etmek için AWS Cost Explorer’ı kullanabilirsiniz. Karpenter, başlattığı EC2 instance’larına otomatik olarak karpenter.sh/provisioner-name ve karpenter.sh/provisioner-family gibi etiketler ekler. Cost Explorer’da bu etiketlere göre filtreleme yaparak, Karpenter’ın sağladığı node’ların maliyetini ve tasarruflarını detaylı bir şekilde analiz edebilirsiniz. Ayrıca, Prometheus ve Grafana ile Karpenter metriklerini izleyerek operasyonel verimliliği gözlemleyebilirsiniz.
#AWS #EKS #Karpenter #Terraform #Kubernetes #CloudMaliyetOptimizasyonu #DevOps