Local host not reachable by using nodeport service in docker desktop - docker

I'm Using docker desktop . When I am using nodeport as a service the application is not accessible for the localhost.
Tried kubectl get SVC and the service is nodeport only

Related

Cannot connect to service on NodePort using Kubernetes on Windows Docker Desktop

Firstly, this is my folder:
This is my Dockerfile:
FROM mcr.microsoft.com/dotnet/sdk:5.0 AS build-env
WORKDIR /app
COPY *.csproj ./
RUN dotnet restore
COPY . ./
RUN dotnet publish -c Release -o out
FROM mcr.microsoft.com/dotnet/aspnet:5.0
WORKDIR /app
COPY --from=build-env /app/out .
ENTRYPOINT ["dotnet", "PlatformService.dll"]
platforms-depl.yaml (deployment file)
apiVersion: apps/v1
kind: Deployment
metadata:
name: platforms-depl
spec:
replicas: 1
selector:
matchLabels:
app: platformservice
template:
metadata:
labels:
app: platformservice
spec:
containers:
- name: platformservice
image: hao14102000/platformservice:latest
platforms-np-srv.yaml (NodePort Service file)
apiVersion: v1
kind: Service
metadata:
name: platformnpservice-srv
spec:
type: NodePort
selector:
app: platformservice
ports:
- name: platformservice
protocol: TCP
port: 80
targetPort: 80
When I apply 2 files this is what I see:
When I try to connect on port 31023 using both options below:
http://localhost:31023/api/platforms
http://10.109.215.230:31023/api/platforms
It doesn't work. This happens:
I don't know what wrong with this...
What happens with Linux containers:
Kubernetes on Windows Docker Desktop by default runs its components in WSL2 (Windows subsystem for Linux), it's separate virtual machine with its own IP address and localhost. This is the reason why service is not reachable on localhost from host OS (in this case Windows).
Another option is to disable using WSL2 based engine in settings, instead hyper-v will be used and virtual machine will be created however in Docker Desktop it's said that preferably WSL2 should be used for performance benefits.
Available options how to access the service using WSL2:
Fastest and easiest (loadbalancer)
Set up a service with LoadBalancer type. EXTERNAL-IP will be localhost which solves all questions immediately. For example:
kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11m
nginx LoadBalancer 10.110.15.53 localhost 8080:30654/TCP 4m10s
Nginx is available in browser on localhost:8080.
Using virtual machine's IP and nodeport
Another option is to find WSL virtual machine and then access service on this IP and nodeport.
To find WSL VM address, you need to run wsl command to connect to this VM and then find its IP address:
wsl
# ip a | grep eth0
6: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
inet 172.19.xxx.yyy/20 brd 172.19.xxx.yyy scope global eth0
Nginx is available in browser on 172.19.xxx.yyy:30654.
Port-forward - for testing purposes
Port-forward is useful for testing purposes, but it shouldn't be used on production systems.
To start the proxy to the service, run following command:
kubectl port-forward service/nginx 8080:80 &
Nginx is available in browser on localhost:8080
Assumptions when Hyper-V is used
First hyper-v should be installed on host machine. Note that not all versions of Windows are supported. Please refer to documentation on which versions and how to enable hyper-v here.
When using WSL2 based engine is deselected, hyper-v is used to work with containers. It creates a separate virtual machine which can be found in Hyper-v Manager.
nodeport works on localhost + nodeport
loadbalancer doesn't work, you can't connect to localhost with service port even though External-IP shows localhost.
Windows containers on Windows Docker Desktop
It's also possible to run Windows containers on Windows Docker Desktop.
It's required to change daemon which will be used. In tray select on switch to Windows containers. Switch between linux and windows containers.
However kubernetes option will become unavailable, because control plane components are designed to be run on linux host.
Environment:
OS: Windows 10 Enterprise, build: 19041.1165
Docker Desktop: 4.0.0 (67817)
Engine: 20.10.8
Kubernetes: 1.21.4
Useful links:
Service types in Kubernetes
Kubernetes port-forwarding
Hyper-V
Docker Desktop for Windows users

Unable to connect to redis cluster on kubernetes from my golang application deployed within the same cluster

I deployed a redis cluster on Kubernetes with bitnami helm charts (https://github.com/bitnami/charts/tree/master/bitnami/redis-cluster).
I can successfully connect to the Redis cluster from within the Kubernetes cluster by running the below commands:
kubectl run my-redis-release-client --rm -it --image docker.io/bitnami/redis:4.0.11-debian-9 -- bash
redis-cli -h redis-cluster-0.redis-cluster-headless.redis
But I am unable to connect to redis cluster from my golang application deployed within the same cluster.
The redis connection string uri I used on my golang application is "redis://redis-cluster-0.redis-cluster-headless.redis:6379". This is following the "redis-pod-name.redis-service-name.namespace" convention.
NOTE: I want to be able to access the redis cluster from only within the Kubernetes cluster. I don’t want to grant external access. Please help...
Headless service is if you don't need load-balancing and a single Service IP. Headless service is not for accessing the redis cluster from only within the Kubernetes cluster
You can create a service to expose redis. Below is an example to create a ClusterIP type which only let's you connect to it from within the cluster and not from outside the cluster.
apiVersion: v1
kind: Service
metadata:
name: redis
namespace: default
spec:
ports:
- port: 6379
targetPort: 6379
selector:
app: redis
The pod or deployment of redis need to have matching label app: redis
Then you can connect to it using redis.default.svc.cluster.local:6379 to connect to it from Golang app.

How to access NodePort in Minikube with docker driver?

I launched minikube with the docker driver on a remote machine and I have used a nodePort service for a particular pod. I believe nodePort exposes the port on the minikube docker container. On doing minikube IP it gave me the IP of the docker container in which minikube runs. How can I port map the port from the minnikube container to the host port so that I can access it remotely. A different approach would other than using driver=none or restarting minikube is appreciated as I do not want to restart my spinnaker cluster.
There is a 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:
$ minikube service example-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 example-minikube --url
http://192.168.99.100:31167
You can run minikube service list to get list of all available services with their corresponding URL's. Also make sure the service points to correct pod by using correct selector.
Try also to execute command:
ssh -i ssh -i ~/.minikube/machines/minikube/id_rsa docker#$(minikube ip) -L *:30000:0.0.0.0:30000
Take a look: minikube-service-port-forward, expose-port-minikube, minikube-service-documentation.

Minikube - External IP not match host's public IP

Shortly, I use GOOGLE COMPUTE ENGINE (external IP: 34.73.89.55, all ports and protocols are opened), then I install Docker, minikube, kubectl. Then:
minikube start --driver=docker
minikube tunnel
kubectl create deployment hello-minikube1 --image=k8s.gcr.io/echoserver:1.4
kubectl expose deployment hello-minikube1 --type=LoadBalancer --port=8080
kubectl get svc
and I get:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-minikube1 LoadBalancer 10.110.130.109 10.110.130.109 8080:31993/TCP 9m22s
My question is, why the EXTERNAL-IP did not match with the host's external IP: 34.73.89.55? How can I access this service remotely by the host's external IP (ex: I'm at home and access via browser)?
Ps: I would like to use GOOGLE COMPUTE ENGINE.
EDIT:
I also try:
sudo minikube start --driver=none
sudo kubectl create deployment hello-minikube1 --image=k8s.gcr.io/echoserver:1.4
sudo kubectl expose deployment hello-minikube1 --type=NodePort --port=8080
wget 127.0.0.1:8080
=>not work
By default minikube expects to run in a separate VM. This can be changed by explicitly specifying a driver.
Why the EXTERNAL-IP did not match with the host's external IP?
Because minikube uses a tunnel which creates a route to services deployed with type LoadBalancer and sets their Ingress to their ClusterIP. For a
detailed example see this documentation.
How can I access this service remotely by the host's external IP?
I see two options here:
More recommended: Set --driver=none
Minikube also supports a --driver=none option that runs the
Kubernetes components on the host and not in a VM. Using this driver
requires Docker and a Linux environment but not a hypervisor.
Might be less ideal: Use port forwarding (either using iptables or proxy). This might be less ideal.
Also remember that minikube was created for testing purposes on locahost. Keep that in mind while using it.
EDIT:
When going for --driver=none you can:
Use NodePort type instead of LoadBalancer.
Continue using Loadbalancer with a modified Service by adding:
spec:
externalIPs:
- <host_address>
For example:
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: hello-minikube1
name: hello-minikube1
spec:
externalIPs:
- <host_address>
ports:
- port: 8080
protocol: TCP
targetPort: 8080
selector:
app: hello-minikube1
type: LoadBalancer
status:
loadBalancer: {}
The above was tested and resulted in EXTERNAL IP = HOST IP.
Please let me know if that helped.

Can't expose port on local Kubernetes cluster (via Docker Desktop)

I am using the local Kubernetes cluster from Docker Desktop on Windows 10. No virtual machines, no minikubes.
I need to expose a port on my localhost for some service.
For example, I take kubernetes-bootcamp image from the official tutorial:
docker pull jocatalin/kubernetes-bootcamp:v2
Put it in the local registry:
docker tag jocatalin/kubernetes-bootcamp:v2 localhost:5000/kubernetes-bootcamp
docker push localhost:5000/kubernetes-bootcamp
Then create a deployment with this image:
kubectl create deployment kubernetes-bootcamp --image=localhost:5000/kubernetes-bootcamp
Then let's expose a port for accessing our deployment:
kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080
kubectl get services
kubernetes-bootcamp NodePort 10.102.167.98 <none> 8080:32645/TCP 8s
So we found out that the exposed port for our deployment is 32645. Let's try to request it:
curl localhost:32645
Failed to connect to localhost port 32645: Connection refused
And nothing is work.
But if I try port-forward everything is working:
kubectl port-forward deployment/kubernetes-bootcamp 7000:8080
Forwarding from 127.0.0.1:7000 -> 8080
Forwarding from [::1]:7000 -> 8080
Handling connection for 7000
Another console:
curl localhost:7000
Hello Kubernetes bootcamp! | Running on: kubernetes-bootcamp-7b5598d7b5-8qf9j | v=2
What am I doing wrong? I have found out several posts like mine, but none of them help me.
try to run the this CMD:
kubectl get svc | grep kubernetes-bootcamp
after this expose the pod to your network by using the CMD:
kubectl expose pod (podname) --type=NodePort
After that, you can check the URL by using the cmd example
minikube 0r kubectl service (service name) --url
So I have found out the problem root - local Kubernetes cluster somehow work the inappropriate way.
How I solve the problem:
Remove C:\ProgramData\DockerDesktop\pki
Recreate all pods, services, deployments
Now the same script I use before works great.

Resources