[Linux] Ansibleを使ったHinemos_Agentのデプロイメント

LC4RIを学んでいく中で

LC4RIをこれまでナンボか取り上げてきたんですが、Jupyter Notebook(NIIカスタマイズ版)とは別に、構成管理ツールであるAnsibleも必要になってきますとのこと。Ansibleは名前は聞くし、必要性は認識してるし、実際一度触ってみたことがあるものの、どうしても理解に至らずにそのまま放置プレイしている状況が有りました。

当時すでにAnsibleサーバは破棄してるし、それならばということで、一先ずAnsbleサーバの再構築からやりなおし、Playbookを書くところまでなんとか漕ぎ着けてみようと思うのでした。

やりたい事

過去に記事を書いて、コレを参考にしながら今までやってたのだけど、微妙にめんどくさいなと感じてたHinemos AgentのインストールをAnsibleで楽にやれるようになることを目標にします。ざっくりした構成はこんな感じ。

Ansibleサーバから集合NFSストレージに接続した状態で、NFSサーバ上には必要なパッケージとなるhinemos_agentとsnmpd.confを配置しときます。

AnsibleサーバにはPlaybookが配置されており、このPlaybookを実行すると、出来たてサーバとして指定されたものに対して、Hinemos Agentが自動で導入され、なおかつエージェントが起動してくるというもの。

Ansibleのインストール

Ansibleのインストールそのものは、当方環境CentOS7ですがyumを使えば簡単にインストールできます。EPELリポジトリを有効にし、ansibleパッケージをインストールする感じになります。

# yum -y install epel-release
# yum -y install ansible

インベントリの設定(ansible-hostsの設定)

次に、インベントリを定義し、対象となるグループ名・対象となるIPアドレス(本当は名前解決できるようにしてFQDNで入れるのが良いらしい)を設定します。

今回は、Ansibleサーバ自身にHinemos Agentが入ってないので、それをインストール対象にしました。

# vi /etc/ansible/hosts
----- 以下設定を入力
[newcommers]
192.168.100.147
-----

Playbookの考え方

Playbookですが、どうやら普通連想しそうな「設定手順」的な書き方ではなく、「冪等性」に基づく設定記入が必要なようです。冪等性とは「ある操作を1回行っても複数回行っても結果が同じであることをいう概念」とのことで、このPlaybookを何度実行しても対象は一つの求められた状態に一度状態が変わった後は変更されない・・・と言うようになるようです。

つまりは、これは個人的な解釈ですが、Playbookに設定するのは「そのサーバのあるべき姿」であり、

  • Ansibleはそのサーバのあるべき姿と現状があっているかを精査
  • あっていれば何もしない
  • あってなければあるべき姿にするために何らかの手段を講じる

と言うかたちで「あるべき姿に持っていく」と言うことをAnsibleが行っていくようです。

例えば、こんな処理があったりするんですが、

 - name: start hinemos_agent and enabled
   service: name=hinemos_agent enabled=yes state=started
  • nameは単なるコメントです
  • serviceと言うモジュールを使って、hinemos_agentの状態を確認
    • あるべき姿としては、Enable/Startedになっていること
    • もしDisableだったらEnableにする
    • もしstoppedだったらサービスをstartにする

と言う感じの内容になります。

全体の作りとしては

  • まず、全体設定としてhosts/user等を定義していく
  • その中でtasksを作り、配下にインデントしてタスクを積んでいく
  • 処理単位はハイフンで区切られている
  • <モジュール>:<パラメータ1> <パラメータ2> …と言うかたちで記載
    • 今回のPlaybookではyum/copy/shell/serviceあたりを使っている
    • 各モジュールの使い方はGoogleで調べると結構あっさり出てくるYO!

本当は、tasks以外にもhandlerと言うセクションがあったり、ディレクトリツリー配置の差異によってもっと色々出来るみたいなんですが、そこは引き続き別途勉強ということで。

実際に作ったPlaybook

こんな内容になっています。

---
- hosts: newcommers
  user: root
  tasks:
  - name: install via yum
    yum: name={{ item }} state=installed
    with_items:
    - java-1.8.0-openjdk
    - net-snmp
    - net-snmp-libs
    - tog-pegasus
    - sblim-wbemcli
    - sblim-cmpi-base
    - sblim-cmpi-fsvol
    - openlmi-storage
  - name: Copy Hinemos Agent from NFS
    copy:
      src: /nfs/hinemos_pkg/hinemos-6.0-agent-6.0.0-1.el.noarch.rpm
      dest: /root/
      mode: 644
  - name: install hinemos agent
    shell: HINEMOS_MANAGER=192.168.100.158 rpm -ivh /root/hinemos-6.0-agent-6.0.0-1.el.noarch.rpm
  - name: snmpd.conf copy
    copy:
      src: /nfs/hinemos_pkg/snmpd.conf
      dest: /etc/snmp/
      mode: 600
  - name: restart snmpd
    service: name=snmpd state=restarted
  - name: restart rsyslog
    service: name=rsyslog state=restarted
  - name: start hinemos_agent and enabled
    service: name=hinemos_agent enabled=yes state=started

処理の流れとしては過去の記事に記載していたものをそのままPlaybookに落とし込んでいて、ざっくり書くとこんな流れです。

  • 前提パッケージのインストール
  • NFS領域からパッケージのコピー
  • Hinemosエージェントのインストール
  • snmpd.confの上書き
  • snmpdの再起動
  • rsyslogの再起動
  • hienmos_agentの起動・自動起動有効化

HinemosエージェントはRPMパッケージですが、yumモジュールを使用することでインストールすることも可能です。ただ、今回は環境変数をきちんと与えた上でインストールをする必要があったため、敢えてshellモジュールを使ってインストール処理を書きました。

本来、冪等性を保つ必要が有ることから、コマンド等を実行することはあまり推奨されていません。すなわち、commandモジュールやshellモジュールは余り使うべきではない・・・ということのようです。

なので、RPMを単純に入れる場合は、yumモジュールを使用したほうが良いのだろうと思います。

ドライラン

ansible-playbookと言うコマンドでPlaybookを実行するわけですが、[-C]オプションを付与することで、ドライラン=テスト実行をすることができます。実行コマンドラインと実行結果を以下の通り記載します。

[root@Parvati ~]# ansible-playbook -C hinemos_agent_deploy.yml

PLAY [newcommers] ********************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************
ok: [192.168.100.147]

TASK [install via yum] ***************************************************************************************************
changed: [192.168.100.147] => (item=[u'java-1.8.0-openjdk', u'net-snmp', u'net-snmp-libs', u'tog-pegasus', u'sblim-wbemcli', u'sblim-cmpi-base', u'sblim-cmpi-fsvol', u'openlmi-storage'])

TASK [Copy Hinemos Agent from NFS] ***************************************************************************************
changed: [192.168.100.147]

TASK [install hinemos agent] *********************************************************************************************
skipping: [192.168.100.147]

TASK [snmpd.conf copy] ***************************************************************************************************
changed: [192.168.100.147]

TASK [restart snmpd] *****************************************************************************************************
changed: [192.168.100.147]

TASK [restart rsyslog] ***************************************************************************************************
changed: [192.168.100.147]

TASK [start hinemos_agent and enabled] ***********************************************************************************
changed: [192.168.100.147]

PLAY RECAP ***************************************************************************************************************
192.168.100.147 : ok=7 changed=6 unreachable=0 failed=0

結果が[OK]となっている箇所は、「変更を必要としなかった」と言うことを意味しており、[changed」となっている所は「変更が必要なので何らかの処理をした]ということを意味しています。

このケースではドライランのため、冪等性が保証されないshellモジュールで作った「install hinemos agent」部分は[skipping]と表示されており、そこについてはテスト結果の保証対象外となります。

また、実際には導入・変更を行わないため、パッケージ等のインストールもなされてはいません。

[root@Parvati ~]# service hinemos_agent status
Redirecting to /bin/systemctl status hinemos_agent.service
Unit hinemos_agent.service could not be found.

本実行

本実行はドライランのときに付与した[-C]を外すだけです。

[root@Parvati ~]# ansible-playbook hinemos_agent_deploy.yml

PLAY [newcommers] ********************************************************************************************************

TASK [Gathering Facts] ***************************************************************************************************
ok: [192.168.100.147]

TASK [install via yum] ***************************************************************************************************
changed: [192.168.100.147] => (item=[u'java-1.8.0-openjdk', u'net-snmp', u'net-snmp-libs', u'tog-pegasus', u'sblim-wbemcli', u'sblim-cmpi-base', u'sblim-cmpi-fsvol', u'openlmi-storage'])

TASK [Copy Hinemos Agent from NFS] ***************************************************************************************
changed: [192.168.100.147]

TASK [install hinemos agent] *********************************************************************************************
changed: [192.168.100.147]

TASK [snmpd.conf copy] ***************************************************************************************************
changed: [192.168.100.147]

TASK [restart snmpd] *****************************************************************************************************
changed: [192.168.100.147]

TASK [restart rsyslog] ***************************************************************************************************
changed: [192.168.100.147]

TASK [start hinemos_agent and enabled] ***********************************************************************************
changed: [192.168.100.147]

PLAY RECAP ***************************************************************************************************************
192.168.100.147 : ok=8 changed=7 unreachable=0 failed=0

ドライランのときと異なり、skippingステータスになっている箇所がありません。また、以下のようにコマンド実行すると、hinemos_agentが起動していることを確認できました。

[root@Parvati ~]# service hinemos_agent status
Hinemos Agent (PID 18783) is running...

加えて、hinemosのインストールログが出力されており、どうやらhinemos_agentが正常にインストールされているようであることも確認できました。

[root@Parvati ~]# cat install.log.hinemos_agent
Hinemos Manager IP: 192.168.100.158

Configuring files (hinemos_agent.cfg, Agent.properties, log4j.properties)...

Hinemos Agent will use the JRE shown below.
----------
openjdk version "1.8.0_161" OpenJDK Runtime Environment (build 1.8.0_161-b14) OpenJDK 64-Bit Server VM (build 25.161-b14, mixed mode)
----------
Please change hinemos_agent.cfg if you want to use a different JRE
[OK]

Createing configuration files...
[OK]
● rsyslog.service - System Logging Service
 Loaded: loaded (/usr/lib/systemd/system/rsyslog.service; enabled; vendor preset: enabled)
 Active: active (running) since 木 2018-02-01 11:33:18 JST; 4h 24min ago
 Docs: man:rsyslogd(8)
 
RSyslog Documentation
Main PID: 745 (rsyslogd) CGroup: /system.slice/rsyslog.service mq745 /usr/sbin/rsyslogd -n 2月 01 11:33:18 Parvati systemd[1]: Starting System Logging Service... 2月 01 11:33:18 Parvati rsyslogd[745]: [origin software="rsyslogd" swVersion="8.24.0" x-pid="745" x-info="http://www.rsyslog.com"] start 2月 01 11:33:18 Parvati systemd[1]: Started System Logging Service. Configuring file (net-snmp).../etc/snmp/snmpd.conf is changed. (appended "view systemview included .1.3.6.1") runlevel(2345) of snmpd service is enabled. Notice : Please edit the snmpd.conf settings to make OIDs below .1.3.6.1 is accessible, if changed from its default settings. Installation of Hinemos Agent is completed.

今後やろうかなとおもったことなど

取り敢えずこれがLC4RIとどう結びつくのかが知りたいのと、加えて、サーバ初期構築時の共通設定自動化をもう少し推し進めたいかなーと言うのはあります。特に公開鍵配布に関してはAnsibleだけではなく、Vulsでも必要となる作業なので、それを個別にあーだこーだするのは色々と面倒だよなぁというのが有ります。

Hinemosで同様のことをするのも簡単なのですが、Hinemosにあまり傾倒すると応用が聞かなくなってしまうような気もしますので、そこはうまく連携する仕組みを考えるほうが今後の広がり・ネタも発掘できて楽しいのかなーとおもったりしています。

余談

LC4RIですが、NIIカスタマイズモジュールを素のJupyter Notebookに導入しようとすると色々苦労しました。どうやらgithubのドキュメントと現在の作りに整合性が合わなくなっているようだとのことで、NII 長久さんからも「Docker版を使って欲しい」と言うお話をいただき、それに従っています。

Dockerイメージの作りを見ていると、Debian系を使っていらっしゃるようで、それが故なのかどうかがわからないんですが、あるはずのモジュールが見つからなかったり、で一部モジュールの実装ができないんですよね。

というわけで、Dockerイメージをそのまま使ってます。NIIクラウドチームとしても、このDockerイメージがそのまま使われてるとのことで、それならばーと実装してみたわけですが、これが中々機能拡張されまくっていて面白いです。

これはこれで記事を起こしてみようかなーとおもっています。現在色んな機能を評価中ですー。