Incident Library

IL-0354 Fly.io · 2026-09-23networking

Fly.io 일부 머신의 사설 네트워크 6PN 이 끊겼고 다음 날 잠깐 다시 끊겼다

Fly.io 의 6PN 주소는 fdaa:netid:netid:hostid:hostid:machid:machid:2 꼴이다. hostid 부분은 머신을 만들 때 머신이 있던 물리 호스트에서 정해지고, 2025년 5월 무렵 이전에는 머신을 옮길 때도 다시 정해졌다. 2025년에 6PN 주소를 고정한 뒤에도 6PN 라우팅용 맞춤 eBPF 프로그램은 한 번도 옮기지 않은 머신의 경로를 기본적으로 hostid 만 보고 정했다. 2026년에 Fly.io 는 디버깅과 변경이 어려운 맞춤 라우팅 구현을 줄이고 표준 Linux 라우팅 테이블에 기대도록 6PN 을 바꾸고 있었다. 이 작업의 핵심은 host ID 를 6PN 라우팅에서 떼어 내는 일이었다. 그러면 머신의 경로는 주소가 아니라 머신이 지금 있는 위치로 정해진다.

게이트웨이 피어에는 static 과 interactive 두 종류가 있다. fly wireguard create 로 만드는 static 피어는 플랫폼의 라우팅 상태에 고정된 신원이 있다. flyctl 이 fly ssh console 같은 일시적 작업에 쓰는 interactive 피어는 그런 신원이 없어서, 게이트웨이의 host ID 를 보고만 경로를 정할 수 있다. 주소에 게이트웨이 피어와 머신을 가를 다른 표시가 없어서, Fly.io 는 netid 마다 게이트웨이의 /80 접두사 전체를 게이트웨이 호스트로 보내는 규칙을 Linux 라우팅 테이블에 넣었다. 기존 게이트웨이에서는 이 방식에 문제가 없었다.

물리 워커 호스트를 퇴역시키면 그 내부 IP 가 풀리고, 내부 IP 가 host ID 를 정한다. 새 호스트는 새 IP 와 host ID 를 받을 수도 있고 퇴역한 호스트의 값을 다시 받을 수도 있다. 6PN 주소가 고정된 뒤로는 머신이 워커가 아닌 호스트에 다시 배정된 host ID 를 계속 가질 수 있었다. 최근 용량과 연결성을 늘리려고 새 에지를 많이 들이면서 에지들이 퇴역한 워커의 host ID 를 다시 썼다. 에지를 non-static 피어의 게이트웨이로 쓰기 시작하자 에지에 /80 경로가 들어갔고, 이 경로가 머신별 라우팅 코드를 덮어썼다. 그 코드는 로컬에서 아직 접근한 적이 없는 머신에는 경로가 없다는 전제에 기대고 있었다. 그 host ID 를 가진 머신들은 에지가 아니라 워커에 있었기 때문에 6PN 이 끊겼다.

Fly.io 는 약 10분 만에 영향을 받은 모든 호스트의 라우팅 테이블에서 잘못된 /80 경로를 지우고, 6PN 경로를 관리하는 데몬 s6pnforwarderd 의 변경을 롤백했다. 이어 interactive 피어를 /128 로만 넣도록 고쳤지만, 문제는 /80 경로만이 아니라 게이트웨이 로직과 워커 로직 사이의 우선순위였기 때문에 다음 날 잠깐 다시 일어났다. 그 뒤 호스트가 워커인지와 상관없이 그 호스트의 ID 를 가진 머신이 있는지부터 찾도록 고쳐 근본 원인을 일단 막았다.

심각도
–
영향 범위
Private networking (6PN) for the subset of machines whose host IDs had been reused by edges
영향 사용자
–
지역
–
감지까지
–
복구까지
10m

증상

9월 23일 일부 머신의 사설 네트워크인 6PN 이 끊겼다. 다음 날에도 같은 문제가 잠깐 다시 일어났다.

영향을 받은 머신은 6PN 주소에 담긴 host ID 가 나중에 에지 호스트에 다시 배정된 머신이었다. 에지에 새로 들어간 /80 경로가 머신별 라우팅을 덮어써, 이 머신들의 경로가 머신이 실제로 있는 워커가 아니라 에지 쪽으로 잡혔다.

처음에는 워커의 host ID 가 워커가 아닌 호스트에 다시 쓰일 수 있다는 점을 모두가 바로 떠올리지는 못했다. 기존 점검은 모두 원래 호스트에 있는 머신을 썼기 때문에 이 충돌을 잡지 못했다.

증상 네트워크 도달 불가요청 오라우팅

원인

촉발
에지가 static 이 아닌 피어의 게이트웨이 역할도 하도록 바꾸면서, 모든 에지에 게이트웨이처럼 netid 마다 /80 접두사 전체를 그 호스트로 보내는 라우팅 규칙이 들어갔다.

감지

–

조치

후속 조치

교훈

Fly.io 는 워커의 host ID 가 워커가 아닌 호스트에 다시 쓰일 수 있다는 점이 문서로 잘 남아 있지 않아 처음에 모두가 떠올린 것은 아니었다고 봤다. 게이트웨이를 오래 손대지 않았기 때문에 에지를 게이트웨이로 쓰기 전까지 문제가 드러나지 않았다. 더 깊은 문제는 6PN 라우팅의 알림과 자동 테스트였다. 기존 점검은 모두 원래 호스트에 있는 머신을 써서 host ID 재사용으로 생기는 충돌이나 고정 6PN 주소 구현과 얽힌 문제를 잡을 수 없었다. Fly.io 는 알림이나 큰 장애로 이어지지 않은 문제가 더 있었을 수 있다고 했다. 6PN 주소의 host ID 가 경로 결정에 아무 역할도 하지 않아야 이런 장애가 되풀이되지 않는다고 결론지었다.

출처

관련 사례

내 클러스터에도 있는지 확인하기

kubegap 은 Claude Code 나 Codex 에서 쿠버네티스 클러스터를 읽기만 하며 이 사례와 같은 상태를 점검합니다. 이 사례의 구성 요소: 호스트 라우팅 규칙, 네트워크 컨트롤 플레인. 점검 항목의 근거는 이 사례 같은 공개 보고서입니다.

AI 도구와 스크립트용

API 는 키가 필요 없습니다. MCP 서버는 search_incidents, get_incident, list_incidents, get_topic, vocab 도구를 내놓습니다. 사용법은 API 와 MCP.