Comprehensive guide7 min read

Mastering Kubernetes APIs for Application Development

SFEIR Institute

Key Takeaways

  • The Kubernetes API is the single entry point for all cluster interactions
  • Master kubectl, client-go, and Custom Resources to control the orchestrator
  • Step-by-step guide with executable code and verification commands

The Kubernetes API is the heart of all cluster interactions. Every kubectl command, every deployment, every scaling operation goes through this REST API. For the Kubernetes Backend developer, understanding and mastering the Kubernetes API represents the difference between being controlled by the orchestrator and controlling it programmatically.

TL;DR: This guide walks you step by step through mastering the Kubernetes API: architecture, interactions via kubectl and client-go, creating Custom Resources, and building custom controllers. Each step includes executable code and verification commands.

These skills are at the core of the LFD459 Kubernetes for Application Developers training.


Prerequisites

Before starting, verify your environment meets these requirements:

ComponentMinimum VersionVerification
Kubernetes clusterv1.28+kubectl version --short
kubectlv1.28+kubectl version --client
Go (for client-go)1.21+go version
Cluster accesscluster-admin or configured RBACkubectl auth can-i create pods

Verify your cluster access:

kubectl cluster-info
# Expected result:
# Kubernetes control plane is running at https://127.0.0.1:6443
# CoreDNS is running at https://127.0.0.1:6443/api/v1/namespaces/kube-system/services/kube-dns:dns/proxy
Key takeaway: 82% of container users run Kubernetes in production (CNCF Annual Survey 2025). Mastering the API positions you on an essential industry standard.

Step 1: Understanding Kubernetes API Architecture

The Kubernetes API is a REST API organized into groups and versions. Each resource belongs to a specific API group.

1.1 Explore available API groups

List all API groups in your cluster:

kubectl api-versions
# Expected result (excerpt):
# apps/v1
# batch/v1
# networking.k8s.io/v1
# rbac.authorization.k8s.io/v1
# v1

Core resources (pods, services, configmaps) belong to the empty group, accessible via /api/v1. Extended resources use /apis//.

1.2 Discover resources in a group

Explore resources in the apps/v1 group:

kubectl api-resources --api-group=apps
# Expected result:
# NAME                  SHORTNAMES   APIVERSION   NAMESPACED   KIND
# deployments           deploy       apps/v1      true         Deployment
# replicasets           rs           apps/v1      true         ReplicaSet
# statefulsets          sts          apps/v1      true         StatefulSet
# daemonsets            ds           apps/v1      true         DaemonSet

Verification: Each resource exposes verbs (create, get, list, watch, update, delete). View them with:

kubectl api-resources --api-group=apps -o wide

This understanding is essential for designing containerized applications for Kubernetes.


Step 2: Interacting with the API via kubectl proxy

kubectl acts as an HTTP client to the API. For direct interactions, use kubectl proxy.

2.1 Start the local proxy

Launch the proxy in a separate terminal:

kubectl proxy --port=8080
# Expected result:
# Starting to serve on 127.0.0.1:8080

2.2 Query the API directly

List pods in the default namespace via curl:

curl http://localhost:8080/api/v1/namespaces/default/pods
# Expected result (JSON):
# {
#   "kind": "PodList",
#   "apiVersion": "v1",
#   "items": [...]
# }

Create a pod via the API:

curl -X POST http://localhost:8080/api/v1/namespaces/default/pods \
-H "Content-Type: application/json" \
-d '{
"apiVersion": "v1",
"kind": "Pod",
"metadata": {"name": "api-test-pod"},
"spec": {
"containers": [{
"name": "nginx",
"image": "nginx:1.25"
}]
}
}'

Verification:

kubectl get pod api-test-pod
# Expected result:
# NAME           READY   STATUS    RESTARTS   AGE
# api-test-pod   1/1     Running   0          30s
Key takeaway: Every kubectl command translates your intentions into HTTP requests to the API. Understanding this mechanism lets you debug effectively and automate via any language.

Step 3: Using client-go for Go Development

For Kubernetes Backend developers working in Go, client-go is the official library for API interactions. It offers strong typing, watchers, and informers.

3.1 Initialize a Go project

Create the project structure:

mkdir k8s-api-demo && cd k8s-api-demo
go mod init k8s-api-demo
go get k8s.io/client-go@v0.29.0
go get k8s.io/apimachinery@v0.29.0

3.2 List pods with client-go

Create the main.go file:

package main

import (
"context"
"fmt"
"os"
"path/filepath"

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

func main() {
// Load kubeconfig configuration
kubeconfig := filepath.Join(os.Getenv("HOME"), ".kube", "config")
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
if err != nil {
panic(err)
}

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

// List pods in the default namespace
pods, err := clientset.CoreV1().Pods("default").List(
context.TODO(),
metav1.ListOptions{},
)
if err != nil {
panic(err)
}

fmt.Printf("Number of pods: %d\n", len(pods.Items))
for _, pod := range pods.Items {
fmt.Printf("- %s (%s)\n", pod.Name, pod.Status.Phase)
}
}

Run the program:

go run main.go
# Expected result:
# Number of pods: 2
# - api-test-pod (Running)
# - another-pod (Running)

This programmatic approach is covered in essential kubectl commands for developers and deepened in the LFD459 training.


Step 4: Creating Custom Resources (CRD)

Custom Resources Kubernetes API allow extending the API with your own types. This is the foundation of Kubernetes operators.

4.1 Define a CustomResourceDefinition

Create the backup-crd.yaml file:

apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: backups.example.com
spec:
group: example.com
versions:
- name: v1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
schedule:
type: string
retention:
type: integer
target:
type: string
scope: Namespaced
names:
plural: backups
singular: backup
kind: Backup
shortNames:
- bkp

Apply the CRD:

kubectl apply -f backup-crd.yaml
# Expected result:
# customresourcedefinition.apiextensions.k8s.io/backups.example.com created

4.2 Create a Custom Resource instance

Create the my-backup.yaml file:

apiVersion: example.com/v1
kind: Backup
metadata:
name: database-backup
spec:
schedule: "0 2 * * *"
retention: 7
target: "postgres-primary"

Apply and verify:

kubectl apply -f my-backup.yaml
kubectl get backups
# Expected result:
# NAME              AGE
# database-backup   5s
Key takeaway: CRDs transform Kubernetes into an extensible platform. 70% of organizations use Helm to deploy packaged applications that often leverage CRDs (Orca Security 2025).

Step 5: Configure Authentication and RBAC

Kubernetes API access requires authentication and authorization. The RBAC (Role-Based Access Control) model defines who can do what.

5.1 Create a ServiceAccount for your application

kubectl create serviceaccount api-client
# Expected result:
# serviceaccount/api-client created

5.2 Define a Role with limited permissions

Create the api-role.yaml file:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: pod-reader
namespace: default
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["example.com"]
resources: ["backups"]
verbs: ["get", "list", "create", "update"]

5.3 Bind the Role to the ServiceAccount

Create the RoleBinding:

kubectl create rolebinding api-client-binding \
--role=pod-reader \
--serviceaccount=default:api-client
# Expected result:
# rolebinding.rbac.authorization.k8s.io/api-client-binding created

Permission verification:

kubectl auth can-i list pods --as=system:serviceaccount:default:api-client
# Expected result: yes

kubectl auth can-i delete pods --as=system:serviceaccount:default:api-client
# Expected result: no

This RBAC configuration is fundamental for Kubernetes security of your applications.


Step 6: Implement a Watcher with client-go

Watchers allow reacting in real time to resource changes. This is the pattern used by all Kubernetes controllers.

6.1 Watcher code

Add this code to your project:

package main

import (
"context"
"fmt"

corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/kubernetes"
)

func watchPods(clientset *kubernetes.Clientset) {
watcher, err := clientset.CoreV1().Pods("default").Watch(
context.TODO(),
metav1.ListOptions{},
)
if err != nil {
panic(err)
}

fmt.Println("Watching pods...")
for event := range watcher.ResultChan() {
pod := event.Object.(*corev1.Pod)
switch event.Type {
case watch.Added:
fmt.Printf("[ADDED] %s\n", pod.Name)
case watch.Modified:
fmt.Printf("[MODIFIED] %s -> %s\n", pod.Name, pod.Status.Phase)
case watch.Deleted:
fmt.Printf("[DELETED] %s\n", pod.Name)
}
}
}

Test by creating/deleting a pod in another terminal:

kubectl run test-watch --image=nginx:1.25
kubectl delete pod test-watch

Your watcher will display events in real time.

Key takeaway: Informers and watchers are the foundation of Kubernetes operators. Mastering this pattern opens the door to advanced Kubernetes application development.

Final Verification

Validate each component of your learning:

TestCommandExpected Result
API accessible`kubectl api-versions \head -5`List of versions
CRD createdkubectl get crd backups.example.comCRD present
RBAC functionalkubectl auth can-i list pods --as=system:serviceaccount:default:api-clientyes
Custom resourcekubectl get backupsInstance listed

Troubleshooting Common Errors

Error: "Unable to connect to the server"

# Verify cluster is accessible
kubectl cluster-info

# If context is incorrect
kubectl config get-contexts
kubectl config use-context <correct-context>

Error: "forbidden: User cannot list resource"

The ServiceAccount lacks permissions. Verify the RoleBinding:

kubectl get rolebindings -o wide
kubectl describe rolebinding api-client-binding

Error: "no matches for kind CRD"

The CRD is not installed or the group/version is incorrect:

kubectl get crd | grep example.com
kubectl api-resources --api-group=example.com

client-go Error: "unable to load kubeconfig"

# Verify KUBECONFIG is set
echo $KUBECONFIG

# Or that ~/.kube/config exists
ls -la ~/.kube/config

For more complex cases, check cloud-native development patterns for Kubernetes.


Additional Resources

The Kubernetes market grows at 21.85% annually, reaching $8.41 billion by 2031 (Mordor Intelligence). This skill represents a lasting investment.

For a concrete case study, discover how to migrate a monolithic application to Kubernetes by leveraging these APIs.


Take Action: Develop Your Kubernetes API Skills

You now master the fundamentals of the Kubernetes API: REST architecture, kubectl and client-go interactions, Custom Resources, and RBAC. These skills are validated by the CKAD certification.

For deeper learning with structured guidance:

Contact our advisors to define the path suited to your Kubernetes Backend developer objectives.