Ansible が利用する Python 実行環境

みなさんこんにちは。レッドハットの杉村です。Ansible のテクニカルサポートをしています。

Ansible Engine や Ansible Tower は Python で書かれています。今回の記事では、Python の実行環境についてお話したいと思います。

Python は 2.7 と 3 で互換性がありません。この違いがよく問題となります。

RHEL に標準搭載されている Python

RHEL 7 では Python 2.7.5 が標準搭載されていますが、RHEL 8 にはありません。/usr/libexec/platform-python として 3.6.8 がインストールされているものの、これは OS の管理に使うことが想定されているものです。

RHEL 7 で利用できる Python

RHEL 7 では標準搭載されている 2.7.5 以外にも、RHSCL (Red Hat Software Collections) で利用できる Python や、RHEL 7.7 以降で含まれるようになった Python をインストールして使うことができます。RHSCL のリポジトリは、RHEL のサブスクリプションをお持ちであれば一部の例外を除いてご利用いただけます。

リポジトリ 利用できるPython パッケージ名
rhel-7-server-rpms 2.7.5 python
rhel-7-server-rpms 3.6.8 python3 (RHEL 7.7以降)
rhel-server-rhscl-7-rpms 2.7.17 python27-python
rhel-server-rhscl-7-rpms 3.4.2 rh-python34-python
rhel-server-rhscl-7-rpms 3.5.1 rh-python35-python
rhel-server-rhscl-7-rpms 3.6.12 rh-python36-python
rhel-server-rhscl-7-rpms 3.8.6 rh-python38-python

例えば Python 3.8 を使うには、RHSCL のリポジトリを有効にしてインストールできます。

# subscription-manager repos --enable=rhel-server-rhscl-7-rpms
リポジトリー 'rhel-server-rhscl-7-rpms' は、このシステムに対して有効になりました。

# yum install rh-python38
…
インストール:
  rh-python38.x86_64 0:2.0-4.el7                                                                                                                        

依存性関連をインストールしました:
  libtirpc.x86_64 0:0.2.4-0.16.el7                                              rh-python38-python.x86_64 0:3.8.6-1.el7                                
  rh-python38-python-libs.x86_64 0:3.8.6-1.el7                                  rh-python38-python-pip.noarch 0:19.3.1-1.el7                           
  rh-python38-python-pip-wheel.noarch 0:19.3.1-1.el7                            rh-python38-python-setuptools.noarch 0:41.6.0-7.el7                    
  rh-python38-python-setuptools-wheel.noarch 0:41.6.0-7.el7                     rh-python38-runtime.x86_64 0:2.0-4.el7                                 
  scl-utils.x86_64 0:20130529-19.el7                                           

完了しました!

# scl --list
rh-python38

# scl enable rh-python38 /bin/bash

# python -V
Python 3.8.6

# exit
exit

RHSCL でインストールされたものを利用するためには、scl enable コマンドでその環境を構成する必要があることに注意してください。詳しくはこちらのドキュメントもご参照ください。

access.redhat.com

RHEL 8 で利用できる Python

RHEL 8 では、必要な Python をインストールして使います。

リポジトリ 利用できるPython パッケージ名
rhel-8-for-x86_64-baseos-rpms 3.6.8 platform-python
rhel-8-for-x86_64-appstream-rpms 2.7.17 python2
rhel-8-for-x86_64-appstream-rpms 3.6.8 python36
rhel-8-for-x86_64-appstream-rpms 3.8.0 python38

AppStream から提供されているものはライフサイクルに注意が必要です。

Pythonのバージョン ライフサイクル
3.6 RHEL 8 と同じ
2.7 2024年6月まで
3.8 2023年5月まで

詳しくはこちらのドキュメントをご確認ください。

access.redhat.com

access.redhat.com

access.redhat.com

Ansible Engine が使う Python

Red Hat が提供する Ansible Engine は、それぞれこれらのリポジトリから利用できます。

RHEL リポジトリ
RHEL 7 rhel-7-server-ansible-2-rpms
RHEL 8 ansible-2-for-rhel-8-x86_64-rpms

2020年10月30日現在の最新版である 2.9.14 では、それぞれこのような依存関係となっています。追加で Python の実行環境をインストールしなくても利用できることがわかります。

RHEL 7

# yum deplist ansible-2.9.14
読み込んだプラグイン:product-id, search-disabled-repos, subscription-manager
パッケージ    : ansible.noarch 2.9.14-1.el7ae
  依存性      : /usr/bin/python2
   provider: python.x86_64 2.7.5-89.el7
  依存性      : PyYAML
   provider: PyYAML.x86_64 3.10-11.el7
  依存性      : python(abi) = 2.7
   provider: python.x86_64 2.7.5-89.el7
  依存性      : python-jinja2
   provider: python-jinja2.noarch 2.7.2-4.el7
  依存性      : python-paramiko
   provider: python-paramiko.noarch 2.1.1-9.el7
  依存性      : python-six
   provider: python-six.noarch 1.9.0-2.el7
  依存性      : python2-cryptography
   provider: python2-cryptography.x86_64 1.7.2-2.el7
  依存性      : sshpass
   provider: sshpass.x86_64 1.06-2.el7

RHEL 8

# dnf deplist ansible-2.9.14
Updating Subscription Management repositories.
メタデータの期限切れの最終確認: 0:06:45 時間前の 2020年10月30日 14時16分47秒 に実施しました。
package: ansible-2.9.14-1.el8ae.noarch
  dependency: /usr/libexec/platform-python
   provider: platform-python-3.6.8-23.el8.i686
   provider: platform-python-3.6.8-23.el8.x86_64
  dependency: python(abi) = 3.6
   provider: platform-python-3.6.8-23.el8.i686
   provider: platform-python-3.6.8-23.el8.x86_64
  dependency: python3-PyYAML
   provider: python3-pyyaml-3.12-12.el8.x86_64
  dependency: python3-cryptography
   provider: python3-cryptography-2.3-3.el8.x86_64
  dependency: python3-jinja2
   provider: python3-jinja2-2.10.1-2.el8_0.noarch
  dependency: python3-six
   provider: python3-six-1.11.0-8.el8.noarch
  dependency: sshpass
   provider: sshpass-1.06-3.el8ae.x86_64
   provider: sshpass-1.06-3.el8ae.x86_64

Ansible Tower が使う Python

Ansible Tower は Web UI やバックグラウンドプロセスを動作させるために Python の実行環境を利用します。

Ansible Tower 3.5 からは Python 3 を利用して動作するようになりました。RHEL 7 では標準で搭載されていないため、バージョンによって複雑な事情が生じてしまっています。

RHEL Towerのバージョン Pythonの実行環境
RHEL 7.4〜7.6 3.5, 3.6 rh-python36
RHEL 7.4〜7.6 3.7 Tower はインストールできない
RHEL 7.7〜 3.5, 3.6 rh-python36
RHEL 7.7〜 3.7 python3
RHEL 8 3.5, 3.6, 3.7 python36

最新版の Ansible Tower 3.7 では RHEL 7.7 以降で利用できるようになった python3 を利用するようになったため、RHEL 7.6 以前の OS のバージョンでは動作しなくなりました。

Ansible Tower から呼び出される Ansible Engine が使う Python

Ansible Tower をインストールしますと2つの virtual environment が作成されます。

venvのパス 用途
/var/lib/awx/venv/ansible/ Ansible Engine 実行環境
/var/lib/awx/venv/awx/ Web UI やバックグラウンドプロセスの実行環境

Ansible Tower からジョブテンプレートを実行しますと、この Ansible Engine 実行環境を使って ansible-playbook コマンドを実行します。この venv では RHEL にインストールされている Ansible Engine を参照しつつ、追加で必要なモジュールが利用できるものとなっています。例えば Windows サーバへの接続に必要な pywinrm などが使えるようになっており、このように確認することができます。

# su - awx
$ source /var/lib/awx/venv/ansible/bin/activate
(ansible) $ pip freeze -l
...
(ansible) $ deactivate
$

この venv は目的に応じて追加で作成して Tower から利用することもできます。同じチームの八木澤(ひよこ大佐)が以前書いた記事に詳しく説明されていますのでご覧ください。

rheb.hatenablog.com

RHEL 7 でも Python 3 の Ansible を利用したいというときには、例えばこのように作成することができます。RHEL 7.9 + Ansible Tower 3.7.3 で実行してみました。python3-devel パッケージが必要なことから、rhel-7-server-optional-rpms を有効にしています。

# subscription-manager repos --enable rhel-7-server-optional-rpms
# yum install gcc python3-devel openssl-devel
# python3 -m venv /var/lib/awx/venv/mypy3
# source /var/lib/awx/venv/mypy3/bin/activate
(mypy3) # umask 0022
(mypy3) # pip3 install python-memcached psutil ansible==2.9.14
(mypy3) # deactivate

pip3 コマンドから ansible をインストールしようとしますと、バージョンを指定しないときは 2.10 を入れようとします。2.10 はこの記事の執筆時点(2020年10月30日)ではサポートしていませんのでご注意ください。

いまの手順では pip3 コマンドから必要最低限のモジュールのみをインストールしましたが、追加で必要とするモジュールを利用したいということがありましたら、deactivate して抜ける前にインストールしてください。

この venv を使ってジョブテンプレートを実行してみます。Ansible Tower の Web UI から参照できるようにするためには、一度ログアウトしてログインし直す必要があります。ジョブテンプレートの画面で、ANSIBLE ENVIRONMENT からプルダウンで出てくるので選択します。

f:id:sugitk:20201030152732p:plain

このジョブテンプレートを実行しますと、先ほど作成した venv (mypy3) を利用して実行されていることがわかります。

f:id:sugitk:20201030152745p:plain

Ansible でよく起こる実行環境の問題

venv を作らずに RHEL のシステムワイドの Python 実行環境に pip コマンドで Ansible をインストールして、実行した際にトラブルになるという事例がよくあります。

一番問い合わせを受けるエラーはこちらのものです。Python 2.7 と 3 が混在している場合に発生します。venv できちんと切り分けて実行環境を管理することで解消します。

AttributeError: module 'enum' has no attribute 'IntFlag'

おわりに

Python の開発元での Python 2.7 のサポートが終了したことから、Python 3 に早く移行したいというお問い合わせもよくいただきます。

www.python.org

RHEL でのサポートについてはこちらにまとまっておりますのでご参照ください。開発元でのサポート終了に関わらず、RHEL としてはそのライフサイクルに従ってサポートが提供されます。

access.redhat.com

全ての場面で完全に Python 2.7 を捨てるには、RHEL 8 への移行をお勧めします。

Ansible Towerの評価ライセンスリクエストはこちらからご利用いただけますのでお試しください。

www.ansible.com

Happy Automation!

* 各記事は著者の見解によるものでありその所属組織を代表する公式なものではありません。その内容については非公式見解を含みます。