3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ローカル環境でAnsibleの鍵交換がめんどくさい貴方に送るプラクティス

Last updated at Posted at 2018-09-30

はじめに

平成の時分も終わりに近づく中、野分立ち尽くす天災に
人々は翻弄され、お家で過ごすのを余儀なくされる日が多いように思います。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

Vagrantfile
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、machinehostnameserver1: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の実行確認

インベントリは連番であれば上記のように記載できます。

inventory.ini
[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が返ってこれば成功です。
おめでとうございます。

おわりに

私が思いついた方法として上記の例を取り上げましたが、もっといい方法があるのではないかと個人的に思っております。そういった意味でベストプラクティスではなくプラクティスというタイトルをつけさせていただきました。上記よりも適切な方法があるのでれば、コメントにて教えていただければ幸いでございます。

最後までお読み頂きありがとうございました。

  1. 被災された皆様に心よりお見舞い申し上げます。我が実家も同様に。

  2. なんとなく言ってみたかった。

3
1
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
3
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?