How to upgrade LXD VMs powered by Ubuntu/Debian or CentOS Linux

in Categories , , , , last updated July 11, 2017

I run over 10+ LXD VMs powered by CentOS Linux 7 and Debian/Ubuntu Linux. How do I upgrade all VMs automatically or on demand using Ansible tool?

lxd-vm-upgradeThere are two ways to upgrade your LXD (Linux containers) VMs. Both methods depend upon the use of the /usr/bin/lxc command.

Method 1 – Update using a shell script

The syntax is pretty simple:
/usr/bin/lxc exec vmNameHere -- command
/usr/bin/lxc exec vmNameHere -- /usr/bin/apt-get -y upgrade
/usr/bin/lxc exec vmNameHere -- /usr/bin/apt-get -y upgrade
/usr/bin/lxc exec vmNameHere -- /usr/bin/yum -y update

Next you can create a shell script as follows:

# Purpose: Run given command inside the LXD vm 
# Note: Must be run from host. Only tested on Ubuntu 16.04 LTS
# Author: Vivek Gite { } under GPL v2.x+
# -----------------------------------------------------------------
for i in vm1 vm2 vm3 vm10
  echo "[*** $i ***]"
  /usr/bin/lxc exec $i -- $cmd

Now all you have to do is run command for a Debian or Ubuntu Linux based vm i.e. pass the apt-get command/apt command to update VM:
$ ~/bin/script-name /usr/bin/apt-get update
$ ~/bin/script-name /usr/bin/apt-get -y upgrade

If you are using a CentOS 7 based VM pass the yum command:
$ ~/bin/script-name /usr/bin/apt-get /usr/bin/yum -y update

Method 2 – Update LXD VMs using Ansible devops/sysadmin automation tool

You can create a lxd-update.yml ansible playbook file as follows:

          # Update host running on Debian/Ubuntu
          - name: Updating host using apt
                    update_cache: yes
                    upgrade: dist
          # Now update VMs powered by Debian/Ubuntu Linux
          - name: Run lxc to update debian/ubuntu vms repo
            command: /usr/bin/lxc exec {{ item }} -- /usr/bin/apt-get -y update 
                    - ubuntuvm1
                    - debianvm2
                    - ubuntuvm3
          - name: Run lxc to upgrade debian/ubuntu vms pacakges
            command: /usr/bin/lxc exec {{ item }} -- /usr/bin/apt-get -y upgrade 
                    - ubuntuvm1
                    - debianvm2
                    - ubuntuvm3
          # Now update VMs powered by CentOS 7 Linux
          - name: Run lxc to upgrade centos vms
            command: /usr/bin/lxc exec {{ item }} -- /usr/bin/yum -y update
                    - centosvm4
                    - centosvm5
                    - centosvm6

You can run it as follows using the ansible-playbook command:
$ ansible-playbook -i my-hosts lxd-update.yml
The last method is easy to use and easy to extend too. Hence, I recommend that you use the Ansible playbooks to update your LXD powered VMs.

Posted by: Vivek Gite

The author is the creator of nixCraft and a seasoned sysadmin, DevOps engineer, and a trainer for the Linux operating system/Unix shell scripting. Get the latest tutorials on SysAdmin, Linux/Unix and open source topics via RSS/XML feed or weekly email newsletter.

Share this on (or read 3 comments/add one below):

3 comment

  1. The first shell script using §for§ doesn’t need the §cmd§ variable at all.

  2. Btw. /usr/bin/lxc is not available on CentOS7 (to my knowledge).

    When I update my containers I normally do something like;

    I normally do something like this.
    lxc-ls –active | while read l ; do
    lxc-attach -n $l — apt-get update
    lxc-attach -n $l — apt-get -y upgrade
    lxc-stop -n $l
    lxc-start -n $1 -d

  3. Hi,
    There is another solution which is, IMHO, more “ansible way”.
    You can use the LXD connection type in your inventory (or in your playbook) and access directly to your containers and use standard ansible module like apt, yum or package instead of command.

    So, in your inventory, list your containers as:
    ubuntuvm1 ansible_connection=lxd
    debianvm2 ansible_connection=lxd
    ubuntuvm3 ansible_connection=lxd

    And in your playbook,

    – name: Update containers
    hosts: all

    – name: update containers
    update_cache: yes
    cache_valid_time: 3600

    And because of ansible_connection=lxd, Ansible access directly to the container, even if there is no ssh server in containers. I use a lot the methode to test my Ansible roles on my laptop.

    Have a question? Post it on our forum!