Ansibleを使って複数のサーバーにDockerをインストールする
こんにちは。SHIFTからRGA(リアルグローブ・オートメーティッド)に出向中の前田です。
ここ最近、コンテナ関連の業務にかかわることもあり、複数台の新規サーバーにDockerをインストールする作業を自動化したい(ついでに個人的によく使うEmacsもインストールしておきたい)と思い立ちました。せっかくなので、Ansibleを使ってやってみたところ上手くできたので、その様子を書いてみたいと思います。
構成
コントロールノード (Ansibleを動作させるマシン)1台
Ubuntu 20.04 (on VirtualBox)
Ansible 2.12.1
ターゲットノード (Ansibleによって操作されるマシン)3台
Ubuntu 20.04 (on AWS EC2)
自動化の手順
まずは(ターゲットノードとなる)サーバー1台を対象として、正しく動作するPlaybookを作成していきます。
これがうまく動作することを確認してから、対象となるサーバーを3台に増やします。
Ansibleの疎通確認
Ansibleのインストール方法はネット上に多数見つかるので、ここでは省略させていただき、Ansibleがターゲットホストと通信できることを確認します。そのために、まず下のようなhostsファイルを作成します。ユーザー名やSSH鍵はあらかじめ取得しておいてください。
hosts
[maeda_no_saba]
targetnode ansible_host=18.176.54.90
[maeda_no_saba:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file="~/.ssh/maeda6-rga.pem"
この状態で "ansible all -i hosts -m ping" を実行して、以下のような結果が返ってこれば成功です。
$ ansible all -i hosts -m ping
targetnode | SUCCESS => {
"ansible_facts": {
"discovered_interpreter_python": "/usr/bin/python3"
},
"changed": false,
"ping": "pong"
}
Playbookの作成
さてここからPlaybookを作成していきます。今回作成する内容は以下の2点です。
Dockerのインストール
Emacsのインストール
これをRoleを使って実装しますので、最終的なディレクトリ構成は以下のような感じになります。site.ymlが実行ポイントで、ここから2つのRoleを呼び出す形ですね。
maeda@maeda-VirtualBox:~/WorkingDir/Ansible$ tree
.
├── ansible.cfg
├── hosts
├── roles
│ ├── docker
│ │ ├── handlers
│ │ │ └── main.yml
│ │ └── tasks
│ │ ├── install.yml
│ │ └── main.yml
│ └── emacs
│ └── tasks
│ ├── install.yml
│ └── main.yml
└── site.yml
Emacsタスクの作成
簡単なのでEmacsから行きましょう。aptモジュールを使ってEmacsをインストールするタスクを作成します。
roles/emacs/tasks/install.yml
- name: apt updateを実行します
become: yes
apt:
update_cache: yes
- name: Emacsのインストールを行います
become: yes
apt:
name: emacs
state: present
roles/emacs/tasks/main.yml
- import_tasks: install.yml
Roleの実行はtasks/main.ymlがスタートポイントになるので、main.ymlは必須です。ここから、install.ymlをimport_taskでインポートする形になります。
install.ymlの内容は見ての通りですが、aptのキャッシュのアップデートして、emacsをインストールするだけのシンプルなものです。
Dockerタスクの作成
続いてDockerをインストールするタスクを作成します。
Ubuntu 20.04へのDockerのインストールおよび使用方法を参考にして、ここに記載されている手順をPlaybookに落とし込んでいきます。
roles/docker/tasks/install.yml
- name: apt updateを実行します
become: yes
apt:
update_cache: yes
- name: Dockerのインストールに必要なパッケージをインストールします
become: yes
apt:
name:
- apt-transport-https
- ca-certificates
- curl
- software-properties-common
state: present
- name: DockerリポジトリのGPGキーをシステムに追加します
become: yes
ansible.builtin.apt_key:
url: https://download.docker.com/linux/ubuntu/gpg
state: present
- name: DockerリポジトリをAPTソースに追加します
become: yes
ansible.builtin.apt_repository:
repo: deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable
state: present
- name: apt updateを実行します
become: yes
apt:
update_cache: yes
- name: Dockerをインストールします
become: yes
apt:
name: docker-ce
notify:
- add_user_to_docker_group
- restart_docker_daemon
changed_when: yes
- meta: flush_handlers
roles/docker/tasks/main.yml
- import_tasks: install.yml
少しタスク数が多いですが、emacsのRoleと同じ構成です。
emacsのRoleとの一番の違いは、Dockerをインストールした後にadd_user_to_docker_groupとrestart_docker_daemonという二つのハンドラーが実行されるようにしている点です。
add_user_to_docker_groupはサーバーにログインしているユーザーをdockerグループに追加し、restart_docker_daemonはDockerを再起動します。
これにより、dockerグループに所属しているユーザーであれば、管理者権限なしでdockerコマンドを実行できるようになります。
ユーザーをdockerグループに追加した後にその変更を反映させるため、Dockerを再起動します。再起動しなくても変更が反映されるかもしれませんが、そのあたりはよくわかりません(今ちょっとテストしてみたら、Dockerの再起動は必要なくて、一度ログアウトしてから再ログインする必要がありました)。
Dockerがすでにインストールされていて変更点がなかった場合にも上記二つのハンドラーは実行されてほしいので、changed_when: yesを追加しています。
ハンドラーは以下のとおりです。
rokes/docker/handlers/main.yml
- name: add_user_to_docker_group
become: yes
user:
name: "{{ansible_user_id}}"
groups: docker
append: yes
- name: restart_docker_daemon
become: yes
service:
name: docker
state: restarted
ansible_user_id変数にはタスクを実行しているユーザーの名前が入っています(自分の環境では、ubuntu)。
site.ymlの作成
site.ymlはansible-playbookコマンドを実行するときに指定するPlaybookです。内容としては、上記2つのRoleを呼び出すだけの簡単なものになります。
site.yml
- hosts: all
roles:
- emacs
- docker
以上でPlaybookの作成は終了です。念のため最初に示したディレクトリ構成になっていることを確認します。
maeda@maeda-VirtualBox:~/WorkingDir/Ansible$ tree
.
├── ansible.cfg
├── hosts
├── roles
│ ├── docker
│ │ ├── handlers
│ │ │ └── main.yml
│ │ └── tasks
│ │ ├── install.yml
│ │ └── main.yml
│ └── emacs
│ └── tasks
│ ├── install.yml
│ └── main.yml
└── site.yml
Playbookの実行
さて、いよいよ作成したPlaybookを実際に実行してみます。
ターミナル上で、"ansible-playbook site.yml -i hosts" を実行してください。
自分はテストのためにこのPlaybookを複数回実行しているので、okやchangedといったステータスは皆さんの環境とは異なるかもしれません。
$ ansible-playbook site.yml -i hosts
PLAY [all] *************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [targetnode]
TASK [emacs : apt updateを実行します] **********************************************************************************************************
changed: [targetnode]
TASK [emacs : Emacsのインストールを行います] ***************************************************************************************************
changed: [targetnode]
TASK [docker : apt updateを実行します] *********************************************************************************************************
changed: [targetnode]
TASK [docker : Dockerのインストールに必要なパッケージをインストールします] *********************************************************************
ok: [targetnode]
TASK [docker : DockerリポジトリのGPGキーをシステムに追加します] ********************************************************************************
ok: [targetnode]
TASK [docker : DockerリポジトリをAPTソースに追加します] ****************************************************************************************
ok: [targetnode]
TASK [docker : apt updateを実行します] *********************************************************************************************************
changed: [targetnode]
TASK [docker : Dockerをインストールします] *****************************************************************************************************
changed: [targetnode]
TASK [docker : meta] ***************************************************************************************************************************
RUNNING HANDLER [docker : add_user_to_docker_group] ********************************************************************************************
changed: [targetnode]
RUNNING HANDLER [docker : restart_docker_daemon] ***********************************************************************************************
changed: [targetnode]
PLAY RECAP *************************************************************************************************************************************
targetnode : ok=11 changed=7 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
最後の行に"failed=0"と表示され、すべてのタスクが実行できたことを確認したら、ターゲットホストにEmacsとDockerがインストールされていることを確認しましょう。
ターゲットノードを3台に増やす
作成したPlaybookが正しく実行されることが確認できたので、次はターゲットノードを1台から3台に増やしたいと思います。
変更が必要なのは、hostsファイルだけです。下のように、1つだけ登録していたターゲットホストを3つに増やしました。
hosts
[maeda_no_sabas]
maeda_no_saba ansible_host=18.176.54.90
maeda_no_saba_2 ansible_host=13.230.197.65
maeda_no_saba_3 ansible_host=52.199.123.115
[maeda_no_sabas:vars]
ansible_user=ubuntu
ansible_ssh_private_key_file="~/.ssh/maeda6-rga.pem"
実行結果
再度ansible-playbookコマンドを実行します。
maeda@maeda-VirtualBox:~/WorkingDir/Ansible$ ansible-playbook site.yml -i hosts
PLAY [all] *************************************************************************************************************************************
TASK [Gathering Facts] *************************************************************************************************************************
ok: [maeda_no_saba]
ok: [maeda_no_saba_2]
ok: [maeda_no_saba_3]
TASK [emacs : apt updateを実行します] **********************************************************************************************************
changed: [maeda_no_saba_3]
changed: [maeda_no_saba_2]
changed: [maeda_no_saba]
TASK [emacs : Emacsのインストールを行います] ***************************************************************************************************
ok: [maeda_no_saba_2]
ok: [maeda_no_saba]
ok: [maeda_no_saba_3]
TASK [docker : apt updateを実行します] *********************************************************************************************************
changed: [maeda_no_saba]
changed: [maeda_no_saba_3]
changed: [maeda_no_saba_2]
TASK [docker : Dockerのインストールに必要なパッケージをインストールします] *********************************************************************
ok: [maeda_no_saba]
changed: [maeda_no_saba_3]
changed: [maeda_no_saba_2]
TASK [docker : DockerリポジトリのGPGキーをシステムに追加します] ********************************************************************************
ok: [maeda_no_saba]
changed: [maeda_no_saba_2]
changed: [maeda_no_saba_3]
TASK [docker : DockerリポジトリをAPTソースに追加します] ****************************************************************************************
ok: [maeda_no_saba]
changed: [maeda_no_saba_2]
changed: [maeda_no_saba_3]
TASK [docker : apt updateを実行します] *********************************************************************************************************
changed: [maeda_no_saba_3]
changed: [maeda_no_saba]
changed: [maeda_no_saba_2]
TASK [docker : Dockerをインストールします] *****************************************************************************************************
changed: [maeda_no_saba]
changed: [maeda_no_saba_3]
changed: [maeda_no_saba_2]
TASK [docker : meta] ***************************************************************************************************************************
RUNNING HANDLER [docker : add_user_to_docker_group] ********************************************************************************************
ok: [maeda_no_saba]
changed: [maeda_no_saba_2]
changed: [maeda_no_saba_3]
RUNNING HANDLER [docker : restart_docker_daemon] ***********************************************************************************************
changed: [maeda_no_saba]
changed: [maeda_no_saba_2]
changed: [maeda_no_saba_3]
PLAY RECAP *************************************************************************************************************************************
maeda_no_saba : ok=11 changed=5 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
maeda_no_saba_2 : ok=11 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
maeda_no_saba_3 : ok=11 changed=9 unreachable=0 failed=0 skipped=0 rescued=0 ignored=0
期待通り、3台のターゲットホストに対してインストールが行われました。
まとめ
Roleに分割しているので少しファイル数は多いですが、Ansibleを用いて(しかもRole分割した分かりやすい形で)複数サーバーに対する環境構築を自動化することができました。
今回は対象サーバーが3台だけでしたが、この手法を用いれば対象が100台や1,000台になっても対応できそうです。
マガジン|IT自動化技術ブログ集
SHIFTのグループ会社の1つである、リアルグローブ・オートメーティッド(RGA)のIT自動化に関する技術ブログをまとめています。IT自動化を導入すると「どんな良いことがあるのか」について紹介しつつ、RGAメンバーの技師たちが日々の業務を通じて培った技術情報や参考情報をお届けします!
――――――――――――――――――――――――――――――――――
【ご案内】
ITシステム開発やITインフラ運用の効率化、高速化、品質向上、その他、情シス部門の働き方改革など、IT自動化導入がもたらすメリットは様々ございます。
IT業務の自動化にご興味・ご関心ございましたら、まずは一度、IT自動化の専門家リアルグローブ・オートメーティッド(RGA)にご相談ください!
お問合せは以下の窓口までお願いいたします。
【お問い合わせ窓口】
代表窓口:info@rg-automated.jp
URL: https://rg-automated.jp