Proxmox Virtualization -- Automatically deploying new LXC containers
Daniel Nashed – 5 December 2021 10:21:27
Proxmox is a very interesting hypervisor based on open source technology.
It comes with ZFS support out of the box and provides VM virtualization and also LXC containers.
LXC containers are a lightweight way to run Linux servers -- But you should be aware the kernel form the Proxmox host is used in this case!
Domino currently does not support 5.x kernel coming with the underlying Debian 11, which is used by Proxmox!
But for a LAB environment this would be still a great choice and works.
I looked into Proxmox APIs and ended up with the command line options instead.
It is a wild mix between different command-line operations.
Sadly the hook-scripts inside the container did not work. So I run commands into the container to install the OpenSSH server (sshd).
The following script creates new LXC instances with Rocky Linux.
The only command I was able to get the disk size specified was "pct".
And it took a while to get this complete command line working.
So if you are looking into Proxmox and you want automation. This script can be a good starting point for your own ideas...
On my Proxmox 7.1.7 server it takes less than 15 seconds until I can log into the server using an existing SSH key!
-- Daniel
#!/bin/bash
# -------------------------------------------------------
HOSTNAME=rocky.nashcom.lab
IP_ADDR=192.168.1.123
DOMAIN=nashcom.org
SUBNET=192.168.1
GATEWAY=192.168.1.1
DNS_SERVER=8.8.8.8
CPU_CORES=2
MEMORY=2048
SWAP=512
DISK_POOL=zfs-pool
DISK_SIZE=24
OS_IMAGE=local:vztmpl/rockylinux-8-default_20210929_amd64.tar.xz
OS_TYPE=centos
SSH_PUB_KEY="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAILkOzdFq8JOtYINEfBa+TFYTMZu0AmR1201uElLDominoaN nsh@nashcom.lab"
#ROOT_PASSWORD="my-secure-password-not-needed-with-ssh-key"
# -------------------------------------------------------
#get next free LXC ID
LXC_ID=$(pvesh get /cluster/nextid)
if [ -n "$1" ]; then
HOSTNAME=$1
fi
if [ -z "$HOSTNAME" ]; then
HOSTNAME=$LXC_ID.$DOMAIN
fi
if [ -n "$2" ]; then
IP_ADDR=$2
fi
if [ -z "$IP_ADDR" ]; then
IP_ADDR=$SUBNET.$LXC_ID
fi
if [ -n "$ROOT_PASSWORD" ]; then
ROOT_PASSWORD_OPTION="--password $ROOT_PASSWORD"
fi
print_delim ()
{
echo "--------------------------------------------------------------------------------"
}
wait_for_server_start()
{
local count=0
while [ $count -le 10 ]; do
ping -c 1 $IP_ADDR > null 2>&1
if [ "$?" = "0" ]; then
return 0
fi
sleep 1
count=`expr $count + 1`
done
return 1
}
print_delim
# Create server with predefined specifications and requested IP
pct create $LXC_ID $OS_IMAGE \
--rootfs $DISK_POOL:$DISK_SIZE \
--cores $CPU_CORES --memory $MEMORY --swap $SWAP \
--hostname $HOSTNAME --nameserver $DNS_SERVER --searchdomain $DOMAIN \
--net0 name=eth0,bridge=vmbr0,firewall=0,gw=$GATEWAY,ip=$IP_ADDR/24,type=veth \
--ostype $OS_TYPE --start 1 --onboot 1 --description "auto generated"
print_delim
wait_for_server_start
lxc-attach -n $LXC_ID -- yum install -y openssh-server
lxc-attach -n $LXC_ID -- systemctl enable --now sshd
lxc-attach -n $LXC_ID -- ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519 -N ""
lxc-attach -n $LXC_ID -- bash -c "echo $SSH_PUB_KEY > ~/.ssh/authorized_keys"
echo
echo
print_delim
echo "LXC Container created"
print_delim
echo "LXC ID: $LXC_ID"
echo "Host name: $HOSTNAME"
echo "IP address: $IP_ADDR"
print_delim
echo
- Comments [3]
1Lars Berntrop-Bos 10.12.2021 14:16:09 Proxmox Virtualization -- Automatically deploying new LXC containers
Great stuff as usual, Daniel!
Thank you for the script.
2artodeto 14.12.2021 15:55:31 Proxmox Virtualization -- Automatically deploying new LXC containers
Thank you very much for this lines of code.
Really easy to read.
3Patrick 29.01.2024 17:17:12 Proxmox Virtualization -- Automatically deploying new LXC containers
Thanks for this, still useful today! Due to using a vlan tag, the ping routine doesn't work for me. Instead I replaced it with the pct_status command:
wait_for_server_start()
{
while [ $COUNT -lt $TIMEOUT ]; do
STATUS=$(pct status $LXC_ID 2>&1) # Get the status of the container
if [[ $STATUS == *"running"* ]]; then
echo "Container $LXC_ID is up."
return 0
fi
sleep 1 # Wait for 1 second before checking again
((COUNT++))
done