Continuous Delivery Guide — Part 3/5

Hello guys, how are you? I hope you're all doing fine!

This will be a five part article, in which we’ll discuss:

  1. What is Continuous Delivery and why is that important?
  2. What are the available tools and how to choose one?
  3. Spinnaker: I want to sail in this one!
  4. Jenkins X: New way to look the good old Jenkins
  5. Concourse CI: New guy in town

I really hope you find this series useful, and if you do, please leave a comment or DM me on LinkedIn.

Today we're here to do a little demo with Spinnaker. Our main goal with this series is to identify the good and the bad aspects of each CD tool we're going to study.

Spinnaker's logo.

This article will explain some core aspects of Spinnaker, how to install it and a little demo.

In each demo, we have an objective: To deploy a Nginx container in our Kubernetes Cluster.

Then, we will compare each tool with its difficulty to install, and to setup a simple workflow.

Spinnaker: Let's sail together

Spinnaker is a multi-cloud continuous delivery tool. According to the official documentation, it has two core features: Application Management and Application Deployment.

Application Management

You can view and interact with your cloud resources in an agnostic way through Spinnaker’s web interface. Today the microservice architecture is on the edge of technology. Spinnaker has that concept in its Application model.

But the basic idea that Spinnaker abstracts for us is the Server Group. A Server Group is a group of resources that runs your code, basically. It could be a Docker Image, a VM, a file system location, and an initial configuration, such as, number of instances, policies and metadata.

Alongside the Server Group there is the Load Balancer. A Load Balancer routes traffic through the Server Group instances. It could have a health check, balancing policies and multiple endpoints.

In order to protect the Load Balancer, there is a Firewall. A Firewall manages security for network access. You could define acceptance of protocols, ports and other stuff. Cool!

In order to put Server Groups together, you have a Cluster. By definition, it’s just a collection of Server Groups that have the same purpose. But please, it is not the same concept as Kubernetes applies.

And finally, we have an Application. Well, putting together Clusters, LoadBalancers and Firewalls must be very hard, so Spinnaker makes it easier for us.

Application Development

The main 3 concepts here are: Stages, Pipelines and Deployment Strategies.

Stages are the minimal part of Spinnaker Application Development. They consist of a set of actions taken a single objective. In our demo, we will deploy a Nginx in our cluster, those actions in order to make a full deployment, are a stage.

Pipelines are a sequence of stages. In Spinnaker you can orchestrate your pipelines in order to achieve high availability and fault tolerance. There are many strategies in order to do that.

Those Deployment Strategies can change with your needs. Here are the strategies Spinnaker can do by default:

Spinnaker's deployment strategies
Spinnaker's deployment strategies
Spinnakers's Deployment Strategies

The Blue/Green Strategy consists of dividing your production environment into two parts. The first one will be taken out of the load balancer and receive the new application, while the other one still receives your customers. After the deployment and tests in the first part, it will be reconnected to the Load Balancer and the other part will be taken out to receive the update and run some tests. After they are both updated and validated, we reconnect the second part to the Load Balancer and the application is now fully updated.

The Red/Black Strategy consists of creating a new updated version of the app and adding the new one to the Load Balancer whilst the old one stills available in case of an emergency. After some tests, the older version is discarded. You can read more about it here.

The Canary Deployment is similar to the Blue/Green one, but more risk free. Instead of switching half of our traffic into a new application, we do it with a small fraction, say like 5%. So, 5% of our users will receive the updated app, whilst the 95% will maintain the older one. We run some tests in the new version, and, if, and only if, it shows better than the older version, we switch it. If you want to know more about it, check out here.

Spinnaker: What does it look like?

Spinnaker has eleven microservices in total. It needs 10 of those in order to run properly. Here is a list of them, and the main functionality:

  • Orca: handles the internal orquestration and the actions of the pipelines
  • Clouddriver: handles the different cloud providers calls, since Spinnaker is a multi-cloud tool
  • Rosco: creates images for different cloud providers
  • Deck: the web UI
  • Echo: sends notifications to e-mails, SMS, Slack or any other integration
  • Gate: the main API. You can use it to call Spinnaker actions and the web UI uses it too.
  • Igor: receives trigger from other sources, like Jenkins or Github, for example
  • Fiat: handles authentication and authorization
  • Front50: saves metadatas and pipelines configuration
  • Halyard: Spinnaker’s configuration tool
  • Kayenta: You only see this service once you enable Canary Deployment. It handles analytics for your deployments

This image is from the official documentation and I'm gonna leave it here just for you to grasp what Spinnaker really looks like:

spinnaker's built in microservices
spinnaker's built in microservices
Spinnaker's microservices diagram

You could also check more information about Spinnaker's architecture in here. Check it if you need to know what ports must be available in order to run it properly.

How do I install it?

Since Spinnaker is cloud agnostic, I'll use Kubernetes to provision it. I've already installed Minikube in my local machine. If you don't know what is Minikube, or don't know how to set it up, click here for more information.

Minikube is a great tool to learn more about Kubernetes and a great development tool.

First, let's make sure out environment is up and running

minikube status

If the message showed is something like this

host: Running
kubelet: Running
apiserver: Running
kubectl: Correctly Configured: pointing to minikube at <some local ip address>

Then we are good to go! First of all, let's use Helm.

Helm is a tool designed to make Kubernetes administrators and developers tasks easier. It is a Kubernetes application manager. Several companies and people around the globe made an effort to combine their skills into something that everyone could use.

The combination of many Kubernetes manifest results in a Chart. A Chart is the way that Helm identifies resources in Kubernetes. You could modify this Charts or use a file, that is primarily called values.yaml .

After you have configured the values.yaml as you wanted, Helm will make the necessary adjustments so your application is set up the way you wanted.

If you want to learn more about it, click here.

After you installed Helm, we must initiate the Tiller Pod. In this article I'll be using Helm v2 because the Helm3 is not yet ready for what we want here. So run the following command:

helm init

After a couple of minutes you'll see a message telling you that the Tiller Pod is ready. But where is this guy? Check with me:

kubectl get pods -n kube-system

You are gonna see a tiller-pod around here. If it's not up, wait a little more. You can check it status by running:

kubectl describe pod -n kube-system <tiller pod name>

Maybe the image could take a while to download.

Ok, we have our Helm installed and configured, our local cluster is OK as well. We can now proceed to install Spinnaker.

I've found this repository made by AirWave Tech, they made this custom Spinnaker for Minikube, which is great!

If you ever want to use Spinnaker in a real world environment, please use the official one.

Now, we are going do clone the repo

git clone https://github.com/airwavetechio/helm-spinnaker.git

After that, go into the folder and install Spinnaker using Helm

cd helm-spinnaker
helm install --name spinnaker --namespace spinnaker -f values-airwave-no-persistence.yml . --timeout 600

We are installing into our Helm an app that we called spinnaker, which will be located at the namespace spinnaker. We are using the no persistence modification, but sure, you could use the persistence one as well. We are referencing the local charts, because we don't want Helm looking into the official ones hence this a modification. And we are increasing the default timeout because Spinnaker takes a while to install.

Wait until the installation is finished, it could take several minutes. After that, you will receive 4 commands to make some port forwarding. Save them!

Two of them are to set environment variables. The other two are to do a port-forward into two containers. As we explained above, Spinnaker has an API responsible for all the backend calls, the Gate service. In order to access it from your machine, you must enable the Gate and the Deck as port-forward.

So open two terminal windows and run both commands.

After that, you will be able to access Spinnaker's interface at

http://localhost:9000

Now, we are going to create our own Pipeline inside Spinnaker.

Go on the top menu and click on Actions. The click on Create Application.

Create app on Spinnaker

For the Application, just give it a default configuration like below:

Application simple configuration

Now, go the top menu and click on Applications and then select the Pipeline on the sub menu.

All pipelines for one application

Click on Configure a New Pipeline and give it a name:

Creating a Pipeline

Now, you will see the configuration screen for a pipeline. Click on Add New Stage and give it a name and Type Deploy (Manifest). Because we will deploy a manifest in our cluster. On the account tab, select the only option, it will be the cluster which Spinnaker is installed. You could configure multiple clusters and they would show up here.

Creating a deploy stage

Now, roll down a little and let’s add our manifest. Use the Text type and paste the following:

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-deployment
namespace: nginx
spec:
selector:
matchLabels:
app: nginx
replicas: 1
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80

It will be something like this:

Manifest on Spinnaker stage

Now click on Sync with Server on the bottom right of the screen.

Before anything, we are declaring in our pipeline that our deployment will be on the nginx namespace, but you do have to create that namespace yourself

kubectl create ns nginx

Now go back to the Pipeline Menu and click on Start Manual Execution.

Spinnaker manual execution

It will take a while, but we could follow the deployment clicking on Deploy Status by clicking on Execution Details

After a couple of minutes, the we'll receive a Successful status.

We can now check if our deployment has been made, go to your terminal window and type:

kubectl get pods -n nginx

There will be one pod there. You could check the deployment with more details:

kubectl describe deploy -n nginx nginx-deployment

Do a port forward to your nginx pod:

kubectl port-forward --namespace nginx <NGINX POD NAME> 80
Nginx index page

OK, cool. Our deploy has been made and we've learned how to setup a default Spinnaker on our cluster, configure a simple pipeline and run it!

I really hope you enjoyed this tutorial. If you have any questions, please leave a comment or send me a message on my In.

See ya!

This is just a bit of my life. Writing another line everyday!