Accessing the API with kubectl proxy
- Introduction
- Accessing the API directly
- Authenticating to the API
- Using
kubectl proxyfor authentication - Trying
kubectl proxy kubectl proxyis intended for local use- Running
kubectl proxyon a remote machine - Security considerations
- Good to know ...
Introduction
The API requires us to authenticate.[¹]
There are many authentication methods available, including:
TLS client certificates
(that's what we've used so far)HTTP basic password authentication
(from a static file; not recommended)various token mechanisms
(detailed in the documentation)
[¹]OK, we lied. If you don't authenticate, you are considered to
be user system:anonymous, which doesn't have any access rights by default.
Accessing the API directly
- Let's see what happens if we try to access the API directly with
curl
Exercise
Retrieve the ClusterIP allocated to the
kubernetesservice:kubectl get svc kubernetesReplace the IP below and try to connect with
curl:curl -k https://`10.96.0.1`/
The API will tell us that user system:anonymous cannot access this path.
Authenticating to the API
If we wanted to talk to the API, we would need to:
extract our TLS key and certificate information from
~/.kube/config(the information is in PEM format, encoded in base64)
use that information to present our certificate when connecting
(for instance, with
openssl s_client -key ... -cert ... -connect ...)figure out exactly which credentials to use
(once we start juggling multiple clusters)
change that whole process if we're using another authentication method
🤔 There has to be a better way!
Using kubectl proxy for authentication
kubectl proxyruns a proxy in the foregroundThis proxy lets us access the Kubernetes API without authentication
(
kubectl proxyadds our credentials on the fly to the requests)This proxy lets us access the Kubernetes API over plain HTTP
This is a great tool to learn and experiment with the Kubernetes API
... And for serious usages as well (suitable for one-shot scripts)
For unattended use, it is better to create a service account
Trying kubectl proxy
- Let's start
kubectl proxyand then do a simple request withcurl!
Exercise
Start
kubectl proxyin the background:kubectl proxy &Access the API's default route:
curl localhost:8001
Terminate the proxy:
kill %1
The output is a list of available API routes.
kubectl proxy is intended for local use
By default, the proxy listens on port 8001
(But this can be changed, or we can tell
kubectl proxyto pick a port)By default, the proxy binds to
127.0.0.1(Making it unreachable from other machines, for security reasons)
By default, the proxy only accepts connections from:
^localhost$,^127\.0\.0\.1$,^\[::1\]$This is great when running
kubectl proxylocallyNot-so-great when you want to connect to the proxy from a remote machine
Running kubectl proxy on a remote machine
If we wanted to connect to the proxy from another machine, we would need to:
bind to
INADDR_ANYinstead of127.0.0.1accept connections from any address
This is achieved with:
kubectl proxy --port=8888 --address=0.0.0.0 --accept-hosts=.*
Do not do this on a real cluster: it opens full unauthenticated access!
Security considerations
Running
kubectl proxyopenly is a huge security riskIt is slightly better to run the proxy where you need it
(and copy credentials, e.g.
~/.kube/config, to that place)It is even better to use a limited account with reduced permissions
Good to know ...
kubectl proxyalso gives access to all internal servicesSpecifically, services are exposed as such:
/api/v1/namespaces/<namespace>/services/<service>/proxyWe can use
kubectl proxyto access an internal service in a pinch(or, for non HTTP services,
kubectl port-forward)This is not very useful when running
kubectldirectly on the cluster(since we could connect to the services directly anyway)
But it is very powerful as soon as you run
kubectlfrom a remote machine