How to expose the API server of a minikube cluster to the public network (LAN)?

4/18/2018

Is there a way to expose the API server of a Kubernetes cluster created with minikube on a public network interface to the LAN?

minikube start --help talks about this option (and two similar ones):

  --apiserver-ips ipSlice \
    A set of apiserver IP Addresses which are used in the generated \
    certificate for localkube/kubernetes. This can be used if you \
    want to make the apiserver available from outside the machine (default [])

So it seems to be possible. But I can't figure out how or find any further information on that.

I naively tried:

minikube start --apiserver-ips <ip-address-of-my-lan-interface>

But that just yields an utterly dysfunctional minikube cluster that I can't even access from localhost.


Following the advise in one answer below I added port forwarding to Kubernetes like this:

vboxmanage controlvm "minikube" natpf1 "minikube-api-service,tcp,,8443,,8443"

And then I can actually access the API server from a different host on the network with:

curl --insecure https://<ip-address-of-host-running-minikube>:8443

But the response is:

{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {

  },
  "status": "Failure",
  "message": "forbidden: User \"system:anonymous\" cannot get path \"/\"",
  "reason": "Forbidden",
  "details": {

  },
  "code": 403
}

There are two problems with this:

  1. I have to use --insecure for the curl call, otherwise I get a SSL validation error.
  2. I get a response, but the response is just telling me that I'm not allowed to use the API...
-- anothernode
kubernetes
minikube

2 Answers

9/3/2019

The big source of your headache is that minikube runs in a VM (usually) with it's own IP address. For security, it generates some self signed certificates and configures the api command line tool, kubectl to use them. The certs are self signed with the VM IP as the host name for the cert.

You can see this if you use kubectl config view. Here's mine:

apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/sam/.minikube/ca.crt
    server: https://192.168.39.226:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /home/sam/.minikube/client.crt
    client-key: /home/sam/.minikube/client.key

Let's unpack that.

server: https://192.168.39.226:8443 - this tells kubectl where the server is. In a vanilla minikube setup, it's https://<ip-of-the-vm>:8443. Note that its https.

certificate-authority: /home/sam/.minikube/ca.crt - this line tells the tool what certificate authority file to use to verify the TLS cert. Because it's a self signed cert, even in vanilla setups, you'd have to either inform curl about the certificate authority file or use --insecure.

- name: minikube
  user:
    client-certificate: /home/sam/.minikube/client.crt
    client-key: /home/sam/.minikube/client.key

This chunk specifies what user to authenticate as when making commands - that's why you get the unauthorized message even after use --insecure.

So to use the minikube cluster from a different IP you'll need to: 1) Use the --apiserver-ips <target-ip-here> (so the cert minikube generates is for the correct IP you'll be accessing it from) 2) Forward the 8443 port from the minikube vm to make it available at <target-ip-here>:8443 3) Publish or otherwise make available the cert files referenced from kubectl config view 4) Setup your kubectl config to mimic your local kubectl config, using the new ip and referencing the published cert files.

-- Sam Sieber
Source: StackOverflow

4/18/2018

You need to forward some ports on your LAN interface to the VMs where Kubernetes are running. That will work for any service inside Minikube, not only for Kubernetes itself.

In short, if you are using VirtualBox as a VM driver, you should:

  1. Find the port on the VM where your service binds. Commands kubectl describe <servicename> and minikube service <servicename> --url should help you.
  2. Forward ports to the VM using vboxmanage tool:

    vboxmanage controlvm "minikube" natpf1 "http,tcp,,12345,,80"

Where minikube - the name of the VM, natfp1 - the virtual interface of the VM, 12345 - port of the VM, 80 - local port.

-- Anton Kostenko
Source: StackOverflow