はじめに
平成の時分も終わりに近づく中、野分立ち尽くす天災に
人々は翻弄され、お家で過ごすのを余儀なくされる日が多いように思います。1
今日のような一日は、自然とQiitaにたどり着き、
PVが増えるのではないかと勝手に邪推する筆者です。
さて、話は閑話休題。
ローカル環境で、仮想マシン立ててAnsible環境作る際に、
コントロールノードからターゲットノードにSSHの鍵交換をすると思うのですが、
ターゲットノードが多い際の交換を一つ一つssh-copy-id
していくのは
甚だ煩わしいこととお感じではないでしょうか。
はじめに鍵交換をしてしまえば、後はLet's Ansible2するだけなのですが、
めんどくさがりの権化である私はどうもこの作業すら億劫になります。
ローカルマシンで冗長構成のWebサーバなんてのを作って遊んでをするときは
最初が兎にも角にもめんどくさい。
環境構築こそ、一番ラクに終わらせて後はInfrastructure as Code(IaC)
していくのが本分なのではないでしょうか。
Environment
- macOS Mojave 10.14
- Vagrant 2.1.5
- VartualBox 5.2.16 r123759 (Qt5.6.3)
- CentOS7のbox(今回はVagrant Cloudの
geerlingguy/centos7
を使用)
※ご自身の環境に合わせて事前に用意をして下さい
仮想環境を立てる
今回の例では、10台のノードをVagrantで立てます。その際、
1台をコントロールノード、残り9台をコントロールノードとして使用します。
任意のディレクトリ下でinit
をしましょう。
$ vagrant init geerlingguy/centos7
作成したディレクトリにVagrantfile
が作成されるので、下記のように記述して下さい。
参考URL:Vagrant Cloud
Vagrant.configure("2") do |config|
config.ssh.insert_key = false
config.vm.box = "geerlingguy/centos7"
N = 10
(1..N).each do |node_id|
config.vm.define "node#{node_id}" do |server|
server.vm.hostname = "server#{node_id}"
server.vm.network "private_network", ip: "192.168.200.#{10+node_id}"
end
end
end
上記のVagrantfileでは、192.168.200.0
のプライベートネットワークに連番で、192.168.200.11
から192.168.200.20
のIPがそれぞれのノードに振られます。また、同様にそれぞれのSSHする際のノード名はnode1:10
、machinehostname
はserver1:10
という名前が割り当てられます。
参考URL:Loop Over VM Definitions
次に、boxを登録した後、vagrant up
します。
この例では、事前にvagrant box add
はする必要がなく、
vagrant init
した際にboxをpullします。
# 全てのノードを起動する
$ vagrant up
# コントロールノード(node1)に接続
$ vagrant ssh node1
コントロールノードの設定
expectで全てのノードに送る
# ansivblerとexepctをnode1にインストールしておく
[vagrant@server1 ~]$ sudo yum -y install ansible expect
仮想マシンが10台起動した後、node1
からnode2:10
を操作する場合、
全てに鍵を送らないといけません。expect
を使用することで、それぞれのIPアドレスに対する
対話形式のコマンドラインを全て変数で渡して処理することができます。
#!/bin/sh
export LANG=C
pw="vagrant"
for i in `seq 12 20`
do
expect -c "
set timeout 5
spawn ssh-copy-id -o StrictHostKeyChecking=no -i $HOME/.ssh/id_rsa.pub 192.168.200.$i
expect \"password:\"
send \"${pw}\n\"
expect \"$\"
exit 0
"
done
詳しくは、@ine1127 様のLinuxの対話がめんどくさい?そんな時こそ自動化だ!-expect編-の記事をお読み下さい。
鍵を作成後、シェルスクリプトを動かしてみましょう。
成功していれば、Number of key(s) added: 1
の記述がそれぞれのサーバに対して表示されるはずです。
# 公開鍵を作成 (名前を変更した場合、適宜スクリプトの変更をする)
[vagrant@server1 ~]$ ssh-keygen
# 実行権限を与える
[vagrant@server1 ~]$ chmod 755 copy_ssh_keys.sh
[vagrant@server1 ~]$ ./copy_ssh_keys.sh
Ansibleの実行確認
インベントリは連番であれば上記のように記載できます。
[vm_nodes]
192.168.200.[12:20]
最後にAnsibleで意思疎通ができるかping
コマンドを送ってみましょう。
$ ansible vm_nodes -i inventory.ini -m ping
192.168.200.14 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.15 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.13 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.12 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.16 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.17 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.18 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.19 | SUCCESS => {
"changed": false,
"ping": "pong"
}
192.168.200.20 | SUCCESS => {
"changed": false,
"ping": "pong"
}
SUCCESS
が返ってこれば成功です。
おめでとうございます。
おわりに
私が思いついた方法として上記の例を取り上げましたが、もっといい方法があるのではないかと個人的に思っております。そういった意味でベストプラクティスではなくプラクティスというタイトルをつけさせていただきました。上記よりも適切な方法があるのでれば、コメントにて教えていただければ幸いでございます。
最後までお読み頂きありがとうございました。