Introduction
The LXD team is very excited to announce the release of LXD 3.13!
This is another very exciting LXD release, packed with useful features and a lot of bugfixes and performance improvements!
The latest addition to the LXD team, @tomp has been busy improving the LXD networking experience with quite a few new features and bugfixes already making it into this release.
We’ve also gotten all the plumbing needed for system call interception done and in place in this release, currently handling mknod
on supported systems.
Cluster users will enjoy this release too, thanks to scaling improvements, reducing the load on the leader a bit and improving container copies and migration, especially on CEPH clusters.
Enterprise users will like the addition of Role Based Access Control through the external Canonical RBAC service, making it possible to control permissions to individual projects on your LXD servers and assign roles to your users and groups.
And we’ve even managed to get quotas working for the dir
storage backend at last, thanks to the addition of filesystem project quotas in recent kernels.
Enjoy!
New features
Cluster: Improved heartbeat interval
In a LXD cluster, the current leader periodically sends a hearbeat to all other cluster members. The main purpose of this is to detect offline cluster members, marking them as offline in the database so that queries no longer block on them. A secondary use for those hearbeats is to refresh the list of database nodes.
Previously, this was done every 4s with all cluster members being contacted at the same time, resulting in spikes in CPU and network traffic, especially on the current cluster leader.
LXD 3.13 changes that by bumping the interval to 10s and by adding randomization to the timing of the hearbeats so that not all cluster members are contacted at the same time. Extra logic was also added to detect cluster members that get added during a hearbeat run.
Cluster Internal container copy
LXD 3.13 now properly implements one step container copies, similar to how you would normally copy a container on a standalone LXD instance. Prior to this, the client had to know whether to perform a copy (if staying on the same cluster member) or a migration (if going to another cluster member), this is now all done internally.
A side benefit of this fix is that all CEPH copies are now near instantaneous on clusters as those do not require any migration at all.
Initial syscall interception support
LXD 3.13 when combined with a 5.0 or higher kernel, as well as the very latest libseccomp and liblxc can now intercept and mediate system calls in userspace.
For this first pass, we have focused on mknod
, implementing a basic allow list of devices which can now be created by unprivileged containers.
It will take a little while before this feature can be commonly used as we will need an upstream release of both libseccomp and liblxc and are waiting for further improvements to the feature in the kernel too.
We will be building upon this capability to allow specific filesystems to be mounted inside unprivileged containers in the future as well as allow things like kernel module loading and more (all will require opt-in from the administrator).
Role Based Access Control (RBAC)
Users of the Canonical RBAC service can now integrate LXD with it.
LXD will register all its projects with RBAC, allowing administrators to assign roles to users/groups for specific projects or for the entire LXD instance.
Currently this includes the following permissions:
- Full administrative access to LXD
- Management of containers (creation, deletion, re-configuration, …)
- Operation of containers (start/stop/restart, exec, console, …)
- Management of images (creation, deletion, aliases, …)
- Management of profiles (creation, deletion, re-configuration, …)
- Management of the project itself (re-configuration)
- Read-only access (view everything tied to a project)
This gets us one step closer to being able to run a shared LXD cluster with unprivileged users being able to run containers on it without concerns of them escalating their privileges.
IPVLAN support
LXD can now make use of the recent implementation of ipvlan
in LXC.
When running a suitably recent version of LXC, IPVLAN can now be configured in LXD through a nic
device:
- Setting the
nictype
property toipvlan
- Setting the
parent
property to the expected outgoing device - For IPv4, setting
ipv4.address
to the desired address - For IPv6, setting
ipv6.address
to the desired address
Here is an example of it in action:
stgraber@castiana:~$ lxc init ubuntu:18.04 ipvlan
Creating ipvlan
stgraber@castiana:~$ lxc config device add ipvlan eth0 nic nictype=ipvlan parent=wlan0 ipv4.address=172.17.0.100 ipv6.address=2001:470:b0f8:1000:1::100
Device eth0 added to ipvlan
stgraber@castiana:~$ lxc start ipvlan
stgraber@castiana:~$ lxc exec ipvlan bash
root@ipvlan:~# ifconfig
eth0: flags=4291<UP,BROADCAST,RUNNING,NOARP,MULTICAST> mtu 1500
inet 172.17.0.100 netmask 255.255.255.255 broadcast 255.255.255.255
inet6 2001:470:b0f8:1000:1::100 prefixlen 128 scopeid 0x0<global>
inet6 fe80::28:f800:12b:bdf8 prefixlen 64 scopeid 0x20<link>
ether 00:28:f8:2b:bd:f8 txqueuelen 1000 (Ethernet)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 5 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 1000 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
root@ipvlan:~# ip -4 route show
default dev eth0
root@ipvlan:~# ip -6 route show
2001:470:b0f8:1000:1::100 dev eth0 proto kernel metric 256 pref medium
fe80::/64 dev eth0 proto kernel metric 256 pref medium
default dev eth0 metric 1024 pref medium
root@ipvlan:~# ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=14.4 ms
--- 8.8.8.8 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 14.476/14.476/14.476/0.000 ms
root@ipvlan:~# ping6 -n 2607:f8b0:400b:800::2004
PING 2607:f8b0:400b:800::2004(2607:f8b0:400b:800::2004) 56 data bytes
64 bytes from 2607:f8b0:400b:800::2004: icmp_seq=1 ttl=57 time=21.2 ms
--- 2607:f8b0:400b:800::2004 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 21.245/21.245/21.245/0.000 ms
root@ipvlan:~#
Quota support on dir
storage backend
Support for the project quota
feature of recent Linux kernels has been added.
When the backing filesystem for a dir
type storage pool is suitably configured, container quotas can now be set as with other storage backends and disk usage is also properly reported.
stgraber@castiana:~$ sudo truncate -s 10G /tmp/ext4.img
stgraber@castiana:~$ sudo mkfs.ext4 /tmp/ext4.img
mke2fs 1.44.6 (5-Mar-2019)
Discarding device blocks: done
Creating filesystem with 2621440 4k blocks and 655360 inodes
Filesystem UUID: d8ab56d9-1e84-40ee-921a-c68c06ad6625
Superblock backups stored on blocks:
32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632
Allocating group tables: done
Writing inode tables: done
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
stgraber@castiana:~$ sudo tune2fs -O project -Q prjquota /tmp/ext4.img
tune2fs 1.44.6 (5-Mar-2019)
stgraber@castiana:~$ sudo mount -o prjquota /tmp/ext4.img /mnt/
stgraber@castiana:~$ sudo rmdir /mnt/lost+found/
stgraber@castiana:~$ lxc storage create mnt dir source=/mnt
Storage pool mnt created
stgraber@castiana:~$ lxc launch ubuntu:18.04 c1 -s mnt
Creating c1
Starting c1
stgraber@castiana:~$ lxc exec c1 -- df -h
Filesystem Size Used Avail Use% Mounted on
/var/lib/lxd/storage-pools/mnt/containers/c1/rootfs 9.8G 742M 8.6G 8% /
none 492K 0 492K 0% /dev
udev 7.7G 0 7.7G 0% /dev/tty
tmpfs 100K 0 100K 0% /dev/lxd
tmpfs 100K 0 100K 0% /dev/.lxd-mounts
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 152K 7.8G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
stgraber@castiana:~$ lxc config device set c1 root size 1GB
stgraber@castiana:~$ lxc exec c1 -- df -h
Filesystem Size Used Avail Use% Mounted on
/var/lib/lxd/storage-pools/mnt/containers/c1/rootfs 954M 706M 249M 74% /
none 492K 0 492K 0% /dev
udev 7.7G 0 7.7G 0% /dev/tty
tmpfs 100K 0 100K 0% /dev/lxd
tmpfs 100K 0 100K 0% /dev/.lxd-mounts
tmpfs 7.8G 0 7.8G 0% /dev/shm
tmpfs 7.8G 152K 7.8G 1% /run
tmpfs 5.0M 0 5.0M 0% /run/lock
tmpfs 7.8G 0 7.8G 0% /sys/fs/cgroup
stgraber@castiana:~$ lxc info c1
Name: c1
Location: none
Remote: unix://
Architecture: x86_64
Created: 2019/05/09 16:09 UTC
Status: Running
Type: persistent
Profiles: default
Pid: 10096
Ips:
eth0: inet 10.166.11.38 vethKM0DFY
eth0: inet6 2001:470:b368:4242:216:3eff:fe4b:2c3 vethKM0DFY
eth0: inet6 fe80::216:3eff:fe4b:2c3 vethKM0DFY
lo: inet 127.0.0.1
lo: inet6 ::1
Resources:
Processes: 24
Disk usage:
root: 739.77MB
CPU usage:
CPU usage (in seconds): 7
Memory usage:
Memory (current): 104.91MB
Memory (peak): 229.67MB
Network usage:
lo:
Bytes received: 1.23kB
Bytes sent: 1.23kB
Packets received: 12
Packets sent: 12
eth0:
Bytes received: 480.35kB
Bytes sent: 27.21kB
Packets received: 332
Packets sent: 277
Routes on container NIC devices
New ipv4.routes
and ipv6.routes
options on the nic
devices make it possible to tie a particular route to a specific container, making it follow the container as it’s moved between hosts.
This will usually be a better option than using the similarly named key on the network itself.
Configurable NAT source address
New ipv4.nat.address
and ipv6.nat.address
properties on LXD networks now make it possible to override the outgoing IP address for a particular bridge.
LXC features exported in API
Similar to what was done in the previous release with kernel features, specific LXC features which LXD can use when present are now exported by the LXD API so that clients can check what advanced feature to expect on the target.
lxc_features:
mount_injection_file: "true"
network_gateway_device_route: "true"
network_ipvlan: "true"
network_l2proxy: "true"
seccomp_notify: "true"
Bugs fixed
- client: Consider volumeOnly option when migrating
- client: Copy volume config and description
- client: Don’t crash on missing stdin
- client: Fix copy from snapshot
- client: Fix copying between two unix sockets
- doc: Adds missing packages to install guide
- doc: Correct host_name property
- doc: Update storage documentation
- i18n: Update translations from weblate
- lxc/copy: Don’t strip volatile keys on refresh
- lxc/utils: Updates progress to stop outputting if msg is longer than window
- lxd/api: Rename alias* commands to imageAlias*
- lxd/api: Rename apiProject* to project*
- lxd/api: Rename certificateFingerprint* to certficate*
- lxd/api: Rename operation functions for consistency
- lxd/api: Rename serverResources to api10Resources
- lxd/api: Rename snapshotHandler to containerSnapshotHandler
- lxd/api: Replace Command with APIEndpoint
- lxd/api: Sort API commands list
- lxd/candid: Cleanup config handling
- lxd/certificates: Make certificate add more robust
- lxd/certificates: Port to APIEndpoint
- lxd/cluster: Avoid panic in Gateway
- lxd/cluster: Fix race condition during join
- lxd/cluster: Port to APIEndpoint
- lxd/cluster: Use current time for hearbeat
- lxd/cluster: Workaround new raft logging
- lxd/containers: Avoid costly storage calls during snapshot
- lxd/containers: Change disable_ipv6=1 to accept_ra=0 on host side interface
- lxd/containers: Don’t fail on old libseccomp
- lxd/containers: Don’t needlessly mount snapshots
- lxd/containers: Early check for running container refresh
- lxd/containers: Fix bad operation type
- lxd/containers: Fix profile snapshot settings
- lxd/containers: Moves network limits to network up hook
- lxd/containers: Only run network up hook for nics that need it
- lxd/containers: Optimize snapshot retrieval
- lxd/containers: Port to APIEndpoint
- lxd/containers: Remove unused arg from network limits function
- lxd/containers: Speed up simple snapshot list
- lxd/daemon: Port to APIEndpoint
- lxd: Don’t allow remote access to internal API
- lxd: Fix volume migration with snapshots
- lxd: Have Authenticate return the protocol
- lxd: More reliably grab interface host name
- lxd: Port from HasApiExtension to LXCFeatures
- lxd: Rename parseAddr to proxyParseAddr
- lxd: Use idmap.Equals
- lxd/db: Fix substr handling for containers
- lxd/db: Parent filter for ContainerList
- lxd/db/profiles: Fix cross-project updates
- lxd/db: Properly handle unsetting keys
- lxd/event: Port to APIEndpoint
- lxd/images: Fix project handling on copy
- lxd/images: Fix simplestreams cache expiry
- lxd/images: Port to APIEndpoint
- lxd/images: Properly handle invalid protocols
- lxd/images: Replicate images to the right project
- lxd/internal: Port to APIEndpoint
- lxd/migration: Fix feature negotiation
- lxd/network: Filter leases by project
- lxd/network: Fix DNS records for projects
- lxd/network: Port to APIEndpoint
- lxd/operation: Port to APIEndpoint
- lxd/patches: Fix LVM VG name
- lxd/profiles: Optimize container updates
- lxd/profiles: Port to APIEndpoint
- lxd/projects: Port to APIEndpoint
- lxd/proxy: Correctly handle unix: path rewriting with empty bind=
- lxd/proxy: Don’t wrap string literal
- lxd/proxy: Fix goroutine leak
- lxd/proxy: Handle mnts for abstract unix sockets
- lxd/proxy: Make helpers static
- lxd/proxy: Make logfile close on exec
- lxd/proxy: Only attach to mntns for unix sockets
- lxd/proxy: Retry epoll on EINTR
- lxd/proxy: Use standard macros on exit
- lxd/proxy: Validate the addresses
- lxd/resource: Port to APIEndpoint
- lxd/storage: Don’t hardcode default project
- lxd/storage: Fix error message on differing maps
- lxd/storage: Handle XFS with leftover journal entries
- lxd/storage: Port to APIEndpoint
- lxd/storage/btrfs: Don’t make ro snapshots when unpriv
- lxd/storage/ceph: Don’t mix stderr with json
- lxd/storage/ceph: Fix snapshot of running containers
- lxd/storage/ceph: Fix snapshot of running xfs/btrfs
- lxd/storage/ceph: Fix UUID re-generation
- lxd/storage/ceph: Only rewrite UUID once
- lxd/sys: Cleanup State struct
- scripts/bash: Add bash completion for profile/container device get, set, unset
- shared: Add StringMapHasStringKey helper function
- shared: Fix $SNAP handling under new snappy
- shared: Fix Windows build
- shared/idmap: Add comparison function
- shared/netutils: Adapt to kernel changes
- shared/netutils: Add AbstractUnixReceiveFdData()
- shared/netutils: Export peer link id in getifaddrs
- shared/netutils: Handle SCM_CREDENTIALS when receiving fds
- shared/netutils: Move network cgo to shared/netutils
- shared/netutils: Move send/recv fd functions
- shared/network: Fix reporting of down interfaces
- shared/network: Get HostName field when possible
- shared/osarch: Add i586 to arch aliases
- tests: Extend migration tests
- tests: Handle built-in shiftfs
- tests: Updates config tests to use host_name for nic tests
Try it for yourself
This new LXD release is already available for you to try on our demo service.
Downloads
The release tarballs can be found on our download page.