Access Hub Collector
Đồng bộ từ mã nguồn lúc 10:57, 03/10/2026
Skip to content
Áp dụng choLinux (binary, systemd) Sẵn sàngImage Docker Chưa cóGói .deb Chưa có

Hướng dẫn triển khai lên môi trường thực tế ​

Tài liệu này dẫn từng bước dựng hệ thống giám sát (Access Hub, Collector, Agent) trên máy thật. Mọi khóa cấu hình, cổng, cờ và mã thoát dưới đây lấy từ mã hiện tại (internal/config, cmd/collector, deploy/systemd, deploy/dev). Kiến trúc và lý do thiết kế xem 01 và 09.

35 phút đọcCập nhật 03/10/2026access-hub-collector, docs/14-production-deployment-guide.md

Trước khi bắt đầu

Máy Linux có systemd, khuyến nghị Ubuntu 22.04 hoặc 24.04 LTS, hoặc Rocky, Alma 9
Đồng bộ thời gian (chrony hoặc systemd-timesyncd) trên mọi node
Redis hoặc Valkey riêng cho collector, appendonly yes và maxmemory-policy noeviction
VictoriaMetrics vm-raw và vm-long, cùng vmalert cho rollup
Tên miền riêng cho agent với chứng chỉ TLS và load balancer 443/TCP
Token API của tài khoản dịch vụ có vai trò Monitoring Collector trong Access Hub (secrets/hub.token)
Token bảo vệ API admin của collector, tối thiểu 24 ký tự (secrets/admin.token)
Máy build có Go để dựng binary collector (make build)
Áp dụng choLinux (binary, systemd) Sẵn sàngImage Docker Chưa cóGói .deb Chưa có

0. Đọc trước: điều gì đã sẵn sàng, điều gì chưa ​

Thành phầnTrạng tháiHệ quả khi triển khai
Agent Linux (.deb, .rpm, install.sh, tar)Mã và gói xong, kiểm thử cục bộ. Chưa thử trên ma trận distro thật, chưa kýThử trên 1 máy mỗi distro trước khi cài hàng loạt. Gói chưa có chữ ký, install.sh đòi khóa công khai hoặc --allow-unsigned (mục 9.4)
Agent Windows (MSI, Authenticode)Chưa làm (AGT-7, giai đoạn 2)Chưa cài được Windows agent
Collector (ingest, worker, admin)COL-1 đến 7 xong, đã kiểm thử với Redis và VictoriaMetrics thậtChưa có image Docker, chưa có gói .deb. Triển khai bằng binary tĩnh và systemd (mục 6)
Collector: luật ngưỡng (COL-8), reload, renewLuật ngưỡng và POST /internal/v1/reload/rules xong. Chống nhiễu (COL-9: silence, flapping, group_down, reload/silences, reload/settings) xong, cần HUB-13 phía Access Hub. Renew token trả 503Cấu hình đổi bằng cách sửa tệp rồi khởi động lại cuốn chiếu
Access Hub phía monitoring (HUB-1 đến 18)Chưa xâyChưa có API /api/v1/monitoring/collector/*, chưa có trang Agents, chưa có bộ tạo License. Xem mục 8
Bus NATS JetStreamChưa làmBus giữa ingest và worker là Redis Streams

Hệ quả quan trọng: vì Access Hub chưa có phần monitoring, hiện chưa thể chạy đầu-cuối thật (enroll agent, đồng bộ registry, nhận alert). Có thể dựng sẵn toàn bộ hạ tầng (Redis, VictoriaMetrics, Collector, LB) và kiểm tra bằng mockhub như môi trường dev, sau đó chờ HUB-* để nối vào Access Hub thật. Đừng đưa mockhub vào production.

1. Sơ đồ triển khai mẫu (production nhỏ) ​

mermaid
flowchart LR
    AG[Agent nhieu may] -->|HTTPS 443| LB[LB TLS agents.example.com]
    LB --> I1[collector ingest 1]
    LB --> I2[collector ingest 2]
    I1 --> R[(Redis master va replica)]
    I2 --> R
    R --> W1[collector worker 1]
    R --> W2[collector worker 2]
    W1 --> VR[(vm-raw 30 ngay)]
    W2 --> VR
    VA[vmalert] --> VR
    VA --> VL[(vm-long 400 ngay)]
    W1 -->|HTTPS| HUB[Access Hub]
    W2 -->|HTTPS| HUB
    HUB -->|HTTPS noi bo, admin token| AD[collector admin]
    AD --> R
    AD --> VR
    AD --> VL

Vai trò tiến trình collector: ingest (nhận dữ liệu agent, đẩy vào bus), worker (đọc bus, ghi VictoriaMetrics, phát hiện agent mất kết nối, gửi sự kiện cho Access Hub), admin (API nội bộ cho Access Hub). Mỗi tiến trình một collector_id riêng. Có thể gộp (roles: [all]) cho hệ thống rất nhỏ, nhưng khi tách vai trò thì bắt buộc có Redis (registry, presence, bus, outbox dùng chung).

2. Kích thước tài nguyên ​

Con số khởi điểm, hiệu chỉnh sau khi đo tải thật (xem 08).

Quy môSố máy giám sátNode collectorRedisVictoriaMetrics
Nhỏđến 1.0002 ingest + 2 worker + 1 admin, mỗi tiến trình 0,5 đến 1 vCPU, 512 MB1 master + 1 replica, 2 vCPU, 4 GB, đĩa SSD1 máy cho vm-raw và vm-long: 4 vCPU, 16 GB, SSD 200 GB
Vừađến 10.000ingest x 3 đến 4, worker x 4, admin x 2Sentinel 3 node, 8 GBvm-raw và vm-long tách máy, SSD 1 TB
Lớntrên 10.000Theo 08Sentinel hoặc ClusterCụm VictoriaMetrics hoặc nhiều instance

Quy đổi tham khảo: agent đẩy khoảng 4 lần mỗi phút (mỗi 30 giây mỗi lô, giới hạn mặc định metrics_per_minute: 4, metrics_burst: 10). Mỗi agent tối đa 500 series (ingest.limits.max_series).

Hệ điều hành khuyến nghị: Ubuntu 22.04 hoặc 24.04 LTS, hoặc Rocky, Alma 9. Đồng bộ thời gian bắt buộc (chrony hoặc systemd-timesyncd): collector từ chối mẫu cũ hơn 24 giờ hoặc vượt tương lai 5 phút (max_point_age, max_point_future), lệch đồng hồ làm mất dữ liệu.

3. Mạng, tên miền, tường lửa ​

  1. Tên miền công khai riêng cho agent, ví dụ agents.example.com (không dùng chung tên miền giao diện Access Hub). Cấp chứng chỉ TLS từ CA công khai (Let's Encrypt hoặc CA doanh nghiệp mà mọi máy agent tin cậy). Nếu dùng CA nội bộ, đặt ca_file trong agent.yaml (gói cài đã có khóa này).
  2. Tên nội bộ cho API admin và cho Redis, VictoriaMetrics.
  3. Tường lửa (mặc định chặn, chỉ mở các luồng sau):
TừĐếnCổngMục đích
Internet (các máy agent)LB443/tcpAgent đẩy dữ liệu (/agent/v1/*)
LBcollector ingest8443/tcp (hoặc cổng riêng mỗi node)Chuyển tiếp
LBcollector ops của ingest9100/tcpKiểm tra sức khỏe chủ động /readyz
collector (mọi role)Redis6379/tcpRegistry, bus, outbox
worker, adminvm-raw 8428, vm-long 8429tcpGhi, đọc, xóa
vmalertvm-raw, vm-longtcpRollup
worker, ingest, adminAccess Hub443/tcpSự kiện, đồng bộ registry, tra cứu
Access Hubcollector admin9101/tcpAPI nội bộ, qua TLS hoặc mạng riêng
Prometheus của bạn (tùy chọn)collector ops9100/tcpThu /metrics của collector

Không bao giờ mở Redis, VictoriaMetrics, admin (9101), ops (9100) ra Internet. VictoriaMetrics bản OSS không có xác thực, phải đặt sau mạng riêng hoặc thêm proxy xác thực.

4. Redis (hoặc Valkey) ​

Dùng một instance riêng cho collector, không dùng chung Redis của Access Hub (registry, bus và outbox cần noeviction, còn cache của Access Hub thường cho phép loại bỏ).

Mẫu /etc/redis/redis-accesshub.conf (đối chiếu deploy/dev/redis/master.conf.tmpl):

conf
bind 10.0.0.10            # IP nội bộ, không 0.0.0.0
port 6379
protected-mode yes
dir /var/lib/redis-accesshub
save 900 1
save 300 100
save 60 10000
appendonly yes
appendfsync everysec
appenddirname "appendonlydir"
aof-load-truncated yes    # nạp được AOF bị cụt đuôi thay vì từ chối khởi động
aof-use-rdb-preamble yes  # AOF rewrite dùng phần đầu RDB, nạp nhanh hơn
maxmemory 4gb             # dưới RAM máy khoảng 20 phần trăm
maxmemory-policy noeviction
tcp-keepalive 60
requirepass <mat-khau-dai-ngau-nhien>      # tốt nhất trong tệp include 0600
masterauth  <cung-mat-khau>                # trên replica

Yêu cầu và lý do:

  • appendonly yes: outbox sự kiện (gửi Access Hub) và bus nằm trong Redis, độ bền của chúng phụ thuộc AOF. Không tắt.
  • save ... (RDB snapshot) giữ bật song song với AOF: dump.rdb là nguồn khôi phục thứ hai khi AOF hỏng (mục 4.2). Không đặt save "".
  • aof-load-truncated yes, aof-use-rdb-preamble yes: ghi rõ dù là mặc định của Redis 7, để không ai vô tình tắt.
  • maxmemory-policy noeviction: không được loại bỏ khóa registry, bus, outbox. Khi đầy, ghi lỗi (ingest trả 503, agent đệm WAL) tốt hơn mất dữ liệu lặng lẽ.
  • Hệ thống: sysctl vm.overcommit_memory=1 (ghi vào /etc/sysctl.d/), tắt Transparent Huge Pages.
  • Replica: replicaof <master> 6379. Có replica chưa phải HA tự động. Muốn failover tự động dùng Sentinel (chưa được collector hỗ trợ trực tiếp, collector nối một redis.addr, nên đặt Sentinel kèm VIP hoặc proxy, xem 08).
  • TLS Redis: đặt redis.tls.enabled: true, ca_file, server_name (tùy chọn cert_file, key_file). insecure_skip_verify chỉ dùng dev.
  • Tiền tố khóa redis.prefix (mặc định ah:). Dùng chung một Redis cho nhiều môi trường thì đặt tiền tố khác nhau.
  • Sao lưu: chép dump.rdb và thư mục AOF định kỳ. Mất Redis không mất dữ liệu nghiệp vụ (registry nạp lại từ Access Hub), nhưng mất sự kiện trong outbox chưa gửi.

Kiểm tra: redis-cli -h 10.0.0.10 -a "$PASS" ping trả PONG, INFO persistence có aof_enabled:1.

4.1 Unit systemd cho Redis: kiểm tra AOF trước khi khởi động, không lặp crash vô hạn ​

Sự cố 2026-10-02 (máy dev mirror production): đĩa đầy làm hỏng tệp appendonly.aof.*.incr.aof. Redis 7 từ chối nạp AOF hỏng, unit có Restart=on-failure, RestartSec=2 và không có giới hạn khởi động nên redis-master crash-loop khoảng 7 giờ, ingest không ghi được bus. Từ bản này unit Redis có ba lớp bảo vệ:

  1. ExecStartPre= chạy deploy/redis/aof-preflight.sh (cài thành redis-aof-preflight) trên thư mục dữ liệu Redis.
  2. StartLimitIntervalSec=600, StartLimitBurst=5: tối đa 5 lần khởi động trong 10 phút, sau đó unit chuyển failed và dừng hẳn. RestartSec=5.
  3. OnFailure=accesshub-unit-failed@%n.service: ghi một dòng CRITICAL (syslog user.crit, thẻ accesshub-unit-failed) kèm lệnh cần chạy. Watchdog của Access Hub vẫn cảnh báo qua trạng thái collector.

Hành vi của preflight (aof-preflight.sh <dir> [appenddirname]):

Tình huốngHành độngKhởi động Redis
redis-check-aof báo AOF hợp lệKhông làm gìCó
AOF hỏng, phần đuôi hỏng (diff) không quá AOF_FIX_MAX_PCT (mặc định 5) phần trăm kích thước tệp hỏngChép cả thư mục sang appendonlydir.bak-<thời điểm>, rồi redis-check-aof --fix (tự trả lời y), kiểm tra lạiCó
AOF hỏng nặng, hoặc không chép được bản sao lưu (đĩa đầy), hoặc --fix không thành côngĐổi tên thư mục sang appendonlydir.damaged-<thời điểm>, tạo appendonlydir mới có tệp base là bản chép dump.rdb (đã qua redis-check-rdb)Có, từ snapshot RDB mới nhất
AOF hỏng và không có dump.rdb hợp lệKhông đụng gì, thoát lỗiKhông (unit dừng sau 5 lần, có dòng CRITICAL)
Không có manifest AOF nhưng có dump.rdbTạo appendonlydir từ dump.rdb như trênCó
Không có AOF và không có dump.rdbKhông làm gì (máy mới)Có

Preflight không bao giờ xóa dữ liệu, chỉ chép và đổi tên. Lý do phải tạo AOF từ dump.rdb thay vì chỉ dời AOF đi: với appendonly yes, Redis 7 không thấy AOF sẽ bỏ qua dump.rdb và khởi động rỗng (đã thử với 7.0.15), rồi lần save sau ghi đè dump.rdb bằng dữ liệu rỗng. Nhật ký preflight nằm trong journal của unit Redis (lọc chữ redis-aof-preflight), dòng hỏng có mức crit. Các thư mục .bak-*, .damaged-* không tự dọn: kiểm tra xong thì xóa tay để lấy lại đĩa.

Production với gói redis-server của distro ([email protected] đọc /etc/redis/redis-accesshub.conf), thêm drop-in thay vì sửa unit gốc:

bash
sudo install -m 0755 deploy/redis/aof-preflight.sh /usr/local/bin/redis-aof-preflight
sudo install -m 0644 deploy/systemd/[email protected] /etc/systemd/system/
sudo mkdir -p /etc/systemd/system/[email protected]
sudo tee /etc/systemd/system/[email protected]/10-accesshub-hardening.conf <<'CONF'
[Unit]
StartLimitIntervalSec=600
StartLimitBurst=5
OnFailure=accesshub-unit-failed@%n.service

[Service]
Environment=AOF_FIX_MAX_PCT=5
ExecStartPre=/usr/local/bin/redis-aof-preflight /var/lib/redis-accesshub
Restart=on-failure
RestartSec=5
TimeoutStartSec=600
CONF
sudo systemctl daemon-reload

Preflight chạy cùng User= và sandbox của unit Redis nên cần quyền ghi vào thư mục dữ liệu (ReadWritePaths của unit gốc phải gồm /var/lib/redis-accesshub). Tăng TimeoutStartSec nếu AOF lớn nhiều GB (kiểm tra và chép tốn thời gian). Bản system unit của [email protected] chỉ cần bỏ --user trong thông báo. Drop-in này chưa được diễn tập trên máy production thật, thử trên máy thử trước.

4.2 Runbook khôi phục Redis khi AOF hỏng ​

Dấu hiệu: unit Redis failed hoặc activating (auto-restart), journal có Bad file format reading the append only file hoặc dòng AOF CORRUPTED của preflight, ingest /readyz 503, monitoring:check-collectors của Access Hub báo collector lỗi.

Trường hợp thường gặp, preflight tự xử lý: xem journal, xác nhận Redis đã lên, so DBSIZE với trước sự cố, kiểm tra replica (INFO replication có master_link_status:up). Dữ liệu ghi sau lần save cuối cùng (tối đa vài phút theo save 300 100) chỉ còn trong appendonlydir.damaged-*.

Xử lý tay (cách đã dùng ngày 2026-10-03, trước khi có preflight):

  1. Giải phóng đĩa trước (nguyên nhân gốc là đĩa đầy): df -h, dọn đến khi còn trên 20 phần trăm trống.
  2. Dừng unit Redis. Đổi tên thư mục AOF hỏng, không xóa: mv appendonlydir appendonlydir.corrupt-$(date +%Y%m%d).
  3. Kiểm tra snapshot: redis-check-rdb dump.rdb phải báo RDB looks OK.
  4. Khởi động Redis với AOF tắt để nạp dump.rdb: sửa tạm appendonly no trong conf rồi start unit (hoặc chạy tay redis-server <conf> --appendonly no). Kiểm tra DBSIZE.
  5. Bật lại AOF khi đang chạy: redis-cli CONFIG SET appendonly yes. Redis viết AOF mới từ dữ liệu trong bộ nhớ; chờ INFO persistence có aof_rewrite_in_progress:0 và aof_last_bgrewrite_status:ok.
  6. Trả conf về appendonly yes, restart unit. Kiểm tra DBSIZE, replica nối lại, ingest hết lỗi Redis, php artisan monitoring:check-collectors báo 0 vấn đề.
  7. Muốn cứu thêm dữ liệu sau snapshot: chép thư mục .damaged-* (hoặc .corrupt-*) sang máy thử, chạy redis-check-aof --fix trên bản chép rồi xem các lệnh còn đọc được. Thường không cần: registry nạp lại từ Access Hub, chỉ outbox chưa gửi là có thể mất.

Unit đã dừng do giới hạn khởi động: sau khi sửa, systemctl reset-failed <unit> && systemctl start <unit> (user unit thêm --user).

5. VictoriaMetrics và vmalert ​

Hai instance: vm-raw giữ mẫu thô, vm-long giữ rollup (docs/04-data-model.md). Tải bản victoria-metrics-prod và vmalert-prod từ trang phát hành chính thức của VictoriaMetrics, kiểm tra checksum, cài vào /usr/local/bin. Tạo user victoriametrics không đăng nhập.

/etc/systemd/system/vm-raw.service (đối chiếu deploy/systemd/accesshub-vm-raw.service):

ini
[Unit]
Description=VictoriaMetrics vm-raw, raw samples 30d
After=network-online.target
Wants=network-online.target

[Service]
User=victoriametrics
ExecStart=/usr/local/bin/victoria-metrics-prod \
  -storageDataPath=/var/lib/vm-raw \
  -retentionPeriod=30d \
  -httpListenAddr=10.0.0.20:8428 \
  -memory.allowedPercent=40 \
  -selfScrapeInterval=30s
Restart=on-failure
RestartSec=3
TimeoutStopSec=60
LimitNOFILE=65535
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
ReadWritePaths=/var/lib/vm-raw
ProtectKernelTunables=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6

[Install]
WantedBy=multi-user.target

vm-long.service tương tự: -storageDataPath=/var/lib/vm-long, -retentionPeriod=400d, -httpListenAddr=10.0.0.20:8429.

/etc/systemd/system/vmalert.service:

ini
[Unit]
Description=vmalert rollup vm-raw to vm-long
After=vm-raw.service vm-long.service
Wants=vm-raw.service vm-long.service

[Service]
User=victoriametrics
ExecStart=/usr/local/bin/vmalert-prod \
  -datasource.url=http://10.0.0.20:8428 \
  -remoteWrite.url=http://10.0.0.20:8429 \
  -rule=/etc/accesshub-collector/vmalert/rules.yml \
  -notifier.blackhole \
  -evaluationInterval=1m \
  -httpListenAddr=127.0.0.1:8880
Restart=on-failure
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=yes

[Install]
WantedBy=multi-user.target

Tệp luật rollup sinh từ chính binary collector đã cài: /usr/local/bin/collector -rollup-rules > /etc/accesshub-collector/vmalert/rules.yml (5 phút và 1 giờ, avg, min, max, last, cho mọi chỉ số trong catalog nhúng của đúng phiên bản đó; bản dev dùng deploy/dev/gen-vmalert-rules.sh). Xem kỹ đầu ra trước khi đặt. Mỗi lần nâng cấp collector có thêm chỉ số, sinh lại tệp và nạp lại vmalert (systemctl reload vmalert hoặc kill -HUP, hoặc curl -X POST http://<vmalert>/-/reload); kiểm tra curl -s http://<vmalert>/api/v1/rules không có lastError. Không giữ tệp luật cũ: chỉ số mới sẽ không có rollup và biểu đồ khoảng dài của chỉ số đó trống sau 7 ngày (collector chỉ đọc lại vm-raw khi khoảng còn trong 30 ngày).

Cấu hình collector (vai trò admin) phải có cả tsdb.url (vm-raw) và tsdb.long_url (vm-long): khi thiếu long_url, API series chỉ nhận khoảng tối đa 31 ngày và luôn đọc vm-raw.

Retention theo gói (Q17, ADR 0016) chạy ở vai trò admin, bật mặc định:

yaml
tsdb:
  retention:
    enforce: true          # xóa vật lý dữ liệu ngoài retention của gói (đọc luôn bị cắt dù tắt)
    dry_run: false         # true: chỉ ghi log những ngày sẽ xóa (nên bật vài ngày khi triển khai lần đầu)
    sweep_interval: 1h
    first_seen: 24h        # chờ trước lần xóa đầu với công ty mới thấy
    force_merge: true      # gọi /internal/force_merge cho phân vùng tháng vừa bị xóa, tối đa 1 lần mỗi ngày

Nếu đặt proxy trước VictoriaMetrics, phải cho collector đi qua /api/v1/label/*/values, /api/v1/export, /api/v1/admin/tsdb/delete_series và /internal/force_merge ở cả vm-raw và vm-long. Theo dõi ahc_retention_last_sweep_timestamp_seconds (cảnh báo nếu cũ hơn 3 giờ), ahc_retention_errors_total, ahc_retention_days_deleted_total và mục retention của GET /internal/v1/status. force_merge ghi lại cả phân vùng tháng: chừa IO và dung lượng trống bằng cỡ phân vùng lớn nhất. Xóa là không hoàn tác: sao lưu vmbackup hằng ngày là cách duy nhất để khôi phục khi Access Hub gửi nhầm chính sách.

Lưu ý vận hành:

  • Đĩa: dự trù dung lượng theo số series x độ phủ x retention. Theo dõi vm_free_disk_space_bytes; VictoriaMetrics cần trống tối thiểu 20 phần trăm đĩa để merge.
  • VictoriaMetrics ẩn 30 giây gần nhất khỏi truy vấn (-search.latencyOffset), nên giá trị "mới nhất" trễ tới 30 giây là bình thường.
  • Collector ghi bằng /api/v1/import (JSON line), không phải remote-write. Xóa dữ liệu công ty hoặc máy chủ dùng /api/v1/admin/tsdb/delete_series của vm-raw và vm-long; nếu đặt proxy phía trước VictoriaMetrics thì không được chặn đường dẫn này.
  • Sao lưu: dùng vmbackup hoặc snapshot (/snapshot/create) theo lịch, chép ra ngoài. Khôi phục bằng vmrestore. Đây là dữ liệu duy nhất của hệ thống giám sát không thể tái tạo từ Access Hub.
  • Nhiều vmalert trùng lặp gây ghi trùng rollup (vô hại nhưng tốn): chỉ chạy một, hoặc hai instance HA có cùng -rule và -remoteWrite.url đã hỗ trợ dedupe (-dedup.minScrapeInterval ở vm-long).

6. Collector ​

6.1 Cài binary ​

Trên máy build (Go đã cài, xem go.mod) hoặc trong CI:

bash
git checkout <tag-phat-hanh>
make build                 # tạo ./bin/collector, CGO_ENABLED=0, nhúng phiên bản bằng ldflags
./bin/collector -version
sha256sum bin/collector > bin/collector.sha256

Nếu máy build không có make, chạy tương đương: CGO_ENABLED=0 go build -trimpath -ldflags "-s -w" -o bin/collector ./cmd/collector. Chép binary sang các node, kiểm checksum, đặt /usr/local/bin/accesshub-collector (root:root, 0755). Giữ phiên bản cũ kế bên (accesshub-collector-<phien-ban>, liên kết tên ngắn) để quay lui nhanh.

Tạo user và thư mục:

bash
sudo useradd --system --no-create-home --shell /usr/sbin/nologin accesshub-collector
sudo install -d -o root -g accesshub-collector -m 0750 /etc/accesshub-collector /etc/accesshub-collector/secrets /etc/accesshub-collector/tls

6.2 Bí mật ​

Mỗi bí mật một tệp 0640 (chủ root, nhóm accesshub-collector), không đặt trong repo, không in log:

TệpNội dungGhi chú
secrets/redis.passwordMật khẩu Redis
secrets/hub.tokenToken dịch vụ của user có vai trò Monitoring Collector trong Access HubCó khi HUB-2 xong (mục 8)
secrets/admin.tokenToken bảo vệ API adminTối thiểu 24 ký tự, sinh: openssl rand -base64 36

Biến môi trường AHC_* (xem mục 6.6) ghi đè YAML, có dạng _FILE cho token và mật khẩu.

6.3 Cấu hình từng vai trò ​

Khóa chưa liệt kê dùng mặc định trong internal/config/config.go. Khóa lạ trong YAML là lỗi (KnownFields), nên gõ sai sẽ bị báo ngay khi -check.

/etc/accesshub-collector/ingest.yaml (mỗi node ingest):

yaml
collector_id: prod-ingest-1        # duy nhất toàn hệ thống, hoặc đặt bằng AHC_COLLECTOR_ID
roles: [ingest]
log: { level: info, format: json }
ops:
  listen: 10.0.1.11:9100           # LB phải tới được để kiểm tra /readyz
ingest:
  listen: 10.0.1.11:8443           # HTTP thuần sau LB, hoặc kèm tls_cert_file và tls_key_file
  public_url: https://agents.example.com
  trusted_proxies: [10.0.1.0/24]   # mạng của LB, để lấy IP thật từ X-Forwarded-For
  checks_sync_interval: 1m         # chu kỳ kéo check trung tâm từ Access Hub (COL-20)
  limits:
    max_body_bytes: 1048576
    max_decoded_bytes: 8388608
    max_series: 500
    max_series_per_company: 0      # 0 = không giới hạn theo công ty; đặt khi một công ty có thể làm phình TSDB (tính theo từng node ingest)
hub:
  base_url: https://hub.example.com
  token_file: /etc/accesshub-collector/secrets/hub.token
  timeout: 10s
redis:
  addr: 10.0.0.10:6379
  password_file: /etc/accesshub-collector/secrets/redis.password
  prefix: "ah:"
shutdown:
  drain_delay: 10s                 # /readyz trả 503 trước, để LB rút node rồi mới dừng nhận
  grace: 25s

/etc/accesshub-collector/worker.yaml (mỗi node worker):

yaml
collector_id: prod-worker-1
roles: [worker]
log: { level: info, format: json }
ops:
  listen: 10.0.1.21:9100
hub:
  base_url: https://hub.example.com
  token_file: /etc/accesshub-collector/secrets/hub.token
redis:
  addr: 10.0.0.10:6379
  password_file: /etc/accesshub-collector/secrets/redis.password
tsdb:
  url: http://10.0.0.20:8428
  long_url: http://10.0.0.20:8429
alerting:
  agent_interval: 30s              # khớp chu kỳ agent. Ngưỡng mất kết nối = max(3 x agent_interval, down_min)
  down_min: 90s
  rules_sync_interval: 1m          # chu kỳ kéo luật từ Access Hub (COL-8)
  silences_sync_interval: 1m       # chu kỳ kéo silence từ Access Hub (COL-9)
  flap_transitions: 4              # số lần chuyển trạng thái để vào flapping, 0 tắt (COL-9)
  flap_window: 30m
  flap_stable: 30m
  group_down:                      # gom sự cố diện rộng (COL-9), nhiều worker thì chỉ một worker bật
    enabled: true
    min: 5
    ratio: 0.30
    window: 60s
    # companies:                   # ghi đè theo công ty khi Access Hub không đặt
    #   "<company_id>": {min: 8, ratio: 0.5, window: 120s}
  rules_state_interval: 30s        # chu kỳ snapshot trạng thái đánh giá
  no_data_after: 5m                # series im lặng quá mức này thì áp no_data
  rules_dir: /var/lib/accesshub-collector/rules  # snapshot tệp khi không dùng Redis
shutdown:
  drain_delay: 0s
  grace: 25s

/etc/accesshub-collector/admin.yaml (1 hoặc 2 node):

yaml
collector_id: prod-admin-1
roles: [admin]
log: { level: info, format: json }
ops:
  listen: 127.0.0.1:9100
admin:
  listen: 10.0.1.31:9101           # chỉ mạng nội bộ Access Hub gọi tới được
  token_file: /etc/accesshub-collector/secrets/admin.token
hub:
  base_url: https://hub.example.com
  token_file: /etc/accesshub-collector/secrets/hub.token
redis:
  addr: 10.0.0.10:6379
  password_file: /etc/accesshub-collector/secrets/redis.password
tsdb:
  url: http://10.0.0.20:8428
  long_url: http://10.0.0.20:8429

API admin hiện chỉ chạy HTTP (không có tls_cert_file). Đặt nó trên mạng riêng hoặc đặt một reverse proxy TLS phía trước, đừng để bearer token đi qua mạng không tin cậy.

Các nhóm khóa tinh chỉnh (YAML): ingest.limits.* (giới hạn body, số điểm, tốc độ theo loại request), bus.{queue_per_shard,readers,block,claim_idle}, outbox.{backend,batch_max,flush_interval,backoff_min,backoff_max,retention}, redis.cache_ttl, worker.{shards,shard_count,shard_index} (nhiều worker dùng chung Redis phải đặt shard_count và shard_index riêng, xem docs/04), tsdb.{timeout,max_batch_samples,max_batch_wait,retry_max}, hub.{sync_interval,lookup_per_second}. Đổi mặc định khi có số liệu đo.

6.4 Kiểm tra cấu hình ​

bash
sudo -u accesshub-collector /usr/local/bin/accesshub-collector -check -config /etc/accesshub-collector/worker.yaml
echo $?     # 0 hợp lệ, 3 cấu hình sai (2 sai cú pháp dòng lệnh, 1 lỗi chung)

Lưu ý cảnh báo: node chỉ có role ingest không cần tsdb, và sẽ không báo thiếu tsdb.url. Node worker hoặc admin thiếu tsdb.url bị cảnh báo.

6.5 Unit systemd ​

Dùng các unit mẫu deploy/systemd/accesshub-collector-{ingest@,worker@,admin}.service làm gốc, sửa cho máy thật: bỏ %h (đường dẫn home dev) thành /etc/accesshub-collector/... và /usr/local/bin/..., chuyển từ user unit sang system unit (thêm User=accesshub-collector, WantedBy=multi-user.target), bỏ phụ thuộc accesshub-mockhub.service. Ví dụ /etc/systemd/system/accesshub-collector-ingest.service:

ini
[Unit]
Description=Access Hub Collector ingest (role ingest)
After=network-online.target
Wants=network-online.target

[Service]
User=accesshub-collector
Group=accesshub-collector
EnvironmentFile=-/etc/accesshub-collector/ingest.env
ExecStartPre=/usr/local/bin/accesshub-collector -check -config /etc/accesshub-collector/ingest.yaml
ExecStart=/usr/local/bin/accesshub-collector -config /etc/accesshub-collector/ingest.yaml
Restart=on-failure
RestartSec=3
TimeoutStopSec=45
LimitNOFILE=65535
NoNewPrivileges=yes
PrivateTmp=yes
PrivateDevices=yes
ProtectSystem=strict
ProtectHome=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
MemoryMax=1G

[Install]
WantedBy=multi-user.target

TimeoutStopSec phải lớn hơn shutdown.drain_delay + shutdown.grace (10 + 25 = 35 giây, đặt 45). Nhiều node cùng một máy thì dùng unit mẫu @ và tệp env riêng mỗi instance đặt AHC_COLLECTOR_ID, AHC_OPS_LISTEN, AHC_INGEST_LISTEN khác nhau.

Khởi động: systemctl daemon-reload && systemctl enable --now accesshub-collector-worker accesshub-collector-admin accesshub-collector-ingest (thứ tự: Redis và VictoriaMetrics trước, rồi worker và admin, cuối cùng ingest, rồi mới thêm vào LB).

6.6 Biến môi trường ​

AHC_CONFIG, AHC_ROLES, AHC_COLLECTOR_ID, AHC_LOG_LEVEL, AHC_OPS_LISTEN, AHC_HUB_URL, AHC_HUB_TOKEN (hoặc _FILE), AHC_TSDB_URL, AHC_TSDB_LONG_URL, AHC_REDIS_ADDR, AHC_REDIS_USERNAME, AHC_REDIS_PASSWORD (hoặc _FILE), AHC_REDIS_PREFIX, AHC_REDIS_DB, AHC_REDIS_TLS, AHC_REDIS_TLS_CA_FILE, AHC_INGEST_LISTEN, AHC_INGEST_TLS_CERT_FILE, AHC_INGEST_TLS_KEY_FILE, AHC_INGEST_PUBLIC_URL, AHC_ADMIN_LISTEN, AHC_ADMIN_TOKEN (hoặc _FILE), AHC_BUS_BACKEND, AHC_OUTBOX_BACKEND, AHC_OUTBOX_DIR.

Cổng mặc định: ops 127.0.0.1:9100 (/healthz, /readyz, /metrics), admin 127.0.0.1:9101, ingest :8443.

7. Load balancer cho agent ​

Yêu cầu: TLS 1.2 trở lên (khuyến nghị 1.2 và 1.3), HTTP/2 bật, tới tên miền agents.example.com, chuyển tiếp HTTP thuần tới các node ingest, thêm X-Forwarded-For và X-Forwarded-Proto, giới hạn body 1 MiB (bằng max_body_bytes), timeout đọc 30 giây, thử lại sang node khác khi lỗi kết nối, timeout, 503.

Kiểm tra sức khỏe chủ động vào http://<node>:9100/readyz (khác môi trường dev chỉ có kiểm tra thụ động). Dùng HAProxy, Nginx Plus, F5, hoặc LB của nhà cung cấp đám mây. /readyz trả 503 khi đang tắt êm (drain_delay), nên nâng cấp cuốn chiếu không rớt request.

Ví dụ HAProxy (đoạn chính):

conf
frontend agents
    bind :443 ssl crt /etc/haproxy/certs/agents.example.com.pem alpn h2,http/1.1 ssl-min-ver TLSv1.2
    option forwardfor
    http-request set-header X-Forwarded-Proto https
    default_backend collector_ingest

backend collector_ingest
    balance roundrobin
    option httpchk GET /readyz
    http-check expect status 200
    default-server check port 9100 inter 3s fall 2 rise 2
    timeout server 30s
    retry-on conn-failure empty-response 503
    retries 2
    server ingest1 10.0.1.11:8443
    server ingest2 10.0.1.12:8443

Tham khảo thêm cấu hình Nginx dev ở deploy/dev/nginx/nginx.conf.tmpl (giới hạn body, timeout, proxy_next_upstream). Nếu Nginx OSS, kiểm tra thụ động (max_fails) là mức tối thiểu, chấp nhận được nhưng chậm phát hiện hơn.

Kiểm tra LB:

bash
curl -sS -o /dev/null -w '%{http_code}\n' https://agents.example.com/agent/v1/config   # không token: mong đợi 401 (không phải 502 hay timeout)
openssl s_client -connect agents.example.com:443 -servername agents.example.com </dev/null 2>/dev/null | openssl x509 -noout -dates -issuer

Đặt nhắc hạn chứng chỉ ít nhất 30 ngày trước khi hết hạn. Hết hạn chứng chỉ là nguyên nhân hàng đầu khiến mọi agent mất tín hiệu cùng lúc.

8. Phía Access Hub ​

Phần monitoring trong Access Hub chưa được xây. Bảng dưới là những gì cần có khi HUB-* xong, để chuẩn bị sớm (chi tiết 06).

ViệcMục HUBTrạng thái
Bảng, model, API /api/v1/monitoring/collector/* (enroll, agents, seen, heartbeat, events)HUB-1, 3, 4, 5Chưa
Quyền monitoring.* và vai trò Monitoring CollectorHUB-2Chưa
Sinh License, giao diện Agents, lệnh càiHUB-6, 7Chưa
Client gọi admin API của collector (MonitoringCollectorClient)HUB-8Chưa

Khi làm xong, các bước triển khai phía Access Hub:

  1. Chạy migration trên môi trường thực (qua quy trình release thường lệ, sao lưu DB trước).
  2. Tạo user dịch vụ (không đăng nhập được), gán vai trò Monitoring Collector, tạo token API, ghi vào secrets/hub.token của từng node collector. Mỗi node có thể dùng chung một token hoặc token riêng (khuyến nghị riêng để thu hồi từng node).
  3. Cấu hình Access Hub trỏ tới collector: URL admin (https://collector-admin.internal:9101) và admin.token. Đặt vào cài đặt hoặc .env của Access Hub (tên khóa do HUB-8 quy định), rồi php artisan config:cache và php artisan queue:restart.
  4. Đảm bảo Access Hub với MySQL read/write split đọc-sau-ghi đúng: sau enroll, bản ghi agent phải đọc từ node ghi (xem 06).
  5. Mở tường lửa hai chiều theo mục 3.

Trong thời gian chờ, đừng đặt hub.base_url trỏ Access Hub hiện tại: API monitoring chưa tồn tại, collector sẽ liên tục lỗi 404 và outbox đầy. Dùng mockhub chỉ trên dev.

9. Agent ​

9.1 Chuẩn bị ​

  1. Có https://agents.example.com hoạt động (mục 7) và hạ tầng trả lời.
  2. Có License dùng một lần (HUB-6). Mỗi token gắn công ty và có thể gắn máy chủ. Token không đi qua dòng lệnh.
  3. Kho chứa gói (Q2) và khóa ký (Q3) chưa được quyết định. Tạm thời tự host gói trên máy chủ HTTPS nội bộ (ví dụ https://downloads.example.com/agent/) gồm các tệp: .deb, .rpm, tar, SHA256SUMS, latest, install.sh.

9.2 Dựng gói (trên máy build, từ mã nguồn của Agent) ​

bash
git tag v1.0.0                  # phiên bản lấy từ git describe (hoặc make package VERSION=v1.0.0)
make package                    # deb, rpm, tar.gz cho amd64 và arm64, install.sh và SHA256SUMS, vào dist/release (scripts/package.sh)

Cần nfpm cài sẵn (go install github.com/goreleaser/nfpm/v2/cmd/[email protected]). Đặt SIGN_HOOK để ký SHA256SUMS khi đã có khóa (Q3). Kiểm tra gói trước khi đưa lên: dpkg-deb -I <tệp>.deb, dpkg-deb -c <tệp>.deb, rpm -qpi và rpm -qpl (máy có rpm).

9.3 Cài thử một máy (bắt buộc trước khi cài hàng loạt) ​

bash
sudo ACCESSHUB_COLLECTOR_URL=https://agents.example.com \
     ACCESSHUB_LICENSE_FILE=/root/license.token \
     apt install ./accesshub-agent_1.0.0_amd64.deb
bash
sudo ... dnf install ./accesshub-agent-1.0.0-1.x86_64.rpm

Gói tạo user accesshub-agent, thư mục /var/lib/accesshub-agent và /var/log/accesshub-agent, đặt /etc/accesshub-agent/agent.yaml, chỉ khi có URL và token thì enroll và khởi động. Không bao giờ khởi động dịch vụ khi chưa enroll. Enroll thủ công (khi không đặt biến lúc cài), đúng tài khoản dịch vụ, token qua stdin:

bash
read -rs TOKEN
printf '%s\n' "$TOKEN" | sudo -u accesshub-agent accesshub-agent enroll --collector https://agents.example.com --token-stdin
unset TOKEN
sudo systemctl enable --now accesshub-agent

Xác minh: accesshub-agent status (mã thoát 0, đã enroll, lần gửi cuối gần đây, WAL gần 0), journalctl -u accesshub-agent -n 50, và accesshub-agent diag --output /tmp/diag.zip khi cần hỗ trợ (đã che bí mật). Mã thoát enroll: 5 bị từ chối (token sai, hết hạn, đã dùng), 6 không kết nối được (DNS, tường lửa, TLS).

Cài và giữ ca_file trong agent.yaml nếu LB dùng CA nội bộ. Không bao giờ đặt insecure_skip_verify: true ở production (agent in cảnh báo mỗi giờ).

9.4 Cài bằng install.sh (kênh tải có xác minh) ​

bash
sudo ACCESSHUB_COLLECTOR_URL=https://agents.example.com \
     ACCESSHUB_LICENSE_FILE=/root/license.token \
     ACCESSHUB_DOWNLOAD_BASE=https://downloads.example.com/agent \
     sh install.sh --pubkey release.pub

Script tải gói đúng kiến trúc, kiểm SHA256SUMS và chữ ký, rồi kiểm checksum gói trước khi cài. Chưa có khóa ký (Q3) thì chỉ có --allow-unsigned (vẫn kiểm checksum nhưng SHA256SUMS nằm cùng nơi với gói, nên chỉ chống hỏng tệp, không chống bị thay thế). Đề nghị hoàn tất Q3 trước khi cài ngoài mạng tin cậy. --dry-run để thử không thay đổi gì.

9.5 Cài hàng loạt ​

CáchKhi nàoGhi chú
Ansible, Salt, PuppetCó sẵn quản lý cấu hìnhPhân phối token từng máy qua kho bí mật (Vault, ansible-vault), ghi vào tệp 0600, rồi chạy install.sh hoặc apt/dnf install với ACCESSHUB_LICENSE_FILE
Cloud-init, image vàngMáy mới sinh raKhông nhúng credentials.json hay token vào image. License dùng một lần, truyền qua user-data hoặc metadata lúc khởi tạo
Lệnh một dòng từ giao diệnQuản trị viên tự càiHUB-6 sẽ tạo lệnh kèm token
Windows GPO, IntuneSau khi AGT-7 xongChưa có

Làm theo lô nhỏ (5 đến 10 máy, rồi 10 phần trăm, rồi toàn bộ), sau mỗi lô kiểm tra mục 10. Collector giới hạn enroll theo IP nguồn (enroll_per_minute: 6, enroll_burst: 10, tính theo IP nguồn client); cài hàng trăm máy sau cùng một NAT sẽ chạm giới hạn này, hãy giãn thời gian hoặc nâng giá trị ingest.limits.enroll_* có kiểm soát.

9.6 Nâng cấp, gỡ agent ​

  • Nâng cấp: apt install ./accesshub-agent_<moi>.deb hoặc dnf upgrade. Cấu hình agent.yaml được giữ, thông tin đăng nhập giữ, dịch vụ tự khởi động lại nếu đang chạy. Trong lúc nâng cấp, dpkg có thể hỏi về agent.yaml (postinstall có chỉnh tệp này), trả lời giữ bản hiện tại.
  • Gỡ: apt remove (giữ dữ liệu) hoặc apt purge (xóa sạch). rpm không có purge: chạy sudo accesshub-agent uninstall --purge trước dnf remove. Gỡ agent không báo collector: thu hồi trong Access Hub (hoặc DELETE /internal/v1/agents/{id}).

Khi collector nâng cấp, nâng collector trước, agent sau (collector hỗ trợ giao thức N và N-1).

10. Danh sách kiểm tra sau triển khai ​

Chạy lần lượt, dừng ở mục đầu tiên hỏng.

#Kiểm traLệnh hoặc cáchKết quả mong đợi
1Đồng bộ thời gian mọi máytimedatectlSystem clock synchronized: yes
2Redisredis-cli -a "$PASS" ping, INFO persistence, INFO replicationPONG, aof_enabled:1, replica nối
3VictoriaMetricscurl -s http://10.0.0.20:8428/health, cổng 8429OK
4vmalertcurl -s http://127.0.0.1:8880/api/v1/rulesCó nhóm luật rollup, không lỗi
5Cấu hình collectoraccesshub-collector -check -config <tệp> từng vai tròMã thoát 0
6Collector khởi độngcurl -s http://<node>:9100/readyz200, mỗi node một collector_id
7LB thấy ingestXem trạng thái backend trong LBMọi node ingest UP
8TLSopenssl s_client (mục 7)Chuỗi đầy đủ, hạn dài, tên khớp
9Dừng 1 ingestsystemctl stop một node, lặp curl tới LBKhông 5xx, agent vẫn gửi
10Giết 1 workerkill -9 một worker giữa dòng dữ liệuKhông khoảng trống dữ liệu (worker còn lại nhận lô treo sau bus.claim_idle, 30 giây)
11Agent thửMục 9.3accesshub-agent status ổn, series xuất hiện trong vm-raw với company_id, server_id
12Dữ liệu đến VictoriaMetricscurl -s 'http://10.0.0.20:8428/api/v1/export?match[]={__name__=~"ah_.*"}' (hoặc truy vấn qua admin API)Có mẫu, nhãn company_id do collector gắn
13RollupChờ 10 phút, truy vấn vm-longCó chuỗi rollup 5 phút
14Mất liên lạcDừng agent thử quá ngưỡng (mặc định 90 giây)Worker phát sự kiện agent_down, vào outbox (hoặc Access Hub nhận, khi có HUB-5)
15OutboxMetric outbox trên /metrics của worker (xem 10)Không tăng dần
16Hai công tyĐẩy dữ liệu hai tenant, truy vấn chéo qua admin APIKhông thấy dữ liệu công ty kia
17Sao lưu thửKhôi phục Redis và VictoriaMetrics vào máy thửĐọc được

devctl.sh smoke (mục 7 của 09) là mẫu kịch bản cho các kiểm tra 9, 10, 11, 12 trên dev; có thể chạy lại tương tự trên staging.

11. Giám sát chính hệ thống giám sát ​

  • Thu /metrics của mọi tiến trình collector (cổng ops) vào Prometheus hoặc VictoriaMetrics riêng (không phải vm-raw của khách hàng).
  • Cảnh báo tối thiểu: /readyz không 200 quá 2 phút; chứng chỉ LB còn dưới 30 ngày; Redis dùng bộ nhớ trên 80 phần trăm maxmemory; đĩa vm-raw, vm-long dưới 25 phần trăm trống; outbox tăng liên tục 15 phút; ingest trả 503 tăng; số worker giảm; vmalert không đánh giá được.
  • Đặt một dead-man check bên ngoài (tự giám sát): nếu toàn bộ collector chết thì không ai báo, cần một kiểm tra từ hệ thống khác vào https://agents.example.com.
  • Chi tiết metric: xem 10.

12. Sao lưu, nâng cấp, quay lui ​

ViệcCách làm
Sao lưu hằng ngàyvmbackup cho vm-raw và vm-long; sao chép dump.rdb và AOF của Redis; chép /etc/accesshub-collector (trừ bí mật, bí mật lưu ở kho riêng). Giữ bản sao ngoài máy và thử khôi phục hằng quý
Nâng cấp collectorNâng worker và admin trước (cuốn chiếu từng node, đợi /readyz 200), rồi ingest từng node: rút khỏi LB (/readyz 503 tự động khi dừng êm), systemctl restart, đợi /readyz 200, cho vào lại. Giữ tối thiểu một node mỗi vai trò chạy
Quay luiĐổi liên kết binary về phiên bản trước rồi restart. Không có migration dữ liệu phía collector nên quay lui an toàn, trừ khi phiên bản mới đã ghi định dạng bus hoặc registry mới (kiểm tra ghi chú phát hành)
Xoay tokenCấp token mới, ghi vào tệp bí mật, khởi động lại cuốn chiếu, thu hồi token cũ. Token admin: cập nhật đồng thời ở Access Hub và collector
AOF Redis hỏngPreflight tự sửa đuôi nhỏ hoặc khởi động từ dump.rdb (mục 4.1); xử lý tay theo mục 4.2
Mất RedisDựng lại Redis rỗng với cùng mật khẩu: registry nạp lại từ Access Hub (sau hub.sync_interval, mặc định 1 phút), agent tự đệm WAL trong lúc chờ. Mất các sự kiện chưa gửi trong outbox
Mất VictoriaMetricsKhôi phục từ snapshot. Trong lúc mất, worker retry (tsdb.retry_max), bus đệm trong Redis, agent đệm WAL (50 MiB hoặc 24 giờ mặc định)
Thu hồi khẩn một agentThu hồi trong Access Hub hoặc DELETE /internal/v1/agents/{agent_id} với Authorization: Bearer <admin token> (idempotent, luôn 204, hiệu lực sau tối đa redis.cache_ttl, mặc định 15 giây)

12.1 Chuyển từ VictoriaMetrics node đơn sang cụm (dàn ý, ADR 0017) ​

Chỉ làm khi COL-15 xong (janitor và purge chạy trên cụm, agentsim đã chạy trên cụm). Chưa có runbook đã diễn tập, các bước dưới đây là dàn ý và phải thử trên bản sao trước.

  1. Dựng cụm rỗng cho vm-raw và vm-long (mỗi cụm tối thiểu 3 vmstorage, 2 vminsert, 2 vmselect, -replicationFactor=2), bật -dedup.minScrapeInterval (cần kiểm chứng) để ghi trùng giai đoạn chuyển không nhân đôi mẫu.
  2. Ghi kép từ mốc T0. Worker ghi cả node đơn và cụm. Giai đoạn này cần mã collector hỗ trợ hai đích ghi (thuộc COL-15).
  3. Nạp lịch sử từ node đơn sang cụm bằng vmctl vm-native (cách duy nhất tài liệu cụm chính thức nêu), theo khoảng [T0 - retention của kho, T0]: 30 ngày cho vm-raw, 400 ngày cho vm-long. Giữ nguyên nhãn, gồm ah_day, không viết lại nhãn. Dùng vmbackup rồi vmrestore để đưa dữ liệu node đơn vào cụm chưa được kiểm chứng, không dùng.
  4. Kiểm tra: so số series theo công ty giữa hai bên, so kết quả API series của vài công ty và vài chỉ số ở hai bên, chạy janitor ở dry_run trên cụm (ahc_retention_*), thử xóa một server thử bằng purge.
  5. Chuyển đọc và janitor sang cụm. Giữ ghi kép tối thiểu 7 ngày làm cửa sổ quay lui.
  6. Ngừng ghi vào node đơn. Giữ node đơn ở chế độ chỉ đọc và vmbackup cuối cùng đến hết retention thô (30 ngày), rồi gỡ.
  • Quay lui: trước bước 6 chỉ cần chuyển đọc và janitor về node đơn (nó vẫn nhận ghi kép). Sau bước 6 phải nạp ngược bằng vmctl từ cụm.
  • Khoảng trống đồ thị: nếu bỏ bước 3 thì mọi đồ thị trước T0 mất (trống). Nếu chỉ nạp vm-raw thì rollup trước T0 phải tạo lại bằng chế độ replay của vmalert (cần kiểm chứng) hoặc chấp nhận khoảng trống ở vm-long. Dữ liệu cũ chưa có nhãn ngày phải được chuyển xong ở node đơn trước bước 1 (ADR 0016 mục 4.6).
  • Thông báo cho khách chỉ cần nếu chấp nhận khoảng trống. Retention theo gói và ân hạn không đổi vì chúng nằm ở Access Hub và collector, không ở kho.

12.2 Chuyển một công ty giữa hai collector ​

Chỉ cần khi có collector thứ hai (cụm riêng cho khách rất lớn hoặc vùng khác, COL-18). Nâng hoặc hạ gói không gây chuyển, vì company_id và collector giữ nguyên.

Lựa chọnCách làmHệ quả
1. Không chuyểnCông ty ở lại collector hiện tại, gán collector đúng ngay lúc tạo công tyKhông mất dữ liệu, không việc thủ công. Khuyên dùng
2. Chuyển, chấp nhận trống lịch sửĐổi collector_id của agent (HUB-15), agent nhận collector_url mới. Dữ liệu cũ ở collector cũ hết hạn tự nhiên theo retention, rồi gọi DELETE /internal/v1/companies/{id}/data để xóa nốtĐồ thị trước thời điểm chuyển trống ở collector mới. Dữ liệu cũ vẫn có trong ân hạn nếu chưa xóa nhưng Access Hub chỉ truy vấn collector hiện tại
3. Chuyển và sao chép dữ liệuNhư 2, thêm vmctl vm-native với bộ chọn {company_id="..."} cho cả hai kho từ cụm cũ sang cụm mới (giữ nhãn ah_day), kiểm tra, rồi xóa dữ liệu công ty ở collector cũ bằng purgeGiữ lịch sử, tốn IO và cần cửa sổ thao tác. Trong lúc sao chép, thời điểm cuối có thể lệch vài phút (chạy lại phần chênh lệch sau khi đổi đích ghi)
  • Gỡ ghim License: MonitoringLicense.collector_id ghim License vào một collector. Khi công ty chuyển, License nào đã ghim phải được gỡ ghim (hoặc ghim lại collector mới) trước, nếu không agent enroll mới sẽ nhận binding_failed (HTTP 422) vì collector báo danh khác collector đã ghim.
  • Chính sách retention và ân hạn theo từng công ty do Access Hub trả (GET /settings/{company_id}), nên collector mới áp đúng chính sách mà không cần chuyển trạng thái.
  • Sau khi chuyển phải kiểm tra cô lập: công ty khác trên collector cũ và mới không bị ảnh hưởng (kiểm thử hai tenant).

13. Bảo mật khi triển khai ​

  • Mọi bí mật (mật khẩu Redis, token hub, token admin) nằm trong tệp 0640, nhóm accesshub-collector, không có trong repo, nhật ký, lịch sử shell. Xoay định kỳ.
  • Collector chạy không root, sandbox systemd (xem unit), MemoryMax giới hạn.
  • Giao tiếp ra ngoài: chỉ agent tới LB (443), collector tới Access Hub, không cho collector tự ra Internet nếu không cần.
  • Agent chỉ đẩy ra, không mở cổng, không thực thi lệnh từ xa (ADR 0010).
  • Mọi truy vấn và ghi TSDB có company_id do collector gắn, không tin nhãn do agent gửi. Mọi thay đổi code chạm vào đây phải có kiểm thử hai tenant.
  • Admin API chỉ sau mạng riêng, token tối thiểu 24 ký tự, xoay định kỳ. Không đưa cổng 9101 ra LB công khai.
  • Tệp credentials.json của agent (0600) là thông tin đăng nhập của máy, không chép ra ngoài, không đưa vào image.
  • Cập nhật hệ điều hành và redis, VictoriaMetrics theo bản vá bảo mật. Chạy govulncheck ./... khi build collector.

14. Xử lý sự cố nhanh ​

Triệu chứngNguyên nhân thường gặpXử lý
Collector thoát mã 3 lúc khởi độngYAML sai (khóa lạ, giá trị ngoài khoảng, thiếu collector_id)accesshub-collector -check -config <tệp>, đọc dòng lỗi
/readyz 503 sau khi khởi độngRedis hoặc TSDB không tới được, sai mật khẩuXem thân JSON của /readyz, kiểm tra mạng và mật khẩu
Agent báo enroll mã 5Token sai, hết hạn, hoặc dùng rồi; LB không chuyển tiếp /agent/v1/enrollCấp token mới, kiểm tra nhật ký ingest
Agent báo mã 6DNS, tường lửa 443, TLS (CA không tin cậy, chứng chỉ hết hạn)accesshub-agent diag (có thử DNS, TCP, TLS, skew)
Mọi agent mất tín hiệu cùng lúcChứng chỉ LB hết hạn, LB chết, Redis mấtMục 7, mục 4
Redis crash-loop hoặc unit failed, journal có Bad file format reading the append only fileAOF hỏng (thường do đĩa đầy)Mục 4.2; giải phóng đĩa trước
Ingest 503Bus đầy (worker chậm hoặc chết), Redis đầy (maxmemory), TSDB chậmXem số worker, INFO memory, độ trễ ghi TSDB; thêm worker
Nhiều agent báo lệch đồng hồNTP hỏngSửa đồng bộ thời gian, dữ liệu cũ quá 24 giờ bị bỏ
Outbox tăngAccess Hub không nhận (chưa có HUB-5, token sai, rate limit)Kiểm tra token và log Access Hub; trong lúc chờ, Redis giữ sự kiện
Dữ liệu rollup trốngvmalert dừng, sai -rule, vm-long hỏngXem :8880/api/v1/rules, log vmalert
Biểu đồ trễ khoảng 30 giâyVictoriaMetrics -search.latencyOffsetBình thường

Khi báo lỗi, đính kèm: collector -version, log JSON quanh thời điểm lỗi (có request_id), accesshub-agent diag từ máy liên quan (đã che bí mật).

15. Việc còn thiếu trước khi gọi là "production thật" ​

Để tránh hiểu nhầm, các điều sau chưa có và cần hoàn tất hoặc chấp nhận rủi ro:

  1. HUB-1 đến 18 (Access Hub phía monitoring), thiếu thì chưa có dữ liệu đầu-cuối thật.
  2. Windows agent và MSI (AGT-7), chữ ký Authenticode (Q3).
  3. Khóa ký gói và kho gói (Q2, Q3): hiện gói chưa ký.
  4. Image Docker, gói .deb cho collector, Helm chart (tùy chọn giai đoạn 3).
  5. Collector: renew; bus JetStream; giới hạn tốc độ và khử trùng inventory hiện theo từng node.
  6. Sentinel hoặc Cluster tự động cho Redis chưa được kiểm chứng với collector.
  7. Kiểm thử tải lớn (1.000 đến 10.000 agent), kiểm thử lỗi cả máy và lỗi mạng giữa các máy (dev chạy một máy).
  8. Phê duyệt các quyết định kiến trúc đang chờ trong docs/architecture/adr (0012 đến 0015), mức quan trọng, RTO và RPO.
Trang này có giúp được bạn không?
Sửa trang này

Nội dung đồng bộ từ kho mã access-hub-collector lúc 10:57, 03/10/2026. Khi tài liệu và mã khác nhau, mã thắng.