zaki work log

作業ログやら生活ログやらなんやら

[Ansible / K3s] 2023年版AWXクイックインストールガイド

本エントリは、Ansible Advent Calendar 2023の6日目の記事になります。

AWXのセットアップがDocker ComposeからKubernetes環境になって手を出しづらくなったとか、インストール方法がわかりづらいなどの声を観測範囲で聞くことがあったので、ローカル環境で簡単に始められる手順についてまとめた。

大まかな手順の流れは以下の通り。

  1. Kubernetesの準備
  2. AWX Operatorのデプロイ
  3. AWXのデプロイ

(追記) ちなみに2と3は手順としては1回にまとめられる(後述)
本編は解説用に分けてデプロイしている。


Kubernetesの準備

クラウドサービスのマネージドK8sを使う人は飛ばしてください。
ローカルのLinuxKubernetesをシュッとたてる場合、個人的には主に以下が候補。

また、Dockerの上にKubernetesをセットアップするかどうかも選択基準の要素になりうる…というか実は上記はすべてDocker上にも構築できる。
(kindはKubernetes in Docker専用、K3sとMinikubeはDocker上にも、VMに直接インストールもできる)

本エントリでは基本的にK3sについて解説。

K3sを使ったKubernetesのセットアップ

VMに直接入れるか、Docker上で動作させるか、どちらか選択。
まっさらな状態からk3s専用機にするならVMに直接、すでにDockerもkubectlもインストール済み・もしくはコンテナでいろいろするホストならDocker版が個人的にはお勧め。

VMに直接インストールする場合

以下を実行する。
デフォルトだとrootユーザーしか設定ファイルの参照権限が無いため毎回sudoが必要なため、簡略化のためオプションを追加してる。

curl -sfL https://get.k3s.io | sh -s - --write-kubeconfig-mode 644

これでしばらく待てば、kubectl get nodekubectl get pod -Aでシングルノード構成でPodが動作するのを確認できる。

zaki-hmkc.hatenablog.com

OS標準のファイアウォールが有効だったりする場合は事前設定があるのでドキュメントを参照。
また、RHEL系の場合はnm-cloud-setupサービスの停止も必要。

docs.k3s.io

Docker上にインストールする場合

Composeファイルが提供されてるので、これを使って起動する。

github.com

curl -LO https://raw.githubusercontent.com/k3s-io/k3s/master/docker-compose.yml
export K3S_TOKEN=${RANDOM}${RANDOM}${RANDOM}
docker compose up -d

ただし、IngressでなくLoadBalancer Serviceを使用する場合は、AWXアクセス用のポートフォワードの設定を追加しておく。設定がないと、コンテナで動作するAWXに外部からアクセスできないので。
例として8080/TCPを設定するのであれば以下の通り。
(外部からのアクセスを8080で受け、AWXのService自体も8080でlistenする場合)

--- docker-compose.yml.org      2023-12-05 00:27:20.833535982 +0000
+++ docker-compose.yml  2023-12-05 00:26:11.208743879 +0000
@@ -29,6 +29,7 @@
     - 6443:6443  # Kubernetes API Server
     - 80:80      # Ingress controller port 80
     - 443:443    # Ingress controller port 443
+    - 8080:8080  # AWX service lb
 
   agent:
     image: "rancher/k3s:${K3S_VERSION:-latest}"

また、kubectlコマンドは付属しないので別途インストールする。
以下はバイナリを直接取ってくる場合。

sudo curl -L "https://dl.k8s.io/release/$(curl -LS https://dl.k8s.io/release/stable.txt)/
bin/linux/amd64/kubectl" -o /usr/local/bin/kubectl
sudo chmod 755 /usr/local/bin/kubectl

ディストリビューションのパッケージ管理を使ったインストールも可能なのでドキュメント参照

kubectlが実行可能になったら、Docker Composeで作成したクラスタ情報が作業ディレクトリに生成されているため、環境変数でパス指定すればクラスタkubectlでアクセスできるようになる。

export KUBECONFIG=$PWD/kubeconfig.yaml
kubectl get node

コンテナ版K3sについては以下も参照。

zaki-hmkc.hatenablog.com

ちなみにデフォルトで80/TCP、443/TCP、6443/TCPをlistenするので同じポートを使うサービスを動かしてる場合は落としておく。(K3s側のポート変えてもよいけど)

kind / Minikubeの場合

どちらもCLIツールをインストールし、CLIツール経由で「クラスタ作成コマンド」などを実行してクラスタ作成を行う。
kindならkind create clusterとか、Minikubeならminikube startなど。
ただしどちらのコマンドもDocker上に構築するので、事前にDockerのインストールが必要。
また、Minikubeはドライバ指定を行うことで、実行環境をDockerでなくKVMなどさまざまな環境で動作させることもできる--driver noneを指定すればVMにセットアップされる。

AWXのデプロイ

インストールに関するドキュメントは以下。

ansible.readthedocs.io

また、Service(サービス公開)に関してはNetwork and tls configurationも参照。

ansible.readthedocs.io

AWX Operatorのデプロイ

2023年12月時点でmake deployの記載があるためわかりづらいけどその部分は無視して、もう一つのデプロイ方法のkustomization.yamlファイルを作成してkubectlコマンドでKustomizeインストールするのが簡単。

Kustomizeについては下記も参照。 zaki-hmkc.hatenablog.com

AWX Operatorバージョン2.8.0をデプロイするなら以下の記述。
使えるtagについては、GitHubのリリースページで確認する。

kustomization.yamlのファイル名で保存する。(ファイル名固定)

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  # Find the latest tag here: https://github.com/ansible/awx-operator/releases
  - github.com/ansible/awx-operator/config/default?ref=2.8.0

# Set the image tags to match the git version from above
images:
  - name: quay.io/ansible/awx-operator
    newTag: 2.8.0

# Specify a custom namespace in which to install AWX
namespace: awx

ファイルを作成したら、kustomization.yamlファイルのあるディレクトリで以下を実行

kubectl apply -k .

これで、awxネームスペースへのAWX Operatorのデプロイと、AWXをデプロイするためのカスタムリソース定義(Custom Resource Definitions)が作成される。

AWX本体のデプロイ

AWX OperatorとAWXカスタムリソース定義がある状態(前段の手順で完了済み)で、AWXカスタムリソースを作成すると、AWX Operatorがそれを見つけてAWXのPodをデプロイしてくれる。

LoadBalancer Serviceでサービス公開する場合

作成するAWXカスタムリソースの例は以下の通り。
ファイル名はなんでもよい。

---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx-sample
spec:
  service_type: LoadBalancer
  loadbalancer_port: 8080

これをデプロイ済みAWX Operatorと同じネームスペース(前述の例ならawx)へデプロイする。
kubectl apply -f awx-manifest.yaml -n awx
ドキュメントにはkustomization.yamlresources以下のリストへファイルを追加し再度Kustomizeを実行する手順になっているが、やってることは同じなのでどちらでも良い。(再々実行と何度もトライアルアンドエラーしたり追加のマニフェストファイルがあったりするのであればKustomizeの方が楽かもしれない)

awx-sampleの部分は名称なので任意。
ポイントはservice_typeLoadBalancerを指定することで、LoadBalancerタイプのServiceリソースを作成するように要求する。
また、その際のlistenするポート番号を8080にしている。

K3sの場合は、デフォルトでLoadBalancerタイプのServiceがサポートされるので、おそらくこの構成が外部アクセスを実現するのには一番簡単。
ただし、標準でIngressコントローラであるTraefikもインストールされ、これがデフォルトで80/TCPと443/TCPを使っており、K3s標準のLoadBalancer ServiceはKlipper LoadBalancerによるノード上に指定ポートをlistenするPodをデプロイする方式のため、ポート番号に80を使うと競合するため8080を指定している。(番号は任意なので25080など好きなポート番号を使えばよい)

デプロイが成功したら(kubectl get pod -n awxでPodのstatusがRunningでreadyのn/mが一致してれば)、ホストOSのIPアドレス(正しくはkubectl get svc -n awxで確認できるAWXのServiceのExternal IP)にwebブラウザでアクセスする。(ポート番号は上記例であれば8080を指定)

kindやMinikubeを使う場合は標準ではLoadBalancerタイプのServiceはサポートされないため、別途MetalLBなどをデプロイして利用する。

kindでMetalLBを使う例は以下も参照

zaki-hmkc.hatenablog.com

クラウドサービスのマネージドK8sであれば、クラウドロードバランサーサービスと連携したサポートが大抵はあるはず。その場合は前述のK3sのポート番号のような競合は起きないので、80など使いたいものを設定できるはず。

ちなみにAWXリソースのパラメタにはloadbalancer_protocolがありhttpsを指定する設定サンプルがドキュメントに載っているが、K3s(に付属のKlipper LB)のLoadBalancer ServiceにSSL終端の機能はないため効果はない。

Ingressでサービス公開する場合

Ingressの場合のAWXカスタムリソースは以下の通り。

---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx-sample
spec:
  service_type: clusterip
  ingress_type: ingress
  hostname: awx.example.org

L7ロードバランサであるIngressは、アクセスのためのFQDNhostnameに指定する。この例ではlocal.example.orgでブラウザでリクエストすればAWXにアクセスできる。名前解決に必要なDNS設定は別途行う(設定できるDNSがなければ、hostsでもOK)

K3sはIngressも標準でサポートしており、リソース生成から若干タイムラグがあるがしばらく待てば外部からアクセスできるようになる。
curlで確認するには以下の通り。

curl --resolve awx.example.org:80:127.0.0.1 awx.example.org

adminユーザーのパスワード確認

デフォルトではAWXのadminパスワードはランダムで設定され、その内容はSecretリソースに出力される。
確認するにはkubectl getで参照する。

ネームスペースがawxでAWXリソース名がawx-sampleあれば以下の通り。(echoは無くてもよい。コピペのしやすさ用)

kubectl get -n awx secret awx-sample-admin-password -o jsonpath='{.data.password}' | base64 -d; echo

初期値を設定してAWXデプロイを行うことも可能。KustomizeのsecretGeneratorで比較的簡単に設定できる。
以下参照。

zaki-hmkc.hatenablog.com

AWXの削除

kubectl deleteで削除する。

kubectl apply -f <マニフェストファイル>でデプロイしたAWX本体は、kubectl delete -k <マニフェストファイル>でAWXリソースが削除され、Operatorによって作成されたAWXのPod類も削除される。
kubectl apply -k <kustomization.yamlのあるディレクトリ>でデプロイしたAWX Operatorは、kubectl delete -k <kustomization.yamlのあるディレクトリ>で削除される。
-nでネームスペースの指定もお忘れなく。(ここまでの例なら-n awx)

なお、AWXを削除してもストレージはpvに残るため、再度インストールすれば前のデータのまま再構築できる。 AWX Operatorを削除するとネームスペースが消えるため、(pvcが消えるため)pvも消える。

クリーンインストールしたいときなどでAWX Operatorを残したままpvを削除したい場合は、pvcを削除すればOK

AWX OperatorとAWX本体をまとめてデプロイする場合

ドキュメントには「Kustomizeを使ってOperatorをデプロイし、次にAWXリソースのマニフェストkustomization.yamlに追記してKustomizeをさらに実行」という手順になっているが、初めから「AWXリソースのマニフェストkustomization.yamlに記載してKustomizeを1回だけ実行」でもOK

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  # Find the latest tag here: https://github.com/ansible/awx-operator/releases
  - github.com/ansible/awx-operator/config/default?ref=2.8.0
  - awx-sample.yaml  # <- これ

# Set the image tags to match the git version from above
images:
  - name: quay.io/ansible/awx-operator
    newTag: 2.8.0

# Specify a custom namespace in which to install AWX
namespace: awx

このkustomization.yamlを使ってkubectl apply -k .でもCRDの作成・Operatorのデプロイ・AWXリソースの作成が行われて、AWXのPodが作成される。
もしAWXリソースの作成に対してCRD未定義エラーが発生する場合は、再実行すればよい。