First, create a container mycontainer with the command lxc launch ubuntu: mycontainer . This command creates a container with the currently default LTS version (at the time of writing, 18.04, soon it will be 20.04).

You are using LXD, you can launch containers and get a shell into them using the following lxc command. This command uses the exec subcommand to run a process in the container mycontainer, and the full line of the process is whatever appears after the —, in this case, /bin/bash . The /bin/bash can be replaced with any executable from the container.

lxc exec mycontainer -- /bin/bash

The -- is a special sequence that tells parameter parser on the host to stop processing parameters. In the above example it is not required because we do not use a parameter for /bin/bash . However, in the following, it is needed. The lxc command sees in the first line that there is a -l option, and tries to process it. But there is no valid -l parameter to lxc exec , hence the error message. The following also demonstrate that the default working directory for the Ubuntu container images is root ‘s home directory, /root .

$ lxc exec mycontainer ls -l Error: unknown shorthand flag: 'l' in -l $ lxc exec mycontainer -- ls -l total 0 $ lxc exec mycontainer -- pwd /root $

The corollary is that if you do not get into the habit of adding -- , you might run a complex command that has a valid lxc exec parameter and the result could be quite weird. However, in most cases, you would want to get just a shell into the container, and then do your work. That is the purpose of this blog post.

Learning about LXD aliases

Managing aliases in LXD You can list, add, rename and remove LXD aliases. Listing LXD aliases Run the lxc alias list command to list all aliases. In the following, there are no aliases at all (default). $ lxc alias list +-------+--------+ | ALIAS | TARGET | +-------+--------+ Adding a LXD alias Let’s create an alias, called list . There is already a lxc list subcommand, therefore we will be hiding the official subcommand. But why do this? First, lxc list produces by default a very wide table so we are going to drop some of the columns. Second, we want to show here how to remove an alias, so we will remove the list alias anyway. $ lxc alias add list 'list -c ns46' $ lxc alias list +-------+---------------+ | ALIAS | TARGET | +-------+---------------+ | list | list -c ns46 | +-------+---------------+ Now, when you run lxc list , you will get just four columns, n for the Name of the container, s for the State of the container (RUNNING, _STOPPED or something else), and 46 for both the IPv4 and IPv6 IP addresses of the container. Renaming a LXD alias Frankly, list is not a good choice for the name of an alias because it masks (hides) the proper lxc list subcommand. Let’s rename the alias to something else. $ lxc alias rename list ll $ lxc alias list +-------+---------------+ | ALIAS | TARGET | +-------+---------------+ | ll | list -c ns46 | +-------+---------------+ Now you can run the following command to list the containers in a table of four only columns. $ lxc ll Removing a LXD alias We have now decided to remove the ll alias. If you love it though, you may keep it! Here is the command anyway. $ lxc alias remove ll

Using sudo --login ubuntu --shell

To get a non-root shell into a LXD container of an Ubuntu container image ( ubuntu: ), you can use the following command. The ubuntu: container images, when launched, create a non-root ubuntu account. Therefore, when we exec into the container, we sudo as user ubuntu and request a login shell. A login shell means that all shell configuration files are parsed ( /etc/profile , /etc/bash* , ~/.profile , etc). Due to this, it might take a few hundreds milliseconds to get to the shell, compared to other ways. This command is also the command that I have been including in my tutorials (since 2016), therefore you can see it a lot around the Internet.

$ lxc exec mycontainer -- sudo --user ubuntu --login To run a command as administrator (user "root"), use "sudo <command>".See "man sudo_root" for details. $

If you were to launch a container and immediately run the above command to get a shell, you may encounter the following error (unknown user: ubuntu). What happened? We were really fast, and the mycontainer container did not fully finish starting up. Which means that the instruction to create the ubuntu non-root account did not run yet. In fact, the instruction to create this account is among that last instructions to run when a new container is created. In such a case, just wait for one more second, and run the lxc exec command again.

$ lxc launch ubuntu: mycontainer Creating mycontainerStarting mycontainer $ lxc exec mycontainer -- sudo --user ubuntu --login sudo: unknown user: ubuntu sudo: unable to initialize policy plugin $

The downside with this lxc exec command is that it assumes there is an ubuntu non-root account, which only works for the ubuntu: repository of container images. It does not work with the Ubuntu container images from the images: repository, nor with other container images. Those other container images only have a default root account.

Using lxc shell mycontainer

The lxc client of LXD currently has a single default alias for lxc shell . This alias is not listed when you run lxc alias list since it is part of the client. Here is the source code,

// defaultAliases contains LXC's built-in command line aliases. The built-in // aliases are checked only if no user-defined alias was found. var defaultAliases = map[string]string{ "shell": "exec @ARGS@ -- su -l", }

You would run this as follows. It runs su -l to get a login shell as root.

$ lxc shell mycontainer mesg: ttyname failed: No such device root@mycontainer:~#

Let’s add an alias that will su as a non-root user. We will name it shell , therefore masking the built-in alias.

$ lxc alias add shell "exec @ARGS@ -- su -l ubuntu" $ lxc shell mycontainer To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details. $

Using lxc ubuntu mycontainer

In 2018, Raymond E Ferguson started a thread on discuss.linuxcontainers.org about useful LXC aliases, and specifically about LXC aliases to get a login shell into a LXD container.

To get a non-root shell to a LXD container (Ubuntu container from ubuntu: repository)

Create the following alias, named ubuntu. You run this once to add the LXD alias to your host’s settings.

lxc alias add ubuntu 'exec @ARGS@ --mode interactive -- /bin/sh -xac $@ubuntu - exec /bin/login -p -f '

Use as:

lxc ubuntu mycontainer

To get a shell to a LXD container (default: root, else specify with $USER)

Create the following alias, named ubuntu. You run this once to add the LXD alias to your host’s settings.

lxc alias add login 'exec @ARGS@ --mode interactive -- /bin/sh -xac $@${USER:-root} - exec /bin/login -p -f '

Run as (to get a root shell by default):

lxc login mycontainer

Run as (to get a specific $USER shell):

lxc login mycontainer --env USER=ubuntu

Learning more about lxc exec

The current version of the LXD lxc client (now at 3.21) has several built-in features that can help get a shell. Let’s see the available parameters. Of interest are --user / --group and --env to set $HOME .

$ lxc exec --help Description: Execute commands in instances The command is executed directly using exec, so there is no shell and shell patterns (variables, file redirects, ...) won't be understood. If you need a shell environment you need to execute the shell executable, passing the shell commands as arguments, for example: lxc exec -- sh -c "cd /tmp && pwd" Mode defaults to non-interactive, interactive mode is selected if both stdin AND stdout are terminals (stderr is ignored). Usage: lxc exec [ :] [flags] [--] Flags: --cwd Directory to run the command in (default /root) -n, --disable-stdin Disable stdin (reads from /dev/null) --env Environment variable to set (e.g. HOME=/home/foo) -t, --force-interactive Force pseudo-terminal allocation -T, --force-noninteractive Disable pseudo-terminal allocation --group Group ID to run the command as (default 0) --mode Override the terminal mode (auto, interactive or non-interactive) (default "auto") --user User ID to run the command as (default 0) Global Flags: --debug Show all debug messages --force-local Force using the local unix socket -h, --help Print help --project string Override the source project -q, --quiet Don't show progress information -v, --verbose Show all information messages --version Print version number

In addition, bash has a --login parameter which we are going to use as well. Therefore, we have the following command for a login shell. The ubuntu: container images create a non-root account with username ubuntu and UID/GID 1000/1000. We set the $HOME because even with bash --login it is not set. We do not specify the full path for bash just in case it is in either /bin or /usr/bin . In Ubuntu it is /bin/bash , so it will work in Ubuntu and provide flexibility if we were to extend to other distributions.

$ lxc exec --user 1000 --group 1000 --env "HOME=/home/ubuntu/" mycontainer -- bash --login You just parsed /etc/bash.bashrc! You just parsed /etc/profile.d/apps-bin-path.sh! You just parsed /etc/profile! You just parsed ~/.bashrc! You just parsed ~/.profile! ubuntu@mycontainer:~$

Notice above that I edited the various configuration files so that they print the sequence they are invoked for a login shell. Let’s see how this looks when we do not add --login to bash . Without a login shell, the only two files that are parsed are /etc/bash.bashrc and ~/.bashrc .

$ lxc exec mycontainer --user 1000 --group 1000 --env HOME=/home/ubuntu/ -- bash You just parsed /etc/bash.bashrc! You just parsed ~/.bashrc! ubuntu@mycontainer:/home/ubuntu$

We are good to go and create the alias. I am changing my old lxc ubuntu alias to this one. Here it is. We remove any old ubuntu alias and add the new one.

lxc alias remove ubuntu lxc alias add ubuntu 'exec @ARGS@ --user 1000 --group 1000 --env HOME=/home/ubuntu/ -- /bin/bash --login'

How to use the lxc ubuntu alias. It works on Ubuntu container images from the ubuntu: repository. Creates a login shell using Bash for the ubuntu non-root user.

Summary

There are several ways to execute a login shell into a LXD container. For the Ubuntu containers (repository ubuntu: ) I am using the following alias, lxc ubuntu mycontainer . ubuntu is the new subcommand (through an LXD alias) to get a login shell as user ubuntu .

If you want to get the same, run the following on each of your LXD hosts.

lxc alias add ubuntu 'exec @ARGS@ --user 1000 --group 1000 --env HOME=/home/ubuntu/ -- /bin/bash --login'

If your container is called mycontainer, you get a login shell as follows:

lxc ubuntu mycontainer

Share this: Twitter

Facebook

Reddit

Email

Print



Like this: Like Loading...