개요
기본편에서 IP, TCP/UDP, DNS, HTTP, 포트, 방화벽, 로드밸런서를 다뤘습니다.
이 글은 그 위에서 “왜 그렇게 동작하는가"와 “클라우드에서 어떻게 설계하는가"를 다룹니다.
1. OSI 7계층과 TCP/IP 4계층
정리 보기
왜 계층을 나누는가
계층으로 나누면 각 층이 자기 역할만 하고, 문제가 생겼을 때 “몇 계층 문제인지” 좁힐 수 있습니다.
OSI 7계층
| 계층 | 이름 | 하는 일 | 대표 프로토콜/장비 |
|---|---|---|---|
| 7 | Application | 사용자와 직접 상호작용 | HTTP, DNS, SSH |
| 6 | Presentation | 데이터 변환/암호화 | TLS/SSL, JPEG (TLS의 계층 배치는 관례적 분류이며 공식 매핑은 없음) |
| 5 | Session | 연결 세션 관리 | 소켓 연결 유지 |
| 4 | Transport | 포트 기반 통신, 신뢰성 | TCP, UDP |
| 3 | Network | IP 주소 기반 라우팅 | IP, ICMP, 라우터 |
| 2 | Data Link | MAC 주소 기반 전달 | 이더넷, 스위치, ARP |
| 1 | Physical | 전기/광 신호 전송 | 케이블, 허브 |
TCP/IP 4계층 (실제 인터넷이 쓰는 모델)
| 계층 | OSI 대응 | 대표 |
|---|---|---|
| Application | 5~7 | HTTP, DNS, SSH |
| Transport | 4 | TCP, UDP |
| Internet | 3 | IP, ICMP |
| Network Access | 1~2 | 이더넷, Wi-Fi |
OSI는 참조 모델이고, 인터넷 프로토콜 스택은 TCP/IP 모델로 구현됩니다.
적용 예시
계층별로 동작하는 대상
- ICMP (ping): L3
- 포트 기반 필터링 (방화벽): L4
- HTTP 요청/응답: L7
- 로드밸런서: L4 (NLB) vs L7 (ALB)2. URL 입력부터 화면까지 — End-to-End 흐름
정리 보기
URL 입력부터 화면 표시까지의 단계
1. URL 파싱
브라우저가 https://example.com/api를 프로토콜, 호스트, 경로로 분리
2. DNS 조회
브라우저 캐시 → OS 캐시 → DNS Resolver → Root → TLD → 권한 DNS
→ IP 주소 획득 (예: 93.184.216.34)
3. TCP 연결 (3-way Handshake)
SYN → SYN+ACK → ACK
→ 연결 수립 (ESTABLISHED)
4. TLS 핸드셰이크 (HTTPS인 경우)
ClientHello → ServerHello + 인증서 → 키 교환 → 세션 키 생성
→ 암호화 채널 확립
5. HTTP 요청 전송
GET /api HTTP/1.1
Host: example.com
6. 서버 처리 + HTTP 응답
HTTP/1.1 200 OK
Content-Type: application/json
...
7. 브라우저 렌더링
HTML 파싱 → DOM 생성 → CSS 적용 → JS 실행 → 화면 표시
8. 연결 유지 또는 종료
Keep-Alive → 재사용 / 또는 4-way Handshake로 종료3. ARP — MAC 주소 찾기
정리 보기
ARP (Address Resolution Protocol) = IP → MAC 주소 변환
같은 서브넷 안에서 통신하려면 상대방의 MAC 주소를 알아야 합니다. IP만 알고 있을 때 ARP로 MAC을 찾습니다.
A (10.0.0.5) → "10.0.0.10의 MAC 주소가 뭐야?" (브로드캐스트)
B (10.0.0.10) → "내 MAC은 aa:bb:cc:dd:ee:ff야" (유니캐스트 응답)동작 흐름
1. A가 10.0.0.10에 패킷을 보내려 함
2. ARP 캐시에 10.0.0.10의 MAC이 없음
3. ARP Request 브로드캐스트 (ff:ff:ff:ff:ff:ff)
4. 10.0.0.10이 자신의 MAC으로 ARP Reply
5. A가 ARP 캐시에 저장 → 이후 직접 통신다른 서브넷으로 보낼 때
A (10.0.0.5) → B (10.0.1.20) 로 보내려면:
- 목적지 IP: 10.0.1.20 (다른 서브넷)
- 목적지 MAC: 게이트웨이(라우터)의 MAC ← ARP로 조회
- 라우터가 받아서 다음 홉으로 전달IP는 end-to-end, MAC은 hop-by-hop입니다. 라우터를 지날 때마다 MAC은 바뀌지만 IP는 그대로입니다.
확인 명령어
# ARP 캐시 확인
arp -a
ip neigh show
# ARP 캐시 삭제 (디버깅용)
sudo ip neigh flush all핵심 포인트
- ARP는 L2(Data Link)에서 동작
- ARP Spoofing: 공격자가 거짓 ARP Reply를 보내 트래픽을 가로챔 (MITM 공격)
- GARP (Gratuitous ARP): 자기 IP에 대해 스스로 ARP를 보냄 → IP 충돌 감지, 페일오버 시 MAC 갱신
4. TCP 3-way / 4-way Handshake 상세
정리 보기
연결 수립 — 3-way Handshake
클라이언트 서버
│── SYN (seq=x) ───────────→│
│←─ SYN+ACK (seq=y, ack=x+1)│
│── ACK (ack=y+1) ──────────→│
│ → ESTABLISHED- 각 단계에서 시퀀스 번호를 교환 → 이후 데이터 순서 보장의 기준점
연결 종료 — 4-way Handshake
클라이언트 서버
│── FIN ────────────────────→│
│←─ ACK ─────────────────────│
│ (서버가 남은 데이터 전송) │
│←─ FIN ─────────────────────│
│── ACK ────────────────────→│
│ → 연결 종료TIME_WAIT
마지막 ACK 후 클라이언트는 2×MSL(Maximum Segment Lifetime) 동안 TIME_WAIT 상태로 대기합니다. MSL은 세그먼트가 네트워크에 존재할 수 있는 최대 시간으로 TCP 명세(RFC 9293)에서 2분으로 정의하지만, MSL 값과 실제 대기 시간은 운영체제 구현과 설정에 따라 다릅니다.
- 이유: 마지막 ACK가 유실됐을 때 상대방의 FIN 재전송을 처리하기 위해
- TIME_WAIT 소켓 수가 로컬 포트 범위를 소진하면 새 연결을 맺지 못할 수 있습니다
# TIME_WAIT 소켓 수 확인
ss -s
netstat -an | grep TIME_WAIT | wc -lSYN Flood 공격
- 공격자가 SYN만 대량으로 보내고 ACK를 안 보냄
- 서버의 SYN 큐(backlog)가 가득 참 → 정상 연결 불가
- Linux는
net.ipv4.tcp_syncookies로 SYN Cookie를 제어합니다
핵심 포인트
- “왜 3-way인가?” → 양쪽 모두 보내기/받기가 가능한지 확인하려면 최소 3번 필요
- “왜 종료는 4-way인가?” → 한쪽이 FIN을 보내도 상대방은 아직 보낼 데이터가 있을 수 있음 (half-close)
- graceful shutdown: SIGTERM → 새 연결 거부 → 기존 연결 처리 완료 → 종료
5. TCP 혼잡 제어 (Congestion Control)
정리 보기
문제: 네트워크가 감당할 수 있는 것보다 더 빨리 보내면?
패킷이 라우터 큐에 쌓이고, 넘치면 버려집니다. TCP는 이걸 감지하고 스스로 속도를 조절합니다.
핵심 개념
| 용어 | 의미 |
|---|---|
| cwnd (Congestion Window) | 송신자가 ACK 없이 보낼 수 있는 데이터 양 |
| rwnd (Receive Window) | 수신자가 받을 수 있는 버퍼 크기 |
| 실제 전송량 | min(cwnd, rwnd) |
| MSS (Maximum Segment Size) | TCP 세그먼트 하나의 최대 데이터 크기 |
혼잡 제어 4단계
1. Slow Start (느린 시작)
- 초기 cwnd(IW)는 RFC 3390에서 2~4 세그먼트, RFC 6928에서 10 세그먼트를 제안
- ACK를 받을 때마다 cwnd를 늘려 RTT마다 약 2배로 증가
- ssthresh(임계값)에 도달하면 → Congestion Avoidance로 전환
2. Congestion Avoidance (혼잡 회피)
- cwnd를 RTT당 약 1 SMSS씩 증가 (선형 증가 = AIMD의 AI)
- 패킷 유실 감지 시 → ssthresh를 줄이고 cwnd 감소
3. Fast Retransmit
- 중복 ACK 3번 수신 → 타임아웃 기다리지 않고 즉시 재전송
4. Fast Recovery
- RFC 5681 기준 ssthresh = max(FlightSize/2, 2×SMSS), cwnd = ssthresh + 3×SMSS
- 재전송 타임아웃(RTO) 시: cwnd를 1 SMSS까지 줄이고 Slow Start부터 다시AIMD (Additive Increase, Multiplicative Decrease)
정상: cwnd를 조금씩 늘림 (+1 MSS per RTT)
유실: cwnd를 절반으로 줄임 (×0.5)
→ 톱니바퀴 모양 그래프가 그려짐현대 혼잡 제어 알고리즘
| 알고리즘 | 특징 |
|---|---|
| Reno/NewReno | 전통적 AIMD |
| CUBIC | Linux 커널의 기본 혼잡 제어 알고리즘. RTT에 덜 민감 |
| BBR (Google) | 대역폭+RTT 기반. 유실이 아닌 지연으로 판단 |
# 현재 사용 중인 혼잡 제어 알고리즘 확인
sysctl net.ipv4.tcp_congestion_control
# 변경
sudo sysctl -w net.ipv4.tcp_congestion_control=bbr핵심 포인트
- “Slow Start가 왜 필요한가?” → 네트워크 용량을 모르는 상태에서 한꺼번에 보내면 혼잡 유발
- “CUBIC과 BBR의 차이?” → CUBIC은 패킷 유실 기반, BBR은 대역폭·RTT 측정 기반
- 혼잡 제어 알고리즘의 동작은 경로의 대역폭, 지연, 유실 특성에 따라 달라집니다
6. MTU, MSS, Fragmentation
정리 보기
MTU (Maximum Transmission Unit)
한 번에 보낼 수 있는 L2 프레임의 최대 크기입니다. 이더넷 기본 MTU = 1500 bytes.
이더넷 프레임:
[이더넷 헤더 14B] [IP 헤더 20B] [TCP 헤더 20B] [데이터 ≤ 1460B] [FCS 4B]
└── MSS
└────────────── MTU (1500B) ───────────────────┘MSS (Maximum Segment Size)
TCP가 한 세그먼트에 담을 수 있는 최대 데이터 크기 = MTU - IP 헤더(20B) - TCP 헤더(20B) = 1460 bytes
패킷이 MTU보다 크면?
| 상황 | 동작 |
|---|---|
| DF(Don’t Fragment) 비트 없음 | 라우터가 분할(fragmentation) |
| DF 비트 설정 | 라우터가 ICMP “Fragmentation Needed” 반환 → 재전송 |
| Path MTU Discovery | DF 비트 설정 + ICMP 응답으로 경로의 최소 MTU 탐색 |
MTU 문제가 생기는 경우
1. VPN/터널링: 원본 패킷에 터널 헤더가 추가됨
예: IPsec → 모드와 암호 스위트에 따라 오버헤드가 달라짐 → 유효 MTU 감소
2. 컨테이너 오버레이 네트워크 (VXLAN)
VXLAN 캡슐화는 50바이트를 추가하므로 내부 인터페이스의 유효 MTU가 그만큼 줄어듦
3. 클라우드 환경별 MTU 상한
트래픽 종류에 따라 상한이 다름
- 1500: 인터넷 게이트웨이, VPN 연결, 리전 간 트래픽(Transit Gateway 미사용)
- 8500: 리전 간 VPC 피어링
- 9001: 현재 세대 인스턴스의 VPC 내부 점보 프레임디버깅
# Path MTU 확인 (DF 비트 설정하여 테스트)
ping -M do -s 1472 target-ip # Linux
ping -D -s 1472 target-ip # macOS
# 1472 + 28 (IP+ICMP 헤더) = 1500 → 통과하면 MTU ≥ 1500
# 안 되면 -s 값을 줄여가며 최대 MTU 탐색
# 인터페이스 MTU 확인/변경
ip link show eth0
sudo ip link set eth0 mtu 1450핵심 포인트
- Path MTU Discovery는 ICMP Fragmentation Needed 메시지에 의존합니다
- Kubernetes에서 CNI 플러그인별 MTU 설정이 다름 (Calico, Cilium 등)
7. Keep-Alive와 Connection Pooling
정리 보기
문제: 매 요청마다 TCP + TLS 핸드셰이크를 반복하면 느림
연결 비용:
- TCP 3-way Handshake: 1 RTT
- TLS Handshake: 1~2 RTT
- 합계: 2~3 RTT를 매 요청마다 소비
계산 예시: RTT가 50ms인 경우 → 2~3 RTT = 매 요청마다 100~150ms 오버헤드HTTP Keep-Alive
하나의 TCP 연결로 여러 HTTP 요청/응답을 주고받습니다.
기존 (HTTP/1.0):
연결 → 요청 → 응답 → 끊기 → 연결 → 요청 → 응답 → 끊기
Keep-Alive (HTTP/1.1 기본):
연결 → 요청 → 응답 → 요청 → 응답 → ... → 타임아웃 후 끊기- HTTP/1.1에서는
Connection: keep-alive가 기본 - 서버 설정:
keepalive_timeout 65;(nginx)
Connection Pooling
애플리케이션이 DB나 외부 API에 연결할 때, 매번 새로 만들지 않고 풀(pool)에서 재사용합니다.
[App] ←→ [Connection Pool] ←→ [DB]
미리 연결 생성 + 반납 후 재사용- TIME_WAIT 소켓 감소
- 연결 생성 비용 절약
- DB 연결 수 제한 관리 가능
HTTP/2 멀티플렉싱
HTTP/1.1: 하나의 연결에서 요청은 순차적 (Head-of-Line Blocking)
HTTP/2: 하나의 연결에서 여러 요청을 동시에 (스트림 기반)
HTTP/3: QUIC (UDP 기반) → 연결 수립 0-RTT 가능설정 예시
# nginx keepalive 설정
upstream backend {
server 10.0.0.10:8080;
keepalive 32; # 백엔드와의 연결 풀 크기
}
# Node.js HTTP agent
const agent = new http.Agent({
keepAlive: true,
maxSockets: 50,
keepAliveMsecs: 30000
});핵심 포인트
- “HTTP/1.1 vs HTTP/2 차이?” → 멀티플렉싱, 헤더 압축, 서버 푸시
- “QUIC이 뭐가 다른가?” → UDP 기반, 0-RTT 연결, HoL Blocking 해결
8. NAT — 주소 변환
정리 보기
NAT = 사설 IP ↔ 공인 IP 변환
IPv4 주소가 부족하므로, 내부망은 사설 IP를 쓰고 외부로 나갈 때만 공인 IP로 바꿉니다.
[PC: 192.168.0.10:54321] → [NAT Gateway] → [인터넷: 203.0.113.5:10001]
사설 IP:포트 → 공인 IP:포트NAT 종류
| 종류 | 동작 | 용도 |
|---|---|---|
| SNAT (Source NAT) | 출발지 IP 변환 | 사설→공인으로 나갈 때 |
| DNAT (Destination NAT) | 목적지 IP 변환 | 외부→내부 서버로 들어올 때 (포트포워딩) |
| PAT / NAPT | IP + 포트 함께 변환 | 여러 사설 IP가 하나의 공인 IP 공유 |
여러 사설 IP가 하나의 공인 IP를 공유해야 하는 환경에서는 포트까지 변환하는 PAT 방식을 사용합니다. 공인 IP 하나를 포트 번호로 구분해 여러 내부 연결을 동시에 처리합니다.
클라우드에서의 NAT
AWS:
[Private Subnet EC2/Pod] → [NAT Gateway (EIP)] → [인터넷]
- 프라이빗 서브넷의 아웃바운드 트래픽은 라우트 테이블이 가리키는 NAT 장치를 거침
- 반대로 외부→내부는 ALB/NLB가 담당
- AWS 문서는 AZ 단위 장애 영향을 줄이기 위해 가용 영역마다 NAT Gateway를 두는 구성을 설명함Kubernetes에서 NAT
Pod IP (10.244.1.5) → Node의 IP로 SNAT → 외부
- Pod에서 외부 API 호출 시 외부에서 보이는 IP = Node IP (또는 NAT GW IP)
- externalTrafficPolicy: Local → 클라이언트 원본 IP 보존# NAT 규칙 확인
iptables -t nat -L -n -v
# 현재 공인 IP 확인
curl -s ifconfig.me핵심 포인트
- “Pod에서 외부 호출 시 IP가 뭐로 보이나?” → SNAT 이해
- conntrack 테이블이 가득 차면 새 연결 추적에 실패할 수 있습니다
9. HTTPS와 TLS Handshake
정리 보기
TLS = TCP 위에 암호화 계층을 추가
HTTP는 평문입니다. 중간에 가로채면 내용이 다 보입니다. TLS가 이걸 암호화합니다.
TLS 1.3 Handshake (현재 표준)
클라이언트 서버
│── ClientHello + 키 공유 ──────→│ (1 RTT)
│←─ ServerHello + 인증서 + Finished│
│── Finished ──────────────────→│
│ → 암호화 통신 시작TLS 1.3은 1 RTT로 핸드셰이크 완료 (TLS 1.2는 2 RTT). 0-RTT 재접속도 지원.
인증서 체인
Root CA (브라우저/OS에 내장)
└── Intermediate CA
└── 서버 인증서 (example.com)- 서버는 인증서 + Intermediate CA를 같이 보냄 (fullchain)
- 클라이언트가 Root CA까지 체인을 검증
mTLS (Mutual TLS)
일반 TLS: 클라이언트가 서버를 검증
mTLS: 서버도 클라이언트를 검증 (양방향)
→ 서비스 메시(Istio, Linkerd)에서 Pod 간 통신 인증에 사용확인 명령어
# 인증서 체인 + 만료일 확인
echo | openssl s_client -connect example.com:443 -servername example.com 2>/dev/null | openssl x509 -noout -dates -issuer
# TLS 버전 확인
curl -vI https://example.com 2>&1 | grep "SSL connection"
# 인증서 디버깅
openssl s_client -connect example.com:443 -showcerts핵심 포인트
- “TLS 1.2 vs 1.3 차이?” → 핸드셰이크 RTT 감소, 불안전한 암호 스위트 제거
- “mTLS는 언제 쓰나?” → 서비스 메시, 내부 마이크로서비스 통신
- 만료된 인증서는 검증에 실패하며, 브라우저 경고와 API 통신 실패로 나타납니다
10. VPN과 터널링
정리 보기
VPN = 인터넷 위에 암호화된 사설 터널
물리적으로 떨어진 두 네트워크를 사설 IP로 통신할 수 있게 연결합니다.
종류
| 종류 | 용도 | 예시 |
|---|---|---|
| Site-to-Site | 네트워크 ↔ 네트워크 | 사무실 ↔ AWS VPC |
| Client VPN | 개인 PC → 사내망 | 재택근무 시 내부 DB 접근 |
터널링 프로토콜
| 프로토콜 | 특징 |
|---|---|
| IPsec | 표준 프로토콜 집합. Site-to-Site 연결에 사용 |
| WireGuard | 구현을 단순하게 유지하는 것을 목표로 설계된 프로토콜 |
| OpenVPN | TLS 기반. 설정 옵션이 많음 |
SSH 터널 (빠른 우회 접속)
# 로컬 포트포워딩
# 내 PC:3306 → jump-server 경유 → db-server:3306
ssh -L 3306:db-server:3306 user@jump-server
# 이후 localhost:3306으로 DB 접속
mysql -h 127.0.0.1 -P 3306
# 다이나믹 포트포워딩 (SOCKS 프록시)
ssh -D 8080 user@jump-server
# 브라우저 프록시를 localhost:8080으로 설정VPN vs Direct Connect
| VPN | Direct Connect (AWS) | |
|---|---|---|
| 경로 | 인터넷 | 전용 물리 회선 |
| 대역폭 | 인터넷 속도 한계 | 전용 회선 속도를 선택해 사용 |
| 비용 | 저렴 | 비쌈 |
| 용도 | 일반 업무 | 대용량 데이터, 지연 민감 |
선택 가능한 포트 속도는 연결 방식에 따라 다릅니다. Dedicated Connection은 1/10/100/400 Gbps(400 Gbps는 일부 Direct Connect 위치에서만 제공), 파트너를 통한 Hosted Connection은 50 Mbps~25 Gbps 중에서 선택합니다.
핵심 포인트
- “VPN과 SSH 터널의 차이?” → VPN은 네트워크 레벨(L3), SSH 터널은 특정 포트만
- VPN은 원본 패킷에 터널 헤더를 추가하므로 터널 헤더만큼 유효 MTU가 줄어듭니다
11. VPC 네트워크 설계
정리 보기
VPC = 클라우드 안의 격리된 사설 네트워크
구성요소
| 구성요소 | 역할 |
|---|---|
| VPC | 전체 IP 공간 (예: 10.0.0.0/16) |
| Subnet | VPC를 나눈 소단위. AZ에 종속 |
| Route Table | 패킷이 어디로 갈지 규칙 |
| Internet Gateway | VPC ↔ 인터넷 |
| NAT Gateway | Private → 인터넷 (아웃바운드만) |
| Security Group | 인스턴스 레벨 방화벽 (Stateful) |
| NACL | 서브넷 레벨 방화벽 (Stateless) |
표준 3-tier 아키텍처
┌──────────── VPC: 10.0.0.0/16 ────────────┐
│ │
│ Public Subnet (10.0.1.0/24) │
│ → ALB, NAT Gateway, Bastion │
│ │ │
│ Private Subnet (10.0.10.0/24) │
│ → App Server, EKS Pod │
│ │ │
│ DB Subnet (10.0.20.0/24) │
│ → RDS, ElastiCache │
│ │
└───────────────────────────────────────────┘- Public: 인터넷에서 직접 접근 가능 (IGW 라우트)
- Private: ALB를 통해서만 접근. 인터넷 나갈 때는 NAT GW
- DB: App에서만 접근. 인터넷 접근 없음
서브넷 사이징
- AWS는 서브넷당 5개 IP를 예약합니다 (네트워크, 라우터, DNS, 예비, 브로드캐스트). /24라면 251개를 쓸 수 있습니다
- 생성한 서브넷의 CIDR 블록은 나중에 변경할 수 없습니다
Multi-AZ 설계
AZ-a: Public-a, Private-a, DB-a
AZ-b: Public-b, Private-b, DB-b
(필요 시 AZ-c도)
→ 하나의 AZ 장애 시에도 서비스 유지VPC Peering / Transit Gateway
VPC Peering: VPC 간 직접 연결 (1:1, 비전이적)
Transit Gateway: 허브 역할. 여러 VPC + VPN을 중앙 연결핵심 포인트
- “Public Subnet vs Private Subnet 차이?” → Route Table에 IGW가 있느냐 없느냐
- “서브넷을 왜 AZ별로 나누나?” → 고가용성 + AZ 장애 격리
12. DNS 심화 — TTL과 라우팅 정책
정리 보기
기본편에서 DNS 레코드 타입(A, CNAME, MX 등)은 다뤘습니다. 여기서는 TTL과 라우팅 정책을 다룹니다.
TTL
TTL: 리졸버가 응답을 캐시에 유지할 수 있는 시간(초)
캐시된 TTL이 남아 있는 동안 리졸버는 권한 서버에 다시 질의하지 않음
→ 레코드를 변경해도 TTL이 만료되기 전까지 이전 값이 반환될 수 있음라우팅 정책 (Route 53 / Cloud DNS)
| 정책 | 동작 | 용도 |
|---|---|---|
| Simple | 단순 매핑 | 기본 |
| Weighted | 비율 분배 (90:10) | Canary 배포, A/B 테스트 |
| Latency | 지연 시간이 가장 낮은 리전으로 | 글로벌 서비스 |
| Failover | Primary 장애 시 Secondary | DR (재해복구) |
| Geolocation | 접속 국가/지역 기반 | 국가별 다른 서버 |
Failover 구성 예시
example.com → Primary: Seoul ALB (헬스체크 OK)
→ Secondary: Tokyo ALB (Primary 실패 시 전환)
헬스체크 실패 → DNS가 자동으로 Secondary IP 반환DNS + 로드밸런서 조합
글로벌 라우팅: DNS Latency-based → 가장 가까운 리전
리전 내 분산: ALB/NLB → 여러 인스턴스/Pod
예:
미국 사용자 → us-east-1 ALB → Pod A, B, C
한국 사용자 → ap-northeast-2 ALB → Pod D, E, F핵심 포인트
- Failover로 레코드가 바뀌어도 리졸버의 캐시가 만료될 때까지는 이전 값이 반환될 수 있습니다