# How to set up nodes via LXC #### [Mint 21.2 Victoria](#mint-212-victoria-1) #### [Debian Bookworm - LXD](#debian-bookworm---lxd-1) #### [Debian Bookworm - LXC](#debian-bookworm---lxc-1) For further information, [LXD - Debian Wiki](https://wiki.debian.org/LXD). ---- ## Mint 21.2 Victoria Install LXC ```sh sudo apt install lxc lxc-templates libvirt-clients ``` Update the old GPG keys for debian releases ```sh cd /tmp wget "https://ftp-master.debian.org/keys/release-^C.asc" sudo gpg --no-default-keyring --keyring=/var/cache/lxc/debian/archive-key.gpg --import release-12.asc ``` Set up a ZFS filesystem for containers. These are throwaway so I don't bother with sync or atime. ```sh sudo zfs create -o atime=off -o sync=disabled -o mountpoint=/var/lib/lxc rpool/lxc ``` If you've got Docker installed, it creates a whole bunch of firewall gunk that totally breaks the LXC bridge. Make a script to let LXC talk: ```sh sudo bash -c "cat >/usr/local/bin/post-docker.sh < /var/log/post-docker-timestamp iptables -I DOCKER-USER -i lxcbr0 -j ACCEPT iptables -I DOCKER-USER -o lxcbr0 -j ACCEPT EOF" sudo chmod +x /usr/local/bin/post-docker.sh ``` And call it after Docker loads: ```sh sudo bash -c "cat >/etc/systemd/system/post-docker.service </etc/NetworkManager/dnsmasq.d/lxc.conf </etc/systemd/system/lxc-dns-lxcbr0.service <> ~/.ssh/known_hosts ``` ---- ## Debian Bookworm - LXD #### Install host packages: ```bash sudo apt install lxd lxd-tools dnsmasq-base btrfs-progs ``` #### Initialize LXD: ```bash # defaults are good sudo lxd init # add yourself to the LXD group sudo usermod -aG lxd # will need to logout/login for new group to be active # try creating a sample container if you want lxc launch images:debian/12 scratch lxc list lxc shell scratch lxc stop scratch lxc delete scratch ``` #### Create and start Jepsen's node containers: ```bash for i in {1..10}; do lxc launch images:debian/12 n${i}; done ``` #### Configure LXD bridge network: `lxd` automatically creates the bridge network, and `lxc launch` automatically configures the containers for it: ```bash lxc network list +--------+----------+---------+----------------+---+-------------+---------+---------+ | NAME | TYPE | MANAGED | IPV4 |...| DESCRIPTION | USED BY | STATE | +--------+----------+---------+----------------+---+-------------+---------+---------+ | lxdbr0 | bridge | YES | 10.82.244.1/24 |...| | 11 | CREATED | +--------+----------+---------+----------------+---+-------------+---------+---------+ ``` Assuming you are using `systemd-resolved`: ```bash # confirm your settings lxc network get lxdbr0 ipv4.address lxc network get lxdbr0 ipv6.address lxc network get lxdbr0 dns.domain # will be blank if default lxd is used # create a systemd unit file sudo nano /etc/systemd/system/lxd-dns-lxdbr0.service # with the contents: [Unit] Description=LXD per-link DNS configuration for lxdbr0 BindsTo=sys-subsystem-net-devices-lxdbr0.device After=sys-subsystem-net-devices-lxdbr0.device [Service] Type=oneshot ExecStart=/usr/bin/resolvectl dns lxdbr0 10.82.244.1 ExecStart=/usr/bin/resolvectl domain lxdbr0 ~lxd ExecStopPost=/usr/bin/resolvectl revert lxdbr0 RemainAfterExit=yes [Install] WantedBy=sys-subsystem-net-devices-lxdbr0.device # bring up and confirm status sudo systemctl daemon-reload sudo systemctl enable --now lxd-dns-lxdbr0 sudo systemctl status lxd-dns-lxdbr0.service sudo resolvectl status lxdbr0 ping n1 PING n1 (10.82.244.166) 56(84) bytes of data. 64 bytes from n1.lxd (10.82.244.166): icmp_seq=1 ttl=64 time=0.598 ms ``` #### Add required packages to node containers: ```bash for i in {1..10}; do lxc exec n${i} -- sh -c "apt-get -qy update && apt-get -qy install openssh-server sudo"; done ``` #### Configure SSH: Slip your preferred SSH key into each node's `.ssh/.authorized-keys`: ```bash for i in {1..10}; do lxc exec n${i} -- sh -c "mkdir -p /root/.ssh && chmod 700 /root/.ssh/"; lxc file push ~/.ssh/id_rsa.pub n${i}/root/.ssh/authorized_keys --uid 0 --gid 0 --mode 644; done ``` Reset the root password to root, and allow root logins with passwords on each container. If you've got an SSH agent set up, Jepsen can use that instead. ```bash for i in {1..10}; do lxc exec n${i} -- bash -c 'echo -e "root\nroot\n" | passwd root'; lxc exec n${i} -- sed -i 's,^#\?PermitRootLogin .*,PermitRootLogin yes,g' /etc/ssh/sshd_config; lxc exec n${i} -- systemctl restart sshd; done ``` Store the node keys unencrypted so that jsch can use them. If you already have the node keys, they may be unreadable to Jepsen -- remove them from `~/.ssh/known_hosts` and rescan: ```bash for n in {1..10}; do ssh-keyscan -t rsa n${n} >> ~/.ssh/known_hosts; done ``` #### Confirm that your host can ssh in: ```bash ssh root@n1 ``` #### Stopping and deleting containers: ```bash for i in {1..10}; do lxc stop n${i}; lxc delete n${i}; done ``` ---- #### Real VMs w/Real Clocks ```bash sudo apt install qemu-system lxc launch images:debian/12 n1 --vm ``` Allows the clock nemesis to bump, skew, and scramble time in the Jepsen node as it's a real vm with a real clock. ---- #### Misc The `lxc` command's \ completion works well, even autocompletes container names. #### LXD/LXC and Docker There are issues with running LXD and Docker simultaneously, Docker grabs port forwarding. Running Docker in an LXC container resolves the issue: [Prevent connectivity issues with LXD and Docker](https://documentation.ubuntu.com/lxd/en/latest/howto/network_bridge_firewalld/#prevent-connectivity-issues-with-lxd-and-docker). ---- ## Debian Bookworm - LXC ```sh # Deps sudo apt install -y lxc lxc-templates distro-info debootstrap bridge-utils libvirt-clients libvirt-daemon-system iptables ebtables dnsmasq-base libxml2-utils iproute2 bzip2 libnss-myhostname && # Create VMs for i in {1..10}; do sudo lxc-create -n c$i -t debian -- --release bookworm; done && # Add network cards for i in {1..10}; do sudo bash -c "cat >>/var/lib/lxc/c${i}/config </etc/systemd/network/1-lxc-dns.network <> ~/.ssh/known_hosts && ## And SSH client config { cat >>~/.ssh/config <> ~/lxc-nodes done && ```