Skip to Main Content

Infrastructure Software

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Interested in getting your voice heard by members of the Developer Marketing team at Oracle? Check out this post for AppDev or this post for AI focus group information.

Getting Started with Docker on Oracle Linux

unknown-1040115May 18 2015 — edited Aug 25 2016

by Ginny Henningsen

Learn how to customize a Docker container image and use it to instantiate application instances across different Linux servers. This article describes how to create a Dockerfile, how to allocate runtime resources to containers, and how to establish a communication channel between two containers (for example, between web server and database containers).

Introduction

The best system administrators I know are downright lazy. I mean "lazy" in a good way, though—they're experts at finding ways to work smarter, not harder. They're skilled at discovering new techniques and technologies that help them efficiently manage operations. It's no surprise that many of them are excited about Docker, an open source virtualization technology that creates lightweight Linux application containers.

Docker is exciting because it can easily capture a full application environment into a virtual container that can be deployed across different Linux servers. System administrators and software developers are learning that Docker can help them deploy application images on Linux quickly, reliably, and consistently—without dependency and portability problems that can inject delays into planned deployment schedules. Docker containers can define an application and its dependencies using a small text file (a Dockerfile) that can be moved to different Linux releases and quickly rebuilt, simplifying application portability. In this way, "Dockerized" applications are easily migrated to different Linux servers where they can execute on bare metal, in a virtual machine, or on Linux instances in the cloud.

Developers love Docker because they can capture the full software environment, including dependencies, and replicate it easily for testing. Administrators love it because it simplifies the task of deploying applications without having to worry about the configuration nuances of the target system. If you're already an Oracle Linux Premier Support customer, you'll love the fact that Oracle provides support for Docker application containers on Oracle Linux automatically, at no additional cost.

This article is designed to help you get a taste for how you can use Docker to simplify application provisioning on Linux. It demonstrates how to create a Docker container on Oracle Linux, modify it, and use it to instantiate multiple application instances. It also describes how to allocate system CPU and memory resources to a Docker container, how to set up a database container, and how other containers can connect to that database container. Because the Docker test environment that I created runs on Oracle Linux, this article also shows to use Ksplice to update the kernel without rebooting—while all of the Docker application containers continue to run.

Docker Lightweight Virtualization Containers

Docker containers are a lightweight virtualization technology for Linux. They provide isolation from other applications and processes running on the same system but make system calls to the same shared Linux kernel, similar to Linux LXC application containers. If you have a background in Oracle Solaris, Docker containers might remind you of non-global zones in Oracle Solaris 10 or 11, which provide application isolation while sharing an underlying Oracle Solaris operating system kernel. Docker containers have their own namespace, so they are fully isolated from one another—processes running in one container can't see or impact processes running in another. By default, each container gets its own networking stack, private network interfaces, and IP address, and Docker creates a virtual bridge so containers can communicate.

Shared container access to the underlying Linux kernel is one reason why Docker containers are deemed lightweight. When a Docker image is modified, the new container shares the same binaries and libraries as the base container, which contributes to a smaller overall footprint (Figure 1). In building and customizing containers, Docker also uses the concept of layering, storing only differences from the base container.

f1.gif

Figure 1. Docker containers versus hypervisor-based virtualization.

As shown in Figure 1, Docker containers consume fewer resources than "heavyweight" hypervisor-based solutions. Hypervisor-based solutions host a full-blown operating system instance in each virtual machine guest, but this also allows them to support different operating systems. (Oracle VM, for example, can host Oracle Linux, Oracle Solaris, and Microsoft Windows in virtual machines.)

Getting Started

In Figure 1, the Linux host runs the Docker Engine, a service that packages, manages, and executes Docker containers. To use Docker, the first step is to download and install the Docker Engine RPM packages. Oracle publishes Docker Engine RPMs for Oracle Linux 6 and Oracle Linux 7 on the public yum site and on the Unbreakable Linux Network (ULN).

Instructions for installing the Docker Engine are available in the Oracle Linux 6 Docker User's Guide, the Oracle Linux 7 Docker User's Guide, or in Avi Miller's blog article, "Ahoy! Cast Off with Docker on Oracle Linux". The initial steps are pretty simple: first enable the add-ons channel in /etc/yum.repos.d/public-yum-ol*.repo and then run yum install docker.

The resources above also describe how to configure Docker to use the Btrfs file system for storing container images. Because Btrfs has built-in snapshot capabilities, it is fast and efficient when replicating Docker container layers.

After configuring Docker to use Btrfs, initialize the Docker Engine service:

|

[root@ol7-host ~]# systemctl enable docker
[root@ol7-host ~]# systemctl start docker

|

The Docker Hub Registry (Figure 2) is a public cloud store of images hosted by Docker, Inc. that can be used to build running containers. Repositories provide a mechanism for Docker image distribution and sharing. Docker, Inc. also hosts private repositories for a monthly fee. Alternatively, you can create a private Docker Registry behind your own corporate firewall, implementing protection mechanisms, such as SSL encryption and HTTP authentication, to restrict and protect access.

f2_small.gif

Figure 2. The Docker Hub Registry stores preconfigured container images.

The following commands pull the Oracle Linux 6 and Oracle Linux 7 images from the public Docker Hub Registry, downloading them to the Oracle Linux host that's my test environment:

|

[root@ol7-host ~]# docker pull oraclelinux:6
Pulling repository oraclelinux 68f3f88739c9: Pulling dependent layers 511136ea3c5a: Download complete ad98bd7101f2: Download complete Status: Downloaded newer image for oraclelinux:6 [root@ol7-host ~]# docker pull oraclelinux:7
Pulling repository oraclelinux 3200155fe586: Download complete 511136ea3c5a: Download complete ad98bd7101f2: Download complete fa5a10a28322: Download complete Status: Downloaded newer image for oraclelinux:7

|

If no version number is specified in the docker pull command, then the latest available version is pulled from the Docker Hub repository (for example, at the time of this publication, the latest Oracle Linux version is actually Oracle Linux 7.1).

Oracle also publishes Docker container images for its verified version of MySQL on the public Docker Hub Registry (note that docker pull mysql will pull the Ubuntu version of MySQL):

|

[root@ol7-host ~]# docker pull mysql/mysql-server
Pulling repository mysql/mysql-server 296ef3e8959e: Download complete 32 B/32 B: Download complete ad98bd7101f2: Download complete 8f0a27825a9a: Download complete c94023a2b919: Download complete 92af7065aa1f: Download complete a81965d5ac77: Download complete be7d80f12dd8: Download complete 54c55eca1c4c: Download complete 45dd68192dba: Download complete d8aaad0b9379: Download complete Status: Downloaded newer image for mysql/mysql-server:latest

|

The command docker images lists the images available locally that I can run and customize:

|

[root@ol7-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mysql/mysql-server latest 461d07d927e6 10 days ago 283 MB oraclelinux 6.6 68f3f88739c9 4 weeks ago 161.9 MB oraclelinux 6 68f3f88739c9 4 weeks ago 161.9 MB oraclelinux 7 3200155fe586 5 weeks ago 195.1 MB oraclelinux 7.0 3200155fe586 5 weeks ago 195.1 MB oraclelinux latest 3200155fe586 5 weeks ago 195.1 MB

|

Customizing a Container for Application Provisioning

Suppose that I want to provision multiple, identical web servers across multiple Linux servers in my data center. Docker makes it easy to create a preconfigured, cookie-cutter environment in a container image. I can then use this prebuilt image and deploy it across one or many Linux hosts.

To build a customized container image, I must first build a guest container, install the web server, and configure it to deliver web server content. I use the docker run command to run an Oracle Linux 7 base container and execute a bash shell in the guest container:

|

[root@ol7-host ~]# docker run -i -t --name guest oraclelinux:7 /bin/bash
[root@f85d55a6893f /]#

|

The Docker Engine assigns an image ID to every running container instance. Because I used the arguments -i and -t, the bash shell runs interactively, and the prompt reflects the first 12 characters (f85d55a6893f) of my running container's image ID. The --name argument specifies a name for the running container instance. (If you choose not to enter a name, the Docker Engine generates a random string that incorporates the name of a notable scientist, inventor, or developer, such as evil_jones; sad_ritchie; sleepy_curie; and prickly_mestorf).

In a shell on my Linux host, the docker ps command shows information about the running guest container, including the shortened form of the image ID, the base image used to create this container, and the container name:

|

[root@ol7-host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES f85d55a6893f oraclelinux:7 "/bin/bash" 28 seconds ago Up 28 seconds guest

|

On the guest, I install the httpd and perl RPM packages using yum, just as I would on any other physical or virtual server. I also specify yum clean all to remove cache files that yum creates during package installation, because that will ultimately save some space in the exported container image:

|

[root@f85d55a6893f /]# yum install -y httpd perl && yum clean all
ol7_UEKR3 | 1.2 kB 00:00:00 ol7_latest | 1.4 kB 00:00:00 (1/5): ol7_UEKR3/x86_64/updateinfo | 24 kB 00:00:00 (2/5): ol7_latest/x86_64/group | 652 kB 00:00:01 (3/5): ol7_latest/x86_64/updateinfo | 348 kB 00:00:01 (4/5): ol7_UEKR3/x86_64/primary | 6.2 MB 00:00:05 (5/5): ol7_latest/x86_64/primary | 8.4 MB 00:00:06 ol7_UEKR3 149/149 ol7_latest 9226/9226 Resolving Dependencies . . . Installed: httpd.x86_64 0:2.4.6-31.0.1.el7 perl.x86_64 4:5.16.3-285.el7 Dependency Installed: apr.x86_64 0:1.4.8-3.el7 apr-util.x86_64 0:1.5.2-6.0.1.el7 httpd-tools.x86_64 0:2.4.6-31.0.1.el7 . . . Complete! Cleaning repos: ol7 UEKR3 ol7_latest Cleaning up everything

|

At this point, I can configure content for the web server to display. For simplicity, I'll create a basic opening page in the /var/www/html hierarchy on the guest:

|

[root@f85d55a6893f /]# echo "Example Web Server Content" > /var/www/html/index.html

|

My guest container is now configured with the software environment that I want. Typing exit stops the running guest, returning a prompt for the Linux host:

|

[root@f85d55a6893f /]# exit
exit [root@ol7-host ~]#

|

Now I want to create a new Docker image that reflects the contents of the guest container that I just configured. The following docker commit command captures the modified container into a new image named mycon/httpd:r1:

|

[root@ol7-host ~]# docker commit -m "OL7-httpd" `docker ps -l -q` mycon/httpd:r1
2fb1c664f394a9b2c5b9fbe2138754adc2c63fe4bdd1715bfbcebf0147981b3d

|

The commit command takes as input the image ID number of the guest container (f85d55a6893f, returned from the docker ps -l -q command) and assigns and returns an ID number for the new image. Running the docker images command now lists the new image, mycon/httpd, along with the Oracle Linux and MySQL images I pulled earlier from the public registry:

|

[root@ol7-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mycon/httpd r1 2fb1c664f394 About a minute ago 414.9 MB mysql/mysql-server latest 461d07d927e6 10 days ago 283 MB . . .

|

Now that I've built a new Docker image from the guest container, I no longer need the guest container:

|

[root@ol7-host ~]# docker rm guest

|

Because Docker containers persist even though they're no longer running, removing unneeded containers is simply a housekeeping step to reduce clutter on my host, and it allows me to reuse the name guest for a new container.

Deploying the Configured Docker Image

I can deploy any number of web servers now using the new Docker image as a template. The following docker run commands run the container image mycon/httpd, creating the containers guest1, guest2, and guest3 and executing httpd in each one:

|

[root@ol7-host ~]# docker run -d --name guest1 -p 8080:80 mycon/httpd:r1 \
/usr/sbin/httpd -D FOREGROUND
[root@ol7-host ~]# docker run -d --name guest2 -p 8081:80 mycon/httpd:r1 \
/usr/sbin/httpd -D FOREGROUND
[root@ol7-host ~]# docker run -d --name guest3 -p 8082:80 mycon/httpd:r1 \
/usr/sbin/httpd -D FOREGROUND

|

The -p argument maps port 80 in each guest to ports 8080, 8081, or 8082 on the host. The docker ps command shows the running guests:

|

[root@ol7-host ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES af521fe5c96f mycon/httpd:r1 "/usr/sbin/httpd -D 5 seconds ago Up 4 seconds 0.0.0.0:8082-> 80/tcp guest3 e6320d4adf50 mycon/httpd:r1 "/usr/sbin/httpd -D 8 seconds ago Up 9 seconds 0.0.0.0:8081-> 80/tcp guest2 603c6d5db100 mycon/httpd:r1 "/usr/sbin/httpd -D 2 minutes ago Up 2 minutes 0.0.0.0:8080-> 80/tcp guest1

|

The default IP address value of 0.0.0.0 means that the port mapping applies to all network interfaces on the host. To access the running guest containers, you might need to enable firewall access first. On an Oracle Linux 7 host, I can use firewall-cmd (rather than using iptables, as you would for Oracle Linux 6):

|

[root@ol7-host ~]# firewall-cmd --add-port=8080/tcp --add-port=8081/tcp --add-port=8082/tcp
success

|

Using a web browser or curl, I can test the web server running in each guest:

|

[root@ol7-host ~]# curl http://ol7-host:8080
Example Web Server Content [root@ol7-host ~]# curl http://ol7-host:8081
Example Web Server Content [root@ol7-host ~]# curl http://ol7-host:8082
Example Web Server Content

|

Docker containers can communicate to other containers and hosts through a virtual bridge created by the Docker Engine. By default, the virtual bridge is named docker0 and assigned a random IP address from a range not in use on the host:

|

[root@ol7-host ~]# ifconfig -a
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.42.1 netmask 255.255.0.0 broadcast 0.0.0.0 inet6 fe80::5484:7aff:fefe:9799 prefixlen 64 scopeid 0x20<link> ether 56:84:7a:fe:97:99 txqueuelen 0 (Ethernet) . . .

|

The Docker Engine also assigns each running container a virtual network interface, which you can see with the docker inspect command:

|

[root@ol7-host ~]# docker inspect -f '{{ .NetworkSettings.IPAddress }}' guest1
172.17.0.2

|

Publishing and Porting

I can now easily move my web server container to another machine and run it there. If I push the Docker image mycon/httpd to a Docker registry, I can then pull it to any other Linux machine running a Docker Engine. I can also backup the image to a tar file using the docker save command:

|

[root@ol7-host ~]# docker save -o webserver.tar mycon/httpd:r1

|

I can move the tar file to another host and load the image into that host's Docker Engine:

|

[root@another-host ~]# docker load -i webserver.tar
[root@another-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mycon/httpd r1 2fb1c664f394 About a minute ago 414.9 MB oraclelinux 7 3200155fe586 5 weeks ago 195.1 MB oraclelinux 7.0 3200155fe586 5 weeks ago 195.1 MB oraclelinux latest 3200155fe586 5 weeks ago 195.1 MB

|

Using a Dockerfile

Now that you've seen how to create and manipulate Docker containers using the command line, the preferred way to build and customize containers is actually using Dockerfiles. A Dockerfile is a small text file that contains the instructions required to construct a container. When a Dockerflle is built, each instruction adds a layer to the container in a step-by-step process. The build creates a container, runs the next instruction in that container, and then commits the container. Docker then runs the committed image as the basis for adding the next layer. The benefit of this layered approach is that Dockerfiles with the same initial instructions reuse layers.

Dockerfiles also create an easily readable and modifiable record of the steps used to create a Docker image. Publishing a Dockerfile to the public Docker Hub or to an internal repository is generally the preferred method of creating and sharing Docker images.

To create a Dockerfile, first create a directory for it:

|

[root@ol7-host ~]# mkdir /home/Dockerf-web
[root@ol7-host ~]# cd !$

|

In that directory, use a text editor to create a file called Dockerfile that contains the following contents:

|

# Dockerfile for creating a Docker image for OL 7 and httpd and perl

FROM oraclelinux:7

MAINTAINER E. Jones <ejones@email-address.com>

RUN yum install -y httpd perl && yum clean all

RUN echo "Example Web Server Content" > /var/www/html/index.html

EXPOSE 80

CMD /usr/sbin/httpd -D FOREGROUND

|

This Dockerfile reflects the same steps as the example in which I manually built the Docker image for my web server—it configures a new container from a base Oracle Linux 7 image, installs the httpd and perl RPMs, and adds placeholder content for the opening web page.

The docker build command constructs a new Docker image from this Dockerfile, creating and removing temporary containers as needed during its step-by-step build process:

|

[root@ol7-host Dockerf-web]# docker build -t mycon/httpd:r2 .
Sending build context to Docker daemon 2.56 kB

Sending build context to Docker daemon

Step 0 : FROM oraclelinux:7 ---> 3200155fe586

Step 1 : MAINTAINER E. Jones <ejones@email-address.com>

---> Running in ed340c7747a2

---> 243472b305b6

Removing intermediate container ed340c7747a2

Step 2 : RUN yum install -y httpd perl && yum clean all

---> Running in ff8c659c6cac

Resolving Dependencies . . . Complete!

Cleaning repos: ol7 UEKR3 ol7_latest

Cleaning up everything

---> dfc8af8ff45c

Removing intermediate container ff8c659c6cac

Step 3 : RUN echo "Example Web Server Content" > /var/www/html/index.html

---> Running in aefb62199d66

Example Web Server Content

---> b0fea1180c8e

Removing intermediate container aefb62199d66

Step 4 : EXPOSE 80

---> Running in df6b1f699468

---> fe4c4ce82aa3

Removing intermediate container df6b1f699468

Step 5 : CMD /usr/sbin/httpd -D FOREGROUND

---> Running in 141571047fdc

---> 16e2d42c3acf

Removing intermediate container 141571047fdc

Successfully built 16e2d42c3acf

|

The docker images command lists the new mycon/httpd:r2 image created from the Dockerfile:

|

[root@ol7-host ~]# docker images
REPOSITORY TAG IMAGE ID CREATED VIRTUAL SIZE mycon/httpd r2 16e2d42c3acf 16 minutes ago 420 MB mycon/httpd r1 2fb1c664f394 22 hours ago 414.9 MB . . .

|

More information is available in the Dockerfile reference guide and in the article "Best practices for writing Dockerfiles."

Limiting Runtime Resources

A Docker container uses underlying control group (cgroup) technologies, creating a cgroup for each Docker container. Cgroups provide useful capabilities, such as collecting metrics for CPU, memory, and block I/O usage and providing resource management capabilities. For each Docker container, you can find metrics in the host's corresponding cgroup hierarchy; for example, on an Oracle Linux 7 host running the Unbreakable Enterprise Kernel Release 3 (UEKR3), a memory.stat file in the directory /sys/fs/cgroup/memory/system.slice/docker-<container ID> lists memory-related metrics for that container. (See the blog article "Gathering LXC and Docker containers metrics.")

The docker run command provides options that enable runtime limits for memory and relative CPU allocations. These options provide a degree of resource control when executing container images. The -m or --memory option limits the amount of physical and swap memory available to processes within a container. For example, the following command places a limit of 256 MB for physical memory (and up to 512 MB for memory plus swap):

|

[root@ol7-host ~]# docker run -d --memory=256m --name guest1 -p 8080:80 mycon/httpd:r2
c9f26a16a4b701b8cb3bcfebb7f8dd90accc906440acb22ba3d33f5ca55a1e85

|

The -c or --cpushares option provides a method of assigning a relative number of CPU shares:

|

[root@ol7-host ~]# docker run -d --cpushares=512 --name guest2 -p 8080:80 mycon/httpd:r2
d7479853f7d1a797e663199809f462e6fcc30f306236d7895814c7825df5f9fa

|

By default, a container gets 1024 CPU shares, so in this example, the guest2 container gets a relative 50 percent share of the available computing resources. Note that the host kernel applies limits only when there is resource contention. For example, if guest2 is assigned 512 shares (50 percent, as shown above) and guest1 is assigned 1024 shares (100 percent), processes in guest2 will still get 100 percent of the available CPU resources if all guest1 processes are idle.

For more information about options to the docker run command, enter docker run --help or see the Docker run reference guide.

Connecting a Web Server Container to a MySQL Container

Suppose I want to connect my web server container to a container running an instance of MySQL. Docker makes it possible to link containers together, creating a secure channel for one container to access certain information from another.

Previously I pulled the Oracle-verified MySQL image from the Docker Hub using the command docker pull mysql/mysql-server. To run the MySQL image as a container named db, I enter the following command:

|

[root@ol7-host ~]# docker run --name db -d -e MYSQL_ROOT_PASSWORD=s5cr5t \
-v /home/datadir:/var/lib/mysql mysql/mysql-server:db1

|

The -d flag starts the db container in detached or background mode. The -e switch passes the environment variable MYSQL_ROOT_PASSWORD to the container.

Using the -v or --volume flag is how you can associate database storage (or, in general, any files or folders) that a Docker container needs to change while it's running. Remember that Docker containers are "ephemeral"—that is, they 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.

Reminiscent of an NFS mount, 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. From an operational standpoint, the ability to mount a database directory as a container volume in this way also provides an easy way to enable database backups.

The Docker Hub mysql/mysql-server image includes an entrypoint script (entrypoint.sh) that sets up the database server automatically, initializing mysqld. I can view log messages generated from a container using the docker logs command:

|

[root@ol7-host ~]# docker logs db
Running mysql_install_db 2015-04016 05:48:31 0 [Warning] TIMESTAMP with implicit DEFAULT value is deprecated. Please use -explicit_defaults_for_timestamp server option (see documentation for more details). 2015-04016 05:48:31 0 [Note] /usr/bin/mysqld (mysqld 5.6.24) starting as process 22 ... PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER ! ... Finished mysql_install_db MYSQL init process in progress... MYSQL init process in progress... MYSQL init process in progress... MYSQL init process done Ready for start up. 2015-04016 05:48:44 0 [Note] /usr/bin/mysqld (mysqld 5.6.24) starting as process 1 ...

|

I can execute a bash shell to investigate the running MySQL container further. Because I mounted the data directory /home/datadir on the host as /var/lib/mysql on the container, I can see the sample database file mysqlsampledatabase.sql that I previously placed in /home/datadir:

|

[root@441db2bac0b1 /]# docker exec -it db bash
[root@441db2bac0b1 /]# ls /var/lib/msql
auto.cnf ibdata1 mysqlsampledatabase.sql ib_logfile0 mysql mysqlsampledatabase.zip ib_logfile0 mysql.sock performance_schema

|

By running the MySQL monitor in the guest container, I can connect to the database server and load the sample database. By default, the Docker image mysql/mysql-server exposes port 3306 (the standard MySQL port) for database access:

|

[root@441db2bac0b1 /]# mysql -h 127.0.0.1 -u root -p
Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 2 Server version: 5.6.24 MySQL Community Server (GPL) Copyright © 2000, 2015, Oracle and/or its affiliates. . . . Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> source /var/lib/mysqlsampledatabase.sql
Query OK, 0 rows affected (0.06 sec) Query OK, 2996 rows affected (0.25 sec) Records: 2996 Duplicates: 0 Warnings 0 . . . Query OK, 110 rows affected (0.25 sec) Records: 110 Duplicates: 0 Warnings 0 Query OK, 0 rows affected (0.00 sec) mysql> quit
Bye [root@441db2bac0b1 /]#

|

By linking containers using the --link flag, other application containers can access the MySQL database running in the db container. This simplifies the separation of database, application, and web services, making it easier to isolate services in different containers. I can run my web server image as a container and connect it to the database container using the following command:

|

[root@ol7-host ~]# docker run -d --name web1 -v /home/webdir -p 80:80 \
--link db:db mycon/httpd:r2
1d99444c4f536a4b7accc906440acb22ba3d33f5c2c63fe4bdd3a55a1e850e0d

|

Assuming I've configured /etc/httpd/conf/httpd.conf to allow CGI script execution on the web server and I created a Perl script to perform some kind of SQL query, I can run queries against the database in the db container (note that I can use the docker inspect command to obtain the web server IP address I need for the query):

|

[root@ol7-host ~]# curl http://172.17.0.23/cgi-bin/doquery.pl?150
+---------------------------+ | customerName | +---------------------------+ | Atelier graphique | | La Rochelle Gifts | | Savely & Henriot, Co. | | ... +---------------------------+ 12 rows in set (0.00 sec)

|

The Oracle Linux documentation includes a detailed example of how to link a web container with a MySQL database, and it provides sample scripts that configure httpd.conf, create a database, and perform queries. Additional background on linking containers and using data volumes is available there and also in the Docker user guide.

Using Ksplice

Because the host for my Docker test environment is running Oracle Linux, this article wouldn't be complete without a discussion of using Ksplice. Ksplice can perform kernel updates on Oracle Linux without the need to reboot. If I were deploying web and database servers in a production environment using Docker containers, this means that I could apply the latest security errata or kernel updates without having a planned outage. The Docker containers, web servers, and database services (or whatever workloads are running in my containers) can continue to function without interruption.

Ksplice is included with an Oracle Linux Premier Support contract, which also includes support for Docker at no additional charge. Oracle offers a 30-day trial version of Ksplice for the Unbreakable Enterprise Kernel or the Red Hat Compatible Kernel (RHCK).

Logging into my Oracle SSO account, I follow the installation instructions provided to install the Ksplice packages on my Linux host:

|

[root@ol7-host ~] wget -N https://www.ksplice.com/uptrack/install-uptrack
[root@ol7-host ~] sh install-uptrack \
881f3ce6da85b13f0c1845f591cfa0770c064e19d458270bc3ee0acd0015aa4c
[ Release detected: ol ] --2015-03-04 20:16:39-- https://www.ksplice.com/yum/uptrack/ol/ksplice-uptrack-release.noarch.rpm Resolving www.ksplice.com (www.ksplice.com)... 137.254.56.32 . . . Installed: uptrack.noarch 0:1.2.24-0.el7 Dependency Installed: PyYAML.x86_64 0:3.10-11.el7 libyaml.x86_64 0:0.1.4-11.el7_0 perl-autodie.noarch 0:2.16-2.el7 Complete! Effective kernel version is 3.8.13-55.1.5.el7uek Nothing to be done. [ Installation Complete! ] [ Please run '/usr/sbin/uptrack-upgrade -y' to bring your system up to date ]

|

Once the Ksplice uptrack program is installed, I can use it to perform a rebootless upgrade:

|

[root@ol7-host ~] /usr/sbin/uptrack-upgrade -y
The following steps will be taken: Install [kxc75rp4] CVE-2014-7825, CVE-2014-7826: Perf DoS and local privilege escalation. Install [nwr7zb2b] CVE-2014-8160: iptables rules by-pass when the protocol module is not loaded. . . . Installing [kxc75rp4] CVE-2014-7825, CVE-2014-7826: Perf DoS and local privilege escalation. Installing [nwr7zb2b] CVE-2014-8160: iptables rules by-pass when the protocol module is not loaded. . . . Installing [lrex34wm] Multiple NULL pointers dereference in Emulex LightPulse SCSI driver. Your kernel is fully up to date. Effective kernel version is 3.8.13-68.el7uek

|

In the meantime, the Docker containers are still running on this system:

|

[root@ol7-host ~] # docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 441db2bac0b1 mysql/mysql-server:latest "/entrypoint.sh mysq 2 hours ago Up 1 hour 3036/tcp->80/tcp db 06517cd0a7bd mycon/httpd:r2 "/bin/sh -c '/usr/sb 2 hours ago Up 2 hours 0.0.0.0:8082->80/tcp guest3 d7479853f7d1 mycon/httpd:r2 "/bin/sh -c '/usr/sb 3 hours ago Up 3 hours 0.0.0.0:8081->80/tcp guest2 154293f56f74 mycon/httpd:r2 "/bin/sh -c '/usr/sb 4 hours ago Up 4 hours 0.0.0.0:8080->80/tcp guest1

|

Learn More

In addition to the Oracle Linux documentation on Docker, there are excellent resources for learning more about Docker at http://docs.docker.com/ including information on installing Docker on different Linux operating systems. An application called Boot2Docker even runs a lightweight Linux VM and a Docker daemon on Mac OS X and Microsoft Windows. The Docker user guide and Docker reference manual are also excellent references.

About the Author

Ginny Henningsen has worked for the last 17 years as a freelance writer developing technical collateral and documentation for high-tech companies. Prior to that, Ginny worked for Sun Microsystems, Inc. as a Systems Engineer in King of Prussia, PA and Milwaukee, WI. Ginny has a BA from Carnegie-Mellon University and an MSCS from Villanova University.

| Revision 1.0, 05/06/2015 |

Follow us:
Blog | Facebook | Twitter | YouTube

Comments
Post Details
Added on May 18 2015
2 comments
32,867 views