본문으로 건너뛰기

Kubernetes에서 RabbitMQ 운영

증상

RabbitMQ가 Kubernetes에서 일관되지 않게 작동하는 경우 이 가이드를 사용하세요.

  • Cluster Operator 또는 Topology Operator가 시작되지 않습니다.
  • 대기열 또는 Exchange CR이 정상이라고 보고하지만 브로커에 개체가 없습니다.
  • Spring 또는 워커 컨슈머가 404 NOT_FOUND - no queue ...와 충돌합니다.
  • 브로커를 다시 시작하면 PRECONDITION_FAILED 교환 유형 불일치가 노출됩니다.
  • 서비스 로그가 정상으로 보이는 경우에도 앱 시작 프로브가 실패합니다.

현재 저장소에서 기대하는 것

현재 RabbitMQ GitOps 분할은 다음과 같습니다.

  • lumie-infra/platform/rabbitmq/base/rabbitmq-cluster.yaml의 브로커 런타임
  • lumie-infra/platform/rabbitmq/base/topology/*.yaml의 토폴로지 CR
  • lumie-infra/platform/rabbitmq/overlays/dev/kustomization.yamllumie-infra/platform/rabbitmq/overlays/prod/kustomization.yaml의 개발 및 프로덕션 소유권 패치

베이스는 여전히 load_definitions 부트스트랩 경로와 rabbitmq-definitions ConfigMap을 전달하지만 이제 두 오버레이 모두 해당 경로를 제거하고 토폴로지 CR을 rabbitmqClusterReference.name로 다시 지정합니다. 이는 기본 파일이 여전히 이전 부트스트랩 메커니즘을 표시하더라도 저장소가 이미 이후 운영자 소유 방향을 반영하고 있음을 의미합니다.

lumie-infra/platform/rabbitmq/base/configmap.yaml는 또한 의도된 분할을 명확하게 문서화합니다. 가상 호스트, 사용자 및 권한만 definitions.json에 속합니다. 교환, 큐, 바인딩 및 정책은 base/topology/에 속합니다.

이러한 실패가 발생하는 이유

이 가이드를 만들게 된 사건은 하나의 버그가 아니었습니다. 여러 운영 함정이 겹친 결과였습니다.

  • 차트 기본값은 실제로 배포된 것과 다른 이미지나 진입점을 가정합니다.
  • 운영자에게 차트 버전이 부여되지 않은 RBAC가 필요했습니다.
  • ConfigMap이 존재했지만 RabbitMQ는 이를 로드하거나 마운트하라는 지시를 받은 적이 없습니다.
  • 동일한 교환이 유형이 다른 둘 이상의 기관에서 선언되었습니다.
  • 실행 중인 Spring Boot 버전이 노출하지 않은 엔드포인트를 대상으로 하는 상태 프로브

일반적인 교훈은 Kubernetes의 RabbitMQ가 하나의 제어 평면이 아니라는 것입니다. 차트, 운영자, 브로커 구성, 토폴로지 CR 및 소비 앱은 모두 각 레이어를 소유한 사람에 동의해야 합니다.

진단 경로

연산자 레이어부터 시작

운영자 Pod가 충돌하는 경우 브로커 자체를 디버깅하기 전에 렌더링된 배포를 검사하세요.

  • 이미지 및 명령
  • ClusterRole 규칙
  • 차트 버전과 실제로 배포된 이미지 버전

안정적인 조정 루프에 도달하지 못한 운영자는 브로커 상태에 대해 아무 것도 증명할 수 없습니다.

"원하는 개체"와 "브로커에 개체가 존재함"을 구분하세요.

큐, 교환, 바인딩 또는 정책 CR의 Ready=True는 컨트롤러가 일부 브로커 대상에 대해 조정되었음을 증명할 뿐입니다. 앱 지향 브로커에 예상한 개체가 있음을 증명하지는 않습니다. 앱에 404 NOT_FOUND - no queue ...가 표시되면 브로커를 신뢰한 다음 CR의 rabbitmqClusterReference를 검사하세요.

정의가 전체 경로로 로드되는지 확인

ConfigMap만으로는 아무 작업도 수행하지 않습니다. 기록 부트스트랩 경로에는 다음이 모두 필요합니다.

  • load_definitions = /etc/rabbitmq/definitions/definitions.json
  • 해당 경로에 ConfigMap을 배치하는 볼륨 마운트

어느 쪽이든 누락된 경우 클러스터에 ConfigMap이 있더라도 브로커는 의도한 정의 없이 시작됩니다.

당국 간 선언 드리프트 확인

이것은 고전적인 PRECONDITION_FAILED 케이스입니다. 앱 코드와 인프라 매니페스트에서 대기열이나 교환이 선언되면 브로커는 모든 유형 불일치를 하드 계약 위반으로 처리합니다. 현재 토폴로지 CR은 lumie.dlxlumie-infra/platform/rabbitmq/base/topology/exchanges.yamltopic 교환으로 정의하므로 모든 앱 측 선언이 해당 계약과 일치해야 합니다.

상태 프로브 경로를 런타임 계약으로 처리

Spring 앱이 로그에서 정상으로 보이지만 Kubernetes가 이를 준비 상태로 표시하지 않는 경우 정확한 프로브 경로가 런타임에 계속 노출되는지 확인하세요. 역사적 /actuator/health/startup 손상은 기본적으로 Boot 끝점 그룹이 존재한다고 가정하여 발생했습니다.

수정

  1. RabbitmqCluster의 브로커 런타임, 토폴로지 운영자 CR의 토폴로지, 소비자 전용 앱 리스너 등 레이어당 하나의 권한을 유지합니다.
  2. 정의 부트스트랩이 여전히 필요한 경우 load_definitions와 일치하는 마운트 경로를 모두 구성합니다. ConfigMap에서 멈추지 마십시오.
  3. 토폴로지 CR이 잘못된 브로커를 가리키고 참조 필드를 변경할 수 없는 경우 rabbitmq.com/keepAfterDeletion: "true"가 있는지 확인한 후에만 CR을 삭제하고 다시 생성하십시오.
  4. 선언된 유형 중 하나를 선택하고 충돌하는 브로커 객체를 삭제하거나 다시 생성하여 교환 유형 불일치를 해결합니다. RabbitMQ는 기존 교환 유형을 변경하지 않습니다.
  5. 시작이 404를 조사하는 경우 앱이 이미 노출한 경로로 전환하거나 프로브가 예상하는 엔드포인트 그룹을 명시적으로 활성화합니다.

예방

  • 배포된 이미지가 차트의 가정된 이미지와 다를 때마다 감사 차트가 기본값으로 설정됩니다.
  • 애플리케이션 시작 외부에서 토폴로지 조정을 유지합니다. 현재 저장소는 이미 대기열, 교환, 바인딩 및 정책을 토폴로지 운영자 CR로 이동합니다.
  • 중복된 선언 경로를 피하세요. 인프라가 lumie.dlx를 소유한 경우 앱 코드는 이를 다른 유형으로 조용히 재정의해서는 안 됩니다.
  • 외부 대상 컨트롤러의 Ready=True를 "앱 지향 브로커가 정확합니다."가 아니라 "API 호출 성공"으로 처리합니다.

확인

cd Lumie
rg -n "load_definitions|rabbitmq-definitions|auth_backends\\.1 = internal" \
lumie-infra/platform/rabbitmq/base/rabbitmq-cluster.yaml \
lumie-infra/platform/rabbitmq/overlays/dev/kustomization.yaml \
lumie-infra/platform/rabbitmq/overlays/prod/kustomization.yaml
rg -n "kind: (Queue|Exchange|Binding|Policy)|keepAfterDeletion|rabbitmqClusterReference" \
lumie-infra/platform/rabbitmq/base/topology \
lumie-infra/platform/rabbitmq/overlays/dev \
lumie-infra/platform/rabbitmq/overlays/prod

성공은 저장소가 여전히 깔끔한 브로커 대 토폴로지 소유권 분할을 표시하고, 두 오버레이 모두 이전 정의 부트스트랩을 제거하고, 토폴로지 개체가 앱 시작 부작용이 아닌 선언적 CR로 남아 있음을 의미합니다.

원본 사고 세부사항

2026년 1월 30일 원본 기록은 여러 작은 실패 이후 Kubernetes 위 RabbitMQ 운영 모델을 정리했습니다. 중요한 구분은 broker ownership과 topology ownership입니다.

세부사항
Broker ownerRabbitMQ Cluster Operator
Topology ownerRabbitMQ Topology Operator CR
Deprecated bootstrapapp topology와 credential을 위한 load_definitions
주요 운영 위험controller readiness를 app-facing broker state의 정확성으로 착각하는 것
지속 모델broker lifecycle과 app topology가 별도 Kubernetes resource를 통해 수렴합니다

원본 기록은 다음 troubleshooting check를 보존합니다.

확인이유
cluster CR statusbroker API object가 reconcile됐는지 증명합니다
pod readiness와 logbroker pod가 실제로 실행 중인지 증명합니다
topology CR statusqueue/exchange/binding/policy API call이 성공했는지 증명합니다
live broker inspectionapp이 기대하는 object가 실제 broker에 있는지 증명합니다
application envapp이 generated credential과 올바른 vhost/host를 쓰는지 증명합니다

이 계층들을 합치지 마세요. Ready=True topology object는 operator의 API call이 성공했다는 뜻입니다. Publisher와 consumer가 기대한 credential, vhost, queue name을 사용한다는 뜻은 아닙니다.