Khắc phục lỗi 'no IP addresses available' trong Kubernetes CNI

intermediate☸️ Kubernetes2026-07-26

Cuộc gọi Pager lúc 2 giờ sáng

Mọi thứ bắt đầu với một bản triển khai (deployment) thất bại. Bạn nhận thấy các pod của mình bị kẹt ở trạng thái ContainerCreating trong mười phút. Khi chạy lệnh kubectl describe pod, bạn sẽ thấy thông báo đáng sợ sau:

Events:
  Type     Reason                  Age                From               Message
  ----     ------                  ----               ----               -------
  Warning  FailedCreatePodSandBox  2m (x15 over 12m)  kubelet            Failed to create pod sandbox: rpc error: code = Unknown desc = failed to set up sandbox container network: no IP addresses available

CNI (Container Network Interface) của bạn đã hết địa chỉ IP. Nó không thể gán định danh mạng cho các pod mới. Điều này làm tê liệt cụm (cluster) của bạn, cho dù bạn đang chạy trên AWS EKS, Azure AKS hay thiết lập Calico trên bare-metal.

Tóm tắt: Các giải pháp khắc phục nhanh

  • AWS VPC CNI: Các subnet của bạn có khả năng đã đầy. Hãy kiểm tra VPC Console. Bạn có thể cần thêm một CIDR phụ hoặc giảm WARM_IP_TARGET nếu các node đang chiếm giữ quá nhiều IP.
  • Calico: IPPool của bạn đã đạt giới hạn. Hãy thêm một khối IPPool mới, lớn hơn ngay lập tức.
  • Azure CNI: Bạn đã chạm giới hạn IP được cấp phát trước trên mỗi node. Bạn thường phải triển khai lại node pool với một subnet rộng hơn để khắc phục điều này.
  • Ứng cứu khẩn cấp: Giảm quy mô (scale down) các bản triển khai không quan trọng. Xóa 20 bản sao (replica) của một ứng dụng môi trường dev thường có thể giúp bạn có đủ "không gian thở" để khắc phục sự cố mạng cốt lõi.

Bước 1: Xác định điểm nghẽn

Vấn đề chỉ nằm ở một node hay toàn bộ mạng?

Kiểm tra dung lượng của từng Node

Một node đơn lẻ có thể thất bại nếu nó chạm giới hạn phần cứng. Ví dụ, một instance AWS t3.medium chỉ hỗ trợ 3 ENI và 6 IP trên mỗi ENI. Nếu bạn cố gắng chạy 18 pod trên đó, bạn sẽ chạm trần giới hạn. Hãy kiểm tra log của CNI để xem liệu nó có đang gặp khó khăn trong việc cấp phát tài nguyên cục bộ hay không:

kubectl logs -n kube-system -l k8s-app=aws-node
# Dành cho người dùng Calico
kubectl logs -n kube-system -l k8s-app=calico-node

Kiểm tra tình trạng cạn kiệt trên toàn Subnet

Nếu mọi node trong cụm đều báo lỗi, có khả năng subnet VPC của bạn đã cạn kiệt. Một subnet /24 chỉ cung cấp 251 địa chỉ có thể sử dụng sau khi AWS hoặc Azure lấy phần của họ. Hãy kiểm tra phần VPC trong bảng điều khiển đám mây để xem số lượng "Available IP Address".

Bước 2: Áp dụng bản sửa lỗi

Kịch bản A: AWS VPC CNI (EKS)

EKS ánh xạ IP của pod trực tiếp từ các subnet VPC. Điều này giúp kết nối mạng nhanh nhưng tiêu tốn IP rất nhanh.

Cách sửa 1: Điều chỉnh WARM_IP_TARGETCNI duy trì một pool IP "ấm" (warm) sẵn sàng để pod khởi động nhanh. Nếu con số này quá cao, một node có thể dự trữ 10 IP ngay cả khi nó chỉ chạy 2 pod. Bạn có thể giảm giá trị này bằng cách chỉnh sửa DaemonSet aws-node:

kubectl set env daemonset aws-node -n kube-system WARM_IP_TARGET=3

Cách sửa 2: Thêm một CIDR phụNếu VPC của bạn thực sự hết không gian, hãy gắn một khối CIDR phụ (như 100.64.0.0/16) vào VPC. Sau đó, cấu hình CNI để sử dụng dải mạng mới này cho các pod thông qua Custom Networking.

Kịch bản B: Calico IPPools

Calico chia CIDR của nó thành các khối (thường là /26, cho phép 64 IP) và giao chúng cho các node. Nếu bạn có nhiều node nhỏ, bạn có thể hết các khối (block) ngay cả khi tổng số lượng IP trông vẫn ổn.

Kiểm tra mức độ sử dụng pool của bạn:

calicoctl get ippool -o wide

Nếu mức sử dụng gần 100%, hãy định nghĩa và áp dụng một IPPool mới với dải mạng lớn hơn:

apiVersion: projectcalico.org/v3
kind: IPPool
metadata:
  name: expansion-pool
spec:
  cidr: 192.168.64.0/18
  ipipMode: Always
  natOutgoing: true

Bước 3: Xác minh sự phục hồi

Sau khi mở rộng dải mạng, hãy theo dõi trạng thái của pod. Các lỗi FailedCreatePodSandBox sẽ biến mất khỏi nhật ký sự kiện (event log) của bạn.

# Theo dõi các pod đang chuyển từ Pending sang Running
kubectl get pods -A -w | grep -v Running

Xác nhận CNI thực sự đang hoạt động bằng cách theo dõi (tail) log để tìm các thông báo thành công:

kubectl logs -n kube-system [CNI_POD_NAME] | grep "Successfully assigned IP"

Mẹo chuyên nghiệp để phòng ngừa

Cạn kiệt IP thường chỉ là một lỗi tính toán. Trước khi khởi chạy một node group mới, hãy tính toán mật độ pod cao nhất của bạn. Đừng quên tính đến các bản cập nhật cuốn chiếu (rolling updates). Trong quá trình triển khai, bạn có thể tạm thời gấp đôi số lượng pod, yêu cầu gấp đôi số lượng IP.

Tôi thường sử dụng một công cụ tính toán subnet để hình dung xem một subnet /24 hoặc /22 thực sự có thể chứa bao nhiêu pod. Đừng quên trừ đi các IP của node và các địa chỉ dự phòng khỏi tổng số đó. Cá nhân tôi sử dụng Trình tính toán Subnet trên ToolCraft. Nó nhanh, hoạt động ngay trên trình duyệt và giữ kín dữ liệu mạng của bạn. Đây là một cách tuyệt vời để kiểm tra lại các phép tính CIDR trước khi áp dụng một IPPool mới.

Dọn dẹp các IP "Zombie"

Đôi khi, một node bị lỗi và CNI không giải phóng được IP của nó. Điều này tạo ra các cấp phát "zombie" chiếm dụng không gian. Việc khởi động lại các pod CNI thường sẽ kích hoạt quá trình đồng bộ lại (resync) để dọn dẹp các IP này:

kubectl rollout restart ds aws-node -n kube-system

Trên bare metal, hãy kiểm tra /var/lib/cni/networks/ trên node host. Bạn có thể tìm thấy các tệp cũ đại diện cho các lần cấp phát trước đó chưa được xóa.

Lời kết

Việc mở rộng dải IP của bạn giải quyết được sự cố sập mạng tức thời, nhưng đừng quên tường lửa của bạn. Hãy đảm bảo các Security Group hoặc tường lửa tại chỗ (on-prem) cho phép lưu lượng truy cập từ dải CIDR mới. Nếu bạn quên bước này, các pod của bạn sẽ khởi động được, nhưng chúng sẽ không thể giao tiếp với bất cứ thứ gì.

Related Error Notes