Proxmox VE
Después de tantos años utilizando VMWare ESXi Hypervisor, nos vemos "en la calle" tras la eliminación de su versión gratuita y el aumento de precios. Siendo así, y para un uso doméstico, moverse hacia Promox VE era la decisión lógica.
Promox VE en su versión gratuita aporta más funcionalidades que la gratuita de VMWare ESXi. Por si fuera poco, tiene resuelto de serie las copias de seguridad.
En general tiene algunos detalles a tener en cuenta:
- Se basa en Debian, así que podemos "tocar" la base para hacer reajustes.
- Tiene una UI con bastantes opciones, pero ojo, toca tirar de comandos.
- En VMWare necesitas un servidor para controlar el clúster (únicamente en la versión de pago). Proxmox VE permite usar la UI de cualquier nodo para controlarlos a todos. Nada de anillo único, ¡todos controlan a todos!
- Las máquinas virtuales (VM) pueden utilizar cloud-init, aunque la versión nativa es un tanto limitada y requiere ser extendida.
- Existe un provider de Terraform, que además permite extender el cloud-init.
Instalación
La página oficial tiene el enlace para descargar la ISO y diferentes opciones para crear un pendrive. En mi caso, usé Balena Etcher en Windows.
Proxmox VE requiere que la CPU tenga la virtualización activa, las BIOS suelen tenerlo apagado de serie.
El asistente no tiene pérdida:
- Aceptar licencia.
- En mi caso cambio la partición a
ZFS
(Raid0 si solo tienes 1 disco). - Seleccionar país para timezone y teclado.
- Contraseña de root y e-mail.
- Definir datos de red.
Entre otros beneficios, la partición ZFS
permite crear snapshots sin duplicar el disco.
Al terminar se podrá acceder mediante la UI.
https://serverName:8006
Recordar mantener el realm
en linux pam
para poder acceder con el usuario root
creado en la instalación.
Configuración
Algunas partes de la configuración y uso se realizan desde la UI y otras vía SSH. En cualquier caso, es posible acceder a la Shell de cada nodo desde la UI.
Configuración básica
Lo más sencillo es lanzar un script que ajusta repositorios, anula el aviso de suscripción y actualiza el sistema.
bash -c "$(wget -qLO - https://github.com/tteck/Proxmox/raw/main/misc/post-pve-install.sh)"
Las opciones para elegir variarán según la utilidad que le demos. Estas activan todas las funcionalidades gratuitas:
✓ Corrected Proxmox VE Sources
✓ Disabled 'pve-enterprise' repository
✓ Enabled 'pve-no-subscription' repository
✓ Corrected 'ceph package repositories'
✗ Selected no to Adding 'pvetest' repository
✓ Disabled subscription nag (Delete browser cache)
✗ Selected no to Disabling high availability
✓ Updated Proxmox VE
✓ Completed Post Install Routines
Copias de seguridad
Por defecto, el disco local
permite almacenar copias de seguridad, lo que es una muy mala idea.
La opción realista es crear una carpeta compartida por NFS
para almacenar las copias de seguridad e imágenes. También se puede utilizar para snippets.
Acceder a:
Datacenter > Storage - Add - NFS
Y definir la carpeta compartida:
Key | Value |
---|---|
ID | local name |
Server | server name |
Export | /NFS_Folder |
Content | ISO Image, VZDump backup file, Snippets |
Antes de nada hay que darle una vuelta por los pools
:
Datacenter > Permissions - Pools
Al definir una VM se le puede asignar a qué pool pertenece, por ejemplo, para indicar el tipo de entorno (producción, test, ...). Estos pools también se pueden asignar a una configuración de copia de seguridad, permitiendo que estas afecten a las VMs de ese pool, lo que nos evita tener que ajustar la configuración cada vez que creamos o eliminamos una VM.
Datacenter > Backup - Add
La configuración dependerá de cuándo y cómo queremos crear copias de seguridad, siendo importante acordarse de asignar la carpeta compartida como destino.
Certificado SSL
La UI utiliza HTTPS con un certificado auto firmado que puede ser modificando mediante un ACME (como Let's Encrypt) o simplemente subiendo un certificado propio de nuestra intranet.
Nodes - <Nodename> - System - Certificates - Upload Custom Certificate
Clúster
Para conectar dos o más Proxmox VE, es tan fácil como definir uno como principal, extraer el código y utilizarlo en el resto para que se conecten
Datacenter - Cluster
Create Cluster in one node
Join Cluster with the other (with the information of Join Information)
Editor de texto
Como fan de vim, no podía faltar el editor.
sudo apt install vim -y
vi /usr/share/vim/vim90/defaults.vim
Y la capacidad para pegar con el clic derecho añadiendo el siguiente al final:
set mouse=r
Temperatura en UI
La UI está hecha en JavaScript, con lo que es posible modificarla para añadir los datos de temperatura u otros.
Las actualizaciones pueden cambiar la UI, así que esta configuración se pierde rápidamente y puede ser diferente en cada versión, con lo que no coincidirá en las líneas indicadas.
Me he basado en este repositorio.
Instalar el sensor y comprobar qué utilizaremos. En mi caso utilizo el agrupador para la CPU y el sensor de disco duro.
sudo apt-get install lm-sensors
sudo sensors-detect
service kmod start
sensors
Añadir la lista de sensores a utilizar.
cp /usr/share/perl5/PVE/API2/Nodes.pm /usr/share/perl5/PVE/API2/Nodes.pm_BKP
vi /usr/share/perl5/PVE/API2/Nodes.pm
Tras el siguiente bloque (línea 498)
$res->{rootfs} = {
total => $dinfo->{blocks},
avail => $dinfo->{bavail},
used => $dinfo->{used},
free => $dinfo->{blocks} - $dinfo->{used},
};
Añadir:
my %sensors_config = (
cputemp => {
jsonpath => ['coretemp-isa-0000', 'Package id 0'],
valkey => 'temp1_input',
critkey => 'temp1_crit',
},
nvmetemp => {
jsonpath => ['nvme-pci-0100', 'Composite'],
valkey => 'temp1_input',
critkey => 'temp1_crit',
},
);
my $temp_default_val = 0;
my $temp_default_crit = 80;
my $sensors = eval { decode_json(`sensors -j`); };
if (defined($sensors)) {
keys %sensors_config;
while (my ($k, $v) = each %sensors_config) {
if (!defined($v->{jsonpath})) { next; }
my $currref = $sensors;
my $pathdefined = 1;
for my $pathseg (@{$v->{jsonpath}}) {
if (defined($currref->{$pathseg})) {
$currref = $currref->{$pathseg}
} else {
$pathdefined = 0;
last;
}
}
if (!$pathdefined) { next; }
$res->{$k} = {
used => defined($v->{valkey}) && defined($currref->{$v->{valkey}})
? $currref->{$v->{valkey}} : $temp_default_val,
total => defined($v->{critkey}) && defined($currref->{$v->{critkey}})
? $currref->{$v->{critkey}} : $temp_default_crit,
};
}
}
Añadir la función transformadora.
cp /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js_BKP
vi /usr/share/javascript/proxmox-widget-toolkit/proxmoxlib.js
Sobre la línea 1097, añadir:
render_node_temp: function(record) {
if (!record || !Ext.isNumeric(record.used) || !Ext.isNumeric(record.total)) {
return '-';
}
return record.used.toFixed(1) + '°C (crit: ' + record.total.toFixed(1) + '°C)';
},
Finalmente hay que añadir el bloque y ajustar las CSS.
cp /usr/share/pve-manager/js/pvemanagerlib.js /usr/share/pve-manager/js/pvemanagerlib.js_BKP
vi /usr/share/pve-manager/js/pvemanagerlib.js
/* Línea 45001 */
Ext.define('PVE.node.StatusView', {
extend: 'Proxmox.panel.StatusView',
alias: 'widget.pveNodeStatus',
height: 350, /* cambiar a 400 */
/* Tras línea 45087 */
{
xtype: 'box',
colspan: 2,
padding: '0 0 20 0',
},
/* Añadir */
{
itemId: 'cputemp',
iconCls: 'fa fa-fw fa-thermometer-half',
title: gettext('CPU temp'),
valueField: 'cputemp',
maxField: 'cputemp',
renderer: Proxmox.Utils.render_node_temp,
},
{
itemId: 'nvmetemp',
iconCls: 'fa fa-fw fa-thermometer-half',
title: gettext('NVMe temp'),
valueField: 'nvmetemp',
maxField: 'nvmetemp',
renderer: Proxmox.Utils.render_node_temp,
},
{
xtype: 'box',
colspan: 2,
padding: '0 0 20 0',
},
Al terminar todos los cambios, reiniciar y confirmar que se muestra correctamente en la UI.
systemctl restart pveproxy.service
La temperatura se muestra en la pantalla de Summary del nodo.
Terraform
La configuración de Terraform para el provider de bpg requiere un token y conexión vía SSH para usar todas las opciones.
Usuario + Token
Acceder por SSH a un nodo para crear el usuario terraform
y asignar roles.
pveum user add terraform@pve
pveum role add Terraform -privs "Datastore.Allocate Datastore.AllocateSpace Datastore.AllocateTemplate Datastore.Audit Pool.Allocate Sys.Audit Sys.Console Sys.Modify SDN.Use VM.Allocate VM.Audit VM.Clone VM.Config.CDROM VM.Config.Cloudinit VM.Config.CPU VM.Config.Disk VM.Config.HWType VM.Config.Memory VM.Config.Network VM.Config.Options VM.Migrate VM.Monitor VM.PowerMgmt User.Modify"
pveum aclmod / -user terraform@pve -role Terraform
pveum user token add terraform@pve provider --privsep=0
Debemos apuntar el token y añadirlo al prefijo según el formato: terraform@pve!provider=00000000-0000-0000-0000-000000000000
Usuario SSH
Definir el usuario en cada nodo.
apt update
apt install sudo
sudo useradd -m terraform
sudo visudo
Añadir las siguientes líneas al final:
terraform ALL=(root) NOPASSWD: /sbin/pvesm
terraform ALL=(root) NOPASSWD: /sbin/qm
terraform ALL=(root) NOPASSWD: /usr/bin/tee
terraform ALL=(root) NOPASSWD: /var/lib/vz/*
Crear un public key
y añadirlo a la configuración.
mkdir /home/terraform/.ssh
vi /home/terraform/.ssh/authorized_keys
Provider
Tras ello, configuramos el provider.
terraform {
required_providers {
proxmox = {
source = "bpg/proxmox"
}
}
}
provider "proxmox" {
endpoint = var.proxmox_endpoint.endpoint
insecure = var.proxmox_endpoint.insecure
api_token = var.proxmox_auth.api_token
ssh {
agent = true
username = var.proxmox_auth.username
private_key = fileexists(var.proxmox_auth.private_key) ? file(var.proxmox_auth.private_key) : var.proxmox_auth.private_key
}
}
Las variables.
variable "proxmox_endpoint" {
description = "Proxmox endpoint"
type = object({
endpoint = string
insecure = bool
})
}
variable "proxmox_auth" {
description = "Proxmox authentication"
type = object({
api_token = string
username = string
private_key = string
})
sensitive = true
}
Este es un ejemplo del fichero de valores donde el fichero con la private key se encuentra en la misma carpeta.
proxmox_endpoint = {
endpoint = "https://serverName:8006/"
insecure = true
}
proxmox_auth = {
api_token = "terraform@pve!provider=00000000-0000-0000-0000-000000000000"
username = "terraform"
private_key = "proxmox.ppk"
}
Comandos
Forzar apagado
La gestión de las VMs requiere que tengan el agente instalado, algo que no hacen por defecto. Sin el agente, varias funcionalidades como Reboot o Shutdown no funcionan y requieren usar las funciones de Reset o Stop, entre otros problemas. Así que es aconsejable que siempre tengan el agente instalado.
Por desgracia, algunas veces una VM puede quedarse bloqueada, sin opción a hacer nada mediante la UI, tenga o no el agente.
Vía SSH podemos mostrar todas las VM junto a su ID
cat /etc/pve/.vmlist
En condiciones normales podremos desbloquearla y parar, pero es posible que ambos fallen.
qm unlock VMID
qm stop VMID
Si no ha funcionado, habrá que encontrar el PID
, matar la aplicación y apagarlo ya que tiende a hacer un autoarranque.
ps aux | grep "/usr/bin/kvm -id VMID"
kill -9 PID
qm stop VMID