Skip to Content
  • +31 653-919-302
Cafayate.Net
  • 0
  • 0
  • Sign in
  • Nederlands English (US) Español (AR)
  • Contact Us
  • Home
  • Blog
  • Jobs
  • Contact us
Cafayate.Net
  • 0
  • 0
    • Home
    • Blog
    • Jobs
    • Contact us
  • +31 653-919-302
  • Nederlands English (US) Español (AR)
  • Sign in
  • Contact Us

How to use convert an KVM image into a LXC container

  • All Blogs
  • Tech Blog
  • How to use convert an KVM image into a LXC container
  • March 5, 2021 by
    Administrator

     

    KVM was an improvement over Xen for me. Still for many use-cases a LXC are a more performance, light-weight alternative – which also seems to be en vougue nowadays.

    Through switching to LXC I’ve reduced my overall memory usage a bit – the main benefit is, that processes within an LXC container are separated processes within the host system. This should allow the host system to manage memory (think cache, buffers, swap, etc.) more efficiently.

    I’ve started converting most of my trusted KVM images into LXC containers, this post contains the necessary steps.

    Step 1: create a new empty lxc container

    First of all we’ll create a new empty LXC container with a default configuration. I’ll name it ‘imap’, guess it’s purpose.

    $ lxc-create --name imap
    

    LXC’s containers are created within /var/lib/lxc and, surprise!, a new and aptly named /var/lib/lxc/imap container can be found. The container containes two entries for now: config for its configuration and an emptyrootfs-directory which will contain the containers filesystem soon.

    Step 2: copy the KVM image into the LXC container

    I’m using LVM-backed KVM/QEMU images, each LVM volume mirrors a physical harddrive including partition tables, etc. Alas this prevents us from just mounting the KVM root image.

    First of all let’s output the KVM image’s partition table:

    $ sudo fdisk -l /dev/vg0/imap.img
    
    Disk /dev/vg0/imap.img: 107.4 GB, 107374182400 bytes
    255 heads, 63 sectors/track, 13054 cylinders, total 209715200 sectors
    Units = sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 512 bytes
    Disk identifier: 0x00022ea3
    
                Device Boot      Start         End      Blocks   Id  System
    /dev/vg0/imap.img1   *        2048   209713151   104855552   83  Linux
    

    So the real filesystem starts at sector 2048 and each sector is 512 bytes long. This allows us to calculate this partitions offset within the image and loopback mount the partition into the hosts filesystem:

     $ mount -o loop,offset=$((2048*512)) /dev/vg0/imap.img /mnt-source
    

    Now we can copy the old KVM image’s contents into the new container:

     $ rsync -av /mnt-source/* /var/lib/lxc/imap/rootfs
    

    Step 3: prepare the container’s device nodes and fix fstab

    LXC does not support udev, so we’ll have to create the container’s device nodes by ourself. To simplify this, I’ve used the following bash script and copied it to /usr/local/sbin/create-lxc-nodes.sh

    #!/bin/bash
    ROOT=$(pwd)
    DEV=${ROOT}/dev
    mv ${DEV} ${DEV}.old
    mkdir -p ${DEV}
    mknod -m 666 ${DEV}/null c 1 3
    mknod -m 666 ${DEV}/zero c 1 5
    mknod -m 666 ${DEV}/random c 1 8
    mknod -m 666 ${DEV}/urandom c 1 9
    mkdir -m 755 ${DEV}/pts
    mkdir -m 1777 ${DEV}/shm
    mknod -m 666 ${DEV}/tty c 5 0
    mknod -m 600 ${DEV}/console c 5 1
    mknod -m 666 ${DEV}/tty0 c 4 0
    mknod -m 666 ${DEV}/tty1 c 4 1
    mknod -m 666 ${DEV}/tty2 c 4 2
    mknod -m 666 ${DEV}/tty3 c 4 3
    mknod -m 666 ${DEV}/tty4 c 4 4
    mknod -m 666 ${DEV}/tty5 c 4 5
    mknod -m 666 ${DEV}/tty6 c 4 6
    mknod -m 666 ${DEV}/full c 1 7
    mknod -m 600 ${DEV}/initctl p
    mknod -m 666 ${DEV}/ptmx c 5 2
    

    Use this script to create all needed device nodes:

     $ cd /var/lib/lxc/imap/rootfs
     $ /usr/local/sbin/create-lxc-nodes.sh
    

    As all filesystems were already prepared by the host system there’s no need for the guest system’s init system to do any work during bootup (actually this might rather be harmful). To prevent any problems I’ve commented out each and every line within the guests “etc/fstab” configuration file.

    Step 4: create LXC configuration file

    Each LXC container’s configuration is stored in the “config” file which is situated around the “rootfs” directory. Let’s create a new one:

    # Template used to create this container: (null)
    # Parameters passed to the template:
    lxc.mount.entry = proc proc proc nodev,noexec,nosuid 0 0
    lxc.mount.entry = sysfs sys sysfs defaults  0 0
    lxc.tty = 2
    lxc.pts = 1024
    lxc.cgroup.devices.deny = a
    lxc.cgroup.devices.allow = c 1:3 rwm
    lxc.cgroup.devices.allow = c 1:5 rwm
    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
    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
    lxc.cgroup.devices.allow = c 254:0 rm
    lxc.utsname = imap
    lxc.network.type = veth
    lxc.network.flags = up
    lxc.network.link = virbr0
    lxc.network.hwaddr = 00:16:3e:f1:35:ab
    lxc.network.ipv4.gateway = 192.168.122.1
    lxc.network.ipv4 = 192.168.122.15
    lxc.cap.drop = sys_module
    lxc.cap.drop = mac_admin
    lxc.cap.drop = mac_override
    lxc.cap.drop = sys_time
    lxc.rootfs = /var/lib/lxc/imap/rootfs
    

    We’ll allow a couple of devices (mostly terminals) and provide a mounted proc and sys filesystem to the guest. Note the container’s name (lxc.utsname) and the configured path for it’s root filesystem (/var/lib/lxc/imap/rootfs). In addition this configuration file contains the network configuration (ipv4 sets the IP address which the container will be assigned to by the internal DHCP server). Please don’t forget to provide an unique MAC address (hwaddr) to each container.

    Step 5: start the container

    Start the container in the background and SSH into it

     $ lxc-start --name imap -d
     $ ssh 192.168.122.15
    

    Say welcome to your new container!

    Appendix 1: improve the container..

    There are some things that are not needed anymore. All commands are entered within the container (which is a Debian 7.0 system BTW)!

     $ apt-get remove --purge acpid acpi
     $ update-rc.d -f hwclock.sh remove
     $ update-rc.d -f mountall.sh remove
     $ update-rc.d -f checkfs.sh remove
     $ update-rc.d -f udev remove
    

    Let’s see how we can improve the container in the future..

     

     

    in Tech Blog
    wp-config options

    Designed for companies

    We are a team of passionate people whose goal is to improve everyone's life through disruptive products. We build great products to solve your business problems. Our products are designed for small to medium size companies willing to optimize their performance.

    Get in touch

    Plantexel
    Pedernera
    Salta Capital 
    Argenina

    • +31 653-919-302
    • [email protected]
    Follow us
    Copyright © Plantexel
    Nederlands | English (US) | Español (AR)