Learn Kubernetes Programming — Part 1

Learn to programmatically talk to the Kubernetes cluster using the Official Client Go Library.

Introduction

In this Part 1 of "Learn Kubernetes Programming" series, we'll build a simple CLI program that connects to the Kubernetes cluster and displays the server version. In the process, you’ll get the taste of Go programming language and will be entering into the world of awesome Kubernetes Programming. So, buckle up, and put your programming hats on!

Fig: CLI In Action

Prepare Development Environment

Setup Kubernetes Cluster

To get started, we’ll need a Kubernetes cluster to interact with. For learning, we’ll use a Lightweight Kubernetes distribution called k3s by Rancher Labs

Here’s how easy it is to get a fully functional Kubernetes cluster up and running on Linux.

$ curl -sfL https://get.k3s.io | sh -$ k3s kubectl get node

From here on, we’ll interact with Kubernetes programmatically through the Kubernetes configuration written by k3s into /etc/rancher/k3s/k3s.yaml

Feel free to use any Kubernetes cluster you have running, as long as you have the kubeconfig file for it.

Setup Go environment

Kubernetes is written in Go. As such, Go programming language is treated as a first-class citizen to program in Kubernetes, given its official support by the Kubernetes community and tons of projects already written on it, to take it as a learning reference.

However, you are not tied to Go. Kubernetes maintains official libraries for many popular programming languages like Python ❤️, Javascript, etc. So, you have other options if programming in Go isn’t your cup of tea.

Alright, please go ahead and install Go on the platform of your choice using the steps described on the official website: https://go.dev/doc/install

On Linux: Go v1.18.2

$ wget https://go.dev/dl/go1.18.2.linux-amd64.tar.gz$ tar -C /usr/local -xzf go1.18.2.linux-amd64.tar.gz$ export PATH=$PATH:/usr/local/go/bin$ go version
go version go1.17.5 linux/amd64

Setup Go workspace

Now, that we have the Kubernetes cluster up and running, and Go installed. We can start preparing the Go workspace, as such:

$ mkdir -p $HOME/learn-kubernetes-programming/src$ export GOPATH=$HOME/learn-kubernetes-programming

💁GOPATH is a variable that defines the root of your workspace. By default, the workspace directory is a directory that is named go within your user home directory (~/go for Linux and MacOS). GOPATH stores your code base and all the files that are necessary for your development.

Let’s code

As you already know, we’ll be coding a simple hello-world CLI program that will connect to the Kubernetes cluster and displays the server version in the console. To facilitate interaction with Kubernetes API from the Go programming language, we’ll be using the official Go library called client-go.

Goal:

  • CLI will take a path to the kubeconfig via -kubeconfig flag similar to kubectl CLI.
  • CLI will then authenticate to Kubernetes API using kubeconfigthen makes calls to retrieve the server version and prints it to the console.

Again, here’s how it will look when it’s complete:

Prepare the directory and initialize the Go module

Let’s first, start by creating a directory called connecting to host the codebase for our CLI program.

$ cd $HOME/learn-kubernetes-programming/src
$ mkdir connecting

And initialize the directory as a Go module.

$ go mod init connecting
go: creating new go.mod: module connecting

💁 The go mod init command creates a go.mod file to track your code’s dependencies, in our case it will list the versions of client-go library packages that our code will depend upon.

Write code

Now, create a file called main.go containing the following code, which will be explained line-by-line below.

File: connecting/main.go
  • Line 1 — The first statement in a Go source file must be the package name. And executable commands must always use package main.
  • Line 3 to 7 — Imports flag package for parsing CLI options, os package for exiting the program when an error occurs in the code and log for logging to console with a timestamp.
  • Line 9 to 12 — Imports clientcmd package for working with kubeconfig file and kubernetes package for access Kubernetes API.
  • Line 14 to 20 — Initializes the kubeconfig flag and a variable kubeconfigto store the reference to the content of kubeconfig file.

💁 In Go init() function is useful to set up some form of state on the init️️ial start of your program, in our case setting up the CLI flags that program accepts.

  • Line 22 to 28 — Begins the main entry point of the program and starts off by parsing and verifying the flags. If the flag is not provided, shows the program usage and exits.
  • Line 30 to 33 — Here, we use the helper function called BuildConfigFromFlags from clientcmd package, that builds configs from a kubeconfig file. On success, it returnsrestclient.Config object, or we exit the program due to invalid kubeconfig file.
  • Line 35 — We call NewForConfigOrDie() from kubernetes packages, which gives us a new Clientset object for the given kubeconfig and exits the program if there is an error in the config.
  • Line 36 to 39 — Using the clientset object, we first call Discovery() to retrieve the DiscoveryClient and then callServerVersion() to get the Kubernetes server version. If there was an error calling DiscoveryClient() or ServerVersion(), we exit the program.
  • Line 40 — Finally, we print out the server version to the console.

Build and run the program

Now, go ahead and compile the source code by running go build inside the connectingdirectory.

💁 If you build with the flags -s -w you can strip out the debug information from the binary, thereby lowering the size of the executable.

$ go build -ldflags="-s -w"
Fig: Compile the source code

Once, the build succeeds, a binary called connecting will pop up in the same directory. Before running the program, ensure the Kubernetes cluster is up and running:

$ k3s kubectl get node

Wait…1,2,3. Go ahead and run it now!

$ ./connecting -kubeconfig /etc/rancher/k3s/k3s.yaml

Notice, how the program outputs the same server version, as output byk3s kubectl get node

🎉 Congratulations, our hello-world CLI program ran successfully!

Conclusion

In this article, we’ve covered the baby steps into the world of Kubernetes programming, by creating a simple CLI program that connects to the running Kubernetes cluster and printing the server version. In the next part, we’ll develop a more useful program. But until then, here’s a challenge. Extend this CLI with the following functionality:

  • List all the namespaces in the cluster
  • and count the number of pods running in each namespace.

Here’s a sneak peek of how that can be implemented with Gophers on your way.

Does that sound like fun? Why not give it try, and see if you can figure it out yourself and complete this challenge.

If you have any questions, need help, or complete this challenge, be sure to Tweet it and mention me @ptuladhar3 on Twitter.

🐦 Follow me on Twitter

--

--

--

Make Complex Simple (https://tuladhar.github.io)

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Puru Tuladhar

Puru Tuladhar

Make Complex Simple (https://tuladhar.github.io)

More from Medium

Develop a Docker Containerized Python API With Terraform, Gitlab, Kubernetes, and AWS

Kubernetes Source Code Overview: kube-controller-manager

Demystifying Kubernetes — Series intro and building a cluster

Your Ultimate Guide to Kubernetes