Control Plane Upgrade Window: Giám Sát Và Rollback Trigger
Tại sao cửa sổ nâng cấp control plane cần được xử lý khác node pool
Control plane là nơi duy nhất trong cluster mà một lỗi upgrade có thể khiến bạn mất khả năng vận hành cluster — không phải mất workload, mà mất khả năng gọi API để sửa bất cứ thứ gì. Đây là lý do control plane luôn được nâng cấp trước node pool (không thể đảo ngược thứ tự — version skew policy không cho phép node mới hơn control plane), và đây cũng là lý do runbook cần một mục riêng cho cửa sổ nâng cấp control plane: rủi ro ở đây không phải "capacity bị giảm" như node pool, mà là "API server không phản hồi", điều này ảnh hưởng ngay tới khả năng chẩn đoán và can thiệp của chính bạn khi có vấn đề.
Internal model: vì sao zonal cluster mất availability nhưng regional cluster không
Zonal cluster: một control plane, một điểm dừng duy nhất
Zonal cluster chạy đúng một instance control plane. Khi upgrade, instance đó phải dừng, cập nhật binary, và khởi động lại:
"Zonal clusters have a single control plane that becomes unavailable during upgrades, preventing new deployments or configuration changes" (Standard cluster upgrades).
Cần hiểu đúng phạm vi ảnh hưởng: workload đang chạy trên node không bị dừng — kube-apiserver không phải là data plane, Pod vẫn tiếp tục xử lý traffic bình thường vì traffic đi qua Service/Load Balancer, không đi qua control plane. Thứ bị mất là khả năng thay đổi trạng thái cluster: không kubectl apply, không tạo Pod mới, không HPA scale (vì HPA controller cũng cần gọi API server), không readiness probe update trạng thái Endpoints mới. Với cluster chạy CI/CD liên tục hoặc autoscaling nhạy traffic, khoảng downtime API server này — dù ngắn — vẫn là một cửa sổ rủi ro thật.
Regional cluster: multi-replica, nhưng "rolling" theo nghĩa không xác định thứ tự
Regional cluster chạy nhiều replica control plane (thường 3, mỗi replica ở một zone khác nhau trong region). Khi upgrade, GKE cập nhật từng replica một, giữ các replica còn lại phục vụ request:
"Regional clusters maintain high availability by upgrading one control plane replica at a time in undefined order" (Standard cluster upgrades).
Từ khoá quan trọng cần chú ý là "undefined order" — bạn không có quyền (và không nên giả định) kiểm soát replica nào được upgrade trước. Điều này có hệ quả trực tiếp lên thiết kế giám sát: bạn không thể theo dõi "replica A rồi B rồi C" theo một lịch trình cố định; thứ bạn giám sát được là trạng thái tổng hợp của API endpoint (thường đứng sau một internal load balancer phân phối request tới replica còn healthy), không phải trạng thái từng replica riêng lẻ. Trong lúc một replica đang upgrade, hai replica còn lại tiếp tục xử lý toàn bộ request — về lý thuyết availability được giữ, nhưng capacity xử lý API giảm tạm thời 1/3, điều này có thể lộ ra dưới dạng tăng latency ở các client gọi API tần suất cao (ví dụ controller reconcile loop dày đặc) trong lúc control plane đang upgrade.
etcd và trạng thái: tại sao downtime control plane không đồng nghĩa mất dữ liệu
Một hiểu lầm cần loại bỏ: upgrade control plane không "xoá" hay "reset" etcd. etcd là một cluster đồng thuận (Raft) chạy độc lập bên dưới kube-apiserver; khi kube-apiserver của một replica restart để nhận binary mới, etcd member tương ứng (nếu co-located, như thường thấy trong kiến trúc GKE) vẫn giữ trạng thái đã persist trên disk. Đây là lý do downtime control plane luôn là vấn đề availability, không phải vấn đề durability — dữ liệu cluster state (object, RBAC, Secret, v.v.) không biến mất khi control plane tạm ngừng phản hồi.
Ràng buộc không-nhảy-cóc: lý do thật đằng sau, không chỉ là quy định
Đã đề cập ở phần trước rằng bạn không thể upgrade control plane từ 1.31 thẳng lên 1.33. Lý do kỹ thuật: mỗi minor version Kubernetes chỉ đảm bảo tương thích ngược với đúng một minor version liền trước cho các cơ chế nội bộ nhạy cảm nhất — định dạng lưu trữ etcd, giao thức giữa API server và các control plane component khác, và feature gate transition. Nhảy 2 minor version cùng lúc đồng nghĩa bỏ qua một bước migration trung gian mà chính Kubernetes upstream không kiểm định là an toàn. Đây là lý do ràng buộc này là cứng ở tầng GKE API (gcloud container clusters upgrade sẽ từ chối yêu cầu nhảy cóc), không phải một khuyến nghị có thể bỏ qua bằng flag đặc biệt.
Two-step minor upgrade: cơ chế soak duration cho phép "thử trước khi commit"
Với minor version upgrade — vốn rủi ro cao hơn patch upgrade — GKE cung cấp một cơ chế preview cho phép tách upgrade thành hai giai đoạn tường minh:
gcloud beta container clusters upgrade CLUSTER_NAME \
--location=CONTROL_PLANE_LOCATION \
--cluster-version VERSION \
--control-plane-soak-duration SOAK_DURATION \
--masterCơ chế nội tại: GKE thực hiện "binary upgrade" (thay binary control plane) nhưng giữ lại khả năng rollback trong suốt khoảng SOAK_DURATION (6 giờ đến 7 ngày). Trong khoảng soak này, bạn có thể quan sát hành vi cluster ở version mới trước khi commit hoàn toàn — và nếu phát hiện vấn đề, rollback lại binary cũ. Đây là cơ chế rollback control plane duy nhất có ý nghĩa thực tế đối với minor version upgrade, và nó chỉ tồn tại trong khoảng soak — sau khi soak kết thúc và upgrade được "complete", cửa sổ rollback này đóng lại vĩnh viễn (chi tiết đầy đủ về rollback được xử lý ở file 07).
Maintenance window: cơ chế xác định "khi nào" GKE được phép chạm vào control plane
Window vs exclusion: hai khái niệm bù trừ nhau
Maintenance window là khoảng thời gian lặp lại mà bạn cho phép GKE tự động thực hiện maintenance (bao gồm auto-upgrade); maintenance exclusion là khoảng thời gian không lặp lại mà bạn cấm GKE làm điều đó (ví dụ trong mùa bán hàng cao điểm). Mỗi cluster hỗ trợ một recurring window, nhưng nhiều exclusion đồng thời.
Ba scope của exclusion mang ý nghĩa kỹ thuật khác nhau, không chỉ khác "mức độ nghiêm khắc"
NO_UPGRADES(mặc định): chặn cả patch và minor upgrade cho cả control plane và node — tối đa 90 ngày, khuyến nghị dưới 30 ngày vì rủi ro bỏ lỡ patch bảo mật.NO_MINOR_UPGRADES: vẫn cho phép patch upgrade (bao gồm patch bảo mật) chạy qua, chỉ chặn minor upgrade — cho phép cấu hình dài hạn kèm theo dõi end-of-support.NO_MINOR_OR_NODE_UPGRADES: chặn minor upgrade và mọi upgrade node (kể cả patch), nhưng vẫn cho phép patch control plane chạy — dùng khi bạn tuyệt đối không muốn workload bị gián đoạn (drain node) nhưng vẫn muốn control plane nhận vá bảo mật.
Bài học kiến thức quan trọng: chọn sai scope là một trong những nguyên nhân phổ biến khiến team nghĩ rằng "mình đã chặn upgrade" trong khi thực chất chỉ chặn một phần. Một exclusion NO_MINOR_UPGRADES không ngăn patch security upgrade tự động chạm vào node — nếu bạn cần tuyệt đối không có node nào bị cordon/drain trong một khung giờ, bạn cần NO_MINOR_OR_NODE_UPGRADES, không phải scope mặc định.
Giới hạn số lượng và ràng buộc thời gian tối thiểu
GKE giới hạn cứng: tối đa 3 exclusion scope "no upgrades" mỗi cluster, tối đa 20 exclusion tổng cộng ở cấp cluster, và mỗi node pool (Standard) chỉ được một exclusion riêng. Quan trọng hơn, GKE bắt buộc phải có tối thiểu 48 giờ khả dụng cho maintenance trong mỗi cửa sổ rolling 92 ngày — bạn không thể chặn maintenance vô thời hạn bằng cách chồng exclusion liên tục; hệ thống sẽ từ chối cấu hình vi phạm ràng buộc này.
Override bắt buộc: khi nào GKE "phá" exclusion của bạn
Có những tình huống GKE reserve quyền vượt qua mọi exclusion đã cấu hình:
Các trường hợp override: lỗ hổng bảo mật nghiêm trọng, upgrade khẩn cấp không có kế hoạch, upgrade bắt buộc từ phần mềm đã deprecated, thao tác sửa control plane, và auto-upgrade khi hết hạn hỗ trợ (sau khi đã cho một khoảng hoãn tạm thời 90 ngày) (Maintenance windows and exclusions).
Điều này định hình lại cách hiểu đúng về maintenance exclusion: nó là công cụ điều phối lịch trình bình thường, không phải một "công tắc tắt vĩnh viễn" quyền kiểm soát vận hành của Google với cluster của bạn ở các tình huống khẩn cấp thật (ví dụ zero-day CVE ảnh hưởng hàng loạt cluster).
Constraints, trade-offs & failure modes
Constraint: manual upgrade bỏ qua toàn bộ maintenance window
Cần phân biệt rõ hai luồng: maintenance window/exclusion chỉ chi phối auto-upgrade do GKE tự khởi tạo. Nếu bạn chủ động chạy gcloud container clusters upgrade, lệnh này thực thi ngay lập tức, bất kể exclusion đang cấu hình gì. Đây là nguồn gốc của không ít incident "tự bắn vào chân" — một script CI/CD chạy cluster upgrade không kiểm tra biến môi trường/lịch trình, vô tình kích hoạt upgrade thủ công đúng vào giữa exclusion mà team đã cẩn thận đặt ra cho auto-upgrade.
Failure mode: theo dõi sai đối tượng khi regional cluster đang upgrade
Vì thứ tự upgrade giữa các control plane replica là "undefined", một sai lầm giám sát phổ biến là cố gắng SSH hoặc curl trực tiếp một địa chỉ IP replica cụ thể để "theo dõi tiến độ" — điều này không phản ánh đúng trạng thái tổng hợp mà client thực sự nhìn thấy (vốn đi qua load balancer trước các replica). Cách giám sát đúng là theo dõi operation ở tầng GKE API (gcloud container operations describe), không phải trạng thái hạ tầng bên dưới mà bạn không được thiết kế để truy cập trực tiếp.
Trade-off: soak duration dài hơn giảm rủi ro nhưng kéo dài toàn bộ chu kỳ upgrade
Two-step upgrade với soak 7 ngày cho bạn thời gian quan sát rất dài trước khi commit — nhưng đồng nghĩa cluster nằm ở trạng thái "nửa upgrade" (binary mới, chưa commit) trong suốt thời gian đó. Ở trạng thái này, một số hành vi vận hành khác (ví dụ auto-upgrade tiếp theo, một số thay đổi cấu hình cluster) có thể bị hạn chế cho tới khi soak kết thúc. Chọn soak duration là một quyết định đánh đổi rõ ràng giữa "thời gian bạn có để phát hiện vấn đề" và "thời gian cluster ở trạng thái transitional, ít linh hoạt hơn bình thường".
GCP-native implementation guidance
Kiểm tra maintenance window/exclusion hiện tại trước khi lên kế hoạch cửa sổ upgrade thủ công (tránh đè lên window tự động):
gcloud container clusters describe CLUSTER_NAME \
--location=LOCATION \
--format="yaml(maintenancePolicy)"Thực hiện upgrade control plane thủ công tới version cụ thể (tuân thủ ràng buộc một-minor-mỗi-lần):
gcloud container clusters upgrade CLUSTER_NAME --master \
--location=CONTROL_PLANE_LOCATION --cluster-version=VERSIONTheo dõi operation đang chạy — đây là cách giám sát đúng cho regional cluster, thay vì cố truy cập trực tiếp một replica:
gcloud container operations list --location=CONTROL_PLANE_LOCATION \
--filter="operationType=UPGRADE_MASTER"
gcloud container operations describe OPERATION_ID \
--location=CONTROL_PLANE_LOCATIONTruy vấn audit log để xác định chính xác thời điểm và kết quả của một lần auto-upgrade control plane trong quá khứ:
resource.type="k8s_cluster"
protoPayload.methodName="UpdateCluster"
protoPayload.metadata.operationType="UPGRADE_MASTER"