Modern web uygulaması geliştirmede performans, ölçeklenebilirlik ve yüksek erişilebilirlik kritik öneme sahiptir. Django tabanlı bir uygulamayı AWS EKS (Elastic Kubernetes Service) üzerinde dağıtmak, bu hedeflere ulaşmak için en güçlü stratejilerden biridir. Bu makale, Django uygulamanızı konteynerize etmekten, bir EKS kümesi kurmaya ve Kubernetes manifest dosyalarıyla dağıtımını otomatikleştirmeye kadar uçtan uca tüm süreci detaylı bir şekilde ele alacaktır.
Günümüzün rekabetçi dijital dünyasında, geliştiricilerin karşılaştığı en büyük zorluklardan biri, web uygulamalarını hem hızlı bir şekilde pazara sürmek hem de değişen taleplere göre kolayca ölçeklendirebilmektir. Django, Python tabanlı bir web çatısı olarak hızlı geliştirmeye olanak tanırken, dağıtım ve operasyonel yönetim süreçleri zaman zaman karmaşıklaşabilir. İşte bu noktada, AWS EKS gibi güçlü bulut hizmetleri devreye girer ve modern dağıtım yaklaşımlarının temelini oluşturur. Peki, mevcut sorunlar nelerdir ve AWS EKS bize nasıl yardımcı olabilir?
Geleneksel dağıtım yöntemlerinde, bir Django uygulamasını bir sunucuya kurmak genellikle manuel süreçler içerir: bağımlılıkların yönetimi, sanal ortamların oluşturulması, web sunucusu (Gunicorn/Nginx) yapılandırması ve veritabanı bağlantılarının ayarlanması. Bu yaklaşım, tek bir sunucu için kabul edilebilir olsa da, uygulamanız büyüdükçe ve birden fazla sunucuya yayılması gerektiğinde kabusa dönüşebilir. Bağımlılık çakışmaları, farklı ortamlarda (geliştirme, test, üretim) tutarsızlıklar ve manuel ölçeklendirme zorlukları sıkça karşılaşılan problemlerdir. Bu durum, “Benim makinemde çalışıyor!” klişesinin ortaya çıkış nedenidir ve geliştirme ile operasyon ekipleri arasında sürtünmelere yol açar.
Bu sorunlara çözüm olarak konteynerizasyon, özellikle de Docker, sahneye çıktı. Docker, uygulamanızı ve tüm bağımlılıklarını tek bir hafif, taşınabilir ve izole edilmiş pakette (konteynerde) bir araya getirmenizi sağlar. Böylece, uygulamanızın farklı ortamlarda tutarlı bir şekilde çalışacağından emin olursunuz. Django uygulamanızı bir Docker konteynerine paketlemek, bir kere inşa edip her yerde çalıştırma felsefesini benimsemek demektir. Bu, geliştiricilerin kendi lokal ortamlarında üretim ortamına olabildiğince yakın bir deneyimle çalışmasına olanak tanır ve dağıtım süreçlerindeki belirsizlikleri azaltır.
Ancak, birden fazla konteyneri yönetmek, özellikle mikroservis mimarisini benimsediğinizde veya uygulamanızın farklı bileşenlerini bağımsız konteynerler olarak çalıştırdığınızda hızla karmaşıklaşır. Yüksek erişilebilirlik, yük dengeleme, otomatik ölçeklendirme, hizmet keşfi ve güncellemelerin sorunsuz bir şekilde yapılması gibi konular, konteyner orkestrasyon araçlarını zorunlu kılar. İşte bu noktada Kubernetes devreye girer. Kubernetes, konteynerli iş yüklerini ve hizmetleri otomatikleştirmek için açık kaynaklı bir sistemdir. Dağıtımı, ölçeklendirmeyi ve yönetmeyi kolaylaştırır. Django uygulamanız için Kubernetes kullanmak, uygulamanızın trafik yükünü etkin bir şekilde yönetmesini, arızalara karşı dayanıklı olmasını ve ihtiyaç duyulduğunda kaynakları otomatik olarak artırıp azaltmasını sağlar.
AWS EKS (Elastic Kubernetes Service) ise, Amazon Web Services’ın yönetilen bir Kubernetes hizmetidir. EKS, Kubernetes kontrol düzlemini (master düğümleri) sizin için yönetir, böylece kontrol düzleminin karmaşık kurulumu, yedeklenmesi ve yükseltilmesi gibi operasyonel yüklerden kurtulursunuz. Siz sadece çalışan düğümleri (worker düğümleri) ve uygulamanızın dağıtımını düşünürsünüz. EKS, AWS’nin diğer hizmetleriyle (VPC, IAM, EBS, ELB gibi) sorunsuz bir şekilde entegre olur, bu da Django uygulamanız için yüksek performanslı, güvenli ve ölçeklenebilir bir altyapı oluşturmanızı kolaylaştırır. Özellikle büyük ölçekli uygulamalar ve sürekli değişen iş yükleri için EKS, operasyonel maliyetleri düşürürken geliştiricilere daha fazla esneklik sunar. Bu geçiş, sadece bir teknoloji değişikliği değil, aynı zamanda daha çevik ve dayanıklı bir yazılım geliştirme kültürü benimsemenin bir yoludur.
Uzman İpucu: Monolitik bir Django uygulamasından mikroservislere geçiş yapmayı planlıyorsanız, konteynerizasyon ve Kubernetes altyapısını erkenden benimsemek, bu geçişi çok daha sorunsuz hale getirecektir. Her bileşeni ayrı bir konteyner olarak düşünerek tasarıma başlayın.
Django Uygulamasını Konteynerize Etmek: Dockerfile Oluşturma ve Geliştirme Süreci Nasıl İşler?
Django uygulamanızı AWS EKS’te dağıtmanın ilk ve en önemli adımı, onu Docker konteynerlerine dönüştürmektir. Konteynerizasyon, uygulamanızın tüm bağımlılıkları, kütüphaneleri ve yapılandırma dosyalarıyla birlikte tek bir, taşınabilir birim halinde paketlenmesi anlamına gelir. Bu süreç, farklı ortamlarda (geliştirme, test, üretim) tutarlılık sağlar ve “benim makinemde çalışıyor” sorununu ortadan kaldırır. Şimdi, bir Django uygulamasını nasıl konteynerize edeceğimize ve bunun için bir Dockerfile’ı nasıl oluşturacağımıza yakından bakalım.
Bir Dockerfile, Docker imajınızı oluşturmak için gereken tüm komutları içeren basit bir metin dosyasıdır. Django uygulaması için ideal bir Dockerfile, Python taban imajıyla başlar, gerekli bağımlılıkları kurar, Django projenizi kopyalar ve uygulamayı çalıştırmak için bir giriş noktası tanımlar. İşte temel bir Django Dockerfile örneği:
# Python'ın hafif bir sürümünü temel imaj olarak kullan
FROM python:3.9-slim-buster
# Çalışma dizinini ayarla
WORKDIR /app
# Bağımlılıkları kopyala ve kur
# Önce requirements.txt'yi kopyalamak, Docker katmanlama (layer caching) için optimize eder
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# Django proje dosyalarını kopyala
COPY . .
# Django'nun statik dosyalarını topla
# 'collectstatic' komutu genellikle Dockerfile'da çalıştırılır
RUN python manage.py collectstatic --noinput
# Gunicorn web sunucusunu kullanarak uygulamayı çalıştır
# Eğer Gunicorn kullanıyorsanız, burayı kendi proje ve ayarlarınıza göre düzenleyin
# Örneğin: myproject.wsgi:application
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "myproject.wsgi:application"]
# Uygulamanın dinleyeceği portu belirt
EXPOSE 8000
Bu Dockerfile, Django uygulamanızı konteynerize etmek için sağlam bir başlangıç noktası sunar. İlk olarak, FROM python:3.9-slim-buster komutuyla bir Python taban imajı seçiyoruz. WORKDIR /app ile konteyner içinde çalışma dizinini belirliyoruz. requirements.txt dosyasını kopyalayıp pip install ile tüm Python bağımlılıklarını kurmak, imaj boyutunu optimize etmek ve bağımlılık katmanını ayrı tutarak yeniden inşa sürelerini hızlandırmak için önemlidir. Daha sonra, tüm Django proje dosyalarını konteyner içine kopyalıyoruz. RUN python manage.py collectstatic --noinput komutu, üretim ortamında statik dosyaların düzgün bir şekilde sunulması için kritiktir. Son olarak, CMD komutu, konteyner başlatıldığında Django uygulamasını Gunicorn web sunucusu aracılığıyla çalıştırmak için kullanılır. EXPOSE 8000 ise uygulamanın dışarıdan erişilebilir olacağı portu belirtir.
Yerel geliştirme ortamında Docker ile çalışırken, docker-compose kullanmak oldukça faydalıdır. Bu araç, uygulamanızın hizmetlerini (Django web sunucusu, PostgreSQL veritabanı, Redis vb.) tek bir docker-compose.yml dosyası aracılığıyla tanımlamanıza ve yönetmenize olanak tanır. Böylece, tüm uygulama yığınınızı tek bir komutla ayağa kaldırabilirsiniz. İşte örnek bir docker-compose.yml dosyası:
version: '3.8'
services:
web:
build: .
command: python manage.py runserver 0.0.0.0:8000
volumes:
- .:/app
ports:
- "8000:8000"
depends_on:
- db
environment:
- DATABASE_URL=postgres://user:password@db:5432/mydatabase
db:
image: postgres:13
environment:
- POSTGRES_DB=mydatabase
- POSTGRES_USER=user
- POSTGRES_PASSWORD=password
volumes:
- postgres_data:/var/lib/postgresql/data/
volumes:
postgres_data:
Bu docker-compose.yml dosyası, Django uygulamanız (web servisi) ve PostgreSQL veritabanınız (db servisi) için iki ayrı hizmet tanımlar. web servisi, mevcut dizindeki Dockerfile'ı kullanarak inşa edilir, yerel dizini konteyner içine bağlar (volumes: - .:/app), portları eşler ve veritabanı servisine bağımlılığını belirtir. db servisi ise resmi PostgreSQL imajını kullanır ve kalıcı veri depolaması için bir volume tanımlar. Bu yapılandırma ile, docker-compose up komutunu çalıştırarak Django uygulamanızı veritabanıyla birlikte kolayca ayağa kaldırabilir ve geliştirmeye başlayabilirsiniz. Konteynerize edilmiş Django uygulamanızı EKS'e taşımadan önce yerel ortamda kusursuz çalıştığından emin olmak, dağıtım sürecini önemli ölçüde basitleştirecektir.
Uzman İpucu: Üretim ortamında
requirements.txtdosyanızda sadece üretim için gerekli bağımlılıkları tutun. Geliştirme bağımlılıklarını (flake8,django-debug-toolbarvb.) ayrı birrequirements-dev.txtdosyasında yönetmek, üretim imajınızın boyutunu küçültür ve güvenlik risklerini azaltır.
AWS Altyapısını Hazırlamak: EKS Kümesi ve Yardımcı Kaynaklar Nasıl Kurulur?
Django uygulamanızı Docker konteynerlerine dönüştürdükten sonraki adım, bu konteynerleri çalıştıracak bir AWS EKS (Elastic Kubernetes Service) altyapısı hazırlamaktır. EKS, Kubernetes kontrol düzlemini sizin için yöneten bir hizmet olduğu için, karmaşık master düğüm kurulumları ve bakımları ile uğraşmanıza gerek kalmaz. Ancak, worker düğümleri, ağ yapılandırması ve IAM izinleri gibi bazı temel AWS kaynaklarını doğru bir şekilde yapılandırmanız gerekir. Bu bölüm, AWS altyapısını adım adım nasıl hazırlayacağınızı detaylandıracaktır.
İlk olarak, EKS kümenizin çalışacağı sanal ağı, yani bir VPC (Virtual Private Cloud) yapılandırmanız gerekir. VPC, AWS içinde izole edilmiş, özel bir ağ alanıdır. Bu VPC içinde, genel (public) ve özel (private) alt ağlar (subnets) oluşturmalısınız. Genel alt ağlar, internete doğrudan erişim gerektiren kaynaklar (örneğin, bir yük dengeleyici veya bir NAT ağ geçidi) için kullanılırken, özel alt ağlar, uygulamanızın çalıştığı EKS worker düğümleri gibi dahili kaynaklar için kullanılır. Bu ayrım, güvenlik açısından kritik öneme sahiptir.
Bir EKS kümesi oluşturmanın en kolay yollarından biri eksctl CLI aracını kullanmaktır. eksctl, Amazon EKS için resmi bir CLI aracıdır ve küme oluşturma, güncelleme ve silme işlemlerini basitleştirir. Aşağıda, temel bir EKS kümesi oluşturan bir eksctl yapılandırma dosyası örneği bulunmaktadır:
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
name: django-eks-cluster
region: eu-central-1
version: "1.23"
vpc:
id: "vpc-0123456789abcdef0" # Mevcut VPC ID'nizi buraya yazın
subnets:
private:
eu-central-1a: { id: "subnet-0abcdef1234567890" }
eu-central-1b: { id: "subnet-0fedcba9876543210" }
public:
eu-central-1a: { id: "subnet-0123456789abcdef1" }
eu-central-1b: { id: "subnet-0abcdef1234567892" }
managedNodeGroups:
- name: ng-general
instanceType: t3.medium
minSize: 2
maxSize: 5
desiredCapacity: 3
volumeSize: 20 # GB
labels: { app: django }
tags:
env: production
Bu yapılandırma dosyasında, kümenizin adını (django-eks-cluster), bölgesini (eu-central-1) ve Kubernetes sürümünü belirtiyorsunuz. Ardından, mevcut VPC ve alt ağlarınızın ID'lerini tanımlıyorsunuz. managedNodeGroups altında ise, EKS worker düğümlerinin yapılandırmasını yapıyorsunuz. Burada, t3.medium örnek tipinde, minimum 2, maksimum 5 ve başlangıçta 3 düğüm ile bir düğüm grubu (ng-general) oluşturuluyor. eksctl create cluster -f cluster.yaml komutuyla bu yapılandırmayı kullanarak kümenizi oluşturabilirsiniz.
IAM (Identity and Access Management) rolleri ve politikaları, EKS kümenizin ve uygulamalarınızın AWS hizmetleriyle etkileşim kurması için kritik öneme sahiptir. EKS kümesi için bir IAM rolü, kümenin AWS API'leriyle iletişim kurmasını sağlar. Benzer şekilde, EKS worker düğümleriniz için de EC2 örneklerinin EKS kontrol düzlemine katılmasına ve diğer AWS hizmetleriyle (örneğin, ECR, S3, EBS) etkileşim kurmasına izin veren bir IAM rolü gerekir. Bu roller, eksctl tarafından otomatik olarak oluşturulabilir veya manuel olarak önceden yapılandırılabilir. Ayrıca, uygulamanızın AWS kaynaklarına (örneğin, S3'e dosya yüklemek veya RDS veritabanına erişmek) erişmesi gerekiyorsa, Kubernetes hizmet hesaplarına (Service Accounts) atanacak özel IAM rolleri (IAM Roles for Service Accounts - IRSA) kullanmanız şiddetle tavsiye edilir. Bu, en az ayrıcalık (least privilege) prensibini uygulamanın en iyi yoludur.
Son olarak, konteynerize ettiğiniz Django uygulamanızın Docker imajlarını depolamak için bir AWS ECR (Elastic Container Registry) deposuna ihtiyacınız olacak. ECR, tam olarak yönetilen bir Docker konteyner imaj deposudur ve AWS ekosistemiyle sorunsuz bir şekilde entegre olur. ECR'de bir depo oluşturduktan sonra, Docker imajınızı buraya push edebilirsiniz. Bu, Kubernetes kümenizin imajları çekebileceği güvenli ve yüksek erişilebilir bir konum sağlar. Bir ECR deposu oluşturmak ve imajınızı push etmek için aşağıdaki adımları izleyebilirsiniz:
- ECR'de yeni bir depo oluşturun (örneğin,
django-app). - AWS CLI kullanarak ECR'ye oturum açma kimlik doğrulamasını alın:
aws ecr get-login-password --region eu-central-1 | docker login --username AWS --password-stdin your_aws_account_id.dkr.ecr.eu-central-1.amazonaws.com - Django uygulamanızın Docker imajını oluşturun:
docker build -t django-app . - İmajı ECR deposuna etiketleyin:
docker tag django-app:latest your_aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/django-app:latest - Etiketlenmiş imajı ECR'ye push edin:
docker push your_aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/django-app:latest
Bu adımlarla, Django uygulamanızı çalıştıracak temel AWS EKS altyapısını ve konteyner imajlarınızı depolayacak ECR deposunu başarıyla hazırlamış olursunuz. Doğru bir altyapı kurulumu, uygulamanızın istikrarlı ve güvenli bir şekilde çalışmasının temelini oluşturur. Sonraki adımda, bu altyapıya Django uygulamanızı nasıl dağıtacağımızı inceleyeceğiz.
Uzman İpucu: EKS kümenizi oluştururken, worker düğümleriniz için yeterli kaynak (CPU, RAM) sağladığınızdan emin olun. Uygulamanızın beklenen yükünü göz önünde bulundurarak
instanceTypevedesiredCapacitydeğerlerini doğru seçmek, performans ve maliyet açısından kritik öneme sahiptir.
Django Uygulamasını EKS'e Dağıtmak: Kubernetes Manifest Dosyaları ile Orkestrasyon Nasıl Yapılır?
AWS EKS kümeniz hazır ve Django uygulamanızın Docker imajı ECR'ye yüklendikten sonra, sıra Kubernetes'in gücünü kullanarak uygulamanızı bu kümeye dağıtmaya gelir. Kubernetes, uygulamalarınızı bildirimsel (declarative) bir yaklaşımla yönetmenizi sağlar. Bu, uygulamanızın istediğiniz durumunu (kaç adet kopyasının çalışacağı, hangi imajı kullanacağı, hangi portları açacağı gibi) YAML dosyaları aracılığıyla tanımladığınız ve Kubernetes'in bu duruma ulaşmak için gerekli adımları otomatik olarak attığı anlamına gelir. Bu bölüm, temel Kubernetes nesnelerini ve Django uygulamanızı EKS'e dağıtmak için gereken manifest dosyalarını detaylı olarak ele alacaktır.
Bir Kubernetes kümesinde Django uygulamanızı çalıştırmak için genellikle birden fazla Kubernetes kaynağını (object) tanımlamanız gerekir. En temel olanlar şunlardır:
- Deployment: Uygulamanızın pod'larını yöneten ve otomatik ölçeklendirme, güncelleme ve geri alma gibi yaşam döngüsü operasyonlarını sağlayan ana yapıdır. Django uygulamanızın kaç adet kopyasının (replica) çalışacağını burada belirtirsiniz.
- Service: Pod'larınıza ağ erişimi sağlayan soyut bir yapıdır. Service, pod'larınızın dinamik IP adresleri değişse bile sürekli bir erişim noktası sunar ve yük dengeleme (load balancing) işlevini de yerine getirebilir.
- Ingress: Uygulamanızın dış dünyadan erişilebilir olmasını sağlayan bir API nesnesidir. HTTP ve HTTPS trafiğini Kubernetes Service'lerine yönlendirir ve etki alanı (domain) tabanlı yönlendirme, SSL sonlandırma gibi özellikleri destekler.
- ConfigMap: Uygulama yapılandırma verilerini (örneğin, ortam değişkenleri, ayar dosyaları) depolamak için kullanılır. Bu, uygulamanızın kodundan yapılandırmayı ayırarak daha esnek ve taşınabilir olmasını sağlar.
- Secret: Hassas verileri (örneğin, veritabanı şifreleri, API anahtarları) güvenli bir şekilde depolamak için kullanılır. ConfigMap'e benzer ancak verileri şifreli olarak saklar.
Şimdi, örnek bir Django uygulaması için bu manifest dosyalarını adım adım oluşturalım. İlk olarak, Django uygulamanız için bir Deployment ve Service tanımlayalım. Bu, genellikle django-deployment.yaml gibi bir dosyada bulunur:
apiVersion: apps/v1
kind: Deployment
metadata:
name: django-app-deployment
labels:
app: django-app
spec:
replicas: 3 # Uygulamanızın 3 kopyasının çalışmasını istiyoruz
selector:
matchLabels:
app: django-app
template:
metadata:
labels:
app: django-app
spec:
containers:
- name: django-app
image: your_aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/django-app:latest # ECR'deki imajınız
ports:
- containerPort: 8000
envFrom:
- configMapRef:
name: django-config
- secretRef:
name: django-secret
---
apiVersion: v1
kind: Service
metadata:
name: django-app-service
spec:
selector:
app: django-app
ports:
- protocol: TCP
port: 80
targetPort: 8000
type: LoadBalancer # AWS ELB (Application Load Balancer) oluşturur
Yukarıdaki Deployment tanımı, Django uygulamanızın ECR'deki imajını kullanarak 3 adet Pod (uygulamanızın bir kopyası) çalıştırmasını sağlar. envFrom alanı, yapılandırma ve hassas verileri ConfigMap ve Secret nesnelerinden çekmek için kullanılır. Service tanımı ise, bu 3 Pod'a dışarıdan erişim sağlamak için bir Yük Dengeleyici (LoadBalancer) oluşturur ve gelen trafiği 80 portundan Pod'ların 8000 portuna yönlendirir. kubectl apply -f django-deployment.yaml komutuyla bu kaynakları uygulayabilirsiniz.
Veritabanı bağlantısı için, Django'nun settings.py dosyasında ortam değişkenlerini kullanarak veritabanı bağlantı bilgilerini alacak şekilde yapılandırmanız gerekir. Bu ortam değişkenleri ConfigMap ve Secret nesneleri aracılığıyla sağlanır. Öncelikle, bir ConfigMap ve Secret oluşturalım. django-config.yaml ve django-secret.yaml:
apiVersion: v1
kind: ConfigMap
metadata:
name: django-config
data:
DJANGO_SETTINGS_MODULE: myproject.settings # Projenizin ayar dosyası
DEBUG: "False" # Üretim ortamında DEBUG'ı false yapın
---
apiVersion: v1
kind: Secret
metadata:
name: django-secret
type: Opaque
data:
DATABASE_URL: base64_encoded_database_url_here # Örneğin: postgres://user:pass@host:port/dbname
SECRET_KEY: base64_encoded_django_secret_key # Django SECRET_KEY
Unutmayın ki Secret içindeki verilerin Base64 ile kodlanmış olması gerekir. Örneğin, echo -n "postgres://user:pass@host:port/dbname" | base64 komutuyla şifrenizi kodlayabilirsiniz. Bu ConfigMap ve Secret nesnelerini de kubectl apply ile uyguladıktan sonra, Django uygulamanızın Pod'ları bu değerleri ortam değişkenleri olarak alacaktır. Django settings.py dosyanızda os.environ.get('DATABASE_URL') gibi ifadelerle bu değerlere erişmeniz gerekir.
Statik dosyalar ve medya dosyaları için, üretim ortamında genellikle AWS S3 gibi bir bulut depolama hizmeti kullanılır. Django'da django-storages kütüphanesini kullanarak statik ve medya dosyalarınızı doğrudan S3'e yükleyebilir ve oradan servis edebilirsiniz. Bu, Pod'larınızın durumsuz kalmasını sağlar ve ölçeklendirme esnasında dosya yönetimi sorunlarını ortadan kaldırır. ConfigMap veya Secret aracılığıyla S3 kimlik bilgilerini ve bucket adını sağlamanız yeterli olacaktır.
Son olarak, Ingress kontrolcüleri, uygulamanıza dış dünyadan daha gelişmiş HTTP/HTTPS yönlendirme ve SSL sonlandırma özellikleri sağlar. AWS için AWS Load Balancer Controller (eski adıyla ALB Ingress Controller) kullanmak yaygın bir çözümdür. Bu kontrolcü, Kubernetes Ingress kaynaklarını dinleyerek otomatik olarak AWS Application Load Balancer (ALB) oluşturur ve yönetir. Örneğin, bir Ingress tanımı şu şekilde olabilir:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: django-app-ingress
annotations:
kubernetes.io/ingress.class: alb # AWS ALB Ingress Controller için
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
alb.ingress.kubernetes.io/listen-ports: '[{"HTTP": 80}, {"HTTPS":443}]'
alb.ingress.kubernetes.io/certificate-arn: arn:aws:acm:eu-central-1:your_aws_account_id:certificate/your_certificate_id # ACM sertifikanız
alb.ingress.kubernetes.io/ssl-redirect: 'true'
spec:
rules:
- host: yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: django-app-service
port:
number: 80
Bu Ingress, yourdomain.com adresinden gelen trafiği django-app-service'e yönlendirecektir. AWS Certificate Manager (ACM) ile yönettiğiniz bir SSL sertifikasını kullanarak HTTPS trafiğini de sonlandırabilirsiniz. kubectl apply -f django-ingress.yaml ile bu Ingress'i dağıttığınızda, AWS Load Balancer Controller otomatik olarak bir ALB oluşturacak ve gerekli yönlendirmeleri yapacaktır.
Bu adımları takip ederek, Django uygulamanızın tüm bileşenlerini (uygulama pod'ları, servisler, yapılandırmalar, hassas veriler ve dış erişim) Kubernetes üzerinde etkin bir şekilde yönetebilir ve AWS EKS'in sağladığı ölçeklenebilirlik ve yüksek erişilebilirlik avantajlarından tam olarak faydalanabilirsiniz.
Uzman İpucu: Kubernetes manifest dosyalarınızı Helm grafikleri kullanarak paketlemek, karmaşık uygulamaların dağıtımını ve yönetimini standartlaştırmak için harika bir yoldur. Helm, parametreleştirilebilir değerler (values.yaml) aracılığıyla ortamlar arası farklılıkları kolayca yönetmenizi sağlar.
CI/CD ile Otomatik Dağıtım Akışları Kurmak: GitHub Actions veya GitLab CI/CD Entegrasyonu
Modern yazılım geliştirme süreçlerinde, Continuous Integration (CI) ve Continuous Delivery/Deployment (CD) pipeline'ları, uygulamaların daha hızlı, daha güvenilir ve daha sık bir şekilde üretim ortamına çıkarılmasını sağlayan temel unsurlardır. Django uygulamanızı AWS EKS'e manuel olarak dağıtmak her ne kadar mümkün olsa da, sürekli entegrasyon ve dağıtım akışları (CI/CD pipelines) kurmak, geliştirme hızınızı artıracak, insan hatası riskini azaltacak ve operasyonel verimliliği önemli ölçüde yükseltecektir. Bu bölümde, GitHub Actions kullanarak basit bir CI/CD pipeline'ını nasıl oluşturacağınızı ele alacağız, ancak bu prensipler GitLab CI/CD, Jenkins veya CircleCI gibi diğer CI/CD araçları için de geçerlidir.
Bir CI/CD pipeline'ı genellikle şu adımlardan oluşur:
- Kod Taahhüdü (Code Commit): Geliştiriciler kodlarını bir versiyon kontrol sistemine (örneğin, Git) push eder.
- Derleme (Build): Uygulama derlenir ve varsa testler çalıştırılır. Django uygulamaları için bu, Docker imajının oluşturulması ve bağımlılıkların yüklenmesi anlamına gelir.
- Test (Test): Birim testleri, entegrasyon testleri ve gerekirse uçtan uca testler çalıştırılır.
- İmaj Oluşturma ve Gönderme (Image Build & Push): Testleri geçen Docker imajı oluşturulur ve bir konteyner kayıt defterine (örneğin, AWS ECR) gönderilir.
- Dağıtım (Deploy): Yeni oluşturulan imaj kullanılarak uygulama üretim ortamına (AWS EKS) dağıtılır.
GitHub Actions, GitHub depolarınızla entegre çalışan, esnek ve güçlü bir CI/CD platformudur. Bir .github/workflows dizini altında YAML dosyaları olarak tanımlanan iş akışları (workflows) aracılığıyla otomasyon sağlar. İşte Django uygulamanız için ECR'ye imaj gönderme ve EKS'e dağıtım yapma adımlarını içeren örnek bir GitHub Actions workflow'u:
name: Django EKS CI/CD
on:
push:
branches:
- main # main dalına yapılan her push'ta tetiklenir
env:
AWS_REGION: eu-central-1
ECR_REPOSITORY: django-app
EKS_CLUSTER_NAME: django-eks-cluster
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Configure AWS credentials
uses: aws-actions/configure-aws-credentials@v1
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: ${{ env.AWS_REGION }}
- name: Login to Amazon ECR
id: login-ecr
uses: aws-actions/amazon-ecr-login@v1
- name: Build, tag, and push image to ECR
id: build-image
env:
ECR_REGISTRY: ${{ steps.login-ecr.outputs.registry }}
IMAGE_TAG: ${{ github.sha }}
run: |
docker build -t $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG .
docker push $ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG
echo "::set-output name=image::$ECR_REGISTRY/$ECR_REPOSITORY:$IMAGE_TAG"
- name: Setup kubectl
uses: aws-actions/setup-kubectl@v1
with:
version: 'latest'
- name: Update kubeconfig
run: |
aws eks update-kubeconfig --name ${{ env.EKS_CLUSTER_NAME }} --region ${{ env.AWS_REGION }}
- name: Deploy to EKS
run: |
# Kubernetes manifest dosyanızdaki imaj adını güncelleyin
# Bu basit bir örnek, gerçek uygulamalarda 'sed' yerine Helm kullanılması daha iyidir
sed -i "s|your_aws_account_id.dkr.ecr.eu-central-1.amazonaws.com/django-app:latest|${{ steps.build-image.outputs.image }}|" k8s/django-deployment.yaml
kubectl apply -f k8s/django-deployment.yaml
kubectl apply -f k8s/django-service.yaml
kubectl apply -f k8s/django-config.yaml
kubectl apply -f k8s/django-secret.yaml # Secret'ı dikkatli yönetin
kubectl apply -f k8s/django-ingress.yaml
kubectl rollout status deployment/django-app-deployment
Bu workflow, main dalına yapılan her push işleminde tetiklenir. İlk olarak, AWS kimlik bilgilerinizi yapılandırır (bu kimlik bilgilerini GitHub Secrets olarak güvenli bir şekilde saklamalısınız). Ardından, ECR'ye giriş yapar, Django uygulamanızın Docker imajını inşa eder, mevcut Git commit SHA'sı ile etiketler ve ECR'ye gönderir. ECR'ye gönderim başarılı olduktan sonra, kubectl aracını kurar, EKS kümenizin kubeconfig dosyasını günceller ve son olarak Kubernetes manifest dosyalarınızı uygulayarak yeni imajı EKS'e dağıtır. Manifest dosyasındaki imaj adını dinamik olarak güncellemek için sed gibi bir komut kullanılabileceği gibi, daha gelişmiş senaryolarda Helm şablonları kullanmak çok daha etkili bir yaklaşımdır. kubectl rollout status komutu, dağıtımın başarılı olup olmadığını kontrol etmek için faydalıdır.
Güvenlik açısından, AWS kimlik bilgilerinizi doğrudan GitHub Actions YAML dosyasına yazmak yerine, GitHub Secrets olarak depolamanız çok önemlidir. Ayrıca, bu AWS kimlik bilgilerine yalnızca ECR'ye push yapma ve EKS'e dağıtım yapma yetkileri veren en az ayrıcalıklı IAM politikalarını atayın. Bu, yetkisiz erişim durumunda potansiyel zararı en aza indirir.
CI/CD pipeline'ınızın başlangıcına birim testleri ve entegrasyon testlerini eklemek, üretim ortamına hatalı kodun ulaşmasını engellemek için kritik öneme sahiptir. Örneğin, docker build adımından önce RUN python manage.py test gibi bir komut ekleyerek testleri çalıştırabilirsiniz. Eğer testler başarısız olursa, pipeline durur ve dağıtım gerçekleşmez.
Bu otomatikleştirilmiş akış sayesinde, her kod değişikliği otomatik olarak test edilir, Docker imajı güncellenir ve uygulamanız EKS kümesine güvenilir bir şekilde dağıtılır. Bu, geliştiricilerin daha çok kod yazmaya odaklanmasını sağlarken, operasyonel yükü azaltır ve uygulamanızın pazara çıkış süresini kısaltır.
Uzman İpucu: CI/CD pipeline'ınızda test kapsamını artırmak için statik kod analizi (örneğin, Pylint, Black), güvenlik taramaları (örneğin, Bandit) ve bağımlılık analizi araçlarını entegre edin. Bu araçlar, sorunları erken aşamada tespit ederek üretim ortamına geçmeden önce düzeltmenize yardımcı olur.
İleri Seviye Konfigürasyonlar ve Optimizasyonlar: Güvenlik, İzleme ve Yüksek Erişilebilirlik Nasıl Sağlanır?
Django uygulamanız AWS EKS'te temel olarak çalışıyor olsa da, gerçek dünya üretim ortamlarında yüksek performans, güvenlik ve kesintisiz hizmet sunabilmek için ek konfigürasyonlara ve optimizasyonlara ihtiyaç duyarsınız. Bu bölümde, EKS'teki Django uygulamanızın daha sağlam, güvenli ve verimli çalışmasını sağlayacak ileri seviye konuları ele alacağız.
Yüksek Erişilebilirlik ve Ölçeklenebilirlik
Yük Dengeleyiciler ve Ingress Kontrolörleri: Daha önce bahsedilen Service tipi LoadBalancer veya AWS Load Balancer Controller ile Ingress kullanımı, uygulamanızın yükünü Pod'lar arasında dağıtarak yüksek erişilebilirlik sağlar. AWS Load Balancer Controller kullanmak, AWS Application Load Balancer (ALB) ile entegrasyonu basitleştirir ve gelişmiş yönlendirme kuralları, SSL sonlandırma ve WAF (Web Application Firewall) entegrasyonu gibi özellikler sunar.
Horizontal Pod Autoscaler (HPA): Kubernetes'in en güçlü özelliklerinden biri HPA'dır. HPA, CPU kullanımı veya özel metrikler gibi belirlenen eşiklere göre uygulamanızın Pod sayısını otomatik olarak artırır veya azaltır. Bu sayede, trafik arttığında uygulamanız otomatik olarak ölçeklenir ve trafik azaldığında kaynaklar boşuna tüketilmez. Django uygulamanızın CPU veya bellek kullanımını izleyerek HPA'yı konfigüre edebilirsiniz. Örneğin:
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: django-app-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: django-app-deployment
minReplicas: 3
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 # CPU kullanımı %70'i geçtiğinde ölçeklen
Cluster Autoscaler: HPA, mevcut düğümler üzerindeki Pod'ları ölçeklendirirken, Cluster Autoscaler ise Kubernetes kümenizdeki worker düğüm sayısını otomatik olarak yönetir. Eğer Pod'larınızın ihtiyaç duyduğu kaynakları karşılayacak yeterli düğüm yoksa, Cluster Autoscaler otomatik olarak yeni EC2 örnekleri (worker düğümleri) ekleyecektir. Bu, uygulamanızın sadece Pod seviyesinde değil, aynı zamanda altyapı seviyesinde de ölçeklenebilmesini sağlar.
Güvenlik Optimizasyonları
IAM Roles for Service Accounts (IRSA): Kubernetes Pod'larınızın AWS hizmetlerine erişimi için en güvenli yöntem IRSA kullanmaktır. Bu, Pod'larınıza özel IAM rolleri atamanızı sağlar, böylece her Pod yalnızca ihtiyaç duyduğu AWS kaynaklarına erişebilir. Bu, "least privilege" prensibini uygulamak için kritik öneme sahiptir.
Ağ Güvenliği (Network Policies): Kubernetes Ağ Politikaları (Network Policies), Pod'lar arası trafiği kısıtlamanıza olanak tanır. Örneğin, Django uygulamanızın sadece veritabanı Pod'larına veya belirli hizmetlere erişmesine izin verebilirsiniz. Bu, saldırı yüzeyini daraltır ve güvenlik duruşunuzu güçlendirir.
Gizli Yönetimi (Secrets Management): Kubernetes Secrets, hassas verileri depolamak için kullanılsa da, bu veriler varsayılan olarak Base64 ile kodlanmış olarak saklanır, şifreli değildir. Daha yüksek güvenlik için AWS Secrets Manager veya HashiCorp Vault gibi harici gizli yönetim çözümlerini Kubernetes ile entegre edebilirsiniz. Bu araçlar, hassas verileri endüstri standardı şifreleme ile korur ve daha sofistike erişim kontrolü sağlar.
Web Application Firewall (WAF): AWS WAF, uygulamanızı SQL enjeksiyonu, XSS gibi yaygın web açıklıklarına karşı korumak için kullanılabilir. Ingress'inizle entegre ederek veya ALB'nin önüne koyarak WAF'ı devreye alabilirsiniz.
İzleme ve Günlükleme (Monitoring & Logging)
Prometheus ve Grafana: Kubernetes kümelerindeki uygulamaları izlemek için de facto standart haline gelmiş açık kaynaklı çözümlerdir. Prometheus, metrikleri toplar ve Grafana, bu metrikleri görselleştirmek için güçlü panolar sunar. Django uygulamanızın Pod'larının CPU/bellek kullanımı, ağ trafiği, HTTP istekleri gibi birçok metriği izleyebilirsiniz. Django tarafında, django-prometheus gibi kütüphanelerle uygulamanızdan özel metrikler yayınlayabilirsiniz.
Merkezi Günlükleme (Centralized Logging): Konteynerize edilmiş uygulamalar için günlükleri toplamak ve analiz etmek zordur. Fluentd, Fluent Bit veya Logstash gibi araçları kullanarak Pod günlüklerini merkezi bir günlük yönetim sistemine (örneğin, AWS CloudWatch, Elasticsearch, Splunk) gönderebilirsiniz. Bu sayede, uygulamanızdaki hataları ve performans sorunlarını kolayca tespit edebilirsiniz. AWS için CloudWatch Logs ile entegrasyon oldukça basittir.
APM (Application Performance Monitoring) Araçları: New Relic, Datadog veya Dynatrace gibi APM araçları, Django uygulamanızın performansını uçtan uca izlemenizi sağlar. Veritabanı sorgularının performansından, HTTP isteklerinin gecikme sürelerine kadar detaylı bilgiler sunar ve performans darboğazlarını hızla belirlemenize yardımcı olur.
Bu ileri düzey konfigürasyonları ve optimizasyonları uygulayarak, AWS EKS üzerindeki Django uygulamanızın sadece çalışmasını sağlamakla kalmaz, aynı zamanda üretim ortamında karşılaşabileceğiniz birçok zorluğa karşı dayanıklı, güvenli ve yüksek performanslı bir çözüm haline getirirsiniz. Unutmayın ki, sürekli izleme ve düzenli güvenlik denetimleri, bu sistemlerin uzun vadeli başarısı için anahtardır.
Uzman İpucu: Kubernetes kümenizi ve uygulamalarınızı izlerken, özel metrikler belirlemek ve bunlara dayalı alarmlar kurmak, potansiyel sorunları proaktif olarak tespit etmenizi sağlar. Örneğin, belirli bir API uç noktasının hata oranı belirli bir eşiği aştığında uyarı almak, sorunları kullanıcılar etkilenmeden önce çözmenize yardımcı olabilir.
Sonuç: Django'yu AWS EKS'te Dağıtmanın Gücü ve Geleceği
Bu makalede, modern bir Django uygulamasını AWS EKS kümesi üzerinde uçtan uca nasıl dağıtacağımızı adım adım inceledik. Geleneksel dağıtım yöntemlerinin zorluklarından yola çıkarak, konteynerizasyonun ve Kubernetes'in neden vazgeçilmez hale geldiğini, ardından AWS EKS'in bu süreci nasıl kolaylaştırdığını detaylandırdık. Django uygulamanızı bir Docker imajına dönüştürmekten, EKS altyapısını hazırlamaya, Kubernetes manifest dosyalarıyla dağıtımı orkestrasyona ve son olarak CI/CD pipeline'ları ile otomasyonu sağlamaya kadar geniş bir yelpazeyi kapsayan bu yolculuk, geliştiricilere ve DevOps mühendislerine önemli yetenekler kazandırır.
AWS EKS üzerinde Django dağıtmak, uygulamanızın yalnızca hızlı bir şekilde çalışmasını sağlamakla kalmaz, aynı zamanda yüksek ölçeklenebilirlik, esneklik ve operasyonel verimlilik sunar. Konteynerize edilmiş uygulamalar, farklı ortamlarda tutarlılık sağlar ve geliştirme ile üretim arasındaki farkları ortadan kaldırır. Kubernetes, karmaşık konteyner yığınlarını yönetme yükünü omuzlarınızdan alırken, EKS bu yönetilen hizmetin bulutun tüm avantajlarıyla birleşmesini sağlar. Sonuç olarak, daha hızlı pazar erişimi, daha az kesinti süresi ve daha kolay bakım ile sonuçlanan modern, bulut tabanlı bir mimari elde edersiniz.
İleri düzey konfigürasyonlar ve optimizasyonlar bölümünde ele aldığımız gibi, güvenlik, izleme ve yüksek erişilebilirlik, üretim ortamında başarı için kritik faktörlerdir. HPA ve Cluster Autoscaler ile otomatik ölçeklenme, IRSA ve Ağ Politikaları ile güçlendirilmiş güvenlik, Prometheus/Grafana ve merkezi günlükleme ile kapsamlı izleme, uygulamanızın her zaman en iyi performansı göstermesini ve potansiyel sorunlara karşı dayanıklı olmasını sağlar.
Django'nun geliştirme hızıyla Kubernetes'in operasyonel gücünü birleştirmek, geleceğin web uygulamaları için standart bir dağıtım modeli sunar. Bu yaklaşım, mikroservis mimarisine geçiş yapmak isteyen ekipler için de sağlam bir temel oluşturur. Bu bilgileri kullanarak, siz de Django uygulamalarınızı AWS EKS'te güvenle dağıtabilir ve bulutun sunduğu sınırsız olanaklardan faydalanabilirsiniz.
Sıkça Sorulan Sorular (SSS)
- EKS'te Django uygulamamı dağıtmak için neden Docker kullanmalıyım?
- Docker, uygulamanızı ve tüm bağımlılıklarını tek bir taşınabilir birimde paketlemenizi sağlar. Bu, uygulamanızın farklı ortamlarda (geliştirme, test, üretim) tutarlı bir şekilde çalışmasını garanti eder ve bağımlılık çakışmaları gibi sorunları ortadan kaldırır. Kubernetes konteynerli iş yüklerini yönettiği için Docker kullanımı zorunludur.
- Django uygulamasının statik ve medya dosyalarını EKS'te nasıl yönetmeliyim?
- Üretim ortamında statik ve medya dosyalarını doğrudan Pod'larınızdan sunmak yerine, AWS S3 gibi bir nesne depolama hizmeti kullanmanız önerilir. Django'da
django-storageskütüphanesi ile bu dosyaları S3'e yükleyebilir ve oradan servis edebilirsiniz. Bu yaklaşım, Pod'larınızın durumsuz kalmasını sağlar ve ölçeklendirme ile bakım işlemlerini basitleştirir. - EKS'te veritabanı bağlantısı için en iyi uygulama nedir?
- Veritabanı bağlantı bilgilerini doğrudan kodunuza yazmak yerine, Kubernetes Secrets ve ConfigMaps kullanarak yönetmelisiniz. Genellikle, AWS RDS (Relational Database Service) gibi yönetilen bir veritabanı hizmeti kullanmak ve bağlantı dizesini bir Kubernetes Secret olarak saklayıp uygulamanıza ortam değişkeni olarak sağlamak en iyi yaklaşımdır. Ayrıca, IAM Roles for Service Accounts (IRSA) ile veritabanına erişim yetkilerini kontrol edebilirsiniz.
- CI/CD pipeline'ı kurmak zorunlu mu, manuel dağıtım yapabilir miyim?
- Manuel dağıtım yapmak mümkündür ancak sürdürülebilir değildir ve insan hatasına açıktır. CI/CD pipeline'ları, kod değişikliklerini otomatik olarak test eder, inşa eder ve dağıtır. Bu, geliştirme hızını artırır, hataları azaltır ve uygulamanızın üretim ortamına daha sık ve güvenilir bir şekilde çıkmasını sağlar. Uzun vadede operasyonel verimlilik için şiddetle tavsiye edilir.
- EKS kümesinde performans izleme ve günlükleme için hangi araçları kullanmalıyım?
- Performans izleme için Prometheus ve Grafana, Kubernetes ortamlarında de facto standarttır. Uygulamanızdan metrikleri toplayıp görselleştirmek için idealdirler. Günlükleme için ise Fluentd veya Fluent Bit'i kullanarak Pod günlüklerini merkezi bir günlük yönetim sistemine (örneğin, AWS CloudWatch Logs veya Elasticsearch) gönderebilirsiniz. Bu, sorun gidermeyi ve uygulama sağlığını anlamayı kolaylaştırır.