Skip to main content

1. Introduction to Operator Fundamentals

Mục lục


1. Giới thiệu khóa học

Kubernetes đã cách mạng hóa cách chúng ta deploy và quản lý ứng dụng. Nhưng khi ứng dụng ngày càng phức tạp, nhiều tác vụ vận hành — như provisioning resource, quản lý upgrade, xử lý backup, và khôi phục sau sự cố — vẫn đòi hỏi công sức thủ công. Kubernetes Operators giải quyết vấn đề này bằng cách mở rộng Kubernetes với trí tuệ vận hành (operational intelligence) đặc thù cho từng ứng dụng, cho phép tự động hóa việc quản lý vòng đời phức tạp theo hướng cloud-native.

Khóa học Kubernetes Operators do Ahmed Elfakharany giảng dạy. Nội dung khóa học gồm các phần sau:

  • Operator Fundamentals — Kubernetes operator là gì, khác controller ra sao, operator pattern, và khi nào operator là lựa chọn đúng thay vì các phương án khác như Helm.
  • Custom Resource Definitions Deep Dive
  • Kubebuilder Scaffolding — học cách định nghĩa custom API và scaffold operator project bằng Kubebuilder.
  • Building the Web App Operator — Core Reconcile — xây dựng logic reconciliation cốt lõi cho một web app operator kiểu production, quản lý deployments, services, config maps, và owner references.
  • Running, Testing, Debugging Locally, Status Conditions, Events, Finalizers and Cleanup, và Validation Webhooks and CEL Policies — học cách test, debug, validate, monitor, và quản lý an toàn vòng đời của operator.
  • Packaging and Distribution, Alternative Approaches — Operator SDK, Helm Operator, và tiêu thụ (consume) các operator phổ biến, ví dụ Cert Manager và Prometheus Operator.
  • Production Readiness, Testing, and Wrap-up — review lại những gì đã xây dựng và bàn về các điểm cần lưu ý khi đưa một operator từ development lên production.

Xuyên suốt khóa học, học viên sẽ xây dựng một web app operator hoàn chỉnh từ đầu, kèm nhiều hands-on lab, demo hướng dẫn, và bài tập thực hành để áp dụng từng khái niệm.

Sau khi hoàn thành khóa học, học viên sẽ có đủ kiến thức và kinh nghiệm thực hành để thiết kế, xây dựng, test, đóng gói, và deploy Kubernetes operators trong các ứng dụng thực tế, theo đúng best practice của ngành.


2. Vấn đề mà Operator giải quyết

Hình dung tình huống này: bạn muốn cho team một cách đơn giản để chạy một ứng dụng trên Kubernetes. Không phải một thư mục đầy YAML mà họ phải hiểu, chỉnh sửa, và trông chừng liên tục. Chỉ là một yêu cầu nhỏ: đây là image của app tôi, và đây là số lượng bản copy tôi cần.

Nghe có vẻ đơn giản. Thoạt nhìn, một Helm chart hay một customized overlay cũng có thể làm được việc này. Đúng là những công cụ đó hữu ích — chúng giúp tạo ra Kubernetes manifest. Nhưng operator nhắm tới một vấn đề khác. Câu hỏi quan trọng không chỉ là "có tạo được các object ban đầu không?" mà câu hỏi lớn hơn là: ai sẽ tiếp tục trông chừng ứng dụng sau khi nó đã chạy?

Để cụ thể hóa các khái niệm này, khóa học sẽ xây dựng một công cụ riêng: WebApp Operator. Custom resource được giữ cố tình đơn giản — chỉ yêu cầu 2 field từ người dùng: imagereplica count. Ngay khi developer apply object đơn giản đó, controller sẽ bắt tay vào việc: tự động tạo, kết nối, và quản lý toàn bộ stack cho họ — một Deployment để chạy các container ứng dụng, một Service để route network traffic tới các container đó, và một ConfigMap để lưu các biến môi trường của ứng dụng. Nó giữ cho tất cả luôn đồng bộ hoàn hảo. Nếu một kỹ sư mệt mỏi lỡ tay xóa deployment lúc 2 giờ sáng, operator sẽ phát hiện sai sót đó ngay ở vòng lặp kế tiếp và tự động tạo lại nó.

💡 Hình dung: cách operator hoạt động giống như đặt món ở nhà hàng. Khách hàng không đi vào bếp, tự bật lò, phân công đầu bếp, bày món ra đĩa, và kiểm tra từng bàn. Họ chỉ đặt món. Người quản lý biết các bước cần làm. Người quản lý cũng luôn để ý khi có gì thay đổi — nếu hết nguyên liệu hay có bàn cần phục vụ, người quản lý phản ứng ngay. Khách hàng không cần điều phối bất kỳ việc gì trong số đó. Trong khóa học này, object WebApp chính là đơn đặt món. Operator là phần biết cách biến đơn đặt món đó thành hành vi thực tế đang chạy trên Kubernetes, và biết cách giữ nó luôn như vậy.

Yêu cầu trước khi học: cần có sự thoải mái thực tế với Kubernetes. Nếu đã dùng kubectl, đọc được các file YAML nhỏ, và biết container chạy trong Pod, vậy là đủ. Không cần chứng chỉ Kubernetes. Cũng không cần là chuyên gia Go — sẽ có viết Go code sau này trong khóa học, nên có chút thoải mái với lập trình cơ bản (functions, variables, structs) sẽ hữu ích. Khi một chi tiết Go hay Kubernetes nào quan trọng, khóa học sẽ giải thích ngay lúc đó.

Những gì học viên sẽ học: trước hết là mental model — vì sao operator khác với một tập manifest tĩnh. Sau đó xây dựng một operator, từng bước — không phải một production platform khổng lồ, mà một WebApp operator đủ nhỏ để hiểu được, nhưng đủ thật để thể hiện đúng pattern. Trong quá trình xây dựng, học viên sẽ thấy các mảnh ghép làm nên một operator: Kubernetes học về object có hình dạng ứng dụng (application-shaped object) như thế nào, code theo dõi (watch) object đó ra sao, operator tạo và duy trì các Kubernetes resource mà app cần như thế nào, và sau đó là operator báo cáo ngược lại tình trạng cho người dùng ra sao.

Một operator hữu ích khi việc chỉ tạo YAML lần đầu là chưa đủ — khi ứng dụng có các rule, quyết định, sửa lỗi, hoặc các bước vòng đời mà nếu không thì phải có người làm thủ công. Thay vì giữ kiến thức vận hành đó trong một runbook, có thể đưa nó vào phần mềm — phần mềm đó theo dõi cluster và hành động thay bạn. Ví dụ: cert-manager cho phép yêu cầu một certificate. Người dùng không phải tự tay thực hiện từng bước renew — cert-manager theo dõi những gì được yêu cầu và tự thực hiện công việc liên quan tới certificate theo thời gian.

Ý tưởng cốt lõi cần nhớ: một template giúp tạo ra các Kubernetes object, nhưng một operator thì liên tục theo dõi một application-shaped object và luôn đẩy cluster tiến về trạng thái mà object đó yêu cầu.


3. Controller và Operator khác nhau ở đâu?

Sự nhầm lẫn bắt đầu khi hai người dùng hai từ khác nhau cho cùng một thứ trông giống nhau. Một kỹ sư nói "chúng ta cần một controller". Người khác nói "chúng ta cần một operator". Cả hai có thể đều đúng một phần, nhưng sự khác biệt này quan trọng trước khi bắt tay xây dựng bất cứ thứ gì.

💡 Hình dung: một Kubernetes controller giống như bộ điều nhiệt (thermostat) trong nhà. Bạn đặt nhiệt độ mong muốn, thermostat kiểm tra nhiệt độ thực tế trong phòng, và bật điều hòa để rút ngắn khoảng cách đó.

Một Kubernetes controller chính là vòng lặp watch-and-fix đó. Nó liên tục nhìn vào một resource, so sánh trạng thái thực tế của cluster với trạng thái mong muốn trong YAML, và hành động nếu chúng không khớp. Ví dụ, Deployment controller có sẵn (built-in) chỉ nhìn vào replica count của bạn và đảm bảo đúng số lượng Pod đó tồn tại. Những controller này đi kèm ngay trong Kubernetes, hoàn toàn generic — chúng không biết và không quan tâm ứng dụng của bạn là một database phức tạp hay chỉ là một website hiển thị ảnh mèo. Chúng chỉ giữ cho các con số khớp nhau.

Một operator dùng cùng cơ chế controller đó nhưng thêm vào kiến thức ứng dụng (application knowledge). Lấy cert-manager làm ví dụ: kiến thức domain ở đây là certificate. Bạn tạo một Certificate custom resource, và controller của cert-manager biết cách request, renew, và lưu trữ certificate. Với web app operator trong khóa học này, kiến thức domain là hình dạng (shape) của web app: người dùng viết imagereplicas. Controller biết rằng điều này cần trở thành một Deployment, một Service, và một ConfigMap.

Quy tắc rõ ràng là: một controller là cơ chế. Một operator là một controller vận hành một ứng dụng hoặc một domain, thường thông qua một custom resource. Vậy nên mọi operator đều là controller, nhưng không phải mọi controller đều là operator.


4. CRD và Controller ăn khớp với nhau ra sao?

Lần đầu mở một operator project, nó có thể trông như một kho hàng đầy thùng: file Go, file YAML, generated code, permissions, tests, webhooks, deployment manifests. Rất dễ tự hỏi operator thật sự đang nằm ở đâu.

💡 Hình dung: một máy bán hàng tự động (vending machine). Nút bấm và màn hình là interface. Bạn bấm, ví dụ B7, và máy biết bạn muốn món snack nào. Bên trong, motor và cuộn dây (coils) làm việc thật sự. Nút bấm mà không có máy móc thì không làm được gì. Máy móc mà không có nút bấm thì không nhận được order. Một operator có hình dạng y hệt như vậy: custom resource definition là interface, controller là máy móc.

CRD cho phép người dùng yêu cầu một thứ gì đó, controller làm việc để hiện thực hóa yêu cầu đó. CRD dạy cho Kubernetes một loại object mới. CRD là viết tắt của custom resource definition. Trong khóa học này, CRD dạy cho Kubernetes về một object WebApp trong API group webapp.codecloud.com/v1. Một khi CRD tồn tại, kubectl có thể tạo và list web app y hệt như tạo và list các Kubernetes object có sẵn.

Object WebApp có hai phần quan trọng:

  • Spec — là những gì người dùng yêu cầu. Với WebApp, spec chứa imagereplicas. image là container image cần chạy. replicas là số bản copy người dùng muốn.
  • Status — là những gì hệ thống báo cáo ngược lại. Đây là nơi controller có thể nói web app đã sẵn sàng (ready) hay chưa.

Controller là chương trình đang chạy. Nó theo dõi các object WebApp và chạy một hàm gọi là reconcile. Reconcile nghĩa là: đọc những gì người dùng yêu cầu, kiểm tra những gì đang tồn tại trong cluster, và làm cho cluster khớp với yêu cầu đó. Với một web app, controller tạo ra các child object quen thuộc: một Deployment cho biết Pod nào cần tồn tại và bao nhiêu bản. Một Pod là đơn vị chạy được (runnable unit) chứa container của app. Một Service cho các Pod đó một cái tên network ổn định, và một ConfigMap lưu cấu hình dạng plain text dưới dạng key-value data.

Còn một mảnh ghép nữa: owner reference. Owner reference là một liên kết nói rằng child object này thuộc về parent object kia. Khi Deployment, Service, và ConfigMap đều trỏ ngược về web app, Kubernetes có thể dọn dẹp chúng khi web app bị xóa.

Xung quanh phần lõi này, operator project còn có các mảnh hỗ trợ: manager là process khởi động và host controller. Cache là view cục bộ của các cluster object. Client là cách controller yêu cầu API server đọc hoặc ghi object. RBAC là kiểm soát quyền của Kubernetes, quyết định controller được phép làm gì.

Anatomy of an Operator: CRD + ControllerCRD — dạy Kubernetes biết object WebAppAPI group: webapp.codecloud.com/v1WebApp Custom Resourcespec: image, replicasControllerwatches WebApp → reconcile()Deploymentchạy đúng số PodServicetên network ổn địnhConfigMaplưu config key-valueOwner reference (nét đứt): Deployment/Service/ConfigMap trỏ ngược về WebApp→ Kubernetes tự dọn dẹp child object khi WebApp bị xóa

Cứ giữ mental map máy bán hàng tự động này: CRD ở phía trước, controller ở bên trong, các child Kubernetes object đi ra, và status báo cáo ngược lại. Một khi hình dạng đó rõ ràng, một operator repository lớn sẽ bớt đáng sợ hơn nhiều.


5. Vì sao Operator Pattern ra đời?

Operator pattern là một ý tưởng: lấy runbook mà SRE làm theo lúc 3 giờ sáng và biến nó thành một controller chạy liên tục bên trong cluster.

Hãy nghĩ về những gì cần để chạy một database ở production: cài đặt nó, cấu hình replication, lên lịch backup, theo dõi khi primary bị lỗi và promote một replica, upgrade cẩn thận từng node một, restore từ backup khi có sự cố. Kiến thức đó nằm trong một wiki, một Helm chart, một runbook, và trong đầu một kỹ sư đã trực on-call quá lâu.

Một operator ghi lại tất cả kiến thức đó vào một Kubernetes controller. Bạn mô tả trạng thái mong muốn trong một custom resource, kiểu như "tôi muốn một cụm Postgres 3 node, version 16, với backup hàng ngày", và reconcile loop của operator sẽ liên tục đẩy thực tế tiến về trạng thái đó. Cùng pattern control loop mà Kubernetes dùng cho deployment và service, chỉ mở rộng sang domain của bạn.

Pattern này được CoreOS đặt tên vào năm 2016. Các operator gốc là etcd OperatorPrometheus Operator — chúng cho thấy có thể làm nhiều hơn là chỉ cài phần mềm, có thể giữ cho nó luôn khỏe mạnh. Cộng đồng đã chính thức hóa điều này thành Operator Capability Levels:

  • Level 1 — basic install.
  • Level 2 — seamless upgrades.
  • Level 3 — full lifecycle: backups, restores, và recovery.
  • Level 4 — deep insight: metrics, alerts, workload analysis.
  • Level 5 — autopilot: horizontal/vertical scaling, auto tuning, anomaly detection.

Hầu hết production operator nằm ở level 2 hoặc 3. Nỗ lực kỹ thuật thật sự nằm ở việc lên tới level 4 và 5.

WebApp operator xây dựng trong khóa học này cố tình đơn giản hơn nhiều: một Deployment, một Service, một ConfigMap, được điều khiển bởi một CR. Nó sẽ không ship một database, nhưng pattern thì giống hệt: reconcile loop, desired state, status condition, finalizer cho việc cleanup, webhook cho validation. Khi đã nắm được các cơ chế này trên một operator nhỏ, mở rộng lên một stateful workload chủ yếu là thêm domain logic, không phải thêm Kubernetes.

Hai điều cần nhớ. Thứ nhất, operator không dành cho mọi workload — nếu app stateless và một Deployment cộng một Helm chart là đủ, bạn không cần operator. Chỉ nên dùng operator khi có logic vận hành liên tục mà khó diễn đạt bằng khai báo (declarative). Thứ hai, một operator là phần mềm. Nó có bug, cần test, cần upgrade, cần RBAC, cần metrics. Bạn không chỉ đang tiêu thụ (consume) Kubernetes, bạn đang mở rộng nó, và điều đó đi kèm trách nhiệm như bất kỳ production controller nào khác.


6. Operator trông như thế nào trong các công cụ thực tế?

Để hiểu trọn vẹn operator pattern, mọi thứ dễ hơn hẳn khi thấy nó trong các công cụ mọi người đã dùng. Operator không chỉ là một ý tưởng hay ho cho riêng khóa học này — chúng là cách nhiều team vận hành các platform service thật trên Kubernetes.

💡 Hình dung: một operator giống như một kỹ thuật viên chuyên môn. Kubernetes cung cấp tòa nhà, các phòng, và nguồn điện. Người kỹ thuật viên biết cách một loại máy cụ thể cần được lắp đặt, kiểm tra, sửa chữa, và nâng cấp như thế nào. Chính kiến thức chuyên môn đó là thứ làm cho một operator hữu ích.

Quay lại cert-manager operator: bạn tạo một object Certificate — một custom Kubernetes resource nói rằng bạn muốn TLS certificate nào. TLS certificate là thứ giúp ứng dụng chứng minh danh tính và dùng HTTPS mã hóa. cert-manager theo dõi certificate đó, request hoặc renew certificate thật, và lưu kết quả vào một Secret — nơi Kubernetes lưu trữ dữ liệu nhạy cảm.

Prometheus Operator đi theo cùng hình dạng đó. Prometheus là một hệ thống monitoring. Thay vì tự tay chỉnh sửa scrape configuration, bạn tạo các object như ServiceMonitor — mô tả những endpoint ứng dụng nào Prometheus cần thu thập metrics. Operator theo dõi các object đó và cập nhật cấu hình Prometheus phía sau.

Database thể hiện giá trị này rõ hơn nữa. Một PostgreSQL operator có thể theo dõi một PostgreSQL cluster object (cluster nghĩa là nhiều thành phần cùng hoạt động để đảm bảo độ tin cậy). Operator có thể quản lý StatefulSet, backup, failover, và upgrade. StatefulSet là một Kubernetes object dành cho các Pod cần identity ổn định, thứ database thường cần.

Strimzi làm công việc tương tự cho Kafka — một streaming platform. Strimzi cho phép mô tả Kafka cluster, topic, và user bằng Kubernetes object, sau đó controller của nó giữ cho hệ thống Kafka đang chạy luôn khớp với các object đó.

Pattern lặp lại giống hệt mỗi lần: thứ nhất, người dùng viết một custom resource, ví dụ một certificate, ServiceMonitor, PostgreSQL cluster, hoặc Kafka. Thứ hai, một controller theo dõi resource đó. Thứ ba, controller tạo hoặc cập nhật các Kubernetes object cấp thấp hơn và thực hiện công việc đặc thù cho ứng dụng.

WebApp operator trong khóa học này chính là phiên bản dành cho người mới bắt đầu của cùng pattern đó: custom resource là WebApp, controller tạo ra một Deployment, Service, và ConfigMap — Deployment kiểm soát các app Pod, Service cho chúng một tên network ổn định, và ConfigMap lưu cấu hình dạng plain text. Đây là cùng hình dạng được dùng bởi cert-manager, Prometheus Operator, PostgreSQL Operator, và Kafka Operator, chỉ với một web app nhỏ để lần xây dựng đầu tiên trở nên dễ tiếp cận hơn.


7. Operator vs Helm — Khi nào dùng cái nào

Sai lầm tốn kém là xây một Operator khi một Helm chart là đủ. Sai lầm ngược lại tương đương là dùng Helm cho một ứng dụng cần có ai đó theo dõi nó liên tục.

💡 Hình dung: giống như đang đi trên đường vậy. Helm giống như in sẵn chỉ đường trước chuyến đi — bạn chọn điểm đến, in ra tuyến đường, rồi đi theo. Cách này rất ổn nếu đường vẫn bình thường. Một operator giống như GPS — nó liên tục theo dõi con đường và có thể phản ứng khi có tắc đường, đóng đường, hoặc rẽ nhầm.

Helm đóng gói Kubernetes YAML. Điều đó hoàn hảo cho nhiều workload. Nếu app của bạn chủ yếu cần một Deployment và một Service, Helm có thể là đủ — Helm cài các object đó gọn gàng và upgrade chúng sau này khi bạn chạy lại Helm.

Một operator khác ở chỗ nó luôn chạy. Nó theo dõi một custom resource, so sánh trạng thái được yêu cầu với trạng thái thực tế của cluster, và phản ứng theo thời gian. Phần logic chạy liên tục đó tốn công xây dựng hơn, nhưng nó có thể xử lý những việc mà một template không làm được.

Vậy nên hãy chọn operator khi ứng dụng có Day 2 operations. Day 2 nghĩa là mọi thứ sau lần cài đặt đầu tiên — như backup, failover, gia hạn certificate, cleanup an toàn, upgrade có phối hợp, hoặc quản lý nhiều bản copy cho nhiều team. Nếu runbook nói "kiểm tra điều kiện này, rồi mới thực hiện bước tiếp theo sau khi app đã an toàn", logic đó có thể thuộc về một Operator. Ví dụ, database failover không chỉ là apply YAML — hệ thống có thể cần chọn một primary mới, đảm bảo dữ liệu an toàn, cập nhật traffic, và tránh để primary cũ tiếp tục nhận write. Đó là phán đoán ở cấp ứng dụng (application judgment). Helm không nằm trong cluster để đưa ra những quyết định đó.

Tuy nhiên cũng có một con đường ở giữa: một Helm-based operator đặt một custom resource ở trước một Helm chart có sẵn. Cách này hữu ích khi chart đã mô tả tốt workload, nhưng người dùng muốn dùng Kubernetes API thay vì lệnh Helm. Lựa chọn này sẽ được trình bày ở phần sau của khóa học.

Vậy nên quyết định khá đơn giản: dùng Helm khi công việc là đóng gói (packaging). Dùng operator khi công việc là vận hành ứng dụng liên tục (ongoing application operations). Nếu app cần một "người theo dõi" có kiến thức domain, operator pattern bắt đầu hợp lý.


8. Operator Capability Levels — Làm sao biết một Operator có đáng tin?

OperatorHub liệt kê hàng trăm operator. Nhìn thoáng qua chúng trông giống nhau — tên tương tự, README tương tự, hướng dẫn cài đặt tương tự. Nhưng khoảng một nửa trong số đó không sẵn sàng cho production. Một operator chỉ xử lý được cài đặt theo happy path là một thứ rất khác so với một operator làm được failover, backup, và version upgrade.

Vậy làm sao để phân biệt? GitHub star không nói lên điều đó. Ngày commit gần nhất cũng không. Vì lý do đó, Operator Framework đã chính thức hóa thành một thang 5 cấp độ năng lực (capability ladder), và mỗi operator trên OperatorHub đều khai báo level của nó ngay trên trang.

💡 Hình dung: giống như thang 5 cấp độ tự lái của ô tô — từ driver assist ở dưới cùng lên tới full self-driving ở trên cùng. Operator Capability Levels đi theo đúng hình dạng đó: 5 bậc thang, mỗi bậc thêm nhiều năng lực hơn. Điểm mấu chốt không phải là "cao hơn luôn tốt hơn", mà là chọn đúng bậc thang khớp với thứ workload của bạn thực sự cần.

  • Level 1 — Basic Install: operator có thể cài workload từ một CR (Custom Resource — object YAML mà operator theo dõi và hành động dựa trên đó). Operator cũng có thể cấu hình CR này, apply một manifest, Pod chạy lên, spec được tuân thủ. Web app operator xây dựng trong phần core reconcile của khóa học nằm ở level này.
  • Level 2 — Seamless Upgrades: operator có thể upgrade chính nó và operand (operand là workload nó quản lý). Operator có thể di chuyển operand qua các version mà không mất state. Các CRD version mới được phục vụ qua conversion. Người dùng chạy kubectl với bundle mới, và operator xử lý việc migration. Nội dung này được đề cập khi khóa học thêm conversion webhook và ship qua OLM (Operator Lifecycle Manager — công cụ quản lý việc cài đặt, upgrade, và vòng đời của operator trên cluster) ở phần packaging and distribution.
  • Level 3 — Full Lifecycle: operator ở đây sở hữu backup, restore, khôi phục sau lỗi, và cấu hình lại phức tạp. Hãy nghĩ tới một database operator có thể snapshot, restore, và rebuild một replica bị lỗi mà không cần bạn động tới kubectl. Đây là nơi finalizer phát huy giá trị. Finalizer là logic cleanup chạy trước khi một resource bị xóa. Leader election và báo cáo status cẩn thận cũng quan trọng ở đây. Các phần Finalizers and Cleanup và Status Conditions/Events dẫn thẳng tới Level 3.
  • Level 4 — Deep Insights: operator phát ra Prometheus metrics, structured events, alert, và condition rõ ràng. Nó cho bạn biết vì sao một reconcile thất bại, không chỉ là nó đã thất bại. Khóa học sẽ dùng controller-runtime metrics endpoint sau này, khi tới phần production readiness and observability. controller-runtime là thư viện Go cung cấp cho operator reconcile loop và instrumentation có sẵn. Một operator level 4 là loại operator mà một SRE thật sự tin tưởng trong production.
  • Level 5 — Autopilot: auto-scaling, auto-healing, auto-tuning, và anomaly detection. Rất ít operator đạt tới level 5, và hầu hết workload cũng không cần tới nó. cert-manager, chẳng hạn — sẽ gặp trong demo tiếp theo và quay lại sau trong khóa học — là một operator trưởng thành mà không phải là một database operator kiểu autopilot. Đó chính là điểm mấu chốt: level được khai báo phản ánh phạm vi (scope) của operator, không phải độ trưởng thành của dự án.
Operator Capability Levels — 5 bậc thang năng lực1. Basic Installinstall từ CR2. Seamless Upgradesupgrade không mất state3. Full Lifecyclebackup, restore, failover4. Deep Insightsmetrics, alerts, events5. Autopilotauto-scale, auto-healCàng lên cao, effort kỹ thuật càng lớn — hầu hết production operator dừng ở Level 2-3

Hai điều cần áp dụng vào thực tế: khi đánh giá một operator từ bên ngoài team, kiểm tra capability level đã khai báo trên OperatorHub — một operator level 2 chạy database production của bạn là một dấu hiệu cảnh báo (red flag). Khi tự xây dựng operator, bắt đầu ở level 1 rồi leo dần lên. Mỗi phần trong khóa học sẽ thêm năng lực cho web app operator, và tới cuối khóa, học viên sẽ đi qua từ level 1 tới level 4.


9. Demo: Cài đặt cert-manager trong 60 giây

Phần demo này cài một operator production-grade thật end-to-end trong chưa tới một phút wall-clock, sau đó thử nghiệm với custom resource nó tạo ra. Đây là hình dạng của mọi lần cài operator trong suốt phần còn lại của khóa học.

Bước 1 — Xác nhận cluster đang trống. Trước khi cài, kiểm tra không có namespace cert-manager và không có CRD cert-manager nào trên cluster:

kubectl get namespace cert-manager
# Output minh họa
Error from server (NotFound): namespaces "cert-manager" not found

(Output minh họa — xác nhận cluster đang sạch, chưa từng cài cert-manager.)

Một mặt bằng sạch.

Bước 2 — Apply manifest cert-manager. Một lệnh kubectl apply duy nhất nhắm vào manifest chính thức của bản release version 1.19.1. Một URL này ship kèm namespace, CRD, controller deployment, webhook, CA injector — toàn bộ operator:

kubectl apply -f <URL manifest cert-manager v1.19.1>
# Output minh họa (rút gọn)
namespace/cert-manager created
customresourcedefinition.apiextensions.k8s.io/certificates.cert-manager.io created
customresourcedefinition.apiextensions.k8s.io/certificaterequests.cert-manager.io created
deployment.apps/cert-manager created
deployment.apps/cert-manager-webhook created
deployment.apps/cert-manager-cainjector created

(Output minh họa — rút gọn, manifest thật tạo nhiều object hơn liệt kê ở đây.)

Chờ cả 3 deployment roll out. Trên một cluster kind (kind — công cụ chạy Kubernetes cluster cục bộ bằng container Docker đóng vai node, thường dùng để test/demo), việc này mất khoảng 20 giây.

Điểm đáng chú ý: operator đã mở rộng Kubernetes API với các resource kind mới. Liệt kê chúng ra:

kubectl api-resources --api-group=cert-manager.io
# Output minh họa
NAME SHORTNAMES APIVERSION NAMESPACED KIND
certificaterequests cr,crs cert-manager.io/v1 true CertificateRequest
certificates cert,certs cert-manager.io/v1 true Certificate
clusterissuers cert-manager.io/v1 false ClusterIssuer
issuers cert-manager.io/v1 true Issuer

(Output minh họa — đúng 4 kind theo lời giảng, tên field/kind khớp thật với cert-manager.io.)

Bốn kind này chưa hề tồn tại trên cluster hai phút trước.

Chứng minh nó thực sự hoạt động. Tạo một self-signed ClusterIssuer — một custom resource mà operator sẽ reconcile:

kubectl apply -f <manifest ClusterIssuer>
# Output minh họa
clusterissuer.cert-manager.io/self-signed created
kubectl wait --for=condition=ready ClusterIssuer self-signed --timeout=10s
# Output minh họa
clusterissuer.cert-manager.io/self-signed condition met
kubectl get ClusterIssuer self-signed
# Output minh họa
NAME READY AGE
self-signed True 8s

(3 output trên đều minh họa — đúng cấu trúc field/thông điệp thật của cert-manager, số liệu cụ thể chỉ mang tính ví dụ.)

Cột READY báo True — đúng là điều lệnh kubectl wait phía trên vừa chờ cho tới khi xảy ra.

cert-manager: Operator Pattern trong 60 giây1. kubectl apply -f cert-manager.yaml (v1.19.1)→ ship Namespace + CRDs + Controller + Webhook + CA Injector2. kubectl api-resources --api-group=cert-manager.io→ 4 API kind mới xuất hiện3. kubectl apply -f clusterissuer.yaml (self-signed)→ tạo custom resource ClusterIssuer4. kubectl wait --for=condition=readyClusterIssuer self-signed --timeout=10s→ chờ operator reconcile xongClusterIssuer READY — Operator Pattern hoạt động

Đó là operator pattern trong 60 giây: một lệnh apply, các API kind mới xuất hiện, controller hoạt động thật sự. Trong phần còn lại của khóa học, học viên sẽ xây dựng đúng hình dạng này, chỉ khác là operator sẽ là của chính học viên. Vài phần nữa, học viên sẽ viết controller theo dõi custom resource và đẩy nó tới trạng thái mong muốn — đúng điệu nhảy (dance) mà controller của cert-manager vừa thực hiện khi reconcile ClusterIssuer đó thành trạng thái ready true.

Mọi operator được xây dựng trong khóa học, dù phức tạp tới đâu, đều quy về một CRD cộng với một controller phản ứng lại nó.


10. Lộ trình xây dựng WebApp Operator

Khóa học này có một lời hứa đơn giản: học viên sẽ xây dựng một operator mà mình thật sự hiểu — không chỉ định nghĩa nó, không chỉ cài đặt nó, mà xây dựng từng mảnh và quan sát chúng phối hợp với nhau.

💡 Hình dung: giống như đặt một bữa ăn đơn giản tại quầy. Khách hàng nói ra thứ họ muốn. Nhà bếp xử lý các bước phía sau tấm rèm. Trong khóa học này, người dùng tạo một object web app, operator xử lý các Kubernetes object đứng sau nó.

Object web app có một spec nhỏ. Spec là phần của object nơi người dùng viết trạng thái mong muốn. Với một web app, người dùng viết imagereplicas. image nghĩa là container image cần chạy. replicas nghĩa là bao nhiêu bản copy cần chạy. Đứng sau một web app đó, controller sẽ tạo ra ba child object:

  • Một Deployment, cho biết có bao nhiêu Pod khớp cần đang chạy.
  • Một Service, cho các Pod đó một tên network ổn định.
  • Một ConfigMap để lưu cấu hình dạng plain text theo key-value data.

Học viên bắt đầu từ phía API. Một CRD (custom resource definition) dạy cho Kubernetes rằng web app là một object hợp lệ. Sau đó tạo các resource web app và xem cách Kubernetes chấp nhận, lưu trữ, và validate chúng.

Tiếp theo là Kubebuilder — một công cụ scaffold operator project để không phải bắt đầu từ một thư mục rỗng. Nó tạo ra cấu trúc project, các file generated, và entry point của controller. Học viên sẽ xem những gì Kubebuilder tạo ra trước khi thêm logic riêng.

Sau đó, học viên xây dựng một reconcile loop. Reconcile là hàm watch-and-fix của controller — nó đọc web app, kiểm tra những gì đang tồn tại, và làm cho Deployment, Service, ConfigMap khớp với nó. Sau bước đó, học viên thêm statusevents để người dùng có thể thấy operator đã làm gì.

Các phần sau thêm vào tính an toàn và đóng gói: validation giúp từ chối các object web app không hợp lệ trước khi chúng được lưu trữ. Finalizer cho controller cơ hội dọn dẹp trước khi việc xóa hoàn tất. Packaging biến controller thành một image có thể chạy bên trong cluster.

Khóa học cũng so sánh các phương án thay thế: Operator SDK thể hiện một workflow khác. Helm-based operator cho thấy cách một Helm chart có sẵn có thể đứng sau một custom resource. Và gần cuối khóa học, học viên chuyển sang vai trò người tiêu thụ (consumer mode) và khảo sát các operator thật như cert-managerPrometheus Operator.

Vậy lộ trình là: một object web app, một controller theo dõi nó, các Kubernetes object được tạo ra phía sau, status, validation, cleanup, packaging, và các so sánh với thế giới thực — thêm vào từng bước một.


Nguồn tham khảo

Nguồn gốc: Khóa "Kubernetes Operators" — phần "Introduction to Operator Fundamentals" (giới thiệu khóa học, vấn đề operator giải quyết, controller vs operator, anatomy CRD + controller, operator pattern, operator trong thực tế, operator vs Helm, operator capability levels, demo cert-manager, lộ trình WebApp operator), nền tảng KodeKloud. Giảng viên: Ahmed Elfakharany.

Fact-check: