Barely Functional Keystone Deployment with Docker

My eventual goal is to deploy Keystone using Kubernetes. However, I want to understand things from the lowest level on up. Since Kubernetes will be driving Docker for my deployment, I wanted to get things working for a single node Docker deployment before I move on to Kubernetes. As such, you’ll notice I took a few short cuts. Mostly, these involve configuration changes. Since I will need to use Kubernetes for deployment and configuration, I’ll postpone doing it right until I get to that layer. With that caveat, let’s begin.

My last post showed how to set up a database and talk to it from a separate container. After I got that working, it stopped, so I am going to back off that a bit, and just focus on the other steps. I do know that the issue was in the setup of the separate Bridge, as when I changed to using the default Bridge network, everything worked fine.

Of the many things I skimped on, the most notable is that I am not doing Fernet tokens, nor am I configuring the Credentials key. These both require outside coordination to have values synchronized between Keystone servers. You would not want the secrets built directly into the Keystone container.

To configure the Keystone database system, I use a single-shot container. This can be thought of as the Command design pattern: package up everything you need to perform an action, and send it to the remote system for execution. In this case, the docker file pulls together the dependencies, which calls a shell script to do the configuration. Here is the Docker file:

FROM index.docker.io/centos:7
MAINTAINER Adam Young 

RUN yum install -y centos-release-openstack-newton &&\
    yum update -y &&\
    yum -y install openstack-keystone mariadb openstack-utils  &&\
    yum -y clean all

COPY configure_keystone.sh /
COPY keystone-configure.sql /
CMD /configure_keystone.sh

The shell script initializes the database using an external SQL file. I use the echo statment for logging/debugging. Passwords are hard coded, as are host names. These should be extracted out to environment variables in the next iteration.

#!/bin/bash

echo -n Database 
mysql -h 172.17.0.2  -P3306 -uroot --password=my-secret-pw < keystone-configure.sql
echo " [COMPLETE]"

echo -n "configuration "
openstack-config  --set  /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:keystone@172.17.0.2/keystone
DATABASE_CONN=`openstack-config  --get  /etc/keystone/keystone.conf database connection `
echo $DATABASE_CONN

echo " [COMPLETE]"

echo -n "db-sync "
keystone-manage db_sync
echo " [COMPLETE]"

echo -n "bootstrap "
keystone-manage bootstrap --bootstrap-password=FreeIPA4All
echo " [COMPLETE]"

The SQL file mere creates the Keystone database and initializes access.

-- Don't drop database keystone;
create database keystone;
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'localhost' IDENTIFIED BY 'keystone'; 
GRANT ALL PRIVILEGES ON keystone.* TO 'keystone'@'%' IDENTIFIED BY 'keystone'; 
exit

By not dropping the Keystone database, we keep from destroying data if we accidentally run this container twice. It means that, for iterative development, I have to manually delete the database prior to a run, but that is easily done from the command line. I can check the state of the database using:

docker run -it     -e MYSQL_ROOT_PASSWORD="my-secret-pw"    --rm mariadb sh    -c 'exec mysql -h 172.17.0.2 -P3306 -uroot -p"$MYSQL_ROOT_PASSWORD"  keystone'

With minor variations on that, I can delete. Once I can connect and confirm that the Database is correctly initialized, I can launch the Keystone container. Here is the Dockerfile

FROM index.docker.io/centos:7
MAINTAINER Adam Young 

RUN yum install -y centos-release-openstack-newton &&\
    yum update -y &&\
    yum -y install openstack-keystone httpd mariadb openstack-utils mod_wsgi &&\
    yum -y clean all

RUN openstack-config --set /etc/keystone/keystone.conf database connection mysql+pymysql://keystone:keystone@172.17.0.2/keystone &&\
    cp /usr/share/keystone/wsgi-keystone.conf /etc/httpd/conf.d

ADD run-httpd.sh /run-httpd.sh
RUN chmod -v +x /run-httpd.sh

CMD ["/run-httpd.sh"]

This makes use of the resources inside the openstack-keystone RPM to configure the Apache HTTPD instance.

The run-httpd.sh script is lifted from the HTTPD container.

#!/bin/bash
# Copied from
#https://github.com/CentOS/CentOS-Dockerfiles/blob/master/httpd/centos7/run-httpd.sh
# Make sure we're not confused by old, incompletely-shutdown httpd
# context after restarting the container.  httpd won't start correctly
# if it thinks it is already running.
rm -rf /run/httpd/* /tmp/httpd*
exec /usr/sbin/apachectl -DFOREGROUND

This should probably be done as an additional layer on top of the CentOS-Dockerfiles version.

I can then run the Keystone container using:

docker run -it -d  --name openstack-keystone    openstack-keystone

Both containers are running. The configuration container stopped running after it completed its tasks.

$ docker ps
CONTAINER ID        IMAGE                COMMAND                  CREATED             STATUS              PORTS               NAMES
6f6afa855cae        openstack-keystone   "/run-httpd.sh"          29 minutes ago      Up 29 minutes                           openstack-keystone
1127467c0b2b        mariadb:latest       "docker-entrypoint.sh"   17 hours ago        Up 17 hours         3306/tcp            some-mariadb

Confirm access:

$ curl http://172.17.0.3:35357/v3
{"version": {"status": "stable", "updated": "2016-10-06T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v3+json"}], "id": "v3.7", "links": [{"href": "http://172.17.0.3:35357/v3/", "rel": "self"}]}}
$ curl http://172.17.0.3:5000/v3
{"version": {"status": "stable", "updated": "2016-10-06T00:00:00Z", "media-types": [{"base": "application/json", "type": "application/vnd.openstack.identity-v3+json"}], "id": "v3.7", "links": [{"href": "http://172.17.0.3:5000/v3/", "rel": "self"}]}}

Leave a Reply

Your email address will not be published. Required fields are marked *