Most examples on the deployment of Docker applications to CoreOS use a single docker application. But as soon as you have an application that consists of more than 1 unit, the number of commands you have to type soon becomes annoying. At Xebia we have a best practice that says "Three strikes and you automate" mandating that a third time you do something similar, you automate. In this blog I share the manual page of the utility called fleetappctl that allows you to perform rolling upgrades and deploy Consul Key value pairs of composite applications to CoreOS and show three examples of its usage.
fleetappctl is a utility that allows you to manage a set of CoreOS fleet unit files as a single application. You can start, stop and deploy the application. fleetappctl is idempotent and does rolling upgrades on template files with multiple instances running. It can substitute placeholders upon deployment time and it is able to deploy Consul key value pairs as part of your application. Using fleetappctl you have everything you need to create a self contained deployment unit of your composite application and put it under version control.
The command line options to fleetappctl are shown below:
fleetappctl [-d deployment-descriptor-file] [-e placeholder-value-file] (generate | list | start | stop | destroy)
option -d
The deployment descriptor file describes all the fleet unit files and Consul key-value pair files that make up the application. All the files referenced in the deployment-descriptor may have placeholders for deployment time values. These placeholders are enclosed in double curly brackets {{ }}.
option -e
The file contains the values for the placeholders to be used on deployment of the application. The file has a simple format:
<name>=<value>
start
starts all units in the order as they appear in the deployment descriptor. If you have a template unit file, you can specify the number of instances you want to start. Start is idempotent, so you may call start multiple times. Start will bring the deployment inline with your descriptor.
If the unit file has changed with respect to the deployed unit file, the corresponding instances will be stopped and restarted with the new unit file. If you have a template file, the instances of the template file will be upgraded one by one.
Any consul key value pairs as defined by the consul.KeyValuePairs entries are created in Consul. Existing values are not overwritten.
generate
generates a deployment descriptor (deployit-manifest.xml) based upon all the unit files found in your directory. If a file is a fleet unit template file the number of instances to start is set to 2, to support rolling upgrades.
stop
stops all units in reverse order of their appearance in the deployment descriptor.
destroy
destroys all units in reverse order of their appearance in the deployment descriptor.
list
lists the runtime status of the units that appear in the deployment descriptor.
Install fleetappctl
to nstall the fleetappctl utility, type the following commands:
curl -q -L https://github.com/mvanholsteijn/fleetappctl/archive/0.25.tar.gz | tar -xzf - cd fleetappctl-0.25 ./install.sh brew install xmlstarlet brew install fleetctl
Start the platform
If you do not have the platform running, start it first.
cd .. git clone https://github.com/mvanholsteijn/coreos-container-platform-as-a-service.git cd coreos-container-platform-as-a-service git checkout 029d3dd8e54a5d0b4c085a192c0ba98e7fc2838d cd vagrant vagrant up ./is_platform_ready.sh
Example – Three component web application
The first example is a three component application. It consists of a mount, a Redis database service and a web application. We generate the deployment descriptor, indicate we do not want to start the mount, start the application and then modify the web application unit file to change the service name into ‘helloworld’. We perform a rolling upgrade by issuing start again.. Finally we list, stop and destroy the application.
cd ../fleet-units/app # generate a deployment descriptor fleetappctl generate # do not start mount explicitly xml ed -u '//fleet.UnitConfigurationFile[@name="mnt-data"]/startUnit' \ -v false deployit-manifest.xml > \ deployit-manifest.xml.new mv deployit-manifest.xml{.new,} # start the app fleetappctl start # Check it is working curl hellodb.127.0.0.1.xip.io:8080 curl hellodb.127.0.0.1.xip.io:8080 # Change the service name of the application in the unit file sed -i -e 's/SERVICE_NAME=hellodb/SERVICE_NAME=helloworld/' app-hellodb@.service # do a rolling upgrade fleetappctl start # Check it is now accessible on the new service name curl helloworld.127.0.0.1.xip.io:8080 # Show all units of this app fleetappctl list # Stop all units of this app fleetappctl stop fleetappctl list # Restart it again fleetappctl start # Destroy it fleetappctl destroy
Example – placeholder references
This example shows the use of a placeholder reference in the unit file of the paas-monitor application. The application takes two optional environment variables: RELEASE and MESSAGE that allow you to configure the resulting responses. The variable RELEASE is configured in the Docker run command in the fleet unit file through a placeholder. The actual value for the current deployment is taken from an placeholder value file.
cd ../fleetappctl-0.25/examples/paas-monitor #check out the placeholder reference grep '{{' paas-monitor@.service ... ExecStart=/bin/sh -c "/usr/bin/docker run --rm --name %p-%i \ <strong>--env RELEASE={{release}}</strong> \ ... # checkout our placeholder values cat dev.env ... release=V2 # start the app fleetappctl -e dev.env start # show current release in status curl paas-monitor.127.0.0.1.xip.io:8080/status # start is idempotent (ie. nothing happens) fleetappctl -e dev.env start # update the placeholder value and see a rolling upgrade in the works echo 'release=V3' > dev.env fleetappctl -e dev.env start curl paas-monitor.127.0.0.1.xip.io:8080/status fleetappctl destroy
Example – Env Consul Key Value Pair deployments
The final example shows the use of a Consul Key Value Pair, the use of placeholders and envconsul to dynamically update the environment variables of a running instance. The environment variables RELEASE and MESSAGE are taken from the keys under /paas-monitor in Consul. In turn the initial value of these keys are loaded on first load and set using values from the placeholder file.
cd ../fleetappctl-0.25/examples/envconsul #check out the Consul Key Value pairs, and notice the reference to placeholder values cat keys.consul ... paas-monitor/release={{release}} paas-monitor/message={{message}} # checkout our placeholder values cat dev.env ... release=V4 message=Hi guys # start the app fleetappctl -e dev.env start # show current release and message in status curl paas-monitor.127.0.0.1.xip.io:8080/status # Change the message in Consul fleetctl ssh paas-monitor@1 \ curl -X PUT \ -d \'hello Consul\' \ https://172.17.8.101:8500/v1/kv/paas-monitor/message # checkout the changed message curl paas-monitor.127.0.0.1.xip.io:8080/status # start does not change the values.. fleetappctl -e dev.env start
Conclusion
CoreOS provides all the basic functionality for a Container Platform as a Service. With the utility fleetappctl it becomes easy to start, stop and upgrade composite applications. The script is an superfluous to fleetctl and does not break other ways of deploying your applications to CoreOS.
The source code, manual page and documentation of fleetappctl can be found on GitHub – mvanholsteijn/fleetappctl.