LXD: OpenStack CLI (OSC) container

# create container
lxc launch ubuntu:20.04 osc
lxc shell osc
# install OpenStack CLI
apt install -y python3-openstackclient python3-neutron-vpnaas python3-octaviaclient
openstack complete | sudo tee /etc/bash_completion.d/openstack
source /etc/bash_completion
# configure connection
mkdir -p .config/openstack
cat <<EOF> .config/openstack/clouds.yaml
      auth_url: https://keystone.service.example.com/v3
      application_credential_id: "xxxxxxxx"
      application_credential_secret: "xxxxxxxx"
    region_name: "eu-fra1"
    interface: "public"
    identity_api_version: 3
    auth_type: "v3applicationcredential"
echo export OS_CLOUD=dev-foo-app >> .bashrc
# test
export OS_CLOUD=dev-foo-app
openstack image list

LXD: storage


Configure default storage

lxc storage create zfs zfs source=rpool/lxd
lxc profile device add default root disk path=/ pool=zfs
lxc storage list
lxc storage delete default
# zfs
lxc storage create zfs zfs source=tank/lxd
lxc storage list
# delete default storage
lxc storage volume list default
lxc storage volume delete default image/7d788819a5a97433db8470ee68370ec69e829b429800fa28b5524f0411490ce9
lxc storage delete default
# move container to another storage
lxc move ${CONTAINER} ${CONTAINER}-tmp -s nvme
lxc move ${CONTAINER}-tmp ${CONTAINER}
lxc start ${CONTAINER}

Configure ZFS storage

lxc profile device del dev-zfs root
lxc profile device add dev-zfs root disk path=/ pool=zfs


# change container storage quota
lxc config device set <CONTAINER_NAME> root size 100GB
# lvm thin pool
lvcreate -L 250G --thinpool kvm system
lxc storage create kvm lvm source=system lvm.thinpool_name=kvm
# unix-block
lxc config device add c1 xvdb1 unix-block source=/dev/xvdb1 required=false
lxc config device remove gitlab-runner3-dev xvdb2

Container root

LXD: nested containers

#cp -a /lib/modules/$(uname -r) /var/lib/lxd/containers/CONTAINER/rootfs/lib/modules/
echo 50000 > /proc/sys/kernel/keys/maxkeys
lxc config set ${CONTAINER} security.nesting true
#lxc launch ${CONTAINER} -p default -p docker
#lxc exec ${CONTAINER} -- apt install -y linux-modules-extra-$(uname -r)
#lxc config set ${CONTAINER} security.privileged true
lxc exec ${CONTAINER} apt install docker.io

Docker inside LXD

lxc launch ubuntu:18.04 gitlab-runner1-dev \
  -p disk-zfs -p nic-dev-mgmt \
  -c security.nesting=true \
  -c security.privileged=true

raw.lxc parameter

printf 'lxc.apparmor.profile = unconfined\nlxc.cgroup.devices.allow = a\nlxc.mount.auto=proc:rw sys:rw\nlxc.cap.drop=' | lxc config set ${CONTAINER_NAME} raw.lxc -


LXD with OpenvSwitch network

# create bridge
ovs-vsctl add-br mybridge
# ifconfig mybridge up
ip link set mybridge up
ovs-vsctl show
# connect ovs bridge to external network
ovs-vsctl add-port mybridge eno1
ifconfig eno1 0
dhclient mybridge -v
ip a show mybridge
route -n
# create LXD container
lxc profile create disk-only
lxc storage create pool1 dir
lxc profile device add disk-only root disk path=/ pool=pool1
lxc profile show disk-only
lxc launch ubuntu:18.04 ovs1 -p disk-only
lxc config device add ovs1 eth0 nic nictype=bridged parent=mybridge host_name=vport11
lxc launch ubuntu:18.04 ovs2 -p disk-only
lxc config device add ovs2 eth0 nic nictype=bridged parent=mybridge host_name=vport12
lxc network list

LXD: Network

Configure default profile

lxc network create lxdbr0
lxc profile device add default eth0 nic nictype=bridged parent=lxdbr0

Configure static IP address

lxc stop c1
lxc network attach lxdbr0 c1 eth0 eth0
lxc config device set c1 eth0 ipv4.address
lxc start c1


lxc network set lxdbr0 ipv6.dhcp.stateful true

ovs network

lxc profile create disk-only
lxc storage create pool1 dir
lxc profile device add disk-only root disk path=/ pool=pool1
lxc profile show disk-only
lxc launch ubuntu:18.04 ovs1 -p disk-only
lxc config device add ovs1 eth0 nic nictype=bridged parent=ovsbridge host_name=vport11
lxc network list
# test static ip
lxc launch redis r
lxc config device override r
lxc config device set r eth0 ipv4.address


LXD: Create container with HTTP(s) proxy

# Create container
lxc launch ubuntu:18.04 ${CONTAINER}
sleep 10
# Deploy SSH key
lxc file push --uid 0 --gid 0 --mode 600 ~/.ssh/id_rsa.pub ${CONTAINER}/root/.ssh/authorized_keys
# Configure http(s) proxy inside of container (if set on host)
[ -z ${http_proxy} ] || echo "export http_proxy=$http_proxy" | lxc shell ${CONTAINER} -- tee -a /etc/environment
[ -z ${https_proxy} ] || echo "export https_proxy=$https_proxy" | lxc shell ${CONTAINER} -- tee -a /etc/environment
# Update APT repository
lxc exec ${CONTAINER} -- bash -c ". /etc/environment && apt update"
# Optional: install applications
lxc exec ${CONTAINER} -- bash -c ". /etc/environment && apt install -y haproxy"

Migrate LXC container to LXD (with ZFS storage)


lxc-stop -n ${CONTAINER_NAME}
lxc init ubuntu:18.04 ${CONTAINER_NAME} -c security.privileged=true -c boot.autostart=true
#lxc stop ${CONTAINER_NAME}
#lxc config set ${CONTAINER_NAME} boot.autostart true
zfs mount tank/lxd/containers/${CONTAINER_NAME}
mv /var/lib/lxd/containers/${CONTAINER_NAME}/rootfs{,.org}
rsync -av --numeric-ids /var/lib/lxc/${CONTAINER_NAME}/rootfs /var/lib/lxd/containers/${CONTAINER_NAME}/
mv /var/lib/lxd/containers/${CONTAINER_NAME}/rootfs/dev{,.org}

LXD: Create container with profile (connect to VLAN)

create profile
lxc profile copy default mgmt-dev
# lxc profile list
lxc profile device set mgmt-dev eth0 nictype macvlan
lxc profile device set mgmt-dev eth0 parent mgmt-dev-v4432
lxc profile show mgmt-dev

create container with profile
lxc launch ubuntu:18.04 bionic-mgmt-dev -p mgmt-dev
lxc ls

Enable container nesting
lxc config set bionic-mgmt-dev security.nesting true

Configure IP
cat < /var/lib/lxd/containers/bionic-mgmt-dev/rootfs/etc/netplan/50-cloud-init.yaml
version: 2