zaki work log

作業ログやら生活ログやらなんやら

[Ansible] ターゲットノードのvenvのPythonを指定して実行する (interpreter_python / ansible_python_interpreter / PYTHONPATH)

コントロールノードでなくターゲットノードで(pipで追加パッケージが必要などの理由で)venvを使いたい場合の方法について。
といっても、venvの中にあるPythonインタプリタのパスをinterpreter_pythonなどで指定すればOK。

Python2/Python3の切り替えでインタプリタを指定するという趣旨の記事が多いというか自分も以前書いてたりするけど、Pythonの仮想環境の指定にも使えたので動作確認した結果をまとめた。

ちなみに「『ターゲットノードでvenvを使う』というドンピシャな情報」を見つけられなかっただけなので、もしこの目的のための設定項目が別にあるなら教えてください…

お題はここでも使ったcommunity.kubernetesコレクションに含まれるk8s_cluster_infoを使ってクラスタ情報を得るというもの。

docs.ansible.com

環境

ansible-playbookを実行するコントロールノードはCentOS 7で、処理する接続先のターゲットノードはFedora 34。
ターゲットのPythonは、デフォルトでは/usr/bin/pythonが参照されるけど、k8s_infoの実行に必要なopenshiftパッケージはシステムワイドにはインストールせずに/home/zaki/tmp/venvに作った仮想環境に入れている、という状態。

ベースとなるplaybookは以下の通り。

---
- hosts: linux
  gather_facts: false

  tasks:
    - name: get cluster info
      community.kubernetes.k8s_cluster_info:
      register: result

    - name: print result
      debug:
        msg: "{{ result.version }}"

以下、いくつかの方法を書いてるけど、どれか一つを採用すればOK

ansible.cfg

defaultsセクションのinterpreter_pythonpythonのパスを指定する

[defaults]
interpreter_python = /home/zaki/tmp/venv/bin/python

全てのターゲットノードでパスが同じであればこれが一番楽。

ターゲットノード毎に設定

ホスト変数を使えばOK
ansible.cfgと異なり、指定する変数名はansible_python_interpreterにパスをセットする。

[linux]
fedora-node ansible_python_interpreter=/home/zaki/tmp/venv/bin/python

ターゲットノードによってvenvのパスが異なる場合で、全ての処理で常に同じPythonインタプリタを使うのであればこれで。

playやtask単位

ホスト変数と同じ要領で、playやtaskの定義でvarsなどを使って変数にパス指定すればOK

    - name: get cluster info
      community.kubernetes.k8s_cluster_info:
      vars:
        ansible_python_interpreter: /home/zaki/tmp/venv/bin/python
      register: result

処理(taskやrole)によって個別にインタプリタを切り替えたい場合はこれで指定する。

パッケージパスの指定

Pythonインタプリタでなく、環境変数PYTHONPATHにパッケージのパスを指定する方法でもいける。

    - name: get cluster info
      community.kubernetes.k8s_cluster_info:
      environment:
        PYTHONPATH: /home/zaki/venv/lib/python3.9/site-packages/
      register: result

ただしパスを見ての通りPythonのサブバージョンまでディレクトリ名に含まれてるので環境情報を把握しておく必要がある。


ちなみにansible-playbookの実行結果はこんな感じ。
戻り値の詳細はドキュメント参照。

ok: [fedora-node] => 
  msg:
    client: 0.12.0
    server:
      kubernetes:
        buildDate: '2021-01-21T01:11:42Z'
        compiler: gc
        gitCommit: faecb196815e248d3ecfb03c680a4507229c2a56
        gitTreeState: clean
        gitVersion: v1.20.2
        goVersion: go1.15.5
        major: '1'
        minor: '20'
        platform: linux/amd64

サンプルコード

github.com