- はじめに
- ■ 1. Automation mesh におけるノードの種類
- ■ 2. 今回の環境 (コントロールノードと実行ノードの分類)
- ■ 3. 下準備
- ■ 4. インストール
- ■ 5. 状態確認
- ■ 6. 動作確認1: Demo Job Template
- ■ 7. 動作確認2: 家の中のマネージドノードを操作するジョブテンプレート
- まとめ・雑感
はじめに
Red Hat Ansible Automation Platform(以下AAP) 2.1 では、スケーラビリティと信頼性を向上させる Automation mesh という機能が導入されました。
AAP1.2 (Ansible Tower としては3.8) までにあった Isolated Node 相当の機能を備えつつ、さらに機能強化されたようなかたちでしょうか。
この記事では、簡単な構成で試したことをまとめます。はじめて調べて試したレベルですので、なにか間違い等あれば @akira6592 までご連絡いただけると助かります。
なお、レッドハットさんの以下のウェビナーを聞いて概要をつかめたので、やってみようと思いました。めちゃくちゃ参考になりました、ありがとうございます!
最新 Ansible Automation Platform 2.1 (AAP 2.1 ) の概要紹介、最新アップデート、実機デモ
珍しく長い記事です。
■ 1. Automation mesh におけるノードの種類
Automation mesh の構成では、それぞれのノードに役割があります。
ノードの役割 | 説明 |
---|---|
コントロールノード(Control node) | 司令塔。Automation Controller の Web UI や API の提供し、実行ノード(後述)にジョブの実行を指示する。プロジェクトの更新のようなコントロールプレーンの処理はこのノード内で行われる |
実行ノード(Execution node) | 実際にジョブを実行するノード。コントロールノードからの指示を受ける |
ホップノード(Hop node) | コントロールノードと実行ノードの間を取り持つノード |
ハイブリッドノード(Hybrid node) | コントロールノードと実行ノードの役割を兼ね備えたノード。AAP 2.1 のインストーラーでは、デフォルトで localhost がハイブリッドノードになる |
各ノードは必ず分離しといけないというわけではなく、環境の状況に応じて使い分けます。
たとえば、シンプルにハイブリッドノードだけで事が足りることもあるでしょうし、コントロールノード、と実行ノードを分けたほうがいいこともあるでしょう。はたまた、ホップノードを挟んで延伸したほうがいいここともあるでしょう。
■ 2. 今回の環境 (コントロールノードと実行ノードの分類)
この記事ではコントロールノードと実行ノードそれぞれ1台ずつの構成をとります。ホップノードは挟みません。
mesh と呼べるほどではないですが、これまでハイブリッドノード構成から役割を分離する構成として、最低限の一番シンプルな構成で試してみよう、というのが趣旨です。
登場人物やそれぞれのノードと役割は以下のとおりです。
各動作の説明です。
No. | 動作 | 説明 |
---|---|---|
(1) | ブラウザからジョブテンプレート実行指示 | Automation Controller の利用者が Web UI や API を利用して、ジョブテンプレートの実行を指示する |
(2) | ジョブテンプレート実行開始 | 利用者からの指示によってジョブテンプレートの実行を開始 |
(3) | プロジェクト更新用EEイメージpull | プロジェクト更新に利用する EE(Execution Environment) のイメージを(手元になければ)pullする。利用するイメージは Automation Controller の画面の [実行環境] > [Control Plane Execution Environment] で定義されている registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest |
(4) | プロジェクト更新用EE起動 | プロジェクト更新用EEを起動する |
(5) | プロジェクト更新 | プロジェクトの SCM タイプが git の場合は、リポジトリからプロジェクトを更新する |
(6) | コレクションダウンロード | プロジェクト内の collections/requirements.yml に利用するコレクションが定義されている場合にコレクションをダウンロードする。デフォルトでは Ansible Galaxy から(今回の構成も) |
(7) | ジョブ実行指示 | コントロールノードから実行ノードに対してジョブの実行を指示する。デフォルトでは TCP 27199 ポートを利用する |
a. | ダイナミックインベントリ更新用EEイメージpull | ダイナミックインベントリ(インベントリ内の「ソース」)があり「起動時の更新」が有効の場合はイメージをpull。デフォルトでは Control Plane Execution Environment に定義の registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest を利用?(Default Execution Environment と同じイメージなので区別が付かない・・ ) |
b. | ダイナミックインベントリ更新用EE起動・更新 | a. の続きでダイナミックインベントリを更新。(7) と a. b. の順序関係が分からずこのあたりは数字表記ではない・・ |
(8) | ジョブ実行用EEイメージpull | ジョブ実行に利用する EE のイメージを(手元になければ)pullする。利用するイメージは Automation Controller の画面の [実行環境] > [Default Execution Environment] で定義されている registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest 。結果的にデフォルトでは Control Plane Execution Environment と同じイメージ |
(9) | ジョブ実行用EE起動 | ジョブ実行用のEEを起動する |
(10) | Playbookによる操作 | Playbook 実行による操作。今回は Cisco IOS のルーターに対して SSH で操作する |
今回は試せていませんが、ダイナミックインベントリの更新は、実行ノード側でされるそうです。
なお、点線で示しているとおりコントロールノードからマネージドノードへ直接アクセスできない構成です。マネージドノードとアクセスできる側に実行ノードを置くことで、コントロールノードから間接的にマネージドノードを制御できるようになります。
今回構築するコントロールノードと実行ノード1台ずつの構成では、信頼性は特に向上しないと思いますが、事情があってAutomation Controller から直接マネージドノードにアクセスできないという場合には、解決策になりそうです(公式ブログ What's new: an introduction to automation mesh)でいうDesign for your enterprise
)。
- 環境
- APP 2.1.1
- Red Hat Enterprise Linux 8.4
- サブスクリプションは Red Hat Developer Program
■ 3. 下準備
RHEL を2台(コントロールノード、実行ノード)用意した状態からはじめます。
3.1. subscription-manage
による作業
subscription-manager
で register
や attach
をして、AAP をインストールできる状態にしておきます。コントロールノード、実行ノードともに必要な作業です。(後述しますが今回AAPのインストーラーはバンドル版ではなく、通常版を利用します。)
# コントロールノード・実行ノード両方 sudo subscription-manager register # 要ログイン sudo subscription-manager list --available # AAPが含まれるプールIDを控える sudo subscription-manager attach --pool AAPが含まれるプールID
実行ログ
$ sudo subscription-manager register Registering to: subscription.rhsm.redhat.com:443/subscription Username: (ユーザー名を入力) Password: (パスワードを入力) The system has been registered with ID: xxxxx The registered system name is: xxxxx $ sudo subscription-manager list --available (いろいろPoolが表示される) $ sudo subscription-manager attach --pool AAPが含まれるプールID Successfully attached a subscription for: Red Hat Developer Subscription for Individuals
加えて、AWS 側に構築したコントロールノード側は明示的にリポジトリ有効化をしておきます。(参考ツイート、ありがとうございます)
# コントロールノード(AWS)側のみ sudo subscription-manager config --rhsm.manage_repos=1
3.2. SSHキーの接続
あとのインストールの中で、コントロールノードからノードに Ansible による SSH 接続が行われます。そのため、認証できる状態にしておく必要があります。
今回は公開鍵認証方式で準備します。キーペアが未作成、未登録の状態から始めているので、以下コマンドでキーペアを作成して、実行ノードに登録します。
# コントロールノード側のみ ssh-keygen -t rsa ssh-copy-id admin@実行ノードのグローバルIP
実行ノードに対して Ansible からパスワード認証でログインできる状態であれば特にこの作業は不要です。
■ 4. インストール
コントロールノード側で作業します。
4.1. インストーラーの準備
Automation Controller のインストールには AAP のインストーラーを利用します。
AAP 2.1 の公式ドキュメントの「RED HAT ANSIBLE AUTOMATION PLATFORM インストーラーの選択および取得」を参考にして、インストーラーをダウンロードして「コントロールノード」に配置します。
今回はバンドル版ではないインストーラー ansible-automation-platform-setup-2.1.1-1.tar.gz
を利用します。
配置後、解凍して、ディレクトリを移動します。
# コントロールノード側作業 tar xvzf ansible-automation-platform-setup-2.1.1-1.tar.gz cd ansible-automation-platform-setup-2.1.1-1
4.2. inventory
の修正(構成の指定)
AAP のインストーラーは、設定ファイルとしてインベントリファイル inventory
を利用します。先ほど移動したディレクトリ ansible-automation-platform-setup-2.1.1-1
にあります。
このファイルの中で、コントロールノード、実行ノードのホスト、各種パスワードなどの指定をします。
今回の構成は、公式ドキュメント「Red Hat Ansible Automation Platform 自動化メッシュガイド」内の「単一の実行ノードを持つ単一ノードのコントロールプレーン」と同じなので、その inventory をベースにしてます。
ポイントだけ抜粋します。
[automationcontroller] localhost ansible_connection=local [automationcontroller:vars] node_type=control peers=execution_nodes [execution_nodes] rhel84ace2 ansible_host=実行ノードのグローバルIP ansible_user=admin ansible_ssh_private_key_file=/home/ec2-user/.ssh/id_rsa ansible_become=yes ansible_become_password=昇格パスワード # ...(略)... [all:vars] admin_password='Automation Controllerへのadminパスワード' # ...(略)... pg_password='DBのパスワード' # ...(略)... registry_url='registry.redhat.io' registry_username='registry.redhat.ioへのユーザー名' registry_password='registry.redhat.ioへのパスワード'
各セクションでの指定の説明は以下のとおりです。なお、今回インストーラーはコントロールノードで実行するため localhost
はコントロールノードを指します。
セクション | 説明 |
---|---|
[automationcontroller] |
localhost がデフォルトで定義されていてそのまま利用 |
[automationcontroller:vars] |
今回は localhost をコントロールノードとして分離したいので node_type=control を指定。デフォルトは node_type=hybrid 相当で、ハイブリッドノード(コントロールノード兼実行ノード)になる |
[execution_nodes] |
実行ノードを指定する。インストーラー内部で Playbook が呼ばれ、ここで指定したノードに接続、インストールするため、Ansible的なお作法で接続できるようにしておく必要がある。要 root 権限。利用するユーザーや権限に応じて要変更 |
[all:vars] |
特にノードの構成とは関係なく定義するもの。デフォルトのハイブリッドノードの構成でインストールするときと同じ |
execution_nodes
グループに所属するホストに対して、対応する SSH ホストキーがコントロールノード上に登録されていない場合、ホストキーチェックで一時停止します。これを防ぐには、あらかじめホストキーを登録しておくか、ansible.cfg
で host_key_checking=False
を指定するなどして対策をしておきます。Ansibleの一般的な対応方法と同じです。
また、インストール中にコントロールノードから実行ノードへのレセプター経由の通信テストが行われます。そのため、あらかじめ実行ノードへの通信経路上で SSH だけでなくTCP 27199ポートが許可されるようにしておく必要があります。
4.3. インストーラーの実行
それでは、インストーラの実行です。ansible-automation-platform-setup-2.1.1-1
ディレクトリのまま以下のコマンドを実行します。
sudo ./setup.sh
今回の環境では、15-20分ほどかかりました。
初めて実行したときは以下のエラーで止まってしまいました。実行ノードへの TCP 27199 は開放していたのですが・・。
TASK [ansible.automation_platform_installer.receptor : Validate connectivity for Mesh peers] *** FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (10 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (9 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (8 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (7 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (6 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (5 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (4 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (3 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (2 retries left). FAILED - RETRYING: [localhost]: Validate connectivity for Mesh peers (1 retries left). failed: [localhost] (item=rhel84ace2) => {"ansible_loop_var": "item", "attempts": 10, "changed": true, "cmd": ["receptorctl", "--socket", "/var/run/awx-receptor/receptor.sock", "ping", "実行ノードのグロバル", "--count", "1"], "delta": "0:00:00.137918", "end": "2022-03-19 06:49:42.683413", "failed_when_result": true, "item": "rhel84ace2", "msg": "non-zero return code", "rc": 2, "start": "2022-03-19 06:49:42.545495", "stderr": "", "stderr_lines": [], "stdout": "Error: no route to node", "stdout_lines": ["Error: no route to node"]} ...ignoring ...(略)... TASK [ansible.automation_platform_installer.receptor : Report error when mesh connectivity issue is detected] *** fatal: [localhost]: FAILED! => {"changed": false, "msg": "An error was detected on Controller Mesh network. Please verify the task output above for further details."} skipping: [rhel84ace2] => {"changed": false, "skip_reason": "Conditional result was False"} ...(略)... PLAY RECAP ********************************************************************* localhost : ok=258 changed=129 unreachable=0 failed=1 skipped=141 rescued=0 ignored=7 rhel84ace2 : ok=77 changed=35 unreachable=0 failed=0 skipped=53 rescued=0 ignored=1
特に何もせず、もう一度インストーラーを実行したら最後まで正常に完了したため、ポート開放状況の問題ではなさそうででした。
正常完了すると最後はこんなログが表示されました。
PLAY RECAP ********************************************************************* localhost : ok=244 changed=53 unreachable=0 failed=0 skipped=162 rescued=0 ignored=0 rhel84ace2 : ok=68 changed=10 unreachable=0 failed=0 skipped=62 rescued=0 ignored=0 The setup process completed successfully. Setup log saved to /var/log/tower/setup-2022-03-19-10:16:41.log.
権限昇格不足だとこんなエラーに
今回の inventory
の [execution_nodes]
で指定したユーザーの場合、ansible_become
による権限昇格が必要でしたが、指定し忘れたときは以下のエラーが表示されました。内部で uid でチェックしているようです。
TASK [ansible.automation_platform_installer.config_dynamic : Ensure user is root] *** skipping: [localhost] => {"changed": false, "skip_reason": "Conditional result was False"} fatal: [rhel84ace2]: FAILED! => {"changed": false, "msg": "UID on remote machine is 1000 (0 required). Check Ansible connection and become settings."}
4.5. 構成図の出力(オマケ)
オマケ的な位置づけですが、inventory
で指定した、各ノードの構成図を Graphviz の dot ファイルで生成する機能が、インストーラーにあります。
./setup.sh -- -t generate_dot_file
この方法は、インストーラー内で実行される Playbook の構成図作成処理に generate_dot_file
タグが付いているため、そのタグを指定しています。インストーラーのコマンドの --
の後に、インストーラー内部の ansible-playbook
コマンドのオプションを渡せる性質を利用しています。構成図作成処理には never
タグも付いているため、デフォルトでは図が作成されません。
今回の構成の場合は、以下の mesh-topology.dot
が生成されました。
$ cat mesh-topology.dot strict digraph "" { rankdir = TB node [shape=box]; subgraph cluster_0 { graph [label="Control Nodes", type=solid]; { rank = same; "localhost"; } } "rhel84ace2"; "localhost" -> "rhel84ace2"; }
描画するこのようになります。(こちらのサイトを利用)
なお、inventory
の [automationcontroller:var]
で、node_type
を hybrid
や control
以外の値を指定したときは以下のエラーが表示されました。実際はただのスペルミスでした。
TASK [Parse Mesh] ************************************************************** fatal: [localhost]: FAILED! => {"msg": "Receptor node localhost has an invalid node_type for group automationcontroller, it must be one of the following: hybrid, control"}
この構成図の作成機能でも、ファクト収集が実行され、実行ノードへのSSH接続がされます。そのため、実際のインストールの前に、構成図を出力して、接続や構成の確認するのはアリかもしれません。
■ 5. 状態確認
インストールが無事にできたようなので、いろいろ状態を確認します。すべてコントロールノードでの作業です。
5.1. API による状態確認
まず手始めに API での確認です。
API で /api/v2/ping/
を叩くと、インスタンスグループとして各ノードの情報が表示されます。認証情報も不要なので、とても手軽に確認できます。
コントロールノードに対してGETで実行します。
https://コントロールノードのグローバルIP/api/v2/ping/
結果は以下のとおりです。instances
配下にノードが2台あり、node_type
が実行ノードでは、execution
、コントロールノードでは control
であることが分かります。
{ "ha": false, "version": "4.1.1", "active_node": "localhost", "install_uuid": "xxx", "instances": [ { "node": "実行ノードのグローバルIP", "node_type": "execution", // ポイント "uuid": "yyy", "heartbeat": "2022-03-19T10:14:06.737391Z", "capacity": 57, "version": "ansible-runner-2.1.1" }, { "node": "localhost", "node_type": "control", // ポイント "uuid": "zzz", "heartbeat": "2022-03-19T10:14:06.678438Z", "capacity": 55, "version": "4.1.1" } ], "instance_groups": [ { "name": "controlplane", "capacity": 55, "instances": [ "localhost" ] }, { "name": "default", "capacity": 57, "instances": [ "実行ノードのグローバルIP" ] } ] }
なお、ハイブリッドノードで構築(デフォルト)した場合、instances
の node_type
の値は hybrid
になります。
5.2. receptorctl
コマンドによる状態確認
Automation mesh 内のノード感の通信状況のなどの操作をする receptorctl
というコマンドがあります。 前述のウェビナーで知りました。
ping
と traceroute
と status
を確認します。
ping
の結果は以下のとおりです。正常に返ってきています。
$ sudo su - awx # awx ユーザーに切り替え $ receptorctl --socket /var/run/awx-receptor/receptor.sock ping 実行ノードのグローバルIP Reply from 実行ノードのグローバルIP in 139.429964ms Reply from 実行ノードのグローバルIP in 140.613656ms Reply from 実行ノードのグローバルIP in 139.723559ms Reply from 実行ノードのグローバルIP in 139.933604ms
通信経路上で TCP 27199 を閉めたり、実行ノード上で sudo systemctl stop receptor
すると、Error: timeout
や Error: no route to node
になりました。
traceroute
の結果は以下のとおりです。ホップノードを挟んでいないのであまりおもしろい結果ではないです。
$ receptorctl --socket /var/run/awx-receptor/receptor.sock traceroute 実行ノードのグローバルIP 0: localhost.localdomain in 76.941µs 1: 実行ノードのグローバルIP in 139.982863ms
あくまで Automation mesh のノードとしての経路を示すので、IPレベルの traceroute
とは経路の見え方が異なります。
status
の結果は以下のとおりです。正しく認識していそうな表示です。Cost
は、メッシュ構成のどの経路を優先するかを決めるもののようです。ルーティングと似ていますね。
$ receptorctl --socket /var/run/awx-receptor/receptor.sock status Node ID: localhost.localdomain Version: 1.1.1 System CPU Count: 2 System Memory MiB: 7556 Connection Cost 実行ノードのグローバルIP 1 Known Node Known Connections 実行ノードのグローバルIP {'localhost.localdomain': 1} localhost.localdomain {'実行ノードのグローバルIP': 1} Route Via 実行ノードのグローバルIP 実行ノードのグローバルIP Node Service Type Last Seen Tags localhost.localdomain control StreamTLS 2022-03-19 11:16:39 {'type': 'Control Service'} 実行ノードのグローバルIP control StreamTLS 2022-03-19 20:07:28 {'type': 'Control Service'} Node Secure Work Types localhost.localdomain local, kubernetes-runtime-auth, kubernetes-incluster-auth 実行ノードのグローバルIP ansible-runner
なお、receptorctl --help
を表示すると、他にも connect
、reload
、version
、work
というコマンドがありました。
Commands: connect Connect the local terminal to a Receptor service on a remote... ping Ping a Receptor node. reload Reload receptor configuration. status Show the status of the Receptor network. traceroute Do a traceroute to a Receptor node. version Show version information for receptorctl and the receptor node work Commands related to unit-of-work processing
5.3. Web UI にる状態確認
今度は、Automation Controller の Web UI(コントロールノード)での確認をします。
ライセンス認証がまだの場合は済ませておきます。今回はマニフェストファイルを利用しました。
パッと見はハイブリッドノードで構築したときと変わりませんが、違いはインスタンスグループ画面に出ます。
[管理] > [インスタンスグループ]
画面には、control plane
と default
というインスタンスグループが表示されます。この内 default
をクリックします。
インスタンスグループの詳細画面が表示されるので、インスタンス
タブをクリックします。
インスタンスの一覧が表示されます。実行ノードとして指定したノードがあることが分かります。インストーラーの inventory
で ansible_host
変数に指定した実行ノードのグローバルIPアドレスの値が、インスタンス名として利用されていました。
なお、ハイブリッドノードとして構築した場合はこの画面では localhost
のみでした。
更にインスタンス名をクリックすると、詳細が表示されます。定期的にヘルスチェックが行われるようで、状態は良好のようでした。眺めてるとヘルチェックは1分間隔のようでした。
あくまで Web UI を持つのはコントロールノードなので、実行ノードには http アクセスできません。
5.4. パケットレベルのコマンドによる状態確認(オマケ)
これはオマケ的な扱いですが、実行ノード上で tcpdump
を眺めていると、コントロールノードとコネクションがはられた状態のまま、10秒間隔でパケットが飛んでいました。
ポーリングのようなものでしょうか。Automation Controller の Web UI で確認できるヘルスチェックの間隔ともまた異なるようです。
契機となるパケットの向きは、以下のように [コントロールノード] > [実行ノード:27199] のときもあれば、逆の時もありました。なにか条件によって変わるのかもしれませんが、詳細は不明です。rhel84ace2
が実行ノードです。
19:56:34.311143 IP コントロールノードのグローバルIP.33580 > rhel84ace2.27199: Flags [P.], seq 341:574, ack 241, win 849, options [nop,nop,TS val 1363547663 ecr 2963536384], length 233 19:56:34.311176 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [.], ack 574, win 1432, options [nop,nop,TS val 2963542674 ecr 1363547663], length 0 19:56:34.381586 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [P.], seq 241:467, ack 574, win 1432, options [nop,nop,TS val 2963542744 ecr 1363547663], length 226 19:56:34.521230 IP コントロールノードのグローバルIP.33580 > rhel84ace2.27199: Flags [.], ack 467, win 849, options [nop,nop,TS val 1363547874 ecr 2963542744], length 0 19:56:44.310948 IP コントロールノードのグローバルIP.33580 > rhel84ace2.27199: Flags [P.], seq 574:807, ack 467, win 849, options [nop,nop,TS val 1363557663 ecr 2963542744], length 233 19:56:44.310969 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [.], ack 807, win 1432, options [nop,nop,TS val 2963552674 ecr 1363557663], length 0 19:56:44.382521 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [P.], seq 467:693, ack 807, win 1432, options [nop,nop,TS val 2963552745 ecr 1363557663], length 226 19:56:44.522032 IP コントロールノードのグローバルIP.33580 > rhel84ace2.27199: Flags [.], ack 693, win 849, options [nop,nop,TS val 1363557875 ecr 2963552745], length 0 19:56:54.311047 IP コントロールノードのグローバルIP.33580 > rhel84ace2.27199: Flags [P.], seq 807:1040, ack 693, win 849, options [nop,nop,TS val 1363567664 ecr 2963552745], length 233 19:56:54.311080 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [.], ack 1040, win 1432, options [nop,nop,TS val 2963562674 ecr 1363567664], length 0 19:56:54.383541 IP rhel84ace2.27199 > コントロールノードのグローバルIP.33580: Flags [P.], seq 693:919, ack 1040, win 1432, options [nop,nop,TS val 2963562746 ecr 1363567664], length 226 19:56:54.523149 IP コントロールノードのグローバルip.33580 > rhel84ace2.27199: Flags [.], ack 919, win 849, options [nop,nop,TS val 1363567876 ecr 2963562746], length 0
逆のときの例(別の環境ですが rhel84ace
が実行ノード)
https://twitter.com/akira6592/status/1504827993528889344/photo/1
■ 6. 動作確認1: Demo Job Template
ようやく、ジョブテンプレートの実行です。なるべく単純なもので試したかったので、デフォルトで存在するジョブテンプレートを試しました。
デモプロジェクト Demo Project
(リポジトリ https://github.com/ansible/ansible-tower-samples)を参照し、localhost で debug メッセージを表示するだけのものです。
6.1. プロジェクト更新がいつの間に失敗
さてジョブを実行しよう、と思ったのですが、プロジェクトの更新が失敗していることに気が付きました。とくに更新の操作はしていませんが。詳細は不明です。
更新を再実行したら正常になりました。
6.2. ジョブテンプレート実行
気を取り直して、Web UI から Demo Job Template
を起動します。
結果はこちら。
うまくいったようです。
若干気になるのが、ジョブ実行画面の詳細画面で以下のメッセージが表示されている点です。
Task was marked as running but was not present in the job queue, so it has been marked as failed.
再実行したら先のメッセージは表示されなくなりました。何度か試して見る限り、実行ノードにイメージがない状態でpullからはじめるとこのエラーが表示される傾向がありました。再実行で解消しても、イメージを削除して再実行すると再現しました。
イメージpullなどの様子
ジョブテンプレート実行によってイメージが pull されることなどを確認しました。それぞれ awx
ユーザーでの確認です。
コントロールノード上
ジョブの実行前は何もイメージがない状態です。
# コントロールノード
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
ジョブ実行中の podman ps
です。これはプロジェクト更新によるもののはずです。特に利用するイメージを指定していないため、実行環境 Control Plane Execution Environment
で指定された registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest
が利用されています。
# コントロールノード $ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 16c6fdd371a7 registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest ansible-playbook ... 1 second ago Up 1 second ago ansible_runner_8
ジョブ実行後、イメージが残っています。
# コントロールノード $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8 latest 2fa77afffbf6 4 days ago 1.17 GB
実行ノード上
ジョブの実行前は何もイメージがない状態です。
# 実行ノード
$ podman images
REPOSITORY TAG IMAGE ID CREATED SIZE
ジョブ実行中の podman ps
です。これはジョブ本体の実行によるもののはずです。特に利用するイメージを指定していないため、実行環境 Default Execution Environment
で指定された registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest
が利用されています。結果的に Control Plane Execution Environment
で指定したイメージと同じになっています。
# 実行ノード
$ podman ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
36745a921bc9 registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest ansible-playbook ... Less than a second ago Up Less than a second ago ansible_runner_9
ジョブ実行後、イメージが残ってます。
# 実行ノード $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8 latest 2fa77afffbf6 4 days ago 1.17 GB
■ 7. 動作確認2: 家の中のマネージドノードを操作するジョブテンプレート
いよいよ、本命のジョブテンプレートの実行を試します。マネージドノードとなる Cisco IOS の機器は、コントロールノードがら IP 的に直接アクセスできない家の中にあります。
7.1. 各種設定
先程試したデモ用とは異なり、以下の工夫を仕込みます。
- ジョブの実行の EE には
Minimal execution environment
で定義している、registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8:latest
を利用- この EE には
cisco.ios
コレクションは含まれていない
- この EE には
collections/requirements.yml
によるコレクションのダウンロード- これにより、
Minimal execution environment
でもcisco.ios
コレクションが利用できるようになる
- これにより、
- スタティックなインベントリ定義に加え、ダイナミックなインベントリプラグイン
azure.azcollection.azure_rm
を利用- マネージドノードが家の機器であることをわかりやすくするため、実際に操作するマネージドノードはスタティックに定義
azure.azcollection.azure_rm
の方は、ダイナミックインベントリの更新がどのノードで行わるかの確認用
プロジェクト設定
git 連携のプロジェクトを作成します。
collections/requirements.yml
には、cisco.ios
コレクションをダウンロードするための定義をしてあります。コントロールノード上でこの定義にしたがってダウンロードされます。
--- collections: - name: cisco.ios version: 2.8.0
他、show コマンドを実行して debug 表示するだけの Playbook などがあります。
認証情報設定
2つの認証情報を作成します。
- Cisco IOS のルーターへの接続に利用する認証情報(タイプ: マシン)
azure.azcollection.azure_rm
インベントリプラグイン用の認証情報(タイプ: Microsoft Azure Resource Manager)
インベントリー設定
インベントリーオブジェクトとして inv_main
を作成し、その中にスタティック定義とダイナミックな定義(インベントリソース)をします。
- 家の Cisco IOS のルーター
ios01
を定義ansible_host
変数に192.168.1.11
を指定、このアドレスはコントロールノードからはアクセス不可だが、実行ノードからはアクセス可
azure.azcollection.azure_rm
インベントリプラグインを利用するインベントリソースを定義- 認証情報には、先程作成した タイプ
Microsoft Azure Resource Manager
の認証情報を指定 - 「起動時の更新」にチェックを入れる
- 実行環境は特に指定しない
- 前述の通り、こちらはダイナミックインベントリ更新がどのノードでされるかの確認用なので、ジョブからは利用しない
- 認証情報には、先程作成した タイプ
ジョブテンプレート設定
これまで作成した、インベントリー、プロジェクト、認証情報を指定します。
Playbook には、Cisco IOS のルーターに show コマンドを実行して debug 表示するだけのものを指定します。show コマンドの実行には、cisco.ios
コレクションのモジュールを利用します。
また、実行環境には Minimal execution environment
を指定します。イメージは registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8:latest
です。
デフォルトの Default execution environment
定義したイメージ registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest
とは異なり、cisco.ios
コレクションが入っていません。ですが、前述の通り、プロジェクト内の collections/requirements.yml
で cisco.ios
を定義しているため、動的にダウンロード後に利用可能になるという仕組みです。
ジョブテンプレートの設定として「インスタンスグループ」もありますが、今回は指定なしにしてみます。
7.2. ジョブテンプレート実行
さて、実行です。通常通りジョブテンプレートを実行します。うまく実行できたようです。
実行ノード上での awx
ユーザーでいくつか確認します。
イメージpullなどの様子
コントロードノード上
ジョブ実行中の podman ps
は以下の通りです。おそらくプロジェクト更新と、collections/requirements.yml
の定義に基づくコレクションのダウンロードしているものかと思います。
# コントロールノード $ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3cf5dcde1a65 registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest ansible-playbook ... 19 seconds ago Up 19 seconds ago ansible_runner_230
実行ノード上
ジョブ実行中の podman ps
です。 2段階あります。
1段階目は、ダイナミックインベントリの更新です。COMMAND
が ansible-inventory
になっていることからそう判断しました。タイミング的には、コントロールノード側で処理のあとでした。
# 実行ノード $ podman images CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 5e0850bc6a5f registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8:latest ansible-inventory... 9 seconds ago Up 9 seconds ago ansible_runner_231
2段階目は、実際のジョブの実行です。ジョブテンプレートの実行環境で指定した、ee-minimal-rhel8
のほうのイメージのコンテナが起動していることが分かります。
# 実行ノード CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES e663d893937f registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8:latest ansible-playbook ... 3 seconds ago Up 3 seconds ago ansible_runner_229
ジョブ実行後、イメージが残ってます。
# 実行ノード $ podman images REPOSITORY TAG IMAGE ID CREATED SIZE registry.redhat.io/ansible-automation-platform-21/ee-supported-rhel8 latest 2fa77afffbf6 6 days ago 1.17 GB registry.redhat.io/ansible-automation-platform-21/ee-minimal-rhel8 latest d8b3521c4042 6 days ago 394 MB
インベントリーの確認
ジョブテンプレート実行後、想定通り azure.azcollection.azure_rm
インベントリプラグインによるホストが追加されました。
collections/requirements.yml
の定義 ないとエラー(オマケ)
なお、collections/requirements.yml
を削除して再実行したら、想定通りモジュールが見つからない旨のエラーになりました。EE Minimal execution environment
で実行されたことが、このことからも分かります。
まとめ・雑感
長くなりましたが、AAP 2.1 で導入された Automation mesh を試しました。シンプルにコントロールノード、実行ノードそれぞれ1台ずつの構成でした。
分離させることによって、なにがどちらのノードの実行させるのかが、調べたり試したりすることによって少し理解できいました。
今回の構成では、コントロールノードが直接アクセスできない構成でも、実行ノードを経由することによって制御可能になる、という点がメリットだと思います。
実行ノードが社内LANにより近い側に置かれると思いますが、依然としてコンテナレジストリへのアクセスが必要なのでインターネット接続性が必要です。もし何らかの事情で、インターネット接続性がない場合は、イメージ予めローカルに置いておくか、アクセスできる範囲に Private Automation Hub や GitLab などのコンテナレジストリを配置するかという形にになるかと思います。
今回はじめて Automation mesh を試しましたが、まだ以下の疑問が残っています。機会があれば調べてみたいと思います。
- 実行ノードでコンテナレジストリにアクセスするための認証情報はどこからくるのか
- 毎回 コントロールノードからくるのか、インストール時に実行ノード側に保存されるのか
- 各ノードを追加、削除する方法
- ジョブ実行時の例のメッセージの詳細
Task was marked as running but was not present in the job queue, so it has been marked as failed.
- ダイナミックインベントリ更新に利用されるデフォルトイメージは
Default Execution Environment
のものかControl Plane Execution Environment
のものか- 実質同じイメージであり、変更もできないのであまり気にする必要もなさそう
参考資料
www.ansible.com www.ansible.com access.redhat.com events.redhat.com