Nguyên tắc: đi từ dưới lên
Sai lầm phổ biến nhất khi debug kết nối là nhảy thẳng vào log HTTP hoặc blame application trong khi vấn đề ở tầng thấp hơn.
Quy trình đúng:
[1] Bước 1: DNS resolve — IP đúng chưa?
│
▼
[2] Bước 2: TCP connect — mở được socket không?
│
▼
[3] Bước 3: TLS handshake — cert hợp lệ không?
│
▼
[4] Bước 4: HTTP request — status code, response time?Dừng ở bước đầu tiên thất bại, không cần kiểm tra bước sau.
Bước 1, DNS: tên resolve đúng không?
# Kiểm tra nhanh
dig +short A api.example.com
# Kiểm tra với resolver cụ thể (bypass cache OS)
dig @8.8.8.8 +short A api.example.com
# Nếu trong Kubernetes: test từ trong Pod
kubectl exec -it debug-pod -- nslookup api.example.com
kubectl exec -it debug-pod -- dig +short A my-service.default.svc.cluster.local
Dấu hiệu lỗi:
- Trả về rỗng hoặc
NXDOMAIN→ tên không tồn tại, kiểm tra zone. - Trả về IP sai (IP cũ) → TTL chưa hết, hoặc split-horizon DNS trả kết quả khác.
SERVFAIL→ nameserver bị lỗi hoặc DNSSEC fail.
Bước 2, TCP: có mở được socket không?
# Test TCP connect đơn giản (không gửi dữ liệu)
nc -vz api.example.com 443
# Hoặc dùng bash built-in (không cần netcat)
timeout 5 bash -c 'cat < /dev/null > /dev/tcp/api.example.com/443' \
&& echo "TCP OK" || echo "TCP FAIL"
# Nếu cần test từ trong cluster
kubectl run -it --rm nettest --image=busybox --restart=Never -- \
nc -vz my-service 80
Đọc kết quả:
Connection to api.example.com 443 port [tcp/https] succeeded! → OK
nc: connect to api.example.com port 443 (tcp) failed: Connection refused
→ Process không LISTEN trên cổng đó (hoặc REJECT firewall)
(timeout sau 5s)
→ Firewall DROP gói SYN, hoặc routing sai
Bước 3, TLS + HTTP cùng lúc với curl -v
curl -v là công cụ tốt nhất để kiểm tra cả TLS và HTTP trong một lệnh:
curl -v --max-time 15 https://api.example.com/health 2>&1
# Đọc output theo phần:
# * Trying 93.184.216.34... → IP resolve từ DNS
# * Connected to api.example.com (93.184.216.34) port 443 → TCP OK
# * SSL connection using TLSv1.3 → TLS version
# * Server certificate:
# * subject: CN=api.example.com
# * start date: Jan 1 00:00:00 2026 GMT
# * expire date: Apr 1 00:00:00 2026 GMT
# * issuer: Let's Encrypt
# * SSL certificate verify ok → Trust chain OK
# > GET /health HTTP/2 → HTTP request
# < HTTP/2 200 → HTTP response
Các flag hữu ích:
# Bỏ qua verify cert (chỉ để test, không dùng production!)
curl -kv https://api.example.com
# Force HTTP version cụ thể
curl --http1.1 -v https://api.example.com
curl --http2 -v https://api.example.com
curl --http3 -v https://api.example.com # cần curl build kèm HTTP/3
# Xem ALPN chọn version nào
curl -v https://api.example.com 2>&1 | grep -E "ALPN|HTTP/"
# Đo thời gian từng phase
curl -w "\n\nDNS: %{time_namelookup}s\nTCP: %{time_connect}s\nTLS: %{time_appconnect}s\nTTFB: %{time_starttransfer}s\nTotal: %{time_total}s\n" \
-o /dev/null -s https://api.example.com
Bước 4, Phía server: ai đang listen cổng nào?
Khi có quyền SSH vào server/pod:
# Xem process nào đang listen cổng nào
ss -lntp
# Xem kết nối đang ESTABLISHED
ss -tnp state established
# Đếm kết nối theo trạng thái
ss -tan | awk '{print $1}' | sort | uniq -c | sort -rn
# Journal log service
journalctl -u nginx -n 100 --no-pager
Template báo sự cố
Khi mở ticket cho platform/infra team, luôn kèm:
URL: https://api.example.com/health
Thời điểm: 2026-04-18 09:30 UTC+7
Từ máy/pod: 10.0.1.50 (hoặc pod tên gì, namespace gì)
1. DNS:
dig +short A api.example.com → 93.184.216.34
(Hoặc: NXDOMAIN / IP khác với mong đợi)
2. TCP:
nc -vz api.example.com 443 → succeeded / refused / timeout
3. TLS + HTTP:
curl -sv https://api.example.com/health → [paste output rút gọn]
Thời gian: DNS=10ms, TCP=5ms, TLS=50ms, TTFB=2000ms
4. Error cụ thể:
HTTP 502 Bad Gateway / ERR_CERT_EXPIRED / Connection timeout...
Bảng tra nhanh: triệu chứng → nguyên nhân
| Triệu chứng | Tầng nghi ngờ | Bước kiểm tra |
|---|---|---|
NXDOMAIN hoặc resolve sai IP | DNS | dig @resolver-khác |
Connection refused nhanh | TCP (không có process) | ss -lntp trên server |
Connection timed out | TCP (firewall DROP / routing) | Kiểm tra SG / ip route |
ERR_CERT_* | TLS | openssl s_client -showcerts |
HTTP 502/504 | HTTP / LB timeout | So sánh timeout LB vs app |
| Kết nối ổn, response chậm | App / DB / upstream | Trace id, APM, app log |
Tóm tắt
- Đi từ dưới lên: DNS → TCP → TLS → HTTP, không bỏ bước.
curl -w+ timing là cách nhanh nhất phân tầng bottleneck.refusedvstimeouttiết kiệm rất nhiều thời gian debug.- Báo sự cố kèm output lệnh thay vì chỉ mô tả cảm giác “chậm” hay “không vào được”.
Câu hỏi hay gặp
TLS verify OK nhưng HTTP 502, bước tiếp theo là gì?
Trả lời: TLS đã xong; 502 là HTTP/proxy. Xem log LB/Ingress, upstream có healthy không, timeout giữa proxy và app, và response từ backend (upstream error).
nc tới 443 OK từ laptop nhưng timeout từ Pod, ba nguyên nhân thường gặp?
Trả lời: NetworkPolicy / firewall chặn egress từ Pod; DNS trong cluster trỏ IP khác hoặc đi đường khác; SNAT/NAT hoặc proxy bắt buộc mà app/pod chưa cấu hình.
time_connect rất nhỏ nhưng time_starttransfer rất lớn, lỗi ở đâu?
Trả lời: TCP/TLS nhanh; chờ lâu là server/app hoặc upstream (DB, API nội bộ). Tìm trace ID, log app, queue, hoặc query chậm, không phải lớp mạng cơ bản.
Bài tiếp theo (Giai đoạn III): Mạng Linux trên server, chuyển từ biết giao thức sang thao tác trực tiếp trên hệ thống.