From 06fc6040b481dc2bd225b8dd653354903dd376ab Mon Sep 17 00:00:00 2001 From: kaffa Date: Tue, 21 Jul 2026 15:33:12 +0900 Subject: [PATCH] =?UTF-8?q?osaka=20APISIX=20etcd=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=A0=95=EC=A0=95=20=EB=B0=8F=20=EC=8B=A4?= =?UTF-8?q?=EC=A0=9C=20=EA=B5=AC=EC=84=B1=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - osaka config.yaml의 죽은 etcd host(10.100.2.214) → mbp 정상 주소(100.115.154.78)로 수정 - osaka가 로컬 waf-etcd 대신 Patroni 공유 통합 etcd를 실사용 중임을 문서화 - mbp etcd 부트스트랩 플래그의 stale 4번째 멤버(etcd-hp2) 기록 - mbp raft 파티션 자연복구 사례 및 osaka APISIX 버전 지연(3.15.0, 최신 3.17.0) 기록 --- history/2026-07-21-osaka-apisix-etcd-fix.md | 42 +++++++++++++++++++++ infra/data/postgresql-ha.md | 2 + infra/network/apisix.md | 7 +++- 3 files changed, 49 insertions(+), 2 deletions(-) create mode 100644 history/2026-07-21-osaka-apisix-etcd-fix.md diff --git a/history/2026-07-21-osaka-apisix-etcd-fix.md b/history/2026-07-21-osaka-apisix-etcd-fix.md new file mode 100644 index 0000000..29dfe3b --- /dev/null +++ b/history/2026-07-21-osaka-apisix-etcd-fix.md @@ -0,0 +1,42 @@ +--- +date: 2026-07-21 +topic: osaka APISIX etcd 설정 오류 발견 및 정정, mbp etcd 멤버 raft 파티션 자연 복구 +areas: + - infra/network/apisix.md + - infra/data/postgresql-ha.md +tags: [history, apisix, etcd, osaka] +--- + +osaka APISIX 버전 확인 과정에서 실제 실행 중인 설정을 점검하다가 두 가지 문제를 발견하고 정정했다. + +## 발견 1: osaka는 로컬 `waf-etcd` 컨테이너를 쓰지 않는다 + +`/opt/waf-saas/docker-compose.yml`에는 로컬 `waf-etcd`(quay.io/coreos/etcd:v3.5.11) 컨테이너가 정의돼 있지만 **실제로는 기동돼 있지 않았다**. 살아있는 `config.yaml`은 Patroni DCS와 공유하는 [[../infra/data/postgresql-ha|외부 통합 etcd 클러스터]](nas/mbp/jp1)를 prefix `/apisix/osaka`로 사용 중이었다. + +## 발견 2: config.yaml의 3번째 etcd host가 죽은 주소였다 + +`config.yaml`의 etcd host 목록: +``` +192.168.9.100 (nas, 정상) +10.100.2.214 (죽은 주소 — 응답 없음) +10.253.101.233 (jp1, 정상) +``` + +`10.100.2.214`는 mbp의 `etcd-mbp` 컨테이너 자체의 `--initial-cluster` 부트스트랩 플래그에 남아있던 옛 4번째 멤버 `etcd-hp2`의 주소였다 (hp2 기반 etcd 멤버는 이미 클러스터에서 제거된 상태, `member/list`엔 3개만 존재). osaka config가 원본 부트스트랩 문자열을 그대로 베껴서 생긴 drift로 추정. 실제 3번째 멤버(`etcd-mbp`)의 올바른 주소는 `100.115.154.78`(Tailscale)인데 config엔 아예 없었다. + +**조치**: `config.yaml`의 `10.100.2.214` → `100.115.154.78`로 수정, `docker compose restart waf-apisix`로 적용. 재시작 후 로그에 `no route to host` 재발 없음, 라우트 11개 정상 로드, `ironclad.it.com` 200 응답 확인. + +## 발견 3 (조사 중 지나가며 확인): mbp etcd 멤버가 일시적으로 raft 파티션 상태였다 + +조사 시점에 `etcd-mbp`(100.115.154.78)가 다른 2개 멤버와 raft 스트림이 끊겨 격리된 상태였다 (`failed to publish local member to cluster through raft ... request timed out` 반복, 로컬 `127.0.0.1:2379/health`조차 무응답). SSH(22번 포트)는 Tailscale로 정상 접속됐으나 raft 스트림만 끊겨 있었음 — 원인은 특정하지 못했으나 **재접속 시도 중 자연 복구**됨 (`established TCP streaming connection with remote peer` 로그, 이후 3노드 전부 정상). 클러스터는 nas+jp1 2/3 쿼럼으로 계속 정상 서비스 중이었어서 이 기간 동안 실제 장애는 없었음. + +## 교훈 + +- APISIX 인스턴스가 여러 개(서울 K3s, 오사카, 서울 relay) 있고 etcd 백엔드도 로컬/K3s내부/외부통합으로 제각각이라, "이 인스턴스가 실제로 어떤 etcd를 쓰는지"는 `docker ps`/`config.yaml` 실물을 봐야 확실함 — 문서에 적힌 구성과 실제가 다를 수 있음 +- 설정값에 여러 호스트 IP가 나열돼 있으면 그중 죽은 게 있는지 개별 헬스체크로 확인할 것. compose 파일에 정의된 서비스가 곧 실제로 쓰이는 서비스라고 가정하지 말 것 +- 3노드 중 1노드가 조용히 파티션되어도 쿼럼(2/3)만 유지되면 겉으로는 정상 동작해서 알아채기 어려움 — 정기적으로 `member/list` + 각 멤버 개별 헬스체크 권장 + +## 참조 + +- [[../infra/network/apisix|APISIX 설정 및 운영]] +- [[../infra/data/postgresql-ha|PostgreSQL HA (Patroni) 및 통합 etcd]] diff --git a/infra/data/postgresql-ha.md b/infra/data/postgresql-ha.md index b84be89..daee71b 100644 --- a/infra/data/postgresql-ha.md +++ b/infra/data/postgresql-ha.md @@ -61,6 +61,8 @@ incus exec postgres-1 -- /opt/patroni/bin/patronictl -c /etc/patroni.yml reinit - jp1: openrc 서비스 (`/etc/init.d/etcd`), `command_background=true` - mbp: docker container `etcd` (named volume `etcd-data`), client/peer 모두 호스트 `127.0.0.1`만 노출 → `socat`이 Tailscale IP `100.115.154.78`의 `2379`/`2380`으로 forward (`~/Library/LaunchAgents/com.kaffa.etcd-socat{,-peer}.plist`) - Patroni etcd namespace: `/patroni` +- ⚠️ mbp의 `etcd` 컨테이너 부트스트랩 커맨드(`--initial-cluster`)에 이미 제거된 4번째 멤버 `etcd-hp2=http://10.100.2.214:2380`가 stale로 남아있음(2026-07-21 확인) — 실제 `member/list`는 3개(nas/mbp/jp1)뿐이라 동작엔 영향 없으나, 이 문자열을 그대로 복사해 다른 곳(osaka APISIX config 등)에 쓰면 죽은 주소가 섞여 들어가니 주의. 재부팅 필요 시 이 플래그도 3노드로 정정 권장 +- ⚠️ 2026-07-21 mbp 멤버가 일시적으로 다른 2노드와 raft 스트림이 끊겨 격리(SSH는 정상, raft만 파티션)된 사례 발견 — 원인 미상, 재접속 시도 중 자연 복구. nas+jp1 2/3 쿼럼으로는 서비스 중단 없었음. [[../../history/2026-07-21-osaka-apisix-etcd-fix|상세 history]] ### etcd 확인 명령어 diff --git a/infra/network/apisix.md b/infra/network/apisix.md index 09cd29e..5244879 100644 --- a/infra/network/apisix.md +++ b/infra/network/apisix.md @@ -38,9 +38,12 @@ updated: 2026-04-04 BunnyCDN(iron-jp, ID 5555247) → apisix-osaka(172.233.93.180) → 백엔드 ``` - 용도: Ironclad 인프라 서비스 (ironclad.it.com, n8n, twilio 등) -- Docker: APISIX 3.15.0 (waf-apisix) + etcd v3.5.11 (waf-etcd) -- 보안: SafeLine WAF + CrowdSec 연동 +- Docker: APISIX 3.15.0-debian (`waf-apisix`, `/opt/waf-saas/docker-compose.yml`). SSH: `root@100.108.39.107` (Tailscale) +- Admin API: `http://100.108.39.107:9180` (Tailscale 전용), Admin Key `edd1c9f034335f136f87ad84b625c8f1` +- etcd: compose에 로컬 `waf-etcd`(quay.io/coreos/etcd:v3.5.11)가 정의돼 있으나 **실제로는 미기동** — 실사용 etcd는 Patroni DCS와 공유하는 [[../data/postgresql-ha|외부 통합 etcd 클러스터]](nas/mbp/jp1), prefix `/apisix/osaka`. `config.yaml`의 etcd host가 죽은 주소를 물고 있던 오류를 2026-07-21 정정 ([[../../history/2026-07-21-osaka-apisix-etcd-fix|history]]) +- 보안: SafeLine WAF + CrowdSec 연동. `crowdsec-bouncer.lua` 커스텀 플러그인은 마운트만 돼 있고 `plugins:` 목록엔 미등록 — 2026-07-21 확인 기준 미사용, CrowdSec 로그 전송은 global_rules `http-logger`→`vector.inouter.com`로 처리 - upstream: incus-jp1 내부(10.253.x), K3s Traefik +- 버전: **3.15.0, 최신(3.17.0, 2026-06-15)보다 2 마이너 뒤처짐** — 업그레이드 미적용 상태 (2026-07-21 확인) ### 서울 (K3s 새 클러스터, apisix 네임스페이스) — 독립 외부 인입 게이트웨이 ```