Scaling Kubernetes to 7,500 nodes
Bài tóm tắt OpenAI 2021 3. Quy mô lớn Độ khó: Nâng cao
OpenAI · 2021 · 3. Quy mô lớn · Độ khó: Nâng cao — bài gốc
Phần tiếp của OpenAI 2018.
Bối cảnh
- Một cụm duy nhất 7.500 node, chọn vì hạ tầng đơn giản cho phép team nghiên cứu scale mà không đổi code.
- Workload khác hẳn công ty thông thường:
- một job ML lớn chiếm trọn các node (GPU nói chuyện trực tiếp qua NVLink), nên ít tranh tài nguyên;
- scheduler chịu tải theo đợt: một job tạo hàng trăm pod cùng lúc;
- job MPI: một pod chết là cả job dừng và chạy lại từ checkpoint ("bán trạng thái");
- hầu như không dùng load balancing hay canary của Kubernetes; dữ liệu đọc từ blob storage.
Thay đổi chính
- Mạng: bỏ Flannel, dùng mạng pod native của Azure VMSS (IP alias), đạt băng thông như host. Cụm lớn nhất có thể dùng khoảng 200.000 IP; route-based thì bị giới hạn số route. Đếm lưu lượng nội bộ và Internet theo namespace bằng iptables mangle + exporter.
- API server và etcd chạy trên node riêng, ngoài cụm: 5 API server và 5 etcd cho cụm lớn nhất. Mỗi API server dùng tới 70 GB heap, tăng tuyến tính theo số node.
- Tải lớn nhất là WATCH trên Endpoints: service mà mọi node đều là thành viên (kubelet, node-exporter), thêm hay bớt một node là bắn tới mọi node. Lưu lượng tăng theo N², có lúc 1 GB/s hoặc hơn. EndpointSlices (Kubernetes 1.17) giảm tải khoảng 1.000 lần.
- Nguyên tắc: cảnh giác mọi request tới API server tăng theo kích thước cụm; tránh DaemonSet gọi API server, nếu cần thì qua một lớp cache trung gian.
- Thêm hàng trăm node cùng lúc làm quá tải API server; chỉ cần dàn đều vài giây là đỡ.
- Prometheus: quá nhiều metric; OOM do Grafana gọi
/api/v1/seriesvới truy vấn lấy mọi histogram. Restart thì replay WAL mất nhiều giờ. Đang chuyển sang hệ khác. - Health check:
- thụ động (lỗi ECC của GPU, đĩa, mạng, sự kiện bảo trì của cloud) thì tự cordon, nặng thì evict;
- chủ động: "preflight" chạy test GPU khi node mới vào (node mang taint tới khi qua test), và chạy định kỳ bằng CronJob.
- Quota theo team: service
team-resource-managergắn taint theo team, admission webhook gắn toleration theo người gửi job. "Bóng bay" CPU/GPU: pod ưu tiên thấp giữ chỗ để autoscaler không xoá node rảnh (họ dùng autoscaler để thay node hỏng), và bị đá ra ngay khi có job thật. - Gang scheduling: hai thí nghiệm cùng xin 100% cụm thì scheduler mặc định có thể cấp mỗi bên một nửa và cả hai đều kẹt. Họ dùng plugin Coscheduling (Kubernetes 1.18).
- Chưa giải: lưu trữ metric; định hình băng thông Internet của pod.
Bài học cho SWE
- Ở quy mô lớn, mọi thứ tỷ lệ với N (WATCH, agent mỗi node, request khi node vào cụm) đều thành bão vào control plane. Tương tự thundering herd ở tầng ứng dụng (Hot partition và thundering herd).
- Nền tảng nội bộ phải được thiết kế theo workload thật (batch, gang, GPU), không theo mặc định của công cụ (Nền tảng nội bộ cho service (đường ray chung)).
- Kiểm tra phần cứng trước khi nhận việc (preflight) là health check quan trọng khi phần cứng có thể hỏng âm thầm.
Liên quan
Nền tảng nội bộ cho service (đường ray chung)Hot partition và thundering herdTự động hoá vận hành và auto-remediation
Được nhắc tới trong
Chủ đề (4)
Công ty (1)