Difference between revisions of "LXD"

From Funtoo
Jump to: navigation, search
(Network Troubleshooting)
 
(19 intermediate revisions by one other user not shown)
Line 1: Line 1:
 
<languages/>
 
<languages/>
{{Subpages|GPU Acceleration,What are subuids and subgids?}}
+
{{Subpages|GPU Acceleration,GPU Acceleration (NVIDIA),What are subuids and subgids?,Administration Tutorial,Features and Concepts}}
 
<translate>
 
<translate>
 
== Introduction == <!--T:1-->
 
== Introduction == <!--T:1-->
Line 90: Line 90:
 
Do you want to configure a new storage pool? (yes/no) [default=yes]: ##i##↵
 
Do you want to configure a new storage pool? (yes/no) [default=yes]: ##i##↵
 
Name of the new storage pool [default=default]: ##i##↵
 
Name of the new storage pool [default=default]: ##i##↵
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]: ##i##dir↵
+
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]: ##i##dir ↵
 
Would you like to connect to a MAAS server? (yes/no) [default=no]: ##i##↵
 
Would you like to connect to a MAAS server? (yes/no) [default=no]: ##i##↵
 
Would you like to create a new local network bridge? (yes/no) [default=yes]: ##i##↵
 
Would you like to create a new local network bridge? (yes/no) [default=yes]: ##i##↵
 
What should the new bridge be called? [default=lxdbr0]: ##i##↵
 
What should the new bridge be called? [default=lxdbr0]: ##i##↵
 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ##i##↵
 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ##i##↵
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ##i##↵
+
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: ##i##none
 
Would you like LXD to be available over the network? (yes/no) [default=no]: ##i##↵
 
Would you like LXD to be available over the network? (yes/no) [default=no]: ##i##↵
 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] ##i##↵
 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] ##i##↵
Line 104: Line 104:
  
 
<!--T:16-->
 
<!--T:16-->
As you can see, we chose all the default 'except' for storage pool, where we opted for using a directory-based container
+
As you can see, we chose all the default ''except'' for:
storage rather than [[Special:MyLanguage/btrfs|btrfs]]. Now, we should be able to run {{c|lxc image list}} and get a response from the LXD daemon:
+
;storage pool: We opted for using a directory-based container storage rather than [[Special:MyLanguage/btrfs|btrfs]] volumes.  Directory-based may be the default option during LXD configuration -- it depends if you have btrfs-tools installed or not.
 +
;IPv6 address: It is recommended you turn this off unless you are specifically wanting to play with IPv6 in your containers. It may cause {{c|dhcpcd}} in your container to only retrieve an IPv6 address if you leave it enabled. This is great if you have IPv6 working -- otherwise, you'll get a dud IPv6 address and no IPv4 address, and thus no network.
 +
 
 +
{{Warning|As explained above, turn off IPv6 NAT in LXD unless you specifically intend to use it! It can confuse {{c|dhcpcd}}.}}
 +
 
 +
Now, we should be able to run {{c|lxc image list}} and get a response from the LXD daemon:
  
 
</translate>
 
</translate>
Line 111: Line 116:
 
# ##i##lxc image list
 
# ##i##lxc image list
 
+-------+-------------+--------+-------------+------+------+-------------+
 
+-------+-------------+--------+-------------+------+------+-------------+
{{!}}
+
{{!}} ALIAS {{!}} FINGERPRINT {{!}} PUBLIC {{!}} DESCRIPTION {{!}} ARCH {{!}} SIZE {{!}} UPLOAD DATE {{!}}
<translate> <!--T:17-->
 
ALIAS {{!}} FINGERPRINT {{!}} PUBLIC {{!}} DESCRIPTION {{!}} ARCH {{!}} SIZE {{!}} UPLOAD DATE {{!}}
 
 
+-------+-------------+--------+-------------+------+------+-------------+
 
+-------+-------------+--------+-------------+------+------+-------------+
 
#
 
#
 
}}
 
}}
 
+
<translate>
 
<!--T:18-->
 
<!--T:18-->
 
If you are able to do this, you have successfully set up the core parts of LXD! Note that we used the command {{c|lxc}} and not {{c|lxd}} like we did for {{c|lxd init}} -- from this point forward, you will use the {{c|lxc}} command. Don't let this
 
If you are able to do this, you have successfully set up the core parts of LXD! Note that we used the command {{c|lxc}} and not {{c|lxd}} like we did for {{c|lxd init}} -- from this point forward, you will use the {{c|lxc}} command. Don't let this
Line 148: Line 151:
 
# ##i##lxc image list
 
# ##i##lxc image list
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
{{!}}
+
{{!}} ALIAS  {{!}} FINGERPRINT  {{!}} PUBLIC {{!}}                DESCRIPTION                {{!}}  ARCH  {{!}}  SIZE  {{!}}        UPLOAD DATE          {{!}}
<translate> <!--T:22-->
 
ALIAS  {{!}} FINGERPRINT  {{!}} PUBLIC {{!}}                DESCRIPTION                {{!}}  ARCH  {{!}}  SIZE  {{!}}        UPLOAD DATE          {{!}}
 
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
</translate>
+
{{!}} funtoo {{!}} fe4d27fb31bf {{!}} no    {{!}} 1.3 Release Skylake 64bit [std] 2019-06-14 {{!}} x86_64 {{!}} 279.35MB {{!}} Jun 15, 2019 at 3:09am (UTC) {{!}}
{{!}}
 
<translate> <!--T:23-->
 
funtoo {{!}} fe4d27fb31bf {{!}} no    {{!}} 1.3 Release Skylake 64bit [std] 2019-06-14 {{!}} x86_64 {{!}} 279.35MB {{!}} Jun 15, 2019 at 3:09am (UTC) {{!}}
 
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
 
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
 
#
 
#
 
}}
 
}}
 +
<translate>
  
=== First Containeer === <!--T:24-->
+
=== First Container === <!--T:24-->
  
 
<!--T:25-->
 
<!--T:25-->
Line 180: Line 179:
 
# ##i##lxc list
 
# ##i##lxc list
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
{{!}}
+
{{!}} NAME         {{!}}  STATE  {{!}} IPV4 {{!}}                    IPV6                      {{!}}    TYPE    {{!}} SNAPSHOTS {{!}}
<translate>    <!--T:27-->
 
NAME     {{!}}  STATE  {{!}} IPV4 {{!}}                    IPV6                      {{!}}    TYPE    {{!}} SNAPSHOTS {{!}}
 
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
</translate>
+
{{!}} testcontainer {{!}} RUNNING {{!}}      {{!}} fd42:8063:81cb:988c:216:3eff:fe2a:f901 (eth0) {{!}} PERSISTENT {{!}}          {{!}}
{{!}}
 
<translate> <!--T:28-->
 
testcontainer {{!}} RUNNING {{!}}      {{!}} fd42:8063:81cb:988c:216:3eff:fe2a:f901 (eth0) {{!}} PERSISTENT {{!}}          {{!}}
 
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
 
+---------------+---------+------+-----------------------------------------------+------------+-----------+
 
#
 
#
 
}}
 
}}
 
+
<translate>
 
<!--T:29-->
 
<!--T:29-->
 
By default, our new container {{c|testcontainer}} will use the default profile, which will connect an {{c|eth0}} interface in the container to NAT, and will also use our directory-based LXD storage pool. We can now enter the container as follows:
 
By default, our new container {{c|testcontainer}} will use the default profile, which will connect an {{c|eth0}} interface in the container to NAT, and will also use our directory-based LXD storage pool. We can now enter the container as follows:
Line 239: Line 233:
 
<translate>
 
<translate>
  
<!--T:32-->
+
What happened is that LXD set up a DHCP server for us (dnsmasq) running on our private container network, and automatically offers IP addresses to our containers. It also configured iptables for us to NAT the connection so that outbound Internet access should magically work.
Time to have some fun!
+
You should also be able to see this IPv4 address listed in the container list when you type {{c|lxc list}} on your host system.
 +
 
 +
=== Network Troubleshooting ===
 +
 
 +
Note that if you are having issues with your container getting an IPv4 address via DHCP, make sure that you turn IPv6 off in LXD. Do this
 +
by running:
  
</translate>
 
 
{{console|body=
 
{{console|body=
%testcontainer% ##i##ego sync
+
###i## lxc network edit lxdbr0
 
}}
 
}}
<translate>
 
  
== Running systemd container on a non-systemd host == <!--T:95-->
+
Then, change {{c|ipv6.nat}} to {{c|"false"}} and restart lxd and the container:
  
<!--T:96-->
 
To use systemd in the container, a recent enough (>=4.6) kernel version with support for cgroup namespaces is needed. Funtoo's openrc has the fix to mount systemd cgroups, which is sufficient to run systemd based distributions lxd containers.
 
 
<!--T:97-->
 
If you want to get <code>systemd</code> hierarchy mounted automatically on system startup, using <code>/etc/fstab</code> will not work, but the
 
</translate>
 
{{Package|dev-libs/libcgroup}}
 
<translate> <!--T:98-->
 
can be used for this. First you needed to edit the <code>/etc/cgroup/cgconfig.conf</code> and add:
 
</translate>
 
{{file|name=/etc/cgroup/cgconfig.conf|body=mount {
 
    "name=systemd" = /sys/fs/cgroup/systemd;
 
}
 
}}
 
<translate>
 
<!--T:99-->
 
Then you need to start the cgconfig daemon:
 
</translate>
 
 
{{console|body=
 
{{console|body=
###i## rc-service cgconfig start
+
###i## /etc/init.d/lxd restart
 +
###i## lxc restart testcontainer
 
}}
 
}}
<translate>
 
<!--T:100-->
 
The daemon can be started as needed, or automatically at system start by simply adding it to default group:
 
</translate>
 
{{console|body=
 
###i## rc-update add cgconfig default
 
}}
 
<translate>
 
  
<!--T:101-->
+
This should resolve the issue.
<hr>
 
<hr>
 
  
 +
=== Finishing Steps ===
  
== [[Special:MyLanguage/LXD/LXD in LXD|PART X - LXD in LXD]] == <!--T:102-->
+
<!--T:32-->
 
+
Assuming your network is now working, you are ready to start using your new Funtoo container. Time to have some fun! Go ahead and run {{c|ego sync}} and then emerge your favorite things:
 
 
== [[Special:MyLanguage/LXD/Docker in LXD|PART Y - Docker in LXD]] == <!--T:103-->
 
 
 
 
 
== [[Special:MyLanguage/LXD/FAQ|PART Z - LXD FAQ]] == <!--T:104-->
 
 
 
 
 
== List of tested and working images == <!--T:105-->
 
 
 
<!--T:106-->
 
These are images from the https://images.linuxcontainers.org repository available by default in lxd. You can
 
list all available images by typing following command (beware the list is very long):
 
 
</translate>
 
</translate>
 
{{console|body=
 
{{console|body=
###i## lxc image list images:
+
%testcontainer% ##i##ego sync
<nowiki>+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
+
\##g##Syncing meta-repo
|              ALIAS              | FINGERPRINT  | PUBLIC |              DESCRIPTION                |  ARCH  |  SIZE  |          UPLOAD DATE          |
+
Cloning into '/var/git/meta-repo'...
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
+
 
| alpine/3.3 (3 more)            | ef69c8dc37f6 | yes    | Alpine 3.3 amd64 (20171018_17:50)        | x86_64  | 2.00MB  | Oct 18, 2017 at 12:00am (UTC) |
+
}}
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.3/armhf (1 more)      | 5ce4c80edcf3 | yes    | Alpine 3.3 armhf (20170103_17:50)        | armv7l  | 1.53MB  | Jan 3, 2017 at 12:00am (UTC)  |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.3/i386 (1 more)        | cd1700cb7c97 | yes    | Alpine 3.3 i386 (20171018_17:50)        | i686    | 1.84MB  | Oct 18, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.4 (3 more)            | bd4f1ccfabb5 | yes    | Alpine 3.4 amd64 (20171018_17:50)        | x86_64  | 2.04MB  | Oct 18, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.4/armhf (1 more)      | 9fe7c201924c | yes    | Alpine 3.4 armhf (20170111_20:27)        | armv7l  | 1.58MB  | Jan 11, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.4/i386 (1 more)        | 188a31315773 | yes    | Alpine 3.4 i386 (20171018_17:50)        | i686    | 1.88MB  | Oct 18, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.5 (3 more)            | 63bebc672163 | yes    | Alpine 3.5 amd64 (20171018_17:50)        | x86_64  | 1.70MB  | Oct 18, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
| alpine/3.5/i386 (1 more)        | 48045e297515 | yes    | Alpine 3.5 i386 (20171018_17:50)        | i686    | 1.73MB  | Oct 18, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
...
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
|                                | fd95a7a754a0 | yes    | Alpine 3.5 amd64 (20171016_17:50)        | x86_64  | 1.70MB  | Oct 16, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
|                                | fef66668f5a2 | yes    | Debian stretch arm64 (20171016_22:42)    | aarch64 | 96.56MB  | Oct 16, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
|                                | ff18aa2c11d7 | yes    | Opensuse 42.3 amd64 (20171017_00:53)    | x86_64  | 58.92MB  | Oct 17, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
|                                | ff4ef0d824b6 | yes    | Ubuntu zesty s390x (20171017_03:49)      | s390x  | 86.88MB  | Oct 17, 2017 at 12:00am (UTC) |
 
+---------------------------------+--------------+--------+------------------------------------------+---------+----------+-------------------------------+
 
</nowiki>}}
 
 
<translate>
 
<translate>
 
<!--T:107-->
 
These are the images that are known to work with current LXD setup on Funtoo Linux:
 
{| class="wikitable sortable"
 
|-
 
! Image  !! Init !! Status
 
|-
 
| CentOS 7 || systemd || Working
 
|-
 
| Debian Jessie (8) - EOL  April/May 2020|| systemd || Working (systemd - no failed units)
 
|-
 
| Debian Stretch (9) - EOL June 2022|| systemd || Working
 
|-
 
| Fedora 26 || systemd with cgroup v2|| Not Working
 
|-
 
| Fedora 25 || systemd || Working
 
|-
 
| Fedora 24 || systemd || Working
 
|-
 
| Oracle 7 || systemd || Working (systemd - no failed units)
 
|-
 
| OpenSUSE 42.2 || systemd || Working
 
|-
 
| OpenSUSE 42.3 || systemd || Working
 
|-
 
| Ubuntu Xenial (16.04 LTS) - EOL 2021-04 || systemd || Working
 
|-
 
| Ubuntu Zesty (17.04) - EOL 2018-01 || systemd || Working
 
|-
 
| Alpine 3.3 || OpenRC || Working
 
|-
 
| Alpine 3.4 || OpenRC || Working
 
|-
 
| Alpine 3.5 || OpenRC || Working
 
|-
 
| Alpine 3.6 || OpenRC || Working
 
|-
 
| Alpine Edge || OpenRC || Working
 
|-
 
| Archlinux || systemd with cgroup v2 || Not Working
 
|-
 
| CentOS 6 || upstart || Working (systemd - no failed units)
 
|-
 
| Debian Buster || systemd with cgroup v2 || Not Working
 
|-
 
| Debian Sid || systemd with cgroup v2 || Not working
 
|-
 
| Debian Wheezy (7) - EOL May 2018 || ? || ? (more testing needed)
 
|-
 
| Gentoo || OpenRC || Working (all services started)
 
|-
 
| Oracle 6 || upstart || ? (mount outputs nothing)
 
|-
 
| Plamo 5 || ? || ?
 
|-
 
| Plamo 6 || ? || ?
 
|-
 
| Sabayon || systemd with cgroup v2 || Not Working
 
|-
 
| Ubuntu Artful (17.10) - EOL 2018-07|| systemd with cgroup v2 || Not Working
 
|-
 
| Ubuntu Core 16 || ? || ?
 
|-
 
| Ubuntu Trusty (14.04 LTS) - EOL 2019-04 || upstart || Working
 
|}
 
 
 
== Features == <!--T:108-->
 
 
<!--T:109-->
 
Some of the biggest features of LXD are:
 
 
<!--T:110-->
 
* Secure by design (unprivileged containers, resource restrictions and much more)
 
* Scalable (from containers on your laptop to thousand of compute nodes)
 
* Intuitive (simple, clear API and crisp command line experience)
 
* Image based (no more distribution templates, only good, trusted images)
 
* Live migration
 
 
 
==== Unprivileged Containers ==== <!--T:111-->
 
 
<!--T:112-->
 
LXD uses unprivileged containers by default. The difference between an unprivileged container and a privileged one is whether the root user in the container is the “real” root user (uid 0 at the kernel level).
 
 
<!--T:113-->
 
The way unprivileged containers are created is by taking a set of normal UIDs and GIDs from the host, usually at least 65536 of each (to be POSIX compliant) and mapping those into the container.
 
 
<!--T:114-->
 
The most common example and what most LXD users will end up with by default is a map of 65536 UIDs and GIDs, with a host base id of 100000. This means that root in the container (uid 0) will be mapped to the host uid 100000 and uid 65535 in the container will be mapped to uid 165535 on the host. UID/GID 65536 and higher in the container aren’t mapped and will return an error if you attempt to use them.
 
 
<!--T:115-->
 
From a security point of view, that means that anything which is not owned by the users and groups mapped into the container will be inaccessible. Any such resource will show up as being owned by uid/gid “-1” (rendered as 65534 or nobody/nogroup in userspace). It also means that should there be a way to escape the container, even root in the container would find itself with just as much privileges on the host as a nobody user.
 
 
<!--T:116-->
 
LXD does offer a number of options related to unprivileged configuration:
 
 
<!--T:117-->
 
* Increasing the size of the default uid/gid map
 
* Setting up per-container maps
 
* Punching holes into the map to expose host users and groups
 
 
 
=== Relationship with LXC === <!--T:118-->
 
 
<!--T:119-->
 
LXD isn't a rewrite of LXC, in fact it's building on top of LXC to provide a new, better user experience. Under the hood, LXD uses LXC through liblxc and its Go binding
 
to create and manage the containers.
 
 
<!--T:120-->
 
It's basically an alternative to LXC's tools and distribution template system with the added features that come from being controllable over the network.
 
 
 
<!--T:121-->
 
<!--T:121-->
[[Category:Virtualization]]
+
[[Category:Containers]]
 +
[[Category:LXD]]
 
[[Category:Official Documentation]]
 
[[Category:Official Documentation]]
 
</translate>
 
</translate>

Latest revision as of 00:59, October 22, 2019

Other languages:
English • ‎português do Brasil

Introduction

LXD is a container "hypervisor" designed to provide an easy set of tools to manage Linux containers, and its development is currently being led by employees at Canonical. You can learn more about the project in general at https://linuxcontainers.org/lxd/ .

LXD is currently used for container infrastructure for Funtoo Containers and is also very well-supported under Funtoo Linux. For this reason, it's recommended that you check out LXD and see what it can do for you.

Basic Setup on Funtoo

The following steps will show you how to set up a basic LXD environment under Funtoo Linux. This environment will essentially use the default LXD setup -- a will be created called lxdbr0 which will use NAT to provide Internet access to your containers. In addition, a default storage pool will be created that will simply use your existing filesystem's storage, creating a directory at /var/lib/lxd/storage-pools/default to store any containers you create. More sophisticated configurations are possible that use dedicated network bridges connected to physical interfaces without NAT, as well as dedicated storage pools that use ZFS and btrfs -- however, these types of configurations are generally overkill for a developer workstation and should only be attempted by advanced users. So we won't cover them here.

Requirements

This section will guide you through setting up the basic requirements for creating an LXD environment.

The first step is to emerge LXD and its dependencies. Perform the following:

root # emerge -a lxd

Once LXD is done emerging, we will want to enable it to start by default:

root # rc-update add lxd default

In addition, we will want to set up the following files. /etc/security/limits.conf should be modified to have the following lines in it:

   /etc/security/limits.conf
*       soft    nofile  1048576
*       hard    nofile  1048576
root    soft    nofile  1048576
root    hard    nofile  1048576
*       soft    memlock unlimited
*       hard    memlock unlimited
# End of file

In addition, we will want to map a set of user ids and group ids to the root user so they are available for its use. Do this by creating the /etc/subuid and /etc/subgid files with the following identical contents:

   /etc/subuid
root:100000:1000000000
   /etc/subgid
root:100000:1000000000

At this point we are ready to initialize and start LXD.

Initialization

To configure LXD, first we will need to start LXD. This can be done as follows:

root # /etc/init.d/lxd start

At this point, we can run lxd init to run a configuration wizard to set up LXD:

root # lxd init
Would you like to use LXD clustering? (yes/no) [default=no]: 
Do you want to configure a new storage pool? (yes/no) [default=yes]: 
Name of the new storage pool [default=default]: 
Name of the storage backend to use (btrfs, dir, lvm) [default=btrfs]: dir ↵
Would you like to connect to a MAAS server? (yes/no) [default=no]: 
Would you like to create a new local network bridge? (yes/no) [default=yes]: 
What should the new bridge be called? [default=lxdbr0]: 
What IPv4 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: 
What IPv6 address should be used? (CIDR subnet notation, “auto” or “none”) [default=auto]: none ↵
Would you like LXD to be available over the network? (yes/no) [default=no]: 
Would you like stale cached images to be updated automatically? (yes/no) [default=yes] 
Would you like a YAML "lxd init" preseed to be printed? (yes/no) [default=no]: 
root #

As you can see, we chose all the default except for:

storage pool
We opted for using a directory-based container storage rather than btrfs volumes. Directory-based may be the default option during LXD configuration -- it depends if you have btrfs-tools installed or not.
IPv6 address
It is recommended you turn this off unless you are specifically wanting to play with IPv6 in your containers. It may cause dhcpcd in your container to only retrieve an IPv6 address if you leave it enabled. This is great if you have IPv6 working -- otherwise, you'll get a dud IPv6 address and no IPv4 address, and thus no network.
   Warning

As explained above, turn off IPv6 NAT in LXD unless you specifically intend to use it! It can confuse dhcpcd.

Now, we should be able to run lxc image list and get a response from the LXD daemon:

root # lxc image list
+-------+-------------+--------+-------------+------+------+-------------+
| ALIAS | FINGERPRINT | PUBLIC | DESCRIPTION | ARCH | SIZE | UPLOAD DATE |
+-------+-------------+--------+-------------+------+------+-------------+
root #

If you are able to do this, you have successfully set up the core parts of LXD! Note that we used the command lxc and not lxd like we did for lxd init -- from this point forward, you will use the lxc command. Don't let this confuse you -- the lxc command is the primary command-line tool for working with LXD containers.

Above, you can see that no images are installed. Images are installable snapshots of containers that we can use to create new containers ourselves. So, as a first step, let's go ahead and grab an image we can use. You will want to browse https://build.funtoo.org for an LXD image that will work on your computer hardware. For example, I was able to download the following file using wget:

root # wget https://build.funtoo.org/1.3-release-std/x86-64bit/intel64-skylake/lxd-intel64-skylake-1.3-release-std-2019-06-11.tar.xz

Once downloaded, this image can be installed using the following command:

root # lxc image import lxd-intel64-skylake-1.3-release-std-2019-06-11.tar.xz --alias funtoo
Image imported with fingerprint: fe4d27fb31bfaf3bd4f470e0ea43d26a6c05991de2a504b9e0a3b1a266dddc69

Now you will see the image available in our image list:

root # lxc image list
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
| ALIAS  | FINGERPRINT  | PUBLIC |                DESCRIPTION                 |  ARCH  |   SIZE   |         UPLOAD DATE          |
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
| funtoo | fe4d27fb31bf | no     | 1.3 Release Skylake 64bit [std] 2019-06-14 | x86_64 | 279.35MB | Jun 15, 2019 at 3:09am (UTC) |
+--------+--------------+--------+--------------------------------------------+--------+----------+------------------------------+
root #

First Container

It is now time to launch our first container. This can be done as follows:

root # lxc launch funtoo testcontainer
Creating testcontainer
Starting testcontainer

We can now see the container running via lxc list:

root # lxc list
+---------------+---------+------+-----------------------------------------------+------------+-----------+
| NAME          |  STATE  | IPV4 |                     IPV6                      |    TYPE    | SNAPSHOTS |
+---------------+---------+------+-----------------------------------------------+------------+-----------+
| testcontainer | RUNNING |      | fd42:8063:81cb:988c:216:3eff:fe2a:f901 (eth0) | PERSISTENT |           |
+---------------+---------+------+-----------------------------------------------+------------+-----------+
root #

By default, our new container testcontainer will use the default profile, which will connect an eth0 interface in the container to NAT, and will also use our directory-based LXD storage pool. We can now enter the container as follows:

root # lxc exec testcontainer -- su --login
testcontainer #

As you might have noticed, we do not yet have any IPv4 networking configured. While LXD has set up a bridge and NAT for us, along with a DHCP server to query, we actually need to use dhcpcd to query for an IP address, so let's get that set up:

testcontainer # echo "template=dhcpcd" > /etc/conf.d/netif.eth0
testcontainer # cd /etc/init.d
testcontainer # ln -s netif.tmpl netif.eth0
testcontainer # rc-update add netif.eth0 default
 * service netif.eth0 added to runlevel default
testcontainer # rc
 * rc is deprecated, please use openrc instead.
 * Caching service dependencies ...                             [ ok ]
 * Starting DHCP Client Daemon ...                              [ ok ]
 * Network dhcpcd eth0 up ...                                   [ ok ]
testcontainer # 

You can now see that eth0 has a valid IPv4 address:

testcontainer # ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.212.194.17  netmask 255.255.255.0  broadcast 10.212.194.255
        inet6 fd42:8063:81cb:988c:25ea:b5bd:603d:8b0d  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::216:3eff:fe2a:f901  prefixlen 64  scopeid 0x20<link>
        ether 00:16:3e:2a:f9:01  txqueuelen 1000  (Ethernet)
        RX packets 45  bytes 5385 (5.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 20  bytes 2232 (2.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

What happened is that LXD set up a DHCP server for us (dnsmasq) running on our private container network, and automatically offers IP addresses to our containers. It also configured iptables for us to NAT the connection so that outbound Internet access should magically work. You should also be able to see this IPv4 address listed in the container list when you type lxc list on your host system.

Network Troubleshooting

Note that if you are having issues with your container getting an IPv4 address via DHCP, make sure that you turn IPv6 off in LXD. Do this by running:

root # lxc network edit lxdbr0

Then, change ipv6.nat to "false" and restart lxd and the container:

root # /etc/init.d/lxd restart
root # lxc restart testcontainer

This should resolve the issue.

Finishing Steps

Assuming your network is now working, you are ready to start using your new Funtoo container. Time to have some fun! Go ahead and run ego sync and then emerge your favorite things:

testcontainer # ego sync
Syncing meta-repo
Cloning into '/var/git/meta-repo'...