Over a million developers have joined DZone.

Building the Kubernetes go-client Using dep

DZone's Guide to

Building the Kubernetes go-client Using dep

Bring Go to Kubernetes using dep to help manage your dependencies along the way. Here we dive into how dep works and how you can use it to build Kubernetes apps.

· Cloud Zone ·
Free Resource

Learn how to migrate and modernize stateless applications and run them in a Kubernetes cluster.

Kubernetes is an extensible system with a powerful API. A common problem is to compile the Kubernetes go-client, without errors due to dependencies.

In this post, I will show the steps to resolve dependencies using dep, the new Golang dependency manager developed with the goal of becoming part of the Go toolchain.

Managing dependencies has been an active topic for Golang (if you are interested in the details see: The Saga of Go Dependency Management).While dep is still new and changing, as of recently, it is considered ready for production use!

A major advantage of dep is that it does not clog up your local GOPATH with dependencies. You can now have a single GOPATH and manage several projects, and their dependencies, in it. (If you prefer using godep, check out this great post from Andy Goldstein at Heptio.)

Briefly, the way dep works is that you have to manage dependencies using your “Gopkg.toml” file, and dep uses this file and its dependency analysis to produce a “Gopkg.lock” file. These files are version controlled – it’s optional to check-in the vendor folder. If you want more information on dep, here is an excellent presentation by Carolyn Van Slyck at Rackspace.

Image title

Here are the steps to build a project that uses the client-go library

Step 1: Write Code That References client-go

To manage a dependency, dep requires you have code that references the external package. A great reference to writing custom Kubernetes controllers, or other applications that use the Kubernetes API, is this KubeCon talk by Aaron Levy from CoreOS.

Using some of the techniques Aaron covers, here is a simple main.go file that initializes a Kubernetes client and lists all Pods in the cluster:

package main

import (

    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"

// optional - local kubeconfig for testing
var kubeconfig = flag.String("kubeconfig", "", "Path to a kubeconfig file")

func main() {

    // send logs to stderr so we can use 'kubectl logs'
    flag.Set("logtostderr", "true")
    flag.Set("v", "3")

    config, err: = getConfig( * kubeconfig)
    if err != nil {
        glog.Errorf("Failed to load client config: %v", err)

    // build the Kubernetes client
    client, err: = kubernetes.NewForConfig(config)
    if err != nil {
        glog.Errorf("Failed to create kubernetes client: %v", err)

    // list pods
    pods, err: = client.CoreV1().Pods("").List(metav1.ListOptions {})
    if err != nil {
        glog.Errorf("Failed to retrieve pods: %v", err)

    for _, p: = range pods.Items {
        glog.V(3).Infof("Found pods: %s/%s", p.Namespace, p.Name)

func getConfig(kubeconfig string)( * rest.Config, error) {
    if kubeconfig != "" {
        return clientcmd.BuildConfigFromFlags("", kubeconfig)

    return rest.InClusterConfig()

Step 2: Run ‘dep init’

Once you have some code that references client-go, you can run dep to automatically analyze dependencies and generate the vendor artifacts:

dep init -v

This may take a while to complete. The “-v” flag provides details on the dependency analysis.

Step 3: Update the client-go Version in Gopkg.toml

When dep completes, it will generate a Gopkg.toml file. Update this to the version of client-go you want to use. Currently “v4.0.0-beta.0” is a good option:

name = "k8s.io/client-go"
version = "v4.0.0-beta.0"

Step 4: Update the API Dependency in Gopkg.toml

Next, we need to make another edit to Gopkg.toml. The Kubernetes client-go depends on the API packages. So, we need to determine the correct revisions to use.

The easiest way to determine this is to check the client-go Git repo. For example, since I selected the “v4.0.0-beta.0” version I can browse to https://github.com/kubernetes/client-go/tree/v4.0.0-beta.0

Then select Godeps and view the Godeps.json file. In there, searching for “apimachinery” reveals the revision used to compile the “v4.0.0-beta.0” version of client-go:

    "ImportPath": "k8s.io/apimachinery/pkg/api/errors",
    "Rev": "abe34e4f5b4413c282a83011892cbeea5b32223b"

Copy this revision and add it to the Gopkg.toml file as an override. The final Gopkg.toml should look like this:

# Gopkg.toml example
# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md
# for detailed Gopkg.toml documentation.
# required = ["github.com/user/thing/cmd/thing"]
# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"]
# [[constraint]]
#   name = "github.com/user/project"
#   version = "1.0.0"
# [[constraint]]
#   name = "github.com/user/project2"
#   branch = "dev"
#   source = "github.com/myfork/project2"
# [[override]]
#  name = "github.com/x/y"
#  version = "2.4.0"

  branch = "master"
  name = "github.com/golang/glog"

  name = "k8s.io/client-go"
  version = "v4.0.0-beta.0"

  name = "k8s.io/apimachinery"
  revision = "abe34e4f5b4413c282a83011892cbeea5b32223b"

Step 5: Run ‘dep ensure’

Finally, run ‘dep ensure’ to re-generate the Gopkg.lock file and update the vendor folder:

dep ensure -v

Once this completes, you can build your code as you normally would:

go build -v


Kubernetes is a fast moving project and can seem daunting at first. It took me a few attempts, and lots of web searches, to figure out how to reliably compile and build applications that use the client-go package. I hope this post helps some of you avoid that pain and gets started with building Kubernetes solutions more easily.

Join us in exploring application and infrastructure changes required for running scalable, observable, and portable apps on Kubernetes.

cloud ,kubernetes ,golang ,dependency management ,tutorial

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}