Ubuntu Kubelet 10250 Portu Hatası Çözümü
Ubuntu sistemlerde kubelet API portu 10250 ile yaşanan address already in use hatalarını ve kubectl exec ile logs komutlarını engelleyen güvenlik duvarı sorunlarını giderin.
10250 numaralı port nedir
10250 numaralı port kubelet API'sine aittir ve bu portu içeren her hata, birbirine zıt iki sorundan birine işaret eder. Ya port halihazırda başka bir süreç tarafından kullanılmaktadır ve bu yüzden kubeadm init çalışmayı reddeder ya da port erişilemez durumdadır; bu durumda da kubectl logs ve kubectl exec, aksi takdirde tamamen sağlıklı görünen bir düğüm (node) üzerinde başarısız olur.
kubelet, Kubernetes'in her düğüm üzerinde çalıştırdığı bir ajandır. Konteynerleri başlatır ve durumlarını kontrol düzlemine (control plane) raporlar. Ayrıca TCP 10250 portunu dinler ve kontrol düzleminin çağrı yaptığı bir HTTPS API sunar. kubectl logs, kubectl exec, kubectl attach veya kubectl port-forward komutlarını çalıştırdığınızda API sunucusu bu porta bir bağlantı açar. metrics-server, kubectl top node komutunun çalışmasını sağlayan verileri aynı port üzerindeki /metrics/resource üzerinden toplar.
Bu API kimlik doğrulamalıdır. kubeadm anonim erişimi kapatır ve kubelet'i küme CA'sine (sertifika yetkilisi) yönlendirir; bu nedenle kimlik bilgisi içermeyen bir istek, konteynerlerinizden birine erişim sağlamak yerine Unauthorized yanıtı ile karşılanır. Bu detayı unutmayın, çünkü portun erişilebilir olduğunu kanıtlamanın en hızlı yolu budur. Port kavramı sizin için yeniyse, Linux'ta portun gerçekte ne olduğu başlıklı bölüm, bu kılavuzun temel aldığı modeli açıklamaktadır.
Her iki hata modu da tek bir gereksinime dayanır. kubelet başlamadan önce 10250 numaralı port boş olmalı ve çalışmaya başladıktan sonra kontrol düzleminden erişilebilir olmalıdır.
Hangi sorunla karşı karşıyasınız
İlgili düğüm üzerinde aşağıdaki komutları çalıştırın. Aşağıdaki her komut, kendi sunucunuzda bizzat uygulamanız gereken komutlardır.
sudo ss -lntp | grep 10250
sudo systemctl status kubelet --no-pagerss -lntp, dinleme durumundaki TCP soketlerini ve her birinin arkasındaki süreci listeler. -l dinleme durumunu, -n portların sayısal olarak gösterilmesini, -t kapsamın TCP ile sınırlandırılmasını, -p ise ilgili süreci gösterir. Bu son bayrak root yetkisi gerektirir; aksi takdirde süreç sütunu boş döner ve herhangi bir bilgi edinemezsiniz.
users:(("kubelet",pid=1043,fd=23)) ile biten bir satır, kubelet'in çalıştığını ve portu tuttuğunu gösterir. Eğer portun boşta olmasını bekliyorsanız, sorununuzun cevabı budur. Eğer ss hiçbir çıktı vermiyor ve kontrol düzlemi hala bu düğüme erişemiyorsa, henüz bir güvenlik duvarı sorunu yoktur; çünkü port üzerinde hizmet veren bir süreç bulunmamaktadır. Herhangi bir kuralı değiştirmeden önce kubelet'in neden kapalı olduğunu tespit edin.
systemctl status kubelet resmin diğer yarısını sunar. Birkaç dakika öncesine ait bir başlangıç zamanı ile active (running) normaldir. Siz kubeadm init veya kubeadm join komutlarını çalıştırmadan önce kubelet'in her birkaç saniyede bir yeniden başlaması da normaldir: paketlenmiş birim kurulum anında başlar, yapılandırma dosyası bulamaz ve sonlanır. Upstream belgeleri, kubelet kubeadm'den ne yapması gerektiğini öğrenene kadar bu durumu beklenen bir davranış (crash loop) olarak tanımlar. systemd yeniden başlatma davranışına aşina değilseniz, systemd servis türleri ve yeniden başlatma politikalarının nasıl çalıştığı bu bölüm için temel bilgileri içerir.
kubeadm init çalıştırıldığında 10250 numaralı port neden kullanımda
kubeadm init diske herhangi bir veri yazmadan önce ön denetimleri gerçekleştirir. Bu denetimlerden biri, kontrol düzleminin ihtiyaç duyduğu her bir porta bağlanmayı dener ve bu işlem başarısız olduğunda 10250 numaralı portu belirten bir hata ile durur. Bu bir yazılım hatası değildir. Bu, kubeadm'in ilkinin kalıntıları üzerine ikinci bir küme oluşturmayı reddetmesidir.
Uygulamada buna dört durum neden olur:
- Yarım kalan bir önceki
kubeadm initveyakubeadm joinişlemi. kubelet zaten bir yapılandırma aldığı için çalışmaktadır ve portu tutmaktadır. - Başlatılmış ancak tamamlanmamış bir
kubeadm resetişlemi. Reset komutu kubelet'i durdurur ancak birimi devre dışı bırakmaz; bu nedenle bir sonraki yeniden başlatmada dinleyici tekrar ayağa kalkar. - Aynı sunucuda yüklü olan k3s veya başka bir Kubernetes dağıtımı. k3s, kendi içinde bir kubelet barındırır ve bu kubelet de 10250 numaralı portu bağlar.
- Henüz kubeadm çalıştırmadığınız bir makinede, apt tarafından çekilen ve kendi systemd birimiyle başlatılan
kubeletpaketi.
Herhangi bir değişiklik yapmadan önce sorunun hangisi olduğunu belirleyin:
sudo ss -lntp 'sport = :10250'
systemctl list-units --type=service --state=running | grep -Ei 'kubelet|k3s|k0s'Eğer dinleyici k3s'e aitse, durun ve hangi kümeyi istediğinize karar verin. k3s ve kubeadm aynı sunucuyu paylaşamazlar; çünkü aynı portları ve aynı CNI (container network interface) dizinini talep ederler. k3s yükleyicisi, sunucu düğümünde /usr/local/bin/k3s-uninstall.sh, aracı düğümünde ise k3s-agent-uninstall.sh konumunda bir kaldırma betiği bırakır.
kubelet sürecini sonlandırmak portu neden serbest bırakmaz
sudo pkill kubelet, 10250 numaralı portu yaklaşık on saniyeliğine serbest bırakır. Paketlenmiş birim bir yeniden başlatma politikasına sahip olduğundan, systemd yeni bir kubelet başlatır ve bu süreç aynı portu tekrar dinlemeye başlar. Politikayı şu komutla kendiniz görebilirsiniz:
systemctl show kubelet -p Restart -p RestartSec
sudo systemctl stop kubelet
sudo ss -lntp | grep 10250Restart=always ile RestartSec=10, birimin varsayılan ayarlarıdır; kill komutunun çalışıyor gibi görünüp ardından başarısız olmasının tam nedeni budur. systemctl stop, portu serbest bırakmanın doğru yoludur; çünkü systemd, durdurulması talimatını verdiğiniz bir birimi yeniden başlatmayı bırakır.
Bir kümenin yarısını taşıyan bir düğümde portun boş olması yeterli değildir. /var/lib/kubelet/config.yaml, /etc/kubernetes/pki altındaki sertifikalar ve /etc/kubernetes/manifests içindeki tüm statik pod manifestleri hala oradadır. Daha sonraki ön kontrol (preflight) süreçleri bu dosyalara takılır; kontrolleri zorla geçmek ise sertifikaları yapılandırmasıyla eşleşmeyen bir kümeye yol açar. Bunun yerine düğümü usulüne uygun şekilde sıfırlayın.
Düğümü temiz bir şekilde sıfırlama
sudo kubeadm reset -f
sudo rm -rf /etc/cni/net.d
rm -rf $HOME/.kube
sudo systemctl stop kubelet
sudo ss -lntp | grep -E '10250|6443|2379'-f bayrağı, onay istemini atlar. Sıfırlama işlemi, init veya join komutlarının gerçekleştirdiği değişiklikleri mümkün olduğunca geri alır. Yerel dosyaları ve yapılandırmayı kaldırır, kontrol düzlemi düğümündeki yerel etcd üyesini siler, /etc/kubernetes/pki dizinindeki sertifikaları temizler ve kubelet yapılandırması ile manifest dosyalarını kaldırır.
Belgeler, sıfırlama işleminin neleri geride bıraktığı konusunda açıktır ve her bir madde kullanıcıların hata yapmasına neden olabilir. İşlem /etc/cni/net.d dizinini temizlemez; bu nedenle eski CNI eklentisi yapılandırması kalır ve yeni kümeniz bunu okumaya devam eder. Ayrıca kube-proxy tarafından ana makineye uygulanan iptables, nftables veya IPVS kurallarını temizlemez. $HOME/.kube dosyasına dokunmaz; bu yüzden kubectl artık var olmayan bir küme ile iletişim kurmaya çalışır ve yeni bir sorun gibi görünen sertifika hataları döndürür.
Geride kalan paket kuralları işin en zahmetli kısmıdır. Tabloları manuel olarak temizlemek, ufw tarafından yüklenen kuralları da siler; çünkü Ubuntu üzerindeki ufw aynı arka uç üzerinden yazar. Bu durum, sudo ufw reload komutunu çalıştırana kadar sunucuyu filtresiz bırakır. Zaten yeniden oluşturduğunuz bir düğümde, sıfırlama işleminden sonra sistemi yeniden başlatın. Yeniden başlatma, kube-proxy tarafından eklenen çalışma zamanı kurallarını temizler ve yarı temizlenmiş bir kural kümesini düzeltmeye çalışmaktan daha az zaman alır. iptables ve nftables kurallarının neden birbirlerinin çıktısında göründüğü konusu, arka planda nelerin gerçekleştiğini açıklar.
Son ss komutu hiçbir çıktı üretmemelidir. 10250, 6443 veya 2379 numaralı portlarda dinleme yapan bir servis olmaması, düğümün yeni bir kubeadm init işlemine hazır olduğu anlamına gelir.
Neden kubectl logs ve kubectl exec komutları 10250 numaralı portta zaman aşımına uğrar
Bu durum, bir önceki sorunun tam tersidir ve kendini doğrudan bir port sorunu olarak belli etmez. Küme ayağa kalkar. Düğümler Ready durumundadır. Pod'lar çalışır. Ancak bir komut başarısız olur:
Error from server: Get "https://10.0.0.12:10250/containerLogs/default/web-0/web": dial tcp 10.0.0.12:10250: i/o timeoutBu mesajı sondan başlayarak okuyun. API sunucusu, düğüme 10250 numaralı port üzerinden bir TCP bağlantısı açmaya çalıştı ancak yanıt alamadı. i/o timeout, paketlerin sessizce düşürüldüğü anlamına gelir; yani bir şey bu paketleri filtrelemektedir: düğüm üzerindeki ana bilgisayar güvenlik duvarı veya kontrol panelinizdeki sağlayıcının ayrı ağ güvenlik duvarı. Aynı konumdaki connect: connection refused ise tam tersini ifade eder. Paket ulaştı ancak dinleyen bir servis yoktu; bu da kubelet'in kapalı olduğu anlamına gelir. Bu, connection refused ile connection timed out arasındaki fark bölümünde farklı bir port üzerinden açıklanan aynı nedenler çiftidir.
Düğümler bu süreç boyunca Ready durumunda kalır çünkü düğüm durumu ters yönde iletilir. Kubelet, 6443 numaralı port üzerinden API sunucusuna dışa doğru bağlanır ve kendi sinyalini (heartbeat) gönderir; bu işlem için 10250 numaralı portta herhangi bir gelen bağlantıya ihtiyaç duyulmaz. Dolayısıyla, engellenmiş bir 10250 numaralı port, pod'ları normal şekilde zamanlayan ancak yalnızca logs, exec, port-forward ve metrics işlemlerinde başarısız olan bir küme ile sonuçlanır.
error: Metrics API not available sorusuna yanıt veren kubectl top node, metrics-server üzerinden görülen aynı hatadır; metrics-server'ın günlüğü düğümü ve portu şu şekilde belirtir:
unable to fully scrape metrics from node worker-1: unable to fetch metrics from node worker-1: Get "https://10.0.0.12:10250/metrics/resource": dial tcp 10.0.0.12:10250: i/o timeoutGüvenlik duvarı kuralını düzenlemeden önce yolu test edin
Bunu bir control plane düğümünden, worker adresine karşı çalıştırın:
nc -zv 10.0.0.12 10250
curl -sk -o /dev/null -w '%{http_code}\n' https://10.0.0.12:10250/healthznc -z bir bağlantı açar, kapatır ve port bağlantıyı kabul ettiğinde succeeded! çıktısını verir. curl satırı daha iyi bir testtir; çünkü portun sadece açık olduğunu değil, kubelet'in hizmet verdiğini kanıtlar. 401 çıktısını verir. Bu sağlıklı bir sonuçtur: TLS (transport layer security) el sıkışması tamamlanmış, ardından kubelet kimliği doğrulanmamış bir isteği reddetmiştir; olması gereken tam olarak budur. -k sertifika kontrolünü atlar; yolu test ettiğiniz, güven zincirini test etmediğiniz için bu bir sorun teşkil etmez.
Zaman aşımı ile sonuçlanan uzun bir bekleme, paketlerin düşürüldüğü anlamına gelir. curl: (7) Failed to connect sonucunun anında dönmesi, portun erişilebilir bir ana makinede kapalı olduğu anlamına gelir. Testi dizüstü bilgisayarınızdan değil, control plane düğümünden yapın; çünkü burada erişimi önemli olan tek makine control plane'dir.
Control plane ve worker düğümlerinin ihtiyaç duyduğu portlar
Bunlar, upstream tarafından listelenen gelen portlardır. Bir control plane düğümünde, API sunucusu için TCP 6443 portu, kubectl çalıştıran her şeye açık olmalıdır. etcd istemci ve eş API'si için TCP 2379 ile 2380 portları, API sunucusu ve etcd'nin kendisi tarafından kullanılır. kubelet API'si için TCP 10250 portu, düğümün kendisi ve control plane tarafından kullanılır. kube-scheduler için TCP 10259 ve kube-controller-manager için TCP 10257 portları, yalnızca düğümün kendisi tarafından kullanılır.
Bir worker düğümünde, kubelet API'si için TCP 10250 portu, düğümün kendisi ve control plane tarafından kullanılır. kube-proxy için TCP 10256 portu, düğümün kendisi ve sağlık kontrolleri yapan yük dengeleyiciler tarafından kullanılır. NodePort servisleri için TCP ve UDP 30000 ile 32767 arasındaki portlar, varsayılan aralıktır ve bu servislere ihtiyaç duyan herkes tarafından erişilebilir olmalıdır.
CNI eklentiniz bu listeye ek olarak kendi portlarını da kullanır ve bunlar bu listede yer almaz. VXLAN modundaki Flannel ve Calico, düğümler arasında UDP 4789 portuna ihtiyaç duyar. BGP kullanan Calico ise TCP 179 portuna ihtiyaç duyar. Eklentinizin dokümantasyonunu kontrol edin ve bu portları düğümler arasında açın; aksi takdirde, bu bölümdeki tüm portlar açık olsa bile farklı düğümlerdeki podlar birbirleriyle iletişim kuramaz.
10250 numaralı portu internete açmadan yapılandırın
Kubelet API, düğüm üzerindeki herhangi bir container içinde süreç başlatabilir. 10250 numaralı portun açık olması, düğüme root erişimi sağlamakla eşdeğerdir; bu nedenle erişimi kaynak IP adresine göre kısıtlayın. Portu hiçbir zaman dış dünyaya tamamen açık bırakmayın.
sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp comment 'kubelet API'
sudo ufw allow from 10.0.0.0/24 to any port 10256 proto tcp comment 'kube-proxy'
sudo ufw status numbered10.0.0.0/24 ifadesini düğümlerinizin paylaştığı ağ ile değiştirin. ufw status numbered komutu, aktif kuralları bir dizin numarasıyla listeler; böylece hatalı bir kuralı sudo ufw delete <number> ile silebilirsiniz. VPS için temel ufw kullanımı rehberi, hangi kuralların geçerli olacağını belirleyen kural sıralama mantığını açıklar.
Tek bir ufw ayarı, Kubernetes'in çalışmasını doğrudan bozabilir. Düğümler arası pod trafiği yönlendirilir (forward), yerel olarak teslim edilmez; ufw ise varsayılan olarak yönlendirilen paketleri reddeder. /etc/default/ufw dosyasında DEFAULT_FORWARD_POLICY="ACCEPT" ayarını yapılandırın ve sudo ufw reload komutunu çalıştırın. Bu ayar yapılmadığı sürece, 10250 numaralı port tamamen açık olsa bile düğümler arası pod trafiği başarısız olur.
Sunucu sağlayıcınızın güvenlik duvarını da kontrol edin. Çoğu VPS paneli, sunucunun önünde yer alan ve ufw status tarafından görülmeyen ağ düzeyinde bir güvenlik duvarına sahiptir. Paket sunucuya ulaşmıyorsa, düğüm üzerinde eklediğiniz bir kuralın hiçbir etkisi olmaz.
Port erişilebilir olduğu halde istek başarısız olduğunda
Bazı 10250 hataları askıda kalmak yerine anında geri döner; bu durum bağlantının başarılı olduğunu ancak isteğin reddedildiğini gösterir. metrics-server günlüğündeki x509: certificate signed by unknown authority, kubelet'in scraper tarafından güvenilmeyen, kendinden imzalı bir sertifika sunduğu anlamına gelir. Yaygın çözümler, küme CA'sının imzalaması için kubelet sertifika rotasyonunu etkinleştirip ardından sertifika imzalama isteğini onaylamak veya laboratuvar ortamındaki bir kümede riski kabul ederek metrics-server'ı --kubelet-insecure-tls ile çalıştırmaktır.
Forbidden içeren bir mesajın nodes/proxy veya nodes/metrics ile birlikte görülmesi, bir RBAC (rol tabanlı erişim denetimi) hatasıdır. Çağrıyı yapan taraf kubelet'e ulaşmış, kubelet ise API sunucusuna bu kimliğin alt kaynağı kullanıp kullanamayacağını sormuş ve olumsuz yanıt almıştır. Çağrıyı yapan tarafın ClusterRole ayarını düzeltin. Hiçbir şey engellenmediği için güvenlik duvarı değişikliği bir işe yaramayacaktır.
Yalnızca tek bir küçük küme istiyorsanız
İlk kez bir VPS üzerinde kubeadm kurulumu yaparken bu hatalarla karşılaşıyorsanız, kubeadm kullanmanın gerçekten gerekli olup olmadığını değerlendirin. VPS üzerinde tek düğümlü k3s kümesi, kubelet, kube-proxy ve CNI bileşenleri halihazırda yapılandırılmış şekilde, tek bir komutla çalışan bir Kubernetes API'si sağlar. 10250 numaralı port orada da mevcuttur ve aynı kurallar bu port için de geçerlidir; ancak kontrol düzlemini artık kendiniz bir araya getirmek zorunda kalmazsınız.
FAQ
Kubernetes'te 10250 numaralı port ne için kullanılır?
Bu port, kontrol düzlemi ve worker düğümleri dahil olmak üzere her düğümdeki kubelet'in kimlik doğrulamalı HTTPS API'sidir. API sunucusu kubectl logs, kubectl exec, kubectl attach ve kubectl port-forward işlemleri için bu porta bağlanır; metrics-server ise kubectl top verilerini sağlamak amacıyla /metrics/resource üzerinden veri çeker. Düğüm durumu bu portu kullanmaz; çünkü kubelet, heartbeat sinyalini 6443 numaralı port üzerinden API sunucusuna dışa doğru gönderir. 10250 numaralı portun engellenmesi durumunda düğümler Ready durumunda görünür, günlük kayıtları ve exec komutları ise başarısız olur.
10250 numaralı portta neyin dinleme yaptığını nasıl bulurum?
Düğüm üzerinde sudo ss -lntp | grep 10250 komutunu çalıştırın. Satırın sonundaki users:((...)) alanı, süreci ve PID numarasını belirtir. sudo kullanımı önemlidir; çünkü root yetkisi olmadan süreç sütunu boş görünür. Eğer sahibi kubelet ise, sudo systemctl status kubelet --no-pager komutu kubelet'in sağlıklı mı çalıştığını yoksa sürekli yeniden başlatma döngüsüne mi girdiğini gösterir. Eğer sahibi k3s ise, aynı sunucuda iki farklı Kubernetes dağıtımı yüklüdür ve birinin kaldırılması gerekir.
10250 numaralı portu güvenlik duvarımda açmam gerekir mi?
Evet, düğümleriniz arasında açmalısınız. Kontrol düzlemi, kendisi dahil her düğümdeki 10250 numaralı porta erişebilmelidir; aksi takdirde günlük kayıtları, exec, port-forward ve metrik işlemleri başarısız olur. Bu portu, düğümlerinizin paylaştığı ağ ile sınırlayın; örneğin sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp kuralını kullanın. İnternete kesinlikle açmayın: bu porta kimlik doğrulaması yapabilen herhangi bir kişi, düğüm üzerindeki herhangi bir container içinde süreç çalıştırabilir.
Neden sadece bir düğümdeki pod'lar için kubectl logs komutu başarısız oluyor?
Çünkü engelleme düğüm bazlıdır ve API sunucusu, pod'un barındırıldığı ilgili düğüme bağlanır. Hata metnini okuyun: hata, ulaşılmaya çalışılan düğümün IP adresini içerir. Ardından bir kontrol düzlemi düğümünden nc -zv <node-ip> 10250 komutunu çalıştırın. Zaman aşımı hatası, o düğümdeki güvenlik duvarına veya servis sağlayıcınızın ağ güvenlik duvarına işaret eder. connection refused hatası ise o düğümde çalışmayan bir kubelet'e işaret eder; bu durumda o düğümde systemctl status kubelet komutunu kontrol edin.