Ansible 2.2 on CentOS 5.11 構築のお話
ことの始まり
ちょっとした環境で Ansible を動かしたい衝動に駆られたので、 Ansibleが動くように構築。
すげぇ苦労したし、色々なこと見聞きしました。超感謝。
前半だけ読めば、とりあえず構築はできるはず。
後半は、私が格闘した2日間の成果です。
構築したい環境
Ansible Host side
- CentOS 5.11 (minimum install)
OpenSSL と Python 2.7 はソースコンパイルでインストールします。
OpenSSLに関しては、yumでインストールできないため、
Python2.7 は、既存Python2.4を汚したくない(別ディレクトリにインストールする)ためです。
検証構築なので、基本rootでの動作確認のみです。一般ユーザの場合はもしかしたら…?
Ansibe Client side
Ansibleはエージェントレスのため、基本的には何も入れなくて済むと思ったのですが、残念ながら…
下の方にも書いてあるので、ご参照ください。
構築手順
CentOS 5.11 に関して
CentOS 5.11 は、netinstall (ftp.riken.jp 経由)で構築済みとし、初回セットアップ時に、
を無効化した状態を用意しました。
インストール後、下記コマンドを実行。どう見ても適当
# yum update # yum groupinstall "Development tools"
OpenSSL 1.0.2 導入
これを入れないと、Ansible の構築がコケる。
さらに、脆弱性が大量に見つかっているので、なんとかしたほうが良さそうなものの一つ。
Ansible の構築に必要なライブラリが同梱されている、OpenSSL 1.0.2 を、先人の知恵を借りつつ、 ソースから気合と根性で入れる。
linux - Compiling Python 2.7.12 with non-system Openssl on Centos 5 - Stack Overflow
# cd /tmp # wget --no-check-certificate https://www.openssl.org/source/openssl-1.0.2k.tar.gz # tar zxfv openssl-1.0.2k.tar.gz # cd openssl-1.0.2k # ./config shared --prefix=/usr/local/ # make && make install
導入後、openssl version
でバージョンが上がっていることを確認できます。
# openssl version OpenSSL 1.0.2k 26 Jan 2017
また、以下の環境変数が構築と、ansible 実行時に必要なので、.bashrc
等に追記しておきます。
# echo 'export LDFLAGS="-L/usr/local/lib64/"' >> ~/.bashrc # echo 'export LD_LIBRARY_PATH="/usr/local/lib64/"' >> ~/.bashrc # echo 'export CPPFLAGS="-I/usr/local/include -I/usr/local/include/openssl"' >> ~/.bashrc # source ~/.bashrc
Python 2.7 導入
既存のPythonを汚したくないので、今回はソースからビルドインストールします。
必要なパッケージのインストール
まずは、python のインストールに必要なパッケージをインストール。
# yum install zlib-devel ncurses-devel sqlite-devel openssl-devel tk-devel bzip2-devel gdbm-devel readline-devel gcc python-devel python-setuptools
何が必要で何が不要かはよく分からんが、とりあえず入れておこうという大作戦です。
もしかしたら、いらないのが続発するかもしれません。
python2.7 の準備
ソースを落とす → configure → make && make altinstall といういつもの流れで行きます。
# wget --no-check-certificate https://www.python.org/ftp/python/2.7.12/Python-2.7.12.tar.xz # xz -dv Python-2.7.12.tar.xz && tar xf Python-2.7.12.tar # cd ./Python-2.7.12 # ./configure --prefix=/opt/python2.7 --enable-unicode=ucs4 --enable-shared # make && make altinstall
最後に、おまじないをかけて、実行できるようにします
(おまじないの訳はコケた所を参照。)
# ln -s /opt/python2.7/lib/libpython2.7.so.1.0 /lib64/ # /opt/python2.7/bin/python2.7 -V Python 2.7.12
OpenSSL 1.0.2 & python2.7.12 の確認
下記コマンドを実行し、OpenSSLのバージョンが新しいかを確認する。
# /opt/python2.7/bin/python2.7 -c "import ssl; print ssl.OPENSSL_VERSION;" OpenSSL 1.0.2k 26 Jan 2017
結果が、OpenSSL 0.9.8
等の場合は、OpenSSL の導入がミスってるかも知れないので確認を。
virtualenv導入 & セットアップ
/opt/python2.7/bin/python2.7
と入力するのもいいですが、なんやかんや面倒くさいので、virtualenvを導入します。
なお、先人の知恵より、virtualenvは1.10.1以上を導入します。
更に、python2.7 で使用するので、virtualenvの setup.py
は /opt/python2.7/bin/python2.7
で実行します。
# wget --no-check-certificate http://pypi.python.org/packages/source/v/virtualenv/virtualenv-1.10.1.tar.gz # tar zvfx virtualenv-1.10.1.tar.gz # cd ./virtualenv-1.10.1 # /opt/python2.7/bin/python2.7 setup.py install
すべて完遂すると、--version
コマンドで確認できます。
# /opt/python2.7/bin/virtualenv --version 1.10.1
最後に、任意のディレクトリにvirtualenvの初期化とactivate
を実行します。
# /opt/python2.7/bin/virtualenv /your/filepath/name --python=/opt/python2.7/bin/python2.7 # cd /your/filepath/name # source ./bin/activate (name) # python -V Python 2.7.12
activate
をすると、シェルの前に (name)
と表示されます。
無効化は、deactivate
コマンドでおkです。
Ansible 導入
ここまでくれば、ほぼ勝ったも同然です。
必要パッケージ導入
この先でコケないために、必要なパッケージを予め入れます。
# yum install epel-release # yum install pkgconfig libffi-devel
epel-release が嫌な方は、rpmが用意されているみたいなので、そちらからどうぞ。
ansible install from pip
通常通り、pipからansibleを導入します。
# pip install markupsafe six packaging appdirs ansible
その他、コケるものは、エラーログを参考にしつつ、とにかく入れてください。
完走すると、次のように確認が取れるはずです。
# pip freeze Jinja2==2.8.1 MarkupSafe==1.0 PyYAML==3.12 ansible==2.2.1.0 appdirs==1.4.3 asn1crypto==0.21.1 cffi==1.9.1 cryptography==1.8.1 enum34==1.1.6 idna==2.5 ipaddress==1.0.18 packaging==16.8 paramiko==2.1.2 pyasn1==0.2.3 pycparser==2.17 pycrypto==2.6.1 pyparsing==2.2.0 six==1.10.0 wsgiref==0.1.2 # ansible --version ansible 2.2.1.0 config file = configured module search path = Default w/o overrides
Ansible 実行
パッケージインストール(ホスト・クライアントともに)
今回は、ホストもクライアントもCentOS5 であるため、先人の知恵により、
下記パッケージをホスト・クライアントともに導入する。(さもなくば動かない)
# yum -y install python-simplejson # pip install --upgrade setuptools
でないと、ping すら通らない。
(コケた所参照)
pingテスト
まずは、自身に対して
# ansible localhost -m ping [WARNING]: Host file not found: /etc/ansible/hosts [WARNING]: provided hosts list is empty, only localhost is available localhost | SUCCESS => { "changed": false, "ping": "pong" }
次に、IP を自身(172.16.1.34
)に設定したもの。予め hosts ファイルを用意しておく。
パスワードも毎回聞く形にする。(--ask-pass
)
# echo "172.16.1.34" > hosts # ansible -i hosts 172.16.1.34 -m ping -u root --ask-pass SSH password: 172.16.1.34 | SUCCESS => { "changed": false, "ping": "pong" }
そして、外にあるCentOS5 に対してping テスト。先ほどと同様にする。
# ansible -i hosts 172.16.1.35 -m ping -u root --ask-pass SSH password: 172.16.1.35 | SUCCESS => { "changed": false, "ping": "pong" }
コケたところ
pythonを入れたのにライブラリ不足で動かない
# /opt/python2.7/bin/python2.7 -V /opt/python2.7/bin/python2.7: error while loading shared libraries: libpython2.7.so.1.0: cannot open shared object file: No such file or directory
先人の知恵通りの動作をしたので、この通り対策します。原因は、libpython2.7.so.1.0
が読み込めなかっただけです。
# ln -s /opt/python2.7/lib/libpython2.7.so.1.0 /lib64/ # /opt/python2.7/bin/python2.7 -V Python 2.7.12
Ansible インストールでコケる①
pipが完走しない場合が多発しますが、 エラーログに表示されている不足パッケージをyum ないし pipで導入すればおkです。
例↓
# pip install ansible Downloading/unpacking ansible (中略) Perhaps you should add the directory containing `libffi.pc' to the PKG_CONFIG_PATH environment variable No package 'libffi' found Package libffi was not found in the pkg-config search path. (中略) distutils.errors.DistutilsError: Setup script exited with error: command 'gcc' failed with exit status 1 ---------------------------------------- Cleaning up... Command /root/ansible/bin/python2.7 -c "import setuptools;__file__='/root/ansible/build/cryptography/setup.py';exec(compile(open(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-29MwMi-record/install-record.txt --single-version-externally-managed --install-headers /root/ansible/include/site/python2.7 failed with error code 1 in /root/ansible/build/cryptography Traceback (most recent call last): File "/root/ansible/bin/pip", line 9, in <module> load_entry_point('pip==1.4.1', 'console_scripts', 'pip')() File "/root/ansible/lib/python2.7/site-packages/pip/__init__.py", line 148, in main return command.main(args[1:], options) File "/root/ansible/lib/python2.7/site-packages/pip/basecommand.py", line 169, in main text = '\n'.join(complete_log) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 61: ordinal not in range(128)
上記の場合は、libffi
が足りないので、入れてあげましょう。
# yum install epel-release # yum install libffi-devel
その他、引っかかったって入れたものは次の通り。
- six
- packaging
- appdirs
- cryptography
事故らないように、最初に入れておくと良さそう。
# pip install six packaging appdirs cryptography
Ansible がコケる②
CentOS 5.11 のデフォルトでインストールされているOpenSSLは、 0.9.8系のため、
最終目標である Ansible で必要な cryptography のインストールでコケる。
# pip install cryptography (略) build/temp.linux-x86_64-2.7/_openssl.c:682: error: parameter name omitted build/temp.linux-x86_64-2.7/_openssl.c:73316: error: expected ‘{’ at end of input error: command 'gcc' failed with exit status 1 ---------------------------------------- Cleaning up... Command /root/ansible/bin/python2.7 -c "import setuptools;__file__='/root/ansible/build/cryptography/setup.py';exec(compile(open(__file__).read().replace('\r\n', '\n'), __file__, 'exec'))" install --record /tmp/pip-4ZVpYs-record/install-record.txt --single-version-externally-managed --install-headers /root/ansible/include/site/python2.7 failed with error code 1 in /root/ansible/build/cryptography Traceback (most recent call last): File "/root/ansible/bin/pip", line 9, in <module> load_entry_point('pip==1.4.1', 'console_scripts', 'pip')() File "/root/ansible/lib/python2.7/site-packages/pip/__init__.py", line 148, in main return command.main(args[1:], options) File "/root/ansible/lib/python2.7/site-packages/pip/basecommand.py", line 169, in main text = '\n'.join(complete_log) UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 84: ordinal not in range(128)
とまあ、完全にopenssl.c
がエラーを吐いていたり、
openssl/cms.h
がnot found 吐いたりと多彩な場合があるのですが、
原因はおそらく、openssl のバージョンが古いせいです。
なので、OpenSSL 1.0.2のインストールが必須となる。
これを入れると、これまで動いていたアプリが動かなくなる可能性がなきにしもあらずなので、
そのあたりは要検証と自己責任でお願いしたい。
Ansible で CentOS5 に対して実行が飛ばない①
先人の知恵により、下記の症状が出ることは知られている。
# ansible -i hosts 172.16.1.36 -m ping -u root --ask-pass SSH password: 172.16.1.36 | FAILED! => { "changed": false, "failed": true, "module_stderr": "", "module_stdout": "Traceback (most recent call last):\r\n File \"/root/.ansible/tmp/ansible-tmp-1489213797.79-3750923784101/ping.py\", line 133, in ?\r\n exitcode = invoke_module(module, zipped_mod, ANSIBALLZ_PARAMS)\r\n File \"/root/.ansible/tmp/ansible-tmp-1489213797.79-3750923784101/ping.py\", line 38, in invoke_module\r\n (stdout, stderr) = p.communicate(json_params)\r\n File \"/usr/lib64/python2.4/subprocess.py\", line 1050, in communicate\r\n stdout, stderr = self._communicate_with_poll(input)\r\n File \"/usr/lib64/python2.4/subprocess.py\", line 1113, in _communicate_with_poll\r\n input_offset += os.write(fd, chunk)\r\nOSError: [Errno 32] Broken pipe\r\n", "msg": "MODULE FAILURE" }
解決策は、クライアント側のサーバに、python-simplejson
パッケージをyumで導入すること。
# yum install python-simplejson (name)# ansible -i hosts 172.16.1.36 -m ping -u root --ask-pass SSH password: paramiko: The authenticity of host '172.16.1.36' can't be established. The ssh-rsa key fingerprint is 98ac62cd827891c07b412449fc1e6f1a. Are you sure you want to continue connecting (yes/no)? yes 172.16.1.36 | SUCCESS => { "changed": false, "ping": "pong" }
Ansible で CentOS5にPingが飛ばない②
(name)# ansible -i hosts 172.16.1.36 -m ping -u root --ask-pass SSH password: No handlers could be found for logger "paramiko.transport" 172.16.1.36 | UNREACHABLE! => { "changed": false, "msg": "(setuptools 0.9.8 (/root/ansible/lib/python2.7/site-packages), Requirement.parse('setuptools>=11.3'))", "unreachable": true }
というわけで、setuptools
が古すぎて動かないそうなので、とにかくupgrade
しましょう
(name) # pip install --upgrade setuptools (ansible)[root@localhost ansible]# ansible -i hosts 172.16.1.36 -m ping -u root --ask-pass SSH password: paramiko: The authenticity of host '172.16.1.36' can't be established. 172.16.1.36 | SUCCESS => { "changed": false, "ping": "pong" }
まとめ
手元の環境では、playbookでファイルの生成(echoしたものの書き出し)が成功した ところまでは確認済みです。
他の何処かで事故るかは未検証なので、その辺りは事故ってからまた修正・検証します。
検証中に新しくコケた部分を見つけたのは内緒。
何かコケても、ログをよく見て対処するなり先人の知恵を拝借するなりしてみてください。