Khi cluster đã có ingress, chứng chỉ tự động và ứng dụng chạy ổn, các câu hỏi "node có đang đầy không", "pod nào ăn nhiều RAM nhất", "tuần trước có gì bất thường" vẫn chỉ trả lời được bằng cách gõ kubectl và đoán. Tài liệu này hướng dẫn dựng hệ thống giám sát Kubernetes bằng kube-prometheus-stack: bộ công cụ gồm những gì, ServiceMonitor hoạt động ra sao, cấu hình cho cluster LKE, cách đưa Prometheus và Grafana ra ngoài qua Ingress có basic auth, và những lỗi cấu hình hay gặp.

1. Vì sao cần giám sát Kubernetes từ sớm

Trên Cloud VPS, mỗi máy là một đơn vị dễ hình dung: SSH vào, htop, xem log. Trong cluster, workload trôi giữa các node, pod chết rồi được tạo lại với tên mới, và lịch sử biến mất theo pod. kubectl top chỉ cho biết lúc này, không cho biết hôm qua. Giám sát Kubernetes trả lời ba nhóm câu hỏi mà kubectl không trả lời được:

  • Tài nguyên theo thời gian: CPU, RAM, đĩa, mạng của từng node và từng pod trong nhiều ngày, để biết pod nào thật sự cần bao nhiêu.
  • Trạng thái đối tượng: pod nào restart liên tục, Deployment nào thiếu replica, PVC nào sắp đầy.
  • So sánh khai báo với thực tế: tổng requests đã chiếm bao nhiêu phần trăm node, trong khi mức dùng thật là bao nhiêu.

Câu hỏi thứ ba đặc biệt quan trọng. Bài Dựng cluster LKE đầu tiên: node pool, kubeconfig và lựa chọn ban đầu đã nói scheduler xếp pod theo requests. Không có giám sát Kubernetes, mọi con số request đều là đoán.

2. kube-prometheus-stack gồm những gì

Thay vì tự lắp từng mảnh của hệ thống giám sát Kubernetes, bạn có thể dùng Helm chart kube-prometheus-stack của cộng đồng Prometheus. Chart đóng gói dự án kube-prometheus thành một release duy nhất:

Thành phầnVai trò
Prometheus OperatorController quản lý Prometheus, Alertmanager và cấu hình thu thập thông qua CRD
PrometheusThu thập (scrape) và lưu metric dạng chuỗi thời gian, trả lời truy vấn PromQL
node-exporterDaemonSet, mỗi node một pod, xuất metric của máy: CPU, RAM, đĩa, mạng, load
kube-state-metricsĐọc API server, xuất metric về đối tượng Kubernetes: số replica, trạng thái pod, số lần restart, request và limit
GrafanaGiao diện dashboard, có sẵn nhiều dashboard cho node, namespace, pod
AlertmanagerGom và gửi cảnh báo

Trong giám sát Kubernetes, hai exporter này dễ bị nhầm với nhau. node-exporter nhìn từ góc máy chủ: node này còn bao nhiêu RAM. kube-state-metrics nhìn từ góc Kubernetes: Deployment này muốn 1 replica nhưng đang có 0. Còn pod dùng bao nhiêu CPU là việc của cAdvisor tích hợp trong kubelet, cũng được chart cấu hình thu thập sẵn.

Prometheus Operator và CRD

Prometheus Operator đưa giám sát Kubernetes về mô hình operator: thay vì sửa file prometheus.yml, bạn khai báo đối tượng Kubernetes và operator tự sinh cấu hình. Chart cài các CRD như Prometheus, Alertmanager, AlertmanagerConfig, ServiceMonitor, PodMonitor, Probe, PrometheusRule, PrometheusAgent, ScrapeConfig và ThanosRuler. Tài liệu đầy đủ nằm trên trang của Prometheus Operator.

ServiceMonitor: khai báo cái gì cần scrape

ServiceMonitor nói với operator: "hãy scrape các Service có label này, ở cổng tên này, đường dẫn này". Ví dụ cho một ứng dụng có endpoint /metrics:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: my-app
  namespace: monitoring
  labels:
    release: <tên-release>        # để Prometheus của chart chọn ServiceMonitor này
spec:
  namespaceSelector:
    matchNames: [my-app]
  selector:
    matchLabels:
      app: my-app
  endpoints:
  - port: metrics
    path: /metrics
    interval: 30s

Cái bẫy phổ biến nhất khi mới làm giám sát Kubernetes bằng chart này nằm ở label release. Với giá trị mặc định của chart, Prometheus chỉ chọn những ServiceMonitor mang label release trùng tên Helm release. Thiếu label đó, ServiceMonitor vẫn được tạo thành công nhưng không bao giờ xuất hiện trong danh sách target. Nếu ứng dụng Laravel chưa có endpoint metric riêng, các ServiceMonitor có sẵn của chart (node, kubelet, kube-state-metrics, CoreDNS, chính Prometheus) đã đủ cho giai đoạn đầu.

3. Cấu hình giám sát Kubernetes cho cluster LKE

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
kubectl create namespace monitoring
helm install <tên-release> prometheus-community/kube-prometheus-stack \
  --namespace monitoring --version <phiên-bản> \
  -f values-monitoring.yaml

File values mẫu cho hệ thống giám sát Kubernetes, lược phần ingress (nói ở mục 4):

prometheus:
  prometheusSpec:
    routePrefix: /
    externalUrl: https://monitoring.example.com/prometheus
    retention: 10d
    resources:
      requests: {cpu: 200m, memory: 1Gi}
      limits:   {memory: 2Gi}
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: linode-block-storage-retain
          resources:
            requests:
              storage: 10Gi

alertmanager:
  enabled: false          # bật khi đã biết cần cảnh báo gì

grafana:
  persistence:
    enabled: true
    storageClassName: linode-block-storage-retain
    size: 10Gi
  grafana.ini:
    server:
      domain: monitoring.example.com
      root_url: "%(protocol)s://%(domain)s/grafana/"

# Control plane do LKE quản lý, không scrape được
kubeEtcd:
  enabled: false
kubeControllerManager:
  enabled: false
kubeScheduler:
  enabled: false

Ba quyết định đáng chú ý:

  • Tắt scrape etcd, controller manager, scheduler. Control plane của LKE do Linode vận hành, các thành phần này không lộ cổng metric cho người dùng. Để mặc định, Prometheus có ba nhóm target luôn down và các rule đi kèm báo lỗi giả.
  • Prometheus và Grafana có volume riêng với StorageClass Retain, như bài Volume, PersistentVolume, PVC và StorageClass trên Kubernetes. Không có volume, Prometheus restart là mất toàn bộ lịch sử giám sát Kubernetes, Grafana restart là mất dashboard tự tạo. Dung lượng cần tăng theo retention và số series.
  • Alertmanager có thể tắt ở giai đoạn đầu, khi bạn còn cần nhìn số liệu để biết nên cảnh báo cái gì. Nhưng đó chỉ là bước tạm: không có cảnh báo, hệ thống chỉ có ích khi có người mở Grafana ra xem.

4. Bảo vệ Prometheus và Grafana bằng basic auth qua Ingress

Prometheus không có đăng nhập. Ai vào được giao diện của nó là xem được mọi metric, gồm tên namespace, tên pod, domain của từng site. Grafana có đăng nhập riêng, nhưng thêm một lớp phía trước không thừa. Có thể đưa hai giao diện giám sát Kubernetes ra một domain, phân biệt bằng đường dẫn, và chặn bằng basic auth của ingress-nginx:

# tạo file htpasswd và Secret trong namespace monitoring
htpasswd -c auth <user>
kubectl create secret generic basic-auth --from-file=auth -n monitoring
rm auth                              # không để file này lại trong repo
prometheus:
  ingress:
    enabled: true
    ingressClassName: nginx
    annotations:
      nginx.ingress.kubernetes.io/rewrite-target: /$2
      nginx.ingress.kubernetes.io/auth-type: basic
      nginx.ingress.kubernetes.io/auth-secret: basic-auth
      nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required'
    hosts:
    - monitoring.example.com
    paths:
    - /prometheus(/|$)(.*)
    tls:
    - secretName: monitoring-tls
      hosts:
      - monitoring.example.com
# grafana.ingress tương tự, path /grafana(/|$)(.*), cùng secretName monitoring-tls

Path dạng regex /prometheus(/|$)(.*) kết hợp rewrite-target: /$2 cắt tiền tố /prometheus trước khi chuyển vào pod. Vì vậy Prometheus vẫn phục vụ ở / (routePrefix: /), còn externalUrl cho nó biết địa chỉ công khai để sinh link đúng. Grafana dùng cùng cách, kèm root_url có /grafana/. Cơ chế basic auth được mô tả trong ví dụ Basic Authentication của ingress-nginx: file phải tên auth, vì ingress-nginx đọc đúng key đó trong Secret.

Chứng chỉ cho domain giám sát Kubernetes đi theo cách ở bài ingress-nginx và cert-manager: HTTPS tự động trên Kubernetes: một Certificate tường minh ghi vào Secret monitoring-tls, dùng chung ClusterIssuer của cluster.

5. Lỗi cấu hình thường gặp khi giám sát Kubernetes

Các lỗi dưới đây đều không báo đỏ ở đâu cả, chỉ lộ ra khi đọc lại values từng dòng:

  • Annotation trỏ tới issuer không tồn tại. Nếu Ingress vừa có annotation cert-manager.io/cluster-issuer sai tên, vừa có khối tls, ingress-shim sẽ sinh thêm một Certificate thứ hai cùng ghi vào Secret TLS, và Certificate đó không bao giờ sẵn sàng. HTTPS vẫn chạy nhờ Certificate tường minh nên lỗi không lộ trên trình duyệt. Đã viết Certificate tường minh thì bỏ annotation.
  • Hai Ingress cùng host, khác Secret TLS. Ingress Grafana trỏ tới một Secret mà không Certificate nào tạo ra. Cùng một domain thì dùng chung một Secret để khỏi phụ thuộc cách ingress-nginx gộp cấu hình.
  • Tạo ClusterIssuer riêng cho monitoring. ClusterIssuer vốn dùng được cho mọi namespace; một bản sao chỉ khác Secret khoá tài khoản ACME là thừa và dễ gây nhầm tên.
  • File auth nằm trong Git. Dù chỉ là hash, file htpasswd không nên vào repo: hash yếu có thể bị dò ngược, và ai đọc repo cũng biết tên user.
  • Monitoring chạy chung node với website, không có resources. Prometheus ngốn RAM và tranh tài nguyên với chính các pod mà nó đang đo.
  • ServiceMonitor thiếu label release, như mục 2.

6. Monitoring nên chạy ở đâu

Hệ thống giám sát Kubernetes không nên chết cùng lúc với thứ nó giám sát. Một website bị tấn công kéo node tới cạn RAM, đúng lúc cần số liệu nhất thì Prometheus trên cùng node bị OOM. Hãy đặt Prometheus, Grafana và operator lên node pool hệ thống, như ý tưởng chia pool theo vai trò ở bài dựng cluster, đồng thời đặt requests và limits rõ ràng. Muốn vậy phải hiểu requests, limits, lớp QoS và nodeAffinity theo label lke.linode.com/pool-id, nội dung của bài tiếp theo.

Có giám sát Kubernetes rồi, cách chỉnh tài nguyên cũng thay đổi: request CPU, RAM của MySQL hay container web chỉ nên hạ hoặc tăng khi đã nhìn thấy mức dùng thật trong nhiều ngày trên Grafana, không đổi theo cảm giác.

7. Checklist giám sát Kubernetes

  1. kube-prometheus-stack được ghim phiên bản, values nằm trong Git (không kèm bí mật).
  2. Tắt scrape các thành phần control plane mà dịch vụ quản lý không lộ ra.
  3. Prometheus và Grafana có volume Retain, retention và dung lượng tương xứng.
  4. Giao diện ra ngoài qua HTTPS, có basic auth, Secret TLS dùng chung cho một host.
  5. ServiceMonitor tự viết có label release đúng.
  6. Monitoring chạy ở pool hệ thống, có resources.
  7. Có kế hoạch bật Alertmanager với một bộ cảnh báo tối thiểu.

Dựng giám sát Kubernetes bằng kube-prometheus-stack nhanh hơn nhiều so với tự lắp: một lệnh Helm có ngay Prometheus, exporter, dashboard và hàng loạt rule viết sẵn. Phần tốn công là thích nghi với môi trường và giữ cấu hình của chính hệ thống giám sát Kubernetes cho đúng. Khi cần tự dựng dashboard riêng, tài liệu Grafana là nơi tra cứu.

Bài tiếp theo

Requests và limits, QoS và nodeAffinity: xếp pod lên đúng node. Đọc số liệu từ Grafana để đặt lại tài nguyên, hiểu ba lớp QoS, và ép từng nhóm pod chạy trên đúng node pool.