Kevin Turcios

Software Engineer and Open Source Contributor

Get Started with the Kubernetes Client on OpenFaaS

January 18, 2018

OpenFaaS is an open source framework created by Alex Ellis for building and deploying serverless functions on Docker and Kubernetes. From the moment I discovered the project I’ve been fascinated by the concept of being able to write a function in any language I want, and use it immediately through a REST API. The best part is that you get all of the beauty comes along with Docker and Kubernetes, such as portability, scalability, consistency, and much more. If you want to get started with some of the basics, the OpenFaaS community has put together a great set of labs that will walk you through from creating your first function to some advanced concepts like auto-scaling your functions.

openfaas banner

Prerequisites

Before we begin, I’m going to assume you have installed and setup a development Kubernetes cluster with OpenFaaS and the OpenFaaS CLI, faas-cli. If you have not done so, the links below should help you get started.

Let’s get started

In order to accomplish this task were going to do five main things:

  1. Create and write the function
  2. Update the OpenFaaS Python template build options to support the Kubernetes Python client
  3. Create a read-only role for our function
  4. Build, push, and deploy our new function
  5. Test out our new function through the OpenFaaS UI

Creating and writing our function

First, we’re going to create a new python function by running:

faas-cli new --lang python get-all-pods --prefix <YOUR_DOCKERHUB_USERNAME> --gateway http://127.0.0.1:31112

This will create a new folder for you named get-all-pods and a YAML file named get-all-pods.yml. Open up the new folder and you will see two more new files in there, handler.py and requirements.txt. handler.py is where our code will go and requirements.txt is where we’ll list any dependencies we need for our function. Since we’ll be working with the Official Kubernetes Python client, let’s add it as a dependency for our function by adding the following line to our requirements.txt.

kubernetes

By default, the latest stable version of the Kubernetes Python client will be installed when we build our function, which at the time of writing this is version 8.0.1.

Now, let’s update our handler.py to call the Kubernetes API to retrieve a list of all pods in every namespace.

from kubernetes import client, config
def handle(req):
   config.load_incluster_config()
   v1 = client.CoreV1Api()
   print("Listing pods with their IPs:")
   ret = v1.list_pod_for_all_namespaces(watch=False)
   for i in ret.items:
      print("%s\t%s\t%s" %
         (i.status.pod_ip, i.metadata.namespace, i.metadata.name))

Updating the OpenFaaS Python template build options

Before we build our function, the Kubernetes Python client has a few extra dependencies that do not come bundled along with the python:2.7-alpine image that our function is based from. These dependencies are not simply Python packages, otherwise we would just throw them into our requirements.txt file! Instead, they’re Alpine Linux package dependencies that the Kubernetes Python client needs, so how do we get these dependencies into our function without having to define our own Dockerfile for the function?

Thankfully, every function template comes with a template.yml file that allows us to define any additional dependencies that our function may need during build time. This gives us the flexibility to build individual functions with different dependencies without having to redefine the entire Python template. So let’s add our dependencies.

When we created the function using the command faas-cli new --lang python ... it created a new folder for you named template. If you open up this folder, you’ll find a list of all the official templates that OpenFaaS provides. Under this folder, locate and open the python folder (not the python3, python-armhf, or python3-armhf folders!) and open the file named template.yml. You’ll see a section titled build_options with different sets of packages that the community has provided for you to choose to build along with your function (e.g. dev, mysql, pillow). What we’re going to do is add a new set of build options, specifically for our Kubernetes client. At the bottom of the template.yml file add the following:

- name:kubernetes-client
  packages:
   - g++
   - libffi-dev
   - openssl-dev

Make sure you keep an identical format to the other build options!

Creating a read-only role for our function

By default, the namespace that our function is deployed in, openfaas-fn, does not have privileges to access the pod resources across the cluster. In order to grant our namespace permission, we’re going to create a ClusterRoleBinding that will give it read-only access to most of the Kubernetes resources. Special thanks to Stefan Prodan for providing an excellent example on how to achieve this with a YAML file named readonly-role.yml that will contain the following:

apiVersion: rbac.authorization.k8s.io/v1beta1
kind: ClusterRoleBinding
metadata:
  name: openfaas-fn-view
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: view
subjects:
- apiGroup: rbac.authorization.k8s.io
  kind: User
  name: system:serviceaccount:openfaas-fn:default

Once you’ve created this file, let’s apply the role.

kubectl apply -f readonly-role.yml

Building, pushing, and deploying our new function

To build, push, and deploy our new function, it’s going to require an additional flag to add along with the faas-cli. If you’re unfamiliar with the faas-cli, I suggest you read Alex Ellis’ blog post on tips for using the faas-cli because the next command that we’ll be running will build, push, and deploy our new function all in one command! Here’s the command to run:

faas-cli up --build-option kubernetes-client -f get-all-pods.yml

One thing to note, if you get an error that the function could not be pushed to Docker Hub, make sure that you’re logged in to your Docker account first and try the command again.

Testing our new function

The previous command should have also deployed our new function to OpenFaaS, so let’s check it out through the OpenFaaS UI by navigating to the following page through your web browser.

http://<MINIKUBE_IP>:31112/ui/

You should now see our new function, get-all-pods listed on the left side. Let’s click on it and once you see that it has the “Ready” status on the top, click “Invoke” (don’t worry about passing in any text as our function does not require any parameters). You should finally see a list of all the Pods from every namespace running on your cluster! Mine looks like the following:

Listing pods with their IPs:
None docker compose-74649b4db6-5xgvw
10.1.0.24 docker compose-74649b4db6-p6f9z
None docker compose-api-58dc5c6787-f67rh
192.168.65.3 docker compose-api-58dc5c6787-nlm8k
192.168.65.3 kube-system etcd-docker-for-desktop
192.168.65.3 kube-system kube-apiserver-docker-for-desktop
192.168.65.3 kube-system kube-controller-manager-docker-for-desktop
10.1.0.16 kube-system kube-dns-86f4d74b45-tm284
192.168.65.3 kube-system kube-proxy-cmg7s
192.168.65.3 kube-system kube-scheduler-docker-for-desktop
10.1.0.33 openfaas-fn base64-5788bd657f-d58hs
10.1.0.81 openfaas-fn create-cron-job-78f8f55777-jnhbj
10.1.0.76 openfaas-fn cron-56c97f5b85-ld8sf
10.1.0.31 openfaas-fn echoit-84475b8587-tbsfz
10.1.0.82 openfaas-fn get-all-pods-5f9fb7f44f-jq82t
10.1.0.77 openfaas-fn get-pods-74f555b94b-k7t8f
10.1.0.34 openfaas-fn hubstats-74b4f64df8-kjlrw
10.1.0.35 openfaas-fn markdown-6cdf46ffd6-xmh6f
10.1.0.36 openfaas-fn nodeinfo-68d67f495-r6vff
10.1.0.32 openfaas-fn wordcount-5db68f44d9-xvhgn
10.1.0.21 openfaas alertmanager-f5b4dfb8b-v857g
10.1.0.17 openfaas gateway-5c57968dd6-55tlk
10.1.0.23 openfaas nats-776b844b7-67mt4
10.1.0.18 openfaas prometheus-7d78d54b57-kxrg2
10.1.0.22 openfaas queue-worker-68c56d7ff6-nrms4

What you’re seeing here is the result of all the pods running from every namespace being listed because we were able to get this information with the Kubernetes Python client. Pretty cool, right?

Wrapping up

This was my very first time writing a blog post so I hope you enjoyed it and learned a thing or two! I would encourage you to test out some more functionality that the Kubernetes Python client has to offer and to also get involved with the growing OpenFaaS community. If you wish to view all of the source code for this post, it is available at my GitHub account https://github.com/kturcios/get-all-pods.

Share This Post