使用 Ansible 离线安装 python3-pip、python3-distutils 和 PyMySQL

在某些生产或隔离环境中,目标机器无法访问互联网,这就要求我们通过离线方式部署 Python 相关组件。本文将详细说明如何使用 Ansible 实现以下内容的离线安装

  • python3-distutils(Python 标准库依赖)
  • python3-pip(Python 包管理工具)
  • PyMySQL(Python 操作 MySQL 的模块)

🧰 适用场景

  • 目标机器不能联网
  • 控制机可以联网并能打包所需文件
  • 目标系统为基于 Debian/Ubuntu 的 Linux 发行版(如 Ubuntu 20.04)
  • 已配置好 Ansible 环境

📁 推荐目录结构

ansible-offline-install/

├── files/

│ ├── get-pip.py # pip 安装脚本(适用于 Python 3.8)

│ ├── python3-distutils_*.deb # python3-distutils 离线包

│ └── PyMySQL-1.1.0-py3-none-any.whl # PyMySQL wheel 文件

├── install_offline_python_packages.yml # Ansible Playbook

└── inventory.ini # 主机清单


🖥️ 步骤一:准备阶段(在有网络的机器上操作)

✅ 1. 下载 get-pip.py(用于安装 pip)

bash 复制代码
curl https://bootstrap.pypa.io/pip/3.8/get-pip.py -o files/get-pip.py

⚠️ 注意:确保下载的是支持 Python 3.8 的版本。


✅ 2. 下载 python3-distutils.deb

bash 复制代码
mkdir -p files

apt update

apt download python3-distutils

mv python3-distutils*.deb files/

你也可以手动从 http://archive.ubuntu.com或镜像站下载对应版本的 .deb 文件。

示例:

bash 复制代码
python3-distutils_3.8.2-1ubuntu1_all.deb

✅ 3. 下载 PyMySQL-1.1.0-py3-none-any.whl

bash 复制代码
pip download PyMySQL

mv PyMySQL-*.whl files/

你也可以直接下载:

https://files.pythonhosted.org/packages/ed/9c/820e9ccc5bce7077a969d32f5a9c1ec9540cbe2acbfc96dd3f8d915a5a6a6/PyMySQL-1.1.0-py3-none-any.whl


📋 步骤二:编写 Ansible Playbook

install_offline_python_packages.yml

bash 复制代码
---
- name: 安装 pip 并离线安装 PyMySQL
  hosts: pymysql
  become: yes
  vars:
    wheel_file: "PyMySQL-1.1.0-py3-none-any.whl"

  tasks:
    - name: 拷贝 python3-distutils 的 .deb 文件到目标主机
      copy:
        src: "files/python3-distutils_3.8.10-0ubuntu1~20.04_all.deb"
        dest: "/tmp/python3-distutils.deb"
        mode: "0644"

    - name: 安装 python3-distutils 离线包
      apt:
        deb: "/tmp/python3-distutils.deb"

    - name: 验证 distutils 是否可用
      command: python3 -c "from distutils import cmd; print('OK')"
      register: result
      changed_when: false

    - name: 输出验证结果
      debug:
        msg: "{{ result.stdout }}"

    - name: 将 get-pip.py 拷贝到目标主机
      copy:
        src: "files/get-pip.py"
        dest: "/tmp/get-pip.py"
        mode: "0644"

    - name: 使用 get-pip.py 安装 pip
      command: python3 /tmp/get-pip.py
      args:
        chdir: /tmp/
      register: pip_install_result
      ignore_errors: no

    - name: 显示 pip 安装结果
      debug:
        msg: "{{ pip_install_result.stdout }}"

    - name: 将 PyMySQL 的 .whl 文件拷贝到目标主机
      copy:
        src: "files/PyMySQL-1.1.1-py3-none-any.whl"
        dest: "/tmp/{{ wheel_file }}"
        mode: "0644"

    - name: 安装 PyMySQL(离线方式)
      pip:
        name: "/tmp/{{ wheel_file }}"
        executable: pip3
      environment:
        PIP_TARGET: /usr/local/lib/python3.8/dist-packages/

    - name: 验证是否成功导入 pymysql
      command: python3 -c "import pymysql; print(pymysql.__version__)"
      register: pymysql_version
      ignore_errors: no

    - name: 输出 PyMySQL 版本
      debug:
        msg: "PyMySQL version: {{ pymysql_version.stdout }}"

🖥️ 步骤三:配置主机清单 inventory.ini

bash 复制代码
[offline_servers]

jw001 ansible_host=192.168.1.101 ansible_user=jw ansible_ssh_pass=your_password

jw002 ansible_host=192.168.1.102 ansible_user=jw ansible_ssh_pass=your_password

如果你使用密钥登录,请去掉 ansible_ssh_pass


▶️ 步骤四:执行 Playbook

确保你在项目根目录下运行:

bash 复制代码
cd ansible-offline-install

ansible-playbook -i inventory.ini install_offline_python_packages.yml

✅ 成功输出示例

bash 复制代码
TASK [输出验证结果] ************************************

ok: [jw001] => {

"msg": "OK"

}



TASK [输出 pip 版本] *************************************

ok: [jw001] => {

"msg": "pip 23.0.1 from /usr/lib/python3/dist-packages/pip (python 3.8)"

}



TASK [输出 PyMySQL 版本] *********************************

ok: [jw001] => {

"msg": "PyMySQL version: 1.1.0"

}

📝 总结

组件 安装方式 作用
python3-distutils .deb文件安装 支持 Python 标准库中 distutils 模块
python3-pip 使用get-pip.py脚本安装 提供 Python 包管理能力
PyMySQL 使用.whl文件安装 实现 Python 对 MySQL 的连接与操作

📦 可选:打包整个部署环境

你可以将整个 ansible-offline-install/ 打包成压缩包,方便分发给其他团队或客户:

bash 复制代码
tar czvf ansible-offline-python-deploy.tar.gz ansible-offline-install/

📌 常见问题排查

问题 原因 解决方法
ModuleNotFoundError: No module named 'distutils' 缺少python3-distutils 安装对应的.deb文件
Could not find pip script pip 未正确安装 检查get-pip.py是否兼容 Python 版本
community.mysql.mysql_query requires PyMySQL 缺少 PyMySQL 安装 PyMySQL 的.whl文件

✅ 结语

通过 Ansible 的强大功能和离线包机制,我们可以在没有网络连接的目标机器上完成 Python 环境的初始化,包括安装 pip、PyMySQL 等关键组件。这对于构建安全、隔离的生产环境非常有用。