Minikube - External IP not match host's public IP - local

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.

Related

Local host not reachable by using nodeport service in docker desktop

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

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

Can you configure the Docker daemon to expose istio-ingressgateway LoadBalancer

I am running Knative/Istio in minikube(docker driver) on a mac computer with docker for mac
kubectl get svc -n istio-system istio-ingressgateway
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.104.16.88 localhost 15021:30057/TCP,80:31309/TCP,443:31753/TCP,15012:31321/TCP,15443:31887/TCP 14d
Is it possible to Configure the Docker daemon in any way so I can expose the "EXTERNAL-IP localhost to the host machine.
And then further expose the host machine to a dns server to access container apps in kubernetes?
{
"dns": ["8.8.8.8", "127.0.0.1"]
}
To be able to do myapp.default.mydomain.com into kubernetes within the minikube on the host machine
Thanks in advance
Run minikube tunnel this will allocate an EXTERNAL-IP that is reachable from the host. for more info check the minkube docs

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 curl container deployed on Kubernetes?

I built my Docker image and uploaded it to Amazon ECS (image repository).
I've written a deployment.yaml file and ran kubectl apply -f deployment.yaml.
Worth noting I've used kops to deploy the K8s cluster to AWS EC2
I can see the containers are running in Kubernetes pods using the Kubernetes Dashboard. Also kubectl get pods -o wide also shows me the pods.
The image I deployed is a simple API that exposes one route. My problem is that I have no idea how to query the container I just deployed.
Dockerfile of deployed image:
FROM node:lts
COPY package*.json tsconfig.json ./
RUN npm ci
COPY . .
RUN npm run build
EXPOSE 3000
CMD ["node", "dist/index.js"]
deployment.yaml (kubectl apply -f deployment.yaml):
apiVersion: apps/v1
kind: Deployment
metadata:
name: vuekcal
spec:
selector:
matchLabels:
app: vuekcal
replicas: 2
template:
metadata:
labels:
app: vuekcal
spec:
containers:
- name: search
image: [my-repo-id].dkr.ecr.eu-central-1.amazonaws.com/k8s-search
ports:
- containerPort: 3000
What I tried:
Run kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
vuekcal-6956589484-7f2kx 1/1 Running 0 16m 100.96.2.6 ip-172-20-54-21.eu-central-1.compute.internal <none> <none>
vuekcal-6956589484-f4pqf 1/1 Running 0 16m 100.96.1.7 ip-172-20-59-29.eu-central-1.compute.internal <none> <none>
If get and IP address from the IP column and try to curl it, nothing happens:
I assume this is because those IPs are local.
Finding the K8s node that is running my K8s pod with my container and trying to curl that node's public ip address
And same thing: no response.
Everything is fine if I run the container locally docker run k8s-search.
I have no idea what to do here. How do I query the image that deployment.yaml sets up inside a Kubernetes node?
To access the pod from outside the cluster you need to create either Nodeport or LoadBalancer type service.
kubectl expose deployment vuekcal --type=NodePort --name=example-service
Then access it via curl http://<public-node-ip>:<node-port>
!Make sure you ran the kubectl expose command above!
Public node IP
To get the public node IP, run the following command:
kubectl get nodes -o wide
and look at the "EXTERNAL-IP" column. This is the public ip of the node that is running your container. This is where you should try to connect. For example, the extrenal IP of your node could be 133.71.33.7. Remember this IP.
NodePort
It's different than the containerPort in your deployment.yaml.
To find the NodePort, run this command:
kubectl describe service example-service
Replace example-service with whatever you wrote in --name= when running kubectl expose deployment ... (first command in this post)
After you run the command, you'll see something like this:
This is the port you should use when connecting.
Putting it together
133.73.133.7:31110

Resources