Saltar al contenido principal

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.

warning

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.
tip

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
note

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:

KeyValue
IDlocal name
Serverserver name
Export/NFS_Folder
ContentISO 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.

danger

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.

tip

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. img

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.

provider.tf
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.

terraform.tfvars
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