by Ginny Henningsen
This article describes typical use cases for Linux containers (LXC) and Docker containers, and provides quick-reference guides for common LXC and Docker commands.
Table of Contents
Choosing a Container Technology
Container Technologies: The Basics
Important LXC and Docker Concepts
"Best Fit" Use Cases
LXC Commands Quick Reference
Docker Commands Quick Reference
About the Author
Choosing a Container Technology
Why should you deploy applications in a container? There are well-known benefits associated with container technologies: the ability to sandbox running applications, control system resources, and easily replicate application environments to speed deployments. But deciding which technology to select for application delivery on Oracle Linux—LXC or Docker—requires some thought. While there are advantages with respect to each container technology, there really is no single "best" choice—the optimal solution depends on the specific application and requirements. In other words, your best choice is truly the technology that's the best fit for the task at hand.
This article explores LXC and Docker container technologies to help IT administrators understand their similarities and differences, as well as typical use cases. When the time comes to use either LXC or Docker, this article also includes a handy quick reference "cheat sheet" containing sample commands for commonly performed tasks.
Container Technologies: The Basics
Let's take a quick look at the similarities and differences between LXC and Docker containers and how they differ from well-established hypervisor technologies (such as Xen, Microsoft Hyper-V, or VMware's ESXi). As shown in Figure 1, traditional virtualization solutions implement the hypervisor as an additional software layer on top of the native host operating system. The hypervisor supports multiple virtual machine (VM) guests, performing hardware emulation to access underlying physical server resources. The additional work of emulation imposes some degree of performance overhead, which is why LXC and Docker containers are considered a lighter-weight approach to isolating applications in comparison to conventional virtualization solutions.
Figure 1. LXC and Docker containers versus hypervisor-based virtualization.
With traditional virtualization solutions, each VM guest contains an isolated, full-blown operating system instance with its own OS kernel and user space. This allows a single physical machine to support applications running simultaneously on completely different operating systems while fully sandboxing them from one another. As an example, Oracle VM (which uses the Xen hypervisor) can support applications that run within separate Linux, Oracle Solaris, and Microsoft Windows guest VMs.
In contrast, LXC containers share the same kernel space (with the same drivers and kernel modules) as the host operating system, but each container has its own isolated user space (Figure 1). LXC containers take advantage of the cgroups resource management and namespace capabilities in Linux, which is how LXC containers implement resource control and isolation.
LXC containers can be deployed in two different ways, either as application or as system containers (although they are primarily deployed as system containers):
- LXC application containers can isolate a single application, similar to a
chrootjail. Application containers make it easy to scale an application or a service, because additional container instances can be deployed quickly in a cookie-cutter fashion to meet demand. LXC application containers share the host's root file system and are created with
lxc-execute, which runs a cut-down version of
init. Because Docker containers provide similar application container functionality and offer other advantages, Docker containers are typically implemented rather than LXC for use cases where application containers are the best fit.
- LXC system containers are the typical use case for LXC containers. Each LXC system container runs an
initprocess that provides an isolated execution environment, enabling support for a complete multiprocess application stack. Like a hypervisor-based virtualization solution, LXC system containers provide sandboxing of the entire stack—processes running in one container can't see or impact processes running in another. But unlike a hypervisor-based virtualization solution using VMware ESXi, Microsoft Hyper-V, or Oracle VM, LXC containers can support only Linux guest VMs that use the host's kernel and device drivers.
A Docker container is an application container best suited for a single application or service. Unlike an LXC system container, a Docker container does not run a separate
init process, so a single container can't easily host a multitiered stack. Instead, multiple Docker containers (each running a separate service or application) must be connected to one another to construct a full multitiered stack. Docker containers are ideally suited for isolating a service, such as a web service, and container instances can be easily cloned to scale the service and support greater capacity.
Docker containers are built using file system layers that capture the complete application environment into a virtual container. The base Docker container image consists of OS binaries and libraries. When the base image is modified—typically by installing application packages and configuring software—the new container shares the same binaries and libraries as the base, as depicted in Figure 1.
Docker containers are managed and run by the Docker Engine, which makes system calls to the underlying OS kernel. You can define a small text file (a Dockerfile) that captures the application container and all of its dependencies. This file can then be moved to any system that has a Docker Engine and be rebuilt, greatly simplifying application portability. At this time, Docker Engines are available for all major Linux distributions and Microsoft operating systems. The ability to capture an application, its environment, and all dependencies and move that across platforms is a significant difference in comparison to Linux-only LXC containers.
Important LXC and Docker Concepts
Because they are both lightweight virtualization tools, LXC and Docker containers have some notable similarities. Unlike a traditional hypervisor-based approach, LXC containers don't require the duplication of a full operating system installed as a guest, and Docker containers rely on efficiently layered images. Both LXC and Docker containers are open source–based, taking advantage of private Linux namespaces to sandbox applications and Linux cgroups to enable resource allocations and limits. And with both technologies, each container gets its own networking stack—a private network interface with a virtual bridge that allows the container to communicate while providing a separate VLAN. On Linux systems, both LXC and Docker containers can leverage an underlying Btrfs file system for fast snapshots, which helps to create new Docker image layers quickly or copy a root file system rapidly when you are cloning an LXC container.
LXC and Docker containers also feature some significant differences—even beyond the prominent difference of an LXC system container supporting an
init process while a Docker container does not. Docker containers are built from previously captured Docker images (Figure 2). Images can be downloaded from (as well as published to) a Docker registry, either the public Docker Hub Registry maintained by Docker, Inc. or a privately maintained local registry. Oracle publishes images for various distribution versions of Oracle Linux 6, Oracle Linux 7, and MySQL to the Docker Hub Registry, and these can be freely downloaded and run as a base layer of a Docker container.
Docker captures all changes made to a base image (such as installing application packages, resolving dependencies, and configuring settings), and you can commit these changes to build a new container image. To save space, Docker stores only changes to a base image in layers to reconstruct the full container image. You can build and run a container image interactively in the Docker Engine, but more commonly, a Dockerfile is defined to build the container image and run the application.
Figure 2. Docker captures changes to a container image and uses layers to efficiently reconstruct a container.
As an example, Figure 2 depicts a container image created on the local host by pulling an Oracle Linux 6.5 image from the Docker Hub Registry. The following
docker run command runs the base Oracle Linux 6.5 image as a container named ContainerA, executing
/bin/bash. Running the shell allows the user to then interactively install packages in the container.
# docker run -i -t --name ContainerA oraclelinux:6.5 /bin/bash
Suppose the administrator configures this Oracle Linux 6.5 image by installing Apache web server packages and web server content. Once the container is installed and configured, the configuration can be committed as follows, generating a new Docker image named ContainerAprime:
# docker commit -m "httpd installed" `docker ps -l -q` ContainerAprime
Figure 2 illustrates how Docker uses layering in container images—the A' image consists of the base Oracle Linux 6.5 image and changes made to that image to construct
ContainerAprime. To deploy three web servers, the Docker Engine can be given these commands to generate three containerized web servers from the same image:
# docker run -d --name websvr0 -p 8080:80 ContainerAprime /usr/sbin/httpd -D FOREGROUND
# docker run -d --name websvr1 -p 8081:80 ContainerAprime /usr/sbin/httpd -D FOREGROUND
# docker run -d --name websvr2 -p 8082:80 ContainerAprime /usr/sbin/httpd -D FOREGROUND
It's important to understand that Docker container storage is ephemeral. Docker containers are transient in nature and data does not persist beyond the lifespan of a container's execution. Associating a data volume with a container using the
-v flag allows the container to access, modify, and persist data on the host. For example, in the following command, the
-v flag causes the directory
/home/datadir on the host to be mounted as
/var/lib/mysql (the default database location for MySQL) on the container
# docker run --name db -d -e MYSQL_ROOT_PASSWORD=s5cr5t -v /home/datadir:/var/lib/mysql \
In contrast to the layering used to construct Docker images, LXC containers are built from template scripts that live on the underlying host Linux system in
/usr/share/lxc/templates. The Oracle Linux 7 distribution includes templates that can create user space containers for many common Linux distributions (including Oracle Linux, Fedora, Gentoo, Ubuntu, and so on). These template scripts configure an LXC container, defining a number of system settings (such as the host name, root file system location, white-listed cgroup devices, and network interface configurations) and container resources. The
lxc-oracle template also defines and sets default passwords for the
root users. The -t argument specifies the template to be used in creating the container:
# lxc-create -n ol7ctr1 -B btrfs -t oracle -- --release=7.latest
Rather than editing a given template, configuration files in
/usr/share/lxc/config can be used to tweak settings for a particular container type. It's also possible to modify configuration parameters (such as network settings) in a container-specific configuration file (such as
"Best Fit" Use Cases
There are a number of use cases that are well-suited for LXC containers, including the following:
- Running multiple Linux distributions and versions on the same machine. For example, on an Oracle Linux 7 host, applications can execute in LXC containers that run Oracle Linux 5, Oracle Linux 6, or Oracle Linux 7. Oracle tests and fully supports specific Oracle distribution versions as LXC containers (see "Supported Oracle Linux Container Versions" in the Oracle Linux documentation). This capability allows an existing application qualified on Oracle Linux 5, for example, to execute on an Oracle Linux 7 system. Templates are also provided for other Linux distributions (although these containers are not tested or supported by Oracle). Because LXC containers share the same kernel with the host, containerized applications cannot have any dependencies on release-specific drivers or kernel modules to function properly.
- Creating isolated environments for application development and Quality Assurance (QA) testing. LXC containers can be deployed as development and test sandboxes, effectively quarantining applications. Oracle Database 12c is fully supported on LXC containers (see the Supported Virtualization and Partitioning Technologies for Oracle Database and RAC Product Releases web page and the Oracle Database Release Notes for Linux). This support makes it easy to deploy isolated development and testing environments for Oracle Database. An LXC container created for development purposes can be easily and quickly cloned to replicate the environment for QA testing.
- Running a multitier software stack. Because LXC containers run an
initprocess, they can easily support a multitier stack such as LAMP (Linux, Apache, MySQL, Perl/PHP/Python) for deploying web services. Depending on the load and server resources, multiple copies of the stack can be replicated to provision additional servers, with each copy of the stack isolated from the others. Each container has its own IP address, which allows each web server to operate independently. In the event of compromise (such as a Denial of Service attack), each container instance is isolated.
- Creating environments that are subject to resource controls. Because LXC containers can use Linux control group mechanisms, it's possible to allocate and limit resources for applications within a container. For example, by limiting CPU shares or memory for containers that host noncritical workloads, an administrator can prevent resource starvation for critical workloads.
Docker application containers are well-suited to deploying a single application service, such web service deployments of NGINX, Apache, lighttpd, or other
httpd servers. By creating additional container instances, it's easy to scale service capacity and support additional demand—while at the same time isolating workloads for better service reliability.
Docker offers additional flexibility because it captures deployment requirements and dependencies, making it easy to move an application service to a different platform. Docker registries also provide mechanisms for application publishing and sharing. Developers can publish an application (including the full environment in which the application runs properly) internally to a corporate registry or publicly on the Docker Hub Registry.
Container technologies have substantial benefits, especially given the need to isolate applications to increase service levels. Both LXC and Docker containers provide application sandboxes so that if a security flaw is exploited or a containerized application is compromised, it's unable to affect other applications and services running in other containers. Clearly there are use cases in which lightweight LXC or Docker container technologies are a good fit.
The Oracle Linux documentation (the Oracle Linux Administrator's Solutions Guide for Release 6 or the Oracle Linux Administrator's Guide for Oracle Linux 7) has detailed sections on getting started with both LXC and Docker container technologies. There are also excellent resources for learning more about Docker at http://docs.docker.com/, including information on installing Docker on different operating systems, the Docker Engine User Guide, and the Docker reference manual.
To help you get started with LXC and Docker technologies, this appendix contains quick reference "cheat sheets." For both technologies, Table 1 and Table 2 list tasks that administrators frequently perform and an example of the appropriate command-line syntax.
LXC Commands Quick Reference
Table 1. Common LXC Tasks and Commands
|Install and configure LXC using the installation instructions for your OS. For optimal performance when cloning, create a Btrfs file system and mount it for LXC containers to use.|
See the chapter "Configuring Operating System Containers" in the Oracle Linux Administrator's Solutions Guide for Release 6 or the Oracle Linux Administrator's Guide for Oracle Linux 7.
|Run a |
|Create an Oracle Linux 6 system container named |
|Create the |
|Start the system container |
|Start the container |
|Log in to the container named |
|Snapshot the root file system of a container for later cloning.|
|Clone a container (method 1).|
|Clone a container (method 2) using a previously captured snapshot of its root file system.|
|List all LXC containers or list containers running on the host.|
|List usage statistics and the IP address for a container.|
|Attach to a running container from the host and run a command there.|
|Suspend or resume container execution.|
|Shut down a container after halting processes.|
|Shut down a container, terminating its processes immediately.|
|Monitor a container's state (for example, starting, running, stopping, stopped, and so on).|
|Display the CPU cores on which container processes can run.|
|Restrict container processes to run on the specified CPU cores.|
|Set a container's relative share of CPU time.|
|Limit a container to 256 MB when memory is low or contended; otherwise, set a hard limit of 512 MB.|
|Modify the file |
Docker Commands Quick Reference
Table 2. Common Docker Tasks and Commands
|Install and configure Docker using the installation instructions for your OS. For optimal performance in cloning, create a Btrfs file system and mount it for Docker containers to use.|
See the chapter “Installing and Configuring the Docker Engine on Oracle Linux 6” or “Installing and Configuring the Docker Engine on Oracle Linux 7” in the Oracle Linux Docker User's Guide.
|Display information about the host and the version of the Docker Engine.|
|Pull the Oracle Linux 6.6 image from the Docker Hub Registry.|
|Pull the latest Oracle Linux 7 image from the Docker Hub Registry.|
|Pull the latest MySQL image from the Docker Hub Registry.|
|Log in to the Docker Hub Registry as the user |
|Push an image to the Docker Hub Registry for the user |
|List the available images to run using the host's Docker Engine.|
|Create a container named |
|Show information about running containers or about all containers.|
|Show information about the most recently created container, displaying only its numeric ID.|
|Stop a running container named |
|Send the "hang up" (HUP) signal to a container.|
|Restart the container |
|Create a new image |
|Show the history of changes made to a Docker image.|
|Remove a container that is not currently running.|
|Remove a container image.|
|Run the NginX server as a background process.|
|Run the HTTP server with a relative weight of CPU shares (the value is relative to the default of 1024).|
|Run the HTTP server with memory limited to 12 MB (the minimum hard limit is 4 MB).|
|Run a MySQL server in a container named |
|List running processes in a container; display a live stream of container resource usage statistics.|
|Execute a command on a container, in this case, the container |
|Display information about a container, in this case, the IP address of the container |
|Save the container (and all of its layers) as a |
|Load a |
|Build a new Docker container image from a Dockerfile.|
|A simple Dockerfile example that configures and runs an Apache web server on an Oracle Linux 7 base image:|
Note: A more complex Dockerfile example is one that installs the Oracle WebLogic 12.2.1 Quick Install Distro, available here.
|Import a file system image from a local |
|Copy from a container to the local file system (perhaps to save output from a container application to the local host).|
|Copy files or directories from a local file system on the host into a container.|
About the Author
Ginny Henningsen has worked for the last 18 years as a freelance writer developing technical collateral and documentation for high-tech companies. Prior to that, Henningsen worked for Sun Microsystems, Inc. as a systems engineer in King of Prussia, Pennsylvania, and in Milwaukee, Wisconsin, with a focus on solution architectures, operating systems, and security. Henningsen has a BA from Carnegie-Mellon University and an MSCS from Villanova University.