Receptor (5): AWX で Hop Node 込みの Automation Mesh を強引に構成する


はじめに

Ansible Automation Platform(AAP)の Automation Mesh では、Execution Node と Hop Node を含んだ複雑なメッシュネットワークを構成できます。一方で AWX では、Kubernetes を使ったデプロイの場合、Hop Node を利用できないため、構成できるトポロジはスター型がせいぜいです。

とはいえ、前回のエントリ で確認したとおり、Hop Node は単なる Receptor のノード にすぎません。また、Kubernetes ではなく Docker Compose を使った開発用の構成 であれば Hop Node を含んだデプロイも行えることからもわかるように、Hop Node を扱う機能自体は内包されています。

そこで本エントリでは、Kuberentes 上の AWX で、Hop Node を含んだマルチホップの Automation Mesh を構築 します。技術的には Hop Node を Windows で構成する ことも可能です。

なお、紹介している内容は公式にはサポートされていない強引なハック なので、真似する場合は自己責任でお願いします。本当は、素直に Hop Node が公式にサポートされるまで待つほうが賢明 です。

おことわり

本エントリで紹介している内容は、本エントリ公開時点の AWX では 公式にはサポートされていない ものです。技術的にとりあえず動く状態強引に実現 する ハック感が強い手順 であり、あくまで技術的な理解を深める目的なので、実環境での利用はまったくおすすめしません。

Hop Node のサポートはロードマップには含まれるようなので、実環境でしっかり利用したい場合は、素直に公式の実装を待つほうが賢明です。

なお、本エントリは AWX の 21.10.2 を前提としています。

今回の構成

Kubernetes 上の AWX から Hop Node を経由して Execution Node でジョブを実行できる構成を考えます。Hop Node と Execution Node はいずれも Kubernetes 外の独立した仮想マシンです。

exec01exec02 には hop01hop02 のどちらかを経由することで、また exec03 には hop03hop04 を経由することでそれぞれ到達できます。

手順

Kubernetes 上に AWX が構築されている前提で、次の流れで作業します。

  1. インスタンスの登録とそれぞれのピアの修正
    • AWX にインスタンスとして Hop Node と Execution Node の情報を登録します
    • すべてのインスタンスのピア情報を修正します(任意)
  2. Control Node の構成
    • AWX 側の Receptor の設定ファイルを修正し、AWX が正しいピアと接続されるようにします
  3. Execution Node と Hop Node の構成
    • Execution Node と Hop Node に Receptor を導入します
  4. 動作の確認
    • Receptor のメッシュネットワークの状態を確認します
    • AWX でインスタンスグループを構成し、任意の Execution Node でジョブが正常に実行できることを確認します

実際には 1 と 2 は逆のほうが手間をほんの少し(後述する Pod の再作成後のピアの再修正の分)減らせますが、流れがわかりにくくなってしまうので今回はこうしています。

エントリ中で使っている実際のファイル群は GitHub のリポジトリに配置 しています。

インスタンスの登録とそれぞれのピアの修正

AWX にインスタンスの情報を登録し、それぞれのピアを修正します。

インスタンスの登録

インスタンスの登録は、Web UI や API では Execution Node しか扱えないため、今回は awx-manage コマンドを使います。

awx-manage provision_instance --hostname <ホスト名> --node_type <ノードタイプ>

<ノードタイプ> は、Execution Node であれば execution、Hop Node であれば hop です。

今回のような Kubernetes 上の AWX では、このコマンドは実際には AWX の Pod の awx-task コンテナで叩くことになります。今回は全部で 7 ノードを登録するため、次のように kubectl execfor で回して登録します。登録時に IP アドレス関連の警告が出ますが、無視します。

EXEC_NODES="
exec01.ansible.internal
exec02.ansible.internal
exec03.ansible.internal
"

HOP_NODES="
hop01.ansible.internal
hop02.ansible.internal
hop03.ansible.internal
hop04.ansible.internal
"

for exec in ${EXEC_NODES}; do
  kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage provision_instance --hostname ${exec} --node_type execution
done

for hop in ${HOP_NODES}; do
  kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage provision_instance --hostname ${hop} --node_type hop
done

この段階で、登録したインスタンスが Web UI の Instances のページに表示されるようになります。Node Type もコマンドで指定した通りです。

Node Typeexecution のノードは、Control Node のインスタンス(AWX)の Peers自動で登録 されます。これは現在の AWX では仕様であり、抑制できません。

Topology View では、登録されているインスタンスとそのピアの情報をグラフィカルに確認できます。この段階では、Execution Node のインスタンスが Control Node のインスタンスのピアになっているだけで、Hop Node のインスタンスは孤立しています。

ピアの修正(任意)

前述のように、この段階で AWX が認識しているトポロジは、Execution Node が Control Node と直結され、Hop Node が孤立した状態です。ここで、各インスタンスのピアを修正して、冒頭の構成図の通りの正しいトポロジを定義します。

この手順は、現在の AWX ではあくまで画面上の表示を直す程度の意味しかなさそうで、実施は任意です。スキップしても動作に影響はなさそうですが、Web UI 上の表示と実機の状態が整合しなくなるため、できれば実施したいところです。

ピアの修正も、awx-manage コマンドで実施します。次の 3 パタンでの指定が可能です。

# インスタンスにピアを追加する場合
awx-manage register_peers <接続元インスタンス> --peers <追加するピア> ...

# インスタンスのピアを削除する場合
awx-manage register_peers <接続元インスタンス> --disconnect <削除するピア> ...

# インスタンスのピアを丸ごと置き換える場合
awx-manage register_peers <接続元インスタンス> --exact <ピア> ...

今回は、次のコマンドで修正します。

CONTROL_NODE=$(kubectl -n awx get pod --no-headers -o custom-columns=:metadata.name -l app.kubernetes.io/name=awx)
kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers ${CONTROL_NODE} --exact hop01.ansible.internal hop02.ansible.internal hop03.ansible.internal

kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers hop01.ansible.internal --peers exec01.ansible.internal exec02.ansible.internal
kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers hop02.ansible.internal --peers exec01.ansible.internal exec02.ansible.internal
kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers hop03.ansible.internal --peers hop04.ansible.internal
kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers hop04.ansible.internal --peers exec03.ansible.internal

Control Node のホスト名は Pod 名から拾えます。Control Node のピアには Execution Node が自動で登録されてしまっているため、ここでは --exact を使って Hop Node のみに置き換えています。

一連の作業が完了すると、各インスタンスの Peers が修正され、Topology View も狙い通りの矢印っぷりになったことが確認できます。

なお、AWX の Pod が再作成 されると、AWX は自分自身を新しい Control Node のインスタンスとして登録して古い Control Node を置き換えています。この影響で、Pod が再作成されるたびに Control Node のピア情報が初期化 され、Execution Node との接続が復活 してしまいます。

したがって、Pod の再作成が発生した後は、もし Web UI 上の表示を実機と整合させたいのであれば、前述の awx-manage register_peers コマンドの再実行が必要です(実際に後述の手順でこの状況が発生します)。

Control Node の構成

理想を言えば、ここまでの作業によって AWX 側の Receptor の設定ファイルもきれいに書き換えられてほしい ところです。

が、前述の通り、この周辺は現在の AWX では充分にサポートされておらず、実装も不十分なため、設定ファイルは残念ながら自力でカスタマイズする必要があります。

前提: 現在の実装の課題

ここまでの作業で、Web UI で確認できる通り、AWX は Control Node である自分自身のピアを正しく把握できているはずです。が、現在の AWX では、残念ながらピアの情報は DB 内に保持されるだけで、Receptor の設定ファイル/etc/receptor/receptor.confにまでは正しく反映されません

実際、ここまでの作業を終えた段階で設定ファイルを確認しても、期待する内容とは異なっています。ピアから削除したはずの Execution Node が(自動登録された時点のまま)残っており、Hop Node もありません。

$ kubectl -n awx exec -it deployment/awx -c awx-ee -- cat /etc/receptor/receptor.conf
...
- tcp-peer:
    address: exec01.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: exec02.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: exec03.ansible.internal:27199
    tls: tlsclient

このため、この機能が正式にサポートされるまでは、AWX で複雑なトポロジのメッシュネットワークを構成したい場合、AWX 用の設定ファイルはどうにかして自力でカスタマイズするしかない 状況です。

前提: カスタマイズの方針

カスタマイズを考えるにあたっては、Kubernetes 上の AWX の Receptor の設定ファイルを取り巻く以下の実装に注意が必要です。簡単に言えば、Execution Node を追加したときにそれが Receptor の構成にも反映されるよう、awx-task コンテナが書き換えた設定ファイルを awx-ee コンテナが読めるように工夫されています。

  • awx-task コンテナと awx-ee コンテナで emptyDir を共有して同一の設定ファイルを同時に参照している
  • 設定ファイルは、awx-task コンテナの起動時に毎回生成され、さらには Execution Node を追加すると awx-task コンテナにより 追記される
  • 設定ファイルは、awx-ee コンテナで動作している Receptor により読み取られ利用される

したがって今回は、設定ファイルは awx-task コンテナでは AWX が自由に書き替えられる ようにしなければならない一方で、awx-ee コンテナでは AWX に書き換えられることのないカスタマイズ済みの中身が読める ようにしなければならないことになります。コンテナ内の設定ファイルを直接編集したとしても、awx-task コンテナにより容易に再生成・追記されてしまうため、意図した状態を保てません。また、awx-task コンテナは設定ファイルを書き込みモードで開けないとそもそも起動できません。

このため、非常に強引な解決策 として、ここでは コンテナごとに同じパスで実体が異なるファイルを握らせる ことを考えます。

  • awx-task コンテナには、emptyDir の Volume 上のファイルを読み書きさせる
  • awx-ee コンテナには、カスタマイズした設定ファイルの ConfigMap をマウントする

コンテナ間で設定ファイルの内容に差異が生じる ことになりますが、動作には致命的な影響はないため許容します。

設定ファイルの用意

awx-ee コンテナに使わせたい設定ファイルを用意します。awx-task コンテナの設定ファイルは AWX が勝手に作るため用意は不要です。

用意した設定ファイル(receptor.conf)を抜粋します。完全なモノは GitHub のリポジトリに配置 しています。

...
- node:
    firewallrules:
      - action: reject
        tonode: /awx-[0-9a-z]{10}-[0-9a-z]{5}/
        toservice: control
- control-service:
    ...
- work-command:
    ...
- work-signing:
    ...
- work-kubernetes:
    ...
- work-kubernetes:
    ...
- tls-client:
    ...
- tcp-peer:
    address: hop01.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: hop02.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: hop03.ansible.internal:27199
    tls: tlsclient

やや複雑に見えますが、デフォルトの設定ファイルから変更した点は以下の二つだけです。

  • firewallrulestonode をホスト名から正規表現に変更(ノード ID が Pod の再作成ごとに変化するため)
  • tcp-peer で目的の構成のピアを追加

これを ConfigMap にします。

$ kubectl -n awx create configmap awx-custom-receptor-config --from-file=receptor.conf
configmap/awx-custom-receptor-config created

$ kubectl -n awx get configmap awx-custom-receptor-config -o yaml
apiVersion: v1
data:
  receptor.conf: |
    ...
    - node:
        firewallrules:
          - action: reject
            tonode: /awx-[0-9a-z]{10}-[0-9a-z]{5}/
            toservice: control
    ...
    - tcp-peer:
        address: hop01.ansible.internal:27199
        tls: tlsclient
    - tcp-peer:
        address: hop02.ansible.internal:27199
        tls: tlsclient
    - tcp-peer:
        address: hop03.ansible.internal:27199
        tls: tlsclient
...

AWX の修正

前述のカスタマイズ方針に従って、AWX リソースの specextra_volumes*_extra_volume_mounts を追加します。awx-task コンテナには emptyDir を、awx-ee コンテナには ConfigMap をマウントさせています。

---
apiVersion: awx.ansible.com/v1beta1
kind: AWX
metadata:
  name: awx
spec:
  ...
  extra_volumes: |
    - name: awx-dummy-receptor-config
      emptyDir: {}
    - name: awx-custom-receptor-config
      configMap:
        name: awx-custom-receptor-config

  task_extra_volume_mounts: |
    - name: awx-dummy-receptor-config
      mountPath: /etc/receptor

  ee_extra_volume_mounts: |
    - name: awx-custom-receptor-config
      mountPath: /etc/receptor/receptor.conf
      subPath: receptor.conf

これを任意の手段(kubectledit でも apply でも helm でも)で適用し、AWX Operator によるリコンサイルが終われば、それぞれのコンテナが目的の設定ファイルを使うようになります。

$ kubectl -n awx exec -it deployment/awx -c awx-task -- cat /etc/receptor/receptor.conf
...
- tcp-peer:
    address: exec01.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: exec02.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: exec03.ansible.internal:27199
    tls: tlsclient

$ kubectl -n awx exec -it deployment/awx -c awx-ee -- cat /etc/receptor/receptor.conf
...
- tcp-peer:
    address: hop01.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: hop02.ansible.internal:27199
    tls: tlsclient
- tcp-peer:
    address: hop03.ansible.internal:27199
    tls: tlsclient

awx-task コンテナでは AWX が生成した設定ファイルが、awx-ee コンテナではカスタマイズした設定ファイルが、それぞれ配置・参照できていることがわかります。

ピアの再修正(任意)

AWX Operator が AWX リソースをリコンサイルする過程で、AWX の Pod が再作成されています。

これにより、前述の通り Control Node のピア情報が初期化されてしまっているため、気になるのであればここで Control Node 分の awx-manage register_peers を再実行します。

CONTROL_NODE=$(kubectl -n awx get pod --no-headers -o custom-columns=:metadata.name -l app.kubernetes.io/name=awx)
kubectl -n awx exec -it deployment/awx -c awx-task -- awx-manage register_peers ${CONTROL_NODE} --exact hop01.ansible.internal hop02.ansible.internal hop03.ansible.internal

Execution Node と Hop Node の構成

Control Node(AWX)ができたら、Execution Node と Hop Node を整えていきます。

Execution Node の構成

Execution Node の構成には、AWX の標準機能をそのまま使えます。すなわち、以前のエントリ で紹介したように、AWX が生成してくれるインストールバンドルを素直にそのまま利用すれば完了です。

詳細は 以前のエントリ で紹介しているため、本エントリでは割愛します。

Hop Node の構成

現在の AWX では Hop Node 用のインストールバンドルは生成できないため、何らかの形で手動で導入が必要です。

今回は、Execution Node のインストールバンドルで利用されている ansible.receptor コレクションの ansible.receptor.setup ロール を使って構成します。また、Control Node と Execution Node がデフォルトで TLS を利用する形で構成されるため、Hop Node もこれに倣うものとします。

……が、現在の ansible.receptor.setup には設定ファイルの *-peer が正しく生成されないバグ(IssuePR)があるため、手元で試す場合は PR の修正を手動で反映させるか、PR 元のブランチ からインストールしてください。

さて、まずは、Hop Node が利用する証明書を生成する必要があります。証明書は、以前のエントリ で紹介した通り receptor コマンドで生成できます。一点、CA 証明書の秘密鍵awx-web コンテナ にしかないため、一時的に awx-ee コンテナにコピーする必要がある点は注意が必要です。

HOP_NODES="
hop01.ansible.internal
hop02.ansible.internal
hop03.ansible.internal
hop04.ansible.internal
"

# CA 証明書の秘密鍵を awx-web から awx-ee にコピー
kubectl -n awx exec deployment/awx -c awx-web -- cat /etc/receptor/tls/ca/receptor-ca.key | kubectl -n awx exec -i deployment/awx -c awx-ee -- bash -c "cat > /tmp/receptor-ca.key"

# Hop Node の証明書と秘密鍵を生成してローカルのカレントディレクトリにコピー
for node in ${HOP_NODES}; do
  kubectl -n awx exec deployment/awx -c awx-ee -- mkdir -p /tmp/${node}
  kubectl -n awx exec deployment/awx -c awx-ee -- receptor --cert-makereq bits=2048 commonname=${node} dnsname=${node} nodeid=${node} outreq=/tmp/${node}/receptor.csr outkey=/tmp/${node}/receptor.key
  kubectl -n awx exec deployment/awx -c awx-ee -- receptor --cert-signreq req=/tmp/${node}/receptor.csr cacert=/etc/receptor/tls/ca/receptor-ca.crt cakey=/tmp/receptor-ca.key outcert=/tmp/${node}/receptor.crt verify=true

  mkdir -p ${node}
  kubectl -n awx exec deployment/awx -c awx-ee -- bash -c "tar zcf - /tmp/${node}" | tar zxvf - --strip-components 2 -C ${node}
  kubectl -n awx exec deployment/awx -c awx-ee -- cat /etc/receptor/tls/ca/receptor-ca.crt > ${node}/receptor-ca.crt
done

# awx-ee にコピーした CA 証明書の秘密鍵を削除
kubectl -n awx exec deployment/awx -c awx-ee -- rm /tmp/receptor-ca.key

これで、ローカルのカレントディレクトリに必要なファイル群が配置されます。

$ tree hop*
hop01.ansible.internal
├── receptor-ca.crt
├── receptor.crt
├── receptor.csr
└── receptor.key
hop02.ansible.internal
├── receptor-ca.crt
├── receptor.crt
├── receptor.csr
└── receptor.key
hop03.ansible.internal
├── receptor-ca.crt
├── receptor.crt
├── receptor.csr
└── receptor.key
hop04.ansible.internal
├── receptor-ca.crt
├── receptor.crt
├── receptor.csr
└── receptor.key

0 directories, 16 files

続けて、ansible.receptor.setup ロールを使うプレイブックを作成します。

---
- hosts: all
  become: true
  tasks:
    - ansible.builtin.user:
        name: "{{ receptor_user }}"
        shell: /bin/bash
    - ansible.posix.firewalld:
        port: "{{ receptor_port }}/tcp"
        permanent: yes
        state: enabled
    - community.general.copr:
        name: ansible-awx/receptor
        state: enabled
    - ansible.builtin.import_role:
        name: ansible.receptor.setup
    - ansible.builtin.systemd:
        name: receptor
        state: restarted

あとは、ansible.receptor.setup ロールがよしなにやってくれるようにインベントリで必要な変数を定義して、プレイブックを実行するだけです。Hop Node なので、tcp-peertcp-listener が適切に記述され、ワークタイプの定義を含まない設定ファイルができれば充分です。

---
all:
  hosts:
    hop01.ansible.internal:
      ansible_host: hop01.ansible.internal
      receptor_peers:
        - protocol: tcp
          address: exec01.ansible.internal
          port: 27199
        - protocol: tcp
          address: exec02.ansible.internal
          port: 27199
    hop02.ansible.internal:
      ansible_host: hop02.ansible.internal
      receptor_peers:
        - protocol: tcp
          address: exec01.ansible.internal
          port: 27199
        - protocol: tcp
          address: exec02.ansible.internal
          port: 27199
    hop03.ansible.internal:
      ansible_host: hop03.ansible.internal
      receptor_peers:
        - protocol: tcp
          address: hop04.ansible.internal
          port: 27199
    hop04.ansible.internal:
      ansible_host: hop04.ansible.internal
      receptor_peers:
        - protocol: tcp
          address: exec03.ansible.internal
          port: 27199
  vars:
    ansible_user: root
    ansible_ssh_private_key_file: ~/.ssh/id_rsa
    receptor_user: awx
    receptor_group: awx
    receptor_tls: true
    custom_tls_certfile: "{{ (ansible_host, 'receptor.crt') | path_join }}"
    custom_tls_keyfile: "{{ (ansible_host, 'receptor.key') | path_join }}"
    custom_ca_certfile: "{{ (ansible_host, 'receptor-ca.crt') | path_join }}"
    receptor_protocol: tcp
    receptor_listener: true
    receptor_port: 27199
ansible-playbook -i inventory.yaml install_hop_nodes.yaml

無事にプレイブックが完走すれば、Hop Node に狙い通りの設定ファイルが配置され、サービスが起動されます。

$ ssh root@hop01.ansible.internal -- cat /etc/receptor/receptor.conf
---
- node:
    id: hop01.ansible.internal
...
- tcp-peer:
    address: exec01.ansible.internal:27199
    redial: true
    tls: tls_client
- tcp-peer:
    address: exec02.ansible.internal:27199
    redial: true
    tls: tls_client

$ ssh root@hop01.ansible.internal -- systemctl status receptor
● receptor.service - Receptor
   Loaded: loaded (/usr/lib/systemd/system/receptor.service; enabled; vendor preset: disabled)
   ...

動作の確認

ここまでで、構成は完了です。実際の動きを見ていきます。

構成のレビュ

すべての作業が問題なく完了していれば、AWX 上でも数分で全インスタンスが Ready になるはずです。

Topoligy View でもすべて緑色になり、意図通りの構成ができています。

Receptor 的なメッシュネットワークの状態は、awx-ee コンテナに receptorctl を導入すると確認できます。

kubectl -n awx exec -it deployment/awx -c awx-ee -- pip install receptorctl

status を実行すると、すべてのノードがきれいに認識できています。TLS も正しく構成され、想定通りのワークタイプも確認できます。

$ kubectl -n awx exec -it deployment/awx -c awx-ee -- /home/runner/.local/bin/receptorctl --socket /var/run/receptor/receptor.sock status
...

Connection              Cost
hop01.ansible.internal  1
hop02.ansible.internal  1
hop03.ansible.internal  1

Known Node              Known Connections
awx-8597d86894-czg7l    hop01.ansible.internal: 1 hop02.ansible.internal: 1 hop03.ansible.internal: 1 
exec01.ansible.internal hop01.ansible.internal: 1 hop02.ansible.internal: 1 
exec02.ansible.internal hop01.ansible.internal: 1 hop02.ansible.internal: 1 
exec03.ansible.internal hop04.ansible.internal: 1 
hop01.ansible.internal  awx-8597d86894-czg7l: 1 exec01.ansible.internal: 1 exec02.ansible.internal: 1 
hop02.ansible.internal  awx-8597d86894-czg7l: 1 exec01.ansible.internal: 1 exec02.ansible.internal: 1 
hop03.ansible.internal  awx-8597d86894-czg7l: 1 hop04.ansible.internal: 1 
hop04.ansible.internal  exec03.ansible.internal: 1 hop03.ansible.internal: 1 

Route                   Via
exec01.ansible.internal hop01.ansible.internal
exec02.ansible.internal hop01.ansible.internal
exec03.ansible.internal hop03.ansible.internal
hop01.ansible.internal  hop01.ansible.internal
hop02.ansible.internal  hop02.ansible.internal
hop03.ansible.internal  hop03.ansible.internal
hop04.ansible.internal  hop03.ansible.internal

Node                    Service   Type       Last Seen             Tags
hop01.ansible.internal  control   StreamTLS  2022-12-20 01:07:48   {'type': 'Control Service'}
hop02.ansible.internal  control   StreamTLS  2022-12-20 01:07:51   {'type': 'Control Service'}
hop03.ansible.internal  control   StreamTLS  2022-12-20 01:07:48   {'type': 'Control Service'}
hop04.ansible.internal  control   StreamTLS  2022-12-20 01:07:46   {'type': 'Control Service'}
exec01.ansible.internal control   StreamTLS  2022-12-20 01:08:10   {'type': 'Control Service'}
exec02.ansible.internal control   StreamTLS  2022-12-20 01:08:19   {'type': 'Control Service'}
exec03.ansible.internal control   StreamTLS  2022-12-20 01:08:37   {'type': 'Control Service'}
awx-8597d86894-czg7l    control   Stream     2022-12-19 16:08:38   {'type': 'Control Service'}

Node                    Work Types
awx-8597d86894-czg7l    local, kubernetes-runtime-auth, kubernetes-incluster-auth

Node                    Secure Work Types
exec01.ansible.internal ansible-runner
exec02.ansible.internal ansible-runner
exec03.ansible.internal ansible-runner

ジョブの実行

インスタンスの状態が問題なければ、あとは通常の Execution Node と同じ感覚で使えます。以前のエントリ で紹介した通り、Instance Group を定義してインスタンスを追加し、Job Template から指定するだけです。

Ansible Runner や Podman の動きも 以前のエントリ で紹介した通りです。特別なことは何もないので割愛します。

補足: Windows 版 Hop Node

Receptor それ自体は Windows でも動作するように実装されています。ということは、技術的には Hop Node を Windows でも構成できる ということになります。実際、Windows 版 Hop Node を介してジョブが実行できることは確認済み です。

Windows 版のバイナリはどこでも配布されていないため、自前でのビルドは必須ですが、EXE ファイルができてしまえば起動の仕方は Linux 版と変わりありません。

# ビルド(Linux 上で実行する場合)
GOOS=windows go build -o receptor.exe ./cmd/receptor-cl

# ビルド(Windows 上で実行する場合)
go build -o receptor.exe .\cmd\receptor-cl

# 起動
.\receptor.exe -c .\receptor.conf

Windows で構成する場合の設定ファイルは、例えば次のような中身です。ファイルのパスが Windows 表記になることと、control-service でソケットファイルのパスを渡す必要がないことに注意すれば、Linux 用の設定ファイルをほぼそのまま流用できます。

---
- node:
    id: hop01.ansible.internal
- log-level: info
- control-service:
    service: control
    tls: tls_server
- tls-server:
    name: tls_server
    cert: C:\receptor\receptor.crt
    key: C:\receptor\receptor.key
    clientcas: C:\receptor\receptor-ca.crt
    requireclientcert: true
    mintls13: False
- tls-client:
    name: tls_client
    cert: C:\receptor\receptor.crt
    key: C:\receptor\receptor.key
    rootcas: C:\receptor\receptor-ca.crt
    insecureskipverify: false
    mintls13: False
- tcp-listener:
    port: 27199
    tls: tls_server
- tcp-peer:
    address: exec01.ansible.internal:27199
    redial: true
    tls: tls_client
- tcp-peer:
    address: exec02.ansible.internal:27199
    redial: true
    tls: tls_client

起動できてしまえば、AWX からの見え方は Linux 版の Hop Node とまったく一緒です。

まとめ

背景にある実装を理解できれば、強引に Hop Node を構成できることがわかりました。

本番環境で安心して使うには公式のサポートを待った方がよいのは前述の通りですが、多少のトラブルを許容できる環境であれば、現状でも便利に使えるかもしれません。

Receptor 関連エントリ

@kurokobo

くろいです。ギターアンサンブルやら音響やらがフィールドの IT やさんなアルトギター弾き。たまこう 48 期ぎたさん、SFC '07 おんぞう、新日本ギターアンサンブル、Rubinetto。今は野良気味。

コメントを残す

メールアドレスが公開されることはありません。