0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

ansibleでコマンド引数が異なる複数マシンの構成を行う

Last updated at Posted at 2024-09-08

ansibleを使うと、1つのマシンから複数のマシンの構成を行うことができます。

構成するためのコマンドの引数が各マシンで異なる場合は、それを変数化して処理します。この記事では、IBM の Db2 の導入・構成を例に、そのやり方を説明します。

ポイント

  • マシンによらず固定値またはシェル・スクリプトで生成するような値は、ansible playbook(yamlファイル)に変数を定義することができます。
    • この記事の例では、
      • 導入時のログのファイル名にホスト名と日付を付与
      • DB接続に必要なDB名、ユーザーID、パスワードを変数化
  • マシンごとに異なる値を定義したい場合は、ホスト名のリストとともに変数を定義することができます(この記事の例では、inventories/hosts.iniファイルに定義)。
    • この記事の例では、
      • Db2サーバーとDb2クライアントで異なる導入定義ファイルを指定
      • Db2クライアントのマシンごとに、異なるDB接続先ホスト名、ポート番号を指定

シナリオ

この記事の例では、Db2サーバーは2つのマシンで構成され、それぞれ2つのノードで動作し、各マシンの1つ目のノードは50000ポート、2つ目のノードは50001ポートでDb2クライアントからのリクエストを受け付けます。

ansible_scenario.png

Db2クライアントとして4つのマシンからDb2サーバーにアクセスします。各クライアントからのアクセスは負荷分散するために、以下のDb2サーバーにアクセスするようにします。

Db2クライアント Db2サーバー接続先
host3 host1の50000ポート
host4 host1の50001ポート
host5 host2の50000ポート
host6 host2の50001ポート

この記事では、上記を実現するための構成の一部である「1. Db2の導入」と「2. Db2クライアントの接続構成」、およびDb2接続確認を行う「3. Db2クライアントからDb2接続」を説明します。

その前に、ansibleのセットアップと、ansibleのシンプルな実行例を述べます。

ansibleのセットアップ

ansibleの実行は、上記のうち1つのサーバーから実行するか、別のマシンから実行することができます。

実行するマシンにはansibleを導入し、構成するすべてのサーバーに対して、rootでパスワードレスでアクセスできるようにします。

ansibleの導入例 (Red Hat 9.2の場合)

# dnf install https://dl.fedoraproject.org/pub/epel/epel-release-latest-9.noarch.rpm -y
# yum install ansible -y

ansibleのシンプルな実行例

シンプルな例として、Db2が導入されているか確認するために、すべてのマシンに対してls /opt/ibm/db2を実行します。
まずは、inventories/hosts.iniファイルにマシンのリストを記述します。
(この例では、以下の3つのマシンに対して実行します)

inventories/hosts.ini
[db2hosts]
host1
host2
host3

実行する内容はansible playbookと呼ばれるyamlファイルに記載します。この例では、ファイル名をdb2_check.ymlとし、以下を記載します。

db2_check.yml
- name: db2 check
  hosts: all
  tasks:
    - name: ls /opt/ibm/db2
      shell:
        cmd: ls /opt/ibm/db2
      register: result
    - name: result
      debug:
        msg: "{{ result.stdout }}"

ansible_db2_check_yml.png

上記のansible playbookを実行するために、以下のコマンドを実行します。

# ansible-playbook -i inventories/hosts.ini db2_check.yml

結果として、以下のように出力されます。

PLAY [db2 check] ***********************************************************************************************************************************************

TASK [Gathering Facts] *****************************************************************************************************************************************
ok: [host2]
ok: [host3]
ok: [host1]

TASK [ls /opt/ibm/db2] *****************************************************************************************************************************************
fatal: [host3]: FAILED! => {"changed": true, "cmd": "ls /opt/ibm/db2", "delta": "0:00:00.011545", "end": "2024-09-08 19:23:04.972991", "msg": 
"non-zero return code", "rc": 2, "start": "2024-09-08 19:23:04.961446", "stderr": "ls: '/opt/ibm/db2' にアクセスできません: そのようなファイルやディレクトリは
ありません", "stderr_lines": ["ls: '/opt/ibm/db2' にアクセスできません: そのようなファイルやディレクトリはありません"], "stdout": "", "stdout_lines": []}
changed: [host1]
changed: [host2]

TASK [result] **************************************************************************************************************************************************
ok: [host1] => {
    "msg": "V11.5"
}
ok: [host2] => {
    "msg": "V11.5"
}

PLAY RECAP *****************************************************************************************************************************************************
host1     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
host2     : ok=3    changed=1    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0
host3     : ok=1    changed=0    unreachable=0    failed=1    skipped=0    rescued=0    ignored=0

上記出力から、host3には/opt/ibm/db2にDb2が導入されておらず、host1とhost2には少なくとも/opt/ibm/db2/V11.5ディレクトリまたはファイルが作成されていることがわかります。

シナリオの実行

以下の3つのansible playbookを作成・実行します。

1. Db2の導入

設計

すべてのマシンにDb2を導入します。
Db2サーバーの導入にはDb2サーバー用にパラメータ設定された db2server.rsp ファイルを指定して導入し、Db2クライアントの導入にはDb2クライアント用にパラメータ設定された db2client.rsp ファイルを指定して導入します。
Db2導入コマンドdb2setupファイルは、事前に、すべてのマシンにNFSマウントされた /download/db2 ディレクトリ下に置きます。
db2server.rspdb2client.rspファイルは、ansibleを実行するディレクトリに置き、ansible playbookで各マシンの/db2installディレクトリにコピーします。
Db2の導入ログを /log/db2_install_[ホスト名]_[YYYYMMDD].log ファイルに取得し、ansible playbook実行マシンの /log ディレクトリ下にコピーします。
Db2の導入コマンドは以下のようになります。

  • Db2サーバー
    • 実行ディレクトリ: /download/db2
    • 実行コマンド: ./db2setup -r /db2install/db2server.rsp -l "/log/db2_install_`hostname`_`date +%Y%m%d`.log"
  • Db2クライアント
    • 実行ディレクトリ: /download/db2
    • 実行コマンド: ./db2setup -r /db2install/db2client.rsp -l "/log/db2_install_`hostname`_`date +%Y%m%d`.log"

ansibleの構築

実行コマンドで、マシンごとに異なるパラメータは以下となります。

  1. Db2サーバーは db2server.rsp、Db2クライアントは db2client.rsp を指定する。
  2. すべてのマシンで、"/log/db2_install_`hostname`_`date +%Y%m%d`.log" を指定する。

1は導入するマシンで決まります。その場合、inventories/hosts.ini ファイルにその変数を記載することができます。

この例では、Db2サーバーとDb2クライアントで値が異なるので、以下のように、すべてのホストをその2つに分類します。

[db2server]
host1
host2
[db2client]
host3
host4
host5
host6

さらに、以下のように、上記に続けて変数を記載します。

[db2server:vars]
rsp_file=db2server.rsp
[db2client:vars]
rsp_file=db2client.rsp

この例では、rsp_fileが変数名になります。

2は、マシンによらずコマンドの実行結果を変数の値としてセットするものです。その場合、ansible playbook(yamlファイル)に以下のように記載します。

  tasks:
    - name: log name
      shell:
        cmd: echo "/log/db2_install_`hostname`_`date +%Y%m%d`.log"
      register: log_name

上記のlog_nameが変数名で、log_name.stdoutに標準出力の値がセットされます。

Db2の導入は、以下のように記載します。

    - name: db2 install
      shell:
        cmd: ./db2setup -r "/db2install/{{ rsp_file }}" -l "{{ log_name.stdout }}"
        chdir: /download/db2

Db2導入実行後のログファイルの取得は、以下のように記載します。

    - name: fetch log file
      fetch:
        src: "{{ log_name.stdout }}"
        dest: "/log/"
        flat: yes

flat:の値をyesにすると、dest:の値が/で終わっている場合、そのディレクトリ下にsrc:のファイルがコピーされます。

上記をまとめると、inventories/hosts.iniは、以下のようになります。

inventories/hosts.ini
[db2server]
host1
host2
[db2client]
host3
host4
host5
host6
[db2server:vars]
rsp_file=db2server.rsp
[db2client:vars]
rsp_file=db2client.rsp

ansible playbookは以下のようになります(この例では、ファイル名をdb2_install.ymlとします)。

db2_install.yml
- name: db2 install
  hosts: all
  tasks:
    - name: log name
      shell:
        cmd: echo "/log/db2_install_`hostname`_`date +%Y%m%d`.log"
      register: log_name
    - name: copy rsp file
      copy:
        src: "{{ rsp_file }}"
        dest: /db2install/
        owner: root
        group: root
        mode: 0644
    - name: db2 install
      shell:
        cmd: ./db2setup -r "/db2install/{{ rsp_file }}" -l "{{ log_name.stdout }}"
        chdir: /download/db2
    - name: fetch log file
      fetch:
        src: "{{ log_name.stdout }}"
        dest: "/log/"
        flat: yes

このansible playbookを実行するために、以下のコマンドを実行します。

# ansible-playbook -i inventories/hosts.ini db2_install.yml

2. Db2クライアントの接続構成

設計

Db2クライアントの接続構成は、Db2インスタンス・ユーザー(この記事ではdb2inst1ユーザーとします)で行います。
ansibleでリモート接続した後、ユーザーを切り替えるには以下のようにbecomebecome_userを指定します。

- name: db2client config
  hosts: db2client
  become: yes
  become_user: db2inst1

しかしながら、この方法でユーザーを切り替えると、ユーザーのプロファイルが実行されません (su - db2inst1ではなく、su db2inst1で切り替えられる)。結果として、Db2のコマンドの実行でエラーとなります。

そこで、上記の代わりに、各コマンドの実行で、su - db2inst1 -c コマンド で対応することとします。

ここで使用するコマンドは各マシンでパラメータが異なり、以下のようになります。

ホスト名 コマンド
host3 db2 catalog tcpip node db2svr remote host1 server 50000
host4 db2 catalog tcpip node db2svr remote host1 server 50001
host5 db2 catalog tcpip node db2svr remote host2 server 50000
host6 db2 catalog tcpip node db2svr remote host2 server 50001

上記でマシンごとの違いは、接続先のホスト名とポート番号になります。

Db2クライアント 接続先ホスト 接続先ポート
host3 host1 50000
host4 host1 50001
host5 host2 50000
host6 host2 50001

ansibleの構築

「1. Db2の導入」では、inventories/hosts.iniでdb2serverとdb2clientに分類しましたが、ここでは、以下のようにdb2clientをさらに分類し、個々のマシンに対して上記の変数を定義します。

inventories/hosts.ini
[db2server]
host1
host2
[db2client:children]
client1
client2
client3
client4
[db2server:vars]
rsp_file=db2server.rsp
[db2client:vars]
rsp_file=db2client.rsp
[client1]
host3
[client2]
host4
[client3]
host5
[client4]
host6
[client1:vars]
db2host=host1
db2port=50000
[client2:vars]
db2host=host1
db2port=50001
[client3:vars]
db2host=host2
db2port=50000
[client4:vars]
db2host=host2
db2port=50001

ansible_hosts_ini.png

ansible playbookは以下のようになります(この例では、ファイル名をdb2client_config.ymlとします)。

db2client_config.yml
- name: db2client config
  hosts: db2client
  tasks:
    - name: catalog node
      shell:
        cmd: su - db2inst1 -c 'db2 catalog tcpip node db2svr remote "{{ db2host }}" server "{{ db2port }}"'

実行するマシンはDb2クライアントのみですので、hosts: には db2client をセットします。

このansible playbookを実行するために、以下のコマンドを実行します。

# ansible-playbook -i inventories/hosts.ini db2client_config.yml

3. Db2クライアントからDb2接続

Db2クライアントからDb2サーバーに接続するためには、Db2のインスタンス・ユーザーから、以下のコマンドを実行します。

$ db2 connect to [DB名] user [ユーザー名] using [パスワード]

DB名、ユーザー名、パスワードを変数化する場合、ansible playbookは以下のようになり(ファイル名をdb2client_connect.ymlとします)、変数値はvars:に指定します。

db2client_connect.yml
- name: db2 connect
  hosts: db2client
  vars:
    dbname: "db1"
    user: "db2inst1"
    pwd: "password"
  tasks:
    - name: db2 connect
      shell:
        cmd: su - db2inst1 -c 'db2 connect to "{{ dbname }}" user "{{ user }}" using "{{ pwd }}"'
      register: result
    - name: result
      debug:
        msg: "{{ result.stdout }}"

このansible playbookを実行するために、以下のコマンドを実行します。

# ansible-playbook -i inventories/hosts.ini db2client_connect.yml

インベントリーの親子関係と変数定義の確認

以下のように、ansible-inventoryコマンドでインベントリーの親子関係と変数定義を確認することができます。

# ansible-inventory --graph --vars -i inventories/hosts.ini 
@all:
  |--@ungrouped:
  |--@db2server:
  |  |--teljpdb41.fyre.ibm.com
  |  |  |--{rsp_file = db2server.rsp}
  |  |--teljpdb42.fyre.ibm.com
  |  |  |--{rsp_file = db2server.rsp}
  |  |--{rsp_file = db2server.rsp}
  |--@db2client:
  |  |--@client1:
  |  |  |--teljpdb43.fyre.ibm.com
  |  |  |  |--{db2host = host1}
  |  |  |  |--{db2port = 50000}
  |  |  |  |--{rsp_file = db2client.rsp}
  |  |  |--{db2host = host1}
  |  |  |--{db2port = 50000}
  |  |--@client2:
  |  |  |--teljpdb31.fyre.ibm.com
  |  |  |  |--{db2host = host2}
  |  |  |  |--{db2port = 50001}
  |  |  |  |--{rsp_file = db2client.rsp}
  |  |  |--{db2host = host2}
  |  |  |--{db2port = 50001}
  |  |--{rsp_file = db2client.rsp}

参考文献

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?