/인프라/Helm "another operation in progress" 에러 해결법 (pending 락)
인프라HelmKubernetes

Helm "another operation in progress" 에러 해결법 (pending 락)

Helm "another operation in progress" 에러로 배포가 막혔나요? helm history 진단, helm rollback과 pending Secret 삭제로 락 푸는 법, --atomic 재발 방지까지 복붙 명령어로 정리했습니다.

Helm "another operation in progress" 에러 해결법 (pending 락)

Helm "another operation in progress" 에러 해결: pending 락 5분 복구법

CI 파이프라인이 빨갛게 멈췄고, 로그 맨 아래엔 이 한 줄이 떠 있습니다.

CODE
Error: UPGRADE FAILED: another operation (install/upgrade/rollback) is in progress

재실행을 눌러도 똑같은 에러. 이 글은 "지금 배포가 막혀 있는 당신"을 위한 것입니다. 결론부터 말하면, 이건 데이터 손실 없이 거의 항상 5분 안에 풀립니다. 단, 절대 하지 말아야 할 행동이 하나 있습니다.

⚠️ 가장 먼저 알아둘 것: 급한 마음에 helm delete(=helm uninstall)를 치지 마세요. 이건 락을 푸는 명령이 아니라 릴리스와 그에 딸린 워크로드(Deployment, Service 등)를 통째로 삭제하는 명령입니다. 프로덕션에서 이걸로 락을 풀려다 서비스가 내려간 사례가 정말 많습니다.

왜 락이 걸리나: Helm 3의 release state 메커니즘

Helm 2 시절엔 Tiller가 릴리스 상태를 ConfigMap에 저장했지만, Helm 3부터는 기본적으로 Secret에 저장합니다. 이름 규칙이 정해져 있어요.

CODE
sh.helm.release.v1.<release-name>.v<revision-number>

배포할 때마다 새 리비전 Secret이 하나씩 쌓이고, 각 Secret에는 상태 라벨이 붙습니다. 정상적인 흐름은 이렇습니다.

시점Secret status 라벨
설치/업그레이드 시작pending-install / pending-upgrade
정상 완료deployed
명시적 삭제uninstalled

문제는 배포가 중간에 죽었을 때입니다. 타임아웃, 파드 강제종료, CI 잡 강제 중단, 동시 트리거... 어떤 이유로든 Helm 프로세스가 deployed로 마무리하지 못하면, 그 리비전 Secret은 영원히 pending-* 상태로 남습니다.

  • pending-install첫 설치가 중단됨 (이전 deployed 리비전이 없음)
  • pending-upgrade업그레이드가 중단됨 (이전 deployed 리비전이 있음)
  • pending-rollback롤백이 중단됨

Helm은 다음 작업을 시작하기 전에 "마지막 리비전이 pending이면 다른 작업이 진행 중인 걸로 간주"하고 막아버립니다. 그게 바로 그 한 줄짜리 에러의 정체입니다. ArgoCD나 Flux 같은 GitOps 도구도 내부적으로 Helm을 쓰기 때문에 동일하게 발생합니다.

진단: 내 릴리스가 어디에 갇혔는지 5분 안에 찾기

복구 전에 반드시 상태부터 확인합니다. 어떤 리비전이 마지막 정상(deployed)인지 알아야 안전하게 풀 수 있어요.

Bash
# 1) 리비전 이력 — STATUS 컬럼을 보세요
helm history <release> -n <ns>

# 2) 현재 릴리스 상태
helm status <release> -n <ns>

# 3) 실제 Secret을 시간순으로 확인
kubectl get secret -n <ns> -l owner=helm,name=<release> \
  --sort-by=.metadata.creationTimestamp

helm history 출력은 이런 식입니다.

CODE
REVISION  STATUS           CHART          DESCRIPTION
3         deployed         myapp-1.2.0    Upgrade complete
4         pending-upgrade  myapp-1.3.0    Preparing upgrade

여기서 핵심은 두 가지입니다.

  1. 마지막으로 deployed인 리비전 번호 → 위 예시에서는 3. 롤백 목표가 됩니다.
  2. pending으로 갇힌 리비전4. 이게 락의 원인입니다.

kubectl get secret으로 보면 sh.helm.release.v1.myapp.v4 Secret이 status=pending-upgrade 라벨을 달고 있는 걸 확인할 수 있습니다. 이 Secret이 범인입니다.

원인별 복구 3루트 (우선순위 순서대로)

가장 안전한 순서대로 시도하세요. 위에서부터 안 되면 아래로 내려갑니다.

1순위 — 직전 deployed 리비전으로 롤백 (가장 안전)

이전에 정상 배포된 리비전이 있다면(=pending-upgrade인 경우), 롤백이 정답입니다. Helm이 pending Secret을 정리하고 상태를 깔끔하게 되돌려 줍니다.

Bash
# 위에서 찾은 '마지막 deployed' 리비전 번호 사용
helm rollback <release> 3 -n <ns>

롤백이 성공하면 락이 풀리고, 다시 helm upgrade를 할 수 있습니다. 데이터 손실 없이 가장 깔끔한 방법입니다.

2순위 — pending Secret 직접 삭제 (롤백 대상이 없거나 롤백도 실패할 때)

pending-install인 경우엔 돌아갈 deployed 리비전이 아예 없어서 롤백이 불가능합니다. 또는 롤백 자체가 실패하기도 합니다. 이럴 땐 pending Secret만 콕 집어 삭제합니다.

Bash
# 라벨로 pending 상태 Secret만 삭제 (status를 정확히 지정!)
kubectl delete secret -n <ns> \
  -l owner=helm,name=<release>,status=pending-upgrade

# 또는 리비전 번호로 특정 Secret만 삭제
kubectl delete secret sh.helm.release.v1.<release>.v<N> -n <ns>

삭제 후 재배포하면 락이 풀린 상태에서 다시 진행됩니다.

Bash
helm upgrade --install <release> ./chart -n <ns>

3순위 — 상태가 꼬였을 때 정리

여러 번 재시도하다 pending Secret이 여러 개 쌓였다면, deployed Secret은 절대 건드리지 말고 pending 라벨이 붙은 것들만 정리한 뒤 재배포합니다. 삭제 전 kubectl get secret으로 대상을 한 번 더 눈으로 확인하는 습관이 사고를 막습니다.

⚠️ 주의사항 (꼭 지키세요)

  • deployed 상태 Secret을 지우면 릴리스 이력이 깨집니다. 오직 pending-*만 삭제하세요.
  • helm delete/helm uninstall은 락 해제용이 아닙니다. 워크로드까지 사라집니다.
  • ✅ 항상 네임스페이스(-n)와 리비전 번호를 명시하고, 삭제 전 대상을 한 번 더 확인하세요.

타임아웃이 근본 원인일 때

실무에서 pending 락의 가장 흔한 원인은 타임아웃입니다. --wait 옵션을 주면 Helm은 파드가 Ready가 될 때까지 기다리는데, 헬스체크가 안 통과하면 결국 이렇게 끝납니다.

CODE
Error: UPGRADE FAILED: timed out waiting for the condition

이때 릴리스는 pending-upgrade로 남고, 다음 배포가 막힙니다. 제 경험상 readinessProbe 설정이 빡빡하거나 이미지 풀이 느린 환경에서 자주 터지는데, 락만 풀고 끝내면 다음에 또 같은 일이 반복됩니다. 근본 처방은 배포 옵션을 바꾸는 것입니다.

Bash
helm upgrade --install <release> ./chart -n <ns> \
  --atomic \            # 실패 시 자동 롤백 → pending이 남지 않음
  --cleanup-on-fail \   # 실패 시 생성된 리소스 정리
  --wait \
  --timeout 10m         # 환경에 맞게 충분히

--atomic이 핵심입니다. 배포가 실패해도 자동으로 직전 상태로 롤백되기 때문에, 애초에 pending 락이 남지 않습니다. CI 파이프라인 배포 명령에 이 옵션 하나만 추가해도 이 에러를 만날 일이 크게 줄어듭니다.

결론: 재발 방지 체크리스트 + 복붙용 요약

진단부터 복구까지 한 장으로 정리합니다.

Bash
# ── 진단 ──
helm history <release> -n <ns>        # deployed / pending 리비전 확인
helm status  <release> -n <ns>
kubectl get secret -n <ns> -l owner=helm,name=<release> \
  --sort-by=.metadata.creationTimestamp

# ── 복구 1순위: 롤백 ──
helm rollback <release> <마지막 deployed REVISION> -n <ns>

# ── 복구 2순위: pending Secret 직접 삭제 ──
kubectl delete secret -n <ns> -l owner=helm,name=<release>,status=pending-upgrade
helm upgrade --install <release> ./chart -n <ns>

# ── 재발 방지: 배포 옵션 ──
helm upgrade --install <release> ./chart -n <ns> \
  --atomic --cleanup-on-fail --wait --timeout 10m

재발 방지 체크리스트:

  • 배포 명령에 --atomic + --cleanup-on-fail 적용
  • --timeout을 환경 현실에 맞게 충분히 설정
  • CI에서 동시/중복 배포 트리거 방지 (GitHub Actions concurrency, GitLab resource_group)
  • 배포 잡 타임아웃을 Helm --timeout보다 길게 (잡이 먼저 죽으면 pending이 남음)

자주 묻는 질문 (FAQ)

Q. pending Secret을 지우면 운영 중인 파드도 같이 사라지나요? A. 아닙니다. sh.helm.release.v1.* Secret은 릴리스의 **메타데이터(상태/매니페스트 이력)**만 담고 있습니다. 실제 워크로드(Deployment, Pod 등)는 별개의 리소스라서, pending Secret 하나를 지워도 실행 중인 파드에는 영향이 없습니다. 단 deployed Secret은 절대 지우지 마세요.

Q. ArgoCD로 배포하는데도 같은 에러가 납니다. 왜죠? A. ArgoCD와 Flux도 내부적으로 Helm 템플릿/릴리스 메커니즘을 사용하기 때문에 동일한 pending 락이 발생할 수 있습니다. 진단과 복구 방법은 같습니다. kubectl로 pending Secret을 정리한 뒤 Sync를 다시 트리거하면 됩니다.

Q. helm rollback도 "another operation in progress"로 실패해요. A. 마지막 리비전이 pending-install이라 돌아갈 deployed 리비전이 없거나, 상태가 꼬인 경우입니다. 이럴 땐 2순위 방법대로 kubectl delete secret으로 pending Secret만 삭제한 뒤 helm upgrade --install로 재배포하세요.

✦ ✦ ✦
편집 검토 · Editorial Review

이 글은 AI 에이전트가 1차 초안을 작성한 뒤, 사람 편집자가 사실관계·출처·톤과 맥락을 검토하여 발행했습니다. 오류나 부정확한 내용이 확인되면 24시간 이내에 정정합니다.

작성 · Content Reviewer·검토 · 사람 편집자·발행 · 2026년 6월 16일

댓글

불러오는 중...