PVE(Proxmox VE)
PVETOOLS
pvetools主要用于pvetools换源,去订阅信息,显示温度,调整cpu功率等
使用前强烈建议先删除企业源
rm /etc/apt/sources.list.d/pve-enterprise.list
安装pvetools
官网源
export LC_ALL=en_US.UTF-8
apt update && apt -y install git && git clone https://github.com/ivanhao/pvetools.git
cd pvetools
./pvetools.sh
国内镜像源
export LC_ALL=en_US.UTF-8
apt update && apt -y install git && git clone https://gitee.com/ZBingK/pvetools.git
cd pvetools
./pvetools.sh
PVE手动换源
pve 8.x的源
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
pve 7.x
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bullseye pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
替换ct源
sed -i.bak 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
#换源后重启web服务,不影响虚拟机运行
systemctl restart pvedaemon
修改web默认语言
编辑文件nano /etc/pve/datacenter.cfg
keyboard: en-us #默认应该有这一行
language: zh_CN #添加这一行,修改默认为简体中文,zh_TW为繁体中文
硬件直通
DANGER
所有硬件直通均可能导致系统开机异常,直通前务必关闭所有虚拟机自启动
首先进入bios,打开vt-x及vt-d 编辑grub
nano /etc/default/grub
# intel cpu
GRUB_CMDLINE_LINUX_DEFAULT="quiet intel_iommu=on video=efifb:off"
# amd cpu
GRUB_CMDLINE_LINUX_DEFAULT="quiet amd_iommu=on video=efifb:off"
# 更新grub
update-grub
打开虚拟机-硬件-添加pci设备
可以用lspci
列出所有pci设备
以下为一些常用的pci设备
集成显卡一般为00:02
硬盘控制器 以SATA
和 Nvme
为主
挂载物理硬盘
查看已有硬盘比如我想挂载/dev/sda 和/dev/sdb到虚拟机100 记录这两个值,然后进行shell
ls /dev/disk/by-id/ #用id方式显示硬盘,后缀带part的是分区,也可以只挂载某一个分区
> ata-WDC_WD20EARZ-00C5XB0_WD-WX72D43AWV52
> ata-WDC_WD20EARZ-00C5XB0_WD-WX72D43AWV52-part1
> ata-WDC_WD20EARZ-00C5XB0_WD-WX72D43AWV52-part2
> ata-WDC_WD20EARZ-00C5XB0_WD-WX72D43AWV52-part3
> ata-WDC_WD20EARZ-00C5XB0_WD-WXU2A23C9Z4R
> ata-WDC_WD20EARZ-00C5XB0_WD-WXU2A23C9Z4R-part1
> ata-WDC_WD20EARZ-00C5XB0_WD-WXU2A23C9Z4R-part2
> ata-WDC_WD20EARZ-00C5XB0_WD-WXU2A23C9Z4R-part3
# 将两个物理硬盘挂载到虚拟机100 sata1和sata2必须为未使用的硬盘看,可以在虚拟机100硬件中查看
qm set 100 --sata1 /dev/disk/by-id/ata-WDC_WD20EARZ-00C5XB0_WD-WX72D43AWV52
qm set 100 --sata2 /dev/disk/by-id/ata-WDC_WD20EARZ-00C5XB0_WD-WXU2A23C9Z4R
VMWare/ESXI 迁移到 PVE
- VMWare 界面将虚拟机关机,然后导出虚拟机,只需要vmdk硬盘即可
- 登录pve,创建新虚拟机记录虚拟机ip,如2000并删除现有硬盘
- 上传vmdk,建议用sftp上传
- 执行命令,导入硬盘后,在硬件选中未添加的硬盘,编辑-添加
qm importdisk 2000 /root/demo.vmdk local-lvm
#推荐 qcow2 可以快照
qm importdisk 2000 /root/demo.vmdk local --format qcow2
5. 修改引导顺序 ,选项-引导顺序
PVE 迁移到 VMWare
PVE 界面上没有将虚拟机导出为 vmdk 文件的途径,只能到 PVE 宿主机的 SHELL 环境里操作。在操作之前得先找到虚拟机所在磁盘,在 PVE 管理页面找到虚拟机配置里磁盘名称,比如 "vm-2002-disk-0",再到 SHELL 下执行下面的命令:
# 找到虚拟机所在磁盘
find / -name vm-2002-disk-0
> /dev/pve/vm-2002-disk-0
# 上面的 /dev/pve/vm-2002-disk-0 实际上是一个链接文件
ls -l /dev/pve/vm-2002-disk-0
> lrwxrwxrwx 1 root root 8 Mar 2 07:07 /dev/pve/vm-2002-disk-0 -> ../dm-10
# 查看实际文件,看到有个 b 标志,表示这是一个块设备文件
ls -l /dev/dm-10
> brw-rw---- 1 root disk 253, 10 Mar 2 07:52 /dev/dm-10
# 用 qemu-img 命令转换,源格式自动判断,目的格式是 vmdk
qemu-img convert -f raw -O vmdk /dev/dm-10 /dev/vm10.vmdk
ls -lh /dev/vm10.vmdk
> -rw-r--r-- 1 root root 7.3G Mar 2 08:03 /dev/vm10.vmdk
得到 vmdk 文件后就简单了,拷贝出来,载入到 VMWare 环境即可
常用命令
systemctl restart pve-cluster
systemctl restart pvedaemon
systemctl restart pveproxy
systemctl restart pvestatd
常见问题处理
PVE修改IP
要改三个地方
nano /etc/network/interfaces
nano /etc/issue
nano /etc/hosts
can't lock file 问题解决
有些时候操作主机重启或停止显示 "can't lock file" 并且拒绝后续操作,可以到命令行界面下执行下面的命令:
# 先看看有没有对应 vmid 的 lock 文件,手工删除
ls -l /run/lock/qemu-server
qm unlock $vmid
rm /run/lock/qemu-server/lock-$vmid.conf
centos7 lxc允许
nano /etc/default/grub #修改 grub,添加下面内容
GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=0"
update-grub #更新引导
reboot #重启
smb挂载失败
<>
及里面的文字都需要替换掉
pvesm add cifs <挂载名称> --server <smb服务器ip> \
--share <文件夹名> \
--username <用户名> \
--password <密码> \
--smbversion 2.0
webAPI
度娘,谷歌都搜了一圈没有找到通过PVE API创建虚拟机的方式, 于是查官网自己试了试,部分代码抄的Sam Liu大佬的作业,感谢大佬。 python代码如下:
import requests
# self-sign CA warning
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
class Pve_api(object):
def __init__(self, ip, username = None, password = None, port = '8006'):
self.ip = ip
self.username = username
self.password = password
self.port = port
self.ticket = None
'''
####### ticket data structure
{
"data":{
"ticket": "PVE:root@pam:xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"cap":{"vms":{"VM.Clone": 1, "VM.Backup": 1, "VM.Config.Options": 1, "VM.Snapshot": 1,…},
"CSRFPreventionToken": "6xxxxxx:/xxxxxxxxxxxxxxxx",
"username": "root@pam"
}
}
'''
#获取ticket
def get_ticket(self):
path = '/api2/json/access/ticket'
url = 'https://' + self.ip + ':' + self.port + path
r = requests.post(url=url, json={"username": self.username, "password": self.password}, verify=False)
self.ticket = r.json() # dict rather than string
return r.json()
#查询节点列表
def ticket_node_list(self):
path = '/api2/json/nodes'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.get(url=url, headers=headers, verify=False)
return r.json()
#查询虚拟机列表
def ticket_vm_list(self, node):
path = f'/api2/json/nodes/{node}/qemu'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.get(url=url, headers=headers, verify=False)
return r.json()
#获取虚拟机信息
def ticket_vm_current(self, node, vmid):
path = f'/api2/json/nodes/{node}/qemu/{vmid}/status/current'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.get(url=url, headers=headers, verify=False)
return r.json()
#启动虚拟机
def ticket_vm_start(self, node, vmid):
path = f'/api2/json/nodes/{node}/qemu/{vmid}/status/start'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.post(url=url, headers=headers, verify=False)
return r.json()
#关闭虚拟机
def ticket_vm_stop(self, node, vmid):
path = f'/api2/json/nodes/{node}/qemu/{vmid}/status/stop'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.post(url=url, headers=headers, verify=False)
return r.json()
#创建虚拟机
def ticket_vm_create(self, node,data):
path = f'/api2/json/nodes/{node}/qemu/'
url = 'https://' + self.ip + ':' + self.port + path
headers = {'CSRFPreventionToken': self.ticket['data']['CSRFPreventionToken'], 'Cookie': 'PVEAuthCookie=' + self.ticket['data']['ticket']}
r = requests.post(url=url, data=data,headers=headers, verify=False)
return r.json()
if __name__ == '__main__':
op = Pve_api(ip='192.168.1.1', username='root@pam', password='xxxxxxxxx')
op.get_ticket()
data = {
'vmid': '102',
'sata0': 'local:100',
'cores': '2',
'memory': '1024',
'name': 'test',
'cdrom': 'local:iso/debian-11.3.0-amd64-netinst.iso'
}
#创建虚拟机的参数,其它参数官网有
r=op.ticket_vm_create(node='node1',data=data)
print(r)
'''
{'data': 'UPID:node1:xxxxxxxxxxxxxxxxx:qmcreate:102:root@pam:'}返回创建成功
'''
流量镜像
少数情况下需要把虚拟机流量镜像到另一个虚拟机
pve下测试失败,暂时保留在哪儿,之后再研究吧 首先安装Open vSwitch
apt install openvswitch-switch
创建一个流量镜像
ovs-vsctl -- --id=@p get port tap7203i3 \
-- --id=@m create mirror name=span1 \
select-all=true output-port=@p \
-- set bridge vmbr11 mirrors=@m
模拟hub直连
可以用于流量回放等测试
操作方式如下:
创建一个Linux Bridge类型网桥的
vmbr3
进入shell执行
brctl setageing vmbr3 0 #禁用mac老化时间,重启设备失效
两个虚拟机都使用
vmbr3
然后关闭防火墙使用
tcpreplay
测试是否生效持久化配置(按需配置)
auto vmbr3
iface vmbr3 inet manual
bridge-ports none
bridge-stp off
bridge-fd 0
#配置老化时间为0
post-up /sbin/brctl setageing vmbr3 0 || true
命令行修改配置
# --hotplug 1 热拨插,注意mac地址修改为现在的mac地址,否则mac变动可能导致网络不通
qm set 100 --net2 macaddr=B2:69:11:27:22:18,virtio,bridge=vmbr21 --hotplug 1