Accessing The Kubernetes API, sans The Proxy

Daisuke Maki
2 min readSep 22, 2017

--

For various reasons, I wanted to access the Kubernetes API from outside of the cluster, but I didn’t want to (couldn’t) use kubectl proxy which is the easiest and recommended in various forums.

Here’s my memo. This is on Kubernetes 1.7, and please let me know if there are mistakes.

Where’s the Kubernetes API?

$ kubectl get endpoints | grep kubernetes

This will give you an IP address and a port number like 1.2.3.4:443.

How Does One Access The API?

There are various ways, but I find the way using Service Accounts the most straight forward.

Basically, you create a Service Account on the Kubernetes Cluster, and find the JWT that is associated with this account. Then you include that in the Authorization HTTP header.

Create The Account

$ kubectl create serviceaccount my-service-account

Be sure to change my-service-account to something more useful.

Find The Associated Secret

There are various ways to do this, but here I’m going to use jq.

$ kubectl get serviceaccount my-service-account -o json | jq -Mr '.secrets[].name'

This will give you the name of the secret that contains the relevant information. Use that name to find the corresponding JWT.

$ kubectl get secrets $name-of-the-secret -o json | jq -Mr '.data.token' | base64 -D

The base64 bit is necessary, as secrets will be base64 encoded.

Using Curl (Attempt #1)

The token that you got in the previous step should be passed to the API via the “Authorization” header. Given the Kubernetes API server 1.2.3.4:443, you would do:

$ curl https://1.2.3.4 -H "Authorization: Bearer $jwt-token"

This is almost right, but you probably got curl screaming at you saying something along the lines of:

curl: (60) SSL certificate problem: Invalid certificate chain

Well, duh. You either need use the --insecure flag, or provide a CA certificate file. If you are in a hurry, and you know for sure — I mean, absolutely sure — that you are accessing the correct server, it’s okay to use the --insecure flag. But don’t put it in any script, that’s just silly.

Using Curl (Attempt #2)

In order to fix the certificate problem properly, you need to get the CA certificate that Kubernetes provides you. Luckily, this can be obtained in almost the same way we obtained the JWT. Drum rolls… it’s in the same secret as the JWT.

$ kubectl get secrets $name-of-the-secret -o json | jq -Mr '.data["ca.crt"]' | base64 -D > ca.crt

This will allow you to save the CA certificate in a file called ca.crt. Now you just need to give curl the appropriate flags:

curl https://1.2.3.4 --cacert ca.crt -H "Authorization: Bearer $jwt-token"

Voila, you should start seeing something. Navigate to the desired API.

--

--

Daisuke Maki
Daisuke Maki

Written by Daisuke Maki

Go/perl hacker; author of peco; works @ Mercari; ex-mastermind of builderscon; Proud father of three boys;