# 03 — 호스트 nginx 라우팅 ## 이 단계가 끝나면 밖에서 보낸 요청이 **nginx → Traefik → 파드**로 닿는다. 아직 TLS 는 없다. ## 전제 [02](../02-k3s/) 가 끝나 두 노드가 `Ready`. ## 왜 프록시가 두 겹인가 nginx 와 Traefik 이 하는 일이 다르다. | | 맡는 것 | |---|---| | 호스트 nginx | 바깥세상과의 접점 — TLS 종단 · 인증서 · `X-Forwarded-*` | | Traefik | 클러스터 안의 동적 라우팅 — Ingress 를 보고 서비스를 고른다 | **이 2홉이 운영 구조와 같다는 것이 이 배치의 핵심**이고, 동시에 B-4 의 헤더 실험이 성립하는 이유다. 1홉을 가정하고 쓴 계약이 2홉에서도 유효한지를 재려면 두 겹이 있어야 한다. --- ## 1. 설정을 쓴다 원본은 [`deploy/lab/host/nginx-keycloak-lab.conf`](../../../deploy/lab/host/nginx-keycloak-lab.conf). **하기** ```bash sudo tee /etc/nginx/sites-available/keycloak-lab > /dev/null <<'EOF' upstream k3s_traefik { server 192.168.122.11:80; server 192.168.122.12:80; } server { listen 80 default_server; server_name _; return 301 https://$host$request_uri; } server { listen 443 ssl default_server; http2 on; server_name _; ssl_certificate /etc/letsencrypt/live/auth.hyeonworks.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/auth.hyeonworks.com/privkey.pem; ssl_protocols TLSv1.2 TLSv1.3; location / { proxy_pass http://k3s_traefik; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header X-Forwarded-Host $host; proxy_set_header X-Forwarded-Proto https; proxy_set_header X-Forwarded-Port 443; proxy_set_header X-Forwarded-For $remote_addr; proxy_set_header X-Real-IP $remote_addr; proxy_read_timeout 3600s; proxy_send_timeout 3600s; } } EOF ``` > **인증서 경로는 아직 없다.** [04](../04-tls/) 에서 만든다. 그전까지는 443 > 블록을 주석 처리하고 80 만 `proxy_pass` 로 두면 이 단계를 먼저 확인할 수 있다. Arch 는 `sites-available` 관례가 없다. 직접 만들고 `nginx.conf` 의 `http` 블록 안에서 include 한다. ```bash sudo mkdir -p /etc/nginx/sites-{available,enabled} sudo ln -s /etc/nginx/sites-available/keycloak-lab /etc/nginx/sites-enabled/ # nginx.conf 의 http { } 안에: include /etc/nginx/sites-enabled/*; ``` ## 2. 문법을 보고 적용한다 **하기** ```bash sudo nginx -t && sudo systemctl reload nginx ``` **`&&` 가 중요하다.** 설정이 깨진 상태에서 reload 하면 nginx 가 새 워커를 띄우지 못한다. `-t` 를 먼저 통과시키고 그때만 reload 한다. ## 3. 층별로 확인한다 — 아래에서 위로 한 번에 밖에서 치지 말고, **가까운 층부터** 본다. 어디서 끊겼는지가 바로 나온다. **확인 ①** Traefik 이 듣고 있나 (nginx 를 건너뛴다) ```bash curl -s -o /dev/null -w '%{http_code}\n' http://192.168.122.11 ``` ``` 404 ``` **`404` 가 성공 신호다.** Traefik 까지 닿았는데 매칭되는 Ingress 규칙이 없다는 뜻이다. `502` 나 연결 거부면 그 아래에서 끊긴 것이다. **확인 ②** nginx 가 80 에서 리다이렉트하나 ```bash curl -s -o /dev/null -w '%{http_code} %{redirect_url}\n' http://auth.hyeonworks.com ``` ``` 301 https://auth.hyeonworks.com/ ``` **확인 ③** 끝까지 닿나 (TLS 이후) ```bash curl -s -o /dev/null -w '%{http_code}\n' https://auth.hyeonworks.com/realms/master ``` ``` 200 ``` ## 4. upstream 이 둘인 이유 ``` upstream k3s_traefik { server 192.168.122.11:80; server 192.168.122.12:80; } ``` 두 노드 모두 Traefik 이 뜨므로 어느 쪽으로 보내도 된다. nginx 는 기본 라운드로빈으로 번갈아 보내고, **한쪽이 죽으면 자동으로 뺀다.** 그 「빼는」 동작이 로그에 이렇게 남는다. ``` connect() failed (113: No route to host) ← 호스트에 못 닿는다 connect() failed (111: Connection refused) ← 포트에 아무도 없다 no live upstreams ← 둘 다 죽었다고 판단 ``` **113 과 111 은 대응이 다르다.** 113 은 네트워크, 111 은 프로세스다. A-4 에서 노드를 잃었을 때 이 세 줄이 1분 안에 순서대로 나왔다. --- ## 막히면 | 증상 | 어디서 끊겼나 | 확인 | |---|---|---| | ① 이 연결 거부 | Traefik 이 안 떴거나 게스트가 죽음 | `kubectl get pods -n kube-system` | | ① 이 `502` | Traefik 은 떴는데 백엔드가 없음 | Ingress 확인 | | ② 가 응답 없음 | nginx 가 안 떴거나 방화벽 | `systemctl status nginx` | | ③ 이 `502` | 인증서 문제 또는 upstream 다운 | [04](../04-tls/) · 아래 로그 | **로그를 볼 때** — 실무자가 치는 형태다. ```bash journalctl -u nginx -p err -n 5 # 최근 에러만 journalctl -u nginx -f # 지금 벌어지는 것 ``` **★ nginx 에러 로그는 2048바이트에서 잘린다.** 긴 URL 이 끝에서 단어 중간에 끊겨 보이면 그것이다. 되찾으려면 **access 로그를 본다** — 거기엔 제한이 없다. ```bash grep oauth2/callback /var/log/nginx/access.log | tail -1 ``` 이 실험대에서 B-7 의 502 원인이 error 로그에 있었는데 잘려 있었고, access 로그에는 3492자로 온전히 남아 있었다.