LXD/LXC Basic Setup

From WikiMLT

LXD Ini­tial Set­up

First add your Lin­ux user to the lxd group in or­der to op­er­ate with the con­tain­ers with­out su­do – note you nay need to cog-out and log-in.

sudo usermod -aG lxd <user>

Ini­tial­ize LXD.

lxd init
#Out­put
Would you like to use LXD clustering? (yes/no) [default=no]: no
Do you want to configure a new storage pool? (yes/no) [default=yes]: yes
Name of the new storage pool [default=default]: default
Name of the storage backend to use (dir, lvm, zfs, ceph, btrfs) [default=zfs]: dir
Would you like to connect to a MAAS server? (yes/no) [default=no]: no
Would you like to create a new local network bridge? (yes/no) [default=yes]: yes
What should the new bridge be called? [default=lxdbr0]: lxdbr0
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: auto
Would you like the LXD server to be available over the network? (yes/no) [default=no]: no
Would you like stale cached images to be updated automatically? (yes/no) [default=yes]: yes
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: yes
config: {}
networks:
- config:
    ipv4.address: auto
    ipv6.address: auto
  description: ""
  name: lxdbr0
  type: ""
  project: default
storage_pools:
- config: {}
  description: ""
  name: default
  driver: dir
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      network: lxdbr0
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: default
projects: []
cluster: null

List the avail­able im­ages by the fol­low­ing com­mands and find the name of an im­age of a de­sired dis­tri­b­u­tion – in this case Ubun­tu Serv­er 22.04.

lxc image list
lxc image list ubuntu:22.04
lxc image list ubuntu:22.04 | grep x86_64

In­stall a cer­tain im­age. We will name the con­tain­er lxc-web­serv­er. We will add a ca­pa­bil­i­ty to the con­tain­er to run oth­er con­tain­ers in­side, for more de­tails read the ar­ti­cle Nest­ed con­tain­ers in LXD.

lxc launch ubuntu:22.04 lxc-webserver -c security.nesting=true
#Out­put
Creating lxc-webserver
Starting lxc-webserver

In or­der to add (or re­move) the nest­ing op­tion to an ex­ist­ing LXC, use:

lxc config set lxc-webserver security.nesting true

List the con­tain­ers avail­able with­in the LXD in use.

lxc list --columns ns4 # name, state and IPv4
#Out­put
+---------------+---------+-----------------------+
|   NAME        |  STATE  |         IPV4          |
+---------------+---------+-----------------------+
| lxc-webserver | RUNNING | 10.127.198.222 (eth0) |
+---------------+---------+-----------------------+

Con­fig­ure the con­tain­er to ob­tain a sta­t­ic IP as­sign­ment.

lxc config device override lxc-webserver eth0
Device eth0 overridden for lxc-webserver
lxc config device set lxc-webserver eth0 ipv4.address 10.127.198.222 # no output mean everything is fine
lxc restart lxc-webserver
lxc list --columns ns4 | grep eth0 # check the ip
| lxc-webserver | RUNNING | 10.127.198.222 (eth0) |

LXD Ba­sic op­er­a­tion

Restart the ser­vice.

sudo snap restart lxd

Mount a host di­rec­to­ry to a di­rec­to­ry in­side a con­tain­er. Map the per­mis­sions.

printf "lxd:$(id -u):1\nroot:$(id -u):1\n" | sudo tee -a /etc/subuid # Allow LXD’s use of our user uid
printf "lxd:$(id -g):1\nroot:$(id -g):1\n" | sudo tee -a /etc/subgid # Allow LXD’s use of our user gid
sudo snap restart lxd                                                # Restart LXD to have it load the new map
printf "uid $(id -u) 1000\ngid $(id -g) 1000" | lxc config set lxc-webserver raw.idmap - # Set a custom map for our container
lxc restart lxc-webserver                                            # Restart the container to have the new map apply
lxc config device add lxc-webserver Git disk source=/home/<user>/Git path=/home/<user>/Git # Mount the directory

Do the ac­tu­al share (mount) of some di­rec­to­ries.

lxc config device add lxc-webserver Git disk source=/home/<user>/Git path=/home/<user>/Git
lxc config device add lxc-webserver VSC disk source=/home/<user>/.vscode-server path=/home/<user>/.vscode-server
Ref­er­ences

LXC Ba­sic op­er­a­tions

List avail­able con­tain­ers.

lxc list
lxc list -c ns4

Lo­gin to a con­tain­er (note lxc-web­serv­er is a con­tain­er name).

lxc shell lxc-webserver

Ex­e­cute a com­mand against the con­tain­er from the host.

lxc exec lxc-webserver -- apt install apache2

Start, stop or delete con­tain­er.

lxc (start|stop|delete) container-name

Cre­ate a snap­shot.

lxc snapshot lxc-webserver snapshot-name

Delete a snap­shot.

lxc delete lxc-webserver/snapshot-name

Re­store a snap­shot.

lxc restore lxc-webserver snapshot-name

Cre­ate a back­up.

lxc export lxc-webserver ./lxc-webserver-backup.tar.gz

Re­store a back­up.

lxc import ./lxc-webserver-backup.tar.gz

Get in­fo about the con­tain­er (and its snap­shots at the bot­tom).

lxc info lxc-webserver

Lim­it the container's mem­o­ry us­age.

lxc config set lxc-webserver limits.memory 1GB

Au­to-start a con­tain­er.

lxc config set lxc-webserver boot.autostart 1

Set an au­to-start de­lay for a con­tain­er.

lxc config set lxc-webserver boot.autostart.delay 30

Set an au­to-start or­der num­ber for a con­tain­er.

lxc config set lxc-database boot.autostart.order 2
lxc config set lxc-webserver boot.autostart.order 3

Dis­able IPv6 for the con­tain­ers – ref­er­ence.

lxc network set lxdbr0 ipv6.address none

Back­up LXC Con­tain­ers

Here are pro­vid­ed notes about back­ing up the con­tain­ers,

Lo­cal ex­port ap­proach

* */1 * * * /snap/bin/lxc export lxc-webserver $HOME/backups/lxc-webserver-backup.tar.gz >/tmp/crontab.${USER}.lxc-webserver-backup.tar.gz.log 2>&1

The com­mand could be a part of your back­up script. Al­so they say it is bet­ter to ex­port a snap shot… Then a re­mote in­stance can fetch it by rsync via SSH.

Ref­er­ences

Re­mote ex­port ap­proach

In this sec­tion, the LXD that is run­ning at metalvel​.tech will be called re­mote serv­er. The LXD that will fetch (ex­port) the back­ups will be called lo­cal serv­er in this case it is szs.spae. Here is used the most sim­ple set­tings and the con­nec­tion be­tween the servers will be car­ry out via SSH tun­nel.

So, at the re­mote serv­er run the fol­low­ing com­mand.

lxc config set core.https_address :8443
lxc config set core.trust_password 'p@s$********wD'

Then at the lo­cal serv­er szs​.space add the nec­es­sary en­try for a con­nec­tion with port for­ward­ing of port 8443 in the file ~/.ssh/config – see the en­try lxd​.fwd​.metalevel​.tech in the SSH sec­tion be­low. Af­ter that test the con­nec­tion bi the fol­low­ing com­mands.

ssh lxd.fwd.metalevel.tech -fTN
sudo netstat -tnupa | grep 8443

If every­thing looks fine, do the Init set­up for this in­stance (an­swer with no at all ques­tions if wont run lo­cal LXCs) and then ex­e­cute the fol­low­ing com­mand to add the re­mote serv­er.

# Default auth type: TLS + password; 'mlt' stands for 'metalevel.tech'
lxc remote add mlt 127.0.0.1:8443
ficate fingerprint: 1778ec79530...
ok (y/n/[fingerprint])? y
Admin password for metalevel.tech: ***
Client certificate now trusted by server: mlt

Then you can switch the de­fault re­mote serv­er and list the run­ning con­tain­ers as fol­low.

lxc remote list
lxc remote switch mlt
lxc list

The above pro­ce­dure must be done for all users that will ma­nip­u­late the re­mote in­stance – in this count the root ac­count!

In or­der to ex­port a back­up from the re­mote in­stance you can per­form the fol­low­ing steps.

lxc snapshot mlt:lxc-webserver backup
lxc export mlt:lxc-webserver/backup ./mlt.lxc-webserver.tar.gz

Note you need to have enough space at the re­mote in­stance, be­cause the snap­shots are cre­at­ed there, al­so back­ups be­fore to be moved to the des­ti­na­tion place are cre­at­ed there as tem­po­rary archive.

lxc export mlt:lxc-webserver ./mlt.lxc-webserver.tar.gz
Ref­er­ences

For­ward the HTTP Traf­fic from the LXD host to a LXC via IPT­a­bles

First in­stall the ipt­a­bles-per­sis­tent pack­age and mi­grate to ipt­a­bles-nft.

sudo apt install iptables-persistent # iptables-save > /etc/iptables/rules.{v4,v6}
sudo apt install ipset-persistent    # ipset save > /etc/ipset/ipsets
sudo update-alternatives --set iptables /usr/sbin/iptables-nft
sudo update-alternatives --remove iptables /usr/sbin/iptables-legacy
sudo modprobe -r iptable_filter iptable_nat iptable_mangle iptable_raw iptable_security

The sec­ond step is to add and make per­sis­tent the Ipt­a­bles rules that will redi­rect the traf­fic at ports 80 and 433 to the lxc-web­serv­er con­tain­er IP 10.127.198.222. The serv­er has the fol­low­ing IP ad­dress­es:

  • eth0: 158.113.3.106: The pub­lic ad­dress of the serv­er, we are us­ing Float­ing IP 137.112.134.165 for the do­main metalevel​.tech, so we do not ex­pect any traf­fic at the web ports on this IP.
  • eth0: 10.14.1.5: The Float­ing IP 137.112.134.165 redi­rects every­thing to this in­ter­face so we will for­ward the traf­fic at this port.
  • eth1: 10.123.1.2: This is the IP in the pri­vate vir­tu­al net­work at Dig­i­talO­cean – so prob­a­bly in the fu­ture oth­er re­sources could ac­cess the droplet vi this in­ter­face so we will for­ward the traf­fic at this port.

Here is a tem­plate com­mand:

sudo iptables -t nat -I PREROUTING -i $IFACE -p TCP -d $PUBLIC_IP --dport $PORT -j DNAT --to-destination $CONTAINER_IP:$PORT -m comment --comment "forward to lxc-webserver"
#Rules Per IP/PORT

It should be ex­e­cut­ed for each set of the fol­low­ing val­ues.

PORT=80 PUBLIC_IP=10.14.1.5 CONTAINER_IP=10.127.198.222 IFACE=eth0
PORT=443 PUBLIC_IP=10.14.1.5 CONTAINER_IP=10.127.198.222 IFACE=eth0
PORT=80 PUBLIC_IP=10.123.1.2 CONTAINER_IP=10.127.198.222 IFACE=eth0
PORT=443 PUBLIC_IP=10.123.1.2 CONTAINER_IP=10.127.198.222 IFACE=eth0
sudo iptables -t nat -L PREROUTING
# sudo iptables -t nat -F PREROUTING
sudo iptables-save | sudo tee /etc/iptables/rules.v4
# sudo iptables-restore < /etc/iptables/rules.v4

Ref­er­ences