Cloud Native Dev Tooling With Go

by Markus Zimmermann | 1367 words | ~7 min read

cloud-native-dev-tools-with-go/tools-hero-image.jpg

In the new Cloud Native world, operation tooling must enable DevOps teams for high productivity and fast flow to production. Architectures often contain dozens of microservices which need to be quickly deployed and operated in the cloud. This is a lot of additional management effort for developers and having separate operations teams does not scale to support all services of a project. Without good tooling that automates most of the day-to-day operation work away from developers, no large platform can be maintained for long. Automation is key!

What are Cloud Native Dev Tools?

The Cloud Native Computing Foundation (CNCF) officially defines Cloud Native as:

Cloud native technologies empower organizations to build and run scalable applications in modern, dynamic environments such as public, private, and hybrid clouds. Containers, service meshes, microservices, immutable infrastructure, and declarative APIs exemplify this approach. (Source).

Cloud Native technologies require Cloud Native Dev Tools to provide solutions for enabling Cloud Native applications to run on container platforms and make operations as automated as possible. Tools are needed for the full development flow of a Cloud Native application from development of containers to deployment of the container to the observability and security of the application itself.

DevOps Development Flow

DevOps Development Flow

Let’s look at some examples in how dev tools can support the different steps in the development flow:

Build:

  • Docker is the best example here, which helps developers build containers of their application locally, test the containers and then push them to any container registry in the cloud.
  • Vulnerability scanning tools like Trivy scan containers or application artifacts for vulnerabilities to prevent security incidents before the application is deployed in production.

Deploy:

  • Kubernetes deployments can be difficult to create with all the necessary resources for a single microservice. As such, blueprint templates for microservices are important and tools such as Helm help generalize the deployment of microservices throughout the whole project.
  • GitOps tooling such as ArgoCD help developers to deploy faster to Kubernetes without the need to write deployment scripts or adding authentication inside application deployment pipelines.

Operate:

  • The Command-line interface (CLI) every DevOps engineer needs in their toolkit is kubectl. It is the tool to manage everything inside a Kubernetes cluster. It is extendable through plugins which lets us integrate any customization within the CLI.
  • Kubernetes operators help with all regular operations tasks around a Kubernetes deployment. They enable auto-updating, self-monitoring and a self-healing infrastructure. There are operators for databases, cloud infrastructure provisioning or security needs. Check the OperatorHub for a curated list of Kubernetes operators.

Why use Go for Cloud Native Dev Tools?

What is the right tool to develop Cloud Native Dev Tools? Over the years, Go managed to position itself as the major language behind the Cloud Native stack. Docker, Kubernetes, Kubectl and many other known tools and infrastructure components are all implemented in Go.

Cloud Native Tools written in go

Cloud Native Tool examples written in go

Go is an open source language maintained by Google. The language has the following key advantages:

  • efficient garbage-collected systems programming language
  • easy to learn due to fewer language features
  • single, self contained binaries which can be built for nearly any platform and OS
  • out-of-the-box development tooling for testing, code formatting, dependency management

Choosing Go lets us participate in the vivid Cloud Native community and use the SDKs that power the Cloud Native stack to write our own Dev Tools.

Doing a Workshop for the community

For the betterCode in 2021, we (M.-Leander Reimer and Markus Zimmermann) created a workshop titled “Go for Operations” which introduced fellow software engineers to Cloud Native Dev Tooling in Go.

The workshop showed that everyone had different DevOps experiences in their jobs, from having strong compliance requirements to being able to quickly prototype their infrastructure. The Go knowledge-level was also mixed between beginners and advanced users. Through hands-on exercises, we showcased different operational automation concepts and showed how to implement them using Go. At the end, everyone took something home which they wanted to apply in their day-to-day operational work.

The content of the workshop is open-source and the exercise descriptions are written as step-by-step guides, so anyone can try the exercises themselves. Just visit our GitHub repository to go through the workshop!

Automation Concepts and their drivers

Let’s quickly go through some of the automation concepts that were part of the workshop to learn what libraries/frameworks are the drivers to implement such concepts in Go.

Building CLI applications with Cobra

Command-line interfaces (CLIs) are tools every developer is used to work with. They are faster to use than graphical interfaces and can be easily automated by calling them in Continuous Integration pipelines. kubectl is one example for a good CLI and used for managing Kubernetes clusters. It is written in Go and its implementation can be used as a blueprint for CLI applications. It uses the popular CLI libraries Cobra and Viper which are the main drivers of Go CLI applications. With these libraries, you can quickly write a CLI and gets many features such as auto-completion, help generation and config management as added bonuses.

You can do Challenge 1 of our workshop to learn how to use Cobra/Viper to write CLIs.

The result in the challenge is a working Kubectl plugin that creates chaos in our cluster to test the resilience of our deployed services. Kubectl plugins are easy to integrate since the installed binary simply needs to have the kubectl- prefix. The only limitation is that plugins cannot overwrite an already existing kubectl command. For example, you cannot create a plugin with the name kubectl-create because it collides with the kubectl command create.

Building a Sidecar container

Sidecars are an easy way to extend a deployed service in Kubernetes. It is a container that runs along-side your application inside the same pod. The sidecar shares storage volumes, networking and other things with the application container, thus it can be used for intercepting traffic, sharing files with the application or to add monitoring.

Such a sidecar container can be easily implemented with plain Go and due to a self-contained binary the container will be rather small.

Log shipping sidecar example

Log shipping sidecar example

Check out Challenge 2 of the workshop where you build a log shipping container which extends any application that only writes logs to disk to ship logs to any logging provider via standard Kubernetes log handling.

Building a Kubernetes Operator in Go

As mentioned earlier, Kubernetes operators help us with maintenance tasks that need to be automated in running Kubernetes deployments. Operators can define Custom Resources and manage their state with them. This is facilitated using the Custom Resource Definition extension of Kubernetes. One advantage of using Kubernetes custom resources is that they can be managed in the same way as your other Kubernetes resources. Operators have a working loop that watches for changes in their custom resources and act upon changes by doing actions inside Kubernetes on the resources they manage.

Kubernetes operators explained

Kubernetes operators explained

One popular framework for writing operators is Operator SDK. It features scaffolding, i.e. it generates all needed code and enables you to quickly write your operator and deploy it directly to a cluster.

Take a look at our Challenge 3 of the workshop where you build a microservice operator using Operator SDK that abstracts the Kubernetes resources which are necessary to deploy a microservice to Kubernetes. With this operator, you only need to define one resource to deploy a microservice instead of defining all needed Kubernetes resources like the Deployment and the Service.

Where to go from here?

This post should give you an introduction to Cloud Native Dev Tools and how to implement your own tools in the main language of the Cloud Native stack, Go. With the workshop exercises, you can get hands-on experience and implement Dev tools yourself. Maybe, they can help you at your work to automate some tedious job you need to do everyday and they give you room for more important tasks. We will try to continue doing the workshop at other conferences, to give more engineers experience in Go to write Cloud Native Dev tools and have an exchange on our experiences with the Cloud Native stack.

Image sources:

The Latest Posts