anisble部署及包衝突處理

anyux發表於2024-08-15

用pip3 安裝ansible

查詢使用 pip 工具可以安裝的 Python 包:

1. PyPI 官方網站

  • 網址: https://pypi.org/
  • 使用方法: 你可以在 PyPI 官網直接搜尋任何 Python 包的名稱。每個包的頁面通常會列出詳細的資訊,包括最新版本、歷史版本、文件、安裝說明以及依賴關係等。

2. pip 工具的 install 命令

  • 命令: pip install package-name
  • 使用方法: 如果你知道包的確切名稱,可以直接嘗試安裝它。如果包存在且版本匹配,它將被安裝。如果你不確定包名,可以先在 PyPI 網站上確認

4. Python 包文件或專案主頁

  • 網址: 許多開源專案都有自己的官方網站或 GitHub 倉庫,這些網站通常會提供詳細的文件和安裝指南。例如,Ansible 的文件可以在 Ansible 的官方網站GitHub 倉庫 上找到。

  • 以ansible官方網站為例,進入參考_附錄/釋出_和_維護頁面,找到社群變更日誌

  • 發現下圖中,示例2.17版本的ansible-core對應10.x版本的ansible社群版本,也可以點選圖表中連結檢視github中的示例檔案

  • Ansible Community Package Release Status Core version dependency
    11.0.0 In development (unreleased) 2.18
    10.x Changelogs Current 2.17
    9.x Changelogs Minor/patch releases (EOL Nov 2024) 2.16
    8.x Changelogs Unmaintained (end of life) 2.15
    7.x Changelogs Unmaintained (end of life) 2.14
    6.x Changelogs Unmaintained (end of life) 2.13
    5.x Changelogs Unmaintained (end of life) 2.12
    4.x Changelogs Unmaintained (end of life) 2.11
    3.x Changelogs Unmaintained (end of life) 2.10
    2.10 Changelogs Unmaintained (end of life) 2.10
  • 參考_附錄/釋出_和_維護頁面查詢文字連結Ansible Roadmap,此頁面包含ansible社群版本的路線圖,進入Ansible 專案 10.0,可以檢視到從ansible-core2.17.x一點點推進到ansible10.x的過程

  • 參考_附錄/釋出_和_維護頁面查詢文字連結ansible-core Roadmaps,此頁面包含ansible-core版本的路線圖,進入Ansible-core 2.17,可以檢視到ansible-core2.17發部過程

  • 以github頁面為例,進入ansible頁面,進入release頁面,點選full changelog的連結,在頁面中有檔案setup.py,setup.cfg,pyproject.toml,requirements.txt這裡包含了ansible對於python版本,pip包的依賴資訊

# Note: this requirements.txt file is used to specify what dependencies are
# needed to make the package run rather than for deployment of a tested set of
# packages.  Thus, this should be the loosest set possible (only required
# packages, not optional ones, and with the widest range of versions that could
# be suitable)
jinja2 >= 3.0.0
PyYAML >= 5.1  # PyYAML 5.1 is required for Python 3.8+ support
cryptography
packaging
# NOTE: resolvelib 0.x version bumps should be considered major/breaking
# NOTE: and we should update the upper cap with care, at least until 1.0
# NOTE: Ref: https://github.com/sarugaku/resolvelib/issues/69
# NOTE: When updating the upper bound, also update the latest version used
# NOTE: in the ansible-galaxy-collection test suite.
resolvelib >= 0.5.3, < 1.1.0  # dependency resolver used by ansible-galaxy

5. pip install 命令

  • 命令: pip install package-name==x.x.x
  • 使用方法: 這個命令可以安裝指定版本的pypi包。

透過前4步的操作,可以明確,想要安裝ansible下2.17版本的ansible-core,透過pypi要安裝ansible的具體版本,又透過pypi官網,可以查詢到ansible的版本號,那麼可以直接安裝了,如果想要歷史版本,可以直接檢視release的資訊

pip3 install ansible==10.3.0

6. pip show 命令

  • 命令: pip show package-name
  • 使用方法: 這個命令提供了關於已安裝包的詳細資訊,包括版本號、安裝位置、依賴關係等。
pip show ansible

Name: ansible
Version: 10.3.0
Summary: Radically simple IT automation
Home-page: https://ansible.com/
Author: Ansible, Inc.
Author-email: info@ansible.com
License: GPL-3.0-or-later
Location: /usr/local/lib/python3.10/dist-packages
Requires: ansible-core
Required-by: 

#檢視ansible版本資訊
ansible --version 

ansible [core 2.17.3]
config file = None
configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
executable location = /usr/local/bin/ansible
python version = 3.10.14 (main, Apr  6 2024, 18:45:05) [GCC 9.4.0] (/usr/bin/python3.10)
jinja version = 3.1.4
libyaml = False

到這裡ansible部署完成了.

但是ansible配置使用的libyaml是Flase,這表示ansible解析yaml檔案時,未使用些模組,而是用python自有的yaml解析器,效率低於C語言編寫的libyaml模組

解決libyaml未開啟問題

libyaml 是一個用 C 語言編寫的 YAML 解析器,它比純 Python 的 YAML 解析器 (PyYAML) 更快。

從系統安全和穩定性的角度來說,通常建議先嚐試使用 pip 來解除安裝或升級 Python 包,如果遇到問題再考慮使用 apt 或其他系統包管理器。這種做法有以下幾個原因:

1. 包的來源

  • pip 安裝的包: 如果包是透過 pip 安裝的,它的管理和依賴資訊都由 pip 處理

  • apt 安裝的包: apt 安裝的包可能與系統的其他軟體有依賴關係。

2. 避免依賴衝突

  • 首先使用 pip: 如果你透過 pip 安裝了某個包,並希望升級或解除安裝,首先使用 pip 可以避免系統與 Python 環境之間的依賴衝突。pip 能準確處理 Python 包的依賴關係,防止殘留檔案或不完整的解除安裝。

  • 再使用 apt: 如果 pip 處理失敗或遇到與系統包的衝突,可以再考慮使用 apt。這是因為 apt 可以更加全面地處理系統級別的依賴關係,確保系統的穩定性。

在安裝升級時,遇到錯誤如下

pip install pyyaml==6.0.2
Collecting pyyaml==6.0.2
  Downloading PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (2.1 kB)
Downloading PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (751 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 751.2/751.2 kB 20.0 MB/s eta 0:00:00
WARNING: Error parsing dependencies of distro-info: Invalid version: '0.23ubuntu1'
WARNING: Error parsing dependencies of python-debian: Invalid version: '0.1.36ubuntu1'
Installing collected packages: pyyaml
  Attempting uninstall: pyyaml
    Found existing installation: PyYAML 5.3.1
error: uninstall-distutils-installed-package

× Cannot uninstall PyYAML 5.3.1
╰─> It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.

error: uninstall-distutils-installed-package

錯誤分析:

  • distutils: distutils 是 Python 的標準打包工具,用於安裝 Python 包。由於它是直接寫入到系統的,而不像 pip 那樣管理包的後設資料,pip 無法準確識別透過 distutils 安裝的包的檔案位置。

  • Partial Uninstall: pip 試圖解除安裝舊版本的 PyYAML,但由於它是透過 distutils 安裝的,pip 不知道哪些檔案屬於舊版本,因此無法安全地解除安裝它。這會導致潛在的“部分解除安裝”,即某些檔案可能會保留在系統中,這會影響新版本的安裝和執行。

  • 也就是說,這個pyyaml包不是pip安裝的,想解除安裝時,牽扯到了distutils,此時需要使用apt來解決,將老版本的pyyaml刪除

解決方案:

apt 解除安裝 pyyaml,pyyaml是對應的pip的包名稱,對應的apt的包名稱是python3-yaml

這個pip包與apt包如何找到對應關係呢

搜尋引擎,官方文件,這種關聯關係很模糊,不好友

apt remove -y python3-yaml

手動安裝pyyaml

pip3 install pyyaml

檢查pyyaml部署位置,是否啟動libyaml

python3 -c "import yaml; print(yaml.__file__)"

#檢查是否啟用libyaml
python3 -c "import yaml; print(yaml.__with_libyaml__)"

檢查ansible是否啟動libyaml解析器

ansible --version 
ansible [core 2.17.3]
  config file = None
  configured module search path = ['/root/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /usr/local/lib/python3.10/dist-packages/ansible
  ansible collection location = /root/.ansible/collections:/usr/share/ansible/collections
  executable location = /usr/local/bin/ansible
  python version = 3.10.14 (main, Apr  6 2024, 18:45:05) [GCC 9.4.0] (/usr/bin/python3.10)
  jinja version = 3.1.4
  libyaml = True

python,Pyyaml,libyaml三者關係

PyYAML 是 Python 中最常用的 YAML 解析庫,它是用純 Python 編寫的,並可以選擇性地使用 libyaml 作為底層加速器

libyaml是由C編寫的,部署時透過apt或原始碼安裝,這就要求必須有libyaml和libyaml-dev包

apt list --installed  | grep yaml

libyaml-0-2/focal,now 0.2.2-1 amd64 [installed,automatic]
libyaml-dev/focal,now 0.2.2-1 amd64 [installed]

#檢視libyaml-0-2資訊
apt show libyaml-0-2
Package: libyaml-0-2
Version: 0.2.2-1
Priority: important
Section: libs
Source: libyaml
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Anders Kaseorg <andersk@mit.edu>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 152 kB
Depends: libc6 (>= 2.14)
Homepage: https://github.com/yaml/libyaml
Task: minimal, ubuntu-core
Download-Size: 48.9 kB
APT-Manual-Installed: no
APT-Sources: http://mirrors.aliyun.com/ubuntu focal/main amd64 Packages
Description: Fast YAML 1.1 parser and emitter library
 LibYAML is a C library for parsing and emitting data in YAML 1.1, a
 human-readable data serialization format.

#檢視libyaml-dev資訊
apt show libyaml-dev
Package: libyaml-dev
Version: 0.2.2-1
Priority: extra
Section: libdevel
Source: libyaml
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Anders Kaseorg <andersk@mit.edu>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 257 kB
Depends: libyaml-0-2 (= 0.2.2-1)
Suggests: libyaml-doc
Homepage: https://github.com/yaml/libyaml
Download-Size: 58.2 kB
APT-Manual-Installed: yes
APT-Sources: http://mirrors.aliyun.com/ubuntu focal/main amd64 Packages
Description: Fast YAML 1.1 parser and emitter library (development)
 LibYAML is a C library for parsing and emitting data in YAML 1.1, a
 human-readable data serialization format.
 .
 This package contains development headers and static libraries.

This package contains development headers and static libraries.

這裡是說dev包將標頭檔案靜態庫包含在內了,也是PyYAML安裝時,會自動啟用libyaml,否則無法啟用這個libyaml

即按libyaml,PyYAML的順序部署,libyaml是系統級別的元件

pyyaml官網

https://pyyaml.org/

https://pyyaml.org/wiki/PyYAMLDocumentation

https://pyyaml.org/wiki/LibYAML

相關文章