26M21a

Young-Kyoo Kim·2026년 3월 20일

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 저장
      → 비교 리포트 생성

다음 단계 제안

위 설계를 바탕으로 아래 순서로 스크립트 작성을 진행할 수 있습니다.

  1. pre_common.sh / post_common.sh — mc 명령어 기반 공통 헬스 체크
  2. history.yaml 생성 헬퍼 함수 — 모든 스크립트에서 재사용하는 공통 로깅 라이브러리
  3. 작업 유형별 스크립트 — install → scale → upgrade → config 순서로
  4. Ansible Playbook (run_pre_check.yaml, run_post_check.yaml)
  5. Jenkinsfile — 파라미터형 Pipeline

어떤 스크립트부터 먼저 작성할까요? 특정 환경(Kubernetes 위 MinIO Operator 기반인지, 베어메탈인지 등) 세부 사항이 있으면 그에 맞게 조정해 드리겠습니다.

==

==

답변 감사합니다! 조합이 흥미롭네요 — 몇 가지만 더 확인하면 바로 시작할 수 있습니다.위젯 응답이 연결이 안 되고 있네요. 아래 합리적인 가정으로 바로 스크립트 작성 시작하겠습니다 — 틀린 부분은 알려주시면 즉시 수정할게요.

적용 가정:

  • dev/staging/prod 각각 별도 클러스터 + 클러스터 내 네임스페이스로 Tenant 분리
  • kubectl / mc 는 bastion 서버 기준, AWX도 상황에 따라 실행
  • Operator 네임스페이스: minio-operator, Tenant: minio-{tenant_name}
  • 크리덴셜: AWX Credential → 환경변수로 주입
  • 클러스터당 Tenant 1개 (파라미터로 멀티 지원)

작성 순서: lib/common.shlib/history.shpre_common.shpost_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단계 구조
  • Python3로 YAML 조작 (yq 불필요), save_snapshot() 4종 (config/tenant_cr/version/storage)
  • diff_with_previous() — pre/post 체크 결과 자동 비교 출력

pre_common.sh — 9개 항목, K8s Operator 특화 포인트:

  • Tenant CRD status.currentState 확인, PVC Bound 수 검증
  • mc admin info JSON 파싱으로 서버/드라이브 수 정밀 확인
  • 작업 전 Lock 수 + Healing 진행 여부 동시 체크

post_common.sh — 8개 항목, 무결성 중심:

  • S3 PUT → GET → SHA256 체크섬 비교 → DELETE 전 사이클 검증
  • Operator + Tenant Pod 에러 로그 5분 내 급증 감지
  • ArgoCD sync 상태를 kubectl get application 또는 argocd CLI로 이중 확인

다음 단계

작업별 스크립트 (pre_upgrade.sh, pre_scale.sh 등) 로 이어집니다. 어느 작업 유형을 먼저 만들까요? 진행 중인 실제 작업이 있으면 그걸 우선으로 해드릴 수 있습니다.

==

환경 파악이 완벽하게 됐습니다. 핵심 추가 정보를 정리하면:

  • 클러스터당 Tenant 1개 → 네임스페이스 구조 단순화 가능
  • 크리덴셜 4중 소스 → 우선순위 로직 필요 (Vault > K8s Secret > AWX Credential > bastion 파일)
  • bastion + AWX Runner 혼용 → 실행 위치 자동 감지 필요

lib/common.sh의 크리덴셜 처리부를 보강하고, 이어서 작업별 스크립트 4종을 순차적으로 만들겠습니다.전체 스크립트 완성됐습니다. 이번 추가 내용의 핵심을 정리하면:


추가된 내용 요약

lib/credentials.sh — 4중 소스 크리덴셜 관리

실행 환경(bastion/AWX Runner/in-cluster)을 자동 감지한 뒤, Vault → K8s Secret → AWX 환경변수 → bastion ~/.mc/config.json 순서로 크리덴셜을 시도합니다. 어떤 조합으로 실행하든 동일 스크립트가 작동합니다.

작업별 스크립트 핵심 체크 포인트

작업Pre 특화Post 특화
installEC 설계 수학 검증 (패리티 < 드라이브/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사람 (스크립트 수정)감시 안 함
historyAWX 자동감시 안 함

push-history.sh 가 핵심 연결고리입니다. 체크 완료 후 이 스크립트가 결과 파일들을 history 레포에 커밋하기 때문에, ops 레포는 항상 깨끗하게 유지됩니다.

Kustomize 전환 전략kustomize/ 디렉토리를 지금부터 gitops 레포에 만들어 두되 비워두면 됩니다. 전환이 필요해지면 ArgoCD Application의 source.pathhelm/tenantkustomize/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.sh

Git 인증을 SSH 키 → HTTPS Token → 시스템 기본 순서로 자동 탐색합니다. RUN_TIMESTAMP 기준으로 해당 실행의 파일만 선택적으로 복사하기 때문에, 여러 체크가 동시에 실행되어도 섞이지 않습니다. CLEANUP_OPS_ARTIFACTS=true(기본값)로 설정하면 push 성공 후 ops 레포 로컬 결과물을 자동 삭제해 디스크를 절약합니다. DRY_RUN=true로 실제 push 없이 시뮬레이션할 수 있어 처음 도입 시 테스트가 쉽습니다.

ArgoCD Application YAML — 환경별 차이

설정devstagingprod
targetRevisiondevelopdevelopmain
automated.prunetruetrue (Operator), false (Tenant)비활성
automated.selfHealtruetrue비활성
sync-wave Operator-1-1-1
수동 승인불필요불필요필요

Tenant는 모든 환경에서 prune: false입니다. ArgoCD가 실수로 Tenant를 삭제하면 데이터가 유실되기 때문입니다.

sync-policy.yaml — Sync Window

prod 환경 sync는 KST 09:00~18:00 업무일에만 자동 허용됩니다. 그 외 시간에는 ArgoCD UI에서 수동으로 override해야 하며, 이 override 자체가 감사 로그에 남습니다.

AWX에서 push-history.sh 호출 방법

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.shbastion에서 수동 테스트bash scripts/run-check.sh
run-check.sh --non-interactiveCI 스크립트나 긴급 대응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개 영역 스크립트를 지금 바로 만들겠습니다.---

추가된 4개 스크립트 핵심 정리

daily_health.sh — 매일 07:00 KST 자동 실행

7개 항목을 점검하고, 매주 월요일에는 지난 7일 일별 체크 이력을 집계해 주별 리포트를 자동 생성합니다. FAIL 결과가 나오면 scheduled_checks.yamldrive_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 Schedulecron (UTC)실행 내용
daily-health-prod0 22 * * *daily_health.sh
weekly-capacity-prod0 0 * * 1capacity_plan.sh
monthly-security-prod0 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.shSTANDALONE_MODULE 플래그로 오케스트레이터 없이도 각 모듈을 직접 실행할 수 있습니다. 특정 레이어만 빠르게 점검할 때 유용합니다:

# Cilium만 빠르게 확인
ENV=prod bash checks/daily/modules/cilium_health.sh

# K8s와 Cilium만 실행
SKIP_MODULES=minio bash checks/daily/daily_health.sh

Cilium 체크 상세 (환경 변수로 조정)

환경 변수기본값설명
BGP_EXPECTED_PEERS0예상 BGP 피어 수. 설정 시 미달이면 FAIL
CLUSTERMESH_CLUSTERS0예상 원격 클러스터 수
ECMP_MIN_PATHS2ECMP 최소 경로 수
CILIUM_NAMESPACEkube-systemCilium 설치 네임스페이스

Cilium CLI(cilium)가 있으면 자동으로 사용하고, 없으면 kubectl exec로 agent Pod에서 직접 실행하는 방식으로 자동 fallback합니다.

0개의 댓글