This documentation provides an in-depth step-by-step guide to deploying a project using the kubernetes/client-go library for production environments. It assumes familiarity with Kubernetes concepts and the client-go library.

Prerequisites

  1. Go Environment: Ensure you have Go installed and set up properly.
  2. Kubernetes Cluster: You need an active Kubernetes cluster, with access configured to interact with it.

Module Setup

Before deploying your application, ensure you are using the correct Golang module.

go mod init k8s.io/client-go

It is crucial not to use -mod=vendor during your build process, as it affects the module’s output.

Building Your Application

Write your application in Go, ensuring to utilize client-go for Kubernetes interactions.

package main

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

func main() {
    // Load the kubeconfig file
    kubeconfig := "/path/to/your/kubeconfig"
    config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
    if err != nil {
        panic(err.Error())
    }

    // Create a clientset
    clientset, err := kubernetes.NewForConfig(config)
    if err != nil {
        panic(err.Error())
    }

    // Example: List Deployments
    deploymentsClient := clientset.AppsV1().Deployments("default")
    deploymentList, err := deploymentsClient.List(context.Background(), metav1.ListOptions{})
    if err != nil {
        panic(err.Error())
    }

    for _, d := range deploymentList.Items {
        fmt.Printf("Deployment Name: %s\n", d.Name)
    }
}

Dockerfile

Create a Dockerfile to containerize your application. The following example assumes your application binary is named app.

# Use the official Golang image for building your app
FROM golang:1.20 as builder

# Set the Current Working Directory inside the container
WORKDIR /app

# Copy go.mod and go.sum files
COPY go.mod go.sum ./

# Download all dependencies. Dependencies will be cached if the go.mod and go.sum files are not changed
RUN go mod download

# Copy the source code into the container
COPY . .

# Build the Go app
RUN CGO_ENABLED=0 GOOS=linux go build -o app .

# Start a new stage from scratch
FROM alpine:latest  

# Copy the Pre-built binary file from the previous stage
COPY --from=builder /app/app .

# Command to run the executable
ENTRYPOINT ["/app"]

Deployment Operations

Example: Create, Update, and Delete Deployment

To perform operations on the Deployment resource, you can follow the example code that demonstrates the fundamental operations such as Create, List, Update, and Delete.

  1. Creating a Deployment:
func createDeployment(clientset *kubernetes.Clientset) {
    // Define the deployment
    deployment := &appsv1.Deployment{
        ObjectMeta: metav1.ObjectMeta{
            Name: "demo-deployment",
        },
        Spec: appsv1.DeploymentSpec{
            Replicas: int32Ptr(1),
            Selector: &metav1.LabelSelector{
                MatchLabels: map[string]string{"app": "demo"},
            },
            Template: corev1.PodTemplateSpec{
                ObjectMeta: metav1.ObjectMeta{
                    Labels: map[string]string{"app": "demo"},
                },
                Spec: corev1.PodSpec{
                    Containers: []corev1.Container{
                        {
                            Name:  "nginx",
                            Image: "nginx:1.14.2",
                        },
                    },
                },
            },
        },
    }

    // Create the deployment
    deploymentsClient := clientset.AppsV1().Deployments("default")
    result, err := deploymentsClient.Create(context.Background(), deployment, metav1.CreateOptions{})
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("Created deployment %q.\n", result.GetObjectMeta().GetName())
}
  1. Listing Deployments:
func listDeployments(clientset *kubernetes.Clientset) {
    deploymentsClient := clientset.AppsV1().Deployments("default")
    deploymentList, err := deploymentsClient.List(context.Background(), metav1.ListOptions{})
    if err != nil {
        panic(err.Error())
    }

    for _, d := range deploymentList.Items {
        fmt.Printf("Deployment Name: %s\n", d.Name)
    }
}
  1. Updating a Deployment:
func updateDeployment(clientset *kubernetes.Clientset) {
    deploymentsClient := clientset.AppsV1().Deployments("default")
    deployment, err := deploymentsClient.Get(context.Background(), "demo-deployment", metav1.GetOptions{})
    if err != nil {
        panic(err.Error())
    }
    
    deployment.Spec.Template.Spec.Containers[0].Image = "nginx:1.16.1"

    result, err := deploymentsClient.Update(context.Background(), deployment, metav1.UpdateOptions{})
    if err != nil {
        panic(err.Error())
    }
    fmt.Printf("Updated deployment %q.\n", result.GetObjectMeta().GetName())
}
  1. Deleting a Deployment:
func deleteDeployment(clientset *kubernetes.Clientset) {
    deploymentsClient := clientset.AppsV1().Deployments("default")
    deletePolicy := metav1.DeletePropagationForeground
    if err := deploymentsClient.Delete(context.Background(), "demo-deployment", metav1.DeleteOptions{
        PropagationPolicy: &deletePolicy,
    }); err != nil {
        panic(err.Error())
    }
    fmt.Println("Deleted deployment")
}

Conclusion

The above guide demonstrates how to deploy and manage Kubernetes resources using the kubernetes/client-go library. The provided examples illustrate the essential operations required in a production deployment scenario. Ensure to follow best practices for error handling and logging in a production environment.