When running kubectl
commands, the CLI is determining the address of the Kubernetes API server, the CA to verify the server's certificate against (to ensure you're talking to a trusted server and not some man-in-the-middle, say) and your client credentials from the kubeconfig file (to establish an encrypted, authenticated connection to the server with mTLS), which is in ~/.kube/config
by default. You can cat
that file in the tutorial to see what's in it:
$ cat ~/.kube/config
apiVersion: v1
clusters:
- cluster:
certificate-authority: /root/.minikube/ca.crt
server: https://172.17.0.26:8443
name: minikube
contexts:
- context:
cluster: minikube
user: minikube
name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
user:
client-certificate: /root/.minikube/client.crt
client-key: /root/.minikube/client.key
You can do the equivalent of what is happening in the tutorial without the proxy, as follows:
$ curl \
--cacert /root/.minikube/ca.crt \
--cert /root/.minikube/client.crt \
--key /root/.minikube/client.key \
https://172.17.0.26:8443/api/v1/namespaces/default/pods/$POD_NAME/proxy/
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-6bf84cb898-5gzp5 | v=1
You can see that after running the proxy command, the resulting curl command you need to run is simpler and more convenient:
curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
You don't need to bother figuring out the address of the API server or dealing with all these certificates and keys, you just connect to localhost and the local proxy running there handles making the secure, authenticated connection to the API and proxies the response from the API server back to you.
Now, most interactions with the Kubernetes API that you need to do can be done directly via kubectl
commands, it's rare that you need to curl
the API directly. You see this when you issued the kubectl run
or kubectl version
command. In fact, you observed that you later found the version information via a curl
, but you don't really need to do that since you can directly run kubectl version
.
So you would probably only use kubectl proxy
when you need to curl
the Kubernetes API directly because there is no native kubectl
command that lets you do what you want and when you prefer the convenience of not having that more complicated curl
command with all the cert flags, etc.
Okay, but when do you really need to curl
the API directly? Again, usually never. However, one thing the API does in addition to being a RESTful API for creating and deleting Kubernetes resources (pods, deployments, services, pvcs, etc.) is it serves as a proxy into the internal container network. Out-of-the-box, there's no way to send traffic to the container you ran in the tutorial, except for via the proxy endpoints provided by the Kubernetes API located at /api/v1/namespaces/default/pods/$POD_NAME/proxy/
.
The StackOverflow question that you link to in the comment to your question has an accepted answer that explains several other ways to send traffic to the running containers. For a real-world application, you're likely to want to use something other than the proxy endpoints on the Kubernetes API server itself, but the proxy endpoints are a quick and easy way to interact over the network with a deployed container, so it might be something you want to do early on in your development lifecycle before setting up more robust and complex infrastructure to handle ingress traffic to your containers.
So putting it all together: when you have deployed a web application to Kubernetes and you would like to send requests to it and you don't (yet) want to set up some of the more complex but robust ways to get ingress traffic to your containers, you can use the container network proxy API located at /api/v1/namespaces/default/pods/$POD_NAME/proxy/
of the Kubernetes API server. There is no kubectl
command that will hit that endpoint for you, so you have to curl it (or open it in a browser) directly. When you want to curl
any Kuberentes server API endpoint directly and you don't want to pass a bunch of flags to your curl
command, then running kubectl proxy
allows you to run simpler curl
commands directed at that local proxy that will proxy your requests to the Kubernetes API.
One final note, there are two completely different proxies going on here. One is the local proxy proxying your requests to any endpoint of the Kuberentes API server. One such (type of) endpoint that the Kubernetes API server has is itself a proxy into the internal network where containers are deployed. (Further still, there are proxies internal to the container network that make things work under the hood but to keep it simple, there's no need to discuss them in this answer). Don't get those two proxies confused.