Minimal インストールの CentOS 6.4 に最新版の ansible をインストールする
ansible の最新版を GitHub から取得してインストールする。
CentOS 6.4 を minimal インストールし、「Minimal インストールの CentOS 6.4 に最新版の git をインストールする」にて git を使用可能にした状態を前提にする。
ansible を使用するには以下の方法があるようで、ここでは make install をやってみる。いろいろ方法があって公式インストール手順もなんか落ち着かない感じ(最後にとってつけたように「make install」ももちろんできるよ、みたいに書かれていたり)。2015年2月13日時点では yum や pip でインストールされるのは 1.8.2 で GitHub 上の最新版は 1.9 になっている。初めて使うなら全ての機能を使いたいし最新版にしておきたい。
- yum install ansible でEPELリポジトリ上のRPM版 ansible をインストールする
- pip install ansible でインストールする
- GitHub からソースを取得してインストールせずに環境変数だけ設定して使用する(./hacking/env-setup)
- GitHub からソースを取得して make install でインストールする★今回選択した方法
- GitHub からソースを取得して RPM を作成してインストールする
パッケージ追加
ansible の動作用にパッケージを追加する。minimal インストールだと ssh クライアントすら入らないので追加が必要。
openssh-clients
# yum install openssh-clients # rpm -qa | grep openssh-clients openssh-clients-5.3p1-104.el6_6.1.x86_64
CentOS 6.4 に標準で含まれる openssh-clients は「openssh-clients-5.3p1-84.1.el6.x86_64」である。理由は以下に記載するが、必ず最新の openssh-clients をインストールする。今回確認したのは「openssh-clients-5.3p1-104.el6_6.1.x86_64」である。すでにインストールされていた場合にも最新版に yum update する。
「RHEL6系でansibleを使うならrecord_host_keysをFalseにすると速くなる」の記事を一部引用する。
ansibleは各ホストとの接続にはsshと使います。この時、sshにはControlPersistという機能に対応していることが必要で、opensshならバージョン5.6以上が対象です。ansibleのデフォルトの動作では、PATH上のsshコマンドがControlPersistに対応していればsshを使い、そうでない場合はparamikoというpythonのsshライブラリが用いられるようになっています。
RHEL6系のopensshはバージョン5.3の為、何も設定せずに使うとparamikoが用いられます。
RHEL 6(CentOS 6)系の ssh は ControlPersist という機能に対応しておらず、ansible は openssh のPython実装である Paramiko を使用して各サーバと接続することになる。実際に 5.3p1-81.1 のまま ansible を使用すると、確かに Paramiko が使用された。
この Paramiko は性能上のディスアドバンテージがあるようなので、できれば素直に ssh コマンドを使って欲しい。RHEL6系だから自分で最新版の openssh をビルドしなければならないかと思ったが、以下のページの情報によれば対応が 5.3p1-100 あたりで入ったようだ。5.3p1-104 であれば ansible は Paramiko ではなく ssh コマンドを使用してくれた。
sshpass
openssh-clients の最新版(ControlPersist対応)を使用することで、ansible は ssh コマンドを使用するようになるのだが、これだけだと以下のエラーが発生してしまう。
# ansible all -m ping --ask-pass SSH password: 127.0.0.1 | FAILED => to use the 'ssh' connection type with passwords, you must install the sshpass program
エラーメッセージの通り、sshpass コマンドを使えるようにする必要がある。この sshpass はEPELリポジトリからインストールできる。
EPELリポジトリを登録するためのRPMをインストールする。リポジトリの情報取得の接続に https を使用するため、nss パッケージを更新しておく。古いバージョンだと「Error: Cannot retrieve metalink for repository: epel. Please verify its path and try again」エラーが発生し、リポジトリにアクセスできない。
# cd /tmp # yum update nss # wget http://ftp-srv2.kddilabs.jp/Linux/distributions/fedora/epel/6/x86_64/epel-release-6-8.noarch.rpm # yum localinstall epel-release-6-8.noarch.rpm
sshpass をインストール。
# yum --enablerepo=epel install sshpass # rpm -qa | grep sshpass sshpass-1.05-1.el6.x86_64
pip, Pythonの依存モジュールをインストール
pip を使用可能にする。
# easy_install pip (中略) Installed /usr/lib/python2.6/site-packages/pip-6.0.8-py2.6.egg Processing dependencies for pip Finished processing dependencies for pip
ansible が依存するPythonのモジュールをインストールする。
# pip install paramiko PyYAML Jinja2 httplib2 (中略) Successfully installed Jinja2-2.7.3 PyYAML-3.11 ecdsa-0.13 httplib2-0.9 markupsafe-0.23 paramiko-1.15.2 pycrypto-2.6.1
ansibleのファイル取得・インストール
GitHub から最新版の ansible を取得する。
# mkdir /persistent/ansible # cd /persistent/ansible # git clone git://github.com/ansible/ansible.git --recursive
インストール!
# cd ansible # make install
動作確認
実行ファイルの配置とバージョンの確認。
# which ansible /usr/bin/ansible # which ansible-playbook /usr/bin/ansible-playbook # ansible --version ansible 1.9 configured module search path = None
自ホストへの ssh 接続確認。
失敗。ホストキーの確認がでる(known_hostsにない)と sshpass は対応できないらしい。
# cd /tmp # echo "127.0.0.1" > ansible_hosts # export ANSIBLE_HOSTS=/tmp/ansible_hosts # ansible all -m ping --ask-pass SSH password: (password) 127.0.0.1 | FAILED => Using a SSH password instead of a key is not possible because Host Key checking is enabled and sshpass does not support this. Please add this host's fingerprint to your known_hosts file to manage this host.
対処方法は5つある。何れも結局は known_hosts にエントリが追加されるだけである。
- ssh 127.0.0.1 を実行して自分で known_hosts に登録する
- ssh-keyscan でホストキーを known_hosts に登録する
- 環境変数 ANSIBLE_SSH_ARGS を使用して ansible が使用する ssh に -o StrictHostKeyChecking=no オプションを渡す
- ansible の設定ファイル (/etc/ansible/ansible.cfg) の host_key_checking を false にする
- ssh の config で対象ホスト向けの StrictHostKeyChecking を no にする
# ssh 127.0.0.1 The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established. RSA key fingerprint is e5:7a:48:ca:6a:bb:d5:19:ee:4f:01:14:e2:7b:fa:82. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added '127.0.0.1' (RSA) to the list of known hosts. root@127.0.0.1's password: (password) Last login: Sat Feb 14 14:27:06 2015 from localhost
ssh-keyscan を使用する場合の操作。
# ssh-keyscan 127.0.0.1 >> ~/.ssh/known_hosts
環境変数 ANSIBLE_SSH_ARGS を使用する場合の操作。
ansible が本来設定する ControlPersist の設定などがされなくなるので、known_hosts にエントリを登録したら unset すること。
# export ANSIBLE_SSH_ARGS="-o StrictHostKeyChecking=no"
/etc/ansible/ansible.cfg で host_key_checking を false にする場合の定義。
[defaults] host_key_checking=false
ssh の config で対象ホスト向けの StrictHostKeyChecking を no にする場合の /root/.ssh/config の定義。
Host 127.0.0.1 StrictHostKeyChecking no
上記の何れかの対処を行った後に自ホストへの ssh 接続確認。
成功!
# ansible all -m ping --ask-pass SSH password: (password) 127.0.0.1 | success >> { "changed": false, "ping": "pong" }
/etc/ansible/hosts ファイル作成
動作確認では /tmp/ansible_hosts を作成していたが、毎回指定するのは不便なのでデフォルトで読む /etc/ansible/hosts を作成する。
# mkdir /etc/ansible # echo "127.0.0.1" >> /etc/ansible/hosts
環境変数 ANSIBLE_HOSTS を指定せずに自ホストへの ssh 接続確認。
成功!
# ansible all -m ping --ask-pass SSH password: (password) 127.0.0.1 | success >> { "changed": false, "ping": "pong" }
最後に ping だけでなく uptime などのコマンドも投げてみる。
# ansible all -m command -a "uptime" --ask-pass SSH password: (password) 127.0.0.1 | success | rc=0 >> 06:20:20 up 16:27, 2 users, load average: 0.06, 0.01, 0.00
その他のメモ
ssh コマンドではなく Paramiko を使うことを明示的に指示する場合
-c paramiko をつければよい。
# ansible all -m ping --ask-pass -c paramiko
Paramiko を使用して known_hosts ファイルがない場合
Paramiko で接続すると、ホストキーが known_hosts に登録されていない場合にも対応できる。
ただし、known_hosts ファイル自体がないと 「OSError: [Errno 2] No such file or directory」エラーとなる。
touch でファイルを存在させておけば、yes 回答で素直に登録してくれる。
# ansible all -m ping --ask-pass -c paramiko SSH password: paramiko: The authenticity of host '127.0.0.1' can't be established. The ssh-rsa key fingerprint is e57a48ca6abbd519ee4f0114e27bfa82. Are you sure you want to continue connecting (yes/no)? yes Traceback (most recent call last): File "/usr/lib/python2.6/site-packages/ansible-1.9-py2.6.egg/ansible/runner/connection_plugins/paramiko_ssh.py", line 393, in close key_stat = os.stat(self.keyfile) OSError: [Errno 2] No such file or directory: '/root/.ssh/known_hosts' 127.0.0.1 | success >> { "changed": false, "ping": "pong" }
known_hostsにエントリを追加しないようにする
-o UserKnownHostsFile=/dev/null オプションも追加すればよい。
export ANSIBLE_SSH_ARGS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null"
環境変数 ANSIBLE_SSH_ARGS を設定すると、ansible が使用する ControlPersist の設定が入らなくなり、接続が維持されなくなる。
known_hosts にも登録せず、かつ、ControlPersist を使うという場合には自分で ControlPersist の設定を加える。
# CPOPTS="-o ControlPath=~/.ansible/cp/ansible-ssh-%h-%p-%r -o ControlMaster=auto -o ControlPersist=60s" # export ANSIBLE_SSH_ARGS="-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null $CPOPTS"