When writing a kubernetes controller I often use client-go to talk to the Kubernetes API. I'm beginning to realize though, that client-go isn't always the best approach, sometimes it can be simpler to use a hand rolled HTTP client, based on go's
Today, I want to share some of the Pros & Cons of using client-go, as I understand them, in Kubernetes controllers or other go applications.
Pros of using client-go
client-go comes with helpful utilities e.g to create in-cluster or out-of-cluster kubeconfig and authenticate against the API Server i.e
I end up using these in every Kubernetes app that I write.
Implementations for all kubernetes API Objects
I find unmarshalling kubernetes resources from JSON to go, pretty cumbersome, particularly if I need to access a deeply nested field e.g reading the
replicas from the
status of a Deployment object.
client-go handles marhsalling/unmarshalling of all compatible Kubernetes resources out of the box. So that's a big help.
Powerful abstractions for common use casses
Common use cases such as watching resources or testing API calls are well supported with abstractions like Shared Informers and fake-client.
Cons of using client-go
This by far the biggest frustration I have when using client-go. Just figuring out the right
k8s.io/api-machinery dependencies to match my
k8s.io/client-go version used to be a struggle. Thankfully with go modules and the new versioning scheme that's really improved.
I still get lost in all the imports regularly, with the sheer no. of structs and interfaces, it's not always clear if I actually need everything I'm importing. Integration tests written with the fake client can also be daunting for a new person to understand.
Sometimes this is just symptom of the scarce docs availble!
Even though there are now actually some hello-world examples in the client-go repo, docs for the go client are still pretty scarce. The first time I had to learn what Informers were, my choices? A random blog post or the actual code.
This means that my usage of the library is only as good as the latest blogpost/book/code I've read. I can understand feeling that way about a more complicated tool, like a Database, but should I have to feel this way about an HTTP client?
Not the most idiomatic go-code
Using client-go sometimes requires comitting generated code or dealing with
*string types. The library isn't always an example of the most idomatic go code.
This might be totally OK for experience go devs, but as someone still learning how to write good go code. I find this confusing.
I still think client-go is worth using for full fledge controllers, especially when dealing with multiple Kubernetes objects. For simple scripts, I'd like to invest more in just using plain go.
If you'd like to learn more about client-go, I can't recommend Programming Kubernetes by Michael Hausenblas and Stefan Schimanski enough!
Some other places:
Top comments (0)