Proxying Minikube Kubernetes API

Proxying Minikube Kubernetes API

Minikube: Introduction

Minikube is a lightweight Kubernetes implementation for quickly setting up a single-node Kubernetes cluster. We can deploy the cluster as a VM, or a container.

This is only for educational purposes only and if you forget to set the few configurations mentioned below, you may expose the authenticated Kubernetes API directly.

The problem

When used in a local system, we can easily interact with the Kubernetes API with the native interface https://192.168.49.2:8443, but when installed in the remote server, we cannot directly access the Kubernetes API. So, in this blog, I am providing the solution on how we can create a reverse proxy for the minikube Kubernetes API.

Installing Nginx

Nginx can be easily installed with a package management tool like apt/ yum. Installing nginx with apt:

sudo apt update && sudo apt install nginx

Generating Certificates

We are now using OpenSSL to generate the certificates. You can modify the SAN in the below code to your liking. Please note that the same SAN should be added to your /etc/hosts file with the IP address of the server. I am using kube.local for now.

mkdir -p /etc/nginx/certs/
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout /etc/nginx/certs/nginx.key -addext "subjectAltName = DNS:kube.local" -out /etc/nginx/certs/nginx.crt

Setting up Virtual host (vhost)

You can simply edit the existing default vhost or create the new vhost under /etc/nginx/sites-available. Also don't forget to symlink the vhost to /etc/nginx/sites-enabled. I am setting the same value for the SAN and server name as I am creating a separate vhost under 'kube.local' hostname.

server {
    listen 8443 ssl;

    server_name kube.local;
    ssl_certificate /etc/nginx/certs/nginx.crt;
    ssl_certificate_key /etc/nginx/certs/nginx.key;
    ssl_client_certificate /home/prdp/.minikube/ca.crt;
    ssl_verify_client on;

    location / {
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_pass https://192.168.49.2:8443;
        proxy_ssl_session_reuse on;
        proxy_ssl_certificate /home/prdp/.minikube/profiles/minikube/client.crt;
        proxy_ssl_certificate_key /home/prdp/.minikube/profiles/minikube/client.key;
        proxy_ssl_trusted_certificate /home/prdp/.minikube/ca.crt;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

}

Warning: If you do not set ssl_verify_client, and ssl_client_certificate, you are directly exposing your Kubernetes API without needing authentication/ authorization.

The ssl_verify_client is for client authentication/ validation with the certificate we receive when interacting with the Kubernetes API. The proxy_ssl_certificate, proxy_ssl_certificate_key, and proxy_ssl_trusted_certificate are the certificates for the minikube config which can be retreived within ~/.kube/config of the server/ instance where the minikube is installed.

After the setup of vhost is completed, restart the nginx server.

systemctl restart nginx

After restarting the server, please add the below in your hosts file.

<your server ip>    kube.local

Generating the kube config

The kube config for your system will be equivalent to:

apiVersion: v1
clusters:
- cluster:
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.1
      name: cluster_info
    server: >-
        https://kube.local:8443
    insecure-skip-tls-verify: true
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        provider: minikube.sigs.k8s.io
        version: v1.31.1
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /Users/pradeep/.kube/client.crt
    client-key: /Users/pradeep/.kube/client.key

The certificates under client-certificate and client-key are the same certificates from the /home/prdp/.minikube/profiles/minikube/client.crt and /home/prdp/.minikube/profiles/minikube/client.key, copied in the local system. As you may have noticed we set up client authentication with the CA of the Kube cluster and use these certificates for client authentication with our nginx reverse proxy. Also, insecure-skip-tls-verify is set to true as the Kubernetes client does not trust our self-signed certificate.

Save the above file under ~/.kube/config in your local system.

Now, we can interact with the Kubernetes API with kubectl and also perform exec, port-forward etc. from the local system.