Kubernetes
Go client
Pod proxy
DevOps
Programming

How to invoke the Pod proxy verb using the Kubernetes Go client?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

The Kubernetes API supports a pod proxy subresource, which lets you send an HTTP request through the API server to a pod endpoint. In Go, the most direct way to invoke it is with client-go and either the Pods(namespace).ProxyGet(...) helper or a raw REST request. This is useful for diagnostics and internal HTTP endpoints, but it still depends on API-server reachability and RBAC.

Build A Kubernetes Client

Start with a normal client-go clientset:

go
1package main
2
3import (
4	"fmt"
5	"path/filepath"
6
7	"k8s.io/client-go/kubernetes"
8	"k8s.io/client-go/tools/clientcmd"
9	"k8s.io/client-go/util/homedir"
10)
11
12func main() {
13	kubeconfig := filepath.Join(homedir.HomeDir(), ".kube", "config")
14	config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
15	if err != nil {
16		panic(err)
17	}
18
19	clientset, err := kubernetes.NewForConfig(config)
20	if err != nil {
21		panic(err)
22	}
23
24	fmt.Println(clientset != nil)
25}

If your program runs inside the cluster, replace the kubeconfig setup with rest.InClusterConfig().

Use ProxyGet On The Pod Client

client-go exposes a convenience method on the pod interface:

go
1package main
2
3import (
4	"fmt"
5
6	"k8s.io/client-go/kubernetes"
7	"k8s.io/client-go/tools/clientcmd"
8)
9
10func main() {
11	config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
12	if err != nil {
13		panic(err)
14	}
15
16	clientset, err := kubernetes.NewForConfig(config)
17	if err != nil {
18		panic(err)
19	}
20
21	namespace := "default"
22	podName := "my-pod"
23	port := "8080"
24	path := "/metrics"
25
26	data, err := clientset.CoreV1().
27		Pods(namespace).
28		ProxyGet("http", podName, port, path, nil).
29		DoRaw()
30	if err != nil {
31		panic(err)
32	}
33
34	fmt.Println(string(data))
35}

That sends a proxied GET request through the API server to the pod on port 8080 and path /metrics.

This is usually the simplest answer when the goal is "perform an HTTP GET to a pod through the Kubernetes API."

Using The Raw REST Path

If you need more control, you can construct the path yourself with the REST client:

go
1package main
2
3import (
4	"fmt"
5
6	"k8s.io/client-go/kubernetes"
7	"k8s.io/client-go/tools/clientcmd"
8)
9
10func main() {
11	config, err := clientcmd.BuildConfigFromFlags("", "/path/to/kubeconfig")
12	if err != nil {
13		panic(err)
14	}
15
16	clientset, err := kubernetes.NewForConfig(config)
17	if err != nil {
18		panic(err)
19	}
20
21	body, err := clientset.CoreV1().
22		RESTClient().
23		Get().
24		Namespace("default").
25		Resource("pods").
26		Name("my-pod:8080").
27		SubResource("proxy").
28		Suffix("healthz").
29		DoRaw()
30	if err != nil {
31		panic(err)
32	}
33
34	fmt.Println(string(body))
35}

This style is more verbose, but it helps when you need to see or customize the exact request shape.

RBAC And Security Requirements

A working client is not enough. The caller also needs permission to use the pod proxy subresource. In RBAC, that usually means allowing the get verb on pods/proxy.

Conceptually, the rule looks like this:

yaml
1rules:
2  - apiGroups: [""]
3    resources: ["pods/proxy"]
4    verbs: ["get"]

Without that permission, the client call fails even if the cluster connection itself is valid.

Also remember that the API server must be able to reach the pod. A proxy call is not a substitute for a healthy network path inside the cluster.

When Pod Proxy Is Useful

Pod proxy calls are commonly used for:

  • scraping an internal HTTP endpoint during debugging
  • reaching an ad hoc diagnostics endpoint inside a container
  • testing API-server-mediated access without exposing a Service

For stable production traffic, a Service, Ingress, or port-forwarding workflow is usually a better fit. Pod proxy is more of an administrative or debugging mechanism than a normal application integration pattern.

Common Pitfalls

The biggest mistake is forgetting RBAC for pods/proxy. A normal pod get permission does not automatically mean proxy access is allowed.

Another common issue is assuming pod proxy works like a generic TCP tunnel. It is fundamentally an HTTP-oriented path through the API server, so it is best suited to HTTP endpoints.

Developers also sometimes use the wrong port string or forget the leading slash in the proxied path. Keep the port as a string and pass paths such as /metrics or /healthz.

Finally, do not rely on pod proxy as a permanent app architecture. It is convenient for tooling and diagnostics, but not usually the right long-term access pattern for internal services.

Summary

  • Use client-go with Pods(namespace).ProxyGet(...) for the simplest pod proxy request.
  • 'DoRaw() is convenient when the proxied endpoint returns a small HTTP payload.'
  • The caller needs RBAC permission for the pods/proxy subresource.
  • Pod proxy is useful for debugging and internal endpoints, not as a normal public-facing access path.
  • If you need more control, you can build the proxy request through RESTClient() directly.

Course illustration
Course illustration

All Rights Reserved.