mirror of
https://git.proxmox.com/git/mirror_lxc
synced 2025-07-27 07:42:57 +00:00
484 lines
15 KiB
Plaintext
484 lines
15 KiB
Plaintext
<!--
|
|
|
|
lxc: linux Container library
|
|
|
|
(C) Copyright IBM Corp. 2007, 2008
|
|
|
|
Authors:
|
|
Daniel Lezcano <daniel.lezcano at free.fr>
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU Lesser General Public
|
|
License as published by the Free Software Foundation; either
|
|
version 2.1 of the License, or (at your option) any later version.
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Lesser General Public License for more details.
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
License along with this library; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
-->
|
|
|
|
<!DOCTYPE refentry PUBLIC @docdtd@ [
|
|
|
|
<!ENTITY seealso SYSTEM "@builddir@/see_also.sgml">
|
|
]>
|
|
|
|
<refentry>
|
|
|
|
<docinfo>
|
|
<date>@LXC_GENERATE_DATE@</date>
|
|
</docinfo>
|
|
|
|
|
|
<refmeta>
|
|
<refentrytitle>lxc</refentrytitle>
|
|
<manvolnum>7</manvolnum>
|
|
<refmiscinfo>
|
|
Version @PACKAGE_VERSION@
|
|
</refmiscinfo>
|
|
</refmeta>
|
|
|
|
<refnamediv>
|
|
<refname>lxc</refname>
|
|
|
|
<refpurpose>
|
|
linux containers
|
|
</refpurpose>
|
|
</refnamediv>
|
|
|
|
<refsect1>
|
|
<title>Overview</title>
|
|
<para>
|
|
The container technology is actively being pushed into the mainstream
|
|
Linux kernel. It provides resource management through control groups and
|
|
resource isolation via namespaces.
|
|
</para>
|
|
|
|
<para>
|
|
<command>lxc</command>, aims to use these new functionalities to provide a
|
|
userspace container object which provides full resource isolation and
|
|
resource control for an applications or a full system.
|
|
</para>
|
|
|
|
<para>
|
|
<command>lxc</command> is small enough to easily manage a container with
|
|
simple command lines and complete enough to be used for other purposes.
|
|
</para>
|
|
</refsect1>
|
|
|
|
<refsect1>
|
|
<title>Requirements</title>
|
|
<para>
|
|
The kernel version >= 3.10 shipped with the distros, will work with
|
|
<command>lxc</command>, this one will have less functionalities but enough
|
|
to be interesting.
|
|
</para>
|
|
|
|
<para>
|
|
<command>lxc</command> relies on a set of functionalities provided by the
|
|
kernel. The helper script <command>lxc-checkconfig</command> will give
|
|
you information about your kernel configuration, required, and missing
|
|
features.
|
|
</para>
|
|
</refsect1>
|
|
|
|
<refsect1>
|
|
<title>Functional specification</title>
|
|
<para>
|
|
A container is an object isolating some resources of the host, for the
|
|
application or system running in it.
|
|
</para>
|
|
<para>
|
|
The application / system will be launched inside a container specified by
|
|
a configuration that is either initially created or passed as a parameter
|
|
of the commands.
|
|
</para>
|
|
|
|
<para>How to run an application in a container</para>
|
|
<para>
|
|
Before running an application, you should know what are the resources you
|
|
want to isolate. The default configuration is to isolate PIDs, the sysv
|
|
IPC and mount points. If you want to run a simple shell inside a
|
|
container, a basic configuration is needed, especially if you want to
|
|
share the rootfs. If you want to run an application like
|
|
<command>sshd</command>, you should provide a new network stack and a new
|
|
hostname. If you want to avoid conflicts with some files eg.
|
|
<filename>/var/run/httpd.pid</filename>, you should remount
|
|
<filename>/var/run</filename> with an empty directory. If you want to
|
|
avoid the conflicts in all the cases, you can specify a rootfs for the
|
|
container. The rootfs can be a directory tree, previously bind mounted
|
|
with the initial rootfs, so you can still use your distro but with your
|
|
own <filename>/etc</filename> and <filename>/home</filename>
|
|
</para>
|
|
<para>
|
|
Here is an example of directory tree
|
|
for <command>sshd</command>:
|
|
<programlisting>
|
|
[root@lxc sshd]$ tree -d rootfs
|
|
|
|
rootfs
|
|
|-- bin
|
|
|-- dev
|
|
| |-- pts
|
|
| `-- shm
|
|
| `-- network
|
|
|-- etc
|
|
| `-- ssh
|
|
|-- lib
|
|
|-- proc
|
|
|-- root
|
|
|-- sbin
|
|
|-- sys
|
|
|-- usr
|
|
`-- var
|
|
|-- empty
|
|
| `-- sshd
|
|
|-- lib
|
|
| `-- empty
|
|
| `-- sshd
|
|
`-- run
|
|
`-- sshd
|
|
</programlisting>
|
|
|
|
and the mount points file associated with it:
|
|
<programlisting>
|
|
[root@lxc sshd]$ cat fstab
|
|
|
|
/lib /home/root/sshd/rootfs/lib none ro,bind 0 0
|
|
/bin /home/root/sshd/rootfs/bin none ro,bind 0 0
|
|
/usr /home/root/sshd/rootfs/usr none ro,bind 0 0
|
|
/sbin /home/root/sshd/rootfs/sbin none ro,bind 0 0
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>How to run a system in a container</para>
|
|
|
|
<para>
|
|
Running a system inside a container is paradoxically easier
|
|
than running an application. Why? Because you don't have to care
|
|
about the resources to be isolated, everything needs to be
|
|
isolated, the other resources are specified as being isolated but
|
|
without configuration because the container will set them
|
|
up. eg. the ipv4 address will be setup by the system container
|
|
init scripts. Here is an example of the mount points file:
|
|
</para>
|
|
|
|
<programlisting>
|
|
[root@lxc debian]$ cat fstab
|
|
|
|
/dev /home/root/debian/rootfs/dev none bind 0 0
|
|
/dev/pts /home/root/debian/rootfs/dev/pts none bind 0 0
|
|
</programlisting>
|
|
|
|
<refsect2>
|
|
<title>Container life cycle</title>
|
|
<para>
|
|
When the container is created, it contains the configuration
|
|
information. When a process is launched, the container will be starting
|
|
and running. When the last process running inside the container exits,
|
|
the container is stopped.
|
|
</para>
|
|
<para>
|
|
In case of failure when the container is initialized, it will pass
|
|
through the aborting state.
|
|
</para>
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
---------
|
|
| STOPPED |<---------------
|
|
--------- |
|
|
| |
|
|
start |
|
|
| |
|
|
V |
|
|
---------- |
|
|
| STARTING |--error- |
|
|
---------- | |
|
|
| | |
|
|
V V |
|
|
--------- ---------- |
|
|
| RUNNING | | ABORTING | |
|
|
--------- ---------- |
|
|
| | |
|
|
no process | |
|
|
| | |
|
|
V | |
|
|
---------- | |
|
|
| STOPPING |<------- |
|
|
---------- |
|
|
| |
|
|
---------------------
|
|
]]>
|
|
</programlisting>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Configuration</title>
|
|
<para>The container is configured through a configuration
|
|
file, the format of the configuration file is described in
|
|
<citerefentry>
|
|
<refentrytitle><filename>lxc.conf</filename></refentrytitle>
|
|
<manvolnum>5</manvolnum>
|
|
</citerefentry>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Creating / Destroying containers</title>
|
|
<para>
|
|
A persistent container object can be created via the
|
|
<command>lxc-create</command> command. It takes a container name as
|
|
parameter and optional configuration file and template. The name is
|
|
used by the different commands to refer to this container. The
|
|
<command>lxc-destroy</command> command will destroy the container
|
|
object.
|
|
<programlisting>
|
|
lxc-create -n foo
|
|
lxc-destroy -n foo
|
|
</programlisting>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Volatile container</title>
|
|
<para>
|
|
It is not mandatory to create a container object before starting it.
|
|
The container can be directly started with a configuration file as
|
|
parameter.
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Starting / Stopping container</title>
|
|
<para>
|
|
When the container has been created, it is ready to run an application /
|
|
system. This is the purpose of the <command>lxc-execute</command> and
|
|
<command>lxc-start</command> commands. If the container was not created
|
|
before starting the application, the container will use the
|
|
configuration file passed as parameter to the command, and if there is
|
|
no such parameter either, then it will use a default isolation. If the
|
|
application ended, the container will be stopped, but if needed the
|
|
<command>lxc-stop</command> command can be used to stop the container.
|
|
</para>
|
|
|
|
<para>
|
|
Running an application inside a container is not exactly the same thing
|
|
as running a system. For this reason, there are two different commands
|
|
to run an application into a container:
|
|
<programlisting>
|
|
lxc-execute -n foo [-f config] /bin/bash
|
|
lxc-start -n foo [-f config] [/bin/bash]
|
|
</programlisting>
|
|
</para>
|
|
|
|
<para>
|
|
The <command>lxc-execute</command> command will run the specified command
|
|
into a container via an intermediate process,
|
|
<command>lxc-init</command>.
|
|
This lxc-init after launching the specified command, will wait for its
|
|
end and all other reparented processes. (to support daemons in the
|
|
container). In other words, in the container,
|
|
<command>lxc-init</command> has PID 1 and the first process of the
|
|
application has PID 2.
|
|
</para>
|
|
|
|
<para>
|
|
The <command>lxc-start</command> command will directly run the specified
|
|
command in the container. The PID of the first process is 1. If no
|
|
command is specified <command>lxc-start</command> will run the command
|
|
defined in lxc.init.cmd or if not set, <filename>/sbin/init</filename> .
|
|
</para>
|
|
|
|
<para>
|
|
To summarize, <command>lxc-execute</command> is for running an
|
|
application and <command>lxc-start</command> is better suited for
|
|
running a system.
|
|
</para>
|
|
|
|
<para>
|
|
If the application is no longer responding, is inaccessible or is not
|
|
able to finish by itself, a wild <command>lxc-stop</command> command
|
|
will kill all the processes in the container without pity.
|
|
<programlisting>
|
|
lxc-stop -n foo -k
|
|
</programlisting>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Connect to an available tty</title>
|
|
<para>
|
|
If the container is configured with ttys, it is possible to access it
|
|
through them. It is up to the container to provide a set of available
|
|
ttys to be used by the following command. When the tty is lost, it is
|
|
possible to reconnect to it without login again.
|
|
<programlisting>
|
|
lxc-console -n foo -t 3
|
|
</programlisting>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Freeze / Unfreeze container</title>
|
|
<para>
|
|
Sometime, it is useful to stop all the processes belonging to
|
|
a container, eg. for job scheduling. The commands:
|
|
<programlisting>
|
|
lxc-freeze -n foo
|
|
</programlisting>
|
|
|
|
will put all the processes in an uninteruptible state and
|
|
|
|
<programlisting>
|
|
lxc-unfreeze -n foo
|
|
</programlisting>
|
|
|
|
will resume them.
|
|
</para>
|
|
|
|
<para>
|
|
This feature is enabled if the freezer cgroup v1 controller is enabled
|
|
in the kernel.
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Getting information about container</title>
|
|
<para>
|
|
When there are a lot of containers, it is hard to follow what has been
|
|
created or destroyed, what is running or what are the PIDs running in a
|
|
specific container. For this reason, the following commands may be useful:
|
|
<programlisting>
|
|
lxc-ls -f
|
|
lxc-info -n foo
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
<command>lxc-ls</command> lists containers.
|
|
</para>
|
|
|
|
<para>
|
|
<command>lxc-info</command> gives information for a specific container.
|
|
</para>
|
|
|
|
<para>
|
|
Here is an example on how the combination of these commands
|
|
allows one to list all the containers and retrieve their state.
|
|
<programlisting>
|
|
for i in $(lxc-ls -1); do
|
|
lxc-info -n $i
|
|
done
|
|
</programlisting>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>Monitoring container</title>
|
|
<para>
|
|
It is sometime useful to track the states of a container, for example to
|
|
monitor it or just to wait for a specific state in a script.
|
|
</para>
|
|
|
|
<para>
|
|
<command>lxc-monitor</command> command will monitor one or several
|
|
containers. The parameter of this command accepts a regular expression
|
|
for example:
|
|
<programlisting>
|
|
lxc-monitor -n "foo|bar"
|
|
</programlisting>
|
|
will monitor the states of containers named 'foo' and 'bar', and:
|
|
<programlisting>
|
|
lxc-monitor -n ".*"
|
|
</programlisting>
|
|
will monitor all the containers.
|
|
</para>
|
|
<para>
|
|
For a container 'foo' starting, doing some work and exiting,
|
|
the output will be in the form:
|
|
<programlisting>
|
|
'foo' changed state to [STARTING]
|
|
'foo' changed state to [RUNNING]
|
|
'foo' changed state to [STOPPING]
|
|
'foo' changed state to [STOPPED]
|
|
</programlisting>
|
|
</para>
|
|
<para>
|
|
<command>lxc-wait</command> command will wait for a specific
|
|
state change and exit. This is useful for scripting to
|
|
synchronize the launch of a container or the end. The
|
|
parameter is an ORed combination of different states. The
|
|
following example shows how to wait for a container if it successfully
|
|
started as a daemon.
|
|
|
|
<programlisting>
|
|
<![CDATA[
|
|
# launch lxc-wait in background
|
|
lxc-wait -n foo -s STOPPED &
|
|
LXC_WAIT_PID=$!
|
|
|
|
# this command goes in background
|
|
lxc-execute -n foo mydaemon &
|
|
|
|
# block until the lxc-wait exits
|
|
# and lxc-wait exits when the container
|
|
# is STOPPED
|
|
wait $LXC_WAIT_PID
|
|
echo "'foo' is finished"
|
|
]]>
|
|
</programlisting>
|
|
</para>
|
|
</refsect2>
|
|
|
|
<refsect2>
|
|
<title>cgroup settings for containers</title>
|
|
<para>
|
|
The container is tied with the control groups, when a container is
|
|
started a control group is created and associated with it. The control
|
|
group properties can be read and modified when the container is running
|
|
by using the lxc-cgroup command.
|
|
</para>
|
|
<para>
|
|
<command>lxc-cgroup</command> command is used to set or get a
|
|
control group subsystem which is associated with a
|
|
container. The subsystem name is handled by the user, the
|
|
command won't do any syntax checking on the subsystem name, if
|
|
the subsystem name does not exists, the command will fail.
|
|
</para>
|
|
<para>
|
|
<programlisting>
|
|
lxc-cgroup -n foo cpuset.cpus
|
|
</programlisting>
|
|
will display the content of this subsystem.
|
|
<programlisting>
|
|
lxc-cgroup -n foo cpu.shares 512
|
|
</programlisting>
|
|
will set the subsystem to the specified value.
|
|
</para>
|
|
</refsect2>
|
|
</refsect1>
|
|
|
|
&seealso;
|
|
|
|
<refsect1>
|
|
<title>Author</title>
|
|
<para>Daniel Lezcano <email>daniel.lezcano@free.fr</email></para>
|
|
<para>Christian Brauner <email>christian.brauner@ubuntu.com</email></para>
|
|
<para>Serge Hallyn <email>serge@hallyn.com</email></para>
|
|
<para>Stéphane Graber <email>stgraber@ubuntu.com</email></para>
|
|
</refsect1>
|
|
|
|
</refentry>
|
|
|
|
<!-- Keep this comment at the end of the file Local variables: mode:
|
|
sgml sgml-omittag:t sgml-shorttag:t sgml-minimize-attributes:nil
|
|
sgml-always-quote-attributes:t sgml-indent-step:2 sgml-indent-data:t
|
|
sgml-parent-document:nil sgml-default-dtd-file:nil
|
|
sgml-exposed-tags:nil sgml-local-catalogs:nil
|
|
sgml-local-ecat-files:nil End: -->
|