Apuntes de Proxmox VE

Advertencia
Este artículo se actualizó por última vez el 2023-03-09, es posible que el contenido no esté actualizado.

Estos apuntes son de Proxmox VE un gestor de virtualizaciones muy potente implementado sobre Debian 11 Bullseye en la versión actual, la 7.1-11 en el momento de escribir esto.

(Actualizado el 2022-03-23)

Proxmox VE

Promox VE es un software libre producto de Proxmox Technologies; una empresa austríaca que suministra productos de software libre (obvio). Proxmox VE, Proxmox Backup Server y Proxmox Mail Gateway, como vemos en su página web

Referencias

Motivación

Inicialmente configuré el mini-PC (Beelink Gemini T4) con Debian Server y Docker para poder implementar micro-servicios e instalar Home Assistant (dockerizado).

Como sentía curiosidad por ver como funciona la versión Supervised de HAss (Home Assistant) empecé a mirar opciones para manejar máquinas virtuales en un servidor headless. Estudié la posibilidad de instalar Qemu, pero lo descarté por que tiene dependencias con Xorg que no me convencen. Varias personas me han hablado maravillas de Proxmox y como tengo toda la instalación del mini-pc bien documentada y con copias de seguridad me he decidido a cambiar a Proxmox. Al fin y al cabo es saltar desde Debian a Debian con Proxmox, no debería ser muy traumático.

Instalación de Proxmox

Preparamos un USB con Etcher con la ISO descargada de la página web

Arrancamos el minipc desde el USB (pulsando F7) y lanzamos la instalación. Durante la instalación sólo he tenido que configurar:

Parámetros de LVM

El disco SSD del minipc es de 256Gb

Filesystem
Escogemos ext4
hdsize
Lo fija el instalador autmáticamente
swapsize
Lo he fijado a 16Gb (creo que es mala idea en un SSD, si vemos que empieza a tirar de swap habrá que plantearse quitarla)
maxroot
escogí 60Gb, este es el tamaño de la partición root que tendrá formato ext4
minfree
la parte del disco que quedará disponible sin usar, he dejado reservados 60Gb
maxvz
sería el límite máximo para el LVM data lo he puesto a 200 para que no limite, todo el disco menos los segmentos especificados en las opciones anteriores será usado para data

Parámetros de Red

Especificamos la IP, el nombre del servidor (con dominio, aunque te lo puedes inventar claro) y el DNS

Timezone

Especificamos en que zona horaria estamos.

Con esto se completa la instalación y el sistema se reiniciará.

Una vez reiniciado el sistema podremos conectarnos al PVE via web.

También podemos conectarnos via ssh. Como tengo muchas claves generadas para distintas conexiones en mi ordenador, si nos conectamos sin más nos dará error de exceso de intentos (probará todas las claves). Para las primeras conexiones tendremos que usar:

1
ssh -o PreferredAuthentications=password root@<proxmox_ip>                                                                                    25

Postinstalación

Lo primero que tenemos que hacer, terminada la instalación es ajustar los orígenes del software y actualizar todos los paquetes. Es decir, lo que se hace siempre en una instalación de Debian.

Cambiamos el origen de sw pve-enterprise por el pve-no-subscription (a menos que queramos alguna de las opciones de pago de Proxmox que sería lo recomendable en un entorno de producción).

Comentamos la linea en el fichero /etc/apt/sources.list.d/pve-enterprise.list

Y creamos un nuevo fichero:

1
echo "deb http://download.proxmox.com/debian/pve buster pve-no-subscription" > /etc/apt/sources.list.d/pve-no-suscription.list

En el fichero /etc/apt/sources.list cambiamos los orígenes de software de Debian, e incluimos contrib y non-free:

1
2
3
4
5
6
7
8
9
deb http://deb.debian.org/debian/ buster main contrib non-free
deb-src http://deb.debian.org/debian/ buster main contrib non-free

deb http://security.debian.org/debian-security buster/updates main contrib non-free
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free

# buster-updates, previously known as 'volatile'
deb http://deb.debian.org/debian/ buster-updates main contrib non-free
deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free

Actualizamos todos los paquetes con:

1
2
apt update
apt upgrade

Podemos actualizar todos los paquetes de Proxmox con el comando pveam update, o hacerlo desde el interfaz gráfico, que es más ilustrativo para las primeras veces (lo vemos luego)

Una vez actualizado el sistema operativo procedemos a instalar nuestros paquetes habituales.

Instalamos git y etckeeper

Suelo instalar etckeeper para tener un histórico automático de cambios en el /etc

Como root ejecutamos:

1
2
3
4
apt install git
git config --global user.email "whaterver@mail.com"
git config --global user.name "Name Surname"
apt install etckeeper

Si quieres ver el histórico de cambios de /etc solo tienes que ejecutar como root:

1
2
cd /etc
git log
Problemas con default locales

Si (como a mi) te dan problemas los locales (suele pasar en la instalación de Debian Server veras que apt y apt-get protestan por la configuración de locales) se puede arreglar fácilmente sin más que ejecutar sudo dpkg-reconfigure locales Puedes aprovechar la ejecución para dejar generado algún locale adicional.

Estos son los que yo he dejado configurados en mi server (se pueden consultar con el comando locale):

 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
## Antes de la reconfiguración
LANGUAGE = (unset),
LC_ALL = (unset),
LC_MONETARY = "es_ES.UTF-8",
LC_ADDRESS = "es_ES.UTF-8",
LC_TELEPHONE = "es_ES.UTF-8",
LC_NAME = "es_ES.UTF-8",
LC_MEASUREMENT = "es_ES.UTF-8",
LC_IDENTIFICATION = "es_ES.UTF-8",
LC_NUMERIC = "es_ES.UTF-8",
LC_PAPER = "es_ES.UTF-8",
LANG = "en_US.UTF-8"

## Después de la reconfiguración
LANG=en_US.UTF-8
LANGUAGE=
LC_CTYPE="en_US.UTF-8"
LC_NUMERIC=es_ES.UTF-8
LC_TIME="en_US.UTF-8"
LC_COLLATE="en_US.UTF-8"
LC_MONETARY=es_ES.UTF-8
LC_MESSAGES="en_US.UTF-8"
LC_PAPER=es_ES.UTF-8
LC_NAME=es_ES.UTF-8
LC_ADDRESS=es_ES.UTF-8
LC_TELEPHONE=es_ES.UTF-8
LC_MEASUREMENT=es_ES.UTF-8
LC_IDENTIFICATION=es_ES.UTF-8
LC_ALL=

Varios programas instalados en Debian 10


OJO: apt instala por defecto los paquetes recomendados, si no quieres que eso ocurra usa apt-get o aptitude con las opciones correspondientes.


Instalamos varias librerías de compresión:

1
apt install rar unrar zip unzip unace bzip2 lzop p7zip p7zip-full

Instalamos algunas utilidades:

1
apt install most mc tree neofetch tmux aptitude htop

Instalamos sudo:

1
apt install sudo

Cualquier usuario que pertenezca al grupo sudo podrá ejecutar comandos con privilegios de root. (podemos añadirlos, por ejemplo, con gpasswd -a <username> sudo)

Configuramos el acceso via ssh

El PVE incluye su propio cortafuegos. Tendremos que revisar su configuración más tarde.

Creamos un usuario de administración

Me voy a crear un usuario de administración para no tener que hacer login con root. El usuario va a estar en el grupo sudo así que va a ser todopoderoso, pero tendrá que saber su password para poder “sudar”.

1
2
3
4
# sudo adduser  administrator
# sudo gpasswd -a administrator sudo
$ adduser --uid=1111 hostadmin
gpasswd -a hostadmin sudo

Parámetros de login ssh

Vamos a:

  • Deshabilitar el login de root via ssh (queremos que todos entren con su usuario persona y después usen sudo)
  • Deshabilitar el login con contraseña (queremos que todo el mundo use autenticación por clave pública)

Lo primero de todo es configurar y probar nuestro acceso con clave ssh, copiamos nuestra clave al servidor, debemos copiarla tanto para el usuario root como para el usuario administrador que hayamos creado:

ssh-copy-id -o IdentitiesOnly=yes -i ~/.ssh/mykey.pub <username>@<proxmox_ip>

Y probamos a conectarnos con la clave.

ssh -i ~/.ssh/mykey <username>@<proxmox_ip>

Si todo va bien podemos añadir (en nuestro pc, no en el servidor Proxmox) la información de conexión a nuestro fichero ~/.ssh/config

1
2
3
4
5
Host <hostname>
    HostName <ip_address>
    User <username>
    Port 22
    IdentityFile ~/.ssh/<mykey>

El fichero que controla la configuración del demonio ssh en nuestro servidor es /etc/ssh/sshd_config tenemos que asegurarnos de añadir las siguientes lineas:

1
2
3
4
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM no

Después de cambiar la configuración reiniciamos el servicio con sudo systemctl restart ssh

Tras el reinicio no deberíamos poder hacer login con root via ssh.

ssh-agent

Esto es un apunte uso para trabajar cómodo con Gitlab desde el servidor Proxmox, con las claves ssh instaladas en el servidor.

1
2
3
4
eval `ssh-agent`
ssh-add .ssh/dev_rsa
ssh-add -l
ssh-add -L

Disco duro interno

En mi caso el disco duro interno que quiero añadir está mapeado en /dev/sda, se trata de un disco de 2Tb y queremos hacer dos particiones: una para almacenar backups, templates, snapshots, etc. etc. Y otra partición (mucho más grande) que usaremos para crear discos para las VM.

Con nuestro programa de particionado favorito creamos las dos particiones. Yo tengo disponibles fdisk y parted pero nada impide instalar el que nos guste.

He creado una partición de 250 Gb para almacenamiento y el resto de la capacidad para discos de VM.

Creando el “directorio”

Navegamos hasta nuestra máquina host debajo del Datacenter localizamos el interfaz Disks::Directory y creamos el nuevo directorio apuntando a la partición que hemos creado en el paso anterior (/dev/sda1 en mi caso), con el sistema de ficheros que nos guste (lo he dejado como ext4) y le damos un nombre descriptivo (para mi hdd_directory).

Creado el volumen lógico

Navegamos a LVM debe estar muy cerca, por encima de Directory. Seleccionamos el botón Create Volume Group: sólo tenemos que especificar la partición a utilizar y un nombre. Y eso es todo ya tenemos un VG donde podremos crear discos para nuestras máquinas virtuales.

Discos duros USB externos

Si son discos nuevos ejecutamos estos pasos

  1. Conectamos los discos al mini-pc
  2. Comprobamos los discos con lsblk -p |grep disk o con sudo fdisk -l
  3. Si es necesario los podemos formatear a ext4 con el comando sudo mkfs.ext4 /dev/sdX (donde X será la letra que corresponda a nuestros discos)
  4. Creamos el/los puntos de montaje de nuestros discos, p.ej. /mnt/usbA, con el comando sudo mkdir /mnt/usbA
  5. Montamos el/los discos con el comando sudo mount /dev/sdX /mnt/usbA

Para dejar los discos duros mapeado permanentemente en nuestro servidor debemos modificar el fichero /etc/fstab:

  1. Averiguamos la identidad de los discos con sudo blkid

  2. Añadimos las lineas correspondientes al fichero /etc/fstab que serán de esta forma (cambia los UUID):

    1
    
    UUID=1a716b79-b39a-49bf-bae6-4992376022e0    /mnt/usbA    ext4    defaults    0    2

Discos duros externos que no dejan de funcionar

Mis discos duros externos son un par de discos USB portátiles, dudo mucho que puedan estar funcionando continuamente.

Proxmox escanea continuamente todos los discos duros del sistema. Si queremos que los discos duros se duerman tenemos que cambiar la configuración en el fichero /etc/lvm/lvm.conf. Concretamente cambiamos la linea:

global_filter = [ "r|/dev/sd(b|c)|" , "r|/dev/zd.*|", "r|/dev/mapper/pve-.*|" "r|/dev/mapper/.*-(vm|base)--[0-9]+--disk--[0-9]+|"]

Con la primera entrada ("r|/dev/sd(b|c)|") estamos indicando que se ignore los discos /dev/sdb y /dev/sdc. Con esto perdemos también la posibilidad de crear volúmenes lvm en estos discos, pero a mi de momento no me interesa.


dynhost en OVH

Instalado el script de actualización de dynhost en OVH.

Es necesario tener disponible dig así que instalamos:

1
sudo apt install dnsutils

Después basta con programar el script periódicamente en el crontab de root con las credenciales de OVH.

Comprobamos la instalación de python

1
2
apt install python-all-dev python3-all-dev
apt install virtualenv python3-virtualenv virtualenvwrapper

Instalado el zsh

Lo he dejado instalado siguiendo la guía.

Revisión de la instalación de Proxmox

  • Nos conectamos al interfaz web con el usuario root y la contraseña que hemos establecido durante la instalación.
  • Clicamos en nuestro nodo (el servidor en el árbol de la izquierda) y comprobamos las actualizaciones pendientes (Updates)

Instalación de una máquina virtual con Home Assistant

Referencias

Una de las misiones principales de mi servidor Proxmox es soportar la VM de Homeassistant. Crear la máquina virtual es muy fácil gracias a los scripts creados por Whiskerz007 y Kanga-Who. Vamos a seguir la página de este último.

Antes de arrancar la VM conviene revisar el hardware asignado y las opciones de la VM (yo solo tuve que ajustar la memoria asignada)

Instalación de Docker

Tendríamos tres formas de instalar Docker en nuestro sistema Proxmox

  • Instalándolo en el S.O. Debian base
  • Como contenedor LXC
  • Como máquina virtual

Mi intención era usar el primer método e instalar el Docker sobre Debian. Este método no debería usarse nunca en producción pero para el uso que yo quiero darle parece aceptable. Lo he instalado aunque, de momento, dejo el servicio Docker desactivado.

El segundo método que he usado es crear una máquina virtual con Alpine Linux e instalar Docker sobre esa máquina.

Instalar Docker en Debian

Vamos allá

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
apt update
apt install apt-transport-https ca-certificates curl gnupg2 software-properties-common
add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/debian $(lsb_release -cs) stable"
apt-key adv --keyserver ha.pool.sks-keyservers.net --recv-keys 7EA0A9C3F273FCD8
apt update
apt-cache policy docker-ce
apt install docker-ce

systemctl status docker

gpasswd -a username docker

Y ya tenemos docker instalado.

Ahora completamos con la instalación de docker-compose.

Primero comprobamos la versión. En el momento de escribir esto es la 1.28.5. Con el siguiente comando descargamos el binario correspondiente a nuestro sistema en /usr/local/bin y le damos permisos de ejecución.

1
2
curl -L https://github.com/docker/compose/releases/download/1.28.5/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
chmod +x /usr/local/bin/docker-compose

Para parar el servicio Docker y dejarlo desactivado (con los alias de zsh):

1
2
3
4
scs docker       # systemctl status docker
scsp docker      # systemctl stop docker
scd docker       # systemctl disable docker
scs docker       # systemctl status docker

Instalar Docker en una máquina virtual

  • Descargamos la imagen ISO de Alpine optimizada para sistemas virtuales desde aquí
  • Subimos la imagen ISO a nuestro nodo en Proxmox (En el árbol vamos a: nodo → local(nodo) → Iso Images)
  • Creamos una máquina virtual (he dejado prácticamente los valores por defecto, asignando 32Gb de disco duro)
  • Una vez arrancada la máquina ejecutamos setup-alpine y vamos asignando las opciones de instalación:
    • Teclado es-winkeys
    • Hostname: srvname
    • Asignamos IP estática
    • Es necesario tener acceso a internet para asignar los repos de software de Alpine, así que hay que asignar gateway y dns server.
    • Escogemos “sys” para la estructura de disco
    • Damos permiso para usar y borrar el disco

Una vez instalado y rearrancado el sistema editamos /etc/apk/repositories y habilitamos comunity.

¡Ojo! si habilitas edge estarás habilitando la rama de desarrollo de Alpine y no es lo que queremos ahora mismo.

Actualizamos los paquetes del sistema con apk update.

Instalamos apk add qemu-guest-agent

Qemu-guest-agent
El qemu-guest-agent sirve para que Proxmox pueda parar la VM y/o congelar su sistema de ficheros de forma segura. Esto facilita mucho varias operaciones como por ejemplo hacer backups de las VM

Editamos el fichero /etc/init-d/qemu-guest-agent, su última línea tiene que ser:

command_args="-m ${GA_METHOD:-virtio-serial} -p ${GA_PATH:-/dev/vport2p1} -l /var/log/qemu-ga.log -d"

Añadimos el agente al arranque: rc-update add qemu-guest-agent boot

Paramos la máquina virtual y en el interfaz Proxmox cambiamos las opciones para habilitar el Qemu Guest Agent

Volvemos a arrancar la VM (Importante reiniciar desde el Proxmox) y comprobamos que en el Summary el qemu-guest-agent se conecta correctamente.

Qemu-guest-agent: fallo al crear el canal

Mi qemu-guest-agent fallaba al arrancar con los siguientes mensajes en /var/log/qemu-ga.log

1
2
3
4
1618081791.809004: critical: error opening channel: No such file or directory
1618081791.809056: critical: error opening channel
1618081791.809070: critical: failed to create guest agent channel
1618081791.809082: critical: failed to initialize guest agent channel

Por alguna razón la máquina que he creado no tiene el dispositivo /dev/vport1p1. El dispositivo en mi máquina es el /dev/vport2p1. Evidentemente el agente falla hasta que corregimos el fichero /etc/init-d/qemu-guest-agent

A continuación procedemos a instalar sudo con apk add sudo y con visudo habilitamos sudo para el grupo wheel (descomentar la linea correspondiente)

Creamos grupo y usuario para Docker:

1
2
3
4
5
6
addgroup -g 150 docker
addgroup dockadmin
adduser -G dockadmin dockadmin
adduser dockadmin wheel
adduser dockadmin docker
cat /etc/passwd

Instalamos Docker:

1
2
3
4
apk add docker
rc-update add docker boot
service docker start
service docker status

Y lo probamos:

docker run --rm hello-world

Como todo va bien instalamos también el docker-compose

1
sudo apk add docker-compose

Cortafuegos

Instalamos el UFW

1
sudo apk add ufw

Y hacemos una configuración inicial

1
2
3
4
5
6
7
sudo ufw status verbose         # Comprobamos que está deshabilitado
sudo ufw app list               # comprobamos que apps soporta
sudo ufw default deny incoming  # le decimos que por defecto no acepta nada entrante
sudo ufw default allow outgoing # por defecto permitimos conexiones salientes
sudo ufw allow ssh              # permitimos conexiones ssh
sudo ufw enable                 # lo habilitamos
sudo ufw status verbose         # vemos el estado del cortafuegos

Instalando nuestros primeros contenedores

Una vez comprobado que funciona todo añadimos una configuración básica con Traefik y Portainer como comentamos en el ejemplo 3 de los apuntes de Traefik

Almacenamiento para Docker

Como hemos sacado los discos duros externos del Proxmox no podemos crear volúmenes en los mismos. Para darle espacio de almacenamiento a los contenedores en esos discos duros vamos a hacer algo un poco rebuscado: montar un directorio del disco externo via sshfs.

En nuestra máquina virtual Alpine:

  1. Instalamos los paquetes sshfs y util-linux, además configuramos el sistema para que se carge el módulo del kernel fuse
1
2
3
sudo apk add sshfs util-linux
sudo modprobe fuse
echo fuse | sudo tee -a /etc/modules
  1. Creamos el directorio local (en nuestra VM) donde montaremos el disco duro externo.
1
mkdir $HOME/mnt/store
  1. Creamos una clave con ssh-keygen que nos permita facilitar la conexión a la máquina virtual.

Una vez creada la clave , podriamos crear el fichero ~/.ssh/config y montar la unidad por comando con el usuario administrador de docker (por ejemplo). Pero nos interesa más montar el directorio del disco duro en el arranque de la máquina virtual dejándolo especificado en el fichero /etc/fstab

Generalmente no permitimos el acceso del usuario root via ssh en ningún sistema, así que tendremos que especificar el montaje con un usuario. Usaremos el usuarios dockadmin del servidor host y el usuario del mismo nombre que creamos en la máquina virtual de Docker.

  1. Añadimos la clave pública al fichero ~/.ssh/authorized_keys del usuario dockadmin en la VM. (depende de tu escenario, yo lo hice pasando por mi ordenador personal, desde donde estoy configurando todo)

  2. Creamos una entrada para la VM en el fichero /etc/hosts

1
sudo echo "<ip_host>  hostname" >> /etc/hosts
  1. Habilitamos netmount
1
sudo rc-update add netmount
  1. Añadimos la linea al fichero /etc/fstab
1
dockadmin@sirio:/mnt/usbA/Work/dockerStore:/home/dockadmin/mnt/store fuse.sshfs _netdev,identityfile=/home/dockadmin/.ssh/id_mount,allow_other,uid=dockeradmin,gid=dockeradmin 0 0

Recetillas

Quitando el mensaje de “invalid subscription”

Editamos el fichero /usr/share/javascript/proxmox-widget-toolkit/promoxlib.js

Localizamos la cadena No valid subscription y cambiamos al función para que quede así:

1
2
void({ //Ext.Msg.show({
  title: gettext('No valid subscription'),

Reiniciamos el servicio con systemctl restart pveproxy.service

0%