## Triển khai Prometheus
<br>

> ⚠️ Tài liệu này chỉ áp dụng cho việc tham khảo triển khai cụm phiên bản 1.22 trở xuống. Đối với các cụm từ phiên bản 1.22 trở lên, vui lòng sử dụng thông qua console - chi tiết cụm - trung tâm giám sát, tham khảo: [Tổng quan về Trung tâm Giám sát](/docs/uk8s/monitor/prometheus/intro2).

### Giới thiệu

Đối với một cụm Kubernetes, các đối tượng cần được giám sát có thể được chia thành các danh mục sau:

- **Thành phần hệ thống Kubernetes:** Các thành phần hệ thống tích hợp sẵn của Kubernetes thường bao gồm apiserver, controller-manager, etcd, kubelet, v.v. Để đảm bảo cụm hoạt động bình thường, chúng ta cần biết trạng thái hoạt động hiện tại của chúng theo thời gian thực.

- **Cơ sở hạ tầng bên dưới:** Trạng thái tài nguyên, các sự kiện kernel, v.v. của các nút Node (máy ảo hoặc máy vật lý).

- **Đối tượng Kubernetes:** Chủ yếu là các đối tượng workload trong Kubernetes, chẳng hạn như Deployment, DaemonSet, Pod, v.v.

- **Chỉ số ứng dụng:** Các chỉ số dữ liệu cần quan tâm trong ứng dụng, chẳng hạn như httpRequest.

### Triển khai Prometheus

Khi triển khai Prometheus trong Kubernetes, ngoài các phương pháp thủ công, CoreOS đã mã nguồn mở các dự án Prometheus-Operator và kube-Prometheus, giúp việc cài đặt và triển khai Prometheus trong K8S trở nên cực kỳ đơn giản. Dưới đây chúng tôi sẽ giới thiệu cách triển khai Kube-Prometheus trong K8S.

#### 1. Về Prometheus-Operator

Bản chất thực sự của Prometheus-operator là một tập hợp các tài nguyên CRD do người dùng xác định và việc triển khai Controller. Controller của Prometheus Operator chịu trách nhiệm lắng nghe các thay đổi tài nguyên tùy chỉnh này dưới quyền hạn BRAC, và tự động hóa các tác vụ như tự quản lý và quản lý cấu hình của Prometheus Server dựa trên các định nghĩa tài nguyên này.

Trong K8S, đơn vị cơ bản nhỏ nhất của các chỉ số giám sát là một nhóm các pod đằng sau một Service, tương ứng với target trong Prometheus. Vì vậy, prometheus-operator đã trừu tượng hóa loại CRD tương ứng là "ServiceMonitor". ServiceMonitor này truy vấn Service tương ứng và các Pod hoặc endpoint đằng sau nó thông qua sepc.selector.labes, và chỉ định đường dẫn url Metrics thông qua sepc.endpoint.
Lấy ví dụ về CoreDNS bên dưới, Namespace của đối tượng Target cần kéo là kube-system, kube-app là label của chúng, và port là metrics.

```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  labels:
    k8s-app: coredns
  name: coredns
  namespace: monitoring
spec:
  endpoints:
  - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token
    interval: 15s
    port: metrics
  jobLabel: k8s-app
  namespaceSelector:
    matchNames:
    - kube-system
  selector:
    matchLabels:
      k8s-app: kube-dns
```

#### 2. Công việc chuẩn bị

SSH vào bất kỳ nút Master nào và sao chép (clone) dự án kube-prometheus. Dự án này bắt nguồn từ dự án mã nguồn mở [kube-prometheus](https://github.com/coreos/kube-prometheus) của CoreOS, so với dự án gốc, nó chủ yếu có các tối ưu hóa sau:

- Thay đổi phương tiện lưu trữ dữ liệu của Prometheus và AlertManager từ emptyDir thành Disk để tăng cường tính ổn định và tránh mất dữ liệu;
- Thống nhất nguồn image thành Hub, để tránh xảy ra lỗi kéo (pull) image;
- Thêm một thư mục K8S chuyên dụng để cấu hình controller-manager, scheduler, etcd;
- Phân chia các tệp thực thi theo thư mục để dễ dàng sửa đổi và đọc.

```Bash
yum install git -y
git clone --depth=1 -b kube-prometheus https://github.com/ucloud/uk8s-demo.git
```

#### 3. Sửa đổi các tham số cấu hình tệp cụ thể của K8S

Trong thư mục manifests, có một thư mục K8S. Các tệp cấu hình này chủ yếu được sử dụng để tạo thủ công các endpoint và svc cho controller-manager, scheduler và etcd trong K8S, để Prometheus Server có thể thu thập dữ liệu giám sát của ba thành phần này thông qua ServiceMonitor.

```Bash
cd /uk8s-demo/manifests/uk8s
# Sửa đổi hai tệp sau, thay thế IP trong đó bằng IP riêng của nút Master UK8S của riêng bạn.
vi controllerManagerAndScheduler_ep.yaml
vi etcd_ep.yaml
```

#### 4. Lưu ý

Việc đề cập ở trên về việc sửa đổi hai tệp controllerManagerAndScheduler_ep.yaml và etcd_ep.yaml, ở đây sẽ giải thích lý do.
Vì ETCD, Scheduler, Controller-Manager của K8S đều được triển khai thông qua các tệp nhị phân, để đạt được việc lấy Metrics thông qua cấu hình "ServiceMonitor", chúng ta phải tạo một đối tượng SVC cho nó trong K8S. Tuy nhiên, vì ba thành phần này không phải là các Pod, nên chúng ta cần tạo Endpoints thủ công cho chúng.

```yaml
apiVersion: v1
kind: Endpoints
metadata:
  labels:
    k8s-app: etcd
  name: etcd
  namespace: kube-system
subsets:
- addresses:
  - ip: 10.7.35.44 # Thay thế bằng IP riêng của nút master
    nodeName: etc-master2
  ports:
  - name: port
    port: 2379
    protocol: TCP
- addresses:
  - ip: 10.7.163.60 # Tương tự
    nodeName: etc-master1
  ports:
  - name: port
    port: 2379
    protocol: TCP
- addresses:
  - ip: 10.7.142.140 # Tương tự
    nodeName: etc-master3
  ports:
  - name: port
    port: 2379
    protocol: TCP
```

#### 5. Triển khai Prometheus Operator

Đầu tiên, tạo một namespace có tên là monitor. Sau khi monitor được tạo thành công, hãy triển khai trực tiếp Operator. Prometheus Operator sẽ khởi động dưới dạng một Deployment và sẽ tạo một số đối tượng CRD đã đề cập trước đó.

```Bash
# Tạo Namespace
kubectl apply -f  00namespace-namespace.yaml
# Tạo Secret để cung cấp cho Prometheus Server lấy dữ liệu ETCD
kubectl -n monitoring create secret generic etcd-certs --from-file=/etc/kubernetes/ssl/ca.pem --from-file=/etc/kubernetes/ssl/etcd.pem --from-file=/etc/kubernetes/ssl/etcd-key.pem
# Tạo Operator
kubectl apply -f operator/
# Xem trạng thái khởi động của operator
kubectl get po -n monitoring
# Xem CRD
kubectl get crd -n monitoring
```

#### 6. Triển khai một bộ CRD hoàn chỉnh

Các thành phần quan trọng hơn bao gồm Prometheus Server, Grafana, AlertManager, ServiceMonitor, Node-Exporter, v.v. Tất cả các image này đã được sửa đổi thành các image chính thức của Hub, vì vậy tốc độ kéo (pull) tương đối nhanh.

```Bash
kubectl apply -f adapter/ 
kubectl apply -f alertmanager/ 
kubectl apply -f node-exporter/ 
kubectl apply -f kube-state-metrics/ 
kubectl apply -f grafana/ 
kubectl apply -f prometheus/ 
kubectl apply -f serviceMonitor/
kubectl apply -f uk8s/
```

Chúng ta có thể sử dụng lệnh sau để kiểm tra trạng thái kéo ứng dụng.

```Bash
kubectl -n monitoring get po
```

Vì tất cả các loại SVC mặc định đều là ClusterIP, chúng tôi chuyển nó thành LoadBalancer để thuận tiện cho việc trình diễn.

```Bash
kubectl edit svc/prometheus-k8s -n monitoring
# Sửa đổi thành type: LoadBalancer
[root@10-9-52-233 manifests]# kubectl get svc -n monitoring
# Lấy EXTERNAL-IP và cổng của Prometheus Server
```

Bạn có thể thấy rằng các chỉ số giám sát của tất cả các thành phần K8S đã được lấy.

#### 7. Giám sát các chỉ số ứng dụng

Trước tiên, hãy triển khai một bộ Pod và SVC. Tiến trình chính bên trong image này sẽ xuất thông tin chỉ số (metrics) trên cổng 8080.

```yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: example-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: example-app
  template:
    metadata:
      labels:
        app: example-app
    spec:
      containers:
      - name: example-app
        image: uhub.cloud.vnpt.vn/uk8s_public/instrumented_app:latest
        ports:
        - name: web
          containerPort: 8080
---
kind: Service
apiVersion: v1
metadata:
  name: example-app
  labels:
    app: example-app
spec:
  selector:
    app: example-app
  ports:
  - name: web
    port: 8080
```

Sau đó, tạo một ServiceMonitor để báo cho prometheus server biết rằng nó cần giám sát một nhóm các chỉ số pod đằng sau svc được gắn nhãn app: example-app.

```yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: example-app
  labels:
    team: frontend
spec:
  selector:
    matchLabels:
      app: example-app
  endpoints:
  - port: web
```

Mở trình duyệt để truy cập Prometheus Server, nhập target để tìm thấy nó đã được lắng nghe, và cấu hình tương ứng đã được tự động tạo và tải.

#### 8. Lưu ý

Tài liệu này chỉ áp dụng cho các phiên bản Kubernetes từ 1.14 trở lên. Nếu phiên bản Kubernetes của bạn dưới 1.14, bạn có thể sử dụng [release-0.1](https://github.com/coreos/kube-prometheus/tree/release-0.1).