mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 08:58:59 +00:00
533 lines
18 KiB
ReStructuredText
533 lines
18 KiB
ReStructuredText
.. _tutorial-lxc:
|
|
|
|
========================
|
|
LXC Management with Salt
|
|
========================
|
|
|
|
.. note::
|
|
|
|
This walkthrough assumes basic knowledge of Salt. To get up to speed, check
|
|
out the :doc:`Salt Walkthrough </topics/tutorials/walkthrough>`.
|
|
|
|
.. warning::
|
|
|
|
Some features are only currently available in the ``develop`` branch, and
|
|
are new in the upcoming 2015.2.0 release. These new features will be
|
|
clearly labeled.
|
|
|
|
|
|
Dependencies
|
|
============
|
|
|
|
Manipulation of LXC containers in Salt requires the minion to have an LXC
|
|
version of at least 1.0 (an alpha or beta release of LXC 1.0 is acceptable).
|
|
The following distributions are known to have new enough versions of LXC
|
|
packaged:
|
|
|
|
- RHEL/CentOS 6 and later (via EPEL_)
|
|
- Fedora (All non-EOL releases)
|
|
- Debian 8.0 (Jessie)
|
|
- Ubuntu 14.04 LTS and later (LXC templates are packaged separately as
|
|
**lxc-templates**, it is recommended to also install this package)
|
|
- openSUSE 13.2 and later
|
|
|
|
.. _EPEL: https://fedoraproject.org/wiki/EPEL
|
|
|
|
|
|
.. _tutorial-lxc-profiles:
|
|
|
|
Profiles
|
|
========
|
|
|
|
Profiles allow for a sort of shorthand for commonly-used
|
|
configurations to be defined in the minion config file, :ref:`grains
|
|
<targeting-grains>`, :ref:`pillar <pillar>`, or the master config file. The
|
|
profile is retrieved by Salt using the :mod:`config.get
|
|
<salt.modules.config.get>` function, which looks in those locations, in that
|
|
order. This allows for profiles to be defined centrally in the master config
|
|
file, with several options for overriding them (if necessary) on groups of
|
|
minions or individual minions.
|
|
|
|
There are two types of profiles, one for defining the parameters used in
|
|
container creation, and one for defining the container's network interface(s).
|
|
|
|
.. _tutorial-lxc-profiles-container:
|
|
|
|
Container Profiles
|
|
------------------
|
|
|
|
In the 2014.7 release cycle and earlier, LXC container profiles were all
|
|
defined underneath the ``lxc.profile`` config option:
|
|
|
|
.. code-block:: yaml
|
|
|
|
lxc.profile:
|
|
centos:
|
|
template: centos
|
|
backing: lvm
|
|
vgname: vg1
|
|
lvname: lxclv
|
|
size: 10G
|
|
centos_big:
|
|
template: centos
|
|
backing: lvm
|
|
vgname: vg1
|
|
lvname: lxclv
|
|
size: 20G
|
|
|
|
However, due to the way that :mod:`config.get <salt.modules.config.get>` works,
|
|
this means that if a ``lxc.profile`` key is defined in both the master config
|
|
file and in a specific minion's config file, that will cause all profiles to be
|
|
overwritten for that minion. For greater flexibility, starting in version
|
|
2015.2.0 each container profile should be configured in its own key, in the
|
|
format ``lxc.container_profile.profile_name``. For example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
lxc.container_profile.centos:
|
|
template: centos
|
|
backing: lvm
|
|
vgname: vg1
|
|
lvname: lxclv
|
|
size: 10G
|
|
lxc.container_profile.centos_big:
|
|
template: centos
|
|
backing: lvm
|
|
vgname: vg1
|
|
lvname: lxclv
|
|
size: 20G
|
|
|
|
This way, the ``centos_big`` profile can be redefined for a single minion
|
|
without also removing the ``centos`` profile. The legacy usage will still be
|
|
supported for a couple release cycles, to allow for some time to update
|
|
configurations.
|
|
|
|
Additionally, in version 2015.2.0 container profiles have been expanded to
|
|
support passing template-specific CLI options to :mod:`lxc.create
|
|
<salt.modules.lxc.create>`. Below is a table describing the parameters which
|
|
can be configured in container profiles:
|
|
|
|
================== ================== ====================
|
|
Parameter 2015.2.0 and Newer 2014.7.x and Earlier
|
|
================== ================== ====================
|
|
*template*:sup:`1` Yes Yes
|
|
*options*:sup:`1` Yes No
|
|
*image*:sup:`1` Yes Yes
|
|
*backing* Yes Yes
|
|
*snapshot*:sup:`2` Yes Yes
|
|
*lvname*:sup:`1` Yes Yes
|
|
*fstype*:sup:`1` Yes Yes
|
|
*size* Yes Yes
|
|
================== ================== ====================
|
|
|
|
1. Parameter is only supported for container creation, and will be ignored if
|
|
the profile is used when cloning a container.
|
|
2. Parameter is only supported for container cloning, and will be ignored if
|
|
the profile is used when not cloning a container.
|
|
|
|
.. _tutorial-lxc-profiles-network:
|
|
|
|
Network Profiles
|
|
----------------
|
|
|
|
In the 2014.7 release cycle and earlier, LXC network profiles were all
|
|
defined underneath the ``lxc.nic`` config option:
|
|
|
|
.. code-block:: yaml
|
|
|
|
lxc.nic:
|
|
centos:
|
|
eth0:
|
|
link: br0
|
|
type: veth
|
|
flags: up
|
|
ubuntu:
|
|
eth0:
|
|
link: lxcbr0
|
|
type: veth
|
|
flags: up
|
|
|
|
However, due to the way that :mod:`config.get <salt.modules.config.get>` works,
|
|
this means that if a ``lxc.nic`` key is defined in both the master config file
|
|
and in a specific minion's config file, that will cause all network profiles to
|
|
be overwritten for that minion. For greater flexibility, starting with version
|
|
2015.2.0 each network profile should be configured in its own key, in the
|
|
format ``lxc.network_profile.profile_name``. For example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
lxc.network_profile.centos:
|
|
eth0:
|
|
link: br0
|
|
type: veth
|
|
flags: up
|
|
lxc.network_profile.ubuntu:
|
|
eth0:
|
|
link: lxcbr0
|
|
type: veth
|
|
flags: up
|
|
|
|
This way, the ``ubuntu`` profile can be redefined for a single minion
|
|
without also removing the ``centos`` profile. The legacy usage will still be
|
|
supported for a couple release cycles, to allow for some time to update
|
|
configurations.
|
|
|
|
The following are parameters which can be configured in network profiles. These
|
|
will directly correspond to a parameter in an LXC configuration file (see ``man
|
|
5 lxc.container.conf``).
|
|
|
|
- **type** - Corresponds to **lxc.network.type**
|
|
- **link** - Corresponds to **lxc.network.link**
|
|
- **flags** - Corresponds to **lxc.network.flags**
|
|
|
|
Interface-specific options (MAC address, IPv4/IPv6, etc.) can be passed on a
|
|
container-by-container basis.
|
|
|
|
|
|
Creating a Container on the CLI
|
|
===============================
|
|
|
|
From a Template
|
|
---------------
|
|
|
|
LXC is commonly distributed with several template scripts in
|
|
/usr/share/lxc/templates. Some distros may package these separately in an
|
|
**lxc-templates** package, so make sure to check if this is the case.
|
|
|
|
There are LXC template scripts for several different operating systems, but
|
|
some of them are designed to use tools specific to a given distribution. For
|
|
instance, the ``ubuntu`` template uses deb_bootstrap, the ``centos`` template
|
|
uses yum, etc., making these templates impractical when a container from a
|
|
different OS is desired.
|
|
|
|
The :mod:`lxc.create <salt.modules.lxc.create>` function is used to create
|
|
containers using a template script. To create a CentOS container named
|
|
``container1`` on a CentOS minion named ``mycentosminion``, using the
|
|
``centos`` LXC template, one can simply run the following command:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt mycentosminion lxc.create container1 template=centos
|
|
|
|
|
|
For these instances, there is a ``download`` template which retrieves minimal
|
|
container images for several different operating systems. To use this template,
|
|
it is necessary to provide an ``options`` parameter when creating the
|
|
container, with three values:
|
|
|
|
1. **dist** - the Linux distribution (i.e. ``ubuntu`` or ``centos``)
|
|
2. **release** - the release name/version (i.e. ``trusty`` or ``6``)
|
|
3. **arch** - CPU architecture (i.e. ``amd64`` or ``i386``)
|
|
|
|
The :mod:`lxc.images <salt.modules.lxc.images>` function (new in version
|
|
2015.2.0) can be used to list the available images. Alternatively, the releases
|
|
can be viewed on http://images.linuxcontainers.org/images/. The images are
|
|
organized in such a way that the **dist**, **release**, and **arch** can be
|
|
determined using the following URL format:
|
|
``http://images.linuxcontainers.org/images/dist/release/arch``. For example,
|
|
``http://images.linuxcontainers.org/images/centos/6/amd64`` would correspond to
|
|
a **dist** of ``centos``, a **release** of ``6``, and an **arch** of ``amd64``.
|
|
|
|
Therefore, to use the ``download`` template to create a new 64-bit CentOS 6
|
|
container, the following command can be used:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.create container1 template=download options='{dist: centos, release: 6, arch: amd64}'
|
|
|
|
.. note::
|
|
|
|
These command-line options can be placed into a :ref:`container profile
|
|
<tutorial-lxc-profiles-container>`, like so:
|
|
|
|
.. code-block:: yaml
|
|
|
|
lxc.container_profile.cent6:
|
|
template: download
|
|
options:
|
|
dist: centos
|
|
release: 6
|
|
arch: amd64
|
|
|
|
The ``options`` parameter is not supported in profiles for the 2014.7.x
|
|
release cycle and earlier, so it would still need to be provided on the
|
|
command-line.
|
|
|
|
|
|
Cloning an Existing Container
|
|
-----------------------------
|
|
|
|
To clone a container, use the :mod:`lxc.clone <salt.modules.lxc.clone>`
|
|
function:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.clone container2 orig=container1
|
|
|
|
|
|
Using a Container Image
|
|
-----------------------
|
|
|
|
While cloning is a good way to create new containers from a common base
|
|
container, the source container that is being cloned needs to already exist on
|
|
the minion. This makes deploying a common container across minions difficult.
|
|
For this reason, Salt's :mod:`lxc.create <salt.modules.lxc.create>` is capable
|
|
of installing a container from a tar archive of another container's rootfs. To
|
|
create an image of a container named ``cent6``, run the following command as
|
|
root:
|
|
|
|
.. code-block:: bash
|
|
|
|
tar czf cent6.tar.gz -C /var/lib/lxc/cent6 rootfs
|
|
|
|
.. note::
|
|
|
|
Before doing this, it is recommended that the container is stopped.
|
|
|
|
The resulting tarball can then be placed alongside the files in the salt
|
|
fileserver and referenced using a ``salt://`` URL. To create a container using
|
|
an image, use the ``image`` parameter with :mod:`lxc.create
|
|
<salt.modules.lxc.create>`:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.create new-cent6 image=salt://path/to/cent6.tar.gz
|
|
|
|
.. note:: Making images of containers with LVM backing
|
|
|
|
For containers with LVM backing, the rootfs is not mounted, so it is
|
|
necessary to mount it first before creating the tar archive. When a
|
|
container is created using LVM backing, an empty ``rootfs`` dir is handily
|
|
created within ``/var/lib/lxc/container_name``, so this can be used as the
|
|
mountpoint. The location of the logical volume for the container will be
|
|
``/dev/vgname/lvname``, where ``vgname`` is the name of the volume group,
|
|
and ``lvname`` is the name of the logical volume. Therefore, assuming a
|
|
volume group of ``vg1``, a logical volume of ``lxc-cent6``, and a container
|
|
name of ``cent6``, the following commands can be used to create a tar
|
|
archive of the rootfs:
|
|
|
|
.. code-block:: bash
|
|
|
|
mount /dev/vg1/lxc-cent6 /var/lib/lxc/cent6/rootfs
|
|
tar czf cent6.tar.gz -C /var/lib/lxc/cent6 rootfs
|
|
umount /var/lib/lxc/cent6/rootfs
|
|
|
|
.. warning::
|
|
|
|
One caveat of using this method of container creation is that
|
|
``/etc/hosts`` is left unmodified. This could cause confusion for some
|
|
distros if salt-minion is later installed on the container, as the
|
|
functions that determine the hostname take ``/etc/hosts`` into account.
|
|
|
|
Additionally, when creating an rootfs image, be sure to remove
|
|
``/etc/salt/minion_id`` and make sure that ``id`` is not defined in
|
|
``/etc/salt/minion``, as this will cause similar issues.
|
|
|
|
|
|
Initializing a New Container as a Salt Minion
|
|
=============================================
|
|
|
|
The above examples illustrate a few ways to create containers on the CLI, but
|
|
often it is desirable to also have the new container run as a Minion. To do
|
|
this, the :mod:`lxc.init <salt.modules.lxc.init>` function can be used. This
|
|
function will do the following:
|
|
|
|
1. Create a new container
|
|
2. Optionally set password and/or DNS
|
|
3. Bootstrap the minion (using either salt-bootstrap_ or a custom command)
|
|
|
|
.. _salt-bootstrap: https://github.com/saltstack/salt-bootstrap
|
|
|
|
By default, the new container will be pointed at the same Salt Master as the
|
|
host machine on which the container was created. It will then request to
|
|
authenticate with the Master like any other bootstrapped Minion, at which point
|
|
it can be accepted.
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.init test1 profile=centos
|
|
salt-key -a test1
|
|
|
|
For even greater convenience, the :mod:`LXC runner <salt.runners.lxc>` contains
|
|
a runner function of the same name (:mod:`lxc.init <salt.runners.lxc.init>`),
|
|
which creates a keypair, seeds the new minion with it, and pre-accepts the key,
|
|
allowing for the new Minion to be created and authorized in a single step:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt-run lxc.init test1 host=myminion profile=centos
|
|
|
|
|
|
Running Commands Within a Container
|
|
===================================
|
|
|
|
For containers which are not running their own Minion, commands can be run
|
|
within the container in a manner similar to using (:mod:`cmd.run
|
|
<salt.modules.cmdmod.run`). The means of doing this have been changed
|
|
significantly in version 2015.2.0 (though the deprecated behavior will still be
|
|
supported for a few releases). Both the old and new usage are documented
|
|
below.
|
|
|
|
2015.2.0 and Newer
|
|
------------------
|
|
|
|
New functions have been added to mimic the behavior of the functions in the
|
|
:mod:`cmd <salt.modules.cmdmod>` module. Below is a table with the :mod:`cmd
|
|
<salt.modules.cmdmod>` functions and their :mod:`lxc <salt.modules.lxc>` module
|
|
equivalents:
|
|
|
|
|
|
======================================= ====================================================== ===========================================================
|
|
Description :mod:`cmd <salt.modules.cmdmod>` module :mod:`lxc <salt.modules.lxc>` module
|
|
======================================= ====================================================== ===========================================================
|
|
Run a command and get all output :mod:`cmd.run <salt.modules.cmdmod.run>` :mod:`lxc.cmd_run <salt.modules.lxc.cmd_run>`
|
|
Run a command and get just stdout :mod:`cmd.run_stdout <salt.modules.cmdmod.run_stdout>` :mod:`lxc.cmd_run_stdout <salt.modules.lxc.cmd_run_stdout>`
|
|
Run a command and get just stderr :mod:`cmd.run_stderr <salt.modules.cmdmod.run_stderr>` :mod:`lxc.cmd_run_stderr <salt.modules.lxc.cmd_run_stderr>`
|
|
Run a command and get just the retcode :mod:`cmd.retcode <salt.modules.cmdmod.retcode>` :mod:`lxc.cmd_retcode <salt.modules.lxc.cmd_retcode>`
|
|
Run a command and get all information :mod:`cmd.run_all <salt.modules.cmdmod.run_all>` :mod:`lxc.cmd_run_all <salt.modules.lxc.cmd_run_all>`
|
|
======================================= ====================================================== ===========================================================
|
|
|
|
|
|
2014.7.x and Earlier
|
|
--------------------
|
|
|
|
Earlier Salt releases use a single function (:mod:`lxc.run_cmd
|
|
<salt.modules.lxc.run_cmd>`) to run commands within containers. Whether stdout,
|
|
stderr, etc. are returned depends on how the function is invoked.
|
|
|
|
|
|
To run a command and return the stdout:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.run_cmd web1 'tail /var/log/messages'
|
|
|
|
To run a command and return the stderr:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.run_cmd web1 'tail /var/log/messages' stdout=False stderr=True
|
|
|
|
To run a command and return the retcode:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.run_cmd web1 'tail /var/log/messages' stdout=False stderr=False
|
|
|
|
To run a command and return all information:
|
|
|
|
.. code-block:: bash
|
|
|
|
salt myminion lxc.run_cmd web1 'tail /var/log/messages' stdout=True stderr=True
|
|
|
|
|
|
Container Management Using States
|
|
=================================
|
|
|
|
Several states are being renamed or otherwise modified in version 2015.2.0. The
|
|
information in this tutorial refers to the new states. For
|
|
2014.7.x and earlier, please refer to the :mod:`documentation for the LXC
|
|
states <salt.states.lxc>`.
|
|
|
|
|
|
Ensuring a Container Is Present
|
|
-------------------------------
|
|
|
|
To ensure the existence of a named container, use the :mod:`lxc.present
|
|
<salt.states.lxc.present>` state. Here are some examples:
|
|
|
|
.. code-block:: yaml
|
|
|
|
# Using a template
|
|
web1:
|
|
lxc.present:
|
|
- template: download
|
|
- options:
|
|
dist: centos
|
|
release: 6
|
|
arch: amd64
|
|
|
|
# Cloning
|
|
web2:
|
|
lxc.present:
|
|
- clone_from: web-base
|
|
|
|
# Using a rootfs image
|
|
web3:
|
|
lxc.present:
|
|
- image: salt://path/to/cent6.tar.gz
|
|
|
|
# Using profiles
|
|
web4:
|
|
lxc.present:
|
|
- profile: centos_web
|
|
- network_profile: centos
|
|
|
|
.. warning::
|
|
|
|
The :mod:`lxc.present <salt.states.lxc.present>` state will not modify an
|
|
existing container (in other words, it will not re-create the container).
|
|
If an :mod:`lxc.present <salt.states.lxc.present>` state is run on an
|
|
existing container, there will be no change and the state will return a
|
|
``True`` result.
|
|
|
|
The :mod:`lxc.present <salt.states.lxc.present>` state also includes an
|
|
optional ``running`` parameter which can be used to ensure that a container is
|
|
running/stopped. Note that there are standalone :mod:`lxc.running
|
|
<salt.states.lxc.running>` and :mod:`lxc.stopped <salt.states.lxc.stopped>`
|
|
states which can be used for this purpose.
|
|
|
|
|
|
Ensuring a Container Does Not Exist
|
|
-----------------------------------
|
|
|
|
To ensure that a named container is not present, use the :mod:`lxc.absent
|
|
<salt.states.lxc.absent>` state. For example:
|
|
|
|
.. code-block:: yaml
|
|
|
|
web1:
|
|
lxc.absent
|
|
|
|
|
|
Ensuring a Container is Running/Stopped/Frozen
|
|
----------------------------------------------
|
|
|
|
Containers can be in one of three states:
|
|
|
|
- **running** - Container is running and active
|
|
- **frozen** - Container is running, but all process are blocked and the
|
|
container is essentially non-active until the container is "unfrozen"
|
|
- **stopped** - Container is not running
|
|
|
|
Salt has three states (:mod:`lxc.running <salt.states.lxc.running>`,
|
|
:mod:`lxc.frozen <salt.states.lxc.frozen>`, and :mod:`lxc.stopped
|
|
<salt.states.lxc.stopped>`) which can be used to ensure a container is in one
|
|
of these states:
|
|
|
|
.. code-block:: yaml
|
|
|
|
web1:
|
|
lxc.running
|
|
|
|
# Restart the container if it was already running
|
|
web2:
|
|
lxc.running:
|
|
- restart: True
|
|
|
|
web3:
|
|
lxc.stopped
|
|
|
|
# Explicitly kill all tasks in container instead of gracefully stopping
|
|
web4:
|
|
lxc.stopped:
|
|
- kill: True
|
|
|
|
web5:
|
|
lxc.frozen
|
|
|
|
# If container is stopped, do not start it (in which case the state will fail)
|
|
web6:
|
|
lxc.frozen:
|
|
- start: False
|