Ansible Tower/AWXのアーキテクチャとジョブ実行の仕組み(1)

Ansible Tower/AWXのアーキテクチャとジョブ実行の仕組みについてのメモ。

# Ansible Tower/AWXのサービス
Ansible Tower/AWXは、以下のようなOSSプロダクトを利用して実装されています。
Tower v3.1/v3.2の場合は、Towerサーバ上でsystemd/supervisordを利用して直接起動します。

| OSS | 役割 |
|:----|:----|
| Ansible | Tower/AWXが実行するジョブのエンジン部分を担う |
| Docker | AWXの各サービスをコンテナとして起動する (AWXのみ) |
| Django | WebUI / RESTful APIを提供するためのフレームワーク |
| Nginx  | WebUI / RESTful APIを提供するためのフロントエンドサービス |
| PostgreSQL | 設定情報や、インベントリ、ジョブの実行結果を格納するデータベース |
| RabbitMQ | ジョブスケジューラが利用するメッセージキューを管理する |
| Celery | RabbitMQと連携するAMQPワーカー |
| Memcached | Live EventやLogging Aggregator用の一時データストア |
| Supervisord | Celery / uwsgiなどのサービスをデーモンとして起動する |

## Towerのアーキテクチャ

Towerの各サービスは、Towerサーバ上でsystemd/supervisord経由で起動されます。
構成管理データベースであるPostgreSQLは、Towerサーバと同居させることも可能ですが、独立させて別サーバ上で起動させることが推奨されています。

![tower.png](https://qiita-image-store.s3.amazonaws.com/0/53686/2005dde6-de3e-6096-2f91-1fe8ee60ddf8.png)

マルチノード構成クラスタ構成を作る場合は、インストレーションプログラムを利用して、Towerサーバ追加することができますが、このインストレーションプログラムでは、PostgreSQLの冗長化を構成することができないため、データベースサーバについては、利用者が独自に冗長化する必要があります。これはコンテナ化されているAWXでも同様です。

## AWXアーキテクチャ

AWXは、前述のOSSをいくつかのサービスの役割毎にまとめて、５つのコンテナをDockerを利用して起動します。

![container.png](https://qiita-image-store.s3.amazonaws.com/0/53686/baaf5c9c-dd35-4c49-fb93-3eff4927b90d.png)

AWXのインストールが完了すると、上の図のように５つのコンテナが起動します。

```
# docker ps
CONTAINER ID        IMAGE                        COMMAND                  CREATED             STATUS              PORTS                                                 NAMES
a7c157abac35        ansible/awx_task:latest      "/tini -- /bin/sh ..."   2 weeks ago         Up 25 minutes       8052/tcp                                              awx_task
ceb292cd5646        ansible/awx_web:latest       "/tini -- /bin/sh ..."   2 weeks ago         Up 25 minutes       0.0.0.0:80->8052/tcp                                  awx_web
b0c0cf8ab563        memcached:alpine             "docker-entrypoint..."   2 weeks ago         Up 25 minutes       11211/tcp                                             memcached
b4d90cd52d1e        ansible/awx_rabbitmq:3.7.4   "docker-entrypoint..."   2 weeks ago         Up 25 minutes       4369/tcp, 5671-5672/tcp, 15671-15672/tcp, 25672/tcp   rabbitmq
3f260f589083        postgres:9.6                 "docker-entrypoint..."   2 weeks ago         Up 25 minutes       5432/tcp                                              postgres
```

アーキテクチャは以下の通りで、基本的にはTowerと同様ですが、各サービスがコンテナ化されている点が異なります。OpenShiftのようなコンテナオーケストレーションを利用している場合は、赤い実線で囲まれているのがPodで、AWXサービス用とデータベース用に各１つのPodが作成されます。

![awx.png](https://qiita-image-store.s3.amazonaws.com/0/53686/9e2fda71-d8e2-574a-3cf3-2265112bc095.png)


図中の赤い破線部分のAWXサービスのPodをスケールアップさせることで、Towerのマルチノードクラスタと同様にジョブを実行するためのインスタンスを追加することができます。
しかし、現状はスケールダウンには完全には対応していないため、スケールダウン時は、awx-manageコマンドで削除されたインスタンスを手動でAWXの構成管理データベースから削除する必要があります。

## AWXコンテナの役割

- __awx-webコンテナ__
  - 利用者へのフロントエンドサービス(Web Dashboard / RESTful API)を提供
  - Supervisordを利用してNginxとuwsgiを利用したフロントエンドサービスを起動
- __awx-memcachedコンテナ__
  - AWXの他のコンポーネント向けにMemcachedサービスを提供
  - ジョブの結果をLive EventでWebクライアントに提供したり、外部ロギングシステムに実行結果を転送するために一時利用される
- __awx-rabbitコンテナ__
  - フロントエンドから送られたAMQPメッセージをハンドリングするAMQPサービスを提供
  - ジョブの起動やイベントの処理、バックグラウンドプロセス、WebSocketの処理に利用
  - K8SやOpenShiftでawxサービスのpodを増やすと自動でRabbitMQクラスタに追加される
- __awx-taskコンテナ__
  - AWXの中枢として、awx-rabbitからメッセージを取得して、プロジェクトの管理やジョブの実行を担うサービス群をSupervisordを利用して起動
  - 自動化のエンジンとなるAnsible(ansible-playbookコマンド)は、このコンテナで実行される
  - Ansibleの実行環境は、Pythonのvirtualenv上に配置(venv/ansible, venv/awx) されている
  - Github / Gitlab などのSCMからチェックアウトしたPlaybookが配置される
- __postgresqlコンテナ__
  - AWXの設定情報を保存する構成管理データベース
  - ジョブテンプレートの設定、インベントリ情報や全てのジョブの実行情報(Playbookの出力など)、Tower/AWXが保持するほぼ全ての情報が保存されている

__つづく...__