DNS Debugging: Resolution Path and TTL Issues
Tại sao DNS Debugging Quan Trọng
"Cannot resolve hostname" (Không thể phân giải tên miền) thường bị lầm tưởng là sự cố mạng (network issue), nhưng thực chất lại là vấn đề ở tầng ứng dụng (application layer). Quy trình phân giải tên miền (DNS resolution path) trên GCP có sự khác biệt so với các trung tâm dữ liệu truyền thống (traditional datacenter):
- Compute Engine internal DNS (169.254.169.254)
- Cloud DNS managed zones
- Fallback tới external nameservers
- Caching ở nhiều tầng khác nhau (multiple levels)
Hiểu rõ resolution path là điều bắt buộc vì các sự cố DNS rất khó debug — cơ chế caching che giấu nguyên nhân gốc rễ, TTL tạo ra độ trễ cập nhật, và việc fallback sang external DNS sẽ làm tăng latency.
Quy trình bên trong: DNS Resolution Path
Khi VM gửi một DNS query, resolver sẽ thực hiện theo tuần tự đường dẫn được sắp xếp sẵn (ordered path):
Bước 1: Kiểm tra Local Cache
Resolver của VM (như systemd-resolved, dnsmasq, v.v.) kiểm tra local cache:
$ nslookup app.myservice.local
Name: app.myservice.local
Address: 10.0.1.5 (lấy từ cache, dữ liệu mới)Tuân thủ TTL: Thời gian cache được quyết định bởi giá trị TTL từ phản hồi DNS. Ví dụ, nếu response TTL=60s, thông tin trong cache sẽ có hiệu lực trong 60 giây.
Bước 2: Truy vấn Compute Engine Metadata Server (169.254.169.254)
Nếu không có trong local cache, VM sẽ gửi truy vấn tới resolver được tích hợp sẵn của Compute Engine (Compute Engine's built-in resolver):
Query: app.myservice.local
→ Destination: 169.254.169.254:53Metadata server hoạt động như sau:
- Kiểm tra internal zone — Kiểm tra Cloud DNS private zones hoặc internal DNS.
- Kiểm tra Compute Engine DNS — Tự động tạo các record cho các instance.
- Nếu tìm thấy: Trả về kết quả, bao gồm cả TTL.
- Nếu không tìm thấy: Chuyển tiếp sang bước tiếp theo.
Internal Zones:
# Tạo private zone
gcloud dns managed-zones create internal-zone \
--zone-type=private \
--networks=defaultBước 3: Cloud DNS Managed Zones
Nếu không thuộc internal zone, hệ thống kiểm tra Cloud DNS managed zones có thể truy cập từ VPC này:
# Tạo public zone (truy cập được từ mọi nơi)
gcloud dns managed-zones create public-zone \
--zone-type=public
# Tạo private zone (chỉ định riêng cho VPC)
gcloud dns managed-zones create private-zone \
--zone-type=private \
--networks=default,other-network # Chỉ truy cập được trong các VPC nàyMetadata server kiểm tra các zone theo thứ tự:
- Các private zone liên kết với VPC của VM.
- Các public zone.
Bước 4: Fallback sang External Nameservers
Nếu vẫn không thể phân giải, metadata server sẽ chuyển tiếp truy vấn tới các external nameservers (như 8.8.8.8, v.v.):
app.external.com
→ Không có trong internal/Cloud DNS
→ Chuyển tiếp tới 8.8.8.8 (public Google nameserver)
→ Public nameserver phân giải và trả về kết quảHệ quả: Các truy vấn đến tên miền bên ngoài sẽ làm tăng latency (do phải đi qua internet tới public DNS).
Bước 5: Không tìm thấy (Not Found)
Nếu tất cả các bước trên đều không phân giải được, hệ thống trả về lỗi NXDOMAIN (tên miền không tồn tại).
Sơ đồ Quy trình Phân giải đầy đủ (Resolution Path)
Query: example.com
1. Kiểm tra local cache
├─ HIT: Trả về kết quả trong cache (theo TTL)
└─ MISS: Tiếp tục
2. Truy vấn metadata server (169.254.169.254)
├─ Khớp internal zone?
│ ├─ HIT: Trả về kết quả + TTL
│ └─ MISS: Tiếp tục
├─ Có record Compute Engine?
│ ├─ HIT: Trả về kết quả
│ └─ MISS: Tiếp tục
└─ Có Cloud DNS zones?
├─ HIT: Trả về kết quả + TTL
└─ MISS: Chuyển tiếp sang external
3. Chuyển tiếp tới external nameserver (8.8.8.8)
├─ HIT: Trả về kết quả + TTL
└─ MISS: Trả về NXDOMAIN
Kết quả: Trả về Answer hoặc lỗi NXDOMAINTTL và Caching
TTL = Time To Live, được tính bằng giây. Cơ chế Caching xảy ra ở nhiều tầng khác nhau:
Tầng 1: OS-Level Resolver Cache
Các chương trình như systemd-resolved trên Linux, mDNSResponder trên macOS:
# Xem thống kê cache (Linux)
systemd-resolve --statistics
# Hiển thị tỷ lệ hit cache, các thông tin trong cache
# Xóa cache
sudo systemctl restart systemd-resolved
# Hoặc dùng nscd:
sudo systemctl restart nscdĐảm bảo tuân thủ TTL: Thông tin trong cache sẽ tồn tại trong đúng số giây quy định của TTL. Sau khi TTL hết hạn, truy vấn tiếp theo sẽ lấy dữ liệu mới.
Tầng 2: Application Library Caching
Các thư viện như java.net.InetAddress, curl có thể tự lưu cache DNS:
// Java lưu cache DNS mặc định trong 300 giây
java.security.Security.setProperty("networkaddress.cache.ttl", "60")
// urllib của Python cũng hỗ trợ lưu cache
import socket
socket.setdefaulttimeout(60)Vấn đề: Cache của ứng dụng có thể ghi đè giá trị TTL. Nếu ứng dụng cấu hình cứng thời gian cache là 300s, thì DNS TTL 60s sẽ không được tuân thủ.
Tầng 3: GCP Metadata Server Caching
Compute Engine metadata server cũng lưu cache (chi tiết cơ chế nội bộ không được công bố công khai).
Hệ quả: Các thay đổi DNS sẽ có độ trễ cập nhật nhất định, cho đến khi TTL cũ hết hạn.
Các lỗi DNS thường gặp khi Debug
Trường hợp 1: Phân giải thành công nhưng kết nối thất bại
Triệu chứng:
$ nslookup app.myservice.local
Name: app.myservice.local
Address: 10.0.1.5
$ ping 10.0.1.5
PING 10.0.1.5 ...
64 bytes from 10.0.1.5: icmp_seq=1 ttl=64 time=1.234 ms
$ curl app.myservice.local:8080
Connection refusedNguyên nhân gốc rễ: DNS hoạt động bình thường (phân giải đúng IP), nhưng:
- Ứng dụng không lắng nghe (not listening) trên port đó.
- Firewall đang chặn port đó.
- Cấu hình sai thông số port.
Debug:
# Kiểm tra xem ứng dụng có lắng nghe port không
gcloud compute ssh vm-instance
sudo netstat -tlnp | grep 8080
# Nếu trống, ứng dụng chưa được khởi chạy hoặc không lắng nghe port này
# Kiểm tra firewall
gcloud compute firewall-rules list --filter="allow-list:tcp:8080"Trường hợp 2: Internal DNS không thể phân giải
Triệu chứng:
$ nslookup app.myservice.local
** server can't find app.myservice.local: SERVFAIL
$ nslookup google.com
Name: google.com
Address: 142.251.41.14 (external phân giải bình thường)Nguyên nhân gốc rễ: Internal DNS zone cấu hình sai hoặc record không tồn tại.
Debug:
# Liệt kê các zone
gcloud dns managed-zones list
# Liệt kê các record trong zone
gcloud dns record-sets list --zone=my-zone
# Kiểm tra xem private zone có thể truy cập được từ VPC của VM không
gcloud dns managed-zones describe my-zone
# Xem field: visibility (phải bao gồm VPC của VM)
# Test trực tiếp
gcloud compute ssh vm-instance
sudo dig app.myservice.local @169.254.169.254
# Sẽ phân giải được nếu zone cấu hình đúngCách sửa:
# Tạo/Cập nhật record
gcloud dns record-sets update app.myservice.local \
--zone=my-zone \
--type=A \
--ttl=300 \
--rrdatas=10.0.1.5
# Hoặc tạo mới
gcloud dns record-sets create app.myservice.local \
--zone=my-zone \
--type=A \
--ttl=300 \
--rrdatas=10.0.1.5Trường hợp 3: Lỗi phân giải chập chờn (Intermittent Resolution Failures)
Triệu chứng: Lúc phân giải được, lúc không. Không rõ quy luật.
Nguyên nhân gốc rễ: Thường do sự cố caching hoặc các record không nhất quán.
Nguyên nhân có thể:
- Cache của ứng dụng bị lỗi thời (outdated).
- TTL hết hạn giữa lúc kết nối.
- Sử dụng Round-robin DNS trả về các IP khác nhau.
- Cơ chế Failover chuyển đổi IP.
Debug:
# Kiểm tra TTL cache của ứng dụng
# (Xem kỹ tài liệu hướng dẫn của ứng dụng)
# Kiểm tra xem có cấu hình round-robin hay không
gcloud dns record-sets list --zone=my-zone \
--filter="name:app.myservice.local"
# Nếu có nhiều rrdatas, đó là cấu hình round-robin
# Xóa cache ứng dụng
# Khởi động lại ứng dụng hoặc invalidate cache
# Kích hoạt Cloud DNS query logging để theo dõi thêm:
gcloud dns logging create logging-config \
--managed-zone=my-zone
# Truy vấn logs trong Cloud LoggingTrường hợp 4: Latency DNS cao
Triệu chứng:
$ time nslookup app.myservice.local
real 0m2.345sNguyên nhân gốc rễ: Các truy vấn bị chuyển tiếp (fallback) ra external nameserver.
Debug:
# Kiểm tra xem internal zone đã được cấu hình chưa
gcloud dns managed-zones describe my-zone
# Nếu không phải private zone, hoặc không liên kết với VPC của VM, truy vấn sẽ ra ngoài internet
# Test latency từ VM
gcloud compute ssh vm-instance
time nslookup app.myservice.local
time nslookup google.com # So sánh latencyCách sửa: Đảm bảo cấu hình đúng internal zones:
gcloud dns managed-zones create internal-zone \
--zone-type=private \
--networks=default \
--dnssecstate=offTrường hợp 5: Đổi Record DNS nhưng client vẫn nhận IP cũ
Triệu chứng:
# Cập nhật record
gcloud dns record-sets update app.local --zone=my-zone --rrdatas=10.0.2.5
# Nhưng client vẫn kết nối đến IP cũ
ping app.local → 10.0.1.5 (IP cũ)Nguyên nhân gốc rễ: Bị lưu cache ở một trong các tầng:
- OS resolver cache (TTL vẫn còn hiệu lực).
- Cache của ứng dụng.
- Cache phía client (trình duyệt, OS).
Debug và khắc phục:
# Xóa cache của OS
sudo systemctl restart systemd-resolved
# Xóa cache ứng dụng
# Thường chỉ cần restart lại ứng dụng
# Xác thực record mới
nslookup app.local
# Phải hiển thị IP mới 10.0.2.5
# Chờ TTL cũ hết hạn trên toàn bộ hệ thống
# Giá trị TTL cũ quyết định thời gian chờ — nếu TTL cũ là 3600s, bạn phải chờ tối đa 1 tiếngCách phòng tránh:
- Cấu hình TTL thấp (60s) đối với các record thường xuyên thay đổi IP.
- Sử dụng TTL=300s mặc định (đây là mức cân bằng tốt).
DNS Query Logging
Kích hoạt Cloud DNS logging để giám sát hành vi phân giải tên miền:
# Tạo cấu hình logging
gcloud dns logging create logging-config \
--managed-zone=my-zone
# Xem logs trong Cloud Logging
# Logs hiển thị: query name, response code, latency, resolverCấu trúc Query Log:
{
"timestamp": "2026-06-26T15:30:45Z",
"queryName": "app.myservice.local",
"queryType": "A",
"responseCode": "NOERROR", // hoặc NXDOMAIN, SERVFAIL, v.v.
"queryLatencyMs": 2,
"clientIp": "10.0.1.2",
"protocol": "UDP"
}Các trường hợp sử dụng:
- Xác định các tên miền được truy vấn nhiều nhất.
- Phát hiện các lỗi NXDOMAIN.
- Đo lường latency phân giải tên miền.
- Debug các mã response code.
DNS Response Codes
Các mã phản hồi phổ biến:
| Code | Meaning | Action |
|---|---|---|
| NOERROR | Phân giải thành công | Bình thường |
| NXDOMAIN | Tên miền không tồn tại | Kiểm tra lại cấu hình zone |
| SERVFAIL | Lỗi DNS Server | Kiểm tra lại hoạt động của nameserver |
| FORMERR | Truy vấn sai định dạng | Lỗi client DNS |
| REFUSED | DNS Server từ chối phản hồi | Kiểm tra xem firewall có chặn DNS không |
| TIMEDOUT | Truy vấn bị timeout | Do nghẽn mạng hoặc server bị down |
Best Practices
1. Sử dụng Private Zones cho các Internal Services
# TỐT: Sử dụng internal zone cấu hình riêng cho VPC
gcloud dns managed-zones create internal \
--zone-type=private \
--networks=prod-vpc
# XẤU: Dựa vào public DNS cho các dịch vụ nội bộ
# (làm tăng latency và rủi ro bảo mật)2. Thiết lập cấu hình TTL hợp lý
# Đặt TTL thấp (60s) cho các record thường xuyên đổi IP
gcloud dns record-sets update service.local \
--zone=my-zone \
--type=A \
--ttl=60 \
--rrdatas=10.0.1.5
# Đặt TTL cao (3600s) cho các record ổn định, ít thay đổi
gcloud dns record-sets update static.local \
--zone=my-zone \
--type=A \
--ttl=3600 \
--rrdatas=10.0.1.53. Kiểm tra Phân giải DNS từ VM
# Từ phía VM
gcloud compute ssh vm-instance
nslookup -type=A app.myservice.local # Thực hiện truy vấn DNS
dig +short app.local # Sử dụng công cụ dig thay thế
# Chỉ định rõ nameserver để kiểm tra
nslookup app.local 169.254.169.254 # Trỏ trực tiếp server4. Giám sát status hoạt động của DNS
# Kiểm tra cấu hình zone
gcloud dns managed-zones describe my-zone
# Liệt kê các nameserver
gcloud dns managed-zones describe my-zone --format="value(nameServers)"
# Kiểm tra cập nhật của record
dig NS example.com @8.8.8.85. Sử dụng cơ chế Health-Check Driven TTL
Kết hợp health checks với DNS:
# Các Cloud Load Balancer health check có thể kích hoạt cơ chế DNS failover
# (thông qua cơ chế health-check-driven routing của Cloud DNS nếu có cấu hình)