Kubernetes Pod Nedir?
Pod, içinde bir veya birden fazla container'ın çalıştığı en küçük Kubernetes birimidir. Bir Pod, birbirleriyle yakından ilişkili olan ve aynı Node üzerinde çalışması gereken container'lar için bir gruplama mekanizması sağlar.
Her Pod, kendine tahsis edilmiş bir internal IP adresine sahiptir. Bir Kubernetes cluster içindeki tüm pod'lar aynı network-address space'i kullandıkları için, bir pod, başka bir pod'un IP adresine kolaylıkla ve doğrudan erişebilir.
Bir pod içinde, bir veya birden fazla container çalışabilir. Asıl container'ın yanında ek olarak çalışan diğer container'lara sidecar container'da denir.
Pod'larla ilgili en önemli şey, bir pod birden çok container içerdiğinde, hepsinin her zaman tek bir node üzerinde çalıştırılmasıdır. Bir pod'un container'ları asla birden çok node üzerine yayılmaz.
Aynı pod içinde çalışan container'lar , aynı network ve linux namespace'i kullanırlar. Bu sebeple aynı pod'un içindeki container'lar;
- Aynı hostname ve network interface'leri paylaşırlar. Örneğin, bir Pod'un adı "
my-pod
" ise, Pod içindeki ilk container'ın hostname'i "my-pod-0
", ikinci container'ın hostname'i "my-pod-1
" olur ve böyle devam eder. - Aynı network namespace'i kullandıkları için aynı IP ve port aralığını kullanmış olurlar. Bu nedenle aynı pod içindeki container'larda port çakışmasına dikkat edilmelidir.
- Aynı loopback network interface'ı paylaştıkları için birbirleriyle localhost üzerinden direkt iletişime geçebilirler.
- Aynı volume'u aynı pod içindeki tüm container'lar mount edebilir.
1. Pod Nasıl Oluşturulur?
Tüm Kubernetes objeleri gibi Pod'ları da iki yöntemle oluşturabiliriz:
- Kubernetes REST API endpoint'e bir JSON veya YAML manifest dosyası göndermek.
- kubectl aracını kullanarak CLI üzerinden komutlarla oluşturmak.
1.1. Manifest Dosyasının Hazırlanması
Kubernetes Pod oluşturmak için bir YAML manifest dosyası kullanabilirsiniz. Bu dosya, Pod'un nasıl oluşturulacağına dair bilgileri içerir. Aşağıdaki örnek, bir YAML manifest dosyasıdır ve "my-pod
" adında bir Pod oluşturur:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: my-container-1
image: nginx:latest
- name: my-container-2
image: busybox:latest
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
Bu YAML dosyasında, Pod'un oluşturulması için gerekli olan 4 ana parametre vardır:
- apiVersion: Kullanılan Kubernetes API sürümünü belirtir. Pod objesi için
v1
kullanılır. - kind: Oluşturulacak objenin türünü belirtir. Bu örnekte, bir Pod oluşturulacağı için
Pod
olarak ayarlanır. - metadata: Pod'un metadata bilgilerini içerir. Örneğin Pod'un adını
name
parametresi ile belirleyebiliriz. - spec: Pod'un özelliklerini belirtir. Bu örnekte, Pod içindeki cantainer'ların listesi yer alır.
apiVersion
parametresinin hangi değerini öğrenmek için http://kubernetes.io/docs/api adresini ziyaret edebilir veya kubectl explain pod
komutunu kullanabilirsiniz. Örnek çıktı aşağıdaki gibidir:Bu dört ana parametreden herhangi birisi hakkında detaylı bilgi almak için kubectl explain
komutunu kullanabilirsiniz. Örneğin kubectl explain pod.spec
komutunun çıktısı şu şekildedir:
Biz yinede bazı parametreleri kendimiz de açıklayalım.
➡ Dört ana parametreden olan spec
şu alt parametreleri içerebilir:
containers
: Pod içindeki container'ların belirtildiği alandır.volumes
: Pod içinde kullanılacak volume'ların belirtildiği alandır.restartPolicy
: Container'ların çökmesi durumunda ne yapılacağını belirtir. Örneğin,Always
olarak ayarlanırsa, container'ların çökmesi durumunda otomatik olarak yeniden başlatılır.imagePullSecrets
: Container'ların Docker imajlarını çekerken kullanılacak kimlik doğrulama bilgilerini belirtir.hostAliases
: Pod'lar için özel host isimleri tanımlamak için kullanılır.nodeSelector
: Pod'un hangi node'larda çalışacağını belirtir.tolerations
: Pod'un çalışabileceği belirli bir durumda tolerans sağlar.affinity
: Pod'un başka kaynaklara bağımlılıklarını belirtir.
Örneğin tüm bu parametreleri içeren örnek bir YAML dosyası örneği şu şekildedir:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "localhost"
- ip: "10.240.0.1"
hostnames:
- "kube-master"
containers:
- name: my-container
image: nginx:latest
volumeMounts:
- name: my-volume
mountPath: /usr/share/nginx/html
volumes:
- name: my-volume
emptyDir: {}
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
nodeSelector:
disktype: ssd
serviceAccountName: default
automountServiceAccountToken: true
imagePullSecrets:
- name: my-registry-key
schedulerName: default-scheduler
securityContext:
runAsUser: 1000
runAsGroup: 3000
fsGroup: 2000
seLinuxOptions:
user: "system_u"
role: "system_r"
type: "svirt_sandbox_file_t"
level: "s0:c123,c456"
priorityClassName: high
priority: 1000
dnsConfig:
nameservers:
- "1.1.1.1"
- "8.8.8.8"
searches:
- "my-domain.local"
➡ Diğer bir parametre olan metadata
şu alt parametreleri içerebilir:
name
: Pod'un adıdır.labels
: Pod'a etiketler ekler. Etiketler, kaynakları gruplamak, aramak veya filtrelemek için kullanılabilir. Örnek olarak:
metadata:
name: my-pod
labels:
env: production
app: my-app
annotations
: Pod hakkında ek bilgi sağlar. Bu bilgiler, açıklama veya notlar gibi metin bilgileri olabilir. Örnek olarak:
metadata:
name: my-pod
annotations:
description: This is my production pod.
version: 1.0.0
namespace
: Pod'un ait olduğu namespace'i belirtir. Namespace'ler, Kubernetes cluster'ındaki farklı ortamları veya uygulamaları ayırmak için kullanılabilir. Örnek olarak:
metadata:
name: my-pod
namespace: production
ownerReferences
: Pod'un sahibi olan objeyi belirtir. Bu parametre, Pod'un silinmesi durumunda sahibi olan objenin de silinmesini sağlar. Örnek olarak:
metadata:
name: my-pod
ownerReferences:
- apiVersion: apps/v1
kind: Deployment
name: my-deployment
➡ spec
parametresi altında yer alan ve önemli bir parametre olan containers
ise şu alt parametreleri içerebilir:
name
: Container'ın adıdır. Bu parametre zorunludur.image
: Container'ın kullanacağı Docker image'ı belirtir.command
: Container'ın başlarken çalıştıracağı komutu belirtir.args
: Container'ın başlarken kullanacağı komut argümanlarını belirtir.env
: Container'ın kullanacağı ortam değişkenlerini belirtir.ports
: Container'ın kullanacağı portları belirtir.volumeMounts
: Container'ın kullandığı volume'leri belirtir.resources
: Container'ın kullanabileceği kaynakları (CPU, RAM vb.) sınırlar.lifecycle
: Container'ın başlatma ve sonlandırma işlemlerini belirtir.
Örnek bir YAML dosyası olarak ise aşağıdaki örneği verebiliriz:
apiVersion: v1
kind: Pod
metadata:
name: my-pod
labels:
app: my-app
spec:
hostAliases:
- ip: "127.0.0.1"
hostnames:
- "localhost"
- ip: "10.240.0.1"
hostnames:
- "kube-master"
containers:
- name: my-container
image: nginx:latest
command: ["nginx"]
args: ["-g", "daemon off;"]
env:
- name: MY_ENV_VAR
value: "my-value"
envFrom:
- configMapRef:
name: my-configmap
- secretRef:
name: my-secret
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
livenessProbe:
httpGet:
path: /healthz
port: http
initialDelaySeconds: 30
periodSeconds: 10
timeoutSeconds: 5
readinessProbe:
httpGet:
path: /readiness
port: http
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 2
volumeMounts:
- name: my-volume
mountPath: /usr/share/nginx/html
volumes:
- name: my-volume
emptyDir: {}
ports
parametresinin belirtilmesi tamamen bilgilendirme amaçlıdır. ports
parametresini eklememenin, istemcilerin bağlanıp bağlanamayacağı üzerinde hiçbir etkisi yoktur. Eğer bir pod, 0.0.0.0
adresine bağlı bir port üzerinden bağlantıları kabul ediyorsa, ports
parametresinde açıkça belirtilmemiş olsa bile diğer podlar her zaman ona bağlanabilir. Ancak, cluster'ınızı kullanan herkesin her pod'un hangi portu expose ettiğini hızlı bir şekilde görebilmesi için ports
parametresi tanımlamak mantıklıdır.1.2. Hazırlanan Manifest Dosyasının Çalıştırılması
Pod manifest dosyasını hazırladıktan sonra ilgili pod'ları oluşturabilmek için kubectl create
veya kubectl apply
komutlarını kullanabilirsiniz.
kubectl create -f <pod-definition-file>.yaml
kubectl create
komutu sonraki çalıştırmalarınızda hata verir. Manifest dosyasında düzenleme yaptıktan sonra podu güncellemek için kubectl create
yerine kubectl apply
komutunu kullanmalısınız.kubectl create -f <pod-definition-file>.yaml -n custom-namespace
1.3. CLI Aracılığıyla Pod Oluşturmak
Pod oluşturmak için YAML veya JSON dosyası kullanmak istemiyorsanız, aşağıdaki adımları izleyerek doğrudan terminalden pod oluşturabilirsiniz:
- Terminali açın: Pod'u oluşturmak için kullanacağınız komutları çalıştırmak için bir terminal açın.
- Pod'u oluşturun: Aşağıdaki komutu kullanarak pod'u oluşturun:
kubectl run <pod-name> --image=<image-name> --port=<port-number>
Bu komut, "pod-name" adlı bir pod oluşturur, "image-name" adlı bir Docker imajı kullanır ve "port-number" adlı bir portu açar.
Örneğin, aşağıdaki komutla "my-pod" adlı bir pod oluşturabilirsiniz:
kubectl run my-pod --image=nginx --port=80 --restart=Never
1.4. Pod'ları Belirli Bir Node Üzerinde Oluşturmak
Yukarıdaki başlıklarda yer alan aşamaları uygulayarak bir pod oluşturduğunuzda, oluşan pod cluster üzerinde yer alan ve varsa cpu, memory gibi koşulları sağlayan rastgele bir node üzerinde oluşturulur. Fakat pod'un oluşturulacağı node'u seçmekte mümkündür.
Örneğin Kubernetes cluster'ımızdaki machine-1
ve machine-2
isimli nodelar CPU, machine-3
ve machine-4
isimli nodelar GPU içersin. İlk olarak tüm nodları type
label'ı ile etiketleyelim.
kubectl label node machine-1 type=cpu
kubectl label node machine-2 type=cpu
kubectl label node machine-3 type=gpu
kubectl label node machine-4 type=gpu
Ardından pod oluştururken eğer oluşturulacak pod'un gpu içeren makinelerden birinde oluşturulmasını istiyorsak, pod manifest dosyasındaki spec
bölümü altında yer alan nodeSelector
parametresini type=gpu
olarak ayarlamalıyız.
apiVersion: v1
kind: Pod
metadata:
name: image-processor
spec:
nodeSelector:
type: gpu
containers:
- image: nvidia/cuda
name: cuda
Artık bu manifest dosyasını kubectl create
veya kubectl apply
komutuyla çalıştırdığınızda pod'unuz gpu içeren node'lardan birinde çalıştırılacaktır.
2. Oluşturulan Pod'ların İncelenmesi ve Listelenmesi
- Cluster'da yer alan pod'ları listelemek için
kubectl get pods
komutunu kullanabilirsiniz.
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
my-pod 1/1 Running 0 32s
- Belirli label'lara ait podları listelemek için
-l
parametresini kullanabilirsiniz.
kubectl get pods -l environment
kubectl get pods -l environment=production,type=gpu
- Bir pod'un loglarını görmek için
kubectl logs <pod-name>
komutunu kullanabilirsiniz.
kubectl logs my-pod
- Bir pod içinde yer alan belirli bir container'ın loglarını görmek için
-c
parametresi ile birliktekubectl logs <pod-name> -c <container-name>
komutunu kullanabilirsiniz.
kubectl logs my-pod -c my-container
kubectl logs
komutu yalnızca son rotate'deki log çıktılarını gösterir.- Pod'un detaylarını görüntülemek için
kubectl describe pod <pod-name>
komutunu kullanabilirsiniz:
$ kubectl describe pod web
Name: web
Namespace: default
Priority: 0
Service Account: default
Node: minikube/192.168.49.2
Start Time: Fri, 28 Apr 2023 16:45:40 +0300
Labels: name=WebApp
***
***
Bu komut, pod'un adını belirttiğinizde pod hakkında ayrıntılı bilgi sağlar. Pod'un etiketleri, durumu, oluşturma zamanı ve diğer özellikleri gibi bilgileri içerir.
3. Pod'ların Silinmesi
Kubernetes'te bir podu silmek için aşağıdaki adımları takip edebilirsiniz.
Bir podu silmek istediğinizde ilgili pod içindeki tüm containerlarda çalışan process'lere önce SIGTERM sinyali gönderilir. Eğer processler 30 saniye içinde sonlandırılmazsa bu sefer SIGKILL sinyali gönderilerek zorla sonladırılır.
Bir podu silmek için önce silmek istediğiniz podun adını bulmalısınız.
kubectl get pods
Daha sonra, aşağıdaki komutu kullanarak podu silebilirsiniz:
kubectl delete pod <pod-adı>
Tek bir pod yerine geçerli namespace altındaki tüm podları silmek istiyorsanız --all
parametresini kullanabilirsiniz.
kubectl delete pod --all
Belirli bir label'a sahip tüm podları silmek isterseniz ise -l
parametresi ile ilgili label'ı yazarak kullanabilirsiniz.
kubectl delete pod -l app=be
4. Pod'lara Annotation Eklemek ve Silmek
Pod Annotation, bir pod'unun üzerine belirli bir anahtar-değer çiftini eklemek veya mevcut bir anahtarın değerini güncellemek için kullanılır.
Bu işlem, bir pod'un metaverilerine ek açıklama eklemek veya mevcut açıklamaları güncellemek için kullanılabilir. Örneğin, bir pod'un ne amaçla oluşturulduğunu, kim tarafından oluşturulduğunu, hangi sürümün kullanıldığını ve diğer benzer bilgileri açıklamak için kullanılabilir.
Aşağıdaki örnek, "my-pod
" adlı bir pod'un üzerine "app-version
" anahtarını eklemek için kullanılan bir "pod annotate
" komutunu göstermektedir:
kubectl annotate pod my-pod app-version=1.0.0
Pod'lara eklenen annonation'ları silmek için ilgili annotation'ın sonuna -
koyarak komutu çalıştırmanız yeterlidir.
kubectl annotate pod my-pod app-version-
Ayrıca, tüm annotation'ları silmek istiyorsanız, --all
parametresini kullanabilirsiniz:
kubectl annotate pod my-pod --all
5. Pod'lara Label Eklemek ve Silmek
Pod label'ları, Kubernetes'te pod'ları gruplamak ve filtrelemek için kullanılan etiketlerdir. Pod'ların özelliklerini veya işlevlerini belirlemek için kullanılabilirler. Etiketler, pod'ların Kubernetes'te ölçeklendirilmesi, izlenmesi, güncellenmesi ve yönetilmesi için önemlidir.
Aşağıdaki komut, kubectl label
kullanarak my-pod
adlı bir pod'a environment=production
label'ı eklemek için bir örnek göstermektedir:
kubectl label pod my-pod environment=production
Bu komut, my-pod
adlı pod'a environment=production
etiketini ekler. -l
veya --selector
parametresini kullanarak birden fazla pod'u seçebilirsiniz. Örneğin, aşağıdaki komut, app=my-app
ve tier=backend
etiketlerine sahip tüm pod'ları seçer ve environment=production
etiketi ekler:
kubectl label pods -l app=my-app,tier=backend environment=production
kubectl label
komutunu kullanarak pod'lardan etiketleri de kaldırabilirsiniz. Aşağıdaki komut, my-pod
adlı pod'dan environment
etiketini kaldırır:
kubectl label pod my-pod environment-
Bu komut, my-pod
adlı pod'dan environment
etiketini kaldırır. Etiketi silmek için anahtar adının sonuna -
eklemeniz yeterlidir.
6. Pod'lara IP Adresi ve Port ile Erişmek
Oluşturduğumuz pod şu anda çalışıyor ve kubectl get
veya kubectl logs
komutlarıyla görüntüleyebiliyoruz. Fakat bu pod içinde çalışan uygulamamıza nasıl erişeceğiz?
Pod'lara atanan IP adresleri internal IP adresleridir ve cluster dışından direkt bu IP adreslerine erişemezsiniz. Cluster dışından pod'larınıza erişim elde etmek için önce kubectl port-forward <exernal-port>:<internal-port>
komutu ile ilgili pod'a port yönlendirmesi yapmamız gerekir.
Bu örnekte local makinenin 8888 portunu Pod içindeki 80 portuna yönlendirmiş olduk.
Artık 127.0.0.1:80
adresine gittiğinizde uygulamanızı görmüş olacaksınız.
Sıradaki yazı ile eğitim serisine devam edebilirsiniz.