はじめに
私: 4つのVMで同じコマンドを打つのがめんどいんだけど一括でできる?
ChatGPT: はい、できます。複数のVMに同じコマンドを一括で実行するには、Ansibleなどのツールを使うと便利です。
以下はChatGPTの出力と自分が躓いたところをまとめた備忘録&初心者輪講教材です。
初心者ゆえお手柔らかにお願いいたします。
環境
Rocky Linux release 8.9 (Green Obsidian)内にインストールしたRocky Linux release 9.4 (Blue Onyx)のLinuxVMで実験を行っています。
手順
-
Ansibleのインストール:
sudo dnf install ansible -y
not foundの場合、epel-releaseを有効にしてください。
sudo dnf install epel-release
-
インベントリファイルの作成:
Ansibleが管理するVMのリストを定義する。
/etc/ansible/hosts
に以下の内容を追加する。
ansible_userはそれぞれ適切なものに変更すること。ssh ここの部分@172.16.1.1
[myvms] vm1 ansible_host=172.16.1.1 ansible_user=admin vm2 ansible_host=172.16.1.2 ansible_user=admin vm3 ansible_host=172.16.1.3 ansible_user=admin vm4 ansible_host=172.16.1.4 ansible_user=admin
-
Playbookの作成:
実行したいコマンドを定義したYAMLファイルを作成する。例えば、myplaybook.yml
というファイルを作成し、以下の内容を記載する。
YAML(YAML Ain't Markup Language)(.yml or .yaml):異なるソフトウェア間のデータ交換で使うファイル。要するにプログラムが読み取りやすい言語。- hosts: myvms tasks: - name: say ho command: echo "ho"
YAMLの定義にYAMLが出てきてるから変な感じ。
-
Playbookの実行:
Ansible Playbookを実行して、コマンドをすべてのVMに適用する。ansible-playbook myplaybook.yml
標準出力を見たいならこう。
ansible-playbook myplaybook.yml -v
こうなれば成功。
PLAY [myvms] ************************************************************************************************************************************************ TASK [Gathering Facts] ************************************************************************************************************************************** ok: [vm2] ok: [vm1] ok: [vm3] ok: [vm4] TASK [say ho] *********************************************************************************************************************************************** changed: [vm2] => {"changed": true, "cmd": ["echo", "ho"], "delta": "0:00:00.002864", "end": "2024-05-19 01:19:05.400496", "msg": "", "rc": 0, "start": "2024-05-19 01:19:05.397632", "stderr": "", "stderr_lines": [], "stdout": "ho", "stdout_lines": ["ho"]} changed: [vm1] => {"changed": true, "cmd": ["echo", "ho"], "delta": "0:00:00.003441", "end": "2024-05-19 01:19:05.398650", "msg": "", "rc": 0, "start": "2024-05-19 01:19:05.395209", "stderr": "", "stderr_lines": [], "stdout": "ho", "stdout_lines": ["ho"]} changed: [vm4] => {"changed": true, "cmd": ["echo", "ho"], "delta": "0:00:00.002860", "end": "2024-05-19 01:19:05.401005", "msg": "", "rc": 0, "start": "2024-05-19 01:19:05.398145", "stderr": "", "stderr_lines": [], "stdout": "ho", "stdout_lines": ["ho"]} changed: [vm3] => {"changed": true, "cmd": ["echo", "ho"], "delta": "0:00:00.002873", "end": "2024-05-19 01:19:05.406218", "msg": "", "rc": 0, "start": "2024-05-19 01:19:05.403345", "stderr": "", "stderr_lines": [], "stdout": "ho", "stdout_lines": ["ho"]} PLAY RECAP ************************************************************************************************************************************************** vm1 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 vm2 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 vm3 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0 vm4 : ok=2 changed=1 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
ansibleを使いこなせば、VMにssh接続して実行、別のVMに接続して実行、、、なんてしなくてよくなりますね!
発展系(やりたかったこと)
ymlを極めればOpenMPIをインストールしてパスを通してファイルを配って、、全部できるはずです。(以下は ChatGPT4oが生成、責任はおいかねます。)
- name: Install OpenMPI and run MPI program
hosts: myvms
become: yes
tasks:
- name: Install development tools
yum:
name: "@Development Tools"
state: present
- name: Install EPEL repository
yum:
name: epel-release
state: present
- name: Install OpenMPI
yum:
name:
- openmpi
- openmpi-devel
state: present
- name: Ensure /usr/lib64/openmpi/bin is in PATH
lineinfile:
path: /etc/profile.d/openmpi.sh
line: 'export PATH=$PATH:/usr/lib64/openmpi/bin'
create: yes
- name: Source /etc/profile.d/openmpi.sh
shell: source /etc/profile.d/openmpi.sh
args:
executable: /bin/bash
- name: Create directory for MPI program
file:
path: /home/{{ ansible_user }}/mpi_program
state: directory
mode: '0755'
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
- name: Copy MPI program to nodes
copy:
src: mpi_program.c
dest: /home/{{ ansible_user }}/mpi_program/mpi_program.c
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Create MPI hostfile
copy:
content: |
vm1 slots=1
vm2 slots=1
vm3 slots=1
vm4 slots=1
dest: /home/{{ ansible_user }}/mpi_program/hostfile
owner: "{{ ansible_user }}"
group: "{{ ansible_user }}"
mode: '0644'
- name: Compile MPI program
shell: mpicc -o /home/{{ ansible_user }}/mpi_program/mpi_program /home/{{ ansible_user }}/mpi_program/mpi_program.c
args:
chdir: /home/{{ ansible_user }}/mpi_program
environment:
PATH: "{{ ansible_env.PATH }}:/usr/lib64/openmpi/bin"
引っ掛かりポイント
ansible-playbookの結果、unreachable=1になる
各環境に公開鍵認証でssh接続できるのが前提となります。
鍵生成→鍵を渡す→各VMのsshd.confingを変更してパスワード認証をnoにする
この辺りの手順はやってください。
何故かうまくいかない、そんなときは鍵を作り直したらうまくいったりします。他のホストとの公開鍵認証がない今回は許されます。