Checklist để nâng Cấp Kubernetes HA đỡ run

Hôm trước tôi nâng cụm Kubernetes nội bộ cho team. Cụm này chỉ chạy 3 control plane, VIP cho kube-apiserver, etcd stacked do kubeadm quản lý. Trước khi làm tôi thử rút điện một con control plane để xem kubectl có còn mượt không :))

Kết quả là có lúc chờ hơi lâu vì VIP không kịp chuyển và một apiserver đang lag. Tôi ngồi note lại thành một checklist để lần sau cho anh em trong team sẵn dùng, chia sẻ ai thấy cần thì tham khảo nhé.

Mục tiêu

  • Control plane 3 node chịu lỗi ổn. Mất một node, kubectl vẫn đáp và scheduler vẫn chạy.
  • TTFB kubectl p95 trong sự cố vẫn dưới 500 ms trong mạng nội bộ.
  • Quá trình leader failover của controller-managerscheduler diễn ra nhanh, cỡ 1 đến 2 giây.
  • Nâng cấp từ v1.30 lên v1.31 bằng bằng kubeadm theo kiểu rolling mà không cắt hơi thở cả cụm (trong on-prem architecture khá nhiều cụm chạy version cũ cũng nhiều lý do mà chưa upgrade).

Kiến trúc gọn để làm việc

3 servers Ubuntu 22.04:

  • 192.168.1.11 cp-1
  • 192.168.1.12 cp-2
  • 192.168.1.13 cp-3
  • VIP 192.168.1.10

Thành phần

  • etcd stacked trên mỗi control plane do kubeadm quản lý
  • kube-apiserver chạy cả 3
  • kube-controller-managerkube-scheduler chạy cả 3, dùng Lease để bầu leader
  • Lớp truy cập chọn một trong hai:
    • Keepalived giữ VIP, HAProxy TCP 6443 cân bằng vào 3 apiserver
    • Hoặc kube-vip chạy static pod, announce VIP trực tiếp

Chuẩn bị hệ thống

Tắt swap và bật sysctl cần thiết

sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab

cat <<EOF | sudo tee /etc/modules-load.d/k8s.conf
br_netfilter
EOF

cat <<EOF | sudo tee /etc/sysctl.d/99-kubernetes.conf
net.bridge.bridge-nf-call-iptables=1
net.ipv4.ip_forward=1
net.bridge.bridge-nf-call-ip6tables=1
EOF

sudo sysctl --system

Cài containerd và bộ kube

sudo apt-get update && sudo apt-get install -y containerd
sudo mkdir -p /etc/containerd
containerd config default | sudo tee /etc/containerd/config.toml >/dev/null
sudo systemctl enable --now containerd

sudo apt-get install -y apt-transport-https ca-certificates curl
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.30/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo "deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.30/deb/ /" | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubeadm=1.30.0-1.1 kubelet=1.30.0-1.1 kubectl=1.30.0-1.1
sudo systemctl enable --now kubelet

Cấu hình VIP kiểu Keepalived + HAProxy

Keepalived

Keepalived vrrp đơn giản:

# /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
  state BACKUP
  interface ens160
  virtual_router_id 51
  priority 100
  advert_int 1
  authentication {
    auth_type PASS
    auth_pass 42secret
  }
  virtual_ipaddress {
    192.168.1.10/24
  }
}

HAProxy

HAProxy TCP 6443:

# /etc/haproxy/haproxy.cfg
global
  log /dev/log local0
defaults
  mode tcp
  timeout client 60s
  timeout server 60s
  timeout connect 5s
frontend fe_k8s
  bind 0.0.0.0:6443
  default_backend be_k8s
backend be_k8s
  option tcp-check
  tcp-check connect
  server cp1 192.168.1.11:6443 check
  server cp2 192.168.1.12:6443 check
  server cp3 192.168.1.13:6443 check

Nếu bạn muốn gọn hơn thì kube-vip cũng được. Nhược điểm khó tinh chỉnh health-check kiểu HAProxy.

Khởi tạo control plane bằng kubeadm

Cấu hình kubeadm

Config chuẩn có controlPlaneEndpoint trỏ về VIP.

cat <<EOF > kubeadm-config.yaml
apiVersion: kubeadm.k8s.io/v1beta4
kind: ClusterConfiguration
kubernetesVersion: v1.30.0
controlPlaneEndpoint: "192.168.1.10:6443"
networking:
  podSubnet: "10.244.0.0/16"
etcd:
  local:
    dataDir: /var/lib/etcd
apiServer:
  extraArgs:
    audit-log-maxage: "7"
    audit-log-maxbackup: "10"
    audit-log-maxsize: "100"
    audit-log-path: "/var/log/kubernetes/apiserver/audit.log"
---
apiVersion: kubeadm.k8s.io/v1beta4
kind: InitConfiguration
localAPIEndpoint:
  advertiseAddress: 192.168.1.11
  bindPort: 6443
nodeRegistration:
  criSocket: unix:///run/containerd/containerd.sock
EOF

Chạy lệnh

sudo kubeadm init --config kubeadm-config.yaml

Cài CNI và Join nodes

Cài CNI rồi join thêm hai control plane.

kubectl apply -f https://github.com/flannel-io/flannel/releases/latest/download/kube-flannel.yml

kubeadm token create --print-join-command

# Trên cp-2 và cp-3
sudo kubeadm join 192.168.1.10:6443 --token 
<token> --discovery-token-ca-cert-hash sha256:<hash> --control-plane

Observability và SLI bắt buộc cho control plane

Tối thiểu có kube-state-metrics, node-exporter, metrics-server hoặc Prometheus Operator. Bạn cần theo dõi:

  • kube-apiserver request duration p95 và p99
  • Lease leader election của controller-managerscheduler
  • etcd backend commit duration p95
  • admission webhooks error và saturation của apiserver

Các kịch bản Chaos Engineering để xác thực cụm HA

A. Tắt kube-apiserver ở cp-1

sudo crictl ps | grep kube-apiserver
sudo crictl stop 
<id_apiserver>

Quan sát VIP vẫn nghe 6443, kubectl get pods vẫn trả.

B. Thử nghiệm Node Failure

HAProxy còn 2 backend, workload vẫn chạy. Bạn xem leader của controller-manager có chuyển nhanh không.

C. Thử nghiệm với Latency vàPacket Loss

sudo tc qdisc add dev ens160 root netem delay 200ms loss 20%
sleep 60
sudo tc qdisc del dev ens160 root netem

Bạn đo p95 request apiserver. Lý tưởng vẫn dưới 500 ms.

D. Dừng etcd trên một node

sudo systemctl stop etcd

Xem quorum còn 2 thành viên. API vẫn sống.

Quy trình nâng cấp control plane ít gián đoạn bằng kubeadm

Nguyên tắc

  • Nâng từng control plane một. Luôn giữ tối thiểu 2 node hoạt động.
  • Không cần drain control plane. Cordon là đủ.
  • Thứ tự hay dùng là cp-2, cp-3, cuối cùng cp-1.

Các bước trên mỗi control plane đích

  1. Nâng kubeadm trước

    sudo apt-get install -y kubeadm=1.31.0-1.1
    sudo kubeadm upgrade plan
    sudo kubeadm upgrade apply v1.31.0
  2. Nâng kubeletkubectl

    sudo apt-get install -y kubelet=1.31.0-1.1 kubectl=1.31.0-1.1
    sudo systemctl daemon-reload
    sudo systemctl restart kubelet
  3. Kiểm tra health

    kubectl get nodes
    kubectl get --raw /readyz?verbose

Lặp lại node tiếp theo. Xong hết thì nâng cp-1.

Upgrade worker để đồng bộ

Làm rolling từng worker. Respect PodDisruptionBudget. Câu lệnh kubeadm node phase upgrade và nâng kubelet tương tự control plane.

Những pha dễ vấp và cách gỡ

  • VIP không chịu failover vì VRRP bị chặn. Kiểm tra firewall, nếu cần dùng unicast VRRP.
  • Certificate apiserver sai khiến HAProxy check pass nhưng kubectl lỗi. Để kubeadm quản lý PKI trong /etc/kubernetes/pki, đừng chỉnh tay.
  • Skew version lệch quá 1 minor. Hạ nhiệt, đi từng nấc như tài liệu kubeadm khuyến nghị.
  • etcd phình to và chậm. Theo dõi backend size, defrag định kỳ.
    ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 \
      --cacert=/etc/kubernetes/pki/etcd/ca.crt \
      --cert=/etc/kubernetes/pki/etcd/server.crt \
      --key=/etc/kubernetes/pki/etcd/server.key defrag

Bảo mật tối thiểu nên enable

  • Audit log cho apiserver như config ở trên
  • RBAC đúng role. Nếu có IdP thì dùng OIDC
  • Admission policy chặn image tag latest, có thể kèm Cosign verify nếu bạn làm supply chain
  • Gia hạn certificate tự động bằng kubeadm certificates renew. Có cron check hạn trước 30 ngày

Checklist

  • Dashboard RED cho apiserver và SLO p95 request
  • Thử nghiệm rút một apiserver hàng tháng để tự tin khi có sự cố
  • etcd snapshot hàng giờ lên object storage và thử restore mỗi quý
  • Kế hoạch upgrade có thời lượng rõ ràng và một lối quay đầu về gói kube

Rollback nhanh khi gặp xui

  • Một control plane nâng xong mà apiserver không lên. Cài lại gói kubeadmkubelet phiên cũ, kiểm chứng PKI, restart kubelet.
  • Nhiều control plane dính lỗi cùng lúc. Hãy giữ VIP ở con còn hoạt động bằng priority cao hơn trong keepalived. Sửa từng máy một.

Thế là hết rồi đấy

Nếu có update thêm gì tôi sẽ cập nhật. Còn cơ bản thì là như vậy đó, tôi thấy mấu chốt là khả năng failover của VIP phải hiệu quả, luôn có ít nhất hai instance apiserver hoạt động, etcd duy trì được quorum, và việc nâng cấp phải theo từng staged, đồng thời được giám sát chặt chẽ qua metrics. Bạn có thể bắt đầu bằng việc dựng đủ ba node, bật metric, chạy các kịch bản giả lập sự cố đã nêu. Sau đó, khi thực hiện nâng cấp thật, bạn sẽ tự tin hơn rất nhiều.

Thông tin nổi bật

Báo cáo quan trọng

Sự kiện đang hiện hành

Chia sẻ bài viết:
Theo dõi
Thông báo của
0 Góp ý
Được bỏ phiếu nhiều nhất
Mới nhất Cũ nhất
Phản hồi nội tuyến
Xem tất cả bình luận