Ansible AWX で Execution Environment と Container Group を作って使う


はじめに

前回のエントリ “Ansible Runner と Ansible Builder で Execution Environment を作って使う” では、AWX で Execution Environment を使うための前段として、Ansible Runner と Ansible Builder の動作を確認しました。

このエントリでは、その続きとして、作成した Execution Environment を実際に AWX から利用する流れを確認します。また、Container Group を作成して、Pod の構成をカスタマイズします。

前提とする環境

本エントリでは、次の環境を前提に書いています。

  • CentOS 8.2
  • Python 3.9.2
  • Docker 20.10.7
  • Kubernetes (K3s) 1.21.2+k3s1
  • AWX 19.2.2

なお、AWX を K3s 上でホストする方法は、別エントリ “AWX を AWX Operator でシングルノード K3s にホストする” で紹介しています。

また、本エントリの再現に必要な諸々の資材は、手順込みで GitHub に配置済み です。

事前準備

諸々の動作を確かめるため、AWX を触り始める前に、次のモノを用意しました。

  • Execution Environment
  • プライベートコンテナレジストリ
  • プライベート Git リポジトリ
  • プレイブック(プライベート Git リポジトリ上)

AWX から自前の Execution Environment を使いたい場合は、当然ながら事前に準備が必要です。今回は 前回のエントリ に従って、Ansible Builder で自分でビルドして用意します。なお、後述しますが、そもそも最近の AWX は、デフォルトで Execution Environment として quay.io/ansible/awx-ee が組み込まれている(というか何もしなくても勝手に使われる)ため、自前での用意は必須ではありません。デフォルトの Execution Environment では要件を満たせない(Ansible のバージョンが違う、モジュールが足りないなど)ときにのみ、自前での用意が必要です。

また、AWX は、Execution Environment を コンテナレジストリ からプルして利用します。今回のように自分でビルドした Execution Environment を使いたい場合は、つまり、事前にそれをどこかのコンテナレジストリにプッシュしておく必要があります。この目的では、Docker Hub や Quai.io などインタネット上のサービスも利用できますが、インタネット上にコンテナイメージを配置したくない場合を想定し、本エントリでは K3s 上にプライベートコンテナレジストリをデプロイ して利用しています。

Execution Environment で動作させるプレイブック(≒AWX に追加するプロジェクトの実体)は、ローカルのプロジェクトディレクトリ(実体は Kubernetes の PV)に配置してもよいですが、少し本格的な利用を想定して、SCM から取得させます。この目的で、本エントリでは K3s 上にプライベート Git リポジトリ をデプロイしています。そして、動作させる プレイブック を実際に Git リポジトリ上に用意します。

上記それぞれのもう一歩踏み込んだ詳細は、本筋ではないのでここでは割愛して、本エントリの末尾で 補足: 事前準備の作業内容 としてまとめています。

AWX での Execution Environment の利用

事前準備ができて環境が整ったら、AWX で実際に Execution Environment を利用してプレイブックを実行します。

今回の環境固有の準備

AWX 上で、次の二つの Credential を登録しておきます。

  • Container Registry の Credential(registry.example.com 用)
  • Source Control の Credential(git.example.com 用)

また、今回は Git リポジトリが自己署名証明書を利用した HTTPS 接続のため、Settings > Jobs > Jobs settingsExtra Environment Variables で、次の値を設定しておきます。

{
  "GIT_SSL_NO_VERIFY": "True"
}

Execution Environment の登録

コンテナレジストリに配置した自前の Execution Environment は、明示的に Execution Environment として AWX に登録が必要です。メニュの Administration > Execution Environment から、名前やイメージのタグ、プルするタイミング、認証情報などを指定して登録します。

自前の Execution Environment は、今回は事前準備段階で二つ用意してあったので、二つとも登録しました。

なお、一覧を見ると、デフォルトで AWX EE と Control Plane Execution Environment が登録されていることがわかります。これらは、Execution Environment を明示しなかったジョブや、SCM の Sync ジョブ、管理系のジョブなどで透過的に利用されています。

プロジェクトの登録

メニュの Resources > Projects から、通常通りにプロジェクトを追加します。ここでは、事前準備で Gitea 上に作成した gitea/ee-demo プロジェクト(中身は GitHub の kurokobo/awx-on-k3s を丸ごとコピーしただけ)を指定しています。

画面の通り、プロジェクトの登録の段階でも Execution Environment を指定できます。今回は空欄にしましたが、プロジェクトレベルでデフォルトを指定しておき、後続のジョブテンプレートレベルでオーバライドするような使い方も可能です。また、SettingsMiscellaneous System settings から、さらに上位のインスタンスレベルでのデフォルトの Execution Environment も指定できるようです。

登録したら、Sync しておきます。

ジョブテンプレートの登録

最後に、メニュの Resources > Templates から、通常通りジョブテンプレートを登録します。

先の手順で登録したプロジェクトを選択して、プレイブックにはテスト用の runner/project/demo.yml を指定しました。これは 前回のエントリ で使ったプレイブックそのもので、自ホスト名や実行ユーザ名、Ansible のバージョン、パッケージやコレクションの一覧を表示してくれるものです。

画面の通り、ジョブテンプレートでも Execution Environment を指定できます。画面では、自前の Custom EE (2.10) を指定しています。

ここを空欄にすると、インスタンスやプロジェクトのデフォルトが設定されていればそれが、設定されていなければ組み込みの AWX EE 0.5.0 が自動で設定されます。AWX では、プレイブックの実行には何らかの Execution Environment が必須です。

プレイブックの実行と結果の確認

ジョブテンプレートを保存して実行すると、設定された Execution Environment を利用してプレイブックが実行されます。

今回の例では、出力からは、Ansible のバージョンが 2.10 で、Ansible Builder でのビルド時に指定した追加パッケージが導入された環境であることが確認できます。意図した通りの環境でプレイブックが実行できたようです。

ジョブテンプレートを修正して、今度は Custom EE (2.9) を指定して再度実行すると、バージョンの変化が見て取れます。

また、ジョブテンプレートで Execution Environment を にして保存すると、AWX 19.2.2 では自動で AWX EE 0.5.0 が指定されます。

そのまま実行すると、結果から、デフォルトの AWX EE 0.5.0 にはあらかじめパブリッククラウド環境などを操作するためのコレクション群やパッケージ群が追加済みであることがわかります。Execution Environment の存在を意識しなくても、ある程度の汎用性がある環境はいつでも使えそうですね。

Kubernetes 上での Execution Environment と Pod の中身

ジョブを実行すると、実行の都度、Execution Environment が Pod として起動し、終了後には削除されます。このため、前回のエントリ でプレイブックを Ansible Runner からコンテナ下で動作させたときと同様、localhost は Pod それ自体 であり、localhost に対する作用は揮発的 で、永続化されません

Pod の作られっぷり

前回 同様、プレイブックの最後に ansible.builtin.pause を追加して AWX からジョブテンプレートを実行します。

- name: Simply pause for a while
  ansible.builtin.pause:
    minutes: 10

待ち時間中に Kubernetes の Pod の状態を確認すると、AWX が存在するネームスペースに、ジョブ実行用の Pod が作られていることがわかります。次の例では、automation-job-43-77fgq です。

$ kubectl -n awx get pod
NAME                      READY   STATUS    RESTARTS   AGE
awx-postgres-0            1/1     Running   0          2d7h
awx-d85c677df-85wvm       4/4     Running   0          2d7h
automation-job-43-77fgq   1/1     Running   0          81s

定義を確認すると、コンテナのイメージとして AWX から指定した Execution Environment が利用されていることがわかります。また、Credential で登録した認証情報が imagePullSecrets として渡されていることも確認できます。

$ kubectl -n awx get pod automation-job-43-77fgq -o json | jq .spec
{
  "containers": [
    {
      "args": [
        "ansible-runner",
        "worker",
        "--private-data-dir=/runner"
      ],
      "image": "registry.example.com/ansible/ee:2.10-custom",
      ...
      "volumeMounts": [
        {
          "mountPath": "/var/run/secrets/kubernetes.io/serviceaccount",
          "name": "kube-api-access-bxqh5",
          "readOnly": true
        }
      ]
    }
  ],
  "imagePullSecrets": [
    {
      "name": "automation-8f2b6-image-pull-secret-4"
    }
  ],
  ...
}

プレイブックの配置っぷり

ところで、前回 の Docker での実行時は、コンテナの /runner にホストのディレクトリが直接マウントされていましたが、Kubernetes 上で動作しているこの Pod には、上記出力例のとおりそのようなマウントの定義はありません。

しかしながら、Pod の中でコマンドを実行してみると、確かにプレイブックは存在しています。用意したデモプロジェクトのディレクトリ構造のせいでわかりくいですが、Pod の /runner/project 下に、AWX で指定したプロジェクトの中身が配置されています。

$ kubectl -n awx exec -it automation-job-43-77fgq -- ls -l /runner/project/runner/project
total 4
-rw-r--r--. 1 root root 1058 Jul 20 15:07 demo.yml

Pod の /runner/project 下のプレイブックは、Docker のときとは異なり、永続ボリュームのマウント ではない 方法で Pod 内に配置されていることになります。

Receptor と Ansible Runner の Transmit、Worker、Process

Pod へのプレイブックの配置とその後の実行は、ざっくり次の二つの仕組みやツールにより実現されているようです。

  • Ansible Runner のリモートジョブ実行機能
    • ansible-runner transmit で、指定されたプレイブックやコマンドライン引数を ZIP で固めて Base64 でエンコードし、標準出力に吐く
    • ansible-runner worker で、transmit から受け取ったデータを展開し、プレイブックを実行して、結果を標準出力に吐く
    • ansible-runner process で、worker から結果を受け取って、コールバック(画面出力やログの保存など)を実行する
  • Receptor
    • 複数のワーカ間でオーバレイネットワークを構成して、データストリームが授受できるようにする

Ansible Runner のリモートジョブ実行機能 は、ドキュメントにも例があるとおり、動作は気軽に確認できます。例えば、transmit を実行すると、標準出力に JSON で引数やエンコードされた ZIP ファイルが吐かれる動きが観察できます。

$ ansible-runner transmit runner -p demo.yml
{"kwargs": {..."playbook": "demo.yml", ..."container_image": "quay.io/ansible/ansible-runner:devel", ...}
{"zipfile": 2039}
UEsDBBQAAAAIAM9V...AE8BAACSBgAAAAA={"eof": true}

さらにこれにパイプで worker を加えると、プレイブックの実行結果の生データ(改行区切りの JSON)が流れてきます。

$ ansible-runner transmit runner -p demo.yml | ansible-runner worker
{"status": "starting", ...}
{"status": "running", ...}
...
{..., "stdout": "\r\nTASK [Gathering Facts] *********************************************************", ...}
{..., "stdout": "", ...}
...

大事なのは、worker はオリジナルのファイルには触れることなくプレイブックを実行 しているということです。オリジナルのファイルを読んだのは transmit だけ で、worker との間はただの標準入出力のデータのやりとりです。

さらにこれをパイプして process で終端すると、見慣れたいつもの出力になります。

$ ansible-runner transmit runner -p demo.yml | ansible-runner worker | ansible-runner process runner
...
TASK [Gathering Facts] *********************************************************
...

AWX でのジョブ実行時も、AWX のインスタンス側とジョブを実行する実際の Pod(Execution Environment)側との間で、ansible-runner 同士のプレイブック一式や結果の授受が行われます。つまり大枠は、

  • AWX のインスタンス側でオリジナルのプレイブックを取得(Sync)して、ansible-runner transmit(実際はこれに相当する API)を実行(プレイブック一式を ZIP 化してパラメータとともに配信)し
  • 新しく作られたジョブ用の Pod 側で、ansible-runner worker がインスタンス側の transmit からプレイブック一式とパラメータを受け取り、Pod 上に展開して実行し
  • worker の実行結果は AWX のインスタンス側の ansible-runner process(実際は API)が受け取る
  • AWX のインスタンスとジョブ用の Pod の間のデータは、Receptor のネットワークで流す

な動きで実現されていることになりそうです。実際、前述の Pod の定義の args からは、ansible-runner にサブコマンド worker が渡されていることが観察できます。Pod で動く worker はオリジナルのファイルを直接読む必要がないので、ボリュームマウントもされていない(実行の都度 transmit から受け取っているだけ)ということですね。

Container Group による Pod のカスタマイズ

ジョブ用の Pod の定義は、Container Group でカスタマイズできます。Container Group はジョブ用の Pod の動作環境を定義するもので、特に意識しなくてもジョブの実行時にはデフォルトの Container Group である default が透過的に利用されています。

Container Group は、ユーザが任意で追加できます。Pod 用のマニフェストを直接編集 できるほか、他の Kubernetes や OpenShift のクラスタの認証情報も渡せます。利用する Container Group は ジョブテンプレート単位で指定 できるので、うまく使うと、

  • データを永続化する
    • connection: local で完結できるプレイブックで、処理したデータを永続ボリューム上に永続化する
  • Pod のスケジューリングを制御する
    • nodeSelectoraffinity などを指定して、Pod を特定のノードで起動させる
  • Pod のリソースを制限する
    • resourceslimitsrequests を指定して、CPU やメモリなどの消費を制限する
    • 別の namespace で動作するようにして、ResourceQuota で制限する
  • Pod の動作をモニタリングする
    • 別の namespace で動作させたり、任意の labels を追加したりして、モニタリングのクエリやフィルタに使う
  • ジョブの処理を別のクラスタにオフロードする
    • ジョブ用の Pod を外部のクラスタに作成させ、処理をオフロードする

などなど、いろいろできそうです。

準備

動作をざっくり確認したいので、まずは準備です。

今回は、AWX が動作しているネームスペース awx とは別に新しいネームスペース ee-demo を作って、PVC demo-clam も作成しました。PVC には PV demo-volume が割り当てられていて、実体には hostPath/data/demo を指定しています。

$ kubectl get ns ee-demo
NAME      STATUS   AGE
ee-demo   Active   4m19s

$ kubectl -n ee-demo get pvc
NAME         STATUS   VOLUME        CAPACITY   ACCESS MODES   STORAGECLASS   AGE
demo-claim   Bound    demo-volume   5Gi        RWO            demo-volume    4m26s

また、この環境がシングルノードなので実際には無意味ですが、nodeSelector の定義が活きることも確認したいので、ノードにラベル awx-node-type=demo も付与しています。

$ kubectl label nodes kuro-awx01.kuro.lab awx-node-type=demo

$ kubectl get nodes --show-labels
NAME                  STATUS   ROLES                  AGE    VERSION        LABELS
kuro-awx01.kuro.lab   Ready    control-plane,master   3d7h   v1.21.2+k3s1   awx-node-type=demo,...

ネームスペース周りも試したいので、AWX が Pod の実行時に利用するサービスアカウント awx が、新しいネームスペース ee-demo も触れるようにしました。ここでは、雑な方法ですが、awx 用に定義されているロールとロールバインディングを、ほぼそのまま新しいネームスペース ee-demo 用に流用して作成しています。kubectl get -o json して jq で整形して kubectl create -f です。

$ kubectl -n awx get role awx -o json | jq '.metadata.namespace="ee-demo" | del(.metadata.ownerReferences)' | kubectl create -f -

$ kubectl -n ee-demo get role
NAME   CREATED AT
awx    2021-07-21T15:59:45Z

$ kubectl -n awx get rolebinding awx -o json | jq '.metadata.namespace="ee-demo" | del(.metadata.ownerReferences) | .subjects[0].namespace="awx"' | kubectl create -f -

$ kubectl -n ee-demo describe rolebinding awx
Name:         awx
Labels:       <none>
Annotations:  <none>
Role:
  Kind:  Role
  Name:  awx
Subjects:
  Kind            Name  Namespace
  ----            ----  ---------
  ServiceAccount  awx   awx

Container Group の作成

準備ができたら実践です。Container Group は、メニュの Administration > Instance Group から作成できます。

作成画面の Customize pod specification にチェックを入れると、Pod のマニフェストを編集できるようになるので、今回は、次の点を構成しました。

  • ネームスペースを ee-demo に変更
  • ラベル app: ee-demo-pod を追加
  • CPU とメモリの requestslimits を追加
  • ボリュームの /etc/demo へのマウントを追加
  • 動作ノードとして awx-node-type: demo を指定

具体的には、以下のマニフェストを指定しています。

apiVersion: v1
kind: Pod
metadata:
  namespace: ee-demo
  labels:
    app: ee-demo-pod
spec:
  containers:
    - image: 'quay.io/ansible/awx-ee:0.5.0'
      name: worker
      args:
        - ansible-runner
        - worker
        - '--private-data-dir=/runner'
      resources:
        requests:
          cpu: 500m
          memory: 100Mi
        limits:
          cpu: 1000m
          memory: 200Mi
      volumeMounts:
        - name: demo-volume
          mountPath: /etc/demo
  nodeSelector:
    awx-node-type: demo
  volumes:
    - name: demo-volume
      persistentVolumeClaim:
        claimName: demo-claim

image は変えてもよいですが、プロジェクトやジョブテンプレートの Execution Environment を指定するとオーバライドされるので、ここではデフォルトのままにしています。

なお、この画面の Credential には、タイプが OpenShift or Kubernetes API Bearer Token の認証情報を追加できます。今回は空欄にしていますが、外部のクラスタにジョブ用の Pod を作成させたい場合は、ここで指定すると機能するようです(試していません)。

ジョブの実行と結果の確認

ジョブテンプレートの Instance Group 欄で、利用する Container Group を指定できます。

設定を変更してジョブを実行すると、Container Group で定義した通り、ネームスペース ee-demo に Pod が作成されました。

$ kubectl -n ee-demo get pod
NAME                      READY   STATUS    RESTARTS   AGE
automation-job-50-qsjbp   1/1     Running   0          17s

定義を確認すると、Container Group に含めたもろもろがきちんと反映されていることがわかります。

$ kubectl -n ee-demo get pod automation-job-50-qsjbp -o yaml
...
metadata:
  ...
  labels:
    ...
    app: ee-demo-pod
...
spec:
  containers:
    ...
    image: registry.example.com/ansible/ee:2.10-custom
    ...
    resources:
      limits:
        cpu: "1"
        memory: 200Mi
      requests:
        cpu: 500m
        memory: 100Mi
    ...
    volumeMounts:
    - mountPath: /etc/demo
      name: demo-volume
    ...
  nodeSelector:
    awx-node-type: demo
  ...
  volumes:
  - name: demo-volume
    persistentVolumeClaim:
      claimName: demo-claim
  ...

Pod の中で /etc/demo 下にファイルを作成させると、実体の PV 内(今回は hostPath/data/demo)でもファイルが確認できました。ジョブが終了、つまり Pod が停止しても、ファイルが残る状態ができています。

$ kubectl -n ee-demo exec -it automation-job-50-qsjbp -- touch /etc/demo/test

$ ls -l /data/demo
total 0
-rw-r--r--. 1 root root 0 Jul 21 12:17 test

楽しいですね。

補足: 事前準備の作業内容

事前準備として紹介した以下のそれぞれを用意する作業のもうちょっと踏み込んだ紹介です。

  • Execution Environment
  • プライベートコンテナレジストリ
  • プライベート Git リポジトリ
  • プレイブック(プライベート Git リポジトリ上)

プライベートコンテナレジストリの用意

プライベートコンテナレジストリとして、本来は Private Automation Hub(Galaxy NG)を立てたいところですが、今回はもっと気軽に Docker が提供している registry で代替しています。素の状態では認証なしかつ HTTP での利用になるため、今回は、次の構成にしました。

  • ホスト名は registry.example.com
  • Kubernetes の Ingress で HTTPS を終端(自己署名証明書を利用)
  • アクセスには htpasswd ベースの認証が必要
  • ストレージは PVC で永続化

具体的な構築手順は割愛しますが、デプロイに必要なマニフェスト群と具体的な手順は、GitHub に配置 しています。

なお、紹介した通り、Execution Environment は、AWX 経由で実行すると Kubernetes の Pod として実行されます。つまり、コンテナレジストリに実際にアクセスしてイメージをプルするのは Kubernetes です。

したがって、イメージのプルに認証が必要な場合は、その認証を Kubernetes 側で行えるようにする必要があるわけですが、AWX 側でレジストリの Credential を作って Execution Environment の設定画面で指定しておくと、あとは勝手にやってくれます。具体的には、その Credential をもとに AWX によって Kubernetes 側(の Execution Environment が起動するネームスペース)に .docerconfigjson を含むシークレットが作成され、Pod に imagePullSecrets として追加されます。

ただし、レジストリのエンドポイントが自己署名証明書の HTTPS の場合は、SSL の検証を無効にする必要があり、この目的で、前述の手順の末尾では、/etc/rancher/k3s/registries.yaml を編集しています。

最終的には以下の状態になっています。

$ sudo /usr/local/bin/crictl info | jq .config.registry.configs
{
  "registry.example.com": {
    "tls": {
      "insecure_skip_verify": true,
      ...

自製 Execution Environment の用意

コンテナレジストリが用意できて動作が確認できたら、利用したい Execution Environment をビルドしてプッシュします。具体的な手順は 前回のエントリ と完全に重複するので、まるっと割愛します。必要な資材と手順は GitHub に配置 しています。

今回は、ベースイメージとして quay.io/ansible/ansible-runnerstable-2.10-develstable-2.9-devel を利用し、次の二つの自製 Execution Environment をビルドしてコンテナレジストリに配置しました。

$ docker image ls
REPOSITORY                              TAG                 IMAGE ID       CREATED        SIZE
registry.example.com/ansible/ee         2.10-custom         6fb343319a80   24 hours ago   740MB
registry.example.com/ansible/ee         2.9-custom          050cf7076379   25 hours ago   871MB
$ reg tags -k registry.example.com/ansible/ee
2.10-custom
2.9-custom

reg コマンドは、コンテナレジストリのコマンドラインクライアント です。前述の コンテナレジストリの構築手順中 に登場しています。今回利用したコンテナレジストリ registry は Web GUI や CLI がないため、プッシュされたことの確認にこの reg を使っています。気軽に使えて便利です。

プライベート Git リポジトリの用意

AWX で SCM をプロジェクトのソースにできるように、Git リポジトリを用意します。GitHub や Backlog などのプライベートリポジトリでももちろん構いませんが、今回は、コンテナレジストリ同様、インタネット上に配置したくない場合を想定して、プライベート Git リポジトリとして Gitea を K3s 上に用意しています。必要な資材と手順は GitHub に配置 しています。

今回は、次の構成で用意しました。

  • ホスト名は git.example.com
  • Kubernetes の Ingress で HTTPS を終端(自己署名証明書を利用)
  • ストレージは PVC で永続化
  • RDBMS は SQLite3

用意が面倒であれば、さんざん紹介している GitHub のリポジトリ kurokobo/awx-on-k3s をそのまま SCM として突っ込んでも大丈夫です。

プレイブックの用意

最後に、AWX から Execution Environment で動かしたいプレイブックを用意します。

この目的では、前回のエントリ で Ansible Runner の動作確認に使ったプレイブックが流用できるので、今回はこのエントリで使っている GitHub のリポジトリ kurokobo/awx-on-k3s の中身を丸ごとそのまま、Gitea 上に作成した gitea/ee-demo リポジトリにプッシュしました。

これも用意が面倒であれば、さんざん紹介している GitHub のリポジトリ kurokobo/awx-on-k3s をそのまま使っても大丈夫です。

Pod からの名前解決の確認

DNS が構成済み(この例では上流で *.example.com を解決できる)の場合は特に気にしなくてよいですが、/etc/hosts でがんばっている場合は、AWX、つまり K3s の Pod の中 から K3s ホストの /etc/hosts を使った名前解決 ができる必要があります。例えば、AWX に SCM として git.example.com のリポジトリを追加しても、名前解決ができなければ当然 Sync ができません。

この対策の簡単な実装例として、GitHub に dnsmasq と K3s 用の resolv.conf を使った設定例 を載せています。最終的には、次のように Pod の中から *.example.com の名前解決ができる必要があります。

$ cat /etc/hosts
...
192.168.0.100 awx.example.com
192.168.0.100 registry.example.com
192.168.0.100 git.example.com

$ kubectl run -it --rm --restart=Never busybox --image=busybox:1.28 -- nslookup git.example.com
Server:    10.43.0.10
Address 1: 10.43.0.10 kube-dns.kube-system.svc.cluster.local

Name:      git.example.com
Address 1: 192.168.0.100
pod "busybox" deleted

おわりに

AWX 上で自前の Execution Environment が利用できる状態を構成して、実際に動きを確認しました。また、ジョブを実行する Pod を Container Group でカスタマイズできることも併せて確認しました。

AWX の画面からは、かつて存在していた Python の仮想環境に関する設定が消えExecution Environment に置き換えられている ことも見て取れます。大きなアーキテクチャの変更であり、ユースケースによっては従来通りの使い方ができなくて困る場合も出てくるかもしれませんが、どちらかといえば新しいアーキテクチャに合わせて使い方自体を変えていく方が理想なのだろうとは思います。

個人的には、Kubernetes 上での動作も含め、Ansible のコンテナ化はとてもうれしい流れです。もりもり使っていきたいですね。

@kurokobo

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

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です