문제 해결
오프라인, 401, 403, 413, 큐 적체: 증상별 원인과 조치
장비에서 다음 항목부터 확인.
geo-mlops-edge status # 맨 위 '!!' 문장, link.state, sync.state, backlog
geo-mlops-edge queue --state failed
journalctl -u geo-mlops-edge -n 200 # 또는 docker compose logs edge
link.state | 뜻 |
|---|---|
online | 중앙과 통신 중 |
probing | 연결을 확인하는 중(연속 성공 2번을 기다림) |
offline | 중앙에 접근할 수 없음. 데이터를 로컬에 누적하는 중. |
auth_failed | 토큰이 거부됨. 사용자가 토큰을 교체해야 함. |
플릿에 '비정상'으로 표시됨 / 오프라인
증상: 목록에서 비정상, 마지막 하트비트가 몇 분 전. 장비의 link.state 가 offline.
하트비트가 서버 기준(기본 180초) 동안 수신되지 않으면 비정상 으로 전환. 확인 항목:
-
에이전트가 실행 중인가?
geo-mlops-edge status가no agent is listening …이면 서비스가 중지된 상태.systemctl status geo-mlops-edge로 확인. -
주소가 올바른가?
geo-mlops-edge config의central.base_url을 확인하고 장비에서 직접 요청.curl -s https://mlops.example.com/api/v1/health응답이 없으면 DNS·방화벽·프록시 문제. 사내 인증서를 사용하는 서버라면 장비에 CA 를 설치하거나(권장)
central.verify_tls: false로 시험. -
Offline 차단인가? 화면에 Offline 차단됨 배지가 있으면 운영자가 서버에서 차단한 상태. 이때 장비의
link.state는online그대로이고, 로그에503 edge device … is blocked by an operator기록. 장비는 데이터를 누적했다가 차단이 해제되면 다시 전송. 차단이 3시간을 넘었으면 해제 후queue --state failed를 확인하고 재동기화 명령 전송(명령·정책·보존). -
하트비트 주기가 너무 긴가? 정책의 하트비트 주기가 180초에 가까우면 정상 장비도 비정상 과 정상 상태를 반복.
오프라인 동안에도 수집은 계속되고 데이터는 보존 한도 안에서 누적. 링크 복구 후 별도 조치 불필요.
401: 토큰 거부
증상: status 맨 위에 !! Central rejected this device's token …, link.state 와 sync.state 가 auth_failed, 로그에 401 invalid or expired edge token.
토큰이 틀렸거나, 회전·회수되었거나, 만료(1년)된 경우. 에이전트는 이 상태에서 의도적으로 중앙 호출을 중단. 명령 폴링도 중단되므로 중앙에서는 해결 불가.
조치: 중앙에서 회전 으로 새 토큰을 발급받고, 장비의 /etc/geo-mlops/edge.env 를 수정한 뒤 서비스 재시작(배포: 디바이스 토큰 교체). 토큰 앞뒤에 공백·줄바꿈이 포함되지 않았는지도 확인.
403: 스코프 없음
증상: status 에 !! Central refuses uploads: … The token is still valid; a scope was removed.(하트비트면 heartbeats), sync.denied 에 거부 사유.
토큰은 유효하지만 해당 작업의 스코프가 비활성화된 상태(예: 파일 업로드인데 data:write 가 없음). 해당 종류의 작업만 중단되고 나머지는 계속. telemetry:write 를 비활성화하면 하트비트도 거부되므로 장비의 링크는 online 이지만 플릿에서는 비정상 으로 표시.
조치: 디바이스 상세 토큰 관리 의 스코프 편집 에서 스코프 활성화. 이후 새로 누적되는 데이터부터 다시 전송. 거부 시점에 전송 중(uploading) 상태였던 항목은 에이전트를 재시작해야 대기 상태로 복귀. geo-mlops-edge queue --state uploading 으로 확인하고, 재시작 명령 전송 또는 서비스 재시작(명령 폴링에는 스코프 불필요).
413: 요청이 너무 큼
발생 위치에 따라 원인과 조치가 다름.
| 발생 위치 | 원인 | 에이전트 동작 | 조치 |
|---|---|---|---|
로컬 API(/inference, /blobs, push) | 요청 본문이 api.max_body_bytes(기본 2 GiB) 초과 | 거부 | 송신 측을 확인. 필요하면 한도 조정. |
| 중앙 레코드 전송 | 한 요청의 레코드 수가 서버 상한(1000) 초과 | 묶음 크기를 줄여 자동 재시도, 데이터는 삭제하지 않음 | sync.batch_size 를 1000 이하로 |
| 중앙 파일 업로드 | 파일 하나가 서버의 파일당 상한(기본 2 GiB) 초과 | 그 파일을 failed 로 표시 | 파일을 분할하거나 서버 관리자에게 상한 문의 |
| http 수집기 | 폴링 응답이 max_body_bytes(기본 1 MiB) 초과 | 그 폴링을 오류로 기록 | URL 이 맞는지 확인, 필요하면 한도 조정 |
PayloadTooLargeError 는 재전송해도 결과가 같으므로 CentralClient 도 재시도하지 않음.
큐 적체 (항목이 줄지 않음)
증상: 플릿 목록의 대기(적체 건수) 숫자가 계속 증가하거나, 옆에 빨간 −N(최근 24시간 보존 한도로 삭제된 건수)이 표시됨.
플릿의 대기 숫자와 backlog.count 는 failed 상태인 항목을 포함하지 않음. status 의 sync 확인.
sync.state / last_error | 원인 | 조치 |
|---|---|---|
paused / paused: cpu above threshold | 시스템 CPU 가 sync.cpu_pause_percent(기본 85) 초과 | 장비 CPU 사용률이 항상 높으면 정책에서 임계값을 올리거나 0(검사 안 함) |
idle 인데 pending 이 줄지 않음 | 현재 시각이 sync.windows(전송 허용 시간대) 범위를 벗어남 | 시간대를 넓히거나, 긴급한 데이터는 priority 를 urgent_priority(90) 이상으로 |
offline | 링크 끊김 | 위 '오프라인' 참고 |
auth_failed | 토큰 거부 | 위 '401' 참고 |
idle 인데 failed 가 누적됨 | 항목별로 거부됨(검증 실패 등) | queue --state failed 의 last_error 확인 후 원인 제거, 재동기화 명령 또는 sync:retry-failed |
기타:
- 전송 속도보다 수집량이 많음.
−N이 계속 표시되면 회선이 데이터 양을 감당하지 못하는 상태. http 수집기의interval_ms를 늘리거나, watchdir 파일 수를 줄이거나,sync.max_bytes_per_s가 너무 낮지 않은지 확인. - 일시적인 실패는 20번째에 재시도 중단. 10초에서 시작해 간격을 두 배씩 늘리며(최대 15분) 재전송, 20번째 실패에서
failed로 표시. 재동기화 로 되돌려도 시도 횟수는 초기화되지 않으므로 다음 일시적 실패에서 즉시 다시failed로 전환. - 삭제 순서는 우선순위가 낮은 것부터, 같은 우선순위에서는 오래된 것부터. 손실되면 안 되는 데이터의 수집기는
priority상향 필요.
기타 증상
| 증상 | 원인 | 조치 |
|---|---|---|
| 에이전트가 시작 직후 종료 코드 4 로 종료됨 | 로컬 API 포트(8600)를 다른 프로세스가 이미 사용 중 | 다른 에이전트가 실행 중인지 확인, 또는 api.port 변경 |
| 재시작 명령 뒤 에이전트가 다시 실행되지 않음 | 감시자 없이 실행 중 | systemd Restart=always 나 컨테이너 restart: 로 실행 |
watchdir 수집기에 queued but could not be removed | 에이전트 계정이 그 폴더에 쓰기 권한이 없음 | 폴더 권한 부여, systemd 면 ReadWritePaths= 에 추가 |
모델을 내려받았는데 activated: false | 해당 프레임워크 엑스트라가 없음 | 로그의 install 'geo-mlops-sdk[yolo]' 대로 설치 |
pull_model 명령이 404 model artifact not found | 레지스트리 버전에 아티팩트가 없음 | 학습으로 만들어진 버전인지 확인 |
push 에 404 no push collector named … | edge.yaml 에 그 이름의 push 수집기가 없음 | collectors: 에 선언하고 재시작 |
| GPU 값이 비어 있음 | NVIDIA 드라이버·gpu 엑스트라 없음 | GPU 장비면 pip install 'geo-mlops-sdk[gpu]' |
modbus 수집기가 starting 에서 변경되지 않고 오류도 없음 | modbus 엑스트라(pymodbus)가 없음 | pip install 'geo-mlops-sdk[edge,modbus]' 후 재시작 |
모델 내려받기가 has no MLmodel; nothing can run it 으로 실패 | 아티팩트가 MLflow 모델 디렉터리(MLmodel 파일)가 아님 | MLflow 모델 형식으로 기록된 버전을 내려받음 |