Experimenting with OpenDJ in CoreOS / Docker

CoreOS is new minimal Linux based OS designed to run applications in containers.  The design concept is similar to Joyent's SmartOS (aside: I would love to see the CoreOS team adopt ZFS. It has so many compelling features for hosting containers. But I digress...)

CoreOS uses Docker lightweight containers, which are in turn based on Linux LXC containers. You will want to check out the excellent getting started guide, but the readers digest summary is that Docker containers are built up incrementally and inherit from their parent containers.  Each new container contains only the deltas from the parent - making it possible to distribute a small incremental feature set.

When you run a Docker container, you are running only the processes that are needed for your service (for example, OpenDJ). You are not running an entire copy of the OS, making these containers super lightweight (OpenSolaris fans have had this feature for years in the form of zones).

For my OpenDJ experiments, I started with a Fedora 20 docker image:

docker pull mattdm/fedora:f20 

That command pulls down the image from the Docker repository.  You can start a shell on that image by running:

docker run -i -t mattdm/fedora:f20 /bin/bash

In the shell we can install additional packages using yum. For example:

yum install java-1.7.0-openjdk-devel.x86_64
curl -O http://download.forgerock.org/downloads/opendj/20131204020001/opendj-2.7.0-1.20131204.noarch.rpm
yum install opendj-2.7.0-1.20131204.noarch.rpm
cd /opt/opendj
.... continue OpenDJ install...

If we exit our bash shell at this point we will find that our changes vanish.  To persist these changes we must create a new container. In a second coreOS shell, we use:

docker commit 4ee0ae2b1bb1 wstrange/f20dj

This command tells Docker to create a new container. The container id from above came from the "docker ps" command and represents our (still) running container. The new container is saved to a container named wstrange/f20dj. 

This new container will provide the JDK and OpenDJ.  Under the covers, the container requires only the incremental bits that we added on top of the original Fedora 20 image. 

Now that we have a new image, we can fire up an instance of OpenDJ:

docker run -p 3389:389 -p 4444:4444 -p 8989:8989  -d wstrange/f20dj /opt/opendj/bin/start-ds -N

This tells Docker to start the container and run the "start-ds" command to start OpenDJ. 

Docker containers are NATed by default. The -p options is used to redirect local ports to container ports. In the above example, DJ listens on port 389. This is wired to port 3389 on our host. We set up redirection for 4444 (management) and 8989 (replication) as well. 

At this time should be able to fire up your favourite LDAP browser and connect to port 3389.

Now let's have some fun with replication. To replicate we need a second DJ installation. That turns out to be quite easy:

docker run -p 4389:389 -p 4446:4444 -p 8988:8989  -d wstrange/f20dj /opt/opendj/bin/start-ds -N

You will note that we simply fire up a second instance of our DJ container - changing the port numbers so that we do not collide with our first instance.  We now have two instances running:

docker ps
CONTAINER ID        IMAGE                   COMMAND                CREATED             STATUS              PORTS                                                                   NAMES
7ce9a470f422        wstrange/f20dj:latest   /opt/opendj/bin/star   46 minutes ago      Up 46 minutes>389/tcp,>4444/tcp,>8989/tcp   berserk_darwin       
8c1c4160f01f        wstrange/f20dj:latest   /opt/opendj/bin/star   46 minutes ago      Up 46 minutes>389/tcp,>4444/tcp,>8989/tcp   romantic_engelbart   

And sure enough, if you connect your LDAP browser to port 4389, you can browse the second DJ server. 

But wouldn't it be nice to enable replication between those instances?   Let's create another interactive container so we can get access to the OpenDJ commands:

docker run  -i -t wstrange/f20dj /bin/bash  

Now we enable replication between the two instances:

# This is our HOST only network for our containers
export HOST=
# enable replication
bin/dsreplication enable --host1  $HOST --port1 4444\
  --bindDN1 "cn=directory manager" \
  --bindPassword1 password --replicationPort1 8989 \
  --host2 $HOST --port2 4446 --bindDN2 "cn=directory manager" \
  --bindPassword2 password --replicationPort2 8988 \
  --adminUID admin --adminPassword password --baseDN "dc=example,dc=com" -X -n

# initialize replication
bin/dsreplication initialize --baseDN "dc=example,dc=com" \
  --adminUID admin --adminPassword password \
  --hostSource $HOST --portSource 4444 \
  --hostDestination $HOST --portDestination 4446 -X -n

[Note: For reasons that escape me, the dsreplication command must be issued twice. You will get an error on the first try - but the second attempt will work]

You now have two OpenDJ instances that are replicating between each other. Try this out by changing an entry on one instance and verifying that it is updated on the other (DJ has multi-master replication - so it does not matter where you make the change). 

The next step in this experiment will be to automate more of the above using Ansible.  A task for another day...

Post a Comment

Popular posts from this blog

OAM R2 REST APIs for Policy Management

SAML Federation in OAM 11g R2

Apache reverse proxy with LDAP authentication