Skip to content

lessons learned

aegis-pi edited this page Jun 14, 2026 · 2 revisions

모범사례와 실패사례 (Lessons Learned)

Aegis-Pi를 만들고 운영하면서 실제로 검증한 **모범사례(Best Practices)**와, 직접 부딪혀 해결한 **실패사례(Failure Cases)**를 한곳에 모았다. 새 노드·새 공장·새 운영자가 같은 문제를 다시 겪지 않도록 하는 것이 목적이다.

한쪽 평면에 치우치지 않도록 **엣지/제어 평면(factory-a Safe-Edge·Hub)**과 데이터/대시보드 평면(Data Pipeline·Dashboard VPC) 양쪽 사례를 함께 담는다.

상태: 운영 검증 기준 기준일: 2026-06-14


이 문서의 위치

  • 이 페이지는 요약·원칙·재발 방지를 담는다. 항목별 명령어 수준의 원본 기록은 아래 운영 문서에 있다.
    • 엣지/제어 평면: docs/ops/04_troubleshooting.md(factory-a·Safe-Edge 40건), docs/ops/09_failover_failback_test_results.md, docs/ops/10_edge_workload_placement.md
    • 데이터/대시보드 평면: docs/ops/22_data_dashboard_vpc_runbook.md, docs/ops/23_data_pipeline.md, docs/ops/31_risk_alert_dispatcher.md
  • 결정을 바꾼 배경은 ADR 인덱스의 개별 ADR을 따른다.
  • AWS Hub build/destroy 과정의 장애는 AWS Hub 트러블슈팅에 따로 있다.

Part 1 — 모범사례 (Best Practices)

1. Edge HA / Failover 운영

1.1 하드웨어 의존 Pod는 Recreate 전략으로 둔다

safe-edge-integrated-ai, safe-edge-audio, bme280-sensor는 노드의 실제 장치 (/dev, /dev/snd, /dev/i2c-1, camera)를 직접 잡는다. Deployment 기본 전략인 RollingUpdate는 새 Pod를 먼저 띄우고 기존 Pod를 나중에 종료하므로, 짧은 시간이라도 두 Pod가 같은 장치를 동시에 열어 초기화 실패와 재시작 루프가 생긴다.

  • 장치를 잡는 Pod는 모두 strategy: Recreate로 둔다.
  • Longhorn RWO PVC를 쓰는 Pod(InfluxDB, Grafana)도 Recreate로 둔다. RollingUpdate는 새 Pod가 다른 노드에서 먼저 뜨면서 RWO volume Multi-Attach 대기를 만든다.

1.2 운영 Pod는 imagePullPolicy: IfNotPresent + 사전 prepull

재부팅 직후 노드의 외부 DNS/registry 경로가 늦게 올라오면, 이미지가 이미 있어도 Always pull 경로를 타다가 ErrImagePull로 복구가 막힌다.

  • 운영 Pod에는 imagePullPolicy: IfNotPresent를 명시한다.
  • worker1/worker2 양쪽에 AI/Audio 이미지를 미리 받아두는 image-prepull DaemonSet을 둔다. prepull 적용 후 LAN 제거 테스트에서 이미지 Pulling으로 인한 장시간 지연이 사라졌다.

1.3 Failback은 K8s CronJob이 아니라 master OS cron(Kubernetes-only 스크립트)

CronJob 기반 자동 failback은 worker2가 Ready로 돌아온 직후, 워크로드가 아직 안정화되기 전에 Pod를 옮기거나 이미 정상인 worker2 Pod를 중복으로 죽일 위험이 있다.

  • failback은 master OS cron이 실행하는 외부 스크립트로 처리한다(SSH·비밀번호 미사용).
  • 스크립트는 worker2에 대상 Pod가 이미 있으면 아무 것도 하지 않는다를 최우선 가드로 둔다.
  • worker1에 남은 대상 Pod만 삭제 후보로 본다.
  • 결정 배경은 Failback OS cron ADR 참조.

1.4 AI snapshot은 Longhorn RWO PVC가 아니라 node-local hostPath

추론 결과(위험도·탐지값)는 InfluxDB(Longhorn PVC)에 남기되, snapshot 이미지는 AI Pod의 failover를 막지 않도록 RWO PVC를 쓰지 않는다.

  • /app/snapshots → hostPath /var/lib/safe-edge/snapshots
  • 24시간 초과 파일은 cleanup sidecar/CronJob이 정리하고, 장기 보관은 후속 비동기 전송 계층(snapshot-uploader presigned PUT → S3)이 담당한다.
  • 배경: AI Snapshot hostPath ADR.

1.5 fencing이 보장되기 전에는 force-detach/강제 삭제를 자동화하지 않는다

Longhorn은 RWO 볼륨에 두 writer가 붙는 것을 막기 위해 worker1 attach를 거부한다. 이는 데이터 손상을 막는 정상 동작이다.

  • worker2NotReady여도 실제 OS·containerd·기존 컨테이너·VolumeAttachment가 즉시 사라진다고 가정하지 않는다.
  • self-healing fencing(worker2 재부팅으로 빠른 자기 복구)과 long failover fencing (전원 차단/외부 power fencing으로 확실히 격리 후 worker1 장기 운영)을 구분한다.
  • 기존 writer가 죽었음을 fencing으로 보장한 뒤에만 stale Pod/VolumeAttachment를 정리한다.

1.6 failover/failback 판정 규칙

장애 직후에는 kubectl의 마지막 관측값이 남아 오판하기 쉽다.

  • 장애 시작 후 첫 5분은 성공/실패를 판정하지 않는다.
  • worker2 Ready만으로 failback 완료로 보지 않는다. 대상 Pod 3개가 worker2 Running이 되어야 failback 완료다.
  • 랜선 제거 시각은 테스트 시작 시각으로만 쓰고, worker2 NotReady/Unreachable 전환 시각을 따로 기록한다.
  • k3s-agent stop과 실제 랜선 제거는 다르다. agent stop은 기존 컨테이너가 잠시 계속 write해 중복이 보일 수 있고, 랜선 제거는 Pod network·node-exporter·Longhorn/CSI까지 끊긴다.
  • 검증 결과: 전원/LAN 제거 모두 RTO 약 12분, hostPath 구성에서 Multi-Attach 재발 없음 (test_07test_09). 상세는 Failover & 복구 시나리오.

2. 네트워크 / 노드 baseline

2.1 eth0(내부망)과 wlan0(인터넷)의 역할을 고정한다

factory-a 3노드는 두 인터페이스를 동시에 쓴다. 역할이 섞이면 flannel·Tailscale·패키지 설치가 한꺼번에 깨진다.

  • eth0: K3s 내부망(10.10.10.0/24) 전용. default gateway/DNS를 두지 않는다 (ipv4.never-default yes, ipv4.ignore-auto-routes/dns yes, route-metric은 높게).
  • wlan0: 인터넷 default route·DNS·Tailscale control plane·image pull 담당(route-metric은 낮게).
  • NetworkManager profile 이름과 device 이름을 eth0로 통일한다. nmcli con up eth0eth0는 device가 아니라 connection profile 이름이다.

2.2 K3s에는 노드 IP와 flannel 인터페이스를 명시한다

자동 선택에 맡기면 Wi-Fi 대역 IP나 잘못된 overlay 경로가 잡힌다.

  • server/agent 실행 인자에 --node-ip/--advertise-address로 독립망 IP를 명시한다.
  • 세 노드 모두 --flannel-iface eth0를 명시해 overlay 경로 불일치를 막는다.
  • 노드 시간 동기화(systemd-timesyncd, NTP)를 켜둔다. 시간이 틀어지면 인증서 certificate not valid 오류로 agent가 못 올라온다.

2.3 서브넷은 /24로 좁힌다

10.10.10.10/8처럼 넓은 마스크는 10.0.0.0/8 전체를 eth0로 보내는 위험한 route를 만든다. /24로 정상화하되, 로컬 작업 머신이 같은 대역에 없으면 직접 SSH가 끊길 수 있으니 운영 접근은 master Tailscale IP / worker wlan0 IP로 한다.

3. 워크로드 배치 / 리소스

  • control-plane과 edge 처리 Pod를 분리한다. master에는 Grafana 같은 가벼운 UI만 두고 반드시 request/limit을 건다(master는 4GiB 노드, k3s-server가 1GiB+ 사용).
  • 장애 도메인을 분리한다. InfluxDB는 데이터 생산처(worker2의 AI/audio/sensor)와 다른 노드(worker1)에 둬서 생산과 저장이 동시에 죽지 않게 한다.
  • AI/audio/BME에는 requests/limits를 둬서 scheduler가 worker1 failover 수용 가능성을 계산할 수 있게 한다(failover 추가 부하 관측치 약 420m CPU / 2.6GiB).
  • Downward API로 NODE_NAME/POD_NAME/POD_UID를 주입해 후속 event_id·idempotency 기반을 마련한다.

4. 보안 / 비용 / 배포 위생

  • 비밀번호·Wi-Fi 키·Tailscale auth key·OAuth secret·certificate/private key는 문서·shell history에 남기지 않는다. AWS IoT 인증서/키는 Kubernetes Secret으로만 주입한다.
  • 같은 이미지 태그를 덮어쓰지 않는다. IfNotPresent에서는 노드 캐시가 우선돼 실제 실행 버전이 불명확해진다. 운영 이미지는 새 태그로 배포하고 values.yaml 갱신 → push → ArgoCD sync 순서를 지킨다.
  • AWS 리소스·상시 컴포넌트·저장소·네트워크 경로를 추가하면 비용 기준서를 함께 갱신한다 (비용 기준서). retired된 AMP/Prometheus Agent는 되살리지 않는다.
  • 송신 컴포넌트(edge-agent)는 message_id idempotency key, last-sent checkpoint, MQTT QoS 1, reconnect/backoff, 최소 RBAC(cluster-admin 금지)를 기본으로 한다.

5. 데이터 파이프라인 / 대시보드 (Data/Dashboard VPC)

5.1 read model 조회는 window별로 원시/집계 경로를 분리한다

대시보드 history 조회는 구간 길이에 따라 다른 read model을 본다. 한 경로로 24시간을 모두 훑으면 DynamoDB 비용과 응답 시간이 폭증한다.

  • 1h 이하: HISTORY#STATE 원시 스냅샷 조회 + max_items=500 cap(ScanIndexForward=False).
  • 6h/12h/24h: GRAPH#5M 5분 집계 item 조회(각각 최대 72/144/288개).
  • 원시(HISTORY#STATE)에는 risk.top_causes 원인 필드가 있지만 집계(GRAPH#5M)에는 없으므로, 긴 구간 Timeline은 top_causes 없음으로 표시한다. 배경: Multi-resolution History ADR.

5.2 데이터가 끊겨도 상태가 stale로 남지 않게 주기적으로 refresh한다

수신 시점에만 pipeline_status/risk를 갱신하면, 메시지가 완전히 끊겼을 때 직전 값 (risk.score=100 등)이 stale로 굳는다.

  • DataProcessorRefresh1m 스케줄러가 1분마다 DataProcessor를 action=refresh_pipeline_status로 호출해, 신선도가 떨어진 공장을 pipeline_status=critical로 내린다.
  • 대시보드 staleness 임계값은 파이프라인 refresh 주기와 맞춘다(staleness threshold ADR 참고).

5.3 영구 리소스는 state 이동(rm/import)으로 분리하고, AWS 리소스는 건드리지 않는다

데모 destroy에도 살아남아야 하는 리소스(Cognito·Route53·ECR·S3 web·CloudFront 등)는 별도 permanent root로 옮긴다.

  • 신규 root에서 import로 기존 리소스를 인수하고, 기존 root에서는 state rm으로 관리에서만 빼낸다. state rmAWS 리소스를 삭제하지 않는다.
  • 양쪽 root 모두 plan 결과가 No changes가 되는지 확인한 뒤 마무리한다.
  • 배경: DynamoDB foundation 이관 ADR, Dashboard VPC 설계.

5.4 secret 값은 Secrets Manager로만 주입하고 state/repo에 남기지 않는다

  • Slack webhook URL 같은 값은 Terraform이 metadata만 관리하고, 실제 값은 빌드 스크립트가 로컬 .secrets/ 파일에서 Secrets Manager로 주입한다. URL 값은 repo와 Terraform state에 저장하지 않는다.

5.5 알림은 specific 우선, 연속 관측, 즉시 알림을 구분해 노이즈를 줄인다

  • 같은 section에 구체(specific) 알림이 있으면 generic fallback 알림을 억제한다(예: EKS specific이 있으면 eks_management_* generic 억제).
  • 일시적 warning은 일정 시간 안에 서로 다른 snapshot을 2회 관측한 뒤에만 보낸다(예: backend_runtime_warning은 90초 내 2회, pods_warning은 450초 내 2회).
  • ALB unhealthy host, Lambda/DynamoDB throttle, collector error, danger/critical은 즉시 알림이다.
  • DynamoDB dedupe state로 같은 알림의 반복 전송을 막는다. 운영 기준은 Alerting 운영.

5.6 Lambda 배포 위생

  • Lambda zip에 __pycache__/*.pyc를 넣지 않는다. stale bytecode가 들어가면 소스 변경과 실제 런타임 동작이 어긋난다.
  • 같은 결과물(processed/)을 덮어쓰는 중복 IoT Rule/Lambda를 만들지 않는다. 구형 경로는 비활성화해 한 경로만 read model을 갱신하게 한다.
  • 주기적으로 실제 AWS 배포본(get-function)과 repo 코드를 대조해 drift를 확인한다.

Part 2 — 실패사례 (Failure Cases)

각 항목은 증상 → 원인 → 해결 → 재발 방지 순서로 정리했다. 전체 명령어는 위의 원본 운영 기록을 참조한다.

6. 스토리지 / Longhorn

6.1 AI Pod가 worker1에서 ContainerCreating에 멈추는 RWO Multi-Attach

  • 증상. worker2가 죽으면 BME·audio는 worker1로 잘 넘어가는데, AI만 ContainerCreating에 계속 머물렀다. 이벤트에는 Multi-Attach error for volume ... Volume is already used by pod(s)가 찍혔다.
  • 원인. AI가 Longhorn RWO PVC(safe-edge-ai-snapshots)를 마운트하고 있었다. worker2가 NotReady로 바뀌어도 기존 Pod와 VolumeAttachment가 stale 상태로 남아, Longhorn이 worker1 attach를 거부했다. 이건 두 writer가 붙는 것을 막는 정상적인 방어 동작이다.
  • 해결. snapshot 저장을 RWO PVC에서 node-local hostPath로 바꾸고 worker2 watchdog fencing을 걷어냈다. 이후 test_07~09에서 Multi-Attach는 재발하지 않았다.
  • 재발 방지. 복구 우선순위가 낮은 데이터에는 RWO PVC를 쓰지 않는다. fencing이 보장되기 전에는 force-detach를 자동화하지 않는다(§1.5).

6.2 Longhorn 설치·기동 단계의 잔실수 모음

  • manager가 master에 안 뜸. master의 NoSchedule taint에 toleration이 없어 DaemonSet이 worker 2개에만 배치됐다 → Longhorn taint-toleration 설정과 DaemonSet toleration을 추가한다.
  • KernelModulesLoaded=False. dm_crypt 모듈이 안 올라와 있었다 → modprobe dm_crypt/etc/modules-load.d/longhorn.conf 등록 후 manager를 재시작한다.
  • 데이터 경로 없음. /var/lib/longhorn이 없었다 → 세 노드에 미리 만들어 둔다.
  • Grafana PVC 권한 오류. 컨테이너 UID/GID가 맞지 않아 /var/lib/grafana is not writable가 났다 → securityContextfsGroup/runAsUser/runAsGroup: 472를 지정한다.

7. Failover / 복구

7.1 CronJob 기반 failback의 재생성 루프

  • 증상. worker2가 복구되자 하드웨어 의존 Pod가 worker2로 올라갔다가 계속 다시 생성됐다.
  • 원인. Kubernetes 관점에서 Ready여도 하드웨어가 아직 불안정했다. cooldown이나 중복 검사 없이 Pod를 삭제하다 보니 정상 동작 중인 Pod까지 죽었다.
  • 해결·재발 방지. failback을 master OS cron + Kubernetes-only 스크립트로 바꾸고, "worker2에 이미 대상 Pod가 있으면 손대지 않는다"는 가드를 최우선에 뒀다(§1.3).

7.2 하드웨어 의존 Pod의 RollingUpdate 장치 충돌

§1.1에서 정리한 그대로다. 같은 카메라·오디오·I2C 장치를 두 Pod가 잠깐이라도 동시에 열면서 초기화에 실패한다. Recreate 전략으로 해결한다.

7.3 재부팅 후 latest/Always pull로 Pod가 복구되지 않음

  • 증상. worker2를 재부팅하니 node-exporter가 ErrImagePull/ImagePullBackOff에 빠졌고, 로그에는 registry DNS 조회 실패가 찍혔다.
  • 원인. 태그가 latest이고 pull policy가 비어 있어 매번 외부 registry로 나가려 했는데, 내부망 노드는 재부팅 직후 외부 경로가 불안정했다.
  • 해결·재발 방지. imagePullPolicy: IfNotPresent를 명시하고 이미지를 미리 받아 둔다(§1.2). 다음 단계로 latest를 고정 버전 태그로 바꾼다.

8. 네트워크 / CNI

8.1 worker2 재부팅 후 flannel default route가 없어 agent가 안 올라옴

  • 증상. worker2가 NotReady에 머물고 k3s-agent가 activating을 반복했다. 로그에는 flannel ... unable to find default route, MetalLB·Longhorn CSI는 CrashLoopBackOff였다.
  • 원인. default route가 없으면 flannel이 기본 인터페이스를 못 고른다. 게다가 노드마다 flannel public-ip가 다른 대역(wlan0 vs eth0)으로 잡혀 overlay 경로가 어긋났다.
  • 해결·재발 방지. 세 노드에 --flannel-iface eth0를 명시하고, 시간 동기화를 켜고, 10.43.0.0/16 dev cni0 service-cidr route를 복구하는 service를 둔다. 빠른 복구는 경량 스크립트(safe-edge-preflight-repair.sh)로 처리한다.

8.2 master wlan0 단절로 Tailscale가 NoState가 되고 start_test.yml이 실패

  • 증상. Ansible start_test.yml의 Tailscale 검증이 실패했다. master에서 tailscale statusNoState/logged out, wlan0는 disconnected, default route도 없었다.
  • 원인. master의 인터넷 경로는 wlan0 default route에 의존한다. Wi-Fi 프로필이 꼬이면 control plane과 동기화가 끊긴다.
  • 해결. SSH는 eth0/Tailscale 경로로 유지한 채, wlan0 Wi-Fi 프로필만 삭제하고 다시 만든 뒤 tailscaled를 재시작했다.
  • 재발 방지. Tailscale 실패를 보면 hostname 불일치부터 의심하지 말고, wlan0 상태·default route·DNS·controlplane.tailscale.com 접근성을 먼저 확인한다. 인터페이스 역할을 고정한다(§2.1).

8.3 NetworkManager profile/device 혼동과 /8 정상화 후 접근 경로 변화

  • 증상. eth0에 IPv4가 안 붙고 nmcli connection up eth0unknown connection으로 실패했다. /8/24로 정상화한 뒤로는 로컬에서 10.10.10.x로 직접 SSH가 안 됐다.
  • 원인. profile 이름(Wired connection 1)과 device 이름(eth0)을 혼동했다. 그리고 직접 SSH가 막힌 건 설정 실패가 아니라, 그동안 지나치게 넓던 /8 route에 기대던 접근 방식이 사라졌기 때문이다.
  • 해결·재발 방지. profile=device=eth0로 통일하고, eth0는 static + never-default로 두며, 운영 접근은 Tailscale/wlan0 경로를 쓴다(§2.1, §2.3). eth0 프로필을 재생성하기 전에 우회 접근 경로부터 확보한다.

9. 하드웨어 / 센서

9.1 AI가 카메라는 잡지만 ai_detection을 못 쓰는 경우

  • 증상. Pod는 2/2 Running이고 로그도 카메라 연결까지 정상인데, InfluxDB에 ai_detection이 안 쌓였다. 로그 끝에는 Camera frontend has timed out이 보였다.
  • 원인. 장치를 인식하는 것과 실제 프레임을 캡처하는 것은 다르다. capture_array()가 막히면 그 뒤의 write가 실행되지 않는데, Pod는 Running이라 Kubernetes가 비정상으로 판단하지 못한다.
  • 해결. AI Deployment를 scale 0 → 1로 재기동한 뒤 ai_detection 최신값과 [AI STATUS] 로그를 확인했다.
  • 재발 방지. capture loop heartbeat, livenessProbe, 또는 일정 시간 write가 없으면 프로세스를 종료하는 watchdog을 추가한다(후보).

9.2 BME280 I2C 미인식과 원격 PATH 누락

  • I2C가 비활성(#dtparam=i2c_arm=on)이라 장치가 안 보였다 → config.txt에서 활성화하고 i2cdetect로 주소 0x76을 확인한다.
  • 비대화형 SSH의 PATH에 /usr/sbin이 없어 i2cdetect를 못 찾았다 → 절대경로 /usr/sbin/i2cdetect로 실행한다.

10. 데이터 파이프라인 / 대시보드

10.1 history 24h 조회에서 cascade 504 Gateway Timeout

  • 증상. /history?window=24h로 3개 공장을 동시에 조회하자 504 Gateway Timeout이 연쇄로 발생했다.
  • 원인. 24시간 구간을 HISTORY#STATE 원시 스냅샷으로 모두 훑으면서 DynamoDB 조회량과 응답 시간이 한계를 넘었다.
  • 해결. 구간별로 read model을 나눴다. 1h 이하는 HISTORY#STATEmax_items=500 cap을, 6h/12h/24hGRAPH#5M 5분 집계를 조회하게 했다(Multi-resolution History ADR).
  • 재발 방지. HISTORY#STATE TTL을 줄여 테이블 아이템 수를 낮추고, 긴 구간은 항상 집계 경로로만 조회한다.

10.2 데이터가 끊긴 공장의 risk score가 stale로 굳음

  • 증상. factory-a가 메시지 송신을 멈춘 뒤에도 DynamoDB LATESTrisk.score=100이 그대로 남아, 대시보드가 위험을 정상으로 보여줬다.
  • 원인. 메시지를 받을 때만 pipeline_statusrisk를 갱신하는 구조라, 데이터가 완전히 끊기면 갱신을 일으킬 trigger 자체가 없었다.
  • 해결. DataProcessorRefresh1m 스케줄러가 1분마다 DataProcessor를 action=refresh_pipeline_status로 호출하게 했다. 적용 후 factory-a는 pipeline_status=critical, risk.score=0으로 정상 전환됐다(메시지가 계속 들어오는 factory-b/c는 영향 없음).
  • 재발 방지. "수신 기반 갱신"에는 항상 신선도 만료를 강제하는 주기 refresh를 함께 둔다(§5.2).

10.3 Spoke의 ECR imagePullSecret 만료로 403 Forbidden/ErrImagePull

  • 증상. Spoke K3s에서 adapter rollout 시 403 ForbiddenErrImagePull이 났다.
  • 원인. Spoke K3s는 EKS node role을 상속받지 못하므로 ECR 토큰이 들어 있는 ai-apps/ecr-registry imagePullSecret이 만료되면 이미지를 못 받는다.
  • 해결·재발 방지. imagePullSecret을 주기적으로 갱신한다. rollout 전에 secret 신선도를 점검 항목에 넣는다.

10.4 구형 Lambda가 processed/ 결과를 덮어씀 + zip stale bytecode

  • 증상. 같은 processed/ 결과를 여러 IoT Rule/Lambda가 만들면서 최신 결과가 구형 Lambda 출력으로 덮였다. 별개로, 소스를 고쳤는데 런타임 동작이 안 바뀌는 경우도 있었다.
  • 원인. 중복 처리 경로가 살아 있었고, Lambda zip에 __pycache__/*.pyc stale bytecode가 섞여 들어갔다.
  • 해결·재발 방지. 중복 IoT Rule/Lambda를 비활성화해 read model 갱신 경로를 하나로 모으고, zip 패키징에서 __pycache__/*.pyc를 제외한다. 실제 배포본과 repo 코드를 주기적으로 대조한다(§5.6).

10.5 CloudInfraSlowCollector의 EKS API 401

  • 증상. Cloud infra slow collector가 EKS Kubernetes API 호출에서 401을 받아 노드/파드/ArgoCD 상태를 못 모았다.
  • 원인. collector IAM role에 대한 EKS access entry가 없었다.
  • 해결·재발 방지. AEGIS-IAMRole-Lambda-CloudInfraSlowCollectorAmazonEKSAdminViewPolicy cluster scope read 권한을 부여하니 errors=[]로 정상 수집됐다. 데이터 평면에서 제어 평면을 조회할 때는 읽기 전용 최소 권한만 부여한다.

11. AWS Hub

Hub build/destroy 과정의 MFA/STS 접근 실패, EKS CloudWatch Log Group 중복, state tainted 등 AWS 측 장애와 untaint/import 해법은 AWS Hub 트러블슈팅에 정리돼 있다. 공통 원칙은 AWS 리소스는 정상인데 state만 어긋났으면 새로 만들지 말고 untaint/import로 맞춘다는 것이다.


관련 문서

Aegis-Pi Wiki

· 대표 문서 목록은 홈의 문서 탐색 표 참조

시작하기

요구사항

핵심 개념

아키텍처

컴포넌트 (Edge → Cloud → Dashboard)

Dashboard & 운영

시나리오 · 사례 · 참조

Clone this wiki locally