브리지 운영하기
브리지와 그 뒤의 링을 굴리는 운영 노트: 계획을 로드하고, 재시작을 견디고, 기여가 계속 흐르게 하고, 엔진을 인터넷에서 떼어 놓기.
게이트웨이(공개 진입점)와 브리지(엔진의 얼굴)는 운영자가 건강하게 유지하는 두 개의 장수 서비스이고, 그 뒤에 p4 에이전트와 스테이지 서버들이 있습니다. 엔진에는 인증이 전혀 없으며 — 서로 닿을 수 있는 머신들은 닿아도 되는 사이라고 가정합니다 — 그래서 공개되는 모든 것은 게이트웨이로 수렴하고, 브리지는 공개하는 대신 터널을 통해 접근합니다.
로딩
계획, 그리고 그것이 로드되는 번호
- 배치는 요청하는 것이 아니라 작성하는 계획입니다: 브리지는 서빙해 달라는 요청에
409로 답합니다. 계획을 생성하고, dry-run하고,--confirm으로 로드하세요. - load generation은 첫 명령이 떠나기 전에 디스크에 기록됩니다. 로드하는 쪽이 정하고, 모든 세션과 언로드에서 정확히 같은지 검사되며, 머신 어디에도 기록되지 않습니다 — 잃어버리면 로드된 모델을 내릴 수조차 없습니다.
- node generation은 바로 그 같은 숫자입니다. 서로 다른 두 값으로 링을 로드하면 정확히 요청 하나를 서빙하고 head가 멈추며, 다음 세션은 부분 로드 상태로 멈춥니다. 로드마다 새 값을 쓰세요 — 아니면 실패한 시도가 남긴 등록이 그 값과 충돌합니다.
- 에이전트는 운영 저널 없이는 로드를 거부합니다. 디버그 플래그가 아니라, 재생 안전한 로드에 필요한 승인 기록입니다.
재시작을 견디기
무엇이 돌아오고 무엇이 돌아오지 않는가
- 에이전트 재시작은 자기 노드를 떨굽니다. 스테이지 서버는 런타임 전용이라 모델을 계획에서 다시 로드해야 합니다. 이것은 장애가 아니라 복구 절차입니다.
- 게이트웨이가 대신 재로드해 주지 않습니다. 게이트웨이의 링 워치독은 서빙이 멈춘 모델을 알아채고, 브리지의
409로부터 배치가 외부의 일임을 배우고, 한 번 그렇다고 말한 뒤 묻기를 멈춥니다. - 기여 카운터는 브리지의 메모리에 있습니다. 게이트웨이가 30초마다 폴링해 델타 크레딧하므로 재시작으로는 아직 폴링되지 않은 만큼만 사라지고, 카운터가 뒤로 돌아가면 게이트웨이는 이중 지불 대신 기준선을 다시 잡습니다.
잠그기
엔진은 인터넷을 향하지 않는다
- 브리지를 루프백에 바인딩하고 서비스 토큰을 주세요. 토큰이 없으면 브리지는 아무도 인증하지 않고, 거기 닿는 것은 무엇이든 링을 공짜로 굴릴 수 있습니다 — 나중에 알게 두는 대신 시작할 때 그렇다고 말해 줍니다.
- 에이전트는 다른 에이전트가 dial할 주소를 광고합니다. 호스트들이 공유하는 가장 빠른 네트워크를 쓰고, 호스트를 넘는 루프백은 절대 쓰지 말고, 그 네트워크를 공개 인터넷에서 떼어 놓으세요.
- 무언가를 공개 IP에 놓아야 한다면, Docker의 published 포트는 INPUT 체인 이전에 DNAT되므로
dport규칙이 매치되지 않는다는 점을 기억하세요.DOCKER-USER체인에서 conntrack의 원본 목적지 포트(--ctorigdstport)로 필터하고,After=docker.service로 정렬된 systemd oneshot으로 영속화하세요.
함정
실제로 시간을 잡아먹는 두 가지
- 운영자 지갑이 설정돼 있지 않으면 수익이 0으로 읽힙니다. 게이트웨이는 소유자가 없는 기여 행을 건너뛰고 아무것도 로그하지 않습니다. 서빙 중인 노드들이 노는 것처럼 보입니다.
- `pkill`은 자기 자신의 명령줄에 매치됩니다.
ssh host 'pkill -f server.js; ...'는 그것을 실행 중인 셸을 죽입니다. 패턴을 원격 명령이 아니라 스크립트 파일에 넣고, 문자 클래스(server[.]js)를 쓰세요. 그리고 맨node server.js로 띄운 프로세스에는 매치할 경로가 아예 없다는 점도 — 그럴 땐 리스닝 포트로 찾으세요.