Herkese merhabalar,
Hali hazırda yazılmış bir Django uygulamasını K8s(Kubernetes’in kısaltması) ortamında çalıştırmak üzerine bir yazı yazıp, Türkçe de bir dökümantasyon oluşturmak istedim. Hadi vakit kaybetmeden başlayalım.
Django Uygulamasını Dockerize Etme
Öncelikle uygulamamızı dockerize ederek pod ve service yapısına entegre edilebilir kılmamız gerekiyor. Bunun için (eğer uygulamanız henüz yayınlanmamışsa) settings.py içerisindeki “allowed host” kısmını * ile doldurarak başlıyoruz:
ALLOWED_HOSTS = ['*']
Şimdi varolan uygulamamızın ana dizininde uygulamayı bir docker imajına çevirebilmek için Dockerfile dosyasını oluşturuyoruz:
# python 3 kutuphanesinden base imajı cek FROM python:3 ENV PYTHONDONTWRITEBYTECODE=1 ENV PYTHONUNBUFFERED=1 # docker'in calisacagi dizine gec WORKDIR /code # projenin ihtiyac duydugu bagimliliklari calisma dizinine tasi COPY requirements.txt /code/ # bagimliliklari yukle RUN pip install -r requirements.txt # projeyi calisma dizinine tasi COPY . /code/ # varolan DB operasyonlarini tetikle RUN python manage.py migrate # 8000 portunu disari ac EXPOSE 8000 # django app i baslat CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]
Eğer uygulamanızın henüz bir “requirements.txt” si oluşturulmamışsa “pip freeze > requirements.txt” komutuyla oluşturabilirsiniz.
Uygulamamızın bir “Dockerfile” ve “requirements.txt” dosyalarını oluşturmayı tamamladıktan sonra docker image’ımızı oluşturabiliriz. Bunun için projenin ana dizinindeyken:
docker build -t sample_django:0.1 .
Proje sıkıntısız bir şekilde imaja dönüştüğinde şuna benzer bir çıktı listesi görmelisiniz:
& sbozkir @ Sezers-MacBook-Pro in ~/PycharmProjects/sezerWebApp 0 [18:43:10] ~ docker build -t sample_django:0.1 . 0 [18:43:10] [+] Building 4.0s (12/12) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 581B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [internal] load metadata for docker.io/library/python:3 2.3s => [auth] library/python:pull token for registry-1.docker.io 0.0s => [1/6] FROM docker.io/library/python:3@sha256:7537c2092cdd042405001f8534b417bb276fa44303b7d1736769941907f2a19e 0.0s => [internal] load build context 0.0s => => transferring context: 4.60kB 0.0s => CACHED [2/6] WORKDIR /code 0.0s => CACHED [3/6] COPY requirements.txt /code/ 0.0s => CACHED [4/6] RUN pip install -r requirements.txt 0.0s => [5/6] COPY . /code/ 0.0s => [6/6] RUN python manage.py migrate 1.5s => exporting to image 0.1s => => exporting layers 0.0s => => writing image sha256:a218d110e90b9c1d26725eea0377f72429851d6330e6c1da3ae1b9fdcadf52fa 0.0s => => naming to docker.io/library/sample_django:0.1 0.0s Use 'docker scan' to run Snyk tests against images to find vulnerabilities and learn how to fix them
İmajımızın doğru bir şekilde oluşturulduğunu teyit edelim “docker images” komutunu çalıştırıyoruz:
sbozkir @ Sezers-MacBook-Pro in ~/PycharmProjects/sezerWebApp 0 [18:48:00] ~ docker images 0 [18:48:00] REPOSITORY TAG IMAGE ID CREATED SIZE sample_django latest 2a2f803ad855 8 minutes ago 951MB
Harika, herşey yolunda olduğuna göre yapımızı k8s ortamına çalıştırmadan önce çalışır durumda olduğundan emin olmak için bir docker container’ı ayağa kaldıralım:
docker run --name ornek -d -p 8000:8000 sample_django:0.1
Bu komut ile docker’a bir konteyner ayağa kaldır, bu konteynere 8000 portunu bağla ve imaj olarakta sample_django imajini kullan demiş oluyoruz. Şimdi web browser a girip localhost:8000 ya da 0.0.0.0:8000 adresine gittiğinizde projenizi görüyor olmanız gerekmekte.
Uygulamanın Kubernetes Ortamına Entegrasyonu
Artık elimizde dockerize edilmiş, imaj haline getirilmiş, k8s ortamında çağırabileceğimiz bir Django uygulaması mevcut. Şimdi de k8s için gerekli Yaml dosyalarını oluşturarak ilerleyebiliriz. Ben bunun için uygulamanın dizini altında k8s diye bir dizin oluşturacağım örnek olması adına (projeye yazının sonundaki Github linkinden ulaşabilirsiniz), ancak normal şartlar altında tabii ki bu YAML dosyalarının proje dışında olması doğal olan.
Deployment YAML dosyamızı yazarak başlayalım:
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: sample-django
name: sample-django
spec:
replicas: 1
selector:
matchLabels:
app: sample-django
template:
metadata:
labels:
app: sample-django
spec:
containers:
- image: sample-django:0.1
name: sample-django
ports:
- containerPort: 8000
restartPolicy: Always
K8s’e bir deployment oluşturacağımızı tek replika olacağını, spec kısmında da container olarak “sample-django” nun 0.1 versiyonunu kullanacağımızı ve 8000 portunu bind edeceğini söyledik. Şimdi bir üst katman olan service katmanını yazalım:
apiVersion: v1
kind: Service
metadata:
labels:
app: sample-django
name: sample-django
spec:
type: NodePort
ports:
- port: 8080
protocol: TCP
targetPort: 8000
nodePort: 30007
selector:
app: sample-django
Burada da service katmanına bağlanacağı deployment’ın ismini, hangi portu nereye yönlendireceğini söylüyoruz. Burada 2 yol mevcut, development aşamasında sıklıkla kullanılan Nodeport kullanabiliriz ya da bir ingress servis oluşturarak domain üzerinden yayınlayabiliriz. Minikube ortamında Nodeport üzerinden ilerleyip hızlıca sonucu görebiliriz,
minikube service sample-django --url
Vee karşımızda containerized, k8s ortamında çalışan bir django uygulaması:
sbozkir @ Sezers-MacBook-Pro in ~/PycharmProjects/sezerWebApp/k8s 0 [13:26:04] ~ minikube service sample-django --url 1 [13:26:04] 🏃 Starting tunnel for service sample-django. |-----------|---------------|-------------|------------------------| | NAMESPACE | NAME | TARGET PORT | URL | |-----------|---------------|-------------|------------------------| | default | sample-django | | http://127.0.0.1:64363 | |-----------|---------------|-------------|------------------------| http://127.0.0.1:64363
URL kısmındaki linke girdiğimizde django template arayüzünü görebilirsiniz. Ayrıca ingress ile birlikte çalışan halini de repoya ekledim. Deneyebilirsiniz.
Repo:
https://github.com/Natgho/Django-Kubernetes-Sample
Bir sonraki yazımda görüşmek üzere 🙂