본문 바로가기
IT/HomeLabs

[홈랩 IaC 자동화 #1] Ansible AWX 설치 - K3s + AWX Operator로 Playbook GUI 환경 구축

by 수누다 2026. 3. 23.

환경 정보

항목 버전 / 내용
OS Rocky Linux 9
K3s v1.32.x+k3s1
AWX Operator 2.19.1
AWX 24.6.1
RAM 8GB (최소 6GB 권장)
CPU 4 vCPU
디스크 40GB

왜 AWX를 올리게 됐나

Proxmox 홈랩에 VM이 점점 늘어나면서 매번 SSH로 접속해서 같은 명령어를 반복하는 게 귀찮아졌다. Ansible은 이미 쓰고 있었는데, 터미널에서 ansible-playbook 명령어 치는 것보다 웹 GUI에서 관리하면 훨씬 편할 것 같아서 AWX를 도입하기로 했다.

AWX는 Red Hat Ansible Automation Platform의 오픈소스 업스트림 프로젝트다. 쉽게 말하면 Ansible의 웹 GUI 버전이다.

참고: 2024년 7월 이후 AWX는 Docker Compose 방식을 버리고 Kubernetes(K3s) + AWX Operator 방식으로 완전히 전환됐다. 예전 Docker Compose 가이드를 따라 하면 설치가 안 된다.


전체 흐름

Rocky Linux 9
    ↓ 설치
K3s (경량 Kubernetes)    ← AWX가 돌아가는 바닥
    ↓ 배포
AWX Operator             ← AWX 설치 관리자
    ↓ 생성
AWX                      ← 실제로 쓸 Ansible GUI

K3s를 몰라도 괜찮다. "AWX가 동작하는 컨테이너 환경"이라고만 생각하면 된다.


STEP 1. 사전 준비

# 시스템 업데이트
dnf update -y

# 기본 도구 설치
dnf install -y git curl wget vim

SELinux Permissive 설정

K3s가 SELinux Enforcing 상태에서 네트워크 문제가 생긴다.

# 즉시 적용
setenforce 0

# 재부팅 후에도 유지
sed -i 's/^SELINUX=.*/SELINUX=permissive/' /etc/selinux/config

# 확인
getenforce
# 출력: Permissive

방화벽 포트 개방

firewall-cmd --permanent --add-port=6443/tcp
firewall-cmd --permanent --add-port=80/tcp
firewall-cmd --permanent --add-port=443/tcp
firewall-cmd --permanent --add-port=8472/udp
firewall-cmd --permanent --add-port=10250/tcp
firewall-cmd --permanent --add-port=30000-32767/tcp

# K3s 내부 네트워크 대역 신뢰
firewall-cmd --permanent --zone=trusted --add-source=10.42.0.0/16
firewall-cmd --permanent --zone=trusted --add-source=10.43.0.0/16

firewall-cmd --reload

STEP 2. K3s 설치

curl -sfL https://get.k3s.io | bash -

설치 후 서비스 상태 확인:

systemctl status k3s

노드 상태 확인:

k3s kubectl get nodes
NAME      STATUS   ROLES                  AGE   VERSION
awx-lab   Ready    control-plane,master   1m    v1.32.x+k3s1

Ready 상태가 나오면 성공이다. NotReady면 1분 정도 더 기다렸다가 다시 확인한다.


STEP 3. kubectl 설정

기본적으로 k3s kubectl로 써야 하는데, 심볼릭 링크를 만들면 그냥 kubectl로 쓸 수 있다.

# kubectl 심볼릭 링크
ln -sf /usr/local/bin/k3s /usr/local/bin/kubectl

# kubeconfig 설정
mkdir -p ~/.kube
cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
export KUBECONFIG=~/.kube/config
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc

# 확인
kubectl get nodes

STEP 4. AWX Operator 배포

최신 버전 확인

AWX_OPERATOR_VERSION=$(curl -s https://api.github.com/repos/ansible/awx-operator/releases/latest \
  | grep tag_name | cut -d '"' -f 4)

echo "AWX Operator 버전: $AWX_OPERATOR_VERSION"
# 출력: AWX Operator 버전: 2.19.1

작업 디렉토리 생성

mkdir -p ~/awx-deploy
cd ~/awx-deploy

kustomization.yaml 작성

cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - github.com/ansible/awx-operator/config/default?ref=${AWX_OPERATOR_VERSION}
images:
  - name: quay.io/ansible/awx-operator
    newTag: ${AWX_OPERATOR_VERSION}
  - name: gcr.io/kubebuilder/kube-rbac-proxy
    newName: quay.io/brancz/kube-rbac-proxy
    newTag: v0.18.1
namespace: awx
EOF

⚠️ kube-rbac-proxy 이미지 주의: gcr.io/kubebuilder/kube-rbac-proxy 이미지가 gcr.io에서 삭제됐다. 반드시 quay.io/brancz/kube-rbac-proxy로 교체해야 한다. 이 설정 없이 배포하면 ErrImagePull 오류가 발생한다.

Namespace 생성 및 Operator 배포

kubectl create namespace awx
kubectl apply -k .

Operator Pod 상태 확인

watch kubectl get pods -n awx
NAME                                               READY   STATUS    AGE
awx-operator-controller-manager-xxxxxxxxx-xxxxx   2/2     Running   2m

2/2 Running이 되면 Ctrl+C로 종료한다.


STEP 5. AWX 인스턴스 배포

awx-instance.yaml 작성

cat <<EOF > awx-instance.yaml
---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
  namespace: awx
spec:
  service_type: nodeport
  nodeport_port: 30080
  projects_persistence: true
  projects_storage_access_mode: ReadWriteOnce
EOF

kustomization.yaml에 인스턴스 추가

cat <<EOF > kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  - github.com/ansible/awx-operator/config/default?ref=${AWX_OPERATOR_VERSION}
  - awx-instance.yaml
images:
  - name: quay.io/ansible/awx-operator
    newTag: ${AWX_OPERATOR_VERSION}
  - name: gcr.io/kubebuilder/kube-rbac-proxy
    newName: quay.io/brancz/kube-rbac-proxy
    newTag: v0.18.1
namespace: awx
EOF

배포 실행

kubectl apply -k .

완료 대기 (10~20분)

watch kubectl get pods -n awx

전부 Running 상태가 될 때까지 기다린다.

NAME                                               READY   STATUS      AGE
awx-migration-24.6.1-xxxxx                        0/1     Completed   7m
awx-operator-controller-manager-xxxxxxxxx-xxxxx   2/2     Running     10m
awx-postgres-15-0                                 1/1     Running     8m
awx-task-xxxxxxxxx-xxxxx                          4/4     Running     7m
awx-web-xxxxxxxxx-xxxxx                           3/3     Running     7m

awx-migrationCompleted가 정상이다.


STEP 6. 접속 및 로그인

admin 비밀번호 확인

kubectl -n awx get secret awx-admin-password \
  -o jsonpath="{.data.password}" | base64 --decode; echo

웹 UI 접속

http://서버IP:30080
항목
Username admin
Password 위에서 확인한 값


트러블슈팅

ErrImagePull - gcr.io/kubebuilder/kube-rbac-proxy

오류 메시지:

Failed to pull image "gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0":
failed to resolve reference "gcr.io/kubebuilder/kube-rbac-proxy:v0.15.0": not found

원인: gcr.io/kubebuilder/kube-rbac-proxy 이미지가 gcr.io에서 삭제됨

해결: kustomization.yaml에 이미지 경로를 quay.io/brancz/kube-rbac-proxy:v0.18.1로 교체

images:
  - name: gcr.io/kubebuilder/kube-rbac-proxy
    newName: quay.io/brancz/kube-rbac-proxy
    newTag: v0.18.1

기존 배포를 삭제하고 재배포한다:

kubectl delete -k .
sleep 5
kubectl apply -k .

마무리

설치 자체는 어렵지 않다. K3s가 Kubernetes를 엄청 단순하게 만들어줘서, Kubernetes를 전혀 몰라도 따라할 수 있다.

삽질 포인트는 딱 하나였는데, kube-rbac-proxy 이미지가 gcr.io에서 없어진 것이다. 공식 문서에는 아직 반영이 안 된 부분이라 이걸 모르면 한참 헤맬 수 있다.

다음 편에서는 실제로 Playbook을 만들어서 홈랩 서버들에 자동으로 설정을 배포해볼 예정이다.

다음 편 예고: [홈랩 IaC 자동화 #2] Ansible Playbook으로 Proxmox VM 일괄 설정 자동화


참고 링크


👉 #2화 — Ansible AWX로 Ubuntu 서버 6대 Playbook 실행하기
👉 #3화 — AWX 스케줄러 + 텔레그램 알림 - 매일 자동 패키지 업데이트
👉 #4화 — Terraform으로 Proxmox VM 자동 생성하기