Part of our work is to be constantly on the lookout for tools that can ease cloud native development processes, that can make our work easier or faster. Just like when you are sailing a boat, you will look for the best course to steer and trim the sails to take as much advantage of the wind as you can. Or you use a combination of sails that yields the greatest velocity. When you are sailing a broad course, you might want to deploy a Spinnaker. Likewise in the cloud native environment, under the right conditions, you might want to deploy using Spinnaker.
So what is Spinnaker anyway? On the website it says:
Spinnaker is an open source, multi-cloud continuous delivery platform for releasing software changes with high velocity and confidence.
It combines a powerful and flexible pipeline management system with integrations to the major cloud providers.
What does this mean? Spinnaker is a tool that helps you deploy your software applications to your cloud environment. It does this by either baking a VM image (using Hashicorp’s Packer) or pulling a Docker image from a registry, and then deploying that artifact to a cloud provider. Spinnaker supports a range of providers like AWS, GCE and Azure, but also Kubernetes, DC/OS and Openstack are supported, with Oracle bare metal being promised soon. A number of predefined deployment strategies are available, like red/black (or blue/green if you prefer), highlander (“there can be only one”, aka recreate) and canary, with the option to define your own. If you’d like to know more about deployment strategies, my colleague Etienne wrote an excellent overview.
I am mainly interested in what Spinnaker has to offer in terms of deployment to Kubernetes. In most cases VM’s are too heavy so we prefer to work with containers. The principles that apply to Kubernetes can also apply to DC/OS I suppose, as it uses containers as deployable units as well.
Spinnaker provides two main features: cluster management and deployment management. Cluster management refers to the management of the infrastructure around your application while deployment management regards workflows, ie pipelines that deploy your application.
Spinnaker provides a CLI tool called Halyard that is used to manage the cluster and Spinnaker’s installation itself. The deployment management (the configuration of the pipelines) is all done via the web interface.
Getting started
There are a few ways to install Spinnaker as listed on the website. If you want a quick demo you can use the installations provided by the cloud providers or use the Helm chart to deploy it on your Kubernetes cluster.
A proper installation however requires the use of Halyard. It is used to configure and install Spinnaker, either locally or on a Kubernetes cluster. Halyard is also used to manage your Spinnaker installation and to backup and restore its configuration.
After the installation, browse to the web interface and start configuring your application. An application is always tied to a Git repository (either Github or Bitbucket) so it always references a single body of code. Then proceed to create a load balancer, which corresponds to a service in Kubernetes. You need a load balancer for each environment you want to deploy to (like ‘test’, or ‘production’).
After the load balancers are defined, you can configure the pipeline for your application. There are options to create a custom deployment strategy, which you can subsequently use in your pipelines.
A pipeline is made up of different stages and it always starts with a configuration stage. In the configuration stage you can set triggers for your pipeline like pushes to git, outputs from your CI, cron schedules, or pushes to your image registry. You can also configure notifications here.
After that you define the pipeline stages. You can select from a range of predefined types of stages, like checking for prerequisites, deploying an application, running a script, or triggering another pipeline. You also need to define the dependencies that you want to exist between the stages. This enables you to build quite elaborate pipelines to handle any use cases for your application.
Deploying your application is usually one of the stages in the pipeline. In order to deploy to Kubernetes you need to create a server group, which corresponds to a replica set in Kubernetes. This involves selecting the image you want to deploy and choosing a deployment strategy.
Spinnaker gives you the option to create a deployment for the server group which will create a corresponding deployment object in Kubernetes. By default this option is not selected and Spinnaker will handle pod management directly.
When you’re done, save your configuration and kick off the deployment, either by firing a trigger or starting it manually. Watch the progress in the UI and visit the public IP of the load balancer in your
browser to check that it works.
Of course there is loads more that you can configure but this should give you a basic idea to get you going with deploying your application. I suggest you try it out for yourself to get a feel for what it can do for you.
My take
As with any tool it takes a bit of time to get used to the way the information is presented in Spinnaker’s UI. But once you find your way around the different views and options it is fairly easy to setup and make adjustments. The ability to copy pipelines is a feature that can dramatically impact the time to set up additional pipelines.
What I found a bit confusing though, having experience with Kubernetes, is that Spinnaker by default does not use the objects that are available in Kubernetes for handling deployments. So instead of Kubernetes Deployments Spinnaker will use custom logic to perform the advanced deployment strategies that it offers. This might cause problems if you plan to migrate an existing setup to Spinnaker. Also, using both Spinnaker and the Kubernetes native constructs (deployments, statefulsets, daemonsets) to operate on the same pod collections could lead to unexpected results. So you need to go all in on Spinnaker and not mess with kubectl as well. This might be an advantage as the power kubectl provides gives you the ability to destroy your application in unforeseen ways.
The naming of concepts in Spinnaker can also lead to some confusion, if you’re used to the definitions used by Kubernetes. I guess this is a consequence of Spinnaker starting out as a tool for handling VM deployments, and later the concepts were applied to corresponding constructs in Kubernetes. Deployments and services have different meanings in Spinnaker and Kubernetes. A deployment is a Spinnaker installation, and a service maps to a Docker image with it’s configuration. But then, an instance in Spinnaker corresponds to a Kubernetes pod, a server group maps to a replica set (which would mean a server is a pod), a cluster can be linked to a deployment in Kubernetes, and a load balancer in Spinnaker is called a service in Kubernetes.
Another awkward thing is that there seems to be no way to save or load your pipeline configuration. The configuration is persisted through Front50 but I found no means to save or load it. When editing you can get a JSON representation of your pipeline, but it’s cumbersome to have to copy, paste, save, commit and push it in order to have version control on your pipeline configuration. Also, you can compare versions in the UI (there is a pipeline revision history) but again you cannot save this or load something you created yourself. You could technically edit your configuration as JSON and paste in your own, but it seems cumbersome.
This to me is a downside because the configuration of pipelines in Spinnaker is not immutable. You can install it and load a configuration, but you cannot load subsequent pipeline configuration, which means you cannot automatically recreate your setup. If your installation breaks, you will have to set it up from scratch. I did read on the Spinnaker blog about deployment templates which looks promising, so this issue might be resolved in the future.
Use case
Why would you want to use Spinnaker? I think that if you are not comfortable with code but want to (or need to) deploy nevertheless, Spinnaker is a nice solution because it provides a graphical representation of a pipeline and the ability to configure various aspects through the UI. You might prefer that.
Also if you want to be able to perform advanced deployment strategies, Spinnaker can provide an easy solution. It provides a number out of the box and you can even define your own.
Would we recommend it? We might. As always, the answer is it depends. If it fits your use case, like if you’re not picky about the technology being used to deploy your application on Kubernetes, or you don’t mind recreating the pipelines from scratch in case it happens to crash, then the ease of handling deployments it provides might make it preferable over other methods. We have seen it being used at customers to great satisfaction. But it has some important drawbacks that would disqualify it in other situations. Personally I prefer to be able to script the whole deployment infrastructure so it would not be my first choice. But other solutions certainly have their own quirks. The Spinnaker development team might address the shortcomings in the future. Then I think it would be an awesome tool.