Fullmoon System

AWX가 떠도 작업이 시작되지 않을 때: 이미지·설정 형식·Dispatcher 점검

AI_Manager

AWX 설치 과정에서는 Pod가 실행 중이라는 표시만으로 준비 상태를 판단할 수 없었다. Operator 보조 이미지 다운로드, 사용자 정의 리소스의 자료형, 작업을 배정하는 Dispatcher 설정에서 서로 다른 문제가 발생했다. 화면이 열리는지와 실제 작업을 시작할 수 있는지를 나누어 확인해 해결했다.

사용 기술·서비스: AWX 24.6.1 · AWX Operator 2.19.1 · K3s · Kubernetes CRD · containerd

이 글의 순서

  1. 1. ImagePullBackOff: 내려받지 못한 이미지를 먼저 찾는다
  2. 2. YAML 문법이 맞아도 CRD 자료형이 다르면 거부된다
  3. 3. No task instances are READY: Web과 작업 배정 상태를 나누어 본다
  4. 4. 수정 후에는 작업 실행까지 확인한다

1. ImagePullBackOff: 내려받지 못한 이미지를 먼저 찾는다

초기 Operator Pod는 ImagePullBackOff 상태였고, 이벤트에는 gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0 이미지를 찾지 못했다는 오류가 남았다. AWX 본체 이미지의 문제가 아니라 Operator에 포함된 보조 컨테이너의 문제였다.

sudo /usr/local/bin/k3s kubectl -n awx get pods
sudo /usr/local/bin/k3s kubectl -n awx get events \
  --field-selector type=Warning

실습에서는 보조 이미지 주소를 같은 버전의 quay.io/brancz/kube-rbac-proxy:v0.15.0으로 수정했다. 화면에서 Pod를 반복 삭제하는 것으로 끝내지 않고, 재설치할 때도 적용되도록 배포 원본의 이미지 정의에 반영했다. 이후 Operator 컨테이너가 정상 실행되는지 확인했다.

온라인망에서는 공식 이미지 위치와 버전·digest를 확인해 준비한다. 폐쇄망에서는 AWX Web뿐 아니라 Operator, RBAC proxy, init, migration, 실행환경 이미지도 반입해야 한다. Docker 저장소에만 이미지를 넣고 K3s에서 바로 사용할 수 있다고 가정하면 안 된다.

2. YAML 문법이 맞아도 CRD 자료형이 다르면 거부된다

AWX 리소스를 적용할 때에는 다음과 같은 오류도 발생했다. 문법상 유효한 YAML이더라도 Kubernetes에 등록된 CRD가 요구하는 자료형과 다르면 저장할 수 없다.

spec.host_aliases: must be of type array
spec.csrf_cookie_secure: must be of type string
spec.session_cookie_secure: must be of type string

이 실습의 Operator 2.19.1에서는 host_aliases를 배열로, 두 cookie 옵션을 문자열로 전달했다. 다음은 수정한 spec의 일부다. 전체 AWX 정의를 대체하는 파일은 아니다.

spec:
  csrf_cookie_secure: 'True'
  session_cookie_secure: 'True'
  host_aliases:
    - ip: "10.77.10.10"
      hostnames:
        - netbox.fullmoon.test
        - zabbix.fullmoon.test

설치된 클러스터에서는 kubectl explain awx.spec.host_aliases로 필드를 확인할 수 있다. 적용 전에는 kubectl apply --dry-run=server -f awx.yml로 서버 측 검사를 한다. 버전별 자료형은 Operator 2.19.1의 CRD 원본을 기준으로 확인했다.

3. No task instances are READY: Web과 작업 배정 상태를 나누어 본다

Web Pod가 실행된 뒤에도 Project 생성 요청이 500을 반환했다. API 로그에는 No task instances are READY and Enabled.가 남았다. 작업을 배정할 수 있는 인스턴스가 준비되지 않았다는 뜻이므로 Web 화면만 다시 확인하지 않고 Task 컨테이너 로그를 읽었다.

Dispatcher 로그의 핵심 오류는 다음과 같았다.

AttributeError: 'int' object has no attribute 'isdigit'
dispatcher entered FATAL state

실제 호출 경로에서 SYSTEM_TASK_ABS_MEM 값을 문자열로 해석하는 코드가 숫자를 받는 것을 확인했다. 실습용으로 추가했던 불필요한 수동 설정을 제거하고 Operator가 관리하는 설정으로 되돌렸다. 이 오류를 모든 AWX 설치에서 발생하는 제품 결함으로 일반화하지 않았다.

로그를 조회할 때에는 Pod 이름뿐 아니라 컨테이너 이름도 실제 목록에서 확인한다. 이 실습에서는 awx-task라는 짧은 이름을 추측해 조회하면 해당 컨테이너가 없다는 오류가 났고, 실제 이름은 fullmoon-awx-task였다.

# 먼저 현재 Pod 이름과 컨테이너 목록을 확인한다.
sudo /usr/local/bin/k3s kubectl -n awx get pods
sudo /usr/local/bin/k3s kubectl -n awx get pod <현재_Task_Pod> \
  -o jsonpath='{.spec.containers[*].name}'
sudo /usr/local/bin/k3s kubectl -n awx logs <현재_Task_Pod> \
  -c fullmoon-awx-task --tail=100

4. 수정 후에는 작업 실행까지 확인한다

Operator와 Task Pod가 정상화된 뒤 AWX 인스턴스의 버전·작업 처리 가능 상태를 확인했다. Git 접속 설정을 추가로 수정한 후 Project 동기화가 성공했고, 자산 등록 → 인벤토리 갱신 → 모니터링 확인 Workflow까지 성공했다.

확인 항목 확인 결과
보조 이미지 다운로드 수정한 주소로 실행
AWX 리소스 자료형 검사 적용 성공
Dispatcher 실행 수동 메모리 설정 제거 후 정상화
실제 Project 동기화 성공
후속 온보딩 Workflow 성공

설치 완료 기준은 Pod의 Running 한 줄이 아니라 실제 작업 성공이다. 또한 이 AWX는 중앙 1호기 안의 단일 K3s 구성이다. API 응답에 나타나는 ha 필드나 여러 Pod의 존재를 물리 서버 장애를 견디는 AWX 이중화로 해석하지 않는다.