Cách GitHub sử dụng công nghệ eBPF để ngăn chặn phụ thuộc vòng và tăng cường an toàn triển khai

16 tháng 4, 2026·5 phút đọc

GitHub đã áp dụng công nghệ eBPF trong nhân Linux để giám sát và chặn các cuộc gọi mạng từ các tập lệnh triển khai, từ đó phát hiện và ngăn chặn các phụ thuộc vòng (circular dependencies) tiềm ẩn. Giải pháp này giúp hệ thống ổn định hơn và giảm thiểu thời gian khôi phục khi sự cố xảy ra.

Cách GitHub sử dụng công nghệ eBPF để ngăn chặn phụ thuộc vòng và tăng cường an toàn triển khai

GitHub là khách hàng lớn nhất của chính mình. Tất cả mã nguồn của nền tảng này đều được lưu trữ trên github.com. Điều này mang lại lợi ích to lớn trong việc kiểm thử nội bộ trước khi tung ra cho người dùng, nhưng cũng đi kèm một rủi ro lớn: nếu github.com bị sập, đội ngũ kỹ sư sẽ không thể truy cập mã nguồn để triển khai bản sửa lỗi.

Đây là một ví dụ điển hình về phụ thuộc vòng (circular dependency): để triển khai GitHub, chúng ta cần chính GitHub. Nếu nền tảng gặp sự cố, khả năng khắc phục sẽ bị tê liệt. Mặc dù GitHub duy trì các bản sao mã nguồn và tài sản build để khắc phục, nhưng vấn đề phức tạp hơn nhiều khi các tập lệnh triển khai (deployment scripts) vô tình tạo ra các phụ thuộc vòng mới.

Mô tả mã nguồn eBPFMô tả mã nguồn eBPF

Các loại phụ thuộc vòng tiềm ẩn

Hãy tưởng tượng một kịch bản khi cơ sở dữ liệu MySQL gặp sự cố, khiến GitHub không thể phục vụ dữ liệu phát hành. Để khắc phục, chúng ta cần chạy một tập lệnh cấu hình trên các node MySQL bị ảnh hưởng. Tuy nhiên, nhiều loại phụ thuộc vòng có thể xảy ra:

  • Phụ thuộc trực tiếp: Tập lệnh cố gắng kéo công cụ mã nguồn mở mới nhất từ GitHub. Vì GitHub đang sập, tập lệnh thất bại.
  • Phụ thuộc ẩn: Công cụ sử dụng đã có sẵn trên máy, nhưng khi chạy, nó tự động kiểm tra cập nhật từ GitHub và bị treo nếu không kết nối được.
  • Phụ thuộc chuyển tiếp: Tập lệnh gọi một dịch vụ nội bộ, và dịch vụ này lại cố gắng tải binary từ GitHub.

Trước đây, trách nhiệm nhận diện các rủi ro này thuộc về từng đội ngũ sở hữu các máy chủ trạng thái (stateful hosts). Tuy nhiên, nhiều phụ thuộc thường chỉ bị phát hiện khi sự cố đã xảy ra, làm chậm quá trình khôi phục.

Giải pháp từ eBPF và cGroup

Việc chặn hoàn toàn quyền truy cập vào github.com từ các máy chủ này là không khả thi vì chúng vẫn cần phục vụ lưu lượng truy cập của người dùng ngay cả khi đang triển khai hoặc khởi động lại.

GitHub đã tìm đến giải pháp eBPF (extended Berkeley Packet Filter). eBPF cho phép tải các chương trình tùy chỉnh vào nhân Linux và neo vào các nguyên thủy hệ thống cốt lõi như mạng. Đặc biệt, chúng tôi sử dụng loại chương trình BPF_PROG_TYPE_CGROUP_SKB để neo vào lưu lượng mạng egress (đi ra) từ một cGroup cụ thể.

cGroup là một nguyên thủy của Linux dùng để thi hành giới hạn tài nguyên và cô lập các tập hợp process. Ý tưởng là tạo một cGroup, đặt tập lệnh triển khai vào bên trong nó, sau đó giới hạn quyền truy cập mạng chỉ dành cho tập lệnh đó.

Cấu hình eBPF và DNSCấu hình eBPF và DNS

Triển khai bộ lọc mạng có điều kiện

Đội ngũ kỹ sư của GitHub đã xây dựng một khái niệm bằng ngôn ngữ Go sử dụng thư viện cilium/ebpf. Thư viện này đơn giản hóa quá trình viết, xây dựng và chạy các chương trình eBPF.

Tuy nhiên, CGROUP_SKB chỉ hoạt động dựa trên địa chỉ IP. Việc duy trì danh sách chặn IP cập nhật liên tục là rất khó. Thay vào đó, GitHub sử dụng thêm một loại chương trình eBPF khác là BPF_PROG_TYPE_CGROUP_SOCK_ADDR để chặn các syscalls tạo socket và thay đổi địa chỉ IP đích.

Cách tiếp cận này cho phép chuyển hướng tất cả các truy vấn DNS từ tập lệnh triển khai đến một DNS proxy chạy trong không gian người dùng (userspace). Proxy này sẽ đánh giá từng tên miền yêu cầu dựa trên danh sách chặn và sử dụng eBPF Maps để giao tiếp với chương trình CGROUP_SKB, cho phép hoặc từ chối yêu cầu tương ứng.

Gỡ lỗi và giám sát

Một tính năng mạnh mẽ khác của giải pháp này là khả năng tương quan các yêu cầu DNS bị chặn với lệnh hoặc process cụ thể đã kích hoạt chúng.

Bên trong chương trình eBPF, chúng tôi có thể trích xuất ID giao dịch DNS và ID Process (PID) đã khởi tạo yêu cầu. Thông tin này được lưu vào một eBPF Map. Vì tất cả các cuộc gọi DNS đều được chuyển hướng qua proxy nội bộ, chúng ta có thể tra cứu PID để tìm ra process nào đã thực hiện yêu cầu đó, và thậm chí đọc dòng lệnh đầy đủ từ /proc/{PID}/cmdline.

Kết quả là các dòng log chi tiết giúp các đội ngũ dễ dàng debug:

WARN DNS BLOCKED reason=FromDNSRequest blocked=true blockedAt=dns domain=github.com. pid=266767 cmd="curl github.com " firewallMethod=blocklist

Kết quả và hướng đi tiếp theo

Sau 6 tháng triển khai, quy trình phát hiện phụ thuộc vòng mới của GitHub đã chính thức vận hành. Giờ đây, nếu một đội ngũ vô tình thêm một phụ thuộc gây vấn đề, công cụ sẽ tự động phát hiện và cảnh báo.

Điều này mang lại kết quả là một nền tảng GitHub ổn định hơn và thời gian khôi phục trung bình (MTTR) nhanh hơn trong các sự cố. GitHub cũng đang sử dụng cGroups để thi hành giới hạn CPU và bộ nhớ cho các tập lệnh triển khai, ngăn chặn việc sử dụng tài nguyên quá mức ảnh hưởng đến workload.

Nếu bạn quan tâm đến eBPF, hãy bắt đầu với các ví dụ trong thư viện cilium/ebpf hoặc các công cụ mã nguồn mở như bpftraceptcpdump.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗