7 ms·
Show HN: Kr8s – a Python client library for Kubernetes
Hey folks. I'm the author of kr8s.
I’ve been working on kr8s for a while now and one of my core goals is to build a Python library for Kubernetes that is the most simple, readable and produces the most maintainable code. It should enable folks to write clean code when working with the Kubernetes API.
If you're interested in how it compares with other libraries then check out [this post](https://jacobtomlinson.dev/posts/2023/comparison-of-kr8s-vs-other-python-libraries-for-kubernetes/ https://jacobtomlinson.dev/posts/2023/comparison-of-kr8s-vs-...).
Happy to answer any questions you might have in the comments here .
- techdragon 3y agoI used this in my KiwiPyCon conference talk yesterday! I used it with Kopf to write a basic little kubernetes operator in Python. Wish I had seen this thread before my talk, but the YouTube video will be online soon and I can link to it when they are uploaded.
- kungfufrog 3y agoThis looks great, will be giving it a go today to replace some increasingly complex bash scripts!
- jacobtomlinson 3y agoAwesome! Let me know how you get on and don't hesitate to open issues if you run into problems or have thoughts about the API design.
- kungfufrog 3y agoWithout opening a philosophical discussion on Python package management what were the pragmatic reasons from switching from Poetry to Hatch? I'm about to run my first bit of kr8s code!
- jacobtomlinson 3y agoPoetry is a locking package manager. That’s extremely useful for applications where you don’t want dependencies to drift. However for a library you want pinning a to be looser so the benefits of poetry aren’t as strong. Given that hatch is the official method from the PyPA it felt like a better choice.
- usrk0123961 3y agoWhy not just use the official python kubernetes client? https://github.com/kubernetes-client/python https://github.com/kubernetes-client/python
- jacobtomlinson 3y agoI built kr8s because the official autogenerated library is extremely verbose, low level and hard to use. Kr8s is modelled after kubectl instead of the REST API to try and be more accessible to developers.
- alpb 3y agoThese low-level constructs in the client libraries exist so that people can build controllers and operators on top of it, no? There's a lot that goes into making of implementing a Kubernetes client such as keeping up with semantic changes (dry run, server-side apply, tracing, rate limiting, patch support etc). Does your library also cover these?
- jacobtomlinson 3y agoAnything you can do with the official library you can do with kr8s. Some things will require writing low level HTTP requests if we haven’t implemented them yet, but it’s not so different to the official low level auto generated API. The goal here is to make easy things easy, while ensuring anything is possible.
- galenmarchetti 3y agoseconding the answer given by OP...I've also found the raw clients very low level and hard to use. I appreciate the higher level abstraction here, emphasis on "batteries included" and usability mirroring kubectl
- dharmab 3y agoThe official python client does not have feature parity with kubectl; I had to reimplement parts of kubectl in my own scripts, like the 'apply' and 'exec' subcommands and less-flaky CRD deployments.
- dbragdon 3y agoAwesome library, but I can't view the documentation at work since the doc site uses http. Please consider using https.
- whalesalad 3y agohttps://docs.kr8s.org/en/latest/ https://docs.kr8s.org/en/latest/
- jacobtomlinson 3y agoThe docs does use https. Let me know where you found an http link so I can fix it. https://docs.kr8s.org/en/latest/ https://docs.kr8s.org/en/latest/
- dbragdon 3y agoInteresting, I'm seeing an invalid certificate warning when I visit the site, it might be on my end. Awesome project nonetheless!
- theptip 3y agoIn the past I used PyKube (https://pykube.readthedocs.io/en/latest/readme.html https://pykube.readthedocs.io/en/latest/readme.html), which did the job. One issue that pykube has is that there is no autocomplete on API object fields. Does kr8s wire this up? Seems you could use a TypedDict on newer versions of Python. Back in the old days you wouldn't get autocomplete on k8s YAML files either, but now the schema is well-known and so your IDE will complete all the fields (even CRDs). These days you get this with Pulumi, if I'm not mistaken.
- jacobtomlinson 3y agoI’m not exactly sure what you mean but we can definitely improve auto completion if that’s valuable. Maybe you could try it out and give us some feedback in an issue?
- theptip 3y agoAnother way of putting it would be - are your object manifests typed according to the OpenAPI schema? If we have: pod = Pod({ "apiVersion": "v1", "kind": "Pod", "metadata": { "name": "my-pod", }, "spec": { "containers": [{"name": "pause", "image": "gcr.io/google_containers/pause",}] }, }) Is there a mypy type for the dict to tell you that only specific keys are valid, and `apiVersion` etc. must be present? And will I get a squiggly in my IDE if I type `apiversion`?
- jacobtomlinson 3y agoNot currently. You might want to check out Lightkube for this. You can use Lightkube models with kr8s too.
- bjt12345 3y ago[flagged]
- gustavus 3y agoThe cycle of tooling Step 1: Look I've made this new great tool that uses a declarative language, you simply declare what you want your environment to look like and boom it will build it out. No more having to figure out a complicated logic flows that can fail or having code that dies on weird error cases, and you don't have to be a developer to use it. Step 2: The tool isn't powerful or flexible enough and the declarative code is getting to cumbersome so we've introduced some basic templating and logic flow to this tool to make it more flexible and reduce bloat. Step 3: The control flow isn't powerful enough to really meet our needs so we have moved it entirely to a full programming language. Step 4: Go back to step 1.
- aknfxb3m 3y agoSteps 1,2,3 create separate solutions that people can use as they see fit. You make it seem like there is no place for anything but a declarative programming language in this area.
- hitchstory 3y agoIt's often better to provide both - especially for something like k8s. Declarative languages and programming languages serve entirely different use cases. They no more preclude each other than garbage collected and non garbage collected programming languages like C and python do.
- jacurtis 3y agoTo be fair... k8s offers both: Write declarative code with yaml and kubectl. This solves most use cases and interactions. Write operators in a variety of languages (usually golang) if you need direct control of the underlying control loop, advanced resources, and other use cases to extend or customize how your cluster works. This is far more flexible and powerful than most people understand and of itself has layers ranging from moderate to very complex. Furthermore there is the api aggregation layer you can extend if you need to customize the core api of your cluster.
- deleted 3y ago[deleted]
- multani 3y agoThis looks really cool! I wrote a few applications using both the official Kubernetes client and the asyncio variant from Tomasz. Both have the same problems to me (that you exposed on the comparison page): The documentation is really terrible (it's even non-existent for kubernetes-asyncio). For the official client, it's hidden deep inside the repository, across hundreds of files (592 at the moment); half the link cross doc don't work, there are rendering issues, etc. It's really a gigantic mess. The API is extremely verbose, directly the underlying Kubernetes API exposed to Python. It gets the job done and it's better than shell script, but the verbosity + the total lack of a decent documentation (cf. above) makes it hard to use and see what you can do with it. Most of the time, you have to fire the REPL and try a bunch of calls until it makes sense. I like that most of the responses are proper objects, but they display as dict in the REPL and of course, the responses format are not documented in the doc :) Last but not least: they both lack support for fancy authentication mechanism. We go to Kubernetes through a fancy proxy that require specific TLS settings + an external exec plugin to get the credentials. The official Kubernetes client should have the right support (for what we need at least) in the next major version but the asyncio variant not yet (I made a PR to fix this, but this requires a new version of aiohttp which is not released yet...) Both clients are very similar for the autogenerated code, but also subtly different for all the things around so you can't really expect 100% that what works on one will work on the other. I'm not sure how kr8s works with this fancy auth system, but at least for the first 2 points, it seems like a huge win, I'll give it a try!
- jacobtomlinson 3y agoAwesome thanks! Kr8s supports the exec auth and TLS options. If you run into anything that’s missing though please raise an issue and we will get it added.
- doctorpangloss 3y agoI seem to be downvoted for this a lot, but responsive to issues like these… I write a ton of automations against k8s in Python by writing literately what I want, then asking GPT4 for the code. And it just works.
- Nullabillity 3y agoRequesting objects without a specific version/apigroup is pretty dangerous, you're effectively opting out of K8s' primary backwards compatibility measure.
- cpressland 3y agoI have literally just spent the last few weeks writing pydantic models for Kubernetes for an internal testing tool. I’ll see how this compares, it looks outstanding.
- jacobtomlinson 3y agoThanks!
- uneekname 3y agoThis is awesome. Jacob, your work on Dask Kubernetes has been immensely helpful to me. The world of distributed Python grows stronger!
- jacobtomlinson 3y agoThanks!
- bjt12345 3y agoHow do you connect remotely? The examples don't easily show this.
- jacobtomlinson 3y agoThe same way you do with kubectl, you configure your cluster in your kube config file. We can definitely add more examples though!
- bjt12345 3y agoThe Use case I have, is to use this within Jupyter notebooks for Devops / deployment journaling. Having something natively python that maps to actual commands is a huge bonus here.
- aknfxb3m 3y agoI stopped at the 3rd example. Kr8s and lightkube are the only solutions I'd dare to use.
- jacobtomlinson 3y agoLightkube is also awesome. The focus of kr8s is on simplicity, similarity to kubectl and having batteries-included. Lightkube focuses on type safety and API correctness. They also work together and you can cast Lightkube objects to kr8s and back again.
- willthames 3y agoThe comparison doesn’t include the (perhaps confusingly named) openshift library. All the ansible kubernetes modules rely heavily on it because its support for dynamic client (where you just want to apply a manifest and don’t know in advance that it’s a Deployment and a Service and a ConfigMap) is first rate.
- jacobtomlinson 3y agoWow I’ve not heard of that one! Do you have a link?
- willthames 3y agoHaha, I meant to add one to my comment but struggled to do so on mobile https://github.com/openshift/openshift-restclient-python https://github.com/openshift/openshift-restclient-python
- ledauphin 3y agodoes this provide sane default behavior for refreshing expired auth tokens and retrying random client timeouts? the "official" SDK has driven me absolutely crazy trying to wrap all the different pieces with retries so that basic long-running operations won't randomly raise spurious exceptions...
- jacobtomlinson 3y agoIt will retry expired auth but backing off the timeout is a good idea!
- snug 3y agoLooks great, but I'm bashing my head trying to figure out what the r means in kr8s?
- jacobtomlinson 3y agohttps://docs.kr8s.org/en/latest/branding.html https://docs.kr8s.org/en/latest/branding.html
- remram 3y agoNothing, they want it pronounced like "kraits". A krait is a type of sea snake, and Python is snake-themed.
- codetrotter 3y agoHow do you pronounce it? Krewbernetes? Krates?
- jacobtomlinson 3y agohttps://docs.kr8s.org/en/latest/branding.html https://docs.kr8s.org/en/latest/branding.html
- codetrotter 3y agoNice :)
- bdcravens 3y agoSeems to be a verbal namespace collision with Rust crates (assuming it's pronounced the same)
- jacobtomlinson 3y agoYup, naming things is hard!
- bovermyer 3y agoThere is sufficient contextual padding that I feel this is not a problem. I am unlikely to be talking about Rust crates anywhere near the same conversation as kr8s code.
- nyellin 3y agoTo put one more option out there, we use Hikaru (https://pypi.org/project/hikaru/ https://pypi.org/project/hikaru/) in Robusta.dev (https://github.com/robusta-dev/robusta https://github.com/robusta-dev/robusta) and have been pretty happy with it. Example code below: with Pod().read(name='thename', namespace='the-namespace') as p: p.labels['new-label'] = 'value'
- remram 3y agoDoes this read or also write?
- bovermyer 3y agoThis is delightful. I'll be taking it for a spin today.
- jacobtomlinson 3y agoThanks! Don’t hesitate to open issues if you find bugs or have feedback :)