- vừa được xem lúc

Sử dụng Prometheus, Blackbox Exporter, Alert Manager và Grafana để theo dõi trạng thái uptime website như updown.io

0 0 37

Người đăng: Dao Thai Son

Theo Viblo Asia

Uptime là gì? Tại sao cần theo dõi nó ?

image.png Uptime (thường biểu thị theo phần trăm) cho biết tỉ lệ phần trăm hoạt động đầy đủ của website. Tỷ lệ phần trăm còn lại là mức độ thường xuyên mà nó không hoạt động. Nếu dịch vụ hosting web nói uptime là 93%, nghĩa là server của họ bị downtime trung bình 7% thời gian Một trong những tính quan trọng nhất của trang web là tính khả dụng. Bạn có thể sở hữu nội dung tuyệt vời, hình ảnh sản phẩm đẹp mắt, và những tính năng đặc biệt đầy thu hút, nhưng khi người dùng cần sử dụng tới thì website lại không hoạt động, điều đó thật sự đem lại trải nghiệm xấu cho người dùng, họ sẵn sàng trải nghiệm 1 website khác thay thế. Đó là lý do tại sao việc theo dõi hiệu suất trang web là cần thiết. Chỉ 1 phút ngừng hoạt động có thể khiến công ty của bạn mất hàng ngàn đô la. Hãy tưởng tượng đến những mất mát từ phút kéo dài sang hàng giờ hoặc thậm chí vài ngày.

Làm thế nào để theo dõi trạng thái Uptime của website ?

Có một số công cụ giám sát uptime website miễn phí sẽ cho bạn biết khi nào trang web ngừng hoạt động ví dụ như https://updown.io, https://uptime.com,... Tuy nhiên đa số chúng đều giới hạn số lượng website được sử dụng. Vì vậy, sẽ thật tuyệt khi bạn tự xây dựng cho mình 1 công cụ và tuỳ ý sử dụng chúng cho bao nhiêu website, bao nhiêu endpoint mà bạn mong muốn.

Hiện tại, mình đang sử dụng bộ công cụ gồm: Prometheus, Blackbox Exporter, Alert Manager và Grafana để theo dõi trạng thái của các website

image.png

Trong bài viết này, mình sẽ chia sẻ cách mình tự xây dựng công cụ giám sát uptime như thế nào, đây là cấu trúc thư mục của project:

.
├── config
│ ├── alertmanager.yml
│ ├── blackbox
│ │ └── blackbox.yml
│ ├── grafana
│ │ └── provisioning
│ │ ├── dashboards
│ │ │ ├── Prometheus\ Blackbox\ Exporter-1653754328923.json
│ │ │ └── dashboard.yml
│ │ └── datasources
│ │ └── datasource.yml
│ ├── nginx
│ │ └── default.conf
│ ├── prometheus.yml
│ └── rules.yml
├── data
│ ├── alertmanager
│ ├── grafana
│ └── prometheus
│ └── docker-compose.yml
└── .env

nào mình cùng bắt đầu thôiiii.

Cài đặt Docker

Docker là nền tảng cung cấp cho các công cụ, service để các lập trình viên và người quản trị hệ thống có thể phát triển, thực thi, chạy các ứng dụng với containers. Việc sử dụng các Linux containers để triển khia ứng dụng được gọi là containerization, sử dụng container giúp dễ dàng hơn trong việc triển khai ứng dụng.

Ngoài ra, mình còn sử dụng thêm Docker Compose, là công cụ giúp định nghĩa và khởi chạy multi-container Docker applications. Với Compose, chúng ta sử dụng Compose file để cấu hình application’s services. Chỉ với một câu lệnh, mình có thể dễ dàng create và start toàn bộ các services phục vụ cho việc chạy ứng dụng.

Cách cài đặt 2 công cụ trên các bạn có thể tham khảo trực tiếp trên trang chủ của Docker:

Cài đặt Prometheus

Prometheus là gì ?

Prometheus là một dịch vụ theo dõi và cảnh báo về hệ thống. Đây là một dịch vụ mã nguồn mở (Open source) hoàn toàn miễn phí. SoundCloud đã khởi đầu xây dựng Prometheus từ năm 2012. Prometheus đã được rất nhiều hệ thống tin tưởng áp dụng. Dự án có một cộng đồng người đóng góp, phát triển rất tích cực.

Giờ đây Prometheus đã được tách khỏi SoundCloud và là một dự án mã nguồn mở độc lập. Năm 2016, Prometheus tham gia vào tổ chức CNCF (Cloud Native Computing Foundation) với vị trí được ưu tiên phát triển thứ hai sau K8s (Kubernetes).

Tính năng quan trọng nhất của Prometheus là thu thập thông số, dữ liệu từ các mục tiêu (dịch vụ) được nhắm đến theo khoảng thời gian nhất định đã được cài đặt trước. Ngoài ra còn các API khác thể hiện được kết quả, đánh giá bằng biểu thức quy tắc và đưa ra cảnh báo. Prometheus còn cung cấp một ngôn ngữ truy vấn rất mạnh PromQL, cực kì hữu ích khi giao tiếp với các dịch vụ monitor khác.

Cài đặt

Các công cụ mình sử dụng đều đã được đóng gói thành các Docker Image và publish trên Docker Hub thế nên đơn giản chúng ta chỉ cần sử dụng chúng vào trong file docker-compose.yml của mình, bổ sung thêm config cho từng công cụ.

Đầu tiên với Prometheus, chúng ta có file config đặt ở config/prometheus.yml như sau:

rule_files: - "/etc/prometheus/rules.yml" alerting: alertmanagers: - static_configs: - targets: - alertmanager:9093
scrape_configs:
- job_name: 'blackbox' scrape_interval: 10s metrics_path: /probe static_configs: - targets: - https://google.com - https://viblo.asia - https://viblo.asia/api/web-init-404 params: module: [http_2xx] relabel_configs: - source_labels: [ __address__ ] target_label: __param_target - source_labels: [ __param_target ] target_label: instance - target_label: __address__ replacement: "blackbox_exporter:9115"
Thuộc tính Ghi chú
rule_file Là mảng chứa thông tin là đường dẫn tới các điều kiện gửi cảnh báo của Alert Manager
alerting Định nghĩa cấu hình của instance Alert Manager
scrape_ configs Blackbox Exporter sẽ trả ra các metrics liên quan tới website, trong section này, chúng ta cần cấu hình cách Prometheus lấy chúng về
scrape_configs.*.static_configs Chứa các url mà chúng ta cần theo dõi
scrape_configs.*.metrics_path Endpoint mà Blackbox Exporter trả về metrics
scrape_configs.*.params.module Đây là các module của Blackbox Exporter
scrape_configs.*.relabel_configs Định nghĩa cho Prometheus viết lại các nhãn trước khi nó kéo metrics từ Blackbox về

Với rule_files là thông tin đường dẫn tới file cấu hình gửi cảnh báo của Alert Manager:

groups: - name: AllInstances rules: - alert: InstanceDown # Condition for alerting expr: up == 0 for: 5s # Annotation - additional informational labels to store more information annotations: title: 'Instance {{ $labels.instance }} down' description: '{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 seconds.' # Labels - additional labels to be attached to the alert labels: severity: 'critical'

Tiếp theo, chúng ta cần mount các file cấu hình trên vào service Prometheus trong Docker Compose nữa:

version: '2.2' networks: frontend: name: frontend services: prometheus: image: prom/prometheus restart: always command: - '--config.file=/etc/prometheus/prometheus.yml' - '--web.enable-lifecycle' labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-prometheus.rule=Host(`prometheus`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-prometheus.loadbalancer.server.port=9090 networks: - default volumes: - ./data/prometheus:/prometheus - ./config/prometheus.yml:/etc/prometheus/prometheus.yml - ./config/rules.yml:/etc/prometheus/rules.yml ports: - 9090:9090

Cài đặt Blackbox Exporter

Blackbox Exporter là một chương trình exporter cho phép gọi tới các endpoint thông qua các giao thức HTTP, HTTPS, DNS, TCPICMP. Điều này cũng có nghĩa bạn có thể sử dụng nó để monitor các endpoint bất kì, có sử dụng một trong các giao thức trên.

Với Blackbox Exporter, chúng ta cần cấu hình các module thực thi việc thăm dò tới các target được định nghĩa ở Prometheus. Do cơ chế Service Discovery, nên các target này được đặt ở Prometheus và ở Blackbox Exporter chúng ta chỉ cần cấu hình các module thôi

modules: http_2xx: http: fail_if_not_ssl: false ip_protocol_fallback: false method: GET no_follow_redirects: false preferred_ip_protocol: ip4 valid_http_versions: - HTTP/1.1 - HTTP/2.0 prober: http timeout: 15s 
Thuộc tính Ghi chú
modules Định nghĩa danh sách modules mà Blackbox Exporter sử dụng
http_2xx Là tên của module
modules.<tên modules>.http Cấu hình cho giao thức module này sử dụng, trong đó với giao thức HTTP ta có thể cấu hình method, điều kiện fail khi target không có SSL, cách resolve target,...
modules.<tên modules>.prober Prober thực thi việc thăm dò
modules.<tên modules>.timeout Thời gian timeout của mỗi lần thăm dò

Tiếp theo chúng ta bổ sung đoạn dưới đây vào file docker-compose.yml mà chúng ta đang xây dựng:

.... blackbox_exporter: image: prom/blackbox-exporter restart: always tty: true labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-backbox.rule=Host(`blackbox_exporter`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-backbox.loadbalancer.server.port=9115 ports: - 9115:9115 dns: 8.8.8.8 command: --config.file=/etc/blackbox/blackbox.yml volumes: - ./config/blackbox/:/etc/blackbox/ networks: - default

Cài đặt Alert Manager

Alert manager sẽ xử lý các cảnh báo gửi từ ứng dụng Prometheus. Thông qua các rules mà ta định nghĩa ở file cấu hình Prometheus. Alert Manager sẽ hoạt động theo:

  • Prometheus sẽ thu thập dữ liệu monitor là metrics từ các endpoint và lưu trong database Prometheus.
  • Bạn tạo các rule alert trong Prometheus, ví dụ như cấu hình của mình ở trên thì: Bất cứ 1 instance nào có trạng thái up == 0 trong 5s, endpoint down trong 5s.
  • Prometheus đẩy các alert này về Alert manager, nó sẽ xử lý việc trùng lặp alert, group các alert và gửi alert tới kênh thông báo mà bạn muốn: mail, telegram, slack,… Nội dung thông báo bạn có thể cấu hình như dưới đây trong file config/alertmanager.yml
global: resolve_timeout: 1m slack_api_url: 'https://hooks.slack.com/services/xxx' route: receiver: 'slack-notifications' receivers: - name: 'slack-notifications' slack_configs: - channel: 'test' send_resolved: true icon_url: https://avatars3.githubusercontent.com/u/3380462 title: |- [{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }} {{- if gt (len .CommonLabels) (len .GroupLabels) -}} {{" "}}( {{- with .CommonLabels.Remove .GroupLabels.Names }} {{- range $index, $label := .SortedPairs -}} {{ if $index }}, {{ end }} {{- $label.Name }}="{{ $label.Value -}}" {{- end }} {{- end -}} ) {{- end }} text: >- {{ range .Alerts -}} *Alert:* {{ .Annotations.title }}{{ if .Labels.severity }} - `{{ .Labels.severity }}`{{ end }} *Description:* {{ .Annotations.description }} *Details:* {{ range .Labels.SortedPairs }} • *{{ .Name }}:* `{{ .Value }}` {{ end }} {{ end }}
... alertmanager: image: prom/alertmanager restart: always labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-alertmanager.rule=Host(`alertmanager`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-alertmanager.loadbalancer.server.port=9093 ports: - 9093:9093 volumes: - ./data/alertmanager/:/etc/alertmanager/ - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml networks: - default depends_on: - prometheus

Với cách cấu hình như trên thì mỗi khi có downtime, 1 alert sẽ được gửi tới Slack channel image.png

Cài đặt Grafana

Cuối cùng để visualize các metrics của các website, chúng ta sử dụng Grafana. Grafana là một giao diện/dashboard theo dõi hệ thống (opensource), hỗ trợ rất nhiều loại dashboard và các loại graph khác nhau để người quản trị dễ dàng theo dõi.

Grafana là một nền tảng open-source chuyên phục vụ mục đích theo dõi và đánh giá các số liệu thu được. Grafana có thể truy xuất dữ liệu từ Graphite, Elasticsearch, OpenTSDB, Prometheus và InfluxDB. Grafana là một công cụ mạnh mẽ để truy xuất và biểu diễn dữ liệu dưới dạng các đồ thị và biểu đồ.

Mình sẽ cấu hình cho Grafana lấy data từ datasourcePrometheus

apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy orgId: 1 url: http://prometheus:9090 basicAuth: false isDefault: true editable: true

Trong thư mục config của Grafana, ngoài cấu hình datasource còn có cấu hình dashboard và 1 file dashboard mình đã export sẵn ra, bạn có thể sử dụng các Dashboard có sẵn từ Grafana cũng được. Tiếp theo là đến cấu hình của service Grafana trong docker-compose.yml

... grafana: image: grafana/grafana-enterprise restart: always tty: true labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-grafana.rule=Host(`grafana`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-grafana.loadbalancer.server.port=3000 ports: - ${PORT:-80}:3000 volumes: - ./data/grafana:/var/lib/grafana - ./config/grafana/provisioning:/etc/grafana/provisioning networks: - frontend - default

Test thử thôi

Sau các bước ở trên, chúng ta có 1 file docker-compose.yml hoàn chỉnh sẽ trông như này

version: '2.2' networks: frontend: name: frontend services: traefik: image: traefik:2.2 restart: always command: - --api.dashboard=true - --entrypoints.http.address=:80 - --providers.docker - --providers.docker.network=frontend - --providers.docker.watch=true - --providers.docker.exposedbydefault=false ports: - 8080:80 networks: - frontend labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-traefik.rule=Host(`traefik.${DOMAIN}`) - traefik.http.routers.${COMPOSE_PROJECT_NAME}-_@.com - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-traefik-dashboard.redirectRegex.regex=/ - traefik.http.middlewares.${COMPOSE_PROJECT_NAME}-traefik-dashboard.redirectRegex.replacement=/dashboard/ volumes: - /var/run/docker.sock:/var/run/docker.sock prometheus: image: prom/prometheus restart: always command: - '--config.file=/etc/prometheus/prometheus.yml' - '--web.enable-lifecycle' labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-prometheus.rule=Host(`prometheus`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-prometheus.loadbalancer.server.port=9090 networks: - default volumes: - ./data/prometheus:/prometheus - ./config/prometheus.yml:/etc/prometheus/prometheus.yml - ./config/rules.yml:/etc/prometheus/rules.yml ports: - 9090:9090 alertmanager: image: prom/alertmanager restart: always labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-alertmanager.rule=Host(`alertmanager`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-alertmanager.loadbalancer.server.port=9093 ports: - 9093:9093 volumes: - ./data/alertmanager/:/etc/alertmanager/ - ./config/alertmanager.yml:/etc/alertmanager/alertmanager.yml networks: - default depends_on: - prometheus blackbox_exporter: image: prom/blackbox-exporter restart: always tty: true labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-backbox.rule=Host(`blackbox_exporter`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-backbox.loadbalancer.server.port=9115 ports: - 9115:9115 dns: 8.8.8.8 command: --config.file=/etc/blackbox/blackbox.yml volumes: - ./config/blackbox/:/etc/blackbox/ networks: - default grafana: image: grafana/grafana-enterprise restart: always tty: true labels: - traefik.enable=true - traefik.http.routers.${COMPOSE_PROJECT_NAME}-grafana.rule=Host(`grafana`) - traefik.http.services.${COMPOSE_PROJECT_NAME}-grafana.loadbalancer.server.port=3000 ports: - ${PORT:-80}:3000 volumes: - ./data/grafana:/var/lib/grafana - ./config/grafana/provisioning:/etc/grafana/provisioning networks: - frontend - default

Ta chỉ cần chạy command cuối cùng là

$ docker-compose up -d

Để truy cập Grafana các bạn truy cập http://localhost/login image.png tài khoản mặc định là admin/admin. Sau khi đăng nhập bước đầu tiên là bạn cần đổi mật khẩu mặc định sang 1 mật khẩu an toàn hơn.

Từ giao diện Grafana, bạn chọn Dashboard > Home > Prometheus Blackbox Exporter là sẽ thấy được các dashboard hiển thị thông tin liên quan tới website, cái mà Prometheus đã thu thập được

image.png

Mỗi instance được thu thập các thông tin trạng thái Up/Down, thời gian phản hồi của trang, trạng thái của SSL,... bạn có thể tuỳ ý thêm các Panel, ngoài ra bạn có thể share dashboard để các thành viên khác cũng có thể theo dõi trạng thái của website cùng.

Tài liệu tham khảo

Bình luận

Bài viết tương tự

- vừa được xem lúc

Cài đặt WSL / WSL2 trên Windows 10 để code như trên Ubuntu

Sau vài ba năm mình chuyển qua code trên Ubuntu thì thật không thể phủ nhận rằng mình đã yêu em nó. Cá nhân mình sử dụng Ubuntu để code web thì thật là tuyệt vời.

0 0 374

- vừa được xem lúc

Phân quyền đơn giản với package Laravel permission

Như các bạn đã biết, phân quyền trong một ứng dụng là một phần không thể thiếu trong việc phát triển phần mềm, dù đó là ứng dụng web hay là mobile. Vậy nên, hôm nay mình sẽ giới thiệu một package có thể giúp các bạn phân quyền nhanh và đơn giản trong một website được viết bằng PHP với framework là L

0 0 421

- vừa được xem lúc

Sử dụng Swagger để xây dựng API documentation

Giới thiệu về Swagger. RESTful API là một tiêu chuẩn dùng trong việc thiết kế API cho các ứng dụng web (thiết kế Web services) để tiện cho việc quản lý các resource.

0 0 1k

- vừa được xem lúc

So sánh Interface và Abstract trong lập trình hướng đối tượng.

Tổng quan. Interface và Abstract class là 2 khái niệm cơ bản trong lập trình OOP.

0 0 48

- vừa được xem lúc

CURL và cách sử dụng trong PHP

Giới Thiệu. CURL là bộ thư viện được sử dụng để giúp thực hiện việc chuyển dữ liệu thông qua nhiều giao thức khác nhau (như HTTP, FPT...). Với giao thức HTTP, cURL hỗ trợ việc gửi dữ liệu sử dụng tất cả các phương thức hiện có như GET, POST, PUT, DELETE... cURL cũng hỗ trợ việc chuyền dữ liệu sử dụn

0 0 77

- vừa được xem lúc

Thêm dòng dữ liệu mới (MySQL) trong Laravel

Chào các bạn, Laravel hiện đang là hot trend trong "thế giới PHP". 1. Cấu hình cơ bản ban đầu. .

0 0 38