Files
document-haness/docs/virtualization/tech-log-studio/network-virtualization/question/question-actual-packet-path-nginx-to-keycloak.md
T

111 lines
9.9 KiB
Markdown

---
id: 600a2621-f6d8-42df-9629-7db65011545d
kind: QUESTION
slug: actual-packet-path-nginx-to-keycloak
title: Host Nginx 에서 Keycloak 까지 packet 은 실제로 어디를 지나는가
topic: network-virtualization
topicName: 네트워크 가상화
project: virtualization
status: 초안
questionStatus: OPEN
studio: "https://hyeonworks.com/studio/documents/600a2621-f6d8-42df-9629-7db65011545d/edit"
sourceRevision: no-commit · 밖에서 반입한 문서 한 편. 고정할 저장소 리비전이 없다
source:
- final/document.md#122-open-question-oq-6
- final/document.md#116-현재-keycloak-k3s-테스트-환경과-연결
- final/document.md#119-실제-packet-path-추적
- final/document.md#94-전체-네트워크-계층
- final/document.md#125-최종-기준-구조
---
# Host Nginx 에서 Keycloak 까지 packet 은 실제로 어디를 지나는가
§116 은 이 테스트 환경의 요청 경로를 클라이언트에서 Keycloak 까지 한 줄로 그렸다. 가상 머신 네트워크까지 펼치면 물리 NIC 에서 브리지와 TAP 을 지나 vhost-net 과 virtqueue 를 거쳐 게스트 안으로 들어간다고 적었다. 그 펼친 그림은 §94 가 기준으로 삼은 구조를 이 환경에 얹은 것이고, 이 호스트에서 패킷을 잡아 본 결과가 아니다. 여기서 묻는 것은 호스트 Nginx 를 지난 요청이 실제로 어느 브리지와 어느 TAP 을 거쳐 어느 가상 머신으로 들어가는가 하나다.
## 관계
- **Guest 의 packet 이 Host Physical NIC 에 닿기까지 — virtio-net · virtqueue · vhost-net · TAP · Bridge**
§94 와 §125 가 그린 기준 경로를 이 개념이 설명한다. 이 물음은 그 경로가 이 호스트에서도 같은지를 묻는다.
- **packet 이 어디서 끊겼는지는 계층마다 capture 해서 가른다**
§119 가 든 계층별 캡처 방법을 규칙으로 편 기준이다. 요청이 중간에서 끊기면 그쪽이 받는다.
- **이 호스트의 가상 머신 네트워크는 Bridge 인가 NAT 인가 Routing 인가**
구성이 셋 중 무엇이냐에 따라 캡처를 걸 지점이 달라진다.
- **VM1 과 VM2 의 TAP/vnet interface 는 무엇이고 어디에 붙어 있는가**
tcpdump 를 걸 인터페이스의 이름을 그쪽이 댄다.
- **Keycloak 실험 결과를 애플리케이션 원인으로 읽기 전에 network 계층을 따로 검증한다**
§120 이 요구한 별도 검증에서 이 경로 확인이 첫 항목이 된다.
## 사실
- §116 이 그린 테스트 환경의 요청 경로
Client → Host Physical NIC → Host Nginx → Host Network → VM1 / VM2 → K3s → Keycloak Node 1 / 2
- §116 이 가상 머신 네트워크까지 펼친 경로
Client → Physical NIC → Host Network Stack / Bridge / Route / NAT → TAP(vm1) / TAP(vm2) → vhost-net → virtqueue → virtio-net → Guest Network Stack → K3s networking → Keycloak
- §116 은 그 뒤에 K3s 내부의 CNI · Service · Pod network 가 추가되므로 별도 계층으로 분석한다고 적었다.
- §94 는 이 문서가 기준으로 삼은 구조를 virtio-net + vhost-net + TAP + Linux Bridge 로 놓고 수신 방향과 송신 방향을 각각 그렸으며, 실제 환경이 Bridge · NAT · Routed Network · macvtap · SR-IOV · VFIO passthrough · Open vSwitch · Kubernetes CNI 에 따라 달라질 수 있다고 밝혔다.
- §125 는 같은 경로를 vhost-net 을 쓸 때와 QEMU backend 를 쓸 때로 나눠 다시 그렸다. 두 그림은 TAP 다음이 vhost-net 인지 QEMU virtio backend 인지에서 갈리고 나머지 구간은 같다.
- §119 는 경로를 확인하는 방법으로 호스트의 physical NIC · bridge · tap 또는 vnet 세 곳과 게스트의 guest interface 한 곳에 sudo tcpdump -ni 를 걸고, 어디까지 보이는지로 의심 구간을 좁히라고 적었다.
- §119 가 든 판정 예 셋
Physical NIC O · Bridge O · TAP X : Guest 내부보다 먼저 Host Bridge/TAP mapping 을 의심한다
TAP O · Guest NIC X : virtio/vhost/Guest NIC 계층을 의심한다
Guest NIC O · Socket X : Guest routing/firewall/listen 상태를 의심한다
- §122 OQ-6 은 Host NIC · Bridge · TAP · Guest NIC 에서 tcpdump 로 추적한다고만 적었다. 어느 이름의 인터페이스인지는 적혀 있지 않다.
- §116 의 그림은 앞부분과 뒷부분의 근거가 다르다. 호스트 Nginx 아래에 가상 머신 두 대가 있고 그 안에서 K3s 와 Keycloak 노드가 돈다는 앞부분은 §89 가 밝힌 실험 구성이고, 브리지와 라우팅·NAT, TAP, vhost-net 으로 펼친 뒷부분은 OQ-1 과 OQ-2, OQ-3 를 확인하기 전의 가정이다.
- 이 호스트에서 패킷을 잡아 본 기록이 없다. §116 이 펼친 경로는 확인한 결과가 아니라 §94 의 기준 구조를 이 환경에 얹은 그림이다.
## 가정
- 호스트 Nginx 를 통해 Keycloak 요청을 한 번 보낼 수 있고, 그 요청이 두 가상 머신 가운데 어느 쪽으로 갔는지 확인하는 쪽이 알 수 있다고 본다.
- 네 지점에 동시에 캡처를 걸어 둘 수 있다고 전제한다. 지점마다 따로 걸면 같은 요청을 본 것인지 갈리지 않는다.
- §116 이 그린 구조가 지금 실험 환경과 같다고 전제한다. 가상 머신이 둘이고 각각 K3s 노드와 Keycloak 을 돌린다는 것까지가 근거 문서에 적힌 전부다.
- 오프로드 설정이 캡처하는 동안 바뀌지 않는다.
## 미지수
- 호스트 Nginx 를 지난 요청이 어느 브리지를 거치는지, 그 브리지에서 어느 TAP 으로 나가는지.
- 그 TAP 이 두 가상 머신 가운데 어느 쪽의 인터페이스인지.
- 게스트 안의 인터페이스에서 같은 요청이 보이는지.
- 네 지점의 결과가 §116 이 펼친 그림과 같은지, 다르다면 어느 지점부터 다른지.
- 지금 오프로드 설정이 무엇인지. 캡처에서 본 패킷 크기와 체크섬을 wire 값으로 읽어도 되는지가 이것으로 갈린다.
## 제약
- 캡처 지점의 이름을 먼저 확정해야 한다. 어느 브리지와 어느 TAP 인지 모르면 tcpdump 를 걸 곳을 고르지 못한다. 그 이름은 네트워크 구성을 묻는 물음과 인터페이스를 묻는 물음이 댄다.
- K3s 안에서 Keycloak Pod 까지 가는 구간은 이 물음이 닫는 범위 밖이다. §116 이 CNI · Service · Pod network 를 별도 계층으로 미뤄 두었다.
- 요청이 중간 지점에서 끊기면 그것은 이 물음의 답이 아니라 장애다. §119 가 든 세 판정 예를 따라 의심 구간을 적고 계층별 캡처 기준으로 넘긴다.
- 이 호스트에서 잰 값이 없어 §116 의 그림을 확인된 경로로 삼지 않는다. 이 환경이 실제로 그렇다는 주장이라 재기 전에는 Case 도 Concept 도 아니라고 보고 근거가 모자란 후보로 남겨 두었으며, OQ-1 과 OQ-2, OQ-3, OQ-6 이 답하면 다시 판정한다.
## 선택지
### 1. 네 지점에 한 번에 걸고 요청을 한 번 보낸다
§119 가 든 호스트 세 지점과 게스트 한 지점에 동시에 tcpdump 를 걸어 두고, 호스트 Nginx 를 통해 Keycloak 요청을 한 번 보낸다. 같은 요청 하나가 네 지점에서 각각 보이는지로 경로가 확정되기 때문에 실행이 한 번으로 끝난다.
지점 이름을 미리 확정해 두어야 하고 네 곳을 동시에 열어 두어야 한다.
### 2. 바깥에서 안쪽으로 한 지점씩 옮겨 간다
물리 NIC 에서 시작해 브리지, TAP, 게스트 인터페이스 순으로 한 지점씩 옮기며 같은 요청을 반복해서 보낸다. 여러 곳을 동시에 열지 않아도 되고 어디서부터 안 보이는지가 바로 드러난다.
요청을 여러 번 보내야 해서 매번 같은 경로로 갔다고 전제해야 한다. 두 가상 머신에 요청이 번갈아 가면 그 전제가 깨진다.
### 3. 두 가상 머신 쪽 TAP 을 모두 열어 놓고 한 번 보낸다
VM1 과 VM2 의 TAP 을 둘 다 열어 두면 요청이 어느 쪽으로 갔는지까지 같은 실행에서 나온다. §120 이 든 「Node1 요청만 지연」 같은 증상을 나중에 볼 때 어느 경로를 먼저 열어야 하는지도 이 기록에서 나온다.
캡처 지점이 다섯으로 늘어난다.
### 4. 제외 — 호스트 Nginx 설정에서 경로를 읽는다
Nginx 가 어느 주소로 요청을 넘기는지 설정만 읽어도 어느 가상 머신으로 가는지는 알 수 있다. 그러나 이 물음은 설정이 말하는 경로가 아니라 패킷이 실제로 지나는 계층을 묻는다. §116 이 그린 그림이 확인된 것이 아니라는 데서 물음이 시작했으므로, 설정을 읽으면 같은 종류의 근거가 하나 더 늘어난다.
## 다음 검증
1. 캡처를 걸 지점의 이름을 먼저 확정한다. 어느 브리지와 어느 TAP 인지는 네트워크 구성을 묻는 물음과 인터페이스를 묻는 물음이 답한다.
2. 호스트에서 sudo tcpdump -ni 뒤에 physical NIC 이름 · bridge 이름 · tap 또는 vnet 이름을 넣어 세 곳에 걸고, 게스트에서 같은 명령을 guest interface 이름에 건다 (§122 OQ-6 · §119).
3. 호스트 Nginx 를 통해 Keycloak 요청을 한 번 보낸다.
4. 네 지점에서 그 요청이 보였는지를 §119 처럼 O 와 X 로 적는다.
5. 캡처하는 동안의 오프로드 상태를 함께 적는다. §113 은 오프로드가 켜져 있으면 tcpdump 에서 보이는 패킷 크기나 체크섬이 실제 wire 에서 보이는 것과 다르게 보일 수 있다고 적었다.
닫는 조건 : 네 지점의 캡처 결과로 실제 경로를 한 줄로 적으면 닫는다. §116 이 펼친 그림과 같으면 그 그림을 이 호스트에서 확인된 경로로 올리고, §116 을 근거로 삼는 후보를 다시 판정한다. 다르면 어느 지점부터 다른지를 적고 §119 의 판정 예대로 그 구간을 의심 구간으로 넘긴다. 요청이 중간 지점에서 끊기면 그것은 이 물음의 답이 아니므로 계층별 캡처 기준으로 넘긴다.