Enjoy Kubernetes with Python

9931

Over the past few years it seems that every cool and trending project is using Golang, but I am a Python guy and I feel a bit left out!

Kubernetes is no stranger to this, it is written in Go, and most clients that you will find are based on the Go client. Building a Kubernetes client has become easier. The Go client is now in its own repository. Therefore, if you want to write in Go, you can just import the Go client and not the entirety of the Kubernetes source code. Also, the Kubernetes API specification follows the OpenAPI standardization effort. If you want to use another language, you can use the OpenAPI specification and auto-generate one.

A couple weeks ago, the Python in me was awakened by a new incubator project for Kubernetes: a Python client almost single-handedly developed by Google engineer @mbohlool. The client is now available on PyPi and — like most Python packages — easily installable from source. To be fair, there already existed a Python client that was built on the Swagger specification but it received little attention.

So, let’s have a look at this new Python client for Kubernetes and take it for a spin.

Getting It

As always the easiest way is to get it from PyPi:


pip install kubernetes


Or get it from source:


pip install git+https://github.com/kubernetes-incubator/client-python.git


Or clone it and build locally:


git clone https://github.com/kubernetes-incubator/client-python.git

cd client-python

python ./setup.py install


Whatever you prefer.

Once installed, you should be able to start Python and import the kubernetes module. Check that your installation went fine.


$ python

Python 2.7.12 (default, Oct 11 2016, 14:42:23) 

[GCC 4.2.1 Compatible Apple LLVM 7.0.2 (clang-700.1.81)] on darwin

Type "help", "copyright", "credits" or "license" for more information.

>>> import kubernetes


Note that you can use Python 2.7 and Python 3.5

To get started using it, you will need a working Kubernetes endpoint. If you do not have one handy, use minikube.

Structure

Before we dive straight into examples, we need to look at the structure of the client. Most of the code is auto-generated. Each Kubernetes API group endpoint is usable and needs to be instantiated separately.

For example:

  • The basic resources (e.g., pods, services) will need the v1 stable API endpoint: kubernetes.client.CoreV1Api

  • The jobs resources will need the Batch endpoint: kubernetes.client.BatchV1Api

  • The deployments will need the Extensions endpoint: kubernetes.client.ExtensionsV1beta1Api

  • The horizontal pod autoscalers will need the Autoscaling endpoint: kubernetes.client.AutoscalingV1Api

In each of these endpoints, the REST methods for all resources will be available as separate Python functions. For example:

  • list_namespaces()

  • delete_namespace()

  • create_namespace()

  • patch_namespace()

The response from these method calls will be dictionaries that you can easily explore with Python.

The part that will take the most time is that, this client is a very low-level client. It can do almost everything you can do with the Kubernetes API, but it does not have any high-level wrappers to make your life easy.

For instance, creating your first Pod will involve going through the auto-generated documentation and finding out all the classes that you need to instantiate to define your Pod specification properly. I will save you some time and show you how, but the process will need to be repeated for all resources.

Example

The client can read your kubeconfig file, but the easiest configuration possible might be to run a proxy kubectl proxy then open Python, create the V1 API endpoint, and list your nodes.



>>> from kubernetes import client,config

>>> client.Configuration().host="http://localhost:8080"

>>> v1=client.CoreV1Api()

>>> v1.list_node()

...

>>> v1.list_node().items[0].metadata.name

minikube


Now the fun with Python starts. Try to list your namespaces:



>>> for ns in v1.list_namespace().items:

...     print ns.metadata.name  

...

default

kube-system


To create a resource, you will need the endpoint the resource is in and some type of body. Because the API version and kind will be implicitly known by the endpoint and the function name, you will only need to create some metadata and probably some specification.

For example, to create a namespace, we need an instance of the namespace class, and we need to set the name of the namespace in the metadata. The metadata is yet another instance of a class.



>>> body = client.V1Namespace()

>>> body.metadata = client.V1ObjectMeta(name="linuxcon")

>>> v1.create_namespace(body)


Deleting a namespace is a little bit simpler but you need to specify some deletion options.



v1.delete_namespace(name="linuxcon", body=client.V1DeleteOptions())


Now I cannot leave you without starting a Pod. A Pod is made of metadata and a specification. The specification contains a list of containers and volumes. In its simple form, a Pod will have a single container and no volumes. Let’s start a busybox Pod. It will use the busybox image and just sleep. In the example below, you can see that we have a few classes:

  • V1Pod for the overall pod.

  • V1ObjectMeta for metadata

  • V1PodSpec for the pod specification

  • V1Container for the container that runs in the Pod

Let’s instantiate a pod and set its metadata, which include its name:



>>> pod = client.V1Pod()

>>> pod.metadata = client.V1ObjectMeta(name="busybox")


Now let’s define the container that will run in the Pod:



>>> container = client.V1Container()

>>> container.image = "busybox"

>>> container.args = ["sleep", "3600"]

>>> container.name = "busybox"


Now let's define the Pod’s specification, in our case, a single container:



>>> spec = client. V1PodSpec()

>>> spec.containers = [container]

>>> pod.spec = spec


And, finally, we are ready to create our Pod in Python:



>>> v1.create_namespaced_pod(namespace="default",body=pod)


We’ll see if the community (i.e., us) decides to add some convenience functions to the Kubernetes python client. Things like kubectl run ghost –image-ghost are quite powerful, and although it can be easily coded with this Python module, it might be worthwhile to make it a first-class function.

Read the previous articles in this series:

Getting Started With Kubernetes Is Easy With Minikube

Rolling Updates and Rollbacks using Kubernetes Deployments

Helm: The Kubernetes Package Manager

Federating Your Kubernetes Clusters — The New Road to Hybrid Clouds

Want to learn more about Kubernetes? Check out the new, online, self-paced Kubernetes Fundamentals course from The Linux Foundation. Sign Up Now!

Sebastien Goasguen (@sebgoa) is a long time open source contributor. A member of the Apache Software Foundation and the Kubernetes organization, he is also the author of the O’Reilly Docker cookbook. He recently founded skippbox, which offers solutions, services and training for Kubernetes.