Howto

Ansibleでリモート管理

このHowtoでは、構成管理ツール Ansible を用いたArmadilloの制御方法を紹介します。

概要

Ansibleは、レッドハット社が開発するオープンソース構成管理ツールです。
AnsibleをインストールしたAnsibleサーバーから、複数のホストを制御することが可能です。

Ansibleの特徴は以下の通りです。

  • シンプル
    Ansibleでは2つのテキストファイルを使用します。
    制御対象ホストを定義するinventoryと、制御内容を定義するPlaybookです。
  • エージェントレス
    ホストに、sshとpython(バージョン2.4以上)がインストールされていれば動作可能です。
    Ansibleを動作させる為に、ホストにAnsible用アプリケーションをインストールする必要はありません。

事前準備

本Howtoでは、AnsibleサーバーにATDEを、ホストにArmadillo-IoT G3 M1を使用します。

Ansibleサーバーの準備

Ansibleのインストール

AnsibleサーバーにAnsibleをインストールします。

以下のコマンドを入力するとAnsibleをインストールできます1

[ATDE ~]$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 93C4A3FD7BB9C367
[ATDE ~]$ sudo apt update
[ATDE ~]$ sudo apt install ansible

ホストの準備

ホストにsshでログイン出来るようにします。
製品マニュアルを参照し(Armadillo-IoT G3であれば22.5. sshでArmadillo-IoT G3に接続する)、sshでの接続ができるように設定してください。2

また、本Howtoではatmarkユーザーアカウントでsshログインし、sudoコマンドを使用して操作を行います。
Armadillo-IoT G3のatmarkユーザーは、初期設定ではsudoコマンドを実行できませんので、 Armadillo-IoT G3: atmarkユーザーでsudoコマンドを実行できるようにする を参照して、atmarkユーザーでsudoコマンドを実行できるようにしてください。

ansibleコマンドで死活監視

Playbookを使用しないで、複数ホストを制御します。
ホストにuptimeコマンドを実行させることで死活監視を行います。

/etc/ansible/hostsにホストのIPアドレスを記載します。名前解決が可能な環境であればホスト名も使用可能です。

/etc/ansible/hosts

192.168.0.2
192.168.0.3

実行コマンド例は以下の通りです。
第1引数のallで/etc/ansible/hostsに記載されている全ホストを対象とし、
-mオプションで実行モジュールを指定、-aオプションでモジュールに対する引数(ここでは実行するコマンド)を指定します。

[ATDE ~]$ ansible all -m command -a "uptime"

ホストにsshログイン時パスワード入力が必要な場合は、-kオプションを付与します。

[ATDE ~]$ ansible all -m command -a "uptime" -k

結果

192.168.0.2 | CHANGED | rc=0 >>
 11:08:42 up 8 min,  2 users,  load average: 0.00, 0.05, 0.05
 
192.168.0.3 | CHANGED | rc=0 >>
 11:08:43 up 21 min,  2 user,  load average: 0.00, 0.02, 0.03

InventoryとPlaybookを使用した構成管理

Inventoryにホストを、Playbookに制御内容を記載し構成管理を行う例を示します。
Playbookを適用する場合、ansible-playbookコマンドを使用します。

ansible-playbookコマンドの主なオプションは以下の通りです。

オプション 説明
-i inventory指定(存在しない場合は/etc/ansible/hostsを適用)
-k sshログイン時にパスワードを入力する
--ask-become-pass sudoコマンド用のパスワードを入力する

Playbookの概要

後程使用しますu-bootとカーネル更新用Playbookの一部を引用し、概要を説明します。

Playbook

---
- hosts: g3m1                   # ホストグループを指定
  become: yes                   # スーパーユーザーとして動作する
  vars:
    uboot_name: u-boot-x1-{{ u_boot_version }}.bin    # このファイル内の変数定義
  tasks:
    - name: copy u-boot file    # u-bootのファイルを制御対処ホストへコピー
      copy:
        src: ./{{ uboot_name }}
        dest: /home/atmark/{{ uboot_name }}
:後略

Playbookは yaml形式 で記載します。各アトリビュートの概要は以下の通りです。

  • hosts: ホストを指定します。
  • vars: このPlaybook内で使用する内部変数を定義します。
  • tasks: 処理内容を並べます。
  • copy: などの実行命令をモジュールと呼びます。詳細は モジュール定義 を参照ください。
  • name: copy:の上部に存在するname:アトリビュートがPlaybook実行時にサーバーの端末に表示されます。これにより、どのモジュールが成功・失敗したかがわかります。
[ATDE ~]$ ansible-playbook -i inventory playbook_~
PLAY [g3m1] ************************************************************************************************************
: 略
TASK [copy u-boot file] ************************************************************************************************
changed: [192.168.0.2]
: 略

Inventoryの概要

Inventoryには、ホストの一覧とグループを記載します。 本Howtoでは、グループ[g3m1]がArmadillo-IoT G3M1、グループ[x1]がArmadillo-IoT X1を想定しています。
コマンドオプション-iでInventoryファイルを指定し、Playbook内のhostsで制御対象を切り替えることができます。
Inventoryファイルを指定しない場合は、/etc/ansible/hostsの内容が適用されます。
Inventoryファイルに記載されている全てのホストを制御したい場合、Playbook内でhosts: allを指定します。

inventory

[g3m1]
192.168.0.2
192.168.0.3
 
[x1]
192.168.0.4
192.168.2.5

inventoryファイルと以下に示すPlaybookは、本Howtoでは同じディレクトリに配置します。

インターネットからファイルをダウンロードしホストに配置する

インターネット上のファイルをホストのホームディレクトリへ配置するPlaybookです。
get_urlモジュールを使用することでファイルのダウンロードが可能です。
URLが実在しないものになっていますので、運用に合わせて変更してください。

playbook_wget.yml

---
- hosts: g3m1
  tasks:
    - name: download file
      get_url:
        url: https://--------/--------
        dest: ~/.

実行コマンドは以下の通りです。

[ATDE ~]$ ansible-playbook -i inventory playbook_wget.yml

u-bootとカーネルイメージを更新し再起動する

Armadilloのu-bootとカーネルイメージを更新し、Armadilloを再起動するPlaybookの例です。
事前にu-bootとカーネルイメージを作業ディレクトリーにダウンロードしてください。

変数u_boot_versionとuimage_versionの値はコマンドラインの引数で指定します。

playbook_update_uimage.yml

---
- hosts: g3m1                   # ホストグループを指定
  become: yes                   # スーパーユーザーとして動作する
  vars:
    uboot_name: u-boot-x1-{{ u_boot_version }}.bin  # このファイル内の変数定義
  tasks:
    - name: copy u-boot file    # u-bootのファイルを制御対処ホストへコピー
      copy:
        src: ./{{ uboot_name }}
        dest: /home/atmark/{{ uboot_name }}
    - name: update u-boot       # u-bootのインストールを実施
      shell: x1-bootloader-install {{ uboot_name }}
    - name: erase file          # 使用したファイルを削除
      file:
        path: /home/atmark/{{ uboot_name }}
        state: absent
    - name: mount               # カーネル更新用にマウント
      shell: mount -t vfat /dev/mmcblk2p1 /mnt
      args:
        warn: no                # mountモジュールを使うようにとwarningが出力されますので抑制します。
#     mount:
#       path: /mnt
#       src: /dev/mmcblk2p1
#       fstype: vfat
#       state: mounted
#       boot: false
    - name: copy kernel file    # カーネルイメージファイルをコピー
      copy:
        src: ./uImage-x1-{{ uimage_version }}
        dest: /mnt/uImage
        owner: root
        group: root
    - name: umount              # アンマウント
      shell: umount /mnt
#     mount:
#       path: /mnt
#       state: unmounted
    - name: do sync             # sync実行
      shell: sync
    - name: reboot              # 再起動
      shell: reboot
      async: 1                  # 非同期実行(一旦sshのコネクションが切れるが、それをエラーとしない為の対処)
      poll: 0                   # 非同期実行時にshellモジュールの戻りを待たない(同上)
    - name: wait for reboot     # 再起動後のssh再接続待ち
      wait_for_connection:
        delay: 20               # reboot後20秒後から確認実施
        timeout: 300            # 確認タイムアウトは5分
    - name: check connection    # 導通チェック
      ping:
  • マウント、アンマウントに関してはAnsibleにmountモジュールが存在しますが、mountモジュールを使用すると/etc/fstabにマウントポイントを記載し、再起動してもマウント状態を永続化してしまう為、期待している一時的にマウントする動作にはなりません。その為、shellモジュールを使用しています。
  • #以降はコメントとして扱われます。

実行コマンド例は以下の通りです。
--extra-varsの内容がバージョンに応じて変化します。

[ATDE ~]$ ansible-playbook -i inventory playbook_update_uimage.yml --extra-vars "u_boot_version=at18 uimage_version=v4.9-at8" --ask-become-pass

lighttpdをインストールし再起動する

lighttpdをインストール、index.htmlを配置、debパッケージをインストール、lighttpdを再起動するPlaybookの例です。
debパッケージのURLが実在しないものになっていますので、運用に合わせて変更してください。

playbook_setup_lighttpd_and_deb.yml

---
- hosts: g3m1
  become: yes
  tasks:
    - name: apt install
      apt:
        name: lighttpd
        state: latest
        update_cache: yes
    - name: put the portal page
      template:
        src: index.html
        dest: /var/www/html/index.html
    - name: Install a .deb package from the internet.
      apt:
        deb: http://--------/--------.deb
    - name: restart lighttpd
      shell: /etc/init.d/lighttpd restart

実行コマンドは以下の通りです。

[ATDE ~]$ ansible-playbook -i inventory playbook_setup_lighttpd_and_deb.yml --ask-become-pass

  1. 参考URL https://docs.ansible.com/ansible/latest/installation_guide/intro_installation.html#latest-releases-via-apt-debian ↩︎

  2. sshのセキュリティーポリシー(パスワードでのログイン可否、rootログイン可否)は、開発・運用環境に応じて適切に設定してください。 ↩︎