Kubernetes Network ve Persistent Storage: Pratik Lab Rehberi
Bu yazıda Kubernetes cluster’ında network yapılandırması ve persistent storage yönetimini SSH üzerinden uygulamalı olarak öğreneceksiniz…

Kubernetes Network ve Persistent Storage: Pratik Lab Rehberi
Bu yazıda Kubernetes cluster’ında network yapılandırması ve persistent storage yönetimini SSH üzerinden uygulamalı olarak öğreneceksiniz. Huawei lab formatında, adım adım ilerleyeceğiz.
Lab Ortamı
Topoloji
Master Node (192.168.1.10) - k8s-master
├── Worker-1 (192.168.1.11)
└── Worker-2 (192.168.1.12)
Gereksinimler: Ubuntu 22.04, 2 CPU, 4GB RAM, Kubernetes v1.28+
Bölüm 1: Cluster Kurulumu ve İlk Yapılandırma
Adım 1.1: Master Node Hazırlığı
# Master node'a SSH bağlantısı
ssh root@192.168.1.10
# Sistem hazırlığı
apt update && apt upgrade -y
hostnamectl set-hostname k8s-master
# Hosts dosyasını düzenle
cat <<EOF >> /etc/hosts
192.168.1.10 k8s-master
192.168.1.11 k8s-worker1
192.168.1.12 k8s-worker2
EOF
Adım 1.2: Container Runtime (containerd) Kurulumu
# Kernel modülleri
cat <<EOF | tee /etc/modules-load.d/containerd.conf
overlay
br_netfilter
EOF
modprobe overlay && modprobe br_netfilter
# Sysctl parametreleri
cat <<EOF | tee /etc/sysctl.d/99-kubernetes-cri.conf
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
net.bridge.bridge-nf-call-ip6tables = 1
EOF
sysctl --system
# Containerd kurulumu
apt install -y containerd
mkdir -p /etc/containerd
containerd config default | tee /etc/containerd/config.toml
systemctl restart containerd && systemctl enable containerd
Adım 1.3: Kubernetes Bileşenleri
# Kubernetes repository
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.28/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.28/deb/ /' | tee /etc/apt/sources.list.d/kubernetes.list
# Kurulum
apt update
apt install -y kubelet kubeadm kubectl
apt-mark hold kubelet kubeadm kubectl
# Swap kapat
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
Adım 1.4: Cluster Başlatma
# Master node'u initialize et
kubeadm init --pod-network-cidr=10.244.0.0/16 --apiserver-advertise-address=192.168.1.10
# Çıktıdaki join komutunu kaydet!
# kubectl config
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
# Kontrol
kubectl get nodes
# Master node 'NotReady' (CNI kurulmadı)
Bölüm 2: Network Yapılandırması
Adım 2.1: Calico CNI Kurulumu
# Calico operator
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/tigera-operator.yaml
# Calico resources
kubectl create -f https://raw.githubusercontent.com/projectcalico/calico/v3.26.1/manifests/custom-resources.yaml
# Pod'ların başlamasını bekle
watch kubectl get pods -n calico-system
# Node durumu
kubectl get nodes
# Master artık 'Ready'
Adım 2.2: Worker Node’ları Ekleme
# Worker-1'e bağlan
ssh root@192.168.1.11
# Adım 1.1-1.3'ü tekrarla (containerd ve kubeadm kurulumu)
# Master'dan aldığınız join komutunu çalıştır
kubeadm join 192.168.1.10:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
# Worker-2 için aynı işlemi tekrarla
Master’da kontrol:
kubectl get nodes -o wide
# 3 node 'Ready' durumunda
Adım 2.3: Network Policy ile Trafik Kontrolü
# İki namespace oluştur
kubectl create namespace development
kubectl create namespace production
kubectl label namespace development env=dev
kubectl label namespace production env=prod
# Her namespace'e pod deploy et
kubectl run dev-app --image=nginx:alpine -n development
kubectl run prod-app --image=nginx:alpine -n production
# IP'leri al
kubectl get pods -n development -o wide
kubectl get pods -n production -o wide
# Default: Her yerden erişim var
kubectl exec dev-app -n development -- wget -O- http://<prod-pod-ip> --timeout=5
# Başarılı
Network Policy ile Kısıtlama:
# Production'a gelen tüm trafiği engelle
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: deny-all-ingress
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
EOF
# Artık erişim engellendi
kubectl exec dev-app -n development -- wget -O- http://<prod-pod-ip> --timeout=5
# Timeout
Sadece Dev Namespace’den İzin Ver:
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: allow-from-dev
namespace: production
spec:
podSelector: {}
policyTypes:
- Ingress
ingress:
- from:
- namespaceSelector:
matchLabels:
env: dev
ports:
- protocol: TCP
port: 80
EOF
# Şimdi HTTP erişimi başarılı
kubectl exec dev-app -n development -- wget -O- http://<prod-pod-ip>
Bölüm 3: Persistent Storage
Adım 3.1: PersistentVolume Oluşturma
# Worker-1'de storage dizini oluştur
ssh root@192.168.1.11
mkdir -p /mnt/k8s-pv
echo "Hello from PV" > /mnt/k8s-pv/index.html
exit
# PV oluştur
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv-local
spec:
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: manual
hostPath:
path: /mnt/k8s-pv
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- k8s-worker1
EOF
kubectl get pv
# STATUS: Available
Adım 3.2: PVC ile Bind Etme
# PVC oluştur
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: pvc-local
spec:
accessModes:
- ReadWriteOnce
storageClassName: manual
resources:
requests:
storage: 3Gi
EOF
kubectl get pvc
# STATUS: Bound
kubectl get pv
# STATUS: Bound
Adım 3.3: Pod’da PVC Kullanma
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: nginx-pv
spec:
volumes:
- name: storage
persistentVolumeClaim:
claimName: pvc-local
containers:
- name: nginx
image: nginx:alpine
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: storage
nodeSelector:
kubernetes.io/hostname: k8s-worker1
EOF
# Dosyayı kontrol et
kubectl exec nginx-pv -- cat /usr/share/nginx/html/index.html
# Output: Hello from PV
Adım 3.4: Data Persistence Testi
# Yeni dosya yaz
kubectl exec nginx-pv -- sh -c "echo 'Persistent data' > /usr/share/nginx/html/test.txt"
# Pod'u sil
kubectl delete pod nginx-pv
# Worker node'da veri durumu
ssh root@192.168.1.11 "cat /mnt/k8s-pv/test.txt"
# Output: Persistent data
# Pod'u yeniden oluştur
kubectl apply -f <same-yaml>
# Veri hala orada
kubectl exec nginx-pv -- cat /usr/share/nginx/html/test.txt
# Output: Persistent data
Bölüm 4: Service ve Ingress
Adım 4.1: Service Tipleri
# Deployment oluştur
kubectl create deployment web --image=nginx:alpine --replicas=3
# ClusterIP (cluster içi)
kubectl expose deployment web --port=80 --type=ClusterIP --name=web-clusterip
# NodePort (dış erişim)
kubectl expose deployment web --port=80 --type=NodePort --name=web-nodeport --node-port=30080
# Servisleri kontrol et
kubectl get svc
# NodePort testi
curl http://192.168.1.11:30080
Adım 4.2: Ingress Controller
# NGINX Ingress Controller
kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.8.1/deploy/static/provider/baremetal/deploy.yaml
# Controller'ın başlamasını bekle
kubectl get pods -n ingress-nginx
# İki backend oluştur
kubectl create deployment app1 --image=nginx:alpine
kubectl create deployment app2 --image=httpd:alpine
kubectl expose deployment app1 --port=80 --name=app1-svc
kubectl expose deployment app2 --port=80 --name=app2-svc
# Ingress oluştur
cat <<EOF | kubectl apply -f -
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: multi-app
spec:
ingressClassName: nginx
rules:
- host: app1.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app1-svc
port:
number: 80
- host: app2.local
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: app2-svc
port:
number: 80
EOF
# Test
echo "192.168.1.11 app1.local app2.local" >> /etc/hosts
curl -H "Host: app1.local" http://192.168.1.11:<ingress-port>
Bölüm 5: ConfigMap ve Secret
Adım 5.1: ConfigMap
# ConfigMap oluştur
kubectl create configmap app-config \
--from-literal=db_host=mysql.default.svc \
--from-literal=log_level=info
# Pod'da kullan
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: config-pod
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo DB_HOST=\$DB_HOST && sleep 3600"]
env:
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: db_host
EOF
kubectl logs config-pod
# Output: DB_HOST=mysql.default.svc
Adım 5.2: Secret
# Secret oluştur
kubectl create secret generic db-secret \
--from-literal=username=admin \
--from-literal=password=secret123
# Pod'da kullan
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: secret-pod
spec:
containers:
- name: app
image: busybox
command: ["sh", "-c", "echo USER=\$USER PASS=\$PASS && sleep 3600"]
env:
- name: USER
valueFrom:
secretKeyRef:
name: db-secret
key: username
- name: PASS
valueFrom:
secretKeyRef:
name: db-secret
key: password
EOF
kubectl logs secret-pod
# Output: USER=admin PASS=secret123
Bölüm 6: Monitoring ve Troubleshooting
Adım 6.1: Metrics Server
# Metrics server kur
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# TLS bypass (lab için)
kubectl patch deployment metrics-server -n kube-system --type='json' \
-p='[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
# Resource kullanımı
kubectl top nodes
kubectl top pods
Adım 6.2: Debugging Komutları
# Pod detayları
kubectl describe pod <pod-name>
# Loglar
kubectl logs <pod-name>
kubectl logs -f <pod-name> # Real-time
kubectl logs <pod-name> --tail=50
kubectl logs <pod-name> --previous # Crashed container
# Pod içine gir
kubectl exec -it <pod-name> -- /bin/sh
# Events
kubectl get events --sort-by='.lastTimestamp'
# Network testi
kubectl exec <pod-name> -- ping -c 3 <target-ip>
kubectl exec <pod-name> -- nslookup kubernetes.default
Adım 6.3: Common Issues
ImagePullBackOff:
kubectl describe pod <pod-name> | grep -A 5 Events
# Çözüm: Image adını kontrol et veya pull secret ekle
CrashLoopBackOff:
kubectl logs <pod-name> --previous
# Uygulama hata loglarını incele
Pending Pod:
kubectl describe pod <pod-name>
# Çözüm: Resource yetersizliği veya node selector hatası
Lab Özeti ve Best Practices
Yapılan İşlemler
✅ Kubernetes cluster kurulumu (1 master, 2 worker) ✅ Calico CNI ile network yapılandırması ✅ Network Policy ile trafik kontrolü ✅ PV/PVC ile persistent storage ✅ Service tipleri (ClusterIP, NodePort) ✅ Ingress controller ile routing ✅ ConfigMap ve Secret yönetimi ✅ Monitoring ve troubleshooting
Best Practices
- Resource Limits: Her pod için CPU/Memory limit tanımlayın
- Namespace Kullanımı: Ortamları (dev/prod) ayırın
- RBAC: Erişim kontrolü uygulayın
- Health Checks: Liveness ve readiness probe ekleyin
- Backup: etcd ve PV verilerini yedekleyin
- Network Policy: Default deny politikası uygulayın
- Secret Management: Hassas verileri Secret olarak saklayın
Cleanup Komutları
# Tüm pod'ları sil
kubectl delete pods --all
# Namespace sil
kubectl delete namespace development production
# PVC ve PV temizliği
kubectl delete pvc --all
kubectl delete pv --all
# Cluster sıfırlama (tüm node'larda)
kubeadm reset -f
rm -rf /etc/cni/net.d
rm -rf $HOME/.kube
Kaynakça
- Kubernetes Official Documentation. (2025). “Networking”. https://kubernetes.io/docs/concepts/services-networking/
- Kubernetes Official Documentation. (2025). “Persistent Volumes”. https://kubernetes.io/docs/concepts/storage/persistent-volumes/
- Project Calico. (2025). “Get Started with Calico”. https://docs.tigera.io/calico/latest/getting-started/
- NGINX Ingress Controller. (2025). “Installation Guide”. https://kubernetes.github.io/ingress-nginx/deploy/
- Kubernetes Official Documentation. (2025). “Network Policies”. https://kubernetes.io/docs/concepts/services-networking/network-policies/
Not: Bu lab çalışması production ortamı için değil, öğrenme amaçlıdır. Production’da managed Kubernetes servisleri ve enterprise storage çözümleri kullanılmalıdır.
메타데이터
- post_id
- d1dc3af30f4c
- slug
- kubernetes-network-ve-persistent-storage-pratik-lab-rehberi-d1dc3af30f4c
- url
- https://medium.com/@dr.parkt01/kubernetes-network-ve-persistent-storage-pratik-lab-rehberi-d1dc3af30f4c
- canonical_url
- https://medium.com/@dr.parkt01/kubernetes-network-ve-persistent-storage-pratik-lab-rehberi-d1dc3af30f4c
- author_url
- https://medium.com/@dr.parkt01
- status
- ok
- fetched_at
- 2026-06-21 07:44:09