Expose port in minikube - kubernetes

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.

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

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.

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=/
...

I ran into a similar issue in 2022. Here are the commands I ran:
kubectl create deployment deploymentName --image=dockerHubUsername/imageTag:imageVersion
kubectl expose deployment deploymentName --type=LoadBalancer --port=8080
minikube tunnel
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

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...

Related

My app is not accessible, is my service definition wrong? [duplicate]

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.
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
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.
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=/
...
I ran into a similar issue in 2022. Here are the commands I ran:
kubectl create deployment deploymentName --image=dockerHubUsername/imageTag:imageVersion
kubectl expose deployment deploymentName --type=LoadBalancer --port=8080
minikube tunnel
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
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...

LoadBalancer 'EXTERNAL IP" is in pending state after I installed k8s using helm Charts

I Installed K8S with Helm Charts on EKS but the Loadbalancer EXTERNAL IP is in pending state , I see that EKS does support the service Type : LoadBalancer now.
Is it something I will have to check at the network outgoing traffic level ? Please share your experience if any.
Tx,
The Loadbalancer usually takes some seconds or a few minutes to provision you an IP.
If after 5 minutes the IP isn't provisioned:
- run kubectl get svc <SVC_NAME> -o yaml and if there is any different annotation set.
By default services with Type:LoadBalancer are provisioned with Classic Load Balancers automatically. Learn more here.
If you wish to use Network load Balancers you have to use the annotation:
service.beta.kubernetes.io/aws-load-balancer-type: nlb
The process is really automatic, you don't have to check for network traffic.
You can check if there is any issue with the Helm Chart you are deploying by manually creating a service with loadbalancer type and check if it gets provisioned:
$ kubectl run --generator=run-pod/v1 nginx --image=nginx --port=80
pod/nginx created
$ kubectl get pod nginx
NAME READY STATUS RESTARTS AGE
nginx 1/1 Running 0 34s
$ kubectl expose pod nginx --type=LoadBalancer
service/nginx exposed
$ kubectl get svc nginx -w
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
nginx LoadBalancer 10.1.63.178 <pending> 80:32522/TCP 7s
nginx LoadBalancer 10.1.63.178 35.238.146.136 80:32522/TCP 42s
In this example the LoadBalancer took 42s to be provisioned. This way you can verify if the issue is on the Helm Chart or something else.
If Kubernetes is running in an environment that doesn't support LoadBalancer services, the load balancer will not be provisioned, but the service will still behave like a NodePort service, your cloud/K8 engine should support LoadBalancer Service.
In that case, if you manage to add EIP or VIP to your node then you can attach to the EXTERNAL-IP of your TYPE=LoadBalancer in the K8 cluster, for example attaching the EIP/VIP address to the node 172.16.2.13.
kubectl patch svc ServiceName -p '{"spec": {"type": "LoadBalancer", "externalIPs":["172.16.2.13"]}}'

Traefik ingress controller on minikube: External IP pending

I am trying to deploy a Traefik Ingress controller in my minikube environment by following this:
helm install stable/traefik --name-template traefik --set dashboard.enabled=true,dashboard.domain=dashboard.traefik,rbac.enabled=true --namespace kube-system
Even after half an hour I still see that External IP is pending:
pascals#pascals:~$ kubectl get svc -l app=traefik -n kube-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik LoadBalancer 10.96.172.128 <pending> 443:30812/TCP,80:31078/TCP 20m
traefik-dashboard ClusterIP 10.96.56.105 <none> 80/TCP 20m
Ideally I would like to reach http://dashboard.traefik but I am not able to do so.
I tried to assign an External Ip using the kubectl patch Api:
kubectl patch svc traefik -n kube-system -p '{"spec":{"externalIPs":["192.168.99.107"]}}'
where, 192.168.99.107 is the minikube ip. This however still did not solve my problem.
Appreciate any nudge in the right direction!
The external IP is assigned by the ServiceController if any cloud provider used in the cluster, usually in managed clusters.
In a minikube cluster, LoadBalance-typed Service will never have an external IP. You can access Services through minikubeip:nodeport, or running minikube service. For the Service traefik-dashboard, it should be a NodePort-typed Service first.
You should install some Kubernetes bare-metal load balancer, like MetalLB

how to access eureka by dns name in kubernetes cluster

I am deploy eureka in kubernetes(v1.15.2) cluster.Now I want to using my app pod register to eureka by domain name,first I try this way:
http://eureka-0.eureka.dabai-fat.svc.cluster.local:8761
It not works.I am login my app pod using this command:
/opt/k8s/bin/kubectl exec -ti soa-room-service-6c4448dfb6-grhtb -n dabai-fat /bin/sh
and using curl command to access cluster's eureka this way:
/ # curl http://eureka-0.eureka.dabai-fat.svc.cluster.local:8761
curl: (6) Could not resolve host: eureka-0.eureka.dabai-fat.svc.cluster.local
but using this way works:
/ # curl http://172.30.224.17:8761
{"timestamp":"2020-02-03T17:10:23.037+0000","status":401,"error":"Unauthorized","message":"Unauthorized","path":"/"}
But I think the domain or dns way is better because the ip could floating in the future. So what is the right way to register to eureka using dns? My coredns in the namespace kube-sytem,and my eureka service and app pod in dabai-fat namespace. By the way,this is my eureka service info in kubernetes:
Do you have service with name eureka-0.eureka in dabai-fat namespace ? You can check it via kubectl get svc -n dabai-fat.
Check the service and change the url to http://eureka.dabai-fat.svc.cluster.local:8761, It works.
/ # curl http://eureka.dabai-fat.svc.cluster.local:8761
{"timestamp":"2020-02-03T17:29:08.045+0000","status":401,"error":"Unauthorized","message":"Unauthorized","path":"/"}
this is service check command output:
[root#ops001 ~]# kubectl get svc -n dabai-fat
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
eureka ClusterIP None <none> 8761/TCP,8081/TCP 2d
soa-auth-service ClusterIP 10.254.84.39 <none> 11013/TCP 2d8h

Publishing the Application

I followed the instructions found here...
https://schoolofdevops.github.io/ultimate-kubernetes-bootcamp/quickdive/
As you can see, "NodePort" type do not have external-IP like wordpress. Therefore I can not connect.
# /usr/local/bin/kubectl --kubeconfig="padhaku2.yaml" get service
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.245.0.1 <none> 443/TCP 38m
vote NodePort 10.245.33.151 <none> 81:31876/TCP 6m20s
wordpress LoadBalancer 10.245.170.65 139.59.49.69 80:31820/TCP 21m
How do I publish the app using external IP?
you can access the application using nodeport.
try http://NODEIP:NODEPORT
in your case, http://NODEIP:31876
follow the steps to update the service type
kubectl delete svc vote
kubectl expose deployment vote --type=LoadBalancer --port 80
you might need to deploy rest of the voting services
kubectl run redis --image=redis:alpine
kubectl expose deployment redis --port 6379
kubectl run worker --image=schoolofdevops/worker
kubectl run db --image=postgres:9.4
kubectl expose deployment db --port 5432
kubectl run result --image=schoolofdevops/vote-result
kubectl expose deployment result --type=NodePort --port 80
If your service type is NodePort, you can connect to your service using the address <protocol>://<Node_ip>:<NodePort>, where
**protocol** may be **http** or **https**
**Node_ip** is the IP of the Node where your application is running
**NodePort** is the value of the **NodePort** field used in your service manifest file