Kubernetes CI/CD pipeline - continuous-integration

My company has decided to transition to a micro/service based architecture.
We have been doing a bunch of research for the last couple of months on exactly what the architecture of this thing is going to look like.
So far, we've settled on:
Dotnet core for service development (although being language agnostic is somewhat of an end goal)
Kafka for message brokering
Docker
Kubernetes
Ansible
We have a pretty basic proof of concept working, which seems to have ticked all the right boxes with the management team, and is an absolute joy to work with.
My next task is to investigate options for how the development workflow is actually going to work. They are already used to working in a CI/CD manner, with some of their newer products using Jenkins/Octopus Deploy.
My question is: Do any of you have any firm recommendations for setting up a CI/CD pipeline when deploying to a Kubernetes cluster?
A list of must haves is:
Multiple environments i.e. Integration, Test, UAT, Staging, Production.
A means through which different business units can uniquely handle deployments to different environments (development can only push to integration, tester into test, etc). This one is probably their biggest ask - they are used to working with Octopus, and they love the way it handles this.
The ability to roll back / deploy at the click of a button (or with as few steps as possible).
We would be deploying to our own servers initially.
I've spent the past couple of days looking in to options, of which there are many.
So far, Jenkins Pipeline seems like it could be a great start. Spinnakar also seems like a solid choice. I did read a bit into Fabric8, and while it offers much of what I'm asking, it seems a bit like overkill.

If you want to use Jenkins, Pipelines are indeed the way to go. Our setup does pretty much what you want, so let me explain how we set it up.
We use a Jenkins agent that has docker and kubectl installed. This agent first builds the docker container and pushes it to our docker registry. It will then call kubectl in various stages to deploy to our testing, acceptance and production clusters.
Different business units: in a Pipeline you can use an input step to ask whether the Pipeline should proceed or not. You can specify who may press the button, so this is how you could solve the deployment to different clusters. (Ideally, when you get to CD, people will realize that pressing the button several times per day is silly and they'll just automate the entire deployment.)
Rollback: we rely on Kubernetes's rollback system for this.
Credentials: we provision the different Kubernetes credentials using Ansible directly to this Jenkins agent.
To reduce code duplication, we introduced a shared Jenkins Pipeline library, so each (micro)service talks to all Kubernetes clusters in a standardized way.
Note that we use plain Jenkins, Docker and Kubernetes. There is likely tons of software to further ease this process, so let's leave that open for other answers.

We're working on an open source project called Jenkins X which is a proposed sub project of the Jenkins foundation aimed at automating CI/CD on Kubernetes using Jenkins pipelines and GitOps for promotion across environments.
If you want to see how to automate CI/CD with multiple environments on Kubernetes using GitOps for promotion between environments and Preview Environments on Pull Requests you might wanna check out my recent talk on Jenkins X at DevOxx UK where I do a live demo of this on GKE.

Related

DevSecOPs Q- how do you build in the capability to automate the ability to discover and apply security patches in your ci/cd pipeline?

Within a DevSecOps Ci/Cd pipeline one of the best practices is to automatically discover and apply patches to vulnerable software prior to deployment.
Is it possible to check a CVE database, find patches, and then deploy. I want to build this capability into my pipeline.
The environments applicable to the above is AWS and Azure.
Can you provide examples of tools I could use to achieve the above?
• Automatically discover and apply patches to vulnerable open-source software prior to deployment.
A tool like Trivy may be your answer.
Trivy looks at the contents of an image to check which packages it includes, scans for all vulnerabilities, and sends them to AWS Security Hub.
If the scan does not uncover vulnerabilities, the Docker images are pushed to Amazon Elastic Container Registry for deployment.
To use Trivy, you must have Security Hub enabled in the AWS Region where you deploy this solution.
There are many other open-source solutions out there. Trivy is just one of them.

How do I manage micro services with DevOps?

Say I have a front end node and three backed nodes tools, blog, and store. Each node communicates with the other. Each of these nodes have their own set of languages and libraries, and have their own Dockerfile.
I understand the DevOps lifecycle of a single monolithic web application, but cannot workout how a DevOps pipeline would work for microservices.
Would each micro-service get its own github repo and CI/CD pipeline?
How do I keep the versions in sync? Let's say the tools microservice uses blog version 2.3. But blog just got pushed to version 2.4, which is incompatible with tools. How do I keep the staging and production environments in sync onto which version they are supposed to rely on?
If I'm deploying the service tools to multiple different servers, whose IP's may change, how do the other services find the nearest location of this service?
For a monolithic application, I can run one command and simply navigate to a site to interact with my code. What are good practices for developing locally with several different services?
Where can I go to learn more?
Would each micro-service get its own github repo and CI/CD pipeline?
From my experience you can do both. I saw some teams putting multiple micro-services in one Repository.
We where putting each micro-service in a separate repository as the Jenkins pipeline was build in a generic
way to build them that way. This included having some configuration files in specific directories like
"/Scripts/microserviceConf.json"
This was helping us in some cases. In general you should also consider the Cost as GitHub has a pricing model
which does take into account how many private repositories you have.
How do I keep the versions in sync? Let's say the tools micro-service uses blog version 2.3. But blog just got pushed to version 2.4, which
is incompatible with tools. How do I keep the staging and production
environments in sync onto which version they are supposed to rely on?
You need to be backwards compatible. Means if your blogs 2.4 version is not compatible with tools version 2.3 you will have high dependency
and coupling which is going again one of the key benefits of micro-services. There are many ways how you get around this.
You can introduce a versioning system to your micro-services. If you have a braking change to lets say an api you need to support
the old version for some time still and create a new v2 of the new api. Like POST "blogs/api/blog" would then have a new api
POST "blogs/api/v2/blog" which would have the new features and tools micro-service will have some brige time in which you support
bot api's so it can migrate to v2.
Also take a look at Semantic versioning here.
If I'm deploying the service tools to multiple different servers, whose IP's may change, how do the other services find the nearest
location of this service?
I am not quite sure what you mean here. But this goes in the direction of micro-service orchestration. Usually your Cloud provider specific
service has tools to deal with this. You can take a look at AWS ECS and/or AWS EKS Kubernetes service and how they do it.
For a monolithic application, I can run one command and simply navigate to a site to interact with my code. What are good practices
for developing locally with several different services?
I would suggest to use docker and docker-compose to create your development setup. You would create a local development network of docker
containers which would represent your whole system. This would include: your micro-services, infrastructure(database, cache, helpers) and others. You can read about it more in this answer here. It is described in the section "Considering the Development Setup".
Where can I go to learn more?
There are multiple sources for learning this. Some are:
https://microservices.io/
https://www.datamation.com/applications/devops-and-microservices.html
https://www.mindtree.com/blog/look-devops-microservices
https://learn.microsoft.com/en-us/dotnet/standard/microservices-architecture/multi-container-microservice-net-applications/multi-container-applications-docker-compose

What is there to do on a Heroku staging app?

I understand how to create and deploy code to a staging environment on Heroku before deploying it to production. I understand that it is good to see if the code will "blow up" in a very similar environment than the one in production.
However, I can't figure out any tangible ways or mechanisms to determine if the application is broken on the staging environment.
In other words, I don't understand how having a running application on the staging environment is supposed to give me the confidence to deploy my application to production.
Hence my questions:
What additional steps are there to do on the staging environment on Heroku?
Are the integration tests supposed to be run on the staging environment?
If I note that the application is running on the staging environment, is it good enough?
A staging environment is intended just for that - to stage, or to "rehearse" an app version, before you promote it to production.
Heroku pipelines enable you to deploy a staging app in an environment as identical as possible to your production app, to reduce "but it worked in my dev environment" problems.
What you do with your app on the staging environment is up to you. You can consider using various simulation tools to simulate live users who would be accessing your production app. You might have migrations that you need to perform on your production app's data, so you could run them first in your staging app. You can have testers working with your staging app to verify everything works as intended before promoting to production.
Bottom line: Whatever you can do with your production app, you should be able to do with your staging app. Therefore, you should strive to achieve a deployment flow whereby BEFORE promoting a version to production, whatever scenarios may occur on production should first be tested on staging. How you achieve that is up to you.
What additional steps are there to do on the staging environment on Heroku?
Visually catch any broken CSS + HTML (which is a very difficult task with currently testing tools)
You might have other members in your team (SEO specialist, Marketing Manager, etc) which wants to inspect text, meta tags, etc. Having a staging environment will just make their life much easier as they can navigate and probe, propose improvements, etc
In your development machine you and other team members may have a different environment than you have running on production (different DB OS versions and third party services (.i.e Elasticsearch, Redis, etc) just to name a few.
You want to test deployment itself (you might have a series of tasks that are triggered during deployment)
The list of benefits and advantages of having a staging environment as close as possible as your production environment goes on...
Are the integration tests supposed to be run on the staging environment?
Normally you run your automated tests in a CI server (not on staging). Staging is just there to visually test and maybe to catch an error not covered yet by your test scenarios
If I note that the application is running on the staging environment, is it good enough?
Good enough is difficult to say (your staging environment may not be a perfect copy of your production environment), but if it is well tested, it should be very close to what you expect to see running in production

How to consolidate build statuses from several Jenkins instances in different locations on one dashboard?

We have several teams located around the world (US, UK, India) who are quite well geographically concentrated on projects. Each team has its own Jenkins server at the moment for building their projects. Lets say it is like this:
JenkinsA (US) [Project A]
JenkinsB (India) [Project B]
JenkinsC (UK) [Project C]
The sites are connected by (necessarily) high latency VPNs. There is a desire by management have an aggregated view of the status of all builds across all teams. However we cannot consolidate to a single build system in one location as the integration systems are geographically distributed.
Is there a prebuilt solution for aggregating the status of all builds from various Jenkins instances on one webpage/dash? Something which could consolidate the various RSS feeds into a single display?
Given our development organisation's structure, geography and network topology, would there be any benefit to promoting the US instance to a Master, with the UK and India instances demoted to slaves? This would give us an aggregated view, but would introduce the US office and the slow VPNs as a single points of failure for all sites? Plus it would potentially take ownership of the build instances away from the teams.
A fairly easy way to do it, is to build a simple HTML page which pulls the status from the various Jenkins instances using the Jenkins API.
Here is some JavaScript code that might work for you:
Jenkins status
This Jenkins plugin might also be of interest.
wiki Jenkins
The plugin description:
This plugin allows records from one Jenkins to be published on another Jenkins. The typical use case is for you to run builds within the firewall, then send the results to another Jenkins which is facing the outside world.
The only issue I've found so far is that you must make sure the jobs have different names between the Jenkins instances. If there already is a job on the "public" Jenkins with the same name as a job you're trying to publish from your "private" Jenkins then the public job might get overwritten and then it seems impossible to disconnects the jobs again.

What exactly is Heroku?

I just started learning Ruby on rails and I was wondering what Heroku really is? I know that its a cloud that helps us to avoid using servers? When do we actually use it?
Heroku is a cloud platform as a service. That means you do not have to worry about infrastructure; you just focus on your application.
In addition to what Jonny said, there are a few features of Heroku:
Instant Deployment with Git push - build of your application is performed by Heroku using your build scripts
Plenty of Add-on resources (applications, databases etc.)
Processes scaling - independent scaling for each component of your app without affecting functionality and performance
Isolation - each process (aka dyno) is completely isolated from each other
Full Logging and Visibility - easy access to all logging output from every component of your app and each process (dyno)
Heroku provides very well written tutorial which allows you to start in minutes. Also they provide first 750 computation hours free of charge which means you can have one processes (aka Dyno) at no cost. Also performance is very good e.g. simple web application written in node.js can handle around 60 - 70 requests per second.
Heroku competitors are:
OpenShift by Red Hat
Windows Azure
Amazon Web Services
Google App Engine
VMware
HP Cloud Services
Force.com
It's a cloud-based, scalable server solution that allows you to easily manage the deployment of your Rails (or other) applications provided you subscribe to a number of conventions (e.g. Postgres as the database, no writing to the filesystem).
Thus you can easily scale as your application grows by bettering your database and increasing the number of dynos (Rails instances) and workers.
It doesn't help you avoid using servers, you will need some understanding of server management to effectively debug problems with your platform/app combination. However, while it is comparatively expensive (i.e. per instance when compared to renting a slice on Slicehost or something), there is a free account and it's a rough trade off between whether it's more cost effective to pay someone to build your own solution or take the extra expense.
Heroku Basically provides with webspace to upload your app
If you are uploading a Rails app then you can follow this tutorial
https://github.com/mrkushjain/herokuapp
As I see it, it is a scalable administrated web hosting service, ready to grow in any sense so you don't have to worry about it.
It's not useful for a normal PHP web application, because there are plenty of web hosting services with ftp over there for a simple web without scalability needs, but if you need something bigger Heroku or something similar is what you need.
It is exposed as a service via a command line tool so you can write scripts to automate your deployments. Anyway it is pretty similar to other web hosting services with Git enabled, but Heroku makes it simpler.
That's its thing, to make the administration stuff simpler to you, so it saves you time. But I'm not sure, as I'm just starting with it!
A nice introduction of how it works in the official documentation is:
https://devcenter.heroku.com/articles/how-heroku-works
Per DZone: https://dzone.com/articles/heroku-or-amazon-web-services-which-is-best-for-your-startup
Heroku is a Platform as a Service (PaaS) product based on AWS, and is vastly different from Elastic Compute Cloud. It’s very important to differentiate ‘Infrastructure as a Service’ and ‘Platform as a Service’ solutions as we consider deploying and supporting our application using these two solutions.
Heroku is way simpler to use than AWS Elastic Compute Cloud. Perhaps it’s even too simple. But there’s a good reason for this simplicity. The Heroku platform equips us with a ready runtime environment and application servers. Plus, we benefit from seamless integration with various development instruments, a pre-installed operating system, and redundant servers.
Therefore, with Heroku, we don’t need to think about infrastructure management, unlike with AWS EC2. We only need to choose a subscription plan and change our plan when necessary.
That article does a good job explaining the differences between Heroku and AWS but it looks like you can choose other iaas (infrastructure) providers other than AWS. So ultimately Heroku seems to just simplify the process of using a cloud provider but at a cost.

Resources