split LXD post in two, explainer and crash course
This commit is contained in:
parent
169418efbd
commit
f25cb39b50
|
@ -0,0 +1,161 @@
|
||||||
|
---
|
||||||
|
title: "Crash Course to LXD"
|
||||||
|
subtitle: "Quick instructions for installing LXD and setting up your first application."
|
||||||
|
date: 2023-09-18T22:30:07-04:00
|
||||||
|
categories:
|
||||||
|
- Technology
|
||||||
|
tags:
|
||||||
|
- Sysadmin
|
||||||
|
- Containers
|
||||||
|
- VMs
|
||||||
|
- Docker
|
||||||
|
- LXD
|
||||||
|
draft: true
|
||||||
|
toc: true
|
||||||
|
rss_only: false
|
||||||
|
cover: ./cover.png
|
||||||
|
---
|
||||||
|
|
||||||
|
If you're wondering _why_ I like system containers, see the previous post, _[LXD: Containers for
|
||||||
|
Human Beings.][lxd]_
|
||||||
|
|
||||||
|
[lxd]: {{< ref "lxd-containers-for-human-beings" >}}
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
{{< adm type="note" >}}
|
||||||
|
|
||||||
|
**Note:** the instructions below say to install LXD using [Snap.][snap] I
|
||||||
|
personally dislike Snap, but LXD is a Canonical product and they're doing their
|
||||||
|
best to promote it as much as possible. [Incus] is a fork of LXD by the primary
|
||||||
|
creators and maintainers and one of the first things they did was [rip out Snap
|
||||||
|
support,][rsnap] so it will eventually be installable as a proper native
|
||||||
|
package.
|
||||||
|
|
||||||
|
[snap]: https://en.wikipedia.org/wiki/Snap_(software)
|
||||||
|
[Incus]: https://github.com/lxc/incus
|
||||||
|
[rsnap]: https://github.com/lxc/incus/compare/9579f65cd0f215ecd847e8c1cea2ebe96c56be4a...3f64077a80e028bb92b491d42037124e9734d4c7
|
||||||
|
|
||||||
|
{{< /adm >}}
|
||||||
|
|
||||||
|
1. Install snap following [Canonical's tutorial](https://earl.run/ZvUK)
|
||||||
|
- LXD is natively packaged for Arch and Alpine, but configuration can be a
|
||||||
|
massive headache.
|
||||||
|
2. `sudo snap install lxd`
|
||||||
|
3. `lxd init`
|
||||||
|
- Defaults are fine for the most part; you may want to increase the size of
|
||||||
|
the storage pool.
|
||||||
|
4. `lxc launch images:debian/12 container-name`
|
||||||
|
5. `lxc shell container-name`
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
As an example of how to use LXD in a real situation, we'll set up [my URL
|
||||||
|
shortener.][earl] You'll need a VPS with LXD installed and a (sub)domain pointed
|
||||||
|
to the VPS.
|
||||||
|
|
||||||
|
Run `lxc launch images:debian/12 earl` followed by `lxc shell earl` and `apt
|
||||||
|
install curl`. Also `apt install` a text editor, like `vim` or `nano` depending
|
||||||
|
on what you're comfortable with. Head to the **Installation** section of [earl's
|
||||||
|
SourceHut page][earl] and expand the **List of latest binaries**. Copy the link
|
||||||
|
to the binary appropriate for your platform, head back to your terminal, type
|
||||||
|
`curl -LO`, and paste the link you copied. This will download the binary to your
|
||||||
|
system. Run `mv <filename> earl` to rename it, `chmod +x earl` to make it
|
||||||
|
executable, then `./earl` to execute it. It will create a file called
|
||||||
|
`config.yaml` that you need to edit before proceeding. Change the `accessToken`
|
||||||
|
to something else and replace the `listen` value, `127.0.0.1`, with `0.0.0.0`.
|
||||||
|
This exposes the application to the host system so we can reverse proxy it.
|
||||||
|
|
||||||
|
[earl]: https://earl.run/source
|
||||||
|
|
||||||
|
The next step is daemonising it so it runs as soon as the system boots. Edit the
|
||||||
|
file located at `/etc/systemd/system/earl.service` and paste the following code
|
||||||
|
snippet into it.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
[Unit]
|
||||||
|
Description=personal link shortener
|
||||||
|
After=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
WorkingDirectory=/root/
|
||||||
|
ExecStart=/root/earl -c config.yaml
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
|
```
|
||||||
|
|
||||||
|
Save, then run `systemctl daemon-reload` followed by `systemctl enable --now
|
||||||
|
earl`. You should be able to `curl localhost:8275` and see some HTML.
|
||||||
|
|
||||||
|
Now we need a reverse proxy on the host. Exit the container with `exit` or
|
||||||
|
`Ctrl+D`, and if you have a preferred webserver, install it. If you don't have a
|
||||||
|
preferred webserver yet, I recommend [installing Caddy.][caddy] All that's left
|
||||||
|
is running `lxc list`, making note of the `earl` container's `IPv4` address, and
|
||||||
|
reverse proxying it. If you're using Caddy, edit `/etc/caddy/Caddyfile` and
|
||||||
|
replace everything that's there with the following.
|
||||||
|
|
||||||
|
[caddy]: https://caddyserver.com/docs/install
|
||||||
|
|
||||||
|
```text
|
||||||
|
<(sub)domain> {
|
||||||
|
encode zstd gzip
|
||||||
|
reverse_proxy <container IP address>:1313
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Run `systemctl restart caddy` and head to whatever domain or subdomain you
|
||||||
|
entered. You should see the home page with just the text `earl` on it. If you go
|
||||||
|
to `/login`, you'll be able to enter whatever access token you set earlier and
|
||||||
|
log in.
|
||||||
|
|
||||||
|
## Further tips
|
||||||
|
|
||||||
|
One of the things you might want to do post-installation is mess around with
|
||||||
|
profiles. There's a `default` profile in LXD that you can show with `lxc profile
|
||||||
|
show default`.
|
||||||
|
|
||||||
|
``` text
|
||||||
|
$ lxc profile show default
|
||||||
|
config: {}
|
||||||
|
description: Default LXD profile
|
||||||
|
devices:
|
||||||
|
eth0:
|
||||||
|
name: eth0
|
||||||
|
network: lxdbr0
|
||||||
|
type: nic
|
||||||
|
root:
|
||||||
|
path: /
|
||||||
|
pool: default
|
||||||
|
type: disk
|
||||||
|
name: default
|
||||||
|
used_by: []
|
||||||
|
```
|
||||||
|
|
||||||
|
Not all config options are listed here though; you'll need to read [the
|
||||||
|
documentation] for a full enumeration.
|
||||||
|
|
||||||
|
[the documentation]: https://documentation.ubuntu.com/lxd/en/latest/config-options/
|
||||||
|
|
||||||
|
I've seen some people say that executing a fork bomb from inside a container is
|
||||||
|
equivalent to executing it on the host. The fork bomb will blow up the whole
|
||||||
|
system and render every application and container you're running inoperable.
|
||||||
|
That's partially true because LXD _by default_ doesn't put a limit on how many
|
||||||
|
processes a particular container can spawn. You can limit that number yourself
|
||||||
|
by running
|
||||||
|
|
||||||
|
```text
|
||||||
|
lxc profile set default limits.processes <num-processes>
|
||||||
|
```
|
||||||
|
|
||||||
|
Any container you create under the `default` profile will have a total process
|
||||||
|
limit of `<num-processes>`. I can't tell you what a good process limit is
|
||||||
|
though; you'll need to do some testing and experimentation on your own.
|
||||||
|
|
||||||
|
As stated in [the containers section][pp] of the previous post, this doesn't
|
||||||
|
_save_ you from fork bombs. It just helps prevent a fork bomb from affecting the
|
||||||
|
host OS or other containers.
|
||||||
|
|
||||||
|
[pp]: {{< ref "lxd-containers-for-human-beings#containers" >}}
|
|
@ -275,145 +275,6 @@ ZFS for your LXD storage pool, maybe go with [syncoid and sanoid.][ss]
|
||||||
My point is that using system containers doesn't mean throwing out the last few
|
My point is that using system containers doesn't mean throwing out the last few
|
||||||
decades of systems knowledge and wisdom.
|
decades of systems knowledge and wisdom.
|
||||||
|
|
||||||
## Crash course to LXD
|
|
||||||
|
|
||||||
Quick instructions for installing LXD and setting up your first application.
|
|
||||||
|
|
||||||
### Installation
|
|
||||||
|
|
||||||
{{< adm type="note" >}}
|
|
||||||
|
|
||||||
**Note:** the instructions below say to install LXD using [Snap.][snap] I
|
|
||||||
personally dislike Snap, but LXD is a Canonical product and they're doing their
|
|
||||||
best to promote it as much as possible. One of the first things the Incus
|
|
||||||
project did was [rip out Snap support,][rsnap] so it will eventually be
|
|
||||||
installable as a proper native package.
|
|
||||||
|
|
||||||
[snap]: https://en.wikipedia.org/wiki/Snap_(software)
|
|
||||||
[rsnap]: https://github.com/lxc/incus/compare/9579f65cd0f215ecd847e8c1cea2ebe96c56be4a...3f64077a80e028bb92b491d42037124e9734d4c7
|
|
||||||
|
|
||||||
{{< /adm >}}
|
|
||||||
|
|
||||||
1. Install snap following [Canonical's tutorial](https://earl.run/ZvUK)
|
|
||||||
- LXD is natively packaged for Arch and Alpine, but configuration can be a
|
|
||||||
massive headache.
|
|
||||||
2. `sudo snap install lxd`
|
|
||||||
3. `lxd init`
|
|
||||||
- Defaults are fine for the most part; you may want to increase the size of
|
|
||||||
the storage pool.
|
|
||||||
4. `lxc launch images:debian/12 container-name`
|
|
||||||
5. `lxc shell container-name`
|
|
||||||
|
|
||||||
### Usage
|
|
||||||
|
|
||||||
As an example of how to use LXD in a real situation, we'll set up [my URL
|
|
||||||
shortener.][earl] You'll need a VPS with LXD installed and a (sub)domain pointed
|
|
||||||
to the VPS.
|
|
||||||
|
|
||||||
Run `lxc launch images:debian/12 earl` followed by `lxc shell earl` and `apt
|
|
||||||
install curl`. Also `apt install` a text editor, like `vim` or `nano` depending
|
|
||||||
on what you're comfortable with. Head to the **Installation** section of [earl's
|
|
||||||
SourceHut page][earl] and expand the **List of latest binaries**. Copy the link
|
|
||||||
to the binary appropriate for your platform, head back to your terminal, type
|
|
||||||
`curl -LO`, and paste the link you copied. This will download the binary to your
|
|
||||||
system. Run `mv <filename> earl` to rename it, `chmod +x earl` to make it
|
|
||||||
executable, then `./earl` to execute it. It will create a file called
|
|
||||||
`config.yaml` that you need to edit before proceeding. Change the `accessToken`
|
|
||||||
to something else and replace the `listen` value, `127.0.0.1`, with `0.0.0.0`.
|
|
||||||
This exposes the application to the host system so we can reverse proxy it.
|
|
||||||
|
|
||||||
[earl]: https://earl.run/source
|
|
||||||
|
|
||||||
The next step is daemonising it so it runs as soon as the system boots. Edit the
|
|
||||||
file located at `/etc/systemd/system/earl.service` and paste the following code
|
|
||||||
snippet into it.
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[Unit]
|
|
||||||
Description=personal link shortener
|
|
||||||
After=network.target
|
|
||||||
|
|
||||||
[Service]
|
|
||||||
User=root
|
|
||||||
Group=root
|
|
||||||
WorkingDirectory=/root/
|
|
||||||
ExecStart=/root/earl -c config.yaml
|
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy=multi-user.target
|
|
||||||
```
|
|
||||||
|
|
||||||
Save, then run `systemctl daemon-reload` followed by `systemctl enable --now
|
|
||||||
earl`. You should be able to `curl localhost:8275` and see some HTML.
|
|
||||||
|
|
||||||
Now we need a reverse proxy on the host. Exit the container with `exit` or
|
|
||||||
`Ctrl+D`, and if you have a preferred webserver, install it. If you don't have a
|
|
||||||
preferred webserver yet, I recommend [installing Caddy.][caddy] All that's left
|
|
||||||
is running `lxc list`, making note of the `earl` container's `IPv4` address, and
|
|
||||||
reverse proxying it. If you're using Caddy, edit `/etc/caddy/Caddyfile` and
|
|
||||||
replace everything that's there with the following.
|
|
||||||
|
|
||||||
[caddy]: https://caddyserver.com/docs/install
|
|
||||||
|
|
||||||
```text
|
|
||||||
<(sub)domain> {
|
|
||||||
encode zstd gzip
|
|
||||||
reverse_proxy <container IP address>:1313
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
Run `systemctl restart caddy` and head to whatever domain or subdomain you
|
|
||||||
entered. You should see the home page with just the text `earl` on it. If you go
|
|
||||||
to `/login`, you'll be able to enter whatever access token you set earlier and
|
|
||||||
log in.
|
|
||||||
|
|
||||||
### Further tips
|
|
||||||
|
|
||||||
One of the things you might want to do post-installation is mess around with
|
|
||||||
profiles. There's a `default` profile in LXD that you can show with `lxc profile
|
|
||||||
show default`.
|
|
||||||
|
|
||||||
``` text
|
|
||||||
$ lxc profile show default
|
|
||||||
config: {}
|
|
||||||
description: Default LXD profile
|
|
||||||
devices:
|
|
||||||
eth0:
|
|
||||||
name: eth0
|
|
||||||
network: lxdbr0
|
|
||||||
type: nic
|
|
||||||
root:
|
|
||||||
path: /
|
|
||||||
pool: default
|
|
||||||
type: disk
|
|
||||||
name: default
|
|
||||||
used_by: []
|
|
||||||
```
|
|
||||||
|
|
||||||
Not all config options are listed here though; you'll need to read [the
|
|
||||||
documentation] for a full enumeration.
|
|
||||||
|
|
||||||
[the documentation]: https://documentation.ubuntu.com/lxd/en/latest/config-options/
|
|
||||||
|
|
||||||
I've seen some people say that executing a fork bomb from inside a container is
|
|
||||||
equivalent to executing it on the host. The fork bomb will blow up the whole
|
|
||||||
system and render every application and container you're running inoperable.
|
|
||||||
That's partially true because LXD _by default_ doesn't put a limit on how many
|
|
||||||
processes a particular container can spawn. You can limit that number yourself
|
|
||||||
by running
|
|
||||||
|
|
||||||
```text
|
|
||||||
lxc profile set default limits.processes <num-processes>
|
|
||||||
```
|
|
||||||
|
|
||||||
Any container you create under the `default` profile will have a total process
|
|
||||||
limit of `<num-processes>`. I can't tell you what a good process limit is
|
|
||||||
though; you'll need to do some testing and experimentation on your own.
|
|
||||||
|
|
||||||
As stated in [the containers section,](#containers) this doesn't _save_ you from
|
|
||||||
fork bombs. It just helps prevent a fork bomb from affecting the host OS or
|
|
||||||
other containers.
|
|
||||||
|
|
||||||
[^1]:
|
[^1]:
|
||||||
There's a [technical
|
There's a [technical
|
||||||
publication](https://dl.acm.org/doi/10.1145/3132747.3132763) indicating that
|
publication](https://dl.acm.org/doi/10.1145/3132747.3132763) indicating that
|
||||||
|
|
Loading…
Reference in New Issue