MinIO AIStor 운영 체크 프레임워크를 설계해 드릴게요. 전체 구조와 각 항목을 인터랙티브하게 확인할 수 있도록 먼저 시각화하고, 이후 디렉토리 구조와 구체적인 항목을 정리하겠습니다.---
1. 공통 + 작업별 분리 구조
모든 체크를 공통(common) + 작업 유형별 레이어로 나눕니다. 실행 시에는 pre_common.sh → pre_{op_type}.sh 순서로 합산 실행하면 됩니다. 이렇게 하면 공통 항목 수정이 전체에 자동 반영됩니다.
2. severity 분류 (badge 기준)
critical — 이 항목 실패 시 작업 즉시 중단warn — 기록은 하되 운영자 판단으로 진행 가능info — 기록 및 참고 목적3. history.yaml 이력 파일
작업마다 run_id / env / operation / phase / operator / ticket / checks[] 구조로 저장합니다. Git에 커밋되므로 PR 기반 이력 추적과 diff 비교가 가능합니다.
4. CI/CD 흐름
Jenkins (파라미터: env, op_type)
→ AWX Job "run_pre_check" (inventory: {env}.ini)
→ pre_common.sh + pre_{op_type}.sh 실행
→ history/{env}/{date}_{op}_pre.yaml 저장
→ [작업 수행 — 별도 Playbook/ArgoCD]
→ AWX Job "run_post_check"
→ post_common.sh + post_{op_type}.sh 실행
→ ArgoCD sync 상태 확인
→ history/{env}/{date}_{op}_post.yaml 저장
→ 비교 리포트 생성
위 설계를 바탕으로 아래 순서로 스크립트 작성을 진행할 수 있습니다.
pre_common.sh / post_common.sh — mc 명령어 기반 공통 헬스 체크history.yaml 생성 헬퍼 함수 — 모든 스크립트에서 재사용하는 공통 로깅 라이브러리run_pre_check.yaml, run_post_check.yaml)어떤 스크립트부터 먼저 작성할까요? 특정 환경(Kubernetes 위 MinIO Operator 기반인지, 베어메탈인지 등) 세부 사항이 있으면 그에 맞게 조정해 드리겠습니다.
==

==
답변 감사합니다! 조합이 흥미롭네요 — 몇 가지만 더 확인하면 바로 시작할 수 있습니다.위젯 응답이 연결이 안 되고 있네요. 아래 합리적인 가정으로 바로 스크립트 작성 시작하겠습니다 — 틀린 부분은 알려주시면 즉시 수정할게요.
적용 가정:
kubectl / mc 는 bastion 서버 기준, AWX도 상황에 따라 실행minio-operator, Tenant: minio-{tenant_name}작성 순서: lib/common.sh → lib/history.sh → pre_common.sh → post_common.sh총 8개 파일이 완성됐습니다. 핵심 설계 포인트를 정리하면:
lib/common.sh — 모든 스크립트의 기반 라이브러리
log_pass/warn/fail), PASS/WARN/FAIL 결과 카운터 자동 추적kctl / mc_cmd 래퍼로 KUBECONFIG, MC_CONFIG_DIR 자동 주입check_result() — 결과를 배열에 누적, print_summary() — 최종 표 출력get_exit_code() — FAIL=1 / WARN=2 / PASS=0 반환 (Jenkins 빌드 결과 연동)lib/history.sh — 이력 관리 전담
init_history() / flush_checks_to_history() / finalize_history() 3단계 구조save_snapshot() 4종 (config/tenant_cr/version/storage)diff_with_previous() — pre/post 체크 결과 자동 비교 출력pre_common.sh — 9개 항목, K8s Operator 특화 포인트:
status.currentState 확인, PVC Bound 수 검증post_common.sh — 8개 항목, 무결성 중심:
kubectl get application 또는 argocd CLI로 이중 확인작업별 스크립트 (pre_upgrade.sh, pre_scale.sh 등) 로 이어집니다. 어느 작업 유형을 먼저 만들까요? 진행 중인 실제 작업이 있으면 그걸 우선으로 해드릴 수 있습니다.
==
환경 파악이 완벽하게 됐습니다. 핵심 추가 정보를 정리하면:
lib/common.sh의 크리덴셜 처리부를 보강하고, 이어서 작업별 스크립트 4종을 순차적으로 만들겠습니다.전체 스크립트 완성됐습니다. 이번 추가 내용의 핵심을 정리하면:
lib/credentials.sh — 4중 소스 크리덴셜 관리실행 환경(bastion/AWX Runner/in-cluster)을 자동 감지한 뒤, Vault → K8s Secret → AWX 환경변수 → bastion ~/.mc/config.json 순서로 크리덴셜을 시도합니다. 어떤 조합으로 실행하든 동일 스크립트가 작동합니다.
| 작업 | Pre 특화 | Post 특화 |
|---|---|---|
| install | EC 설계 수학 검증 (패리티 < 드라이브/2), AIStor 라이선스 JWT 만료일 파싱, StorageClass/DirectPV 확인 | CRD 설치 확인, StatefulSet Ready, TLS 만료일, 성능 기준값 측정 |
| scale | 클러스터 100% Green 필수 (FAIL 시 즉시 중단), 신규 노드 K8s 등록 및 Ready 확인, 라이선스 노드 한도 | Pool 수 증가 확인, 총 용량 증가 비교, Rebalancing 상태 |
| upgrade | 전 노드 Green 필수, 롤백 CR/Helm values 자동 저장, 스테이징 검증 완료 확인 (STAGING_VERIFIED) | 전 노드 버전 통일 확인, Pre 설정값 보존 여부 diff, 데이터 SHA256 무결성 |
| config | 변경 유형별 영향도 자동 분석 (env_var/tls/iam/replication/lifecycle), 변경 키 현재값 스냅샷 | Pre/Post 설정 diff 라인 수 측정, ArgoCD OutOfSync 경고, 변경 유형별 기능 검증 |
# 업그레이드
TARGET_MINIO_VERSION=RELEASE.2025-03-12T...
TARGET_OPERATOR_VERSION=6.1.0
STAGING_VERIFIED=true
BREAKING_CHANGES_REVIEWED=true
# 증설
NEW_POOL_NODES=4
NEW_POOL_DRIVES=8
NEW_NODE_IPS="10.0.1.10,10.0.1.11,10.0.1.12,10.0.1.13"
# 설정 변경
CONFIG_CHANGE_TYPE=tls # env_var|policy|tls|replication|lifecycle|iam
CONFIG_KEYS_TO_CHANGE=identity.openid,site.name
RESTART_REQUIRED=true
===
좋은 질문입니다. 핵심 설계 결정이 하나 있는데 — 레포를 목적별로 분리해야 합니다. ArgoCD가 감시하는 레포에 점검 결과가 커밋되면 불필요한 sync가 트리거되기 때문입니다.---
왜 3개 레포인가 — 가장 중요한 이유는 커밋 목적이 다르기 때문입니다.
| 레포 | 커밋 트리거 | ArgoCD |
|---|---|---|
gitops | 사람 (PR 승인) | 감시함 — sync 발생 |
ops | 사람 (스크립트 수정) | 감시 안 함 |
history | AWX 자동 | 감시 안 함 |
push-history.sh 가 핵심 연결고리입니다. 체크 완료 후 이 스크립트가 결과 파일들을 history 레포에 커밋하기 때문에, ops 레포는 항상 깨끗하게 유지됩니다.
Kustomize 전환 전략 — kustomize/ 디렉토리를 지금부터 gitops 레포에 만들어 두되 비워두면 됩니다. 전환이 필요해지면 ArgoCD Application의 source.path를 helm/tenant → kustomize/overlays/prod로 변경하는 것만으로 충분합니다. Helm과 Kustomize는 환경별로 독립 선택이 가능하기 때문에, prod는 안정적인 Helm을 유지하면서 dev에서 먼저 Kustomize를 실험해볼 수 있습니다.
다음으로 push-history.sh와 ArgoCD Application YAML 템플릿을 만들어 드릴까요?
===

===
이제 ArgoCD Application YAML을 만들겠습니다. App of Apps 패턴으로 구성해서, 상위 Application 하나가 env별 하위 Application들을 관리합니다.총 10개 파일입니다. 각 파일의 핵심 설계 포인트를 정리하면:
push-history.shGit 인증을 SSH 키 → HTTPS Token → 시스템 기본 순서로 자동 탐색합니다. RUN_TIMESTAMP 기준으로 해당 실행의 파일만 선택적으로 복사하기 때문에, 여러 체크가 동시에 실행되어도 섞이지 않습니다. CLEANUP_OPS_ARTIFACTS=true(기본값)로 설정하면 push 성공 후 ops 레포 로컬 결과물을 자동 삭제해 디스크를 절약합니다. DRY_RUN=true로 실제 push 없이 시뮬레이션할 수 있어 처음 도입 시 테스트가 쉽습니다.
| 설정 | dev | staging | prod |
|---|---|---|---|
targetRevision | develop | develop | main |
automated.prune | true | true (Operator), false (Tenant) | 비활성 |
automated.selfHeal | true | true | 비활성 |
sync-wave Operator | -1 | -1 | -1 |
| 수동 승인 | 불필요 | 불필요 | 필요 |
Tenant는 모든 환경에서 prune: false입니다. ArgoCD가 실수로 Tenant를 삭제하면 데이터가 유실되기 때문입니다.
sync-policy.yaml — Sync Windowprod 환경 sync는 KST 09:00~18:00 업무일에만 자동 허용됩니다. 그 외 시간에는 ArgoCD UI에서 수동으로 override해야 하며, 이 override 자체가 감사 로그에 남습니다.
run_checks.yaml playbook의 post_tasks에 아래 태스크를 추가하면 됩니다:
- name: "체크 결과 history 레포에 push"
shell: bash {{ ops_repo_path }}/scripts/push-history.sh
environment:
HISTORY_REPO_URL: "{{ history_repo_url }}"
ENV: "{{ env }}"
OPERATION: "{{ operation }}"
PHASE: "{{ phase }}"
GIT_TOKEN: "{{ bitbucket_token }}" # AWX Credential
TICKET_ID: "{{ ticket_id }}"
OPERATOR: "{{ operator }}"
when: push_history | default(true)
===
전체 그림부터 잡고 시나리오별로 보여드릴게요. 그리고 모든 걸 하나로 묶는 AWX 중심 오케스트레이션 플레이북을 만들겠습니다.이제 모든 걸 하나로 묶는 AWX 중심 오케스트레이션 플레이북을 만들겠습니다.---
시나리오 뷰어에서 탭별로 볼 수 있듯이, 모든 작업은 동일한 5단계 구조를 따릅니다.
어떤 파일이 언제 실행되는가:
AWX Job "minio-aistor-orchestrate"
└─ orchestrate.yaml 실행
├─ [1] pre-check
│ ├─ lib/credentials.sh → 크리덴셜 자동 탐색 (Vault→K8s→AWX→bastion)
│ ├─ checks/common/pre_common.sh → 9개 공통 항목
│ └─ checks/{op}/pre_{op}.sh → 작업별 추가 항목
│
├─ [2] 승인 게이트 (prod만) → AWX pause task, 운영자 Enter
│
├─ [3] ArgoCD sync
│ └─ argocd app sync minio-tenant-prod (또는 kubectl fallback)
│
├─ [4] post-check
│ ├─ checks/common/post_common.sh
│ └─ checks/{op}/post_{op}.sh
│
└─ [5] push-history
└─ scripts/push-history.sh → history 레포 커밋
실행 방법 3가지:
| 방법 | 언제 | 명령 |
|---|---|---|
| AWX Job Template | 표준 운영 작업 | AWX Survey에서 env/operation 선택 후 Launch |
run-check.sh | bastion에서 수동 테스트 | bash scripts/run-check.sh |
run-check.sh --non-interactive | CI 스크립트나 긴급 대응 | ENV=prod OPERATION=upgrade ... bash scripts/run-check.sh -y |
orchestrate.yaml에서 핵심 설계 포인트 두 가지를 보면 — prod 환경에서 Pre-Check가 rc==1(FAIL)이면 즉시 플레이북이 중단되고, ArgoCD CLI가 없는 환경에서는 kubectl patch application으로 자동 fallback합니다.
=

==
지금까지 만든 건 "작업 전후 점검"이 전부입니다. 실제 운영엔 그 외에도 꽤 많은 영역이 빠져 있습니다. 전체 그림부터 보여드릴게요.22개 미구현 항목 중 실운영 영향이 가장 큰 4개 영역 스크립트를 지금 바로 만들겠습니다.---
daily_health.sh — 매일 07:00 KST 자동 실행7개 항목을 점검하고, 매주 월요일에는 지난 7일 일별 체크 이력을 집계해 주별 리포트를 자동 생성합니다. FAIL 결과가 나오면 scheduled_checks.yaml이 drive_failure.sh를 자동 트리거합니다.
security_audit.sh — 월 1회IAM 비활성 계정·관리자 권한 계정 탐지, TLS 알고리즘(SHA-1 탐지), 감사 로그 활성화 여부, 버킷 퍼블릭 정책, Service Account 만료 미설정 탐지 6개 영역을 점검합니다.
capacity_plan.sh — 주 1회history 레포의 daily_health.sh 이력에서 daily_used_bytes 값을 추출해 선형 회귀로 일별 증가율을 계산하고, 현재 여유 공간 기준으로 풀 소진 예상일과 80% 도달 예상일(증설 권장 시점)을 출력합니다. daily_health.sh가 30일 이상 쌓인 후부터 정확해집니다.
drive_failure.sh — 인시던트 발생 시 자동/수동Quorum 손실 여부 판단 → Healing 자동 트리거 → 데이터 접근 가능 여부 확인 → CrashLoop Pod 재시작 → 인시던트 리포트 생성 순으로 대응합니다.
scheduled_checks.yaml — AWX Schedule 설정| AWX Schedule | cron (UTC) | 실행 내용 |
|---|---|---|
daily-health-prod | 0 22 * * * | daily_health.sh |
weekly-capacity-prod | 0 0 * * 1 | capacity_plan.sh |
monthly-security-prod | 0 1 1 * * | security_audit.sh |
아직 남아있는 DR/복제 검증, 성능 기준선 추적, 라이선스 컴플라이언스 스크립트가 필요하면 이어서 만들어 드릴 수 있습니다.
===
모듈 구조 설계부터 잡고 바로 작성하겠습니다. daily_health.sh는 오케스트레이터로만 남기고, 각 인프라 레이어를 독립 모듈로 분리합니다.---
checks/daily/
├── daily_health.sh ← 오케스트레이터 (실행 순서 제어)
└── modules/
├── _module_helper.sh ← 공통 헬퍼 (단독/오케스트레이터 양방향 지원)
├── k8s_health.sh ← Kubernetes 레이어
├── cilium_health.sh ← Cilium CNI 레이어
└── minio_health.sh ← MinIO AIStor 레이어
실행 순서가 의도적 — K8s → Cilium → MinIO 순으로 인프라 레이어 하위부터 점검합니다. Cilium이 죽으면 MinIO API도 당연히 안 되기 때문에, 장애 원인을 하위 레이어에서 먼저 발견할 수 있습니다.
모듈 단독 실행 가능 — _module_helper.sh의 STANDALONE_MODULE 플래그로 오케스트레이터 없이도 각 모듈을 직접 실행할 수 있습니다. 특정 레이어만 빠르게 점검할 때 유용합니다:
# Cilium만 빠르게 확인
ENV=prod bash checks/daily/modules/cilium_health.sh
# K8s와 Cilium만 실행
SKIP_MODULES=minio bash checks/daily/daily_health.sh
| 환경 변수 | 기본값 | 설명 |
|---|---|---|
BGP_EXPECTED_PEERS | 0 | 예상 BGP 피어 수. 설정 시 미달이면 FAIL |
CLUSTERMESH_CLUSTERS | 0 | 예상 원격 클러스터 수 |
ECMP_MIN_PATHS | 2 | ECMP 최소 경로 수 |
CILIUM_NAMESPACE | kube-system | Cilium 설치 네임스페이스 |
Cilium CLI(cilium)가 있으면 자동으로 사용하고, 없으면 kubectl exec로 agent Pod에서 직접 실행하는 방식으로 자동 fallback합니다.