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

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?

There 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:

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

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
            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 
            with_items:
                    - ubuntuvm1
                    - debianvm2
                    - ubuntuvm3
 
          - name: Run lxc to upgrade debian/ubuntu vms pacakges
            command: /usr/bin/lxc exec {{ item }} -- /usr/bin/apt-get -y upgrade 
            with_items:
                    - 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
            with_items:
                    - 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.

🐧 If you liked this page, please support my work on Patreon or with a donation.
🐧 Get the latest tutorials on SysAdmin, Linux/Unix, Open Source/DevOps topics:
CategoryList of Unix and Linux commands
File Managementcat
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network Utilitiesdig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
2 comments… add one
  • Casper Jul 12, 2017 @ 19:32

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

    When I update my containers I normally do something like;

    13914750335fbcb4af18d8f_000002

  • Jean-Louis FEREY Jul 13, 2017 @ 8:43

    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:
    [MyContainers]
    ubuntuvm1 ansible_connection=lxd
    debianvm2 ansible_connection=lxd
    ubuntuvm3 ansible_connection=lxd

    And in your playbook,

    ---
    - name: Update containers
       hosts: all
       
       tasks:
       - name: update containers
          apt:
             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.

Leave a Reply

Your email address will not be published. Required fields are marked *

Use HTML <pre>...</pre>, <code>...</code> and <kbd>...</kbd> for code samples.