This asciibuild [1] file can be used to build a wide variety of variations of Docker containers for running a Riak cluster. It runs a single node per container instance and by setting the CLUSTER_COORDINATOR environment variable to the IP address of a "master" node (the primary or seed node of a cluster), subsequent containers can be automatically joined into a cluster.
-
riak_version: {riak_version} -
riak_flavor: {riak_flavor} -
riak_tag: {riak_tag} -
riak_explorer_version: {riak_explorer_version} -
riak_client_version: {riak_client_version}
-
openjdk: set or unset Whether or not to include OpenJDK 8 -
docker: set or unset Whether or not to include the Docker command-line tools -
riak_explorer: set or unset Whether or not to include Riak Explorer -
riak_client: set or unset Whether or not to include the Riak Python client
FROM {{os_family}}:{{os_version}}
ENV OS_FAMILY {{os_family}}
ENV OS_VERSION {{os_version}}
ENV RIAK_VERSION {{riak_version}}
ENV RIAK_FLAVOR KV
RUN curl -s https://packagecloud.io/install/repositories/basho/{{riak_pkg}}/script.{{pkg_format}}.sh | bash
# Expose default ports
EXPOSE 8087
EXPOSE 8098
# Expose volumes for data and logs
VOLUME /var/log/riak
VOLUME /var/lib/riak
# Install custom start script
COPY riak-cluster.sh $RIAK_HOME/riak-cluster.sh
RUN chmod a+x $RIAK_HOME/riak-cluster.sh
# Install custom hooks
COPY prestart.d /etc/riak/prestart.d
COPY poststart.d /etc/riak/poststart.d
# Prepare for bootstrapping schemas
RUN mkdir -p /etc/riak/schemas
WORKDIR /var/lib/riak
CMD $RIAK_HOME/riak-cluster.sh
# Clean up APT cache
RUN rm -rf /var/lib/apt/lists/* /tmp/*
This file is an asciibuild-enabled AsciiDoc file. It is also heavily parameterized in order to produce a wide variety of variations. Some of the variations possible include:
-
Riak KV
-
Based on
ubuntu:14.04 -
Based on
centos:7
-
-
Riak TS
-
Based on
ubuntu:14.04 -
Based on
centos:7 -
Based on
debian:8
-
-
Optional components (enabled or disabled based on the attributes set)
This asciibuild file will produce a riak_{riak_flavor} image based on {os_family}:{os_version}. Optional components included in this build:
To build the image using asciibuild, process this README file:
asciibuild README.adocTo change the variation of image produced, set attributes according to the following configuration matrix:
Attribute Value |
Produces |
|
Ubuntu Trusty image |
|
CentOS 7 image |
|
Turns off OpenJDK install |
|
Turns off Docker install |
|
Turns off Riak Explorer install |
|
Turns off Riak Python Client install |
Validate the container is started by waiting for it to fully boot, then access the /stats endpoint.
riak-admin wait-for-service riak_kv
function stats() {
echo `curl -s localhost:8098/stats | jq -r '.vnode_gets'`
}
# There should be no read stats for an empty cluster
[ "0" == "$(stats)" ]
# Increment the read stats
curl -s localhost:8098/types/default/buckets/notfound/keys/notfound
# Wait for stats to be eventually-consistent
sleep 1
# Verify read stats have incremented
[ "3" == "$(stats)" ]
To augment the riak.conf file with additional settings, mount a user.conf file into the /etc/riak/ directory. Each line should follow the pattern setting = value. Each line will be split on the = and made into a regex passed to sed that matches the setting key and replaces the value with the value you specify in user.conf.
# {{=<% %>=}}
CONTAINER=$(docker run --label role=cluster -d -P -v `pwd`/test/user.conf:/etc/riak/user.conf <% riak_tag %>)
docker exec $CONTAINER riak-admin wait-for-service riak_kv
# Check that the backend was set to leveldb
BACKEND=$(docker exec $CONTAINER riak config effective | egrep "^storage_backend" | cut -d= -f2 | tr -d ' ')
[ "$BACKEND" == "leveldb" ]
This Docker image has support for automatically creating a cluster by setting the environment variable COORDINATOR_NODE to the IP address of a node to which you want to join when the container starts.
# {{=<% %>=}}
# Discover coordinator node IP
COORDINATOR_NODE=$(docker inspect -f {{.NetworkSettings.IPAddress}} <% riak_pkg %>)
# Start new nodes for the cluster
for i in 1 2; do
CONTAINER=$(docker run -d --label=asciibuild.name="Riak in Docker" --label=role=cluster -e COORDINATOR_NODE=$COORDINATOR_NODE <% riak_tag %>)
# Wait for node to completely start
docker exec $CONTAINER riak-admin wait-for-service riak_kv
done
# Wait for cluster to settle some
sleep 5
# Verify three nodes report up
STATUS=$(docker exec <% riak_pkg %> riak-admin cluster status --format csv | tail -n 3 | cut -d, -f3)
[ "$(echo $STATUS)" == "up up up" ]
This Docker image has support for automatically boostrapping bucket types and TS tables. Files in /etc/riak/schemas/ that end in .dt will be read and the name of the file (minus the extension .dt) will be used as the bucket name and the contents of the file should contain a single line, which is the bucket type to use.
counter
If the boostrapping script found the above, it would translate that into a riak-admin bucket-type create, followed by a riak-admin bucket-type activate.
riak-admin bucket-type create my_bucket '{"props":{"datatype":"counter"}}'
riak-admin bucket-type activate my_bucketTo enable automatic bootstrapping, mount the schemas into the container via volume, or COPY the resources into the /etc/riak/schemas directory in a derived container.
# {{=<% %>=}}
SCHEMAS_CONTAINER=$(docker run -d -P --label role=schemas -v $(pwd)/test/schemas:/etc/riak/schemas <% riak_tag %>)
docker exec $SCHEMAS_CONTAINER riak-admin wait-for-service riak_kv
# Discover the IP of the container
IP=$(docker inspect -f '{{.NetworkSettings.IPAddress}}' $SCHEMAS_CONTAINER)
# Only way to ensure bucket types exist is to wait for script to complete.
# There's no way to know when it's done, so we just do a sleep.
sleep 5
# Check that the bucket type has been defined
BUCKET_TYPES=$(docker exec $SCHEMAS_CONTAINER curl -s $IP:8098/admin/explore/clusters/default/bucket_types)
[[ ! -z "$BUCKET_TYPES" ]]
[ "$(echo $BUCKET_TYPES | jq -r '.bucket_types[] | select(.id == "test") | .props.datatype')" == "counter" ]
if [ '<% riak_flavor %>' == 'ts' ]; then
# Check that the TS tables have been created
[ "$(echo $BUCKET_TYPES | jq -r '.bucket_types[] | select(.id == "GeoCheckin") | .props.ddl.local_key[]' | tr -d '\n')" == "idtime" ]
fi
# Remove the container
docker rm -f $SCHEMAS_CONTAINER || true
Clean up temporary and transitory files that get rebuilt each time this build is run.
This step can be skipped by setting the attribute skip_clean when running the build.
rm -Rf Dockerfile for r in cluster schemas; do docker rm -f $(docker ps -aqf label=role=$r) || true done