Triển khai và vận hành
Hướng dẫn từng bước lên môi trường thực tế: 14. Hướng dẫn triển khai production.
1. Cấu phần và yêu cầu
| Thành phần | Dev | Production nhỏ | Production lớn |
|---|---|---|---|
collector | 2 ingest sau LB, 2 worker, 1 admin, mỗi tiến trình một collector_id (xem mục 7) | Như dev, hoặc 2 node all sau LB khi ít máy | ingest x N, worker x N, admin x 2 |
| Redis hoặc Valkey | 1 master + 1 replica, có mật khẩu | 1 master + 1 replica | Sentinel hoặc Cluster, 3 node |
Bus giữa ingest và worker | Redis streams (tự chọn khi có redis.addr) | Redis streams | Redis streams, NATS JetStream là phương án mở rộng (chưa làm) |
| Outbox sự kiện gửi Access Hub | Redis (tự chọn khi có redis.addr) | Redis | Redis |
| TSDB | vm-raw + vm-long | 1 VictoriaMetrics single | Cụm VM, hoặc nhiều instance |
| Rollup | vmalert + vm-long | vmalert + vm-long | vmalert HA + vm-long |
| Access Hub | Cục bộ (SQLite) | MySQL Read/Write | MySQL Read/Write, nhiều node |
| Load balancer | Nginx TLS (user-level) | Nginx, HAProxy hoặc LB nền tảng | Như trái, nhiều AZ |
2. Cấu hình collector
Nguồn cấu hình: tệp YAML (-config hoặc AHC_CONFIG) cộng biến môi trường AHC_* ghi đè, bí mật qua tệp (*_file) hoặc biến môi trường. Khóa lạ trong YAML là lỗi. Kiểm tra bằng collector -check -config <tệp> (mã thoát 0 hợp lệ, 3 cấu hình sai). Danh sách đầy đủ khóa, mặc định và mẫu từng vai trò nằm ở 14 mục 6, mã nguồn ở internal/config/config.go. Ví dụ tối thiểu cho một node worker:
collector_id: prod-worker-1 # duy nhất toàn hệ thống
roles: [worker] # ingest | worker | admin | all
log: { level: info, format: json }
ops: { listen: 10.0.1.21:9100 } # /healthz, /readyz, /metrics
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 # vm-raw
long_url: http://10.0.0.20:8429 # vm-long (rollup)Ghi chú: ingest.listen là HTTP thuần sau LB (hoặc thêm tls_cert_file, tls_key_file), admin.listen mặc định 127.0.0.1:9101 kèm admin.token_file (tối thiểu 24 ký tự), bus.backend và outbox.backend mặc định auto (Redis khi có redis.addr). Các khóa listen.agent, tls.cert_file, accesshub.*, redis.addrs, bus.kind, limits.* trong bản thiết kế ban đầu đã đổi tên như trên.
3. Đóng gói
| Định dạng | Ghi chú |
|---|---|
| Docker image | Distroless, chạy không root, ENTRYPOINT ["/collector"], đa kiến trúc (amd64, arm64). Chưa có |
| Binary tĩnh và tar | Cho triển khai không dùng container |
| Helm chart (tùy chọn GĐ 3) | Deployment cho ingest, StatefulSet hoặc Deployment cho worker, PodDisruptionBudget, HPA theo CPU và độ trễ bus |
| Docker Compose | deploy/compose/dev.yaml cho dev, deploy/compose/prod-small.yaml mẫu production nhỏ |
| systemd unit | deploy/systemd/accesshub-collector-{ingest@,worker@,admin}.service (mẫu dev, chuyển sang system unit theo 14 mục 6.5) |
4. Đường truyền và tên miền
- Endpoint agent: một tên miền công khai riêng (ví dụ
agents.example.com) trỏ LB. Không dùng chung tên miền giao diện Access Hub, để dễ scale, chặn, đổi IP độc lập. - Endpoint admin: mạng nội bộ, không công khai.
- LB: cân bằng theo vòng, kiểm tra sức khỏe
/readyz, timeout đọc 30 giây, giới hạn kích thước body ở LB bằng giới hạn collector, HTTP/2 bật. - IPv6: hỗ trợ nếu LB hỗ trợ.
5. Vận hành hằng ngày
| Việc | Cách làm |
|---|---|
| Nâng cấp collector không gián đoạn | Cuốn chiếu (rolling): ingest rút khỏi LB (/readyz trả 503 khi đang tắt êm, chờ hết request đang xử lý), rồi nâng. Worker: tắt êm, snapshot trạng thái, node khác nhận shard |
| Tương thích khi nâng cấp | Collector luôn hỗ trợ giao thức N và N-1. Nâng collector trước, agent sau |
| Thêm node ingest | Thêm vào LB, không cần cấu hình gì khác |
| Thêm node worker | Khởi động, tự đăng ký lease shard, phân bổ lại sau vài chục giây |
| Thu hồi khẩn cấp một agent | Access Hub, hoặc DELETE /internal/v1/agents/{id} |
| Xoay token dịch vụ hoặc admin | Cấp token mới, cập nhật secret, khởi động cuốn chiếu, thu hồi token cũ |
| Sao lưu | Snapshot VM theo lịch, RDB Redis, xuất cấu hình. Access Hub sao lưu MySQL theo quy trình riêng |
| Khôi phục | Runbook: dựng lại Redis rỗng (registry tự nạp lại từ Access Hub), dựng lại collector, TSDB khôi phục từ snapshot |
6. Runbook sự cố (rút gọn, chi tiết viết ở GĐ 1)
| Triệu chứng | Chẩn đoán | Xử lý |
|---|---|---|
| Agent hàng loạt mất tín hiệu | ingest down, LB, chứng chỉ hết hạn, Redis mất | Kiểm tra /readyz, chứng chỉ, Redis. Có cờ ân hạn tự động sau khởi động |
| Alert bão | Sự cố mạng cả subnet | Kiểm tra sự kiện group_down, xác nhận gom nhóm đang bật |
| Ingest 503 | Bus đầy, worker chậm hoặc TSDB chậm | Kiểm tra độ sâu bus, độ trễ ghi TSDB, thêm worker |
| Outbox tăng | Access Hub không nhận | Kiểm tra Access Hub, token dịch vụ, giới hạn tốc độ |
| Tổng series tăng vọt | Agent gửi nhãn lạ | Xem metric series bị bỏ theo agent, thu hồi hoặc sửa cấu hình |
| Truy vấn chậm | Khoảng thời gian dài trên vm-raw | Kiểm tra logic chọn rollup, tài nguyên vmselect |
7. Môi trường phát triển
Môi trường dev mô phỏng đủ các thành phần của production nhỏ, chạy bằng systemd user unit (không cần sudo, không cần Docker), mọi thành phần là một dịch vụ riêng, có khởi động lại tự động, log vào journald và cấu hình sandbox (ProtectSystem=strict, NoNewPrivileges, ...). Bật linger nên stack tự chạy lại sau khi khởi động máy mà không cần đăng nhập.
| Thành phần | Dev | Cổng | Ghi chú |
|---|---|---|---|
| Nginx (user-level, không phải nginx hệ thống) | accesshub-lb | 127.0.0.1:8443 | TLS 1.2/1.3 và HTTP/2, upstream 2 node ingest, kiểm tra sức khỏe thụ động (max_fails), thử lại sang node còn lại cho lỗi kết nối, timeout và 503, body tối đa 1 MiB, timeout đọc 30 giây. Nhật ký truy cập ở ~/.local/share/accesshub-lb/logs/access.log |
Collector ingest 1, 2 | accesshub-collector-ingest@1, @2 (vai trò ingest, collector_id dev-ingest-1, dev-ingest-2) | ingest 18443, 18444, ops 9111, 9112 | Sau LB, HTTP thuần giữa LB và node, trusted_proxies cho 127.0.0.0/8. Chỉ nhận dữ liệu, đẩy lô vào bus Redis |
Collector worker 1, 2 | accesshub-collector-worker@1, @2 (vai trò worker, dev-worker-1, dev-worker-2) | chỉ ops 9121, 9122 | Đọc bus Redis theo consumer group, ghi VictoriaMetrics, đánh giá agent mất kết nối, gửi sự kiện cho Access Hub. Một worker chết thì worker còn lại nhận lô treo sau bus.claim_idle (30 giây) |
Collector admin | accesshub-collector-admin (vai trò admin, dev-admin) | admin 127.0.0.1:9101, ops 9110 | Token từ tệp bí mật |
| Redis master | accesshub-redis-master | 127.0.0.1:6380 | requirepass, AOF everysec cộng RDB, maxmemory 256mb, noeviction. Tách khỏi Redis hệ thống (6379) mà Access Hub đang dùng. Giữ registry, presence, bus và outbox |
| Redis replica | accesshub-redis-replica | 127.0.0.1:6381 | replicaof master, masterauth |
vm-raw | accesshub-vm-raw | 127.0.0.1:8428 | Retention 30 ngày, mẫu thô |
vm-long | accesshub-vm-long | 127.0.0.1:8429 | Retention 400 ngày, rollup |
vmalert | accesshub-vmalert | 127.0.0.1:8880 | Luật rollup 5 phút và 1 giờ (avg, min, max, last) cho mọi chỉ số trong catalog, ghi sang vm-long |
| Access Hub giả lập | accesshub-mockhub | 127.0.0.1:8090 | Chỉ dev. API monitoring thật của Access Hub (HUB-*) chưa được xây, mockhub thay thế cho tới khi có |
| Agent | accesshub-agent | (đi ra) | Ghim CA dev bằng ca_file, không dùng insecure_skip_verify, chu kỳ 10 giây cho nhanh phản hồi |
Cấu hình mỗi vai trò sinh từ mẫu deploy/dev/collector.{ingest,worker,admin}.yaml.tmpl. Cả ba đặt redis.addr, nên bus.backend và outbox.backend (mặc định auto) tự chọn Redis. Giá trị riêng từng tiến trình (AHC_COLLECTOR_ID, AHC_OPS_LISTEN, AHC_INGEST_LISTEN) nằm trong ~/.config/accesshub-collector/dev/<vai trò>-<n>.env, nên mỗi tiến trình có collector_id và cổng ops khác nhau. Chỉ ingest không cấu hình tsdb, vì nó không ghi TSDB.
Điểm khác production còn lại (có chủ đích, ghi rõ để không nhầm):
- Nginx OSS chỉ có kiểm tra sức khỏe thụ động. Bản production nên dùng LB có kiểm tra chủ động vào
/readyzcủa cổng ops. - Access Hub là mockhub (xem trên), Redis chưa có Sentinel, VictoriaMetrics chưa có snapshot theo lịch.
- Tất cả chạy trên một máy, nên chưa kiểm chứng được lỗi cả máy hay lỗi mạng giữa các máy.
Lệnh điều khiển
Mọi thao tác qua deploy/dev/devctl.sh:
| Lệnh | Việc làm |
|---|---|
install | Tạo thư mục, bí mật (0600, không in ra), CA dev và chứng chỉ máy chủ cho agents.dev.local (SAN có localhost và 127.0.0.1), sinh cấu hình và tệp env từng tiến trình từ mẫu deploy/dev/**, liên kết unit từ deploy/systemd/ vào ~/.config/systemd/user, gỡ topology cũ (node@) nếu còn. Chạy lại được nhiều lần |
build | Build collector, mockhub và agent vào ~/.local/opt/accesshub/bin, tên có phiên bản (collector-<commit>), liên kết tên ngắn tới bản mới nhất |
up, down | Khởi động hoặc dừng theo thứ tự phụ thuộc |
restart [unit] | Khởi động lại một unit (ví dụ collector-worker@1, collector-ingest@2, lb) hoặc cả stack |
status | Trạng thái và kiểm tra sức khỏe từng thành phần |
logs [unit...] | Log journald (LINES_N=200 để xem nhiều hơn) |
enroll [--force] | Enroll agent dev với mockhub qua LB |
smoke [--quick] [--rollup] | Kiểm tra đầu cuối và chịu lỗi, xem bên dưới |
reset --yes | Xóa toàn bộ dữ liệu dev (Redis, vm-raw, vm-long, thông tin đăng nhập agent) |
Trình tự lần đầu: devctl.sh install, devctl.sh build, devctl.sh up, devctl.sh enroll, devctl.sh smoke.
Kiểm tra đầu cuối (smoke)
devctl.sh smoke chạy hai nhóm kiểm tra. Cờ --quick bỏ nhóm thứ hai, --rollup chờ thêm tối đa 7 phút để thấy rollup 5 phút trong vm-long. Chạy đủ mất khoảng 5 phút và cố ý làm chết các tiến trình, đừng chạy khi đang thử tay.
Nhóm 1, luồng thường: đẩy dữ liệu thật của agent qua nginx TLS, ingest, bus Redis, worker vào vm-raw rồi đọc lại bằng API export (không bị độ trễ tìm kiếm 30 giây của VictoriaMetrics). Kiểm tra: TLS với CA đã ghim, Redis bắt buộc mật khẩu, replica đã nối, cả 5 tiến trình collector sẵn sàng với collector_id khác nhau, mẫu lưu trong vm-raw mang company_id và server_id do collector đặt, và có khóa ah:bus:* trong Redis (chứng tỏ bus là Redis, không phải trong tiến trình).
Nhóm 2, chịu lỗi (mọi lần "chết" là SIGKILL, tiến trình giữ ở trạng thái dừng trong lúc kiểm tra):
- Giết
worker1 giữa dòng dữ liệu: dữ liệu vẫn vàovm-raw, và sau 40 giây không có khoảng trống lớn hơn 25 giây (chu kỳ agent 10 giây), tức không mất lô nào kể cả lô đang xử lý dở của worker chết. - Giết
ingest1: 20 request tới LB đều được node còn lại trả lời (không 5xx, không timeout), dữ liệu của agent vẫn vào. - Dừng cả hai
ingest45 giây: WAL của agent phải tăng (agent đệm), sau khiingestchạy lại WAL phải xả hết và dữ liệu trong khoảng mất kết nối phải xuất hiện đủ trongvm-raw.
Kiểm tra bộ nối VictoriaMetrics của collector với VictoriaMetrics thật (ghi, đọc lại Range và Latest, cô lập hai tenant, xóa, định tuyến sang rollup ở vm-long) bằng:
AHC_TEST_VM_URL=http://127.0.0.1:8428 AHC_TEST_VM_LONG_URL=http://127.0.0.1:8429 \
go test ./deploy/dev/vmcheck -count=1 -vBài này bỏ qua khi thiếu AHC_TEST_VM_URL, nên CI không cần VictoriaMetrics. Mẫu ghi luôn cũ hơn 60 giây và phép đọc được thử lại, vì VictoriaMetrics ẩn 30 giây gần nhất khỏi truy vấn (-search.latencyOffset).
Bước cần quyền root (tùy chọn)
Không có bước nào bắt buộc. deploy/dev/sudo-steps.sh gom các bước tùy chọn (chưa từng được chạy tự động): đặt vm.overcommit_memory=1 cho Redis, thêm agents.dev.local vào /etc/hosts, tin cậy CA dev toàn hệ thống. Đọc kỹ rồi chạy bằng sudo bash deploy/dev/sudo-steps.sh.
Phương án khác
make runchạy một tiến trình--roles=allvớideploy/dev/collector.yamlđể lặp nhanh khi viết mã, không có Redis hay VictoriaMetrics.docker-compose.dev.yml(make up) giữ lại như phương án thay thế cho máy không dùng systemd. Không mô phỏng đủ topology, đừng dùng để kiểm chứng triển khai.- Mock Access Hub sinh từ tệp mẫu
tests/ApiSamplescủa Access Hub để phát triển collector mà không cần Access Hub thật. make agentsim N=1000chạy mô phỏng tải cục bộ (dự kiến, GĐ 2).- Tích hợp với Access Hub thật (khi HUB-* xong): đặt
hub.base_urltrỏ Access Hub dev, tạo user dịch vụ và vai tròMonitoring Collector, tạo token, ghi vào~/.config/accesshub-collector/secrets/hub.token.
8. CI/CD
| Bước | Nội dung |
|---|---|
| Pull request | gofmt, go vet, staticcheck, golangci-lint, go test -race, buf lint, buf breaking, govulncheck, kiểm thử tích hợp với Redis và VictoriaMetrics trong container |
| Nhánh chính | Build đa kiến trúc, image, kiểm thử hợp đồng (contract) với OpenAPI của Access Hub |
| Tag phát hành | Build tái lập, ký (cosign), SBOM, đẩy image, tạo release, cập nhật tài liệu phiên bản giao thức |
| Hằng đêm | Kiểm thử tải rút gọn, fuzzing, quét phụ thuộc |