SSD Nodes Learn 🎉 VPS เริ่ม $5.50/เดือน
คู่มือ Matt Connorโดย Matt Connor · อัปเดตเมื่อ 2026-08-21

วิธีแก้ปัญหา Kubelet พอร์ต 10250 บน Ubuntu

แก้ไขปัญหาพอร์ต 10250 ถูกใช้งานอยู่ขณะรัน kubeadm init หรือปัญหา Firewall บล็อกการเชื่อมต่อที่ทำให้ kubectl logs และ exec ใช้งานไม่ได้ พร้อมวิธีตรวจสอบสถานะการทำงาน

พอร์ต 10250 คืออะไร

พอร์ต 10250 คือ kubelet API และทุกข้อผิดพลาดที่ระบุถึงพอร์ตนี้มักเกิดจากปัญหาตรงกันข้าม 2 ประการ ประการแรกคือมีบางอย่างใช้งานพอร์ตนี้อยู่แล้ว ทำให้ kubeadm init ไม่สามารถทำงานได้ หรือประการที่สองคือไม่มีสิ่งใดเข้าถึงพอร์ตนี้ได้ ทำให้ kubectl logs และ kubectl exec ล้มเหลวทั้งที่โหนดดูเหมือนจะทำงานได้ตามปกติ

kubelet คือเอเจนต์ที่ Kubernetes รันบนทุกโหนด ทำหน้าที่เริ่มคอนเทนเนอร์และรายงานสถานะกลับไปยัง control plane นอกจากนี้ยังฟังคำสั่งบน TCP 10250 และให้บริการ HTTPS API ที่ control plane เรียกใช้ API server จะเปิดการเชื่อมต่อมายังพอร์ตนี้เมื่อคุณรันคำสั่ง kubectl logs, kubectl exec, kubectl attach หรือ kubectl port-forward ส่วน metrics-server จะดึงข้อมูลจาก /metrics/resource บนพอร์ตเดียวกัน ซึ่งเป็นสิ่งที่ทำให้ kubectl top node ทำงานได้

API ดังกล่าวมีการตรวจสอบสิทธิ์ kubeadm จะปิดการเข้าถึงแบบ anonymous และชี้ kubelet ไปยัง CA (certificate authority) ของคลัสเตอร์ ดังนั้นคำขอที่ไม่มีข้อมูลรับรองจะได้รับคำตอบเป็น Unauthorized แทนที่จะเป็นการเข้าถึง shell ภายในคอนเทนเนอร์ของคุณ โปรดจำรายละเอียดนี้ไว้ เพราะเป็นวิธีที่เร็วที่สุดในการพิสูจน์ว่าพอร์ตสามารถเข้าถึงได้ หากคุณยังใหม่กับเรื่องพอร์ต พอร์ตคืออะไรบน Linux จะครอบคลุมถึงรูปแบบที่คู่มือนี้ใช้เป็นพื้นฐาน

โหมดความล้มเหลวทั้งสองประการเกิดจากข้อกำหนดเดียว คือพอร์ต 10250 ต้องว่างก่อนที่ kubelet จะเริ่มทำงาน และต้องสามารถเข้าถึงได้จาก control plane เมื่อ kubelet เริ่มทำงานแล้ว

คุณกำลังประสบปัญหาใดในสองกรณีนี้

ให้รันคำสั่งเหล่านี้บนโหนดที่มีปัญหา ทุกคำสั่งด้านล่างนี้เป็นคำสั่งที่คุณต้องรันด้วยตนเองบนเซิร์ฟเวอร์ของคุณ

sudo ss -lntp | grep 10250
sudo systemctl status kubelet --no-pager

ss -lntp ใช้สำหรับแสดงรายการ TCP socket ที่กำลังเปิดรับการเชื่อมต่อพร้อมระบุ process ที่เกี่ยวข้อง -l หมายถึงสถานะการฟัง (listening) -n ใช้แสดงพอร์ตเป็นตัวเลข -t จำกัดการแสดงผลเฉพาะ TCP -p ใช้แสดง process ที่เป็นเจ้าของพอร์ต แฟล็กสุดท้ายนี้จำเป็นต้องใช้สิทธิ์ root หากไม่มีสิทธิ์ดังกล่าว คอลัมน์ process จะว่างเปล่าและคุณจะไม่ได้รับข้อมูลใดๆ

หากบรรทัดใดลงท้ายด้วย users:(("kubelet",pid=1043,fd=23)) แสดงว่า kubelet กำลังทำงานและถือครองพอร์ตนั้นอยู่ หากคุณคาดหวังว่าพอร์ตควรจะว่าง นั่นคือคำตอบของปัญหา แต่หาก ss ไม่แสดงผลลัพธ์ใดๆ เลยในขณะที่ control plane ยังไม่สามารถเข้าถึงโหนดนี้ได้ แสดงว่ายังไม่มีปัญหาเรื่อง firewall เพราะไม่มีบริการใดเปิดพอร์ตใช้งานอยู่ตั้งแต่แรก คุณควรตรวจสอบสาเหตุที่ kubelet ไม่ทำงานก่อนที่จะไปแก้ไขกฎ firewall ใดๆ

systemctl status kubelet ให้ข้อมูลอีกด้านหนึ่งของสถานการณ์ active (running) ที่แสดงเวลาเริ่มต้นเมื่อไม่กี่นาทีก่อนถือเป็นเรื่องปกติ การที่ kubelet รีสตาร์ททุกๆ สองสามวินาที ก่อน ที่คุณจะรัน kubeadm init หรือ kubeadm join ก็ถือเป็นเรื่องปกติเช่นกัน เนื่องจาก unit ที่ติดตั้งมาจะเริ่มทำงานทันทีหลังติดตั้ง แต่เมื่อไม่พบไฟล์ config จึงหยุดทำงานไป เอกสารของ upstream ระบุว่าการวนลูปแบบ crash loop นี้เป็นพฤติกรรมที่คาดการณ์ได้ในขณะที่ kubelet รอให้ kubeadm มากำหนดค่าการทำงาน หากคุณยังไม่คุ้นเคยกับพฤติกรรมการรีสตาร์ทของ systemd คุณสามารถศึกษา วิธีการทำงานของ service types และ restart policies ใน systemd เพื่อเป็นพื้นฐานสำหรับส่วนนี้

เหตุใดพอร์ต 10250 จึงถูกใช้งานอยู่เมื่อรัน kubeadm init

kubeadm init จะดำเนินการตรวจสอบสถานะเบื้องต้น (preflight checks) ก่อนที่จะเขียนข้อมูลใดๆ ลงบนดิสก์ หนึ่งในการตรวจสอบเหล่านั้นคือการพยายาม bind พอร์ตทุกพอร์ตที่ control plane จำเป็นต้องใช้ และระบบจะหยุดทำงานพร้อมแสดงข้อผิดพลาดระบุถึงพอร์ต 10250 หากการ bind ล้มเหลว นี่ไม่ใช่ข้อผิดพลาดของซอฟต์แวร์ (bug) แต่เป็นกลไกของ kubeadm ที่ปฏิเสธการสร้างคลัสเตอร์ที่สองทับซ้อนบนสิ่งที่หลงเหลือจากคลัสเตอร์แรก

ในทางปฏิบัติ มี 4 สาเหตุที่ทำให้เกิดปัญหานี้:

  • การรัน kubeadm init หรือ kubeadm join ก่อนหน้านี้แล้วล้มเหลวระหว่างทาง ทำให้ kubelet ได้รับการตั้งค่าและทำงานอยู่ จึงยังคงถือครองพอร์ตดังกล่าวไว้
  • การรัน kubeadm reset ที่เริ่มต้นขึ้นแต่ยังไม่เสร็จสมบูรณ์ คำสั่ง reset จะหยุดการทำงานของ kubelet แต่ไม่ได้ปิดการใช้งาน unit ดังนั้นเมื่อรีบูตเครื่องใหม่ ตัว listener จะกลับมาทำงานอีกครั้ง
  • มี k3s หรือ Kubernetes distribution อื่นติดตั้งอยู่บนเซิร์ฟเวอร์เดียวกัน k3s มีการฝัง kubelet มาด้วย และ kubelet นั้นก็ทำการ bind พอร์ต 10250 เช่นกัน
  • แพ็กเกจ kubelet ถูกดึงเข้ามาโดย apt และเริ่มทำงานโดย systemd unit ของตัวมันเอง บนเครื่องที่คุณยังไม่ได้รัน kubeadm

ให้ตรวจสอบหาสาเหตุที่แท้จริงก่อนทำการเปลี่ยนแปลงใดๆ:

sudo ss -lntp 'sport = :10250'
systemctl list-units --type=service --state=running | grep -Ei 'kubelet|k3s|k0s'

หาก listener ดังกล่าวเป็นของ k3s ให้หยุดและตัดสินใจว่าคุณต้องการใช้คลัสเตอร์ใดกันแน่ k3s และ kubeadm ไม่สามารถใช้งานบนเซิร์ฟเวอร์เดียวกันได้ เนื่องจากทั้งคู่ต้องการใช้พอร์ตเดียวกันและไดเรกทอรี CNI (container network interface) เดียวกัน ตัวติดตั้ง k3s จะทิ้งสคริปต์ถอนการติดตั้งไว้ที่ /usr/local/bin/k3s-uninstall.sh บนโหนดที่เป็น server และที่ k3s-agent-uninstall.sh บนโหนดที่เป็น agent

เหตุใดการ kill kubelet จึงไม่ทำให้พอร์ตว่างลง

sudo pkill kubelet จะทำให้พอร์ต 10250 ว่างลงเป็นเวลาประมาณสิบวินาที เนื่องจาก unit ที่ติดตั้งมาพร้อมกับแพ็กเกจมีการกำหนดนโยบายการรีสตาร์ทไว้ systemd จึงเริ่มการทำงานของ kubelet ใหม่และผูกพอร์ตเดิมอีกครั้ง คุณสามารถตรวจสอบนโยบายดังกล่าวได้ด้วยตนเอง:

systemctl show kubelet -p Restart -p RestartSec
sudo systemctl stop kubelet
sudo ss -lntp | grep 10250

Restart=always ร่วมกับ RestartSec=10 คือสิ่งที่มาพร้อมกับ unit ซึ่งเป็นเหตุผลว่าทำไม kill จึงดูเหมือนว่าได้ผลในตอนแรกแต่กลับไม่เป็นเช่นนั้น systemctl stop เป็นวิธีที่ถูกต้องในการทำให้พอร์ตว่างลง เพราะ systemd จะหยุดรีสตาร์ท unit ที่คุณสั่งให้หยุดทำงาน

การทำให้พอร์ตว่างลงยังไม่เพียงพอสำหรับโหนดที่แบกรับภาระงานของคลัสเตอร์ไว้ครึ่งหนึ่ง /var/lib/kubelet/config.yaml, ใบรับรองภายใต้ /etc/kubernetes/pki และไฟล์ static pod manifest ใดๆ ใน /etc/kubernetes/manifests ยังคงอยู่ที่เดิม การตรวจสอบ preflight ในภายหลังจะติดขัดกับไฟล์เหล่านี้ และการฝืนข้ามขั้นตอนการตรวจสอบจะทำให้คุณได้คลัสเตอร์ที่มีใบรับรองไม่ตรงกับค่าคอนฟิก ให้รีเซ็ตโหนดอย่างถูกวิธีแทน

การรีเซ็ตโหนดอย่างหมดจด

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 จะข้ามการยืนยันจากผู้ใช้ การรีเซ็ตจะพยายามย้อนกลับสิ่งที่ init หรือ join ได้ทำไว้ให้ได้มากที่สุด โดยจะลบไฟล์และค่าคอนฟิกูเรชันในเครื่อง ลบสมาชิก etcd ในเครื่องบนโหนด control plane ทำความสะอาดใบรับรองใน /etc/kubernetes/pki และลบคอนฟิกูเรชันรวมถึงไฟล์ manifest ของ kubelet

เอกสารระบุไว้อย่างชัดเจนว่าการรีเซ็ตจะทิ้งสิ่งใดไว้บ้าง และแต่ละรายการมักเป็นจุดที่ทำให้ผู้ใช้งานเกิดปัญหา โดยการรีเซ็ตจะไม่ลบ /etc/cni/net.d ทำให้คอนฟิกูเรชันของ CNI plugin เดิมยังคงอยู่และคลัสเตอร์ใหม่ของคุณจะอ่านค่าเหล่านั้น นอกจากนี้ยังไม่ลบกฎ iptables, nftables หรือ IPVS ที่ kube-proxy ได้เพิ่มไว้ในโฮสต์ และไม่แตะต้อง $HOME/.kube ส่งผลให้ kubectl ยังคงพยายามติดต่อกับคลัสเตอร์ที่ไม่มีอยู่แล้ว และแสดงข้อผิดพลาดเกี่ยวกับใบรับรองซึ่งดูเหมือนเป็นปัญหาใหม่

กฎของแพ็กเก็ตที่ตกค้างอยู่เป็นส่วนที่จัดการได้ยาก การล้างตารางด้วยตนเองจะลบกฎที่ ufw ติดตั้งไว้ด้วย เนื่องจาก ufw บน Ubuntu เขียนกฎผ่านแบ็กเอนด์เดียวกัน ซึ่งจะทำให้เซิร์ฟเวอร์ไม่มีการกรองทราฟฟิกจนกว่าคุณจะรัน sudo ufw reload สำหรับโหนดที่คุณกำลังสร้างใหม่ ให้ทำการรีบูตหลังจากรีเซ็ต การรีบูตจะล้างกฎรันไทม์ที่ kube-proxy เพิ่มไว้และใช้เวลาน้อยกว่าการมานั่งแยกแยะชุดกฎที่ถูกล้างไปเพียงครึ่งเดียว เหตุใดกฎ iptables และกฎ nftables จึงปรากฏในผลลัพธ์ของกันและกัน อธิบายถึงสิ่งที่เกิดขึ้นเบื้องหลัง

คำสั่ง ss สุดท้ายควรแสดงผลลัพธ์ว่างเปล่า หากไม่มีการเปิดพอร์ต 10250, 6443 หรือ 2379 แสดงว่าโหนดพร้อมสำหรับการทำ kubeadm init ใหม่แล้ว

เหตุใด kubectl logs และ kubectl exec จึงหมดเวลาที่พอร์ต 10250

นี่เป็นปัญหาในทางตรงกันข้ามและไม่ได้แจ้งเตือนว่าเป็นปัญหาที่พอร์ตโดยตรง คลัสเตอร์ทำงานได้ปกติ โหนดมีสถานะเป็น Ready พอดทำงานได้ แต่กลับมีคำสั่งหนึ่งที่ล้มเหลว:

Error from server: Get "https://10.0.0.12:10250/containerLogs/default/web-0/web": dial tcp 10.0.0.12:10250: i/o timeout

ให้อ่านข้อความนั้นจากส่วนท้าย API server พยายามเปิดการเชื่อมต่อ TCP ไปยังโหนดที่พอร์ต 10250 แต่ไม่ได้รับการตอบกลับ i/o timeout หมายความว่าแพ็กเก็ตถูกทิ้งโดยไม่มีการตอบสนอง ซึ่งแสดงว่ามีบางอย่างคัดกรองแพ็กเก็ตเหล่านั้นอยู่ ไม่ว่าจะเป็น host firewall บนโหนด หรือ network firewall แยกต่างหากของผู้ให้บริการในแผงควบคุม ส่วน connect: connection refused ในตำแหน่งเดียวกันหมายถึงสิ่งตรงกันข้าม คือแพ็กเก็ตส่งไปถึงแล้วแต่ไม่มีบริการใดรอรับอยู่ แสดงว่า kubelet หยุดทำงาน ซึ่งเป็นสาเหตุคู่เดียวกันกับที่อธิบายไว้ใน การปฏิเสธการเชื่อมต่อเทียบกับการหมดเวลาการเชื่อมต่อ ซึ่งสามารถอ่านได้ที่นี่ในพอร์ตอื่น

โหนดจะยังคงมีสถานะเป็น Ready ตลอดเหตุการณ์นี้ เนื่องจากสถานะของโหนดถูกส่งในทิศทางตรงกันข้าม kubelet จะเชื่อมต่อ ออก ไปยัง API server ที่พอร์ต 6443 เพื่อส่งสัญญาณ heartbeat ของตัวเอง ซึ่งไม่จำเป็นต้องมีการเชื่อมต่อขาเข้าที่พอร์ต 10250 ดังนั้นการบล็อกพอร์ต 10250 จึงทำให้คุณมีคลัสเตอร์ที่จัดตารางพอดได้ตามปกติ แต่จะล้มเหลวเฉพาะการเรียกดู logs, exec, port-forward และ metrics เท่านั้น

kubectl top node ที่ตอบกลับ error: Metrics API not available คือความผิดพลาดเดียวกันที่พบผ่าน metrics-server ซึ่ง log จะระบุชื่อโหนดและพอร์ตไว้:

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 timeout

ทดสอบเส้นทางก่อนแก้ไขกฎ firewall ใดๆ

ให้รันคำสั่งนี้จากโหนด control plane โดยระบุที่อยู่ของ worker:

nc -zv 10.0.0.12 10250
curl -sk -o /dev/null -w '%{http_code}\n' https://10.0.0.12:10250/healthz

nc -z จะเปิดการเชื่อมต่อ ปิดการเชื่อมต่อ และแสดง succeeded! เมื่อพอร์ตยอมรับการเชื่อมต่อ คำสั่ง curl เป็นการทดสอบที่ดีกว่า เพราะเป็นการพิสูจน์ว่า kubelet กำลังทำงานอยู่จริง ไม่ใช่แค่พิสูจน์ว่าพอร์ตเปิดอยู่เท่านั้น คำสั่งนี้จะแสดง 401 ซึ่งเป็นผลลัพธ์ที่ปกติ: การทำ TLS (transport layer security) handshake เสร็จสมบูรณ์ จากนั้น kubelet ปฏิเสธคำขอที่ไม่มีการยืนยันตัวตน ซึ่งเป็นพฤติกรรมที่ถูกต้องแล้ว -k จะข้ามการตรวจสอบใบรับรอง ซึ่งทำได้เนื่องจากคุณกำลังทดสอบเส้นทาง ไม่ใช่ทดสอบห่วงโซ่ความเชื่อถือ (trust chain)

หากมีการหยุดชะงักนานจนจบด้วย timeout หมายความว่าแพ็กเก็ตถูกทิ้ง หาก curl: (7) Failed to connect ส่งผลลัพธ์กลับมาทันที หมายความว่าพอร์ตถูกปิดอยู่บนโฮสต์ที่เข้าถึงได้ ให้ทดสอบจากโหนด control plane เท่านั้น ไม่ใช่จากแล็ปท็อปของคุณ เนื่องจาก control plane เป็นเครื่องเดียวที่การเข้าถึงมีความสำคัญในกรณีนี้

พอร์ตที่จำเป็นสำหรับ control plane และ worker แต่ละตัว

นี่คือพอร์ตขาเข้าที่ระบุไว้ในเอกสารต้นทาง สำหรับโหนด control plane ต้องเปิดพอร์ต TCP 6443 สำหรับ API server เพื่อรองรับทุกสิ่งที่ทำงานด้วย kubectl, พอร์ต TCP 2379 ถึง 2380 สำหรับ etcd client และ peer API ซึ่งใช้งานโดย API server และตัว etcd เอง, พอร์ต TCP 10250 สำหรับ kubelet API ซึ่งใช้งานโดยตัวโหนดเองและ control plane, พอร์ต TCP 10259 สำหรับ kube-scheduler และพอร์ต TCP 10257 สำหรับ kube-controller-manager ซึ่งทั้งสองพอร์ตนี้ใช้งานโดยตัวโหนดเองเท่านั้น

สำหรับโหนด worker ต้องเปิดพอร์ต TCP 10250 สำหรับ kubelet API ซึ่งใช้งานโดยตัวโหนดเองและ control plane, พอร์ต TCP 10256 สำหรับ kube-proxy ซึ่งใช้งานโดยตัวโหนดเองและ load balancer ที่ทำ health check, และพอร์ต TCP กับ UDP ช่วง 30000 ถึง 32767 สำหรับบริการประเภท NodePort ซึ่งเป็นช่วงพอร์ตเริ่มต้นและต้องสามารถเข้าถึงได้จากผู้ที่ต้องการใช้งานบริการเหล่านั้น

ปลั๊กอิน CNI ของคุณจะมีพอร์ตเพิ่มเติมจากรายการนี้ ซึ่งไม่ได้รวมอยู่ในรายการข้างต้น โดย Flannel และ Calico ในโหมด VXLAN จำเป็นต้องใช้พอร์ต UDP 4789 ระหว่างโหนด ส่วน Calico ที่ใช้ BGP จำเป็นต้องใช้พอร์ต TCP 179 โปรดตรวจสอบเอกสารประกอบของปลั๊กอินที่คุณใช้งานและเปิดพอร์ตเหล่านั้นระหว่างโหนด มิฉะนั้น pod ที่อยู่บนโหนดต่างกันจะไม่สามารถสื่อสารกันได้ แม้ว่าจะเปิดพอร์ตทั้งหมดที่ระบุในส่วนนี้แล้วก็ตาม

เปิดพอร์ต 10250 โดยไม่ให้เข้าถึงได้จากอินเทอร์เน็ต

kubelet API สามารถเริ่มกระบวนการทำงานภายใน container ใดก็ได้บนโหนดนั้น ให้ถือว่าการเปิดพอร์ต 10250 เทียบเท่ากับการเข้าถึงโหนดในฐานะ root และจำกัดการเข้าถึงด้วย source address ห้ามอนุญาตให้เข้าถึงจากทุกแหล่งโดยเด็ดขาด

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 numbered

แทนที่ 10.0.0.0/24 ด้วยเครือข่ายที่โหนดของคุณใช้งานร่วมกัน ufw status numbered จะแสดงรายการกฎที่ใช้งานอยู่พร้อมดัชนี เพื่อให้คุณสามารถลบกฎที่ผิดพลาดออกได้ด้วย sudo ufw delete <number> บทความ พื้นฐานการใช้งาน ufw สำหรับ VPS ครอบคลุมถึงการจัดลำดับกฎซึ่งเป็นตัวกำหนดว่ารายการใดของคุณจะมีผลบังคับใช้จริง

การตั้งค่า ufw เพียงอย่างเดียวอาจทำให้ Kubernetes ทำงานไม่ได้ เนื่องจาก traffic ของ Pod ที่ข้ามโหนดจะถูกส่งต่อ (forward) ไม่ได้ถูกส่งไปยังปลายทางในเครื่อง และโดยปกติแล้ว ufw จะทิ้ง (drop) แพ็กเก็ตที่ถูกส่งต่อเหล่านี้ ให้ตั้งค่า DEFAULT_FORWARD_POLICY="ACCEPT" ในไฟล์ /etc/default/ufw แล้วรันคำสั่ง sudo ufw reload หากไม่ดำเนินการดังกล่าว แม้พอร์ต 10250 จะเปิดกว้าง แต่การสื่อสารระหว่าง Pod ที่อยู่คนละโหนดก็ยังคงล้มเหลว

ตรวจสอบ firewall ของผู้ให้บริการของคุณด้วย แผงควบคุม VPS ส่วนใหญ่จะมี firewall ระดับเครือข่ายที่วางอยู่หน้าเซิร์ฟเวอร์ ซึ่งมองไม่เห็นผ่าน ufw status กฎที่คุณเพิ่มบนโหนดจะไม่มีผลใดๆ หากแพ็กเก็ตไม่เคยเดินทางมาถึงตัวเครื่อง

เมื่อพอร์ตสามารถเชื่อมต่อได้แต่คำขอยังคงล้มเหลว

ความล้มเหลวที่พอร์ต 10250 บางกรณีจะตอบกลับทันทีแทนที่จะค้าง ซึ่งบ่งบอกว่าการเชื่อมต่อสำเร็จแต่คำขอถูกปฏิเสธ ข้อความ x509: certificate signed by unknown authority ใน log ของ metrics-server หมายความว่า kubelet กำลังให้บริการด้วย self-signed certificate ซึ่งตัว scraper ไม่เชื่อถือ วิธีแก้ไขทั่วไปคือการเปิดใช้งาน kubelet serving certificate rotation เพื่อให้ cluster CA ทำการลงนาม แล้วจึงอนุมัติ certificate signing request หรือหากเป็น lab cluster ที่ยอมรับความเสี่ยงได้ ให้รัน metrics-server ด้วยแฟล็ก --kubelet-insecure-tls

ข้อความที่มี Forbidden ร่วมกับ nodes/proxy หรือ nodes/metrics คือความล้มเหลวของ RBAC (role based access control) ผู้เรียกสามารถเข้าถึง kubelet ได้แล้ว แต่ kubelet ได้สอบถามไปยัง API server ว่า identity ดังกล่าวมีสิทธิ์ใช้ subresource นั้นหรือไม่ และได้รับคำตอบว่าไม่มีสิทธิ์ ให้แก้ไข ClusterRole ของผู้เรียก การปรับเปลี่ยน firewall จะไม่ช่วยแก้ปัญหานี้เนื่องจากไม่มีการบล็อกการเชื่อมต่อเกิดขึ้น

หากคุณต้องการเพียงคลัสเตอร์ขนาดเล็กหนึ่งชุด

หากคุณพบข้อผิดพลาดเหล่านี้ในขณะที่กำลังติดตั้ง kubeadm บน VPS เพียงเครื่องเดียวเป็นครั้งแรก ให้พิจารณาว่าคุณจำเป็นต้องใช้ kubeadm จริงหรือไม่ คลัสเตอร์ k3s แบบโหนดเดียวบน VPS ช่วยให้คุณมี Kubernetes API ที่ใช้งานได้ด้วยคำสั่งเดียว โดยมีการตั้งค่า kubelet, kube-proxy และ CNI มาให้พร้อมสรรพ พอร์ต 10250 ยังคงมีอยู่และใช้กฎเดียวกัน แต่คุณไม่จำเป็นต้องประกอบ control plane ด้วยตนเองอีกต่อไป

FAQ

พอร์ต 10250 ใน Kubernetes ใช้ทำอะไร

เป็น HTTPS API ที่ผ่านการยืนยันตัวตนของ kubelet บนทุกโหนด ทั้งในส่วน control plane และ worker โดย API server จะเชื่อมต่อเข้ามาเพื่อทำ kubectl logs, kubectl exec, kubectl attach และ kubectl port-forward ส่วน metrics-server จะดึงข้อมูล /metrics/resource ผ่านพอร์ตนี้เพื่อส่งต่อให้ kubectl top สำหรับสถานะของโหนดนั้นไม่ได้ใช้พอร์ตนี้ เนื่องจาก kubelet จะส่ง heartbeat ออกไปยัง API server ผ่านพอร์ต 6443 ด้วยเหตุนี้หากพอร์ต 10250 ถูกบล็อก โหนดจะแสดงสถานะเป็น Ready ในขณะที่การดู log และการใช้คำสั่ง exec จะล้มเหลว

จะตรวจสอบได้อย่างไรว่ามีโปรเซสใดกำลังฟังพอร์ต 10250 อยู่

ให้รันคำสั่ง sudo ss -lntp | grep 10250 บนโหนดนั้น โดยฟิลด์ users:((...)) ที่ท้ายบรรทัดจะระบุชื่อโปรเซสและ PID ของมัน การใช้ sudo มีความสำคัญเนื่องจากหากไม่มีสิทธิ์ root คอลัมน์โปรเซสจะว่างเปล่า หากเจ้าของโปรเซสคือ kubelet ให้ใช้ sudo systemctl status kubelet --no-pager เพื่อดูว่า kubelet ทำงานปกติหรือกำลังรีสตาร์ทวนซ้ำ หากเจ้าของคือ k3s แสดงว่ามีการติดตั้ง Kubernetes สองชุดบนเซิร์ฟเวอร์เดียวกัน ซึ่งคุณจำเป็นต้องลบออกหนึ่งชุด

จำเป็นต้องเปิดพอร์ต 10250 ในไฟร์วอลล์หรือไม่

จำเป็น ต้องเปิดระหว่างโหนดของคุณ โดย control plane ต้องสามารถเข้าถึงพอร์ต 10250 ของทุกโหนดได้ รวมถึงโหนดของตัวเองด้วย มิฉะนั้นการดู log, การใช้ exec, port-forward และ metrics จะล้มเหลวทั้งหมด ให้จำกัดการเข้าถึงตามแหล่งที่มาเฉพาะเครือข่ายที่โหนดของคุณใช้งานร่วมกัน เช่น sudo ufw allow from 10.0.0.0/24 to any port 10250 proto tcp ห้ามเปิดพอร์ตนี้สู่สาธารณะเด็ดขาด เพราะผู้ใดก็ตามที่สามารถยืนยันตัวตนกับพอร์ตนี้ได้ จะสามารถรันโปรเซสใน container ใดก็ได้บนโหนดนั้น

ทำไม kubectl logs ถึงล้มเหลวเฉพาะกับ pod ที่อยู่บนโหนดเดียว

เนื่องจากการบล็อกเกิดขึ้นเป็นรายโหนด และ API server จะเชื่อมต่อไปยังโหนดที่โฮสต์ pod นั้นโดยเฉพาะ ให้ตรวจสอบข้อความแสดงข้อผิดพลาด ซึ่งจะมี IP address ของโหนดที่พยายามเชื่อมต่ออยู่ จากนั้นให้รันคำสั่ง nc -zv <node-ip> 10250 จากโหนดที่เป็น control plane หากเกิด timeout แสดงว่าเป็นปัญหาที่ไฟร์วอลล์บนโหนดนั้นหรือไฟร์วอลล์เครือข่ายของผู้ให้บริการ หากขึ้น connection refused แสดงว่า kubelet บนโหนดนั้นไม่ได้ทำงาน ให้ตรวจสอบด้วย systemctl status kubelet บนโหนดดังกล่าวแทน