はじめに
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 外の独立した仮想マシンです。
exec01
と exec02
には hop01
か hop02
のどちらかを経由することで、また exec03
には hop03
と hop04
を経由することでそれぞれ到達できます。
手順
Kubernetes 上に AWX が構築されている前提で、次の流れで作業します。
- インスタンスの登録とそれぞれのピアの修正
- AWX にインスタンスとして Hop Node と Execution Node の情報を登録します
- すべてのインスタンスのピア情報を修正します(任意)
- Control Node の構成
- AWX 側の Receptor の設定ファイルを修正し、AWX が正しいピアと接続されるようにします
- Execution Node と Hop Node の構成
- Execution Node と Hop Node に Receptor を導入します
- 動作の確認
- 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 exec
を for
で回して登録します。登録時に 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 Type
が execution
のノードは、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
やや複雑に見えますが、デフォルトの設定ファイルから変更した点は以下の二つだけです。
firewallrules
のtonode
をホスト名から正規表現に変更(ノード 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 リソースの spec
に extra_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
これを任意の手段(kubectl
の edit
でも 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
が正しく生成されないバグ(Issue、PR)があるため、手元で試す場合は 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-peer
と tcp-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 を構成できることがわかりました。
本番環境で安心して使うには公式のサポートを待った方がよいのは前述の通りですが、多少のトラブルを許容できる環境であれば、現状でも便利に使えるかもしれません。