とことんDevOps | 日本仮想化技術が提供するDevOps技術情報メディア

DevOpsに関連する技術情報を幅広く提供していきます。

日本仮想化技術がお届けするとことんDevOpsでは、DevOpsに関する技術情報や、日々のDevOps業務の中での検証結果など、DevOpsのお役立ち情報をお届けします。
主なテーマ: DevOps、CI/CD、アジャイル開発、コンテナ開発など

開催予定の勉強会

各種SNSのフォローもよろしくお願いいたします。

コンテナベースの実行環境 Ansible Navigatorを試す

試そうと思ったきっかけ

某所での話のやり取りで、Ansible Coreはどう動かすかという話になりました。 コンテナーで動かすと並列的に処理ができそうだとか、コンテナーで動かさずにマシンにAnsibleをインストールして動かすほうがシンプルだしわかりやすいといったような話をしました。

マシンにAnsibleをpipとかで入れると、Pythonモジュールがたくさん入ってその管理やメンテが大変(OSが必要とするモジュールとのバッティングによる影響)といった話の流れがありまして調べていた所、このブログに行き着きました。

rheb.hatenablog.com

ざっくりいうと、今回の内容はAnsibleの処理系をコンテナをうまく使って処理しようという話です。 コンテナはDockerとPodmanに対応しているようです。

Ansible Navigatorとはなにか

Ansible Navigatorは、インベントリ、プレイブック、コレクションなどの Ansible コンテンツを作成、レビュー、およびトラブルシューティングするためのコマンドベースのツールです。Red Hat Ansible Automation Platform 用のテキストベースのユーザーインターフェイス (TUI)としても動作するようです。

今回はAnsible NavigatorをLinux上で動かしていますが、macOSとWSL2を有効化したWindowsにも対応しています。 それでは早速動かしてみましょう。

動作確認環境

手元では、以下のOS構成で動作確認しています。

  • Fedora 36

    • DockerおよびPodman
    • Python 3.10.4
    • pipでインストールしたansible-navigator 2.1.0
  • Red Hat Enterprise Linux 8.6

    • Podman
    • Python 3.9.7
    • ansible-navigator-2.1.0-1.el8ap.noarch (repo: ansible-automation-platform-2.2-for-rhel-8-x86_64-rpm)

pipを使ったインストールは、Python3.8以降のバージョンがインストールされていれば他のディストリビューションでも動くのではないかと思います。今回は時間の都合で試せていません。

コンテナランタイムのインストール

ランタイムはDockerとPodmanをサポートしているようです。 試しに同じようにDockerを使ってみた所、SELinuxをenforcingモードのまま実行することができませんでした。

この方法を使うと、ホスト上に用意したインベントリファイルとPlaybookを使って、Ansible Navigatorが設定通り 任意のランタイムを使ってコンテナーを実行し、Ansible Core(AnsibleとAnsible Playbook)の機能を使ってコンテナーから命令を出してその結果をAnsible Navigatorホストにログとして残すという動きをします。実行されたコンテナは処理が終わってログを吐き出すと、コンテナは終了します。

FedoraではDockerとPodmanのパッケージが標準で用意されています(パッケージ名はディストリビューションによる)。Dockerに関してはコミュニティ版Docker Engine(旧称Docker CE)をインストールする方法もあります。若干の初期設定が異なるものもありますが、同じように動作します。

$ sudo dnf install moby-engine
$ sudo systemctl enable --now docker

or

$ sudo dnf install podman

私のおすすめはPodmanです。 APIを使った制御はしないので、Podmanのサービスの実行はここでは不要です。

ファイルとディレクトリ構成など

ディレクトリーを作って、ファイル一式をまとめます。 わざわざtouchコマンドを使ってファイルを作っていますが、特に必要はありません(ファイルとディレクトリー構成を見てほしかったので、あえてそうしました)。

$ mkdir ansiblenavi
$ cd ansiblenavi

$ touch ansible-navigator.yml
$ mkdir inventory
$ touch inventory/hosts
$ mkdir playbook
$ touch playbook/test.yml

$ tree
.
├── ansible-navigator.yml
├── inventory
│   └── hosts
└── playbook
    └── test.yml

ansible-navigator.ymlの内容

ほぼ参考サイトのままです。 そのまま過ぎても面白くないので、本記事ではPodmanを使うことにしました。

---
ansible-navigator:
  ansible:
    inventory:
      help: False
      entries:
        - ./inventory/hosts
    playbook:
      help: False
      path: ./playbook/test.yml
  execution-environment:
    container-engine: podman
    enabled: true
    image: quay.io/ansible/ansible-runner:stable-2.12-devel
    pull:
      policy: missing
  logging:
    append: true
    file: ./logs/ansible-navigator.log
    level: debug
  mode: stdout
  playbook-artifact:
    enable: true
    replay: ./logs/artifact/replay.json
    save-as: ./logs/artifact/replay.json

インベントリファイル - inventory/hosts

とりあえず、ssh接続が可能なサーバーを用意します。書き方はAnsibleのインベントリファイルの書き方と一緒です。 デフォルトと異なる名前の秘密鍵を認証に使う場合はansible_ssh_private_key_fileで指定します。

手元ではMicrostackを使ってインスタンスを作り、それぞれAnsible Navigator用とAnsibleによって処理されるノードとしました。

[linux]
172.16.214.188

[linux:vars]
ansible_user=fedora

Playbook - playbook/test.yml

とりあえず、まずはPingを実行するPlaybookを作ってみます。

---
- hosts: all
  gather_facts: false

  tasks:
    - ping:

Ansible Navigatorのインストール

Ansible Navigatorのインストールは、公式のセットアップ手順に従って行います。

sudo dnf install python3-pip
pip3 install --user ansible-navigator

echo 'export PATH=$HOME/.local/bin:$PATH' >> ~/.profile
source ~/.profile

RHEL 8以降にはパッケージが専用のリポジトリーに用意されているので、次のようにインストールします(09/09/2022現在)。依存するPython関係やPodmanが自動で選択されて、一緒にインストールされます。

sudo subscription-manager repos --enable ansible-automation-platform-2.2-for-rhel-8-x86_64-rpms
sudo dnf install ansible-navigator

SELinuxの設定

ランタイムとして「Docker」を設定した場合は、実行前にsudo setenforce 0を実行して、処理が終わったらsudo setenforce 1を実行します。永続的に設定する場合は/etc/selinux/configを設定します。

ランタイムとして「Podman」を設定した場合は、特に設定変更する必要はありません。安全のためにもenforcingモードのまま運用しましょう。

Ansible Navigatorの実行

実行すると、指定したコンテナエンジンでコンテナイメージをダウンロードしたあとにAnsible Playbookによる処理が実行されます。

$ ansible-navigator run 
-----------------------------------------------------------------------------------
Execution environment image and pull policy overview
-----------------------------------------------------------------------------------
Execution environment image name:  quay.io/ansible/ansible-runner:stable-2.12-devel
Execution environment image tag:   stable-2.12-devel
Execution environment pull policy: missing
Execution environment pull needed: True
-----------------------------------------------------------------------------------
Updating the execution environment
-----------------------------------------------------------------------------------
stable-2.12-devel: Pulling from ansible/ansible-runner
a1d0c7532777: Pull complete
0051e33d76d8: Pull complete
3fb241a85b00: Pull complete
014e39b4ae38: Pull complete
442efd345444: Pull complete
79831b585400: Pull complete
27b3a0cd32c9: Pull complete
a0432b3d84b6: Pull complete
93e0336932fc: Pull complete
44e3598950f0: Pull complete
fc120b105d20: Pull complete
25df1b0a7e8d: Pull complete
b1cb03d0f630: Pull complete
324f5147ca8f: Pull complete
Digest: sha256:2c44521150e5f260a85ee99fee4f3a5e41216510c9f408d6e2a64df9eb9064ab
Status: Downloaded newer image for quay.io/ansible/ansible-runner:stable-2.12-devel
quay.io/ansible/ansible-runner:stable-2.12-devel

PLAY [all] *********************************************************************


TASK [ping] ********************************************************************
ok: [172.16.214.188]

PLAY RECAP *********************************************************************
172.16.214.188             : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0 

ログの方にも、ジョブが成功したような記録が残っていました。

{
    "plays": [
        {
            "__play_name": "all",
            "name": "all",
            "pattern": "all",
            "play": "all",
            "play_pattern": "all",
            "play_uuid": "06cbe0db-ae23-d7d9-6a2c-000000000006",
            "playbook": "/home/fedora/ansiblenavi/playbook/test.yml",
            "playbook_uuid": "f91759cb-d5bc-4df3-912b-e595b9ee6c16",
            "tasks": [
                {
                    "__changed": false,
                    "__duration": "1s",
                    "__host": "172.16.214.188",
                    "__number": 0,
                    "__result": "Ok",
                    "__task": "ping",
                    "__task_action": "ping",
...
    "status": "successful",
    "status_color": 10,
    "stdout": [
        "",
        "PLAY [all] *********************************************************************",
        "",
        "TASK [ping] ********************************************************************",
        "\u001b[0;32mok: [172.16.214.188]\u001b[0m",
        "",
        "PLAY RECAP *********************************************************************",
        "\u001b[0;32m172.16.214.188\u001b[0m             : \u001b[0;32mok=1   \u001b[0m changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   "
    ],
    "version": "2.0.0"
}

というわけで、特に苦労することなくすんなり動かすことができました。 参考にしたサイトでは、Ansibleの実行環境をansible-builderを使ってカスタマイズする方法も書かれていました。そちらについても今後検証してみたいと思います。

情報源