====== migration from vserver to lxc ======
===== preface =====
host system: debian jessie 8.9
the host uses lvm2, one lv per vserver
you need: LXC > Version 2.0, install it from jessie-backports
do not install dnsmasq!
I use [[http://www.fischglas.de/software/vo/|vo]] to keep track of changes so does this document.
===== prereq. =====
if ! grep -q "[^#]* jessie-backports" /etc/apt/sources.list ; then
vo -o /etc/apt/sources.list
echo "deb http://ftp.de.debian.org/debian jessie-backports main non-free contrib" >> /etc/apt/sources.list
vo -i /etc/apt/sources.list
fi
apt-get update
apt-get install --no-install-recommends lxc/jessie-backports lxcfs uidmap debootstrap
# new kernel
apt-get install linux-image-4.9.0-0.bpo.3-amd64 linux-base=4.3~bpo8+1 firmware-linux-free irqbalance
apt-get install linux-image-amd64
apt-get clean
===== start migration =====
# stop vservers:
VSERVERS=$(
vserver-stat | awk 'NR > 1 { print $NF }'
)
echo "$VSERVERS" > /root/vservers-list
xargs -r -i% vserver % stop < /root/vservers-list
reboot
System should boot with Linux 4.9.0-0.bpo.3-amd64 .
The subuid mechanism needs the uid/gid values inside the container
to be recalculated and changed.
[[http://www.fischglas.de/software/ownrecalc/|ownrecalc]] gets the job done
smoothly.
if [ ! -f /usr/bin/ownrecalc ]; then
wget http://www.fischglas.de/software/ownrecalc/ownrecalc -O /usr/bin/ownrecalc
chmod 755 /usr/bin/ownrecalc
fi
Create a default container configuration:
if [ ! -f /var/lib/lxc/default.conf ] ; then
touch /var/lib/lxc/default.conf
vo -o /var/lib/lxc/default.conf
cat << EOF > /var/lib/lxc/default.conf
lxc.autodev = 1
lxc.kmsg = 0
lxc.network.type = veth
lxc.network.flags = up
lxc.network.name = eth0
lxc.mount.auto = sys:ro proc:mixed cgroup-full:mixed
lxc.cap.keep = chown net_raw dac_override dac_read_search fowner fsetid kill setgid setuid linux_immutable net_bind_service net_broadcast ipc_lock ipc_owner sys_chroot sys_ptrace sys_pacct sys_boot sys_nice sys_resource sys_tty_config lease audit_write audit_control syslog wake_alarm
lxc.pts = 1024
lxc.cgroup.devices.deny = a
lxc.aa_profile = unconfined
# --- devices --- #
# /dev/null and zero
lxc.cgroup.devices.allow = c 1:3 rwm
lxc.cgroup.devices.allow = c 1:5 rwm
# consoles
lxc.cgroup.devices.allow = c 5:1 rwm
lxc.cgroup.devices.allow = c 5:0 rwm
lxc.cgroup.devices.allow = c 4:0 rwm
lxc.cgroup.devices.allow = c 4:1 rwm
# /dev/{,u}random
lxc.cgroup.devices.allow = c 1:9 rwm
lxc.cgroup.devices.allow = c 1:8 rwm
lxc.cgroup.devices.allow = c 136:* rwm
lxc.cgroup.devices.allow = c 5:2 rwm
# rtc
lxc.cgroup.devices.allow = c 254:0 rwm
lxc.mount.entry=run run tmpfs rw,nosuid,nodev,relatime,mode=755 0 0
EOF
vo -i /var/lib/lxc/default.conf
fi
===== migrate a single vserver =====
# name of the volume group
VGNAME='vg_00'
CONTAINER_NAME='vserver01'
CONTAINER_IP=$( cat /etc/vservers/$CONTAINER_NAME/interfaces/0/ip )
CONTAINER_BRIDGE=$( cat /etc/vservers/$CONTAINER_NAME/interfaces/0/dev )
CONTAINER_NETMASK=$( cat /etc/vservers/$CONTAINER_NAME/interfaces/0/prefix )
if [ -z "$CONTAINER_NETMASK" ]; then
# netzmaske der ersten IPv4-adresse
CONTAINER_NETMASK=$( ip a l dev $CONTAINER_BRIDGE | awk -F"[ /]+" '$2 == "inet" { print $4; exit 0 }' )
fi
CONTAINER_GATEWAY=$( ip r l | awk '$1 == "default" { print $3 }' )
# https://serverfault.com/questions/40712/what-range-of-mac-addresses-can-i-safely-use-for-my-virtual-machines
CONTAINER_MACADDR_PFX='22'
CONTAINER_SUBUID_STEP='1000000'
CONTAINER_SUBUID=$(
awk -F: '{ print $2}' /etc/subuid | sort -n | tail -1 | awk -v s=$CONTAINER_SUBUID_STEP '{ print int (( $1 + 2 * s - 1 ) / s) * s }'
)
VOLUME=$( df -k /vservers/$CONTAINER_NAME | awk 'NR==2 { print $1 }' )
# 22 + 0 + hex(ip)
CONTAINER_MACADDR="$CONTAINER_MACADDR_PFX:0:$( printf "%x:%x:%x:%x" $( tr . ' ' <<< $CONTAINER_IP ))"
# check things
cat << EOF
CONTAINER_NAME $CONTAINER_NAME
CONTAINER_IP $CONTAINER_IP/$CONTAINER_NETMASK
GW $CONTAINER_GATEWAY
CONTAINER_MACADDR $CONTAINER_MACADDR
CONTAINER_BRIDGE $CONTAINER_BRIDGE
CONTAINER_SUBUID $CONTAINER_SUBUID
VGNAME $VGNAME
VOLUME $VOLUME
EOF
##
## remount the lv
##
NEWMNTPT=/var/lib/lxc/$CONTAINER_NAME
mkdir -p /etc/RCS
vo -o /etc/fstab
MOUNTPT=$( awk -v v=$VOLUME '$1 == v { print $2 }' /etc/fstab )
umount $MOUNTPT
sed -i "s#\([\t ][\t ]*\)$MOUNTPT\([\t ][\t ]*\)#\1$NEWMNTPT\2#" /etc/fstab | grep $VOLUME
rcsdiff /etc/fstab
vo -i /etc/fstab
if [ -e /var/lib/lxc/$CONTAINER_NAME ]; then
echo "base directory already exists, exiting"
exit 1;
fi
mkdir /var/lib/lxc/$CONTAINER_NAME
mount /var/lib/lxc/$CONTAINER_NAME
##
## calculate and enter sub(u|g)id
##
touch /etc/subuid /etc/subgid
vo -o /etc/subuid /etc/subgid
cat << EOF >> /etc/subuid
root:$CONTAINER_SUBUID:65536
EOF
rcsdiff /etc/subuid
cat << EOF >> /etc/subgid
root:$CONTAINER_SUBUID:65536
EOF
rcsdiff /etc/subgid
vo -i /etc/subuid /etc/subgid
##
## bootstrap container
##
mkdir /var/lib/lxc/$CONTAINER_NAME/rootfs
mv /var/lib/lxc/$CONTAINER_NAME/* /var/lib/lxc/$CONTAINER_NAME/rootfs/
ls -la /var/lib/lxc/$CONTAINER_NAME/
# if there are .dot files, move them manually
lxc-create -n $CONTAINER_NAME -t none
# create individual container config
touch /var/lib/lxc/$CONTAINER_NAME/config
mkdir -p /var/lib/lxc/$CONTAINER_NAME/RCS
vo -o /var/lib/lxc/$CONTAINER_NAME/config
cat << EOF > /var/lib/lxc/$CONTAINER_NAME/config
lxc.include = /var/lib/lxc/default.conf
lxc.rootfs = /var/lib/lxc/$CONTAINER_NAME/rootfs
lxc.utsname = $CONTAINER_NAME
lxc.network.link = $CONTAINER_BRIDGE
lxc.network.hwaddr = $CONTAINER_MACADDR
lxc.network.ipv4 = $CONTAINER_IP/$CONTAINER_NETMASK
lxc.network.ipv4.gateway = $CONTAINER_GATEWAY
lxc.network.veth.pair = $CONTAINER_NAME
lxc.id_map = u 0 $CONTAINER_SUBUID 65536
lxc.id_map = g 0 $CONTAINER_SUBUID 65536
lxc.start.auto = 1
EOF
vo -i /var/lib/lxc/$CONTAINER_NAME/config
# fix /run inside the container
if [ -L /var/lib/lxc/$CONTAINER_NAME/rootfs/run ]; then
rm /var/lib/lxc/$CONTAINER_NAME/rootfs/run
fi
if [ ! -e /var/lib/lxc/$CONTAINER_NAME/rootfs/run ]; then
mkdir /var/lib/lxc/$CONTAINER_NAME/rootfs/run
fi
# adjust uid/gid for the container
ownrecalc -U "*" -G "*" -u +$CONTAINER_SUBUID -g +$CONTAINER_SUBUID -d /var/lib/lxc/$CONTAINER_NAME/rootfs
# check, should be empty:
find /var/lib/lxc/$CONTAINER_NAME/rootfs -uid -$(( $CONTAINER_SUBUID )) -ls
find /var/lib/lxc/$CONTAINER_NAME/rootfs -uid +$(( $CONTAINER_SUBUID + $CONTAINER_SUBUID_STEP -1 )) -ls
# start the new container
lxc-start -d -n $CONTAINER_NAME
# check:
lxc-attach -n $CONTAINER_NAME -- uname -a
lxc-attach -n $CONTAINER_NAME -- ps xa
##
## delete the obsolete vserver config
##
vserver $CONTAINER_NAME delete
Repeat the above for all vservers.
===== Remove obsolete vserver setup =====
apt-get purge util-vserver-sysv util-vserver-core util-vserver-build linux-image-4.1-vserver-amd64 libvserver0
apt-get --purge autoremove
rm -rf /etc/vservers /var/lib/vservers /vservers