How to talk with Kubernetes from inside the cluster ?

How to talk with Kubernetes from inside the cluster ?

Introduction

In the dynamic world of cloud-native development, Kubernetes is the go-to platform for managing containerized applications. While kubectl is the standard tool for interacting with Kubernetes clusters, there are scenarios where you may want to automate these interactions within your application code. This blog post will guide you through the basics of programmatically interacting with Kubernetes using Go, specifically from inside a Kubernetes cluster.

Prerequisites

Before diving into the code, ensure you have the following:

  • A running Kubernetes cluster.

  • Go installed on your machine.

  • The client-go library installed (go get k8s.io/client-go).

  • Access to your Kubernetes configuration file (~/.kube/config).

Code Walkthrough

Let's dive into the Go code that lists the Pods and Deployments in the "default" namespace of your Kubernetes cluster from inside the cluster.

Importing Required Packages

import (
    "context"
    "flag"
    "fmt"
    v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    "k8s.io/client-go/kubernetes"
    "k8s.io/client-go/rest"
    "k8s.io/client-go/tools/clientcmd"
)

Here, we import the necessary packages for Kubernetes API interactions and handling context and configuration.

Setting Up the Context and Configuration

ctx := context.Background()
kubeconfig := flag.String("kubeconfig", "/home/anish/.kube/config", "other path")
config, err := clientcmd.BuildConfigFromFlags("", *kubeconfig)
if err != nil {
    fmt.Printf("Error in building kubeconfig file %s", err.Error())
    config, err = rest.InClusterConfig()
    if err != nil {
        fmt.Printf("Error in config %s", err.Error())
    }
}

Explanation:

  • Context: Used to control the lifetime of requests to Kubernetes.

  • Kubeconfig: Specifies the path to the Kubernetes config file.

  • BuildConfigFromFlags: This method loads the Kubernetes configuration from the specified file.

  • InClusterConfig: If the application is running inside the Kubernetes cluster, this function automatically configures the application to interact with the cluster using the service account's credentials.

Creating the Kubernetes Client

clientset, err := kubernetes.NewForConfig(config)
if err != nil {
    fmt.Printf("Error in creating the client set %s ", err.Error())
}

The clientset is the main interface to interact with Kubernetes. It is created using the loaded configuration.

Listing Pods in the Default Namespace

pods, err := clientset.CoreV1().Pods("default").List(ctx, v1.ListOptions{})
if err != nil {
    fmt.Printf("Error in Listing the pod %s ", err.Error())
}
fmt.Println("The pods are:")
for _, pod := range pods.Items {
    fmt.Printf("%s\n", pod.Name)
}

This section lists all the pods in the "default" namespace and prints their names.

Listing Deployments in the Default Namespace

deployments, err := clientset.AppsV1().Deployments("default").List(ctx, v1.ListOptions{})
if err != nil {
    fmt.Printf("Error in Listing the deployment %s\n ", err.Error())
    return
}
fmt.Println("The deployments are:")
for _, d := range deployments.Items {
    fmt.Printf("%s\n", d.Name)
}

Similarly, this part lists all the deployments in the "default" namespace and prints their names.

Running the Application Inside the Cluster

Building the Docker Image with ko

Instead of writing a Dockerfile, we can use ko, a tool for building Go applications into container images.

Installation Guide

  • Install Go: Ensure you have Go installed on your machine. If not, download it from golang.org.

  • Install ko: You can install ko by running the following command:

      go install github.com/google/ko@latest
    
  • Configure Docker: Ensure Docker is running on your machine and that ko is configured to push images to your preferred container registry.

Creating the Docker Image

  • Run ko: Use ko to build and push the Docker image for your Go application:

    Here , i used ttl registry .

      KO_DOCKER_REPO=ttl.sh/anish ko build
    

    This command will build your Go application into a container image and push it to the specified registry.

    Once it successful you'll see output like below and last line is your docker image.

Deploying and Running the Application

Once the Docker image is built, deploy it to your Kubernetes cluster as a pod

kubectl run test --image ttl.sh/anish/go-clientt-6927216a823fed3a5da707447f2a833a@sha256:cd17ef98398d18c16e3a0a9b153050171a9b00600b3f8d2f8d3c8f79af167f7a

Role and RoleBinding for Service Account

Since the application runs inside the cluster, it interacts with the Kubernetes API as a service account. To list Pods and Deployments, you need to grant the necessary permissions.

Create Role and RoleBinding

  • Role: Create a Role that allows listing Pods and Deployments in the "default" namespace.

      kubectl create role pod-deploy-list-role \
        --verb=list
        --resource=pods,deployments
    
  • RoleBinding: Bind the Role to the default service account in the "default" namespace.

      kubectl create rolebinding pod-deploy-list-binding \
        --role=pod-deploy-list-role \
        --serviceaccount=default:default
    

Output

if you check the logs of the pod kubectl logs test , then you will see the list of the pod and deployment as a output.

Conclusion

This simple Go program demonstrates how to programmatically interact with a Kubernetes cluster using the Kubernetes Go client library, now from inside the cluster. Whether listing pods, deployments, or other resources, the client-go library provides a powerful and flexible way to automate tasks in your Kubernetes environment.