94

In minikube, how to expose a service using nodeport ?

For example, I start a kubernetes cluster using the following command and create and expose a port like this:

$ minikube start
$ kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.4 --port=8080
$ kubectl expose deployment hello-minikube --type=NodePort
$ curl $(minikube service hello-minikube --url)
CLIENT VALUES:
client_address=192.168.99.1
command=GET
real path=/ ....

Now how to access the exposed service from the host? I guess the minikube node needs to be configured to expose this port as well.

KarateKid
  • 3,138
  • 4
  • 20
  • 39
  • Can you clarify what you mean by "access the exposed service from the host"? It seems that you are already able to access the hello-minikube service from the host at the url specified by: `minikube service hello-minikube --url` – aaron-prindle Nov 23 '16 at 19:28
  • Yes you are right. Actually it was configuration error because of which the port was not accessible from the host and I was in a confusion that I need to change some firewall settings to make it accessible. – KarateKid Nov 24 '16 at 10:04

7 Answers7

155

I am not exactly sure what you are asking as it seems you already know about the minikube service <SERVICE_NAME> --url command which will give you a url where you can access the service. In order to open the exposed service, the minikube service <SERVICE_NAME> command can be used:

$ kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.4 --port=8080
deployment "hello-minikube" created
$ kubectl expose deployment hello-minikube --type=NodePort
service "hello-minikube" exposed
$ kubectl get svc
NAME             CLUSTER-IP   EXTERNAL-IP   PORT(S)    AGE
hello-minikube   10.0.0.102   <nodes>       8080/TCP   7s
kubernetes       10.0.0.1     <none>        443/TCP    13m

$ minikube service hello-minikube
Opening kubernetes service default/hello-minikube in default browser...

This command will open the specified service in your default browser.

There is also a --url option for printing the url of the service which is what gets opened in the browser:

$ minikube service hello-minikube --url
http://192.168.99.100:31167
aaron-prindle
  • 3,077
  • 1
  • 17
  • 15
  • On my Linux host it cannot find the port `$ kubectl expose deployment hello-minikube --type=NodePort error: couldn't find port via --port flag or introspection` – Stephane Sep 15 '17 at 21:28
  • 1
    You need to expose the port too @Stephane. Example: `kubectl expose deployment influxdb --port=8086 --target-port=8086` – d1ll1nger Nov 13 '18 at 14:54
  • 1
    Thanks, I was trying to hit the exposed NodePort service (web-nodeport) on localhost:31000, but that didn't work. minikube service web-nodeport did worked. But curious why localhost didn't worked. – Mahtab Alam Dec 27 '18 at 07:33
  • 3
    @MahtabAlam it does not work as the NodePort is exposed inside of a VM that minikube is running k8s in, not the host machine. You can use the new `minikube tunnel` command which should proxy the ports to interact with localhost. – aaron-prindle Jan 22 '19 at 19:43
  • 1
    github url is broken. – yogihosting Feb 10 '21 at 10:43
49

As minikube is exposing access via nodeIP:nodePort and not on localhost:nodePort, you can get this working by using kubectl's port forwarding capability. For example, if you are running mongodb service:

kubectl port-forward svc/mongo 27017:27017

This would expose the service on localhost:27017, FWIW. Furthermore, you might want to figure out how to run this in background.

Arun Reddy
  • 3,443
  • 1
  • 21
  • 16
32

minikube runs on something like 192.168.99.100. So you should be able to access it on the NodePort you exposed your service at. For eg, say your NodePort is 30080, then your service will be accessible as 192.168.99.100:30080.

To get the minikube ip, run the command minikube ip.

Update Sep 14 2017:

Here's a small example that works with minikube v0.16.0.

1) Run the commands below to create an nginx running on 8080 and a NodePort svc forwarding to it:

$ kubectl run hello-minikube --image=gcr.io/google_containers/echoserver:1.4 --port=8080
deployment "hello-minikube" created
$ kubectl expose deployment hello-minikube --type=NodePort
service "hello-minikube" exposed

2) Find the nodeport used by the svc:

$ kubectl get svc hello-minikube
NAME             CLUSTER-IP   EXTERNAL-IP   PORT(S)          AGE
hello-minikube   10.0.0.76    <nodes>       8080:30341/TCP   4m

3) Find the minikube ip:

$ minikube ip
192.168.99.100

4) Talk to it with curl:

$ curl 192.168.99.100:30341
CLIENT VALUES:
client_address=172.17.0.1
command=GET
real path=/
...
GabLeRoux
  • 16,715
  • 16
  • 63
  • 81
iamnat
  • 4,056
  • 1
  • 23
  • 36
  • 32
    This does not appear to be true. – macrael Jun 15 '17 at 20:44
  • 4
    1) kubernetes assigns an IP & port to the exposed service 2) that IP & port are running on a VM with a virtual IP that your laptop doesn't have native access to. – ives Sep 13 '17 at 21:53
  • 2
    @macrael This is 100% true and works on windows, mac and Linux. Please check your VM network settings, your kubernetes settings or post them here so that others can help. The downvote is unwarranted! – iamnat Sep 13 '17 at 23:58
  • @icordoba Just tested this on macos as well. Are you able to ping your minikube VM? Try reproducing the instructions? – iamnat Sep 13 '17 at 23:59
  • can I define the exposed port? I mean, what do I have to do if I want to expose it to 8080 (192.168.99.100:8080) – ItayB Jun 24 '18 at 20:48
  • 5
    I have been at this all day. Minikube on mac does not setup an IP address you can hit via browser. Says and hasnt changed in over 2 hours. I have been reading mixed messages that loadBalancer works and does not work for minikube. Anyone else get this to work yet? I had an instance running and working with Ambassador, but not without it yet. – Wes Duff Jul 07 '18 at 03:19
  • 4
    `kubectl expose deployment hello-minikube --type=NodePort` command from the example doesn't work for me (MacOS minikube + docker driver, minikube version: v1.14.0, docker engine version 19.03.13, k8s client 1.18, k8s server 1.19) – Dmitry Shvetsov Oct 20 '20 at 04:09
  • Worked great for me on Linux with minikube/vbox !!! This should be the accepted answer! – Dr. Chocolate Nov 22 '20 at 15:14
  • @DmitryShvetsov It doesn't work for me too. Why we require minikube service command? Can we do without using it? – VIJAYKUMAR SUBRAMANI Jan 03 '21 at 15:48
  • the deployment and service names end up being `helloworld`, not `hello-minicube`, when I run it. – Justin Waulters Jan 16 '21 at 16:52
  • 2
    @macrael - that is because the answer is incomplete. The above probably works in a specific kind of Minikube cluster - maybe vbox (since a network between the host and guests are created). The default Minikube cluster is that of docker and this answer does not work with it. Must either be added to the answer, failing which it is extremely misleading and, in a way, wrong! – Rads Mar 11 '21 at 04:03
  • 1
    how solve if write in yaml file? – Nikolay Baranenko Feb 13 '23 at 14:28
8

I ran into a similar issue in 2022. Here are the commands I ran:

  1. kubectl create deployment deploymentName --image=dockerHubUsername/imageTag:imageVersion
  2. kubectl expose deployment deploymentName --type=LoadBalancer --port=8080
  3. minikube tunnel
  4. kubectl get services deploymentName this provides the external ip address needed to access the application. I access the app with 127.0.0.1:8080

Source

nkr
  • 3,026
  • 7
  • 31
  • 39
gbengaoyetade
  • 700
  • 8
  • 6
4

Just a note for anyone looking for connection refused answers: If your minikube does not run on "something like 192.168.99.100" you probably runned with another vm-driver like "none". In that case delete your minikube cluster and rebuild using the default. it 'll work....ish... I do not seem to be able to get the tunnel working...

SomeOne_1
  • 808
  • 10
  • 10
  • Thanks this resolved my issue. I started the minikube cluster without vm-driver option. Deleted the minikube cluster and used minikube start driver=hyperkit on MacOS resolved the issue. Remember for macos users, you can use any of the drivers listed here https://minikube.sigs.k8s.io/docs/drivers/ – msapkal Apr 17 '22 at 15:07
1

I'm using wsl2 on windows11 docker desktop. the only thing that worked for me was using service type ClusterIp, together with the command:
kubectl port-forward svc/<service name> -n <namespace> <host port>:<service port>
I tried NodePort in any way, restarting minikube with the "--port" arg, but nothing else worked.

Benaya Trabelsi
  • 351
  • 3
  • 11
0

After a lot of research and struggle, this is what I found.

Minikube by default, uses docker as its VM Driver and due to that, whenever you start a minikube cluster, it creates a new network with the name minikube (you can find it using docker network ls. Hence, that minikune IP is only defined in that 'minikube' network.

To run minikube on the host network and give minikube IP as hostIP, you need to run minikube with --vm-driver=none

Below are the complete commands

# Make sure that version of minikube is v1.30.1
curl -LO https://storage.googleapis.com/minikube/releases/v1.30.1/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Make sure that version of kubectl is v1.23.0
curl -LO "https://dl.k8s.io/release/v1.23.0/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

minikube start --extra-config=apiserver.service-node-port-range=300-20000 --memory=6g minikube start --kubernetes-version=v1.23.0 --vm-driver=none

Minikube will expose via nodeIP:nodePort and not on localhost:nodePort when you use default vm-driver. If you use --vm-driver as none, it then uses localhost.