Kubernetes Nedir ve Kurulumu
Bu yazıda önce Kubernetes’in ne olduğunu ve nasıl çalıştığını kısaca anlatıp, ardından kubeadm ile 1 control plane ve 1 worker node’dan oluşan bir cluster’ı adım adım kuracağız. Kurulum RHEL 9 / Rocky Linux 9 / AlmaLinux 9 üzerinde, container runtime olarak containerd ve resmi pkgs.k8s.io paket deposu ile yapılır.
Container Nedir, Kubernetes Neden Gerekli?
Container teknolojisi, bir uygulamayı ihtiyaç duyduğu paketler, kütüphaneler ve diğer bağımlılıklarıyla birlikte paketlememizi sağlar. Böylece uygulama, çalıştığı sunucunun özelliklerine bağlı kalmadan bir container runtime (containerd, CRI-O vb.) olan her makinede aynı şekilde çalışır.
Container sayısı arttıkça bunları elle yönetmek zorlaşır: hangi container hangi sunucuda çalışacak, çökerse kim yeniden başlatacak, trafiği kim dağıtacak? Kubernetes, bu soruları çözen bir container orkestrasyon platformudur.
Kubernetes Mimarisi

Control Plane (Master Node) Bileşenleri
- kube-apiserver: Cluster’a gelen tüm REST isteklerini karşılar, kimlik doğrulama ve yetkilendirme yapar. Yapılan tüm değişiklikleri etcd’ye yazar. Diğer tüm bileşenler birbiriyle API server üzerinden konuşur.
- kube-scheduler: Yeni oluşturulacak pod’un hangi node üzerinde çalışacağına karar verir. Kaynak gereksinimleri, node etiketleri, taint/toleration ve affinity kurallarını değerlendirir.
- kube-controller-manager: Cluster’ın mevcut durumunu sürekli olarak istenen duruma getiren denetleyicileri çalıştırır (Deployment, ReplicaSet, Node, Endpoint, ServiceAccount controller’ları vb.).
- etcd: Cluster’ın tüm durum bilgisini tutan, tutarlı ve dağıtık bir key-value veritabanıdır. etcd’nin yedeği, cluster’ın yedeği demektir.
Worker Node Bileşenleri
- kubelet: Her node üzerinde çalışan ana ajandır. API server’ı dinler, kendisine atanan pod’ları container runtime aracılığıyla ayağa kaldırır ve sağlıklı çalıştıklarını takip eder.
- kube-proxy: Service nesneleri için ağ kurallarını (iptables/IPVS) yönetir ve Service arkasındaki pod’lar arasında yük dağıtımı sağlar.
- Container runtime: Container’ları gerçekten çalıştıran katmandır. Kubernetes, CRI (Container Runtime Interface) uyumlu runtime’larla çalışır; en yaygınları containerd ve CRI-O‘dur. Docker Engine, Kubernetes 1.24 ile birlikte doğrudan desteklenmemektedir.
- Pod: Kubernetes’in en küçük çalışma birimidir. Bir veya daha fazla container’dan oluşur; pod içindeki container’lar aynı IP adresini ve network namespace’ini paylaşır.
Bir Pod Nasıl Oluşturulur?
- Kullanıcı
kubectlile pod oluşturma isteğini API server’a gönderir. - API server isteği doğrular ve etcd’ye yazar.
- Scheduler, henüz bir node’a atanmamış pod’u görür ve uygun node’u seçer.
- Seçim API server üzerinden etcd’ye kaydedilir.
- İlgili node’daki kubelet, kendisine yeni bir pod atandığını görür.
- Kubelet, container runtime’a (containerd) container’ları oluşturmasını söyler.
- Kubelet pod’un durumunu API server’a bildirir, durum etcd’ye yazılır.
Kubernetes Kurulumu (kubeadm)
Ön Gereksinimler
- 2 adet RHEL 9 / Rocky Linux 9 / AlmaLinux 9 sunucu (1 control plane, 1 worker)
- Her sunucuda en az 2 CPU ve 2 GB RAM (control plane için 2 CPU zorunludur)
- Sunucular birbirine ağ üzerinden erişebilmeli; her birinin hostname’i, MAC adresi ve
product_uuiddeğeri farklı olmalı - Komutlar root olarak çalıştırılır (ya da başına
sudoeklenir)
Aksi belirtilmedikçe aşağıdaki adımlar her iki sunucuda da uygulanır.
1. Hostname ve hosts Dosyası
# Control plane sunucusunda
hostnamectl set-hostname k8s-master
# Worker sunucusunda
hostnamectl set-hostname k8s-worker1
Her iki sunucuda /etc/hosts dosyasına kendi IP adreslerinizi ekleyin:
cat <<EOF >> /etc/hosts
192.168.1.10 k8s-master
192.168.1.11 k8s-worker1
EOF
2. Firewall Portları
Control plane üzerinde:
firewall-cmd --permanent --add-port=6443/tcp
firewall-cmd --permanent --add-port=2379-2380/tcp
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=10257/tcp
firewall-cmd --permanent --add-port=10259/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --reload
Worker node üzerinde:
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=10256/tcp
firewall-cmd --permanent --add-port=30000-32767/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --reload
| Port | Bileşen |
|---|---|
| 6443 | kube-apiserver |
| 2379-2380 | etcd |
| 10250 | kubelet API |
| 10257 | kube-controller-manager |
| 10259 | kube-scheduler |
| 10256 | kube-proxy |
| 30000-32767 | NodePort servisleri |
| 8472/udp | Flannel VXLAN |
3. Swap ve SELinux
swapoff -a
sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
setenforce 0
sed -i 's/^SELINUX=enforcing$/SELINUX=permissive/' /etc/selinux/config
4. Kernel Modülleri ve Ağ Ayarları
cat <<EOF > /etc/modules-load.d/k8s.conf
overlay
br_netfilter
EOF
modprobe overlay
modprobe br_netfilter
cat <<EOF > /etc/sysctl.d/k8s.conf
net.bridge.bridge-nf-call-iptables = 1
net.bridge.bridge-nf-call-ip6tables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
Eski kurulumlarda sık görülen /proc/sys/net/ipv4/ip_forward contents are not set to 1 hatası, yukarıdaki net.ipv4.ip_forward = 1 ayarı sayesinde artık oluşmaz.
5. containerd Kurulumu
containerd paketi Docker’ın resmi deposundan kurulur:
dnf install -y dnf-plugins-core
dnf config-manager --add-repo https://download.docker.com/linux/rhel/docker-ce.repo
dnf install -y containerd.io
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
systemctl enable --now containerd
systemctl status containerd
SystemdCgroup = true ayarı önemlidir: kubelet varsayılan olarak systemd cgroup sürücüsünü kullanır ve containerd’nin de aynı sürücüyü kullanması gerekir. Aksi halde pod’lar sürekli yeniden başlar.
6. kubeadm, kubelet ve kubectl Kurulumu
Eski packages.cloud.google.com deposu kapatıldı; paketler artık pkgs.k8s.io üzerinden ve her minor sürüm için ayrı bir depodan dağıtılıyor. Aşağıdaki ilk komut güncel kararlı sürümü otomatik olarak bulur:
K8S_MINOR=$(curl -Ls https://dl.k8s.io/release/stable.txt | cut -d. -f1,2)
echo $K8S_MINOR
cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/rpm/
enabled=1
gpgcheck=1
gpgkey=https://pkgs.k8s.io/core:/stable:/${K8S_MINOR}/rpm/repodata/repomd.xml.key
exclude=kubelet kubeadm kubectl cri-tools kubernetes-cni
EOF
dnf install -y kubelet kubeadm kubectl --setopt=disable_excludes=kubernetes
systemctl enable --now kubelet
Depodaki exclude satırı, sistem güncellemesi sırasında Kubernetes paketlerinin kontrolsüz şekilde yükseltilmesini engeller. Cluster yükseltmelerini her zaman kubeadm upgrade ile planlı yapın.
7. Cluster’ı Başlatma (Sadece Control Plane)
kubeadm config images pull
kubeadm init --pod-network-cidr=10.244.0.0/16
Komut tamamlandığında ekranın sonunda bir kubeadm join ... komutu görürsünüz. Bu komutu bir kenara kaydedin; worker node’u cluster’a eklerken kullanacağız.
kubectl’in cluster’a erişebilmesi için:
mkdir -p $HOME/.kube
cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
chown $(id -u):$(id -g) $HOME/.kube/config
8. Pod Ağı (Flannel)
kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml
kubectl get pods -n kube-flannel
CNI kurulmadan CoreDNS pod’ları Pending durumunda bekler; bu normaldir. Flannel çalışmaya başlayınca CoreDNS de ayağa kalkar.
9. Worker Node’u Cluster’a Ekleme
Worker sunucusunda, kubeadm init çıktısında aldığınız komutu çalıştırın:
kubeadm join 192.168.1.10:6443 --token <token> \
--discovery-token-ca-cert-hash sha256:<hash>
Komutu kaybettiyseniz veya token’ın süresi dolduysa (varsayılan 24 saat), control plane üzerinde yenisini üretebilirsiniz:
kubeadm token create --print-join-command
10. Kontrol
kubectl get nodes -o wide
kubectl get pods -A
İki node da Ready durumundaysa ve kube-system altındaki pod’lar Running ise cluster hazırdır.
Sık Karşılaşılan Sorunlar
| Belirti | Muhtemel sebep | Çözüm |
|---|---|---|
| kubeadm init swap hatası veriyor | Swap açık | swapoff -a ve fstab’daki swap satırını kapatın |
| Pod’lar sürekli yeniden başlıyor | cgroup sürücüsü uyuşmazlığı | containerd’de SystemdCgroup = true olduğunu kontrol edip systemctl restart containerd |
Node NotReady, CoreDNS Pending | CNI kurulmamış | Flannel adımını uygulayın, kube-flannel pod’larını kontrol edin |
| Worker join sırasında zaman aşımı | 6443 portu kapalı ya da token süresi dolmuş | Firewall kurallarını kontrol edin, kubeadm token create --print-join-command |
| Kurulumu baştan yapmak istiyorum | – | kubeadm reset -f sonra rm -rf $HOME/.kube /etc/cni/net.d |
Video Anlatım
Aşağıdaki video bu yazının ilk sürümünde, RHEL 7 üzerinde çekilmiştir. Kavramlar ve akış aynıdır; komutlar için yukarıdaki güncel adımları kullanın.
Çok faydalı bir çalışma olmuş. Elinize saglık
Teşekkür ederim.