一、前置准备:CentOS7 基础网络与 Yum 源配置
在安装 Python3 之前,必须先确保系统网络通畅且软件源可用。CentOS 7.5 属于历史版本,官方基础源已下线,需替换为清华 Vault 归档源。

1.1 网卡与 DNS 配置
编辑 NAT 模式网卡配置文件,配置固定 IP 与网关:
vi /etc/sysconfig/network-scripts/ifcfg-ens33
配置参考:


plaintext
DEVICE=ens33
TYPE=Ethernet
BOOTPROTO=none
ONBOOT=yes
IPADDR=192.168.1.241
PREFIX=24
GATEWAY=192.168.1.254
DNS1=10.91.87.88

配置 DNS 解析文件使其立即生效:

vi /etc/resolv.conf

# 写入DNS服务器地址

nameserver 10.91.87.88

配置物理机网络共享,将本地网络共享给 VMnet8 虚拟网卡,确保虚拟机可访问外网。完成后重启网卡并验证连通性:

systemctl restart network

ping www.baidu.com

1.2 替换 CentOS 7.5 Vault 软件源
CentOS 7.5 官方源已停止维护,替换为清华大学开源镜像站归档源:
# 备份原有repo文件
mv /etc/yum.repos.d/* /opt

# 新建Vault源配置文件
vi /etc/yum.repos.d/CentOS-Vault.repo

写入以下完整源配置:
[C7.5.1804-base]
name=CentOS-7.5.1804 - Base
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.5.1804/os/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[C7.5.1804-updates]
name=CentOS-7.5.1804 - Updates
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.5.1804/updates/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[C7.5.1804-extras]
name=CentOS-7.5.1804 - Extras
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.5.1804/extras/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[C7.5.1804-centosplus]
name=CentOS-7.5.1804 - CentOSPlus
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.5.1804/centosplus/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

[C7.5.1804-fasttrack]
name=CentOS-7.5.1804 - Fasttrack
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.5.1804/fasttrack/$basearch/
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-7
enabled=1

执行yum makecache生成缓存,确认源可用。

二、Python3.6.8 编译安装全流程
CentOS7 默认自带 Python2.7,需手动编译安装 Python3.6,且不影响系统原有 Python 环境。
2.1 获取安装包
方式一:在线下载
cd /opt
mkdir ph && cd ph
wget https://www.python.org/ftp/python/3.6.8/Python-3.6.8.tgz
方式二:离线 FTP 上传(适合无外网场景)
控制节点安装 vsftpd 并开启匿名上传权限:
yum -y install vsftpd
vi /etc/vsftpd/vsftpd.conf
# 启用以下配置(取消注释)
write_enable=YES
anon_upload_enable=YES
anon_mkdir_write_enable=YES

# 授权pub目录
chown ftp /var/ftp/pub
chmod 777 /var/ftp/pub

# 关闭防火墙与SELinux
systemctl start vsftpd
setenforce 0
systemctl stop firewalld
物理机访问ftp://192.168.1.241,将安装包拖入 pub 目录,再复制到 /opt/ph 并解压:


cp /var/ftp/pub/Python-3.6.8.tgz /opt/ph
cd /opt/ph
tar -xzf Python-3.6.8.tgz
2.2 安装编译依赖
一次性安装 Python 编译所需的全部依赖库:
yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gcc make
2.3 编译安装
指定安装路径为/usr/local/python3,避免与系统 Python 冲突:
mkdir /usr/local/python3
cd /opt/ph/Python-3.6.8
./configure prefix=/usr/local/python3
make && make install


编译过程约 10 分钟,耐心等待无报错即可。
2.4 配置全局环境变量
将 Python3 路径加入系统环境变量,实现全局调用:
vi /etc/profile
# 文件末尾追加
export PYTHON=/usr/local/python3
export PATH=$PYTHON/bin:$PATH
刷新配置使其生效:
source /etc/profile
2.5 安装验证
任意目录执行python3,出现交互界面即安装成功:
python3
# Python 3.6.8 (default, May  6 2024, 21:57:18)
# [GCC 4.8.5 20150623 (Red Hat 4.8.5-44)] on linux
# Type "help", "copyright", "credits" or "license" for more information.
# >>>

三、Python 运维核心依赖库安装与测试

OpenStack API 调用核心依赖requests库,jsontime为 Python 内置库无需安装。

3.1 升级 pip 并安装 requests

# 升级pip工具
python3 -m pip install --upgrade pip

# 安装HTTP请求库requests
pip3 install requests

3.2 基础功能测试

测试 requests 库

新建test-requests.py

import requests
response = requests.get('https://www.baidu.com')
print(response.status_code)

执行后输出200则表示库安装正常。

测试 JSON 解析

新建test-json.py

import json

# JSON解析测试
json_data = '{"name": "John", "age": 30, "city": "New York"}'
try:
    data = json.loads(json_data)
    print("JSON success:", data)
except json.JSONDecodeError:
    print("JSON failure: data format error")

# JSON序列化测试
data_to_encode = {'name': 'Jane', 'age': 25, 'city': 'Los Angeles'}
try:
    encoded_data = json.dumps(data_to_encode)
    print("JSON encode success:", encoded_data)
except (TypeError, OverflowError) as e:
    print("JSON encode failure:", e)

执行后正常输出解析与序列化结果即为正常。

四、OpenStack API 运维核心原理

4.1 API 自动化运维的价值

OpenStack 所有组件均提供 RESTful API,通过 Python 调用 API 可实现资源批量创建、自动清理、状态监控等运维自动化需求,比 Dashboard 操作效率提升数十倍,也是云计算赛项的核心考点。

4.2 Keystone 认证流程

OpenStack 采用 Token 认证机制:

  1. 客户端向 Keystone(5000 端口)发送账号密码,申请认证 Token
  2. Keystone 验证通过后返回有效 Token
  3. 后续调用 Nova、Glance、Neutron 等组件 API 时,请求头携带该 Token 即可完成鉴权

4.3 核心编程思想

  • 异常处理:通过try-except捕获网络异常、认证失败等错误,避免脚本崩溃
  • 面向对象封装:将云主机操作封装为类,代码结构清晰、可复用性强
  • JSON 数据处理:API 请求体与返回值均为 JSON 格式,需熟练掌握序列化与解析

五、实战:Python 脚本实现云主机自动化创建

5.1 需求说明(赛题原题)

在 controller 节点编写create_vm.py,调用 OpenStack API 实现:

  1. 若已存在同名虚拟机,先执行删除
  2. 使用指定镜像、规格、子网创建 1 台名为pvm1的云主机
  3. 创建成功后输出 “创建云主机成功”

5.2 完整代码与解析

import json
import requests
import time

# ========== 第一步:获取Keystone认证Token ==========
try:
    auth_url = "http://20.0.0.10:5000/v3/auth/tokens"
    auth_body = {
        "auth": {
            "identity": {
                "methods": ["password"],
                "password": {
                    "user": {
                        "domain": {"name": "demo"},
                        "name": "admin",
                        "password": "000000"
                    }
                }
            },
            "scope": {
                "project": {
                    "domain": {"name": "demo"},
                    "name": "admin"
                }
            }
        }
    }
    headers = {"Content-Type": "application/json"}
    # 从响应头中提取Token
    Token = requests.post(auth_url, json.dumps(auth_body), headers=headers).headers["X-Subject-Token"]
    headers = {"X-Auth-Token": Token, "Content-Type": "application/json"}
    print("认证成功,Token已获取")
except Exception as e:
    print(f"认证失败:{str(e)}")
    exit(0)


# ========== 第二步:封装云主机操作类 ==========
class VmManager:
    def __init__(self, headers):
        self.headers = headers
        self.nova_url = "http://20.0.0.10:8774/v2.1"
        self.glance_url = "http://20.0.0.10:9292/v2"
        self.neutron_url = "http://20.0.0.10:9696/v2.0"
        self.vm_name = "pvm1"
        self.image_name = "pvm_image"
        self.flavor_name = "pvm_flavor"
        self.network_name = "pvm_intsubnet"

    def delete_exist_vm(self):
        """删除同名虚拟机"""
        res = requests.get(f"{self.nova_url}/servers", headers=self.headers)
        for vm in res.json()['servers']:
            if vm['name'] == self.vm_name:
                requests.delete(f"{self.nova_url}/servers/{vm['id']}", headers=self.headers)
                print(f"已删除同名虚拟机:{self.vm_name}")
                time.sleep(3)  # 等待删除完成

    def get_image_id(self):
        """获取镜像ID"""
        res = requests.get(f"{self.glance_url}/images", headers=self.headers)
        for img in res.json()['images']:
            if img['name'] == self.image_name:
                self.image_id = img['id']
                return
        raise Exception(f"未找到镜像:{self.image_name}")

    def get_flavor_id(self):
        """获取规格ID"""
        res = requests.get(f"{self.nova_url}/flavors", headers=self.headers)
        for flavor in res.json()['flavors']:
            if flavor['name'] == self.flavor_name:
                self.flavor_id = flavor['id']
                return
        raise Exception(f"未找到规格:{self.flavor_name}")

    def get_network_id(self):
        """获取子网ID"""
        res = requests.get(f"{self.neutron_url}/networks", headers=self.headers)
        for net in res.json()['networks']:
            if net['name'] == self.network_name:
                self.network_id = net['id']
                return
        raise Exception(f"未找到网络:{self.network_name}")

    def create_vm(self):
        """创建云主机主方法"""
        self.delete_exist_vm()
        self.get_image_id()
        self.get_flavor_id()
        self.get_network_id()

        # 构造创建请求体
        data = {
            "server": {
                "name": self.vm_name,
                "imageRef": self.image_id,
                "flavorRef": self.flavor_id,
                "networks": [{"uuid": self.network_id}]
            }
        }

        res = requests.post(
            f"{self.nova_url}/servers",
            headers=self.headers,
            data=json.dumps(data)
        )
        if res.status_code in [200, 202]:
            print("创建云主机成功")
        else:
            print(f"创建失败,状态码:{res.status_code},错误信息:{res.text}")


# ========== 第三步:执行创建 ==========
if __name__ == "__main__":
    vm_ops = VmManager(headers)
    vm_ops.create_vm()

5.3 代码核心说明

  1. 认证模块:调用 Keystone v3 接口获取 Token,所有后续 API 请求均携带该 Token
  2. 前置清理delete_exist_vm遍历虚拟机列表,同名则先删除,满足题目要求
  3. 资源查询:分别调用 Glance、Nova、Neutron API,通过名称匹配获取对应资源 ID
  4. 创建执行:构造符合 Nova API 规范的 JSON 请求体,提交创建请求并判断返回状态

六、执行验证与常见排错
6.1 执行步骤
将脚本上传至 controller 节点 /root 目录
确保控制节点 20.0.0.10 的 OpenStack 各服务正常运行
执行脚本:
python3 create_vm.py
输出创建云主机成功后,可登录 Dashboard 验证虚拟机状态。

6.2 常见报错排查

报错现象常见原因解决方法
获取 Token 失败,连接超时控制节点 IP 错误或 Keystone 服务未启动检查 20.0.0.10 连通性,确认 keystone 服务状态
认证返回 401账号、密码、域名不匹配核对 openrc.sh 中的 admin 账号与 domain 配置
未找到镜像 / 规格 / 网络名称与 OpenStack 中实际名称不一致Dashboard 中确认资源名称,严格区分大小写
创建返回 400请求体格式错误检查 JSON 结构,确认 imageRef/flavorRef 字段正确
requests 库导入失败库未安装或 Python 版本不对重新执行 pip3 install requests,确认使用 python3 执行

七、总结与拓展
本文完整实现了从 Python 环境搭建到 OpenStack API 自动化运维的全流程,核心价值在于掌握「API 认证 + 资源查询 + 操作执行」的通用运维开发范式。在此基础上可进一步拓展:
批量创建 / 删除云主机,实现资源批量管理
增加云主机状态查询、开机 / 关机 / 重启功能
对接 Cinder、Neutron API,实现卷挂载、安全组配置等自动化
加入日志与定时任务,实现常态化运维巡检
掌握 Python+OpenStack API,是从手动运维转向自动化运维的关键一步,也是云计算岗位的核心必备技能。

更多推荐