diff --git a/doc/.sphinx/.markdownlint/exceptions.txt b/doc/.sphinx/.markdownlint/exceptions.txt index a717484f5bc2..f3fd45f47741 100644 --- a/doc/.sphinx/.markdownlint/exceptions.txt +++ b/doc/.sphinx/.markdownlint/exceptions.txt @@ -1,3 +1,4 @@ +.tmp/doc/howto/access_ui.md:31: MD029 Ordered list item prefix .tmp/doc/howto/import_machines_to_instances.md:114: MD034 Bare URL used .tmp/doc/howto/import_machines_to_instances.md:218: MD034 Bare URL used .tmp/doc/howto/network_forwards.md:66: MD004 Unordered list style diff --git a/doc/custom_conf.py b/doc/custom_conf.py index c5f728b0e408..1d9e7f155a8e 100644 --- a/doc/custom_conf.py +++ b/doc/custom_conf.py @@ -387,7 +387,6 @@ custom_excludes.extend(['security.md','external_resources.md','reference/network_external.md','migration.md']) redirects['security/index'] = '../explanation/security/' redirects['migration/index'] = '../howto/import_machines_to_instances/' - redirects['tutorial/index'] = 'first_steps/' custom_tags.append('diataxis') toc_filter_exclude = ['topical'] diff --git a/doc/howto/access_ui.md b/doc/howto/access_ui.md index e836e1cabddb..c0660fe8d4f4 100644 --- a/doc/howto/access_ui.md +++ b/doc/howto/access_ui.md @@ -25,7 +25,9 @@ Complete the following steps to access the LXD web UI: 1. Make sure that your LXD server is {ref}`exposed to the network `. You can expose the server during {ref}`initialization `, or afterwards by setting the {config:option}`server-core:core.https_address` server configuration option. -1. Access the UI in your browser by entering the server address (for example, `https://192.0.2.10:8443`). + + +2. Access the UI in your browser by entering the server address (for example, `https://127.0.0.1:8443` for a local server, or `https://192.0.2.10:8443`). If you have not set up a secure {ref}`authentication-server-certificate`, LXD uses a self-signed certificate, which will cause a security warning in your browser. Use your browser's mechanism to continue despite the security warning. @@ -36,14 +38,26 @@ Complete the following steps to access the LXD web UI: ``` 1. Set up the certificates that are required for the UI client to authenticate with the LXD server by following the steps presented in the UI. - These steps include creating a set of certificates, adding the private key to your browser, and adding the public key to the server's trust store. + + You have two options, depending on whether you already have a client certificate selected in your browser: + + - If you don't have a certificate yet, click {guilabel}`Create a new certificate` to get instructions for creating a set of certificates, adding the public key to the server's trust store, and adding the private key to your browser. + + ```{figure} /images/ui_set_up_certificates.png + :width: 100% + :alt: Instructions for setting up certificates for the UI + ``` + + - If you already have a client certificate in your browser, select "use an existing certificate" to authorize the certificate with the server and re-use it. + + ```{figure} /images/ui_set_up_existing_cert.png + :width: 100% + :alt: Instructions for re-using an existing certificate for the UI + ``` See {ref}`authentication` for more information. - ```{figure} /images/ui_set_up_certificates.png - :width: 80% - :alt: Instructions for setting up certificates for the UI - ``` + After setting up the certificates, you can start creating instances, editing profiles, or configuring your server. diff --git a/doc/images/tutorial/add_disk_device.png b/doc/images/tutorial/add_disk_device.png new file mode 100644 index 000000000000..6b06f020c1f4 Binary files /dev/null and b/doc/images/tutorial/add_disk_device.png differ diff --git a/doc/images/tutorial/broken_terminal.png b/doc/images/tutorial/broken_terminal.png new file mode 100644 index 000000000000..29d8e333b4a9 Binary files /dev/null and b/doc/images/tutorial/broken_terminal.png differ diff --git a/doc/images/tutorial/create_desktop_vm.png b/doc/images/tutorial/create_desktop_vm.png new file mode 100644 index 000000000000..9aaed3adf8dc Binary files /dev/null and b/doc/images/tutorial/create_desktop_vm.png differ diff --git a/doc/images/tutorial/create_instance.png b/doc/images/tutorial/create_instance.png new file mode 100644 index 000000000000..5740c1af051a Binary files /dev/null and b/doc/images/tutorial/create_instance.png differ diff --git a/doc/images/tutorial/create_project.png b/doc/images/tutorial/create_project.png new file mode 100644 index 000000000000..797994dc2319 Binary files /dev/null and b/doc/images/tutorial/create_project.png differ diff --git a/doc/images/tutorial/create_vm.png b/doc/images/tutorial/create_vm.png new file mode 100644 index 000000000000..2a1be43d1e39 Binary files /dev/null and b/doc/images/tutorial/create_vm.png differ diff --git a/doc/images/tutorial/desktop_console.png b/doc/images/tutorial/desktop_console.png new file mode 100644 index 000000000000..fd690d2b776b Binary files /dev/null and b/doc/images/tutorial/desktop_console.png differ diff --git a/doc/images/tutorial/hello_world_desktop.png b/doc/images/tutorial/hello_world_desktop.png new file mode 100644 index 000000000000..3cdcf7ae6be8 Binary files /dev/null and b/doc/images/tutorial/hello_world_desktop.png differ diff --git a/doc/images/tutorial/instance_summary.png b/doc/images/tutorial/instance_summary.png new file mode 100644 index 000000000000..86c203e1c2d0 Binary files /dev/null and b/doc/images/tutorial/instance_summary.png differ diff --git a/doc/images/tutorial/instances.png b/doc/images/tutorial/instances.png new file mode 100644 index 000000000000..6749134cc2ec Binary files /dev/null and b/doc/images/tutorial/instances.png differ diff --git a/doc/images/tutorial/resource_limits.png b/doc/images/tutorial/resource_limits.png new file mode 100644 index 000000000000..98cde02d0af9 Binary files /dev/null and b/doc/images/tutorial/resource_limits.png differ diff --git a/doc/images/tutorial/root_disk_size.png b/doc/images/tutorial/root_disk_size.png new file mode 100644 index 000000000000..62fef9eb7a8f Binary files /dev/null and b/doc/images/tutorial/root_disk_size.png differ diff --git a/doc/images/tutorial/yaml_configuration.png b/doc/images/tutorial/yaml_configuration.png new file mode 100644 index 000000000000..d2c29c82bd44 Binary files /dev/null and b/doc/images/tutorial/yaml_configuration.png differ diff --git a/doc/images/ui_set_up_certificates.png b/doc/images/ui_set_up_certificates.png index ab8809c61823..78b912187089 100644 Binary files a/doc/images/ui_set_up_certificates.png and b/doc/images/ui_set_up_certificates.png differ diff --git a/doc/images/ui_set_up_existing_cert.png b/doc/images/ui_set_up_existing_cert.png new file mode 100644 index 000000000000..222111cce444 Binary files /dev/null and b/doc/images/ui_set_up_existing_cert.png differ diff --git a/doc/index.md b/doc/index.md index 4655f22b0ccf..dbba9cc44799 100644 --- a/doc/index.md +++ b/doc/index.md @@ -22,9 +22,11 @@ LXD (" +restart_button: "" snapshot_expiry_format: "Controls when snapshots are to be deleted (expects an expression like `1M 2H 3d 4w 5m 6y`)" snapshot_pattern_detail: "The `snapshots.pattern` option takes a Pongo2 template string to format the snapshot name.\n\nTo add a time stamp to the snapshot name, use the Pongo2 context variable `creation_date`.\nMake sure to format the date in your template string to avoid forbidden characters in the snapshot name.\nFor example, set `snapshots.pattern` to `{{ creation_date|date:'2006-01-02_15-04-05' }}` to name the snapshots after their time of creation, down to the precision of a second.\n\nAnother way to avoid name collisions is to use the placeholder `%d` in the pattern.\nFor the first snapshot, the placeholder is replaced with `0`.\nFor subsequent snapshots, the existing snapshot names are taken into account to find the highest number at the placeholder's position.\nThis number is then incremented by one for the new name." snapshot_pattern_format: "Pongo2 template string that represents the snapshot name (used for scheduled snapshots and unnamed snapshots)" diff --git a/doc/tutorial/first_steps.md b/doc/tutorial/first_steps.md index 57d0aa14f883..6cc1d3693b4a 100644 --- a/doc/tutorial/first_steps.md +++ b/doc/tutorial/first_steps.md @@ -10,6 +10,8 @@ After going through these steps, you will have a general idea of how to use LXD, Ensure that you have 20 GiB free disk space before starting this tutorial. ``` + + ## Install and initialize LXD The easiest way to install LXD is to install the snap package. @@ -22,11 +24,11 @@ If you prefer a different installation method, or use a Linux distribution that ```{terminal} :input: snap version - snap 2.59.4 - snapd 2.59.4 + snap 2.63+24.04ubuntu0.1 + snapd 2.63+24.04ubuntu0.1 series 16 - ubuntu 22.04 - kernel 5.15.0-73-generic + ubuntu 24.04 + kernel 5.15.0-117-generic ``` If you see a table of version numbers, snap is installed and you can continue with the next step of installing LXD. @@ -65,6 +67,8 @@ If you prefer a different installation method, or use a Linux distribution that This will create a minimal setup with default options. If you want to tune the initialization options, see {ref}`initialize` for more information. + + ## Launch and inspect instances LXD is image based and can load images from different image servers. @@ -345,6 +349,10 @@ You can create a snapshot of your instance, which makes it easy to restore the i See {ref}`instances-snapshots` for more information. + + ## Next steps -Now that you've done your first experiments with LXD, check out the information in the {ref}`getting-started` section! +Now that you've done your first experiments with LXD, you should read up on important concepts in the {ref}`explanation` section and check out the {ref}`howtos` to start working with LXD! + + diff --git a/doc/tutorial/index.md b/doc/tutorial/index.md new file mode 100644 index 000000000000..66f90b7e650d --- /dev/null +++ b/doc/tutorial/index.md @@ -0,0 +1,11 @@ +(tutorials)= +# Tutorials + +The following tutorial guides you through installing and initializing LXD, creating and configuring some instances, interacting with the instances, and creating snapshots: + +```{toctree} +:titlesonly: + +first_steps +ui +``` diff --git a/doc/tutorial/ui.md b/doc/tutorial/ui.md new file mode 100644 index 000000000000..56107d7a9557 --- /dev/null +++ b/doc/tutorial/ui.md @@ -0,0 +1,418 @@ +(tutorial-ui)= +# Getting started with the UI + +This tutorial gives a quick introduction to using the LXD UI. +It covers installing and initializing LXD, getting access to the UI, and carrying out some standard operations like creating, configuring, and interacting with instances, configuring storage, and using projects. + +After going through these steps, you will have a general idea of how to use LXD through its UI, and you can start exploring more advanced use cases! + +```{note} +Ensure that you have 20 GiB free disk space before starting this tutorial. +``` + +% Include content from [first_steps.md](first_steps.md) +```{include} first_steps.md + :start-after: + :end-before: +``` + +## Access the UI + +You access the LXD UI through your browser. +See {ref}`access-ui` for more information. + +1. Expose LXD to the network by setting the {config:option}`server-core:core.https_address` server configuration option: + + lxc config set core.https_address :8443 + +% Include content from [../howto/access_ui.md](../howto/access_ui.md) +```{include} ../howto/access_ui.md + :start-after: + :end-before: +``` + +## Create and start instances + +Let's start by launching a few instances. +With *instance*, we mean either a container or a virtual machine. +See {ref}`containers-and-vms` for information about the difference between the two instance types. + +1. Select {guilabel}`Instances` from the navigation. +1. Click {guilabel}`Create instance` to launch a container called `first` using the Ubuntu 24.04 LTS image: + + ```{figure} /images/tutorial/create_instance.png + :width: 100% + :alt: Create an Ubuntu 24.04 LTS container + ``` + + To select the base image, click {guilabel}`Browse images`. + Click {guilabel}`Select` next to the Ubuntu 24.04 LTS image. + + ```{note} + The images that are displayed are hosted on pre-configured {ref}`remote-image-servers`. + You can filter which images are displayed. + + You can also upload a custom ISO file to boot from. + See {ref}`instances-create-iso` for more information. + ``` + +1. Click {guilabel}`Create and start` to launch the container. + + ```{note} + Launching this container takes a few seconds, because the image must be downloaded and unpacked first. + ``` + +1. Create another container called `second`, using the same image, but click {guilabel}`Create` instead of {guilabel}`Create and start`. + + This container will be created but not started. + + ```{note} + Creating this container is quicker than launching the first, because the image is already available locally. + ``` + +1. Launch a VM called `ubuntu-vm` using the Ubuntu 24.04 LTS image by selecting {guilabel}`VM` as the instance type: + + ```{figure} /images/tutorial/create_vm.png + :width: 100% + :alt: Create an Ubuntu 24.04 LTS VM + ``` + + ```{note} + Even though you are using the same image name to launch the instance, LXD downloads a slightly different image that is compatible with VMs. + ``` + +1. Launch a VM called `ubuntu-desktop` using the Ubuntu 24.04 LTS desktop image (filter by variant "desktop" to find it). + When you select the image, the instance type is automatically set to {guilabel}`VM`: + + ```{figure} /images/tutorial/create_desktop_vm.png + :width: 100% + :alt: Create an Ubuntu 24.04 LTS desktop VM + ``` + + To run smoothly, the desktop VM needs more RAM. + Therefore, navigate to {guilabel}`Advanced` > {guilabel}`Resource limits` and set the {guilabel}`Memory limit` to 4 GiB before you start the instance. + +1. Check the list of instances that you created: + + ```{figure} /images/tutorial/instances.png + :width: 100% + :alt: List of instances + ``` + + You will see that all but the `second` container are running. + This is because you created the `second` container but didn't start it. + + You can start the `second` container by clicking the {guilabel}`Start` button (▷) next to it. + +See {ref}`instances-create` for more information. + +## Inspect instances + +In the list of instances, click on one of the lines to see more information about the respective instance: + +```{figure} /images/tutorial/instance_summary.png +:width: 100% +:alt: Information about an instance in the instance summary +``` + +Click on an instance name to go to the instance detail page, where you can inspect your instance: + +- The {guilabel}`Overview` tab shows general information and usage statistics about the instance. +- The {guilabel}`Configuration` tab contains the instance configuration. + For now, just click through to inspect the configuration. + We'll do some updates later. + + If you want to see the full instance configuration, go to the YAML configuration: + + ```{figure} /images/tutorial/yaml_configuration.png + :width: 100% + :alt: YAML configuration of an instance + ``` + +- The {guilabel}`Snapshots` tab shows available snapshots. + You can ignore this for now; we'll look into snapshots later. +- The {guilabel}`Terminal` tab allows you to interact with your instance. + For example, enter the following command to display information about the operating system: + + cat /etc/*release + + Or have some fun: + + apt update + apt install fortune + /usr/games/fortune + + See {ref}`run-commands-shell` for more information. + + ```{note} + When you navigate away from the {guilabel}`Terminal` tab, you are asked to confirm. + The reason for this confirmation prompt is that the terminal session is not saved, so once you navigate away, your command history is lost. + ``` + +- The {guilabel}`Console` tab is mainly relevant during startup of an instance, and for VMs. + + Go to the instance detail page of the `ubuntu-desktop` VM and check the graphic console: + + ```{figure} /images/tutorial/desktop_console.png + :width: 100% + :alt: Graphic console of the Ubuntu desktop VM + ``` + + See {ref}`instances-console` for more information. +- The {guilabel}`Logs` tab contains log files for inspection and download. + Running instances have only limited information. + More log files are added if an instance ends up in error state. + + See {ref}`instances-troubleshoot` for more information. + +## Stop and delete instances + +For the remainder of the tutorial, we don't need all of the instances we created. +So let's clean some of them up: + +1. Go back to the instances list. +1. Stop the `second` container by clicking the {guilabel}`Stop` button (□) next to it. +1. Delete the `second` container. + To do so, click the instance name to go to the instance detail page. + Then click the {guilabel}`Delete instance` button at the top. +1. Go to the instance detail page of the `ubuntu-vm` VM to delete it. + + You will see that the {guilabel}`Delete instance` button at the top is not active. + This is because the instance is still running. + + Stop it by clicking the {guilabel}`Stop` button (□) at the top, then click {guilabel}`Delete instance`. + +```{tip} +If stopping an instance takes a long time, click the spinning {guilabel}`Stop` button to go back to the confirmation prompt, where you can select to force-stop the instance. +``` + +See {ref}`instances-manage` for more information. + +## Configure instances + +There are several limits and configuration options that you can set for your instances. +See {ref}`instance-options` for an overview. + +Let's create another container with some resource limits: + +1. Click {guilabel}`Create instance`, enter `limited` as the instance name and select the Ubuntu 24.04 LTS image. + +1. Expand {guilabel}`Advanced` and go to {guilabel}`Resource limits`. + +1. Change the {guilabel}`Exposed CPU limit` to 1 and the {guilabel}`Memory limit` to 4 GiB: + + ```{figure} /images/tutorial/resource_limits.png + :width: 100% + :alt: Configure some resource limits + ``` + +1. Click {guilabel}`Create and start`. + +1. When the instance is running, go to its instance detail page and select {guilabel}`Configuration` > {guilabel}`Advanced` > {guilabel}`Resource limits`. + Confirm that the limits you set are visible. + +1. Go to the {guilabel}`Terminal` tab and enter the following commands: + + free -m + nproc + + You should see that the total memory is limited to 4096, and the number of available CPUs is 1. + +1. Go to the instance detail page of the `first` container and enter the same commands. + + You should see that the values differ from those of the `limited` container. + The exact values depend on your host system (so if your host system has only one CPU, for example, you might see one CPU for the `first` container as well). + +1. You can also update the configuration while your container is running: + + 1. Go back to the instance detail page of the `limited` container and select {guilabel}`Configuration` > {guilabel}`Advanced` > {guilabel}`Resource limits`. + + 1. Click {guilabel}`Edit instance` and change the memory limit to 2 GiB. + Then save. + + 1. Go to the {guilabel}`Terminal` tab and enter the following command: + + free -m + + Note that the number has changed. + +Depending on the instance type and the storage drivers that you use, there are more configuration options that you can specify. +For example, you can configure the size of the root disk device for a VM: + +1. Go to the terminal for the `ubuntu-desktop` VM and check the current size of the root disk device (`/dev/sda2`): + + df -h + +1. Navigate to {guilabel}`Configuration` > {guilabel}`Advanced` > {guilabel}`Disk devices`. + + ```{tip} + By default, the size of the root disk is inherited from the default profile. + Profiles store a set of configuration options and can be applied to instances instead of specifying the configuration option for each instance separately. + + See {ref}`profiles` for more information. + ``` + +1. Override the size of the root disk device to be 30 GiB: + + ```{figure} /images/tutorial/root_disk_size.png + :width: 100% + :alt: Change the size of the root disk + ``` + +1. Save the configuration, and then restart the VM by clicking the {guilabel}`Restart` button ({{restart_button}}). + +1. In the terminal, check the size of the root disk device again: + + df -h + + Note that the size has changed. + +See {ref}`instances-configure` and {ref}`instance-config` for more information. + +## Manage snapshots + +You can create a snapshot of your instance, which makes it easy to restore the instance to a previous state. + +1. Go to the instance detail page of the `first` container and select the {guilabel}`Snapshots` tab. + +1. Click {guilabel}`Create snapshot` and enter the snapshot name `clean`. + Leave the other options unchanged and create the snapshot. + + You should now see the snapshot in the list. + +1. Go to the {guilabel}`Terminal` tab and break the container: + + rm /usr/bin/bash + +1. Confirm the breakage by reloading the page: + + ```{figure} /images/tutorial/broken_terminal.png + :width: 100% + :alt: Error when trying to load the terminal + ``` + + The UI cannot open a terminal in your container anymore, because you deleted the `bash` command. + +1. Go back to the {guilabel}`Snapshots` tab and restore the container to the state of the snapshot by clicking the {guilabel}`Restore snapshot` button ({{restore_button}}) next to it. + +1. Go back to the {guilabel}`Terminal` tab. + The terminal should now load again. + +1. Go to the {guilabel}`Snapshots` tab and delete the snapshot by clicking the {guilabel}`Delete snapshot` button ({{delete_button}}) next to it. + +See {ref}`instances-snapshots` for more information. + +## Add a custom storage volume + +You can add additional storage to your instance, and also share storage between different instances. +See {ref}`storage-volumes` for more information. + +Let's start by creating a custom storage volume: + +1. Navigate to {guilabel}`Storage` > {guilabel}`Volumes`. + + Even though you have not created any custom storage volumes yet, you should see several storage volumes in the list. + These are instance volumes (which contain the root disks of your instances) and image volumes (which contain the cached base images). + +1. Click `Create volume` and enter a name and a size. + Leave the default content type (`filesystem`). + +After creating the instance, we can attach it to some instances: + +1. Go to the instance detail page of the `first` container. + +1. Go to {guilabel}`Configuration` > {guilabel}`Advanced` > {guilabel}`Disk devices`. + +1. Click {guilabel}`Edit instance` and then {guilabel}`Attach disk device`. + +1. Select the disk device that you just created. + + ```{tip} + You can create a custom volume directly from this screen as well. + ``` + +1. Enter `/data` as the mount point and save your changes: + + ```{figure} /images/tutorial/add_disk_device.png + :width: 100% + :alt: Add the custom volume to your instance + ``` + +1. Go to the {guilabel}`Terminal` tab and enter the following command to create a file on the custom volume: + + touch /data/hello_world + +1. Go to the instance detail page of the `ubuntu-desktop` VM and add the same custom storage volume with the same mount point (`/data`). + +1. Go to the {guilabel}`Terminal` tab and enter the following command to see the file you created from your `first` container: + + ls /data/ + + ````{note} + You can also look at the directory in the file browser. + To do so, enter the following command in the terminal first: + + chown ubuntu /data /data/* + + Then switch to the console, open the file browser, and navigate to the `/data` folder: + + ```{figure} /images/tutorial/hello_world_desktop.png + :width: 100% + :alt: View the file on the shared volume in the file browser + ``` + ```` + +## Use projects + +You can use projects to group related instances, and other entities, on your LXD server. +See {ref}`exp-projects` and {ref}`projects-create` for more information. + +Originally, there is only a default project on the server. +All the instances you created so far are part of this project. + +Now, let's create another project: + +1. Expand the {guilabel}`Project` dropdown and click {guilabel}`Create project`: + + ```{figure} /images/tutorial/create_project.png + :width: 100% + :alt: Create a project + ``` + +1. Enter `tutorial` as the project name. + +1. For features, select `Customised`. + + You can then select which features should be isolated. + "Isolated" in this context means that if you select one of the features, entities of this type are confined to the project. + So when you use a project where, for example, storage volumes are isolated, you can see only the storage volumes that are defined within the project. + +1. Deselect `Storage volumes` and create the project. + +The new project is automatically selected for you. +Let's check its content: + +1. Go to {guilabel}`Instances`. + + You will see that there are no instances in your project, because instances are always isolated, and the instances you created earlier are in the default project. + +1. Create an instance in the new project. + + You should notice that you get an error about missing root storage. + The reason for this is that the root storage is usually defined in the default profile, but profiles are isolated in the project. + +1. To resolve the error, edit the root storage. + Use the `default` pool and leave the size empty. + + Then create the instance. + +1. Go to {guilabel}`Storage` > {guilabel}`Volumes`. + + Because you deselected `Storage volumes` when creating the project, storage volumes are not isolated to the project, and you can see the custom storage volume that you created in the default project. + However, you cannot see any of the instance or image volumes from the other project, because those are isolated. + +% Include content from [first_steps.md](first_steps.md) +```{include} first_steps.md + :start-after: + :end-before: +```