PVE 8.3.1安装后的优化
网上PVE优化文章比较比较多,记录一下优化的过程:
1,删除订阅的弹窗:
sed -Ezi.bak "s/(Ext.Msg.show\(\{\s+title: gettext\('No valid sub)/void\(\{ \/\/\1/g" /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js && systemctl restart pveproxy.service # 执行完成后,浏览器Ctrl+F5强制刷新缓存
2,更换Debian源:
需修改文件
/etc/apt/sources.list
/etc/apt/sources.list.d/ceph.list
/etc/apt/sources.list.d/pve-enterprise.list
修改前先备份,以防万一:
mkdir /etc/apt/sources_backup cp /etc/apt/sources.list /etc/apt/sources_backup/sources.list.bak cp /etc/apt/sources.list.d/ceph.list /etc/apt/sources_backup/ceph.list.bak cp /etc/apt/sources.list.d/pve-enterprise.list /etc/apt/sources_backup/pve-enterprise.list.bak
方法一(推荐):
sed -i 's|^deb http://ftp.debian.org|deb https://mirrors.ustc.edu.cn|g' /etc/apt/sources.list sed -i 's|^deb http://security.debian.org|deb https://mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list
方法二:
wget --no-check-certificate https://v2rayssr.com/tool/yuan.sh -O yuan.sh && chmod +x yuan.sh && ./yuan.sh
如果以上脚本失效,可以自己编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #!/bin/bash dir= "/etc/apt/sources.list.d/" file= "/etc/apt/sources.list" if [ -d "$dir" ]; then echo "Deleting directory $dir..." rm -rf "$dir" echo "Directory deleted." else echo "Directory $dir does not exist. Skipping deletion." fi echo "Replacing content of $file..." echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm main contrib non-free non-free-firmware" > "$file" echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm-updates main contrib non-free non-free-firmware" >> "$file" echo "deb https://mirrors.ustc.edu.cn/debian/ bookworm-backports main contrib non-free non-free-firmware" >> "$file" echo "deb https://mirrors.ustc.edu.cn/debian-security bookworm-security main" >> "$file" echo "deb https://mirrors.ustc.edu.cn/proxmox/debian bookworm pve-no-subscription" >> "$file" echo "Content replaced." |
3,pve页面上显示cpu、磁盘等温度、频率、功率等信息
wget --no-check-certificate -c https://raw.githubusercontent.com/a904055262/PVE-manager-status/main/showtempcpufreq.sh && chmod +x showtempcpufreq.sh && ./showtempcpufreq.sh
同样,如果以上脚本失效,自行编写:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 | #!/usr/bin/env bash # version: 2023.9.5 #添加硬盘信息的控制变量,如果你想不显示硬盘信息就设置为false #NVME硬盘 sNVMEInfo= true #固态和机械硬盘 sODisksInfo= true #debug,显示修改后的内容,用于调试 dmode= false #脚本路径 sdir=$(cd "$(dirname " ${BASH_SOURCE[0]} ")" ; pwd) cd "$sdir" sname=$(basename "${BASH_SOURCE[0]}" ) sap=$sdir/$sname echo 脚本路径: "$sap" #需要修改的文件 np=/usr/share/perl5/PVE/API2/Nodes.pm pvejs=/usr/share/pve-manager/js/pvemanagerlib.js plibjs=/usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js if ! command -v sensors > /dev/ null ; then echo 你需要先安装 lm-sensors 和 linux-cpupower,脚本尝试给你自动安装 if apt update ; apt install -y lm-sensors; then echo lm-sensors 安装成功 echo 尝试继续安装linux-cpupower获取功耗信息 if apt install -y linux-cpupower;then echo linux-cpupower安装成功 else echo -e "linux-cpupower安装失败,可能无法正常获取功耗信息,你可以使用\033[34mapt update ; apt install linux-cpupower && modprobe msr && echo msr > /etc/modules-load.d/turbostat-msr.conf && chmod +s /usr/sbin/turbostat && echo 成功!\033[0m 手动安装" fi else echo 脚本自动安装所需依赖失败 echo -e "请使用蓝色命令:\033[34mapt update ; apt install -y lm-sensors linux-cpupower && chmod +s /usr/sbin/turbostat && echo 成功! \033[0m 手动安装后重新运行本脚本" echo 脚本退出 exit 1 fi fi #获取版本号 pvever=$(pveversion | awk -F "/" '{print $2}' ) echo "你的PVE版本号:$pvever" restore() { [ -e $np.$pvever.bak ] && mv $np.$pvever.bak $np [ -e $pvejs.$pvever.bak ] && mv $pvejs.$pvever.bak $pvejs [ -e $plibjs.$pvever.bak ] && mv $plibjs.$pvever.bak $plibjs } fail() { echo "修改失败,可能不兼容你的pve版本:$pvever,开始还原" restore echo 还原完成 exit 1 } #还原修改 case $1 in restore) restore echo 已还原修改 if [ "$2" != 'remod' ];then echo -e "请刷新浏览器缓存:\033[31mShift+F5\033[0m" systemctl restart pveproxy else echo ----- fi exit 0 ;; remod) echo 强制重新修改 echo ----------- "$sap" restore remod > /dev/ null "$sap" exit 0 ;; esac #检测是否已经修改过 [ $(grep 'modbyshowtempfreq' $np $pvejs $plibjs | wc -l) -eq 3 ] && { echo -e " 已经修改过,请勿重复修改 如果没有生效,或者页面一直转圈圈 请使用 \033[31mShift+F5\033[0m 刷新浏览器缓存 如果一直异常,请执行:\033[31m\"$sap\" restore\033[0m 命令,可以还原修改 如果想强制重新修改,请执行:\033[31m\"$sap\" remod\033[0m 命令,可以还原修改 " exit 1 } contentfornp=/tmp/.contentfornp.tmp [ -e /usr/sbin/turbostat ] && { modprobe msr chmod +s /usr/sbin/turbostat } echo msr > /etc/modules-load.d/turbostat-msr.conf cat > $contentfornp << 'EOF' #modbyshowtempfreq $res->{thermalstate} = `sensors -A`; $res->{cpuFreq} = ` goverf=/sys/devices/system/cpu/cpufreq/policy0/scaling_governor maxf=/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_max_freq minf=/sys/devices/system/cpu/cpufreq/policy0/cpuinfo_min_freq cat /proc/cpuinfo | grep -i "cpu mhz" echo -n 'gov:' [ -f \$goverf ] && cat \$goverf || echo none echo -n 'min:' [ -f \$minf ] && cat \$minf || echo none echo -n 'max:' [ -f \$maxf ] && cat \$maxf || echo none echo -n 'pkgwatt:' [ -e /usr/sbin/turbostat ] && turbostat --quiet --cpu package --show "PkgWatt" -S sleep 0.25 2>&1 | tail -n1 `; EOF contentforpvejs=/tmp/.contentforpvejs.tmp cat > $contentforpvejs << 'EOF' //modbyshowtempfreq { itemId: 'thermal' , colspan: 2, printBar: false , title: gettext( '温度(°C)' ), textField: 'thermalstate' , renderer:function(value){ //value进来的值是有换行符的 console.log(value) let b = value.trim().split(/\s+(?=^\w+-)/m).sort(); let c = b.map(function (v){ // 风扇转速数据,直接返回 let fandata = v.match(/(?<=:\s+)[1-9]\d*(?=\s+RPM\s+)/ig) if ( fandata ) { return '风扇: ' + fandata. join ( ';' ) } let name = v.match(/^[^-]+/)[0].toUpperCase(); let temp = v.match(/(?<=:\s+)[+-][\d.]+(?=.?°C)/g); // 某些没有数据的传感器,不是温度的传感器 if ( temp ) { temp = temp.map(v => Number(v).toFixed(0)) if (/coretemp/i.test(name)) { name = 'CPU' ; temp = temp[0] + ( temp.length > 1 ? ' ( ' + temp.slice(1). join ( ' | ' ) + ' )' : '' ); } else { temp = temp[0]; } let crit = v.match(/(?<=\bcrit\b[^+]+\+)\d+/); return name + ': ' + temp + ( crit? ` ,crit: ${crit[0]}` : '' ); } else { return 'null' } }); console.log(c); // 排除null值的 c=c.filter( v => ! /^ null $/.test(v) ) //console.log(c); //排序,把cpu温度放最前 let cpuIdx = c.findIndex(v => /CPU/i.test(v) ); if (cpuIdx > 0) { c.unshift(c.splice(cpuIdx, 1)[0]); } console.log(c) c = c. join ( ' | ' ); return c; } }, { itemId: 'cpumhz' , colspan: 2, printBar: false , title: gettext( 'CPU频率(GHz)' ), textField: 'cpuFreq' , renderer:function(v){ //return v; console.log(v); let m = v.match(/(?<=^cpu[^\d]+)\d+/img); let m2 = m.map( e => ( e / 1000 ).toFixed(1) ); m2 = m2. join ( ' | ' ); let gov = v.match(/(?<=^gov:).+/im)[0].toUpperCase(); let min = (v.match(/(?<=^min:).+/im)[0]); if ( min !== 'none' ) { min=(min/1000000).toFixed(1); } let max = (v.match(/(?<=^max:).+/im)[0]) if ( max !== 'none' ) { max=(max/1000000).toFixed(1); } let watt= v.match(/(?<=^pkgwatt:)[\d.]+$/im); watt = watt? " | 功耗: " + (watt[0]/1).toFixed(1) + 'W' : '' ; return `${m2} | MAX: ${max} | MIN: ${min}${watt} | 调速器: ${gov}` } }, EOF #检测nvme硬盘 echo 检测系统中的NVME硬盘 nvi=0 if $sNVMEInfo;then for nvme in $(ls /dev/nvme[0-9] 2> /dev/ null ); do chmod +s /usr/sbin/smartctl cat >> $contentfornp << EOF \$res->{nvme$nvi} = \`smartctl $nvme -a -j\`; EOF cat >> $contentforpvejs << EOF { itemId: 'nvme${nvi}0' , colspan: 2, printBar: false , title: gettext( 'NVME${nvi}' ), textField: 'nvme${nvi}' , renderer:function(value){ //return value; try { let v = JSON.parse(value); //名字 let model = v.model_name; if (! model) { return '找不到硬盘,直通或已被卸载' ; } // 温度 let temp = v.temperature?.current; temp = ( temp !== undefined ) ? " | " + temp + '°C' : '' ; // 通电时间 let pot = v.power_on_time?.hours; let poth = v.power_cycle_count; pot = ( pot !== undefined ) ? ( " | 通电: " + pot + '时' + ( poth ? ',次: ' + poth : '' )) : '' ; // 读写 let log = v.nvme_smart_health_information_log; let rw= '' let health= '' if (log) { let read = log.data_units_read; let write = log.data_units_written; read = read ? (log.data_units_read / 1956882).toFixed(1) + 'T' : '' ; write = write ? (log.data_units_written / 1956882).toFixed(1) + 'T' : '' ; if (read && write) { rw = ' | R/W: ' + read + '/' + write; } let pu = log.percentage_used; let me = log.media_errors; if ( pu !== undefined ) { health = ' | 健康: ' + ( 100 - pu ) + '%' if ( me !== undefined ) { health += ',0E: ' + me } } } // smart状态 let smart = v.smart_status?.passed; if (smart === undefined ) { smart = '' ; } else { smart = ' | SMART: ' + (smart ? '正常' : '警告!' ); } let t = model + temp + health + pot + rw + smart; //console.log(t); return t; } catch (e){ return '无法获得有效消息' ; }; } }, EOF let nvi++ done fi echo "已添加 $nvi 块NVME硬盘" #检测机械键盘 echo 检测系统中的SATA固态和机械硬盘 sdi=0 if $sODisksInfo;then for sd in $(ls /dev/sd[a-z] 2> /dev/ null ); do chmod +s /usr/sbin/smartctl chmod +s /usr/sbin/hdparm #检测是否是真的机械键盘 sdsn=$(awk -F '/' '{print $NF}' <<< $sd) sdcr=/sys/block/$sdsn/queue/rotational [ -f $sdcr ] || continue if [ "$(cat $sdcr)" = "0" ];then hddisk= false sdtype= "固态硬盘$sdi" else hddisk= true sdtype= "机械硬盘$sdi" fi #[] && 型条件判断,嵌套的条件判断的非 || 后面一定要写动作,否则会穿透到上一层的非条件 #机械/固态硬盘输出信息逻辑, #如果硬盘不存在就输出空JSON cat >> $contentfornp << EOF \$res->{sd$sdi} = \` if [ -b $sd ];then if $hddisk && hdparm -C $sd | grep -iq 'standby' ;then echo '{"standy": true}' else smartctl $sd -a -j fi else echo '{}' fi \`; EOF cat >> $contentforpvejs << EOF { itemId: 'sd${sdi}0' , colspan: 2, printBar: false , title: gettext( '${sdtype}' ), textField: 'sd${sdi}' , renderer:function(value){ //return value; try { let v = JSON.parse(value); console.log(v) if (v.standy === true ) { return '休眠中' } //名字 let model = v.model_name; if (! model) { return '找不到硬盘,直通或已被卸载' ; } // 温度 let temp = v.temperature?.current; temp = ( temp !== undefined ) ? " | 温度: " + temp + '°C' : '' ; // 通电时间 let pot = v.power_on_time?.hours; let poth = v.power_cycle_count; pot = ( pot !== undefined ) ? ( " | 通电: " + pot + '时' + ( poth ? ',次: ' + poth : '' )) : '' ; // smart状态 let smart = v.smart_status?.passed; if (smart === undefined ) { smart = '' ; } else { smart = ' | SMART: ' + (smart ? '正常' : '警告!' ); } let t = model + temp + pot + smart; //console.log(t); return t; } catch (e){ return '无法获得有效消息' ; }; } }, EOF let sdi++ done fi echo "已添加 $sdi 块SATA固态和机械硬盘" echo 开始修改nodes.pm文件 if ! grep -q 'modbyshowtempfreq' $np ;then [ ! -e $np.$pvever.bak ] && cp $np $np.$pvever.bak if [ "$(sed -n " /PVE::pvecfg::version_text()/{=;p;q} " " $np ")" ];then #确认修改点 #r追加文本后面必须跟回车,否则r 后面的文字都会被当成文件名,导致脚本出错 sed -i "/PVE::pvecfg::version_text()/{ r $contentfornp }" $np $dmode && sed -n "/PVE::pvecfg::version_text()/,+5p" $np else echo '找不到nodes.pm文件的修改点' fail fi else echo 已经修改过 fi echo 开始修改pvemanagerlib.js文件 if ! grep -q 'modbyshowtempfreq' $pvejs ;then [ ! -e $pvejs.$pvever.bak ] && cp $pvejs $pvejs.$pvever.bak if [ "$(sed -n '/pveversion/,+3{ /},/{=;p;q} }' $pvejs)" ];then sed -i "/pveversion/,+3{ /},/r $contentforpvejs }" $pvejs $dmode && sed -n "/pveversion/,+8p" $pvejs else echo '找不到pvemanagerlib.js文件的修改点' fail fi echo 修改页面高度 #统计加了几条 addRs=$(grep -c '\$res' $contentfornp) addHei=$(( 28 * addRs)) $dmode && echo "添加了$addRs条内容,增加高度为:${addHei}px" #原高度300 echo 修改左栏高度 if [ "$(sed -n '/widget.pveNodeStatus/,+4{ /height:/{=;p;q} }' $pvejs)" ]; then #获取原高度 wph=$(sed -n -E "/widget\.pveNodeStatus/,+4{ /height:/{s/[^0-9]*([0-9]+).*/\1/p;q} }" $pvejs) sed -i -E "/widget\.pveNodeStatus/,+4{ /height:/{ s#[0-9]+#$(( wph + addHei))# } }" $pvejs $dmode && sed -n '/widget.pveNodeStatus/,+4{ /height/{ p;q } }' $pvejs #修改右边栏高度,让它和左边一样高,双栏的时候否则导致浮动出问题 #原高度325 echo 修改右栏高度和左栏一致,解决浮动错位 if [ "$(sed -n '/nodeStatus:\s*nodeStatus/,+10{ /minHeight:/{=;p;q} }' $pvejs)" ]; then #获取原高度 nph=$(sed -n -E '/nodeStatus:\s*nodeStatus/,+10{ /minHeight:/{s/[^0-9]*([0-9]+).*/\1/p;q} }' "$pvejs" ) sed -i -E "/nodeStatus:\s*nodeStatus/,+10{ /minHeight:/{ s#[0-9]+#$(( nph + addHei - (nph - wph) ))# } }" $pvejs $dmode && sed -n '/nodeStatus:\s*nodeStatus/,+10{ /minHeight/{ p;q } }' $pvejs else echo 右边栏高度找不到修改点,修改失败 fi else echo 找不到修改高度的修改点 fail fi else echo 已经修改过 fi echo 温度,频率,硬盘信息相关修改已完成 echo ------------------------ echo ------------------------ echo 开始修改proxmoxlib.js文件 echo 去除订阅弹窗 if ! grep -q 'modbyshowtempfreq' $plibjs ;then [ ! -e $plibjs.$pvever.bak ] && cp $plibjs $plibjs.$pvever.bak if [ "$(sed -n '/\/nodes\/localhost\/subscription/{=;p;q}' $plibjs)" ];then sed -i '/\/nodes\/localhost\/subscription/,+10{ /res === null /{ N s/(.*)/( false )/ a //modbyshowtempfreq } }' $plibjs $dmode && sed -n "/\/nodes\/localhost\/subscription/,+10p" $plibjs else echo 找不到修改点,放弃修改这个 fi else echo 已经修改过 fi echo -e "------------------------ 修改完成 请刷新浏览器缓存:\033[31mShift+F5\033[0m 如果你看到主页面提示连接错误或者没看到温度和频率,请按:\033[31mShift+F5\033[0m,刷新浏览器缓存! 如果你对效果不满意,请执行:\033[31m\"$sap\" restore\033[0m 命令,可以还原修改 " systemctl restart pveproxy |
4,CT 模板换源
需修改文件:
/usr/share/perl5/PVE/APLInfo.pm
用如下指令修改,把 APLInfo.pm
里所有 http://download.proxmox.com
替换成中科大的镜像
#先备份以防万一 cp /usr/share/perl5/PVE/APLInfo.pm /usr/share/perl5/PVE/APLInfo.pm.bak sed -i 's|http://download.proxmox.com|https://mirrors.ustc.edu.cn/proxmox|g' /usr/share/perl5/PVE/APLInfo.pm
具体变更的内容如下所示
1 2 3 4 5 6 7 8 9 10 11 | --- a/usr/share/perl5/PVE/APLInfo.pm.bak +++ b/usr/share/perl5/PVE/APLInfo.pm @@ -197,7 +197,7 @@ sub get_apl_sources { my $sources = [ { host => "download.proxmox.com" , - url => "http://download.proxmox.com/images" , + url => "https://mirrors.ustc.edu.cn/proxmox/images" , file => 'aplinfo-pve-8.dat' , }, { |
注意这里的 host
属性是不能修改的,只改 url
就好
重启下 pvedaemon.service
,刷新下 web 页面,完事
systemctl restart pvedaemon.service
5,pve-enterprise.list
把 pve-enterprise.list
的企业源扬了。毕竟这个企业源得订阅了才能用,没订阅意味着没用
echo "" > /etc/apt/sources.list.d/pve-enterprise.list
(可选)如果没有订阅,却依然想要一个可以更新 PVE 的源,可以用 PVE 的 pve-no-subscription 源。可以用如下指令添加
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/pve bookworm pve-no-subscription" > /etc/apt/sources.list.d/pve-no-subscription.list
如文档所述,这个源的 PVE 软件包是作为企业源的上游源,可能相对不那么的稳定
6,ceph.list
这个原文件就一行,直接覆盖了完事
echo "deb https://mirrors.ustc.edu.cn/proxmox/debian/ceph-quincy bookworm no-subscription" > /etc/apt/sources.list.d/ceph.list
这里,我这里用了 no-subscription
,但中科大文档里用的是 pve-no-subscription
,原因是 中科院源里 里只有叫个 no-subscription
子目录,并没有 pve-no-subscription
,因此得根据情况改一下
7,扩充root分区,删除lvm-thin
直接参考:https://www.cnblogs.com/airoot/p/18721178
8,工具推荐
pve_source
Pve Tools:https://github.com/ivanhao/pvetools
其他参考链接:
https://pkernel.com/?p=1415
https://bozai.me/pve-install.html
https://bozai.me/pve.html
https://blog.fallenbreath.me/zh-CN/2023/pve8-change-sourceslist/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)