K3s Cluster'ından Worker Node Silmek

Selamlar, bu yazımda K3s cluster'ından bir worker node'u nasıl temiz bir şekilde sileriz, ona bakacağız. Konu basit gibi gözüküyor ama acele edilince hem üstündeki pod'lar düşüyor hem de cluster'da hayalet node kayıtları kalıyor. Lafı uzatmadan adımlara geçelim.

İşin özü iki aşamalı: önce node'un üstündeki iş yüklerini Kubernetes'in drain mekanizmasıyla nazikçe başka node'lara taşıyacağız, sonra makinenin kendisinden K3s agent'ını söküp arkasında bıraktığı kalıntıları temizleyeceğiz. Bu sırayı atlamayın derim, çünkü doğrudan delete node çekerseniz pod'lar bir anda kaybolur, controller yeniden ayağa kaldırana kadar request'ler 502 dönmeye başlar.

Önce node'u tespit edelim

Hangi node'u sileceğimizi netleştirelim ve üstünde ne dönüyor bir bakalım:

kubectl get nodes -o wide
kubectl get pods -A --field-selector spec.nodeName=worker-01

İkinci komut bence hayati. Bazen 'boş zannettiğim node'da meğer prod'un metrics-collector'u çalışıyormuş' tarzı sürprizlerle karşılaşırsınız. Önceden görmek, sonradan açıklama yazmaktan iyidir.

Cordon ve drain

Şimdi node'u cordon'layarak yeni pod kabul etmesini engelleyelim, ardından üstündekileri tahliye edelim:

kubectl cordon worker-01

kubectl drain worker-01 \
  --ignore-daemonsets \
  --delete-emptydir-data \
  --timeout=120s

--ignore-daemonsets flag'i şart, çünkü DaemonSet'ler tanım gereği her node'da çalışır ve drain onları taşıyamaz. --delete-emptydir-data ise emptyDir volume kullanan pod'ları görünce drain'in durmamasını sağlar; ama bu volume'lerdeki veri uçacak, ona göre. PodDisruptionBudget'a takılırsanız ilgili PDB'yi kubectl describe pdb ile inceleyin, gerçekten esnetmek güvenli mi diye karar verin, sonra kubectl edit pdb ile geçici olarak gevşetin ve drain'den sonra eski haline döndürün.

Drain bittiğinde node'da sadece DaemonSet pod'ları kalmış olmalı:

kubectl get pods -A -o wide --field-selector spec.nodeName=worker-01

Node'u cluster'dan düşürmek

Sıra geldi node objesini Kubernetes tarafından silmeye:

kubectl delete node worker-01
kubectl get nodes

Burada güzel bir yan etki var: K3s her node için <node-adi>.node-password.k3s şeklinde bir secret tutar kube-system içinde. delete node çağrısı bu secret'ı da kendiliğinden temizler. Yine de paranoyak davranıp kontrol etmek iyi olur:

kubectl -n kube-system get secrets | grep 'worker-01.node-password.k3s'

Çıktı boşsa tertemiz, secret silinmiş demektir.

Agent'ı makineden söküp atmak

Sıra geldi makinenin kendisine. SSH ile node'a bağlanın ve K3s'in size hediye ettiği uninstall script'ini çalıştırın:

ssh root@worker-01-ip
/usr/local/bin/k3s-agent-uninstall.sh

Bu script bence harika bir şey: servisi durduruyor, binary'leri ve symlink'leri siliyor, /var/lib/rancher/k3s, /etc/rancher/k3s, /run/k3s, /run/flannel, /var/lib/kubelet, /var/lib/cni gibi dizinleri temizliyor, üstüne flannel ve CNI'nin bıraktığı network interface'lerini de kaldırıyor. Tek başınıza yapsanız atlama ihtimaliniz yüksek.

Gel gör ki bazen bu script bulunamayabilir; eski kurulumlar veya bozuk paket güncellemeleri sonucu kaybolmuş olabiliyor. O zaman elle gideceğiz:

systemctl stop k3s-agent
systemctl disable k3s-agent
rm -f /etc/systemd/system/k3s-agent.service
rm -f /etc/systemd/system/k3s-agent.service.env
systemctl daemon-reload

rm -f /usr/local/bin/k3s /usr/local/bin/k3s-killall.sh
rm -rf /var/lib/rancher/k3s /etc/rancher/k3s
rm -rf /run/k3s /run/flannel
rm -rf /var/lib/kubelet /var/lib/cni

ip link delete flannel.1 2>/dev/null || true
ip link delete cni0 2>/dev/null || true

/var/lib/rancher/k3s özellikle önemli; orayı silmezseniz makineyi yeniden cluster'a aldığınızda eski node ID'siyle gelir ve API server kafayı yer.

Sık karşılaşılan hatalar

  • Drain'i atlayıp doğrudan delete node çekmek: Node hâlâ ayakta olduğu için kubelet bir süre daha API server'a bağlanmaya çalışır, pod'lar üstünde dönmeye devam eder. Controller'lar yeni pod ayağa kaldırana kadar trafik kaybedersiniz.
  • /var/lib/rancher/k3s dizinini silmemek: Aynı makineyi tekrar cluster'a almak istediğinizde eski TLS sertifikaları ve node kimliği yüzünden join hata verir. Tecrübeyle sabit.
  • PodDisruptionBudget'ı görmezden gelip --force ile geçmek: Drain ısrarla itiraz ediyorsa bir nedeni vardır. Önce PDB'yi okuyun, sonra karar verin.

Kapanış

Bu yazıda K3s'te bir worker node'u cluster'dan nasıl temiz bir şekilde çıkardığımıza baktık: drain, delete, uninstall sırası şaşmasın. Bence prod cluster'da node silmek, kurmaktan daha dikkat isteyen bir iş; çünkü kurarken bir şey patlasa zaten görürsünüz, ama silerken yarım bıraktığınız artıklar haftalar sonra başınıza dert olur. Umarım faydalı olur, bir sonraki yazıda görüşmek üzere.