An AKS Performance Journey: Part 2 — Networking It Out
Bài tóm tắt ASOS 2021 3. Quy mô lớn Độ khó: Khó
ASOS · 2021 · 3. Quy mô lớn · Độ khó: Khó — bài gốc
Phần 2/2. Phần 1: ASOS 2021 (SNAT, SKU, kích thước pod).
Bối cảnh
- Sau phần 1, PLP trên AKS vẫn chậm hơn Cloud Services khoảng 100 ms ở percentile cao. Log có nhiều timeout gọi API, kèm lỗi
getaddrinfo EAI_AGAINtừ NodeJS và các lần chờ đúng 5 giây.
Thay đổi chính
- Race của conntrack: DNS lookup trong pod đi qua ClusterIP của CoreDNS, kube-proxy (iptables) dùng DNAT. glibc và musl gửi truy vấn A và AAAA song song qua cùng một socket UDP; hai gói đua nhau qua DNAT, một gói bị kernel bỏ, client chờ timeout 5 giây rồi thử lại. Kiểm bằng counter
insert_failedcủaconntrack -S. SNAT cũng có race tương tự khi cấp cổng; cờ--random-fullycho MASQUERADE vào kube-proxy từ 9/2019 (Kubernetes 1.16) nhưng tới khoảng giữa 2020 cloud mới nâng iptables đủ để có tác dụng. - Các cách giảm race:
single-request-reopentrongdnsConfig(chỉ glibc, musl/Alpine không hỗ trợ); ép NodeJS chỉ dùng IPv4 (family: 4) để bỏ truy vấn AAAA; DNS qua TCP (use-vc), chậm hơn một chút mỗi lần nhưng bỏ được ca 3 lần thử × 5 giây; chạy DNS dạng daemonset để hai gói đua đi tới cùng một server. - Mặc định của Kubernetes nhân số truy vấn:
ndots: 5cộng bốn search domain làmwww.asos.combị thử bốn tên nội bộ trước tên thật, nhân hai vì A và AAAA, thành 10 lần resolve, tăng xác suất race. Dùng FQDN có dấu chấm cuối, hoặc đặtndots: 2: nhanh hơn 20% ở mọi percentile.dnsPolicy: Defaultnhanh hơn chút nhưng mất tên ngắn của Service. - NodeJS không hoàn toàn bất đồng bộ: DNS lookup là lời gọi đồng bộ, được đẩy sang thread pool libuv mặc định 4 thread. PLP có thể làm 5 lookup đồng thời nên pool đầy, lookup xếp hàng và request timeout trước khi kịp bắt đầu.
UV_THREADPOOL_SIZE=8nhanh hơn khoảng 3% và latency mượt hơn hẳn. - Keep-alive: theo gợi ý của Microsoft, dùng lại kết nối HTTP (agent
keepAlive, góiagentkeepalive) để bớt DNS, handshake và cổng SNAT mới, đồng thời giảm tải DNAT/SNAT: latency giảm một nửa ở hầu hết percentile.
Kết quả (theo ASOS)
- Tổng hợp các thay đổi, AKS nhanh hơn Cloud Services khoảng 30% (so với Cloud Services đã áp cùng thay đổi NodeJS), và hơn hai lần so với mốc Cloud Services ban đầu; đã chạy production vài tháng.
- Hướng tiếp: NodeLocal DNSCache (cache DNS trên mỗi node, nói với CoreDNS qua TCP; AKS chưa hỗ trợ vào 2/2021) và chế độ Transparent của Azure CNI (1/2021, giảm race conntrack).
Vì sao
- Latency đuôi đến từ những chi phí cố định cho mỗi kết nối ra ngoài (DNS, NAT, handshake) bị nhân lên bởi mặc định của nền tảng; dùng lại kết nối là cách gỡ nhiều nhất vì nó trả chi phí đó một lần cho nhiều request (Batching và khấu hao round-trip).
- Đổi nền tảng chạy làm lộ hành vi của tầng mạng mà ứng dụng không hề đổi; phải đo ở tải thật trước khi chuyển (Migration không downtime).
Bài học cho SWE
- Thấy timeout đều đặn 5 giây trên Kubernetes thì nghĩ tới DNS và conntrack trước.
- Kiểm tra
ndotsvà search domain; tên ngoài nên là FQDN. - Bật keep-alive cho client HTTP gọi service khác; nó giảm cả latency lẫn tài nguyên NAT.
- Thread pool ẩn của runtime (libuv) cũng là một hàng đợi có giới hạn.
Liên quan
- ASOS 2021 · Kubernetes 2018 (kube-proxy) · Neon 2025 · ClickHouse 2025 (conntrack để đo lưu lượng)
- Migration không downtime · Batching và khấu hao round-trip
#Kubernetes DNS#conntrack race#DNAT#SNAT#insert_failed#ndots#dnsPolicy#single-request-reopen#libuv thread pool#Keep-alive#NodeLocal DNSCache#Azure CNI
Được nhắc tới trong
Công ty (1)
Bài tóm tắt (2)