Skip to content

Instantly share code, notes, and snippets.

@gustavohenrique
Last active April 25, 2024 21:06
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save gustavohenrique/4a7e99696bc85030d88803dc58e86c00 to your computer and use it in GitHub Desktop.
Save gustavohenrique/4a7e99696bc85030d88803dc58e86c00 to your computer and use it in GitHub Desktop.
Basic commands to run LXD containers

install

sudo snap install lxd && lxd init

Init

lxd init --preseed <<EOF
config:
  core.https_address: '[::]:8443'
  images.auto_update_interval: "0"
networks:
- config:
    ipv4.address: 10.10.10.1/24
    ipv4.nat: "true"
    ipv6.address: none
  description: ""
  name: lxdbr0
  type: ""
  project: default
storage_pools:
- config:
    size: 200GiB
  description: ""
  name: default
  driver: zfs
profiles:
- config: {}
  description: ""
  devices:
    eth0:
      name: eth0
      network: lxdbr0
      type: nic
    root:
      path: /
      pool: default
      type: disk
  name: default
projects: []
cluster: null
EOF

images

Default repositories:

  • ubuntu: (for stable Ubuntu images)
  • ubuntu-daily: (for daily Ubuntu images)
  • images: (for a bunch of other distros)

Links:

lxc image ls images:
lxc image ls ubuntu-daily:  # : is required

container

# create local
lxc launch ubuntu-daily:20.04 mycontainer
lxc launch images:archlinux/desktop-gnome desktop --vm -c security.secureboot=false -c limits.cpu=4 -c limits.memory=4GiB --console=vga
lxc launch images:centos/8/amd64 nginx
lxc exec nginx bash

# create remote
lxc launch ubuntu-daily:20.04 flathost:mycontainer

# create without start
# lxc init ubuntu-daily:18.04 mycontainer -c security.idmap.isolated=true

lxc config device add nginx porta80 proxy listen=tcp:0.0.0.0:5555 connect=tcp:127.0.0.1:80

lxc stop nginx
lxc publish nginx --compression none --alias nginx

lxc image export nginx /tmp/images
lxc image import /tmp/images/<filename>.tar local: --alias nginx

file transfer

lxc file pull web/usr/share/nginx/html/index.html .
lxc file push ./index.html web/usr/share/nginx/html/

profile

cat > t2.profile <<EOF
name: t2
config:
  environment.TALK_NAME: LXD
devices:
  public:
    path: /public
    type: disk
    source: /home/gustavo/Public
    readonly: true
EOF
lxc profile create t2
cat t2.profile | lxc profile edit t2
lxc profile add web t2  # lxc profile remove web t2

Downloads

cat > downloads.profile <<EOF
name: downloads
config:
  security.idmap.isolated: true
  raw.idmap: |
    uid 1000 1000
    gid 1000 1000
description: ""
devices:
  downloads:
    path: /Downloads
    type: disk
    source: /home/gustavo/Downloads
    readonly: false
EOF

lxc profile create downloads
cat downloads.profile | lxc profile edit downloads

X11 Profile

HOST_DISPLAY=`echo $DISPLAY | cut -d ':' -f2`  # 0 or 1
cat > x11.profile <<EOF
config:
  environment.DISPLAY: :0
  environment.PULSE_SERVER: unix:/home/ubuntu/pulse-native
  user.user-data: |
    #cloud-config
    runcmd:
      - 'sed -i "s/; enable-shm = yes/enable-shm = no/g" /etc/pulse/client.conf'
      - 'echo "DISPLAY=:0" >> /etc/environment'
    packages:
      - mesa-utils
      - pulseaudio
description: GUI LXD profile
devices:
  PASocket1:
    bind: container
    connect: unix:/run/user/1000/pulse/native
    listen: unix:/home/ubuntu/pulse-native
    security.gid: "1000"
    security.uid: "1000"
    uid: "1000"
    gid: "1000"
    mode: "0777"
    type: proxy
  X0:
    bind: container
    connect: unix:@/tmp/.X11-unix/X$HOST_DISPLAY
    listen: unix:@/tmp/.X11-unix/X0
    security.gid: "1000"
    security.uid: "1000"
    type: proxy
  mygpu:
    type: gpu
name: x11
EOF

lxc profile create x11
cat x11.profile | lxc profile edit x11
xhost +local:

api

curl --unix-socket /var/lib/lxd/unix.socket a/1.0/instances/web | python -m json.tool
curl --unix-socket /var/lib/lxd/unix.socket -X PUT -d '{"action": "stop"}' a/1.0/containers/web/state

remote access

# run it on host to allow remote connections
lxc config set core.https_address "[::]"
lxc config set core.trust_password blablabla

# run it on client
remote=flathost.xyz  # or IP 10.0.0.1
lxc remote add flathost ${remote} --protocol=lxd

# login
lxc exec flathost:mycontainer -- su ubuntu

unprivileged containers

cat > /etc/sub{uid,gid} <<EOF
root:1:1000000000   
lxd:1:1000000000
EOF
systemctl restart lxd  # or snap restart lxd (ubuntu)

mycontainer=xpto
printf "uid $(id -u) 1000\ngid $(id -g) 1000" | lxc config set $mycontainer raw.idmap -
echo -ne "security.idmap.isolated: true" | lxc config set $mycontainer -
lxc restart $mycontainer

disable auto update

lxc image edit <fingerprint>  # and setting auto_update: true as a top-level item in the config
lxc config unset images.auto_update_interval

container doesn't connect to internet

I had this problem using Linux Mint, because Docker install iptables and it cause some confusion in LXD. So, I solved it running:

# outside container
sudo su
for ipt in iptables iptables-legacy ip6tables ip6tables-legacy; do $ipt --flush; $ipt --flush -t nat; $ipt --delete-chain; $ipt --delete-chain -t nat; $ipt -P FORWARD ACCEPT; $ipt -P INPUT ACCEPT; $ipt -P OUTPUT ACCEPT; done
systemctl reload snap.lxd.daemon
# https://discuss.linuxcontainers.org/t/containers-do-not-have-outgoing-internet-access/10844/4

Windows WSL2

Compile kernel using the config-wsl provided by Microsoft.

  1. Download the config file
  2. Run make menuconfig and select the vhost driver
  3. Compile kernel and copy bzImage output file to some windows dir
  4. Create the .wslconfig file
  5. Restart WSL2
wget https://mirrors.edge.kernel.org/pub/linux/kernel/v5.x/linux-5.15.146.tar.gz
wget https://raw.githubusercontent.com/microsoft/WSL2-Linux-Kernel/linux-msft-wsl-5.15.y/arch/x86/configs/config-wsl
make KCONFIG_CONFIG=arch/x86/configs/config-wsl-custom menuconfig
  Device Drivers -> [*] VHOST drivers -> <M> vhost virtio-vsock driver
  Networking support -> Networking options -> Open vSwitch
make KCONFIG_CONFIG=arch/x86/configs/config-wsl-custom -j$(nproc)
sudo make KCONFIG_CONFIG=arch/x86/configs/config-wsl-custom modules_install headers_install
echo vhost_vsock | sudo tee -a /etc/modules
mkdir /mnt/c/Users/Gustavo\ Henrique/.wsl-kernels
cp arch/x86/boot/bzImage /mnt/c/Users/Gustavo\ Henrique/.wsl-kernels/
cat << EOF > /mnt/c/Users/Gustavo\ Henrique/.wslconfig
[wsl2]
kernel=C:\\\\Users\\\\Gustavo Henrique\\\\.wsl-kernels\\\\bzImage
EOF

# Run windows cmd
wsl --shutdown
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment