Eğitim ve test amaçlı olarak minikube ve docker destop önelikle eğer benim gibi ortamınız windows ise kurulmalıdır.
Yapacağımız örnek ise “TechWorld with Nana” kanalının “Kubernetes Crash Course for Absolute Beginners [NEW]” da anlatılandır.
Örnekte arka planda MongoDB nin oldugu bir NodeJS tabanlı web application kurulumu yapacağız.
4 adet dosya olusturacagiz.
- Config map : Mongo db endpoint ayarlari
- Secret : mongobd user ve password
- Mongodb App icin Deployment ve service ayarlari
- WebApp icin deployment ve service ayarlari
ConfigMap
Ilk dosyamiz „Mongo-config.yaml“
Surdan ilk kismi kopyaliyoruz
https://kubernetes.io/docs/concepts/configuration/configmap/
apiVersion: v1
kind: ConfigMap
metadata:
name: game-demo
data:
sonra bunu editliyorruz. Data altinda key:value ciftleri olmalidir
apiVersion: v1
kind: ConfigMap
metadata:
name: Mongo-config
data:
mongo-url: mongo-service
Secret
Simdi „Secrets“ mongo-secret.yaml
https://kubernetes.io/docs/concepts/configuration/secret/
yukarida ki linkten örnek kismi aliyoruz.
apiVersion: v1
kind: Secret
metadata:
name: mysecret
type: Opaque
data:
USER_NAME: YWRtaW4=
PASSWORD: MWYyZDFlMmU2N2Rm
ve editliyoruz.
apiVersion: v1
kind: Secret
metadata:
name: mongo-secret
type: Opaque
data:
mongo-user: bW9uZ28tdXNlcg==
mongo-password: bW9uZ28tcGFzc3dvcmQ=
Secrets dosyasina yazilan username ve password gibi gizli bilgiler base64 olarak kodlanmalidir.
Bunun icin bash te
$ echo -n "mongo-user"|base64
bW9uZ28tdXNlcg==
Olur. Password üde ayni sekilde yapariz. Secrets linkinde cok önemli bilgiler var mutlaka okunmali.
Service ve Deployment
Simdi de mongobd icin deployment ve service konfigürasyonunu olusturalim.
„mongo.yaml“ her bir deployment bir service e ihtiyac duyar bu nedenle ikisi tekbir dosyadadir.
Asagida ki linke gidip yine örnegi kopyaliyoruz.
https://kubernetes.io/docs/concepts/workloads/controllers/deployment/
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
labels:
app: nginx
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
Ve tabii ki yine editliyoruz. Ancak burda bilmemiz gereken template bölümü pod larin sablonu gibidir. Template bölümünün kendi metadatasi ve kendi spec alt bölümü vardir. Bu kısım deployment icinde pod u tanimlar. POD icinde birden cok container olabilir ancak mantık olarak her pod da bir application olmalidir. Template:spec:container icinde bu containerlari tanimliyoruz.
Bu örnekte mongodb kullanacagimiz icin docker hub dan önce mongodb nin tam adını buluyoruz. (örnekte tag olarak versiyon 5 kullanıldı) port bilgiside dockerhub daki dokümandan geldi.
Ayrica metadata altında labeller var. Kubernetes da her componente bir label vermek mümkündür. Labellar key:value ikiklisidir ve resourcelara atanırlar. Labeller kullanışlı teşhis (identification) elemanlarıdır. Örnek
„env“:“dev“
„release“:“Pazar gunu“
Her yeni resource tipi (örnegin POD) olustuğunda bunların unique bir adı olur ancak label hepsinde aynidir. Böylece POD replikalarinin tamamini ayni label ile teshis edebiliriz. Bu nedenle PODlar icin label zorunlu olarak olmak zorundadir. Diger componentlerde label opsiyoneldir ama önerilir.
POD replikalari olustururken Deployment nereden biliyor hangi tip POD olusturacagini? Yani K8s nereden biliyor hangi POD hangi deployment a ait? Iste bu „Spec:selector:matchLabels“ ile saglanir. MatchLabels ile tanimlanmis tüm POD’lar o deploymenta aittir.
En son kac replika POD istedigimizi belirttigimiz POD sayisi mevcut. Biz simdilik basitlik amaciyla tek replika yapacagiz.
apiVersion: apps/v1
kind: Deployment
metadata:
name: mongo-deployment
labels:
app: mongo
spec:
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongodb
image: mongo:5
ports:
- containerPort: 27017
YAML da „—„ ile birden cok yaml dosyasini tek bir dosyada toplayabiliriz
Burada da böyle yapacagiz ve service örnegini de bunun altina ekleyecegiz.
Önce örnek config i asagida ki linkten aliyoruz.
https://kubernetes.io/docs/concepts/services-networking/service/
apiVersion: v1
kind: Service
metadata:
name: my-service
spec:
selector:
app: MyApp
ports:
- protocol: TCP
port: 80
targetPort: 9376
simdi de editleyelim
burada metadata:name ile belirledigimiz name mongo-config.yaml da ki service namedir. Yani ikisi ayni olmalidir.
Service configuration icinde „spec:selector:“ vardir bunun ile service hangi POD lara forwarding yapacagini ögrenmektedir. Bu nedenle buraya girdigimiz deger deployment taki POD’larin labellari ile ayni olmalidir.
Ayrica iki adet port tanimi mevcuttur. „Port „ bu servise hangi porttan erisilebilecegidir ve „targetPort“ ise POD’lara hangi porttan forward edecegidir. Bu nedenle Deployment ta belirtilen POD portu ile ayni olmak zorundadir.
apiVersion: v1
kind: Service
metadata:
name: mongo-service
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 27017
targetPort: 27017
Buraya kadar MongoDB application i icin gerekli ayarlari yaptik ancak ayrica web applicationimizda var bu mongo db nin erisecegi. Bütün settingleri kopyalayip „webapp.yaml“ dosyasini olusturuyoruz.
Image ise : nanajanashia/k8s-demo-app:v1.0
Bu basit bir nodejs application ve port 3000 de. POD ve Container ve ayrica service portunu ayni yapiyoruz.
apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp-deployment
labels:
app: webapp
spec:
replicas: 1
selector:
matchLabels:
app: webapp
template:
metadata:
labels:
app: webapp
spec:
containers:
- name: webapp
image: nanajanashia/k8s-demo-app:v1.0
ports:
- containerPort: 3000
---
apiVersion: v1
kind: Service
metadata:
name: webapp -service
spec:
selector:
app: webapp
ports:
- protocol: TCP
port: 3000
targetPort: 3000
Secret ve configMap bağlama
Buraya kadar hemen hemen gerekli her dosayi olusturduk ancak henüz secret ve configMap i baglamadik.
MongoDB basladiginda derhal username ve password u set etmemiz gerekmektedir. Peki nasil?
Docker hub da ki MongoDB sayfasina gidiyoruz ve dökümantasyonu okuyoruz.
https://hub.docker.com/_/mongo
orada environment ayarları var.
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: example
Peki bu environment setting i nasıl göndereceğiz?
Deployment config dosyasinda MongoDB Container ayarlarının altına gri bölümden sonra olacak sekilde aşağıyı ekliyoruz.
spec:
containers:
- name: mongodb
image: mongo:5
ports:
- containerPort: 27017
env:
- name: MONGO_INITDB_ROOT_USERNAME
value:
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: MONGO_INITDB_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
Istersek normal bir environment degişkenini name ve value olarak direk gönderebiliriz. Ancak bizde secret oldugu için onu refere etmemiz gerekiyor. Bu nedenle „value“ yerine „valueFrom“ kullandık.
secretKeyRef ile dosyanin adını ve key ile de hangi değerin „Value“ sini alacağımızı söyledik. Aynı işlemi hem password için hemde username için yaptık.
Daha sonra webapp başladığında onunda veritabanina erişmesi gerekmekte dolayısıyla ona da bir password ve username iletmemiz gerekiyor ki basladiginda database e erissin. Ayrica hangi database eriseceginide „configMap“ ile belirtiyoruz. Nananin containerinin hangi değişkenleri alacağı yine docker hub daki sayfasinda belirtilmiş.
Tabii bu ayarlarda Webapp Container config inin altına ekleniyor. Mavi kısım MongoDB container env ayarından direk copy paste.
containers:
- name: webapp
image: nanajanashia/k8s-demo-app:v1.0
ports:
- containerPort: 3000
env:
- name: USER_NAME
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-user
- name: USER_PWD
valueFrom:
secretKeyRef:
name: mongo-secret
key: mongo-password
- name: DB_URL
valueFrom:
configMapKeyRef:
name: mongo-config
key: mongo-url
ConfigMap ten referans yaparken „configMapKeyRef“ kullaniliyor.
Geriye son bir basamak kaldi ve oda bu uygulamanin disardan erisilebilir olmasini saglamaktir.
Buda „external service“ ile olur. Bunun icin service config dosyasini editlememiz gerekmektedir.
apiVersion: v1
kind: Service
metadata:
name: webapp -service
spec:
type: ClusterIP
type: NodePort
selector:
app: webapp
ports:
- protocol: TCP
port: 3000
targetPort: 3000
nodePort: 30100
type default olarak °ClusterIP° dir. „NodePort“ external bir servis tipidir. Type: NodePort eklenince Spec:Ports a da nodePort key:value ciftini eklemek gereklidir. NodePort ile her bir node daki IP nin belirli bir Portunu static olarak Application in erisilebilmesi icin acar.
<nodeIP>:<nodePort> ile bu servise erisebilecegiz ve oda arkasinda ki POD’lara erisebilecek.
NodePort sadece 30000 ile 32767 portlari arasinda tanimlanabilir.
UYGULAMA (DEPLOYMENT)
Bu noktaya kadar tüm konfigürasyonlari bitirdik ancak henüz deploy etmedik. Artik kubectl ile deploy edebiliriz.
Ancak deploy etmeden önce „configMap“ ve „Secret hazir olmalidir.
$ kubectl apply –f mongo-config.yaml --> configMap
$ kubectl apply –f mongo-secret.yaml --> Secret
$ kubectl apply –f mongo.yaml --> DB yi baslatiyoruz önce cünkü webapp ona depend ediyor. DB olmadan webapp crash
$ kubectl apply –f webapp.yaml --> Webapp deployment
Kontroller
$ kubectl get all
$ kubectl get configmap
$ kubectl get secret
$ kubectl describe service webapp-service –> eger daha cok detay görmek istersek
$ kubectl logs <POD name> –> o POD a ilisken loglari görmek icin
-f ile stream olarak da görebiliriz.
$ kubectl get svc –>scv= service burada
$ minikube ip –> minikube un baglandigi IP yi bulmak icin.
$ kubectl get node –>burdda da node (minikube ) ip si görülür.
$ kubectl get node –o wide