In this codelab you will be creating a set of basic pipelines for deploying code from a Github repo to a Kubernetes cluster in the form of a Docker container.
Given that there are a number of fully-featured docker registries that both store and build images, Spinnaker doesn't build Docker images but instead depends on any registry that does.
The workflow generally looks like this:
- Push a new tag to your registry. (Existing tag changes are ignored for the sake of traceability - see below).
- Spinnaker sees the tag and deploys the new tag in a fresh Replication Controller, and optionally deletes or disables any old Replication Controllers running this image.
- The deployment is verified externally.
- Spinnaker now redeploys this image into a new environment (production), and disables the old version the Replication Controller was managing
We need a few things to get this working.
- A Github repo containing the code we want to deploy.
- A Dockerhub repo configured to build on changes to the above repo.
- A running Kubernetes cluster.
- A running Spinnaker deployment configured with the contents of steps 2 and 3.
The code I'll be deploying is stored here. Feel free to fork this into your own account, and make changes/deploy from there. What's needed is a working Dockerfile
at the root of the repository that can be used to build some artifact that you want to deploy. If you're completely unfamiliar with Docker, I recommend starting here.
Create a new repository on Dockerhub. This guide covers how to get your Github repository hooked up to your new Dockerhub repository by creating an automated build that will take code changes and build Docker images for you. In the end your repository should look something like this.
Follow one of the guides here. Once you are finished, make sure that you have an up-to-date ~/.kube/config
file that points to whatever cluster you want to deploy to. Details on kubeconfig files here.
We will be deploying Spinnaker to the same Kubernetes cluster it will be managing. To do so, follow the steps in this guide, being sure to use this section to configure your registry.
Spinnaker applications are groups of resources managed by the underlying cloud provider, and are delineated by the naming convention <app name>-
. Since Spinnaker and a few other Kubernetes-essential pods are already running in your cluster, your Applications tab will look something like this:
Under the Actions dropdown select Create Application and fill out the following dialog:
You'll notice that you were dropped in this Clusters tab for your newly created application. In Spinnaker's terminology a Cluster is a collection of Server Groups all running different versions of the same artifact (Docker Image). Furthermore, Server Groups are Kubernetes Replication Controllers (this is subject to change to either Replica Sets, or Deployments in the future).
We will be creating a pair of Spinnaker Load Balancers (Kubernetes Services) to serve traffic to our dev and prod versions of our app. Navigate to the Load Balancers tab, and select Create Load Balancer in the top right corner of the screen.
First we will create the dev Load Balancer:
Once the dev Load Balancer has been created, we will create an external-facing load balancer. Select Create Load Balancer again:
At this point your Load Balancers tab should look like this:
Next we will create a Server Group as a sanity check to make sure we have set up everything correctly so far. Before doing this, ensure you have at least 1 tag pushed to your Docker registry with the code you want to deploy. Now on the Clusters screen, select Create Server Group/Job, choose Server Group from the drop down and hit Next to see the following dialog:
Scroll down to the newly created Container subsection, and edit the following fields:
Once the create task completes, open a terminal and type $ kubectl proxy --port 7777
, and now navigate in your browser to http://localhost:7777/api/v1/proxy/namespaces/default/services/serve-dev:80/ to see if your application is serving traffic correctly.
Once you're satisfied, don't close the proxy or browser tab just yet as we'll use that again soon.
Now let's automate the process of creating server groups associated with the dev loadbalancer. Navigate to the Pipelines tab, select Configure > Create New... and then fill out the resulting dialog as follows:
In the resulting page, select Add Trigger, and fill the form out as follows:
Now select Add Stage just below Configuration, and fill out the form as follows:
Next, in the Server Groups box select Add Server Group, where you will use the already deployed server group as a template like so:
In the resulting dialog, we only need to make one change down in the Container subsection. Select the image that will come from the Docker trigger as shown below:
Lastly, we want to add a stage to destroy the previous server group in this dev cluster. Select Add Stage, and fill out the form as follows:
#5. Verification Pipeline
Back on the Pipelines dialog, create a new pipeline as before, but call it "Manual Judgement". On the first screen, add a Pipeline trigger as shown below:
We will only add a single stage, which will serve to gate access to the prod environment down the line. The configuration is shown here:
Keep in mind, more advanced types of verification can be done here, such as running a Kubernetes batch job to verify that your app is healthy, or calling out to an external Jenkins server. For the sake of simplicity we will keep this as "manual judgement".
Create a new pipeline titled "Deploy to Prod", and configure a pipeline trigger as shown here:
Now we need to find the deployed image in dev that we previously verified. Add a new stage and configure it as follows:
Now, to deploy that resolved image, add a new stage and configure it as follows:
Select Add Server Group, and again use the dev deployment as a template:
This time we need to make three changes to the template. First, change the "stack" to represent our prod cluster:
Next in the load balancers section:
Lastly in the container section:
Now to prevent all prior versions of this app in production from serving traffic once the deploy finishes, we will add a "Disable Cluster" stage like so:
Save the pipeline, and we are ready to go!
Push a new branch to your repo, and wait for the pipeline to run.
NEW_VERSION=v1.0.0
git checkout -b $NEW_VERSION
git push origin $NEW_VERSION
Once the Manual Judgement stage is hit, open http://localhost:7777/api/v1/proxy/namespaces/default/services/serve-dev:80/ to "verify" your deployment, and hit continue once you are ready to promote to prod.