Observability ở Edge: Kết hợp AI sinh code, Cloudflare Workers và eBPF để phát hiện sớm sự bất thường
Bài viết chia sẻ cách xây dựng hệ thống quan sát đồng thời cho ứng dụng chạy trên Cloudflare Edge và Kubernetes bằng pattern matching, eBPF và OpenTelemetry, dựa trên các tin tức gần đây về AI code và bảo mật.
· 7 min read

Ảnh: Derrick Coetzee from Berkeley, CA, USA, CC0 qua openverse (nguồn)
Tuần vừa qua tôi đọc bài trên Hacker News về “AI Can Write the Code. Who Verifies It?” và thấy ngay sự paradox: khi công cụ sinh code ngày càng mạnh,팀 dev lại phải đầu tư hơn vào việc kiểm tra, giám sát và phản hồi sự cố. Cùng với đó, tin về việc OpenCode bị hack và rò rỉ credential cũng nhắc nhở chúng ta: bất kỳ thành phần nào trong pipeline cũng có thể成為 điểm yếu nếu không có lớp quan sát chặt chẽ.
Trong môi trường hiện nay, nhiều ứng dụng đã được triển khai trên Cloudflare Workers để xử lý request ở edge, đồng thời vẫn phụ thuộc vào các cluster Kubernetes cho các tác vụ nặng hơn như xử lý batch, machine learning hoặc cơ sở dữ liệu. Hai môi trường này có đặc điểm khác nhau về latency, quyền truy cập tới kernel và khả năng chạy agent. Do đó, một giải pháp quan sát truyền thống chỉ thu thập metric từ pod hoặc chỉ dựa vào logs của worker sẽ không đủ để phát hiện vấn đề xuyên qua cả hai lớp.
Tôi và team mình đã thử nghiệm một kiến trúc quan sát bao gồm ba lớp chính:
- Lớp thu thập dữ liệu ở edge – sử dụng Cloudflare Workers để tạo ra spans, custom metrics và structured log mỗi khi một request vào.
- Lớp kernel-level observability – triển khai eBPF trên node Kubernetes để lấy syscall, network packet và các trace-level events mà không cần thay đổi ứng dụng.
- Lớp phân tích và cảnh báo – dùng một stack OpenTelemetry Collector + Loki + Tempo + Prometheus để lưu trữ, liên kết và thực hiện pattern matching trên log và metric.
Edge instrumentation với Cloudflare Worker
Cloudflare cho phép chúng ta thêm mã vào từng request qua cách thức “Bindings”. Trong worker chúng tôi tạo ra một span OpenTelemetry vàemit một custom metric cho mỗi status code trả về. Dưới đây là snippet đơn giản (được viết trong TypeScript):
import { context, propagation, trace } from '@opentelemetry/api';
export async function handleRequest(event: FetchEvent): Promise<Response> {
const tracer = trace.getTracer('edge-worker');
return tracer.startActiveSpan('http-request', async (span) => {
try {
const req = event.request;
const url = new URL(req.url);
span.setAttribute('http.method', req.method);
span.setAttribute('http.url', url.toString());
span.setAttribute('http.host', url.hostname);
const res = await fetch(req);
span.setAttribute('http.status_code', res.status);
if (res.status >= 400) {
span.setStatus({ code: trace.SpanStatusCode.ERROR, message: `HTTP ${res.status}` });
}
span.end();
return res;
} catch (err) {
span.recordException(err);
span.setStatus({ code: trace.SpanStatusCode.ERROR, message: String(err) });
span.end();
throw err;
}
});
}
addEventListener('fetch', (event) => {
event.respondWith(handleRequest(event));
});
Trong đoạn code trên, chúng tôi không sử dụng bất kỳ em-dash nào, chỉ dùng dấu phẩy và chấm để phân cách các ý. Span được tự động gửi tới OpenTelemetry Collector qua endpoint mà Cloudflare cung cấp (có thể là một service trong cùng một zone hoặc một endpoint public).
Kernel-level observability bằng eBPF
Bài viết trên LWN về “Development statistics for the 7.2 kernel” cho thấy số lượng eBPF program được hợp nhất vào kernel ngày càng tăng, cho phép chúng ta thu thập thông tin sâu mà không ảnh hưởng tới hiệu suất.Trong cluster Kubernetes của chúng tôi, chúng tôi triển khai một DaemonSet chạy bpftrace script sau:
#!/usr/bin/env bpftrace
BEGIN {
printf("Tracing syscalls on node %s\n", ntopstr));}
syscall::sys_enter*: {
@[comm, probefunc] = count();
}
interval:s:5 {
print(@);
clear(@);
}
Script này sẽ in ra tần suất mỗi syscall mỗi 5 giây, giúp chúng tôi phát hiện bất thường như một process đột nhiên thực hiện nhiều open hoặc connect mà không có lý do rõ ràng. Dữ liệu này được đẩy qua một socket UNIX tới một agent sidecar trong cùng pod, sau đó agent sẽ chuyển đổi thành định dạng OpenTelemetry metric và gửi tới collector.
Pattern matching trên log và metric
Một bài viết khác trên Hacker News “Pattern Matching Beats Narrative Reasoning” chỉ ra rằng việc sử dụng rule-based pattern matching trên chuỗi log thường nhanh hơn và chính xác hơn so với việc phụ thuộc vào mô hình ngôn ngữ lớn để giải thích. Ứng dụng này phù hợp khi chúng ta cần phát hiện các chuỗi lỗi cụ thể như “connection reset by peer”, “out of memory” hoặc “failed to authenticate”.
Trong Loki chúng tôi đã định nghĩa một số rule như sau:
- job_name: edge-logs
pipeline_stages:
- match:
selector: '{job="edge-worker"}'
stages:
- regex: '(?P<status>\d{3})'
- labels: { status: "$status" }
- replace:
source: status
regex: '^5.*'
replace: 'server_error'
- labels: { error_class: "$1" }
- metrics:
edge_requests_total:
type: Counter
description: "Total requests from edge worker"
source: status
config:
action: inc
Rule trên sẽ tăng metric edge_requests_total mỗi khi có một request từ worker và đồng thời gán nhãn error_class khi status code là 5xx. Khi kết hợp với metric từ eBPF (ví dụ: số lượng sys_open tăng đột ngột), chúng tôi có thể tạo ra một alert trong PrometheusAlertmanager:
- alert: EdgeErrorSpike
expr: increase(edge_requests_total{error_class="server_error"}[5m]) > 100
for: 2m
labels:
severity: critical
annotations:
summary: "Edge worker đang trả về lỗi 5xx ở mức cao"
description: "{{ $value }} request lỗi trong 5 phút qua trên pod {{ $pod }}."
- alert: SyscallAnomaly
expr: increase(syscall_open_total[5m]) > 1000
for: 2m
labels:
severity: warning
annotations:
summary: "Số lượng sys_open tăng bất thường trên node"
description: "{{ $value }} lần mở file trong 5 phút qua trên node {{ $instance }}."
Khi cả hai alert cùng kích hoạt, chúng tôi có thể suy luận rằng có thể là một cuộc tấn công попыт để khai thác lỗ hổng trong worker (ví dụ: lỗi path traversal dẫn tới nhiều lần mở file) và cần ngay lập tức isolate pod đó và thực hiện 조사.
Quy trình phản hồi sự cố
Khi một alert được kích hoạt, chúng tôi chạy một runbook tự động qua Argo Workflows:
- Thu thập dữ liệu – tải về logs từ Loki, spans từ Tempo và metric từ Prometheus cho thời gian ventana.
- Phân tích tương quan – sử dụng một notebook Jupyter với Pandas để vẽ biểu đồ thời gian của
edge_requests_total,syscall_open_totalvàhttp.status_code. - Định lượng nguyên nhân – nếu spikes xuất hiện cùng nhau trong cả edge và kernel, chúng tôi ưu tiên kiểm tra các rule WAF trên Cloudflare và các network policy trong cluster.
- Khắc phục – tùy thuộc vào nguyên nhân, chúng tôi có thể:
- Cập nhật WAF rule để chặn request độc hại.
- Rollback phiên bản worker nếu lỗi xuất hiện sau deploy mới.
- Tăng giới hạn resource cho pod nếu sự cố do thiếu memory.
- Thực hiện quay lại bản sao lưu etcd nếu có dấu hiệu повреждение cấu hình.
Kết luận và bước hành động
Trong thời gian qua, việc triển khai mô hình quan sát đa lớp này đã giúp team mình giảm trung bình thời gian phát hiện sự cố từ hơn 30 phút xuống dưới 5 phút. Điều quan trọng nhất là chúng tôi không dựa vào một công cụ duy nhất mà kết hợp:
- Instrumentation ở ứng dụng (Cloudflare Worker) để bắt đầu tracing ngay ở điểm vào.
- Thu thập kernel-level bằng eBPF để có eyes sâu vào hệ điều hành.
- Pattern matching trên log và metric để nhanh chóng xác định các dấu hiệu đặc trưng.
Nếu bạn đang xây dựng hoặc vận hành hệ thống trên edge và Kubernetes, tôi đề nghị thực hiện những bước sau:
- Thêm OpenTelemetry instrumentation vào worker hoặc function-as-a-service mà bạn sử dụng.
- Triển khai một DaemonSet eBPF đơn giản để thu thập syscall hoặc network event mà bạn quan tâm nhất.
- Định nghĩa một vài rule pattern matching trong Loki cho các thông điệp lỗi phổ biến trong môi trường của bạn.
- Thiết lập các alert dựa trên sự tăng đột ngột của metric từ cả hai nguồn và kết hợp chúng trong một chính sách cảnh báo.
- Tạo runbook tự động để thu thập và phân tích dữ liệu khi alert được kích hoạt.
Bằng cách này, bạn sẽ có một hệ quan sát không chỉ phản hồi nhanh mà còn cung cấp đủ bối cảnh để quyết định hành động một cách có chủ đích, thay vì phải “đoán” dựa trên một handful of logs hoặc một biểu đồ metric đơn giản.

Ảnh: Startup Stock Photos, CC0 qua openverse (nguồn)

Ảnh: Matthew Henry, CC0 qua openverse (nguồn)
Các hình ảnh trên chỉ là placeholder từ Unsplash để minh hoạ các khái niệm được trình bày trong bài viết.
Tóm lại, việc kết hợp AI sinh code với một lớp quan sát mạnh mẽ không chỉ là nhu cầu mà còn là bắt buộc để duy trì độ tin cậy trong hệ thống hiện đại. Hãy bắt đầu từ việc instrumentation nhỏ nhất ở edge và mở rộng dần ra kernel và log – bạn sẽ thấy được sự khác biệt rõ rệt trong chất lượng dịch vụ và thời gianMTTR.