I'm trying to get an ingress controller working in Minikube and am following the steps in the K8s documentation here, but am seeing a different result in that the IP address for the ingress controller is different than that for Minikube (the example seems to indicate they should be the same):
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
example-ingress hello-world.info 10.0.2.15 80 12m
$ minikube ip
192.168.99.101
When I try to connect to the Minikube IP address (using the address directly vs. adding it to my local hosts file), I'm getting a "Not found" response from NGINX:
$ curl http://`minikube ip`/
<html>
<head><title>404 Not Found</title></head>
<body>
<center><h1>404 Not Found</h1></center>
<hr><center>openresty/1.15.8.1</center>
</body>
</html>
When I try to connect to the IP address associated with the ingress controller, it just hangs.
Should I expect the addresses to be the same as the K8s doc indicates?
Some additional information:
$ kubectl get nodes -o wide
NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME
minikube Ready master 2d23h v1.16.0 10.0.2.15 <none> Buildroot 2018.05.3 4.15.0 docker://18.9.9
$ kubectl get ingresses example-ingress -o yaml
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"networking.k8s.io/v1beta1","kind":"Ingress","metadata":{"annotations":{"nginx.ingress.kubernetes.io/rewrite-target":"/$1"},"name":"example-ingress","namespace":"default"},"spec":{"rules":[{"host":"hello-world.info","http":{"paths":[{"backend":{"serviceName":"web","servicePort":8080},"path":"/"}]}}]}}
nginx.ingress.kubernetes.io/rewrite-target: /$1
creationTimestamp: "2019-10-28T15:36:57Z"
generation: 1
name: example-ingress
namespace: default
resourceVersion: "25609"
selfLink: /apis/extensions/v1beta1/namespaces/default/ingresses/example-ingress
uid: 5e96c378-fbb1-4e8f-9738-3693cbce7d9b
spec:
rules:
- host: hello-world.info
http:
paths:
- backend:
serviceName: web
servicePort: 8080
path: /
status:
loadBalancer:
ingress:
- ip: 10.0.2.15
Here’s what worked for me:
minikube start
minikube addons enable ingress
minikube addons enable ingress-dns
Wait until you see the ingress-nginx-controller-XXXX is up and running using Kubectl get pods -n ingress-nginx
Create an ingress using the K8s example yaml file
Update the service section to point to the NodePort Service that you already created
Append
127.0.0.1 hello-world.info
to your /etc/hosts file on MacOS (NOTE:
Do NOT use the Minikube IP)
Run minikube tunnel ( Keep the window open. After you entered the password there will be no more messages, and the cursor just blinks)
Hit the hello-world.info ( or whatever host you configured in the yaml file) in a browser and it should work
I've reproduced your scenario in a Linux environment (on GCP) and I also have different IPs:
user#bf:~$ minikube ip
192.168.39.144
user#bf:~$ kubectl get ingresses
NAME HOSTS ADDRESS PORTS AGE
example-ingress * 192.168.122.173 80 30m
Your problem is not related to the fact you have different IPs. The guide instructs us to create an ingress with the following rule:
spec:
rules:
- host: hello-world.info
This rule is telling the ingress service that a DNS record with hello-world.info name is expected.
If you follow the guide a bit further, it instructs you to create an entry on your hosts file pointing to your ingress IP or Minikube IP.
Note: If you are running Minikube locally, use minikube ip to get the external IP. The IP address displayed within the ingress list
will be the internal IP.
Source: Set up Ingress on Minikube with the NGINX Ingress Controller
(if you want to curl the IP instead of DNS name, you need to remove the host rule from your ingress)
It should look like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: web
servicePort: 8080
Apply your changes:
user#bf:~$ kubectl apply -f example-ingress.yaml
And curl the IP using -Lk options to surpass problems related to secure connections.
user#bf:~$ curl -Lk 192.168.39.144
Hello, world!
Version: 1.0.0
Hostname: web-9bbd7b488-l5gc9
In addition to the accepted answer, minikube now has a tunnel command which allows you generate external ip addresses for your services which can be accessed directly on your host machine without using the general minikube ip.
Run minikube tunnel in a separate terminal. This runs in the foreground as a daemon.
In a different terminal, execute your kubectl apply -f <file_name> command to deploy your desired service. It should generate an ip address for you that is routed directly to your service and available on port 80 on that address.
More here on the minikube documentation: https://minikube.sigs.k8s.io/docs/tasks/loadbalancer/
I got Minikube on Windows 11 to work for me
minikube start --vm-driver=hyperv
Install minikube Ingress Controller
minikube addons enable ingress
minikube addons enable ingress-dns
Deploy Helm Chart
helm install ...
Get Kubernetes IP Address
nslookup <host-found-in-ingress> $(minikube ip)
Add to etc/host
<minikube-ip> <domain-url>
Live!
curl <domain-url>
Related
I am following this tutorial for how to expose your local cluster for external access.
I only need to be able to check my application from browser, without exposing the app to the Internet.
> kubectl get service web
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
web NodePort 10.98.217.114 <none> 8080:32718/TCP 10m
> minikube service web --url
http://192.168.49.2:32718
Followed the guide until the etc/hosts part. I set up the ingress:
> kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx hello-world.info 192.168.49.2 80 96s
For various reasons I cannot edit the etc/hosts file on my Windows machine, it says another process is using it. However, neither 192.168.49.2 nor http://192.168.49.2:32718 in the browser returns anything, as well as curl 192.168.49.2 (and with :32718). I don't think that should be expected, as the hosts file merely forwards hello-world.info to the IP, I should be able to access my app with just the IP. What am I missing here?
Kubectl v1.24.1 (kustomize v4.5.4, server v1.23.3), Minikube v1.25.2, Windows 10, Minikube with the Docker driver.
Okay my solution to the problem was this: port-forward to the ingress-controller pod (not to the ingress itself object, because it doesn't seem to be possible)
Sample ingress file for a service named "web":
# example-ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web
port:
number: 8080
Run it with
kubectl apply -f example-ingress.yaml
Check that it's running
> kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
example-ingress nginx * 192.168.49.2 80 23h
If you ssh into minikube (minikube ssh), you can curl 192.168.49.2:80 and it returns the proper output.
Output nginx-controller pods:
> kubectl get pod -n ingress-nginx
NAME READY STATUS RESTARTS
AGE
ingress-nginx-admission-create-56gbc 0/1 Completed 0
46h
ingress-nginx-admission-patch-fqf92 0/1 Completed 0
46h
ingress-nginx-controller-cc8496874-7znt5 1/1 Running 4 (39m ago)
46h
Forward port to it:
> kubectl port-forward ingress-nginx-controller-cc8496874-7znt5 8080:80 -n ingress-nginx
Then check out localhost:8080. If it returns nginx 404, then your Ingress.yaml setup is probably wrong. Otherwise works for me.
How do I expose an ingress when running kubernetes with minikube in windows 10?
I have enabled the minikube ingress add on.
My ingress is running here...
NAME CLASS HOSTS ADDRESS PORTS AGE
helmtest-ingress nginx helmtest.info 192.168.49.2 80 37m
I have added my hosts entry...
192.168.49.2 helmtest.info
I just get nothing when attempting to browse or ping either 192.168.49.2 or helmtest.info
My ingress looks like the following
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: helmtest-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: helmtest.info
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: helmtest-service
port:
number: 80
My service looks like the following...
apiVersion: v1
kind: Service
metadata:
name: helmtest-service
labels:
app: helmtest-service
spec:
type: ClusterIP
selector:
app: helmtest
ports:
- port: 80
targetPort: 80
protocol: TCP
I can access my service successfully in the browser after running minikube service helmtest-service --url
If I run minikube tunnel it just hangs here....
minikube tunnel
❗ Access to ports below 1024 may fail on Windows with OpenSSH clients older than v8.1. For more information, see: https://minikube.sigs.k8s.io/docs/handbook/accessing/#access-to-ports-1024-on-windows-requires-root-permission
🏃 Starting tunnel for service helmtest-ingress.
Where am I going wrong here?
OP didn't provide further information so I will provide answer based on the current information.
You can run Ingress on Minikube using the $ minikube addons enable ingress command. However, ingress has more addons, like Ingress DNS using minikube addons enabled ingress-dns. In Minikube documentation you can find more details about this addon and when you should use it.
Minikube has quite a well described section about tunnel. Quite important fact about the tunnel is that it must be run in a separate terminal window to keep the LoadBalancer running.
Services of type LoadBalancer can be exposed via the minikube tunnel command. It must be run in a separate terminal window to keep the LoadBalancer running. Ctrl-C in the terminal can be used to terminate the process at which time the network routes will be cleaned up.
This part is described in Accessing apps documentation.
As OP mention
I can access my service successfully in the browser after running minikube service helmtest-service --url
If I run minikube tunnel it just hangs here....
Possible Solution
You might use the old version of SSH, update it.
You are using ports <1024. This situation it's described in this known issue part. Try to use higher port like 5000 like in this example
It might look like it just hangs, but you need a separate terminal window. Maybe it works correctly but you have to use another terminal
Useful links
How do I expose ingress to my local machine? (minikube on windows)
Cannot export a IP in minikube and haproxy loadBalancer - using minikube tunnel
It might be the host file missing minikube ip address with your host name. If ingress cannot resolve the hostname you set in yaml file it just stays in the schedule to sync phase
Similar answer
I built my own 1 host kubernetes cluster (1 host, 1 node, many namespaces, many pods and services) on a virtual machine, running on a always-on server.
The applications running on the cluster are working fine (basically, a NodeJS backend and HTML frontend).
So far, I have a NodePort Service, which is exposing Port 30000:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
traefik-ingress-service NodePort 10.109.211.16 <none> 443:30000/TCP 147d
So, now I can access the web interface by typing https://<server-alias>:30000 in my browser adress bar.
But I would like to access it without giving the port, by only typing https://<server-alias>.
I know, this can be done with the kubectl port-forwarding command:
kubectl -n kube-system port-forward --address 0.0.0.0 svc/traefik-ingress-service 443:443
This works. But it does not seem to be a very professional thing to do.
Port forwarding also seems to keep disconnecting from time to time. Sometimes, it throws an error and quits, but leaves the process open, which leaves the port open - have to kill the process manually.
So, is there a way to do that access-my-application stuff professionally? How do the cluster provider (AWS, GCP...) do that?
Thank you!
Using Ingress Nginx you can access to you website with the name server:
Step 1: Install Nginx ingress in you cluster you can flow this link
After the installation is completed you will have a new pod
NAME READY STATUS
nginx-ingress-xxxxx 1/1 Running
And a new Service
NAME TYPE CLUSTER-IP EXTERNAL-IP
nginx-ingress LoadBalancer 10.109.x.y a.b.c.d
Step 2 : Create new deployment for you application but be sure that you are using the same name space for nginx ingress svc/pod and you application and you set the svc type to ClusterIP
Step 3: Create Kubernetes Ingress Object
Now you have to create the ingress object
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: test-ingress
namespace: **Same Name Space**
spec:
rules:
- host: your DNS <server-alias>
http:
paths:
- backend:
serviceName: svc Name
servicePort: svc Port
Now you can access to your website using the .
To create a DNS for free you can use freenom or you can use /etc/hosts
update it with :
server-alias a.b.c.d
Since the Type of your Traefik Ingress Service is NodePort, you get to access to the port provided which will have a value from 30000-32000.
You can also configure it to be of type LoadBalancer and interface with a cloud-based Load Balancer.
Ref: https://kubernetes.io/docs/tasks/access-application-cluster/create-external-load-balancer/
Here's a very related question: Should I use NodePort in my Traefik deployment on Kubernetes?
I have a Kubernetes Cluster running on Azure. I use the nginx-ingress to handle incoming requests. To set up the ingress I used the official guide https://kubernetes.github.io/ingress-nginx/deploy/#azure .
I also created a public static IP which I want to use for the Ingress.
Unfortunately, I´m not able to find the ingress service (generic-deployment.yaml). Also, my ingress is not describable.
How I installed Ingress:
$ sudo kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/mandatory.yaml
...
deployment.apps/nginx-ingress-controller created
$ sudo kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml
service/ingress-nginx created
Additionally, I installed some routing configs by ingress.yaml:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: myingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path:
backend:
serviceName: app0-service
servicePort: 80
- path: /app1
backend:
serviceName: app1-service
servicePort: 80
$sudo kubectl apply -f ingress.yaml
ingress.extensions/myingress created
What confuses me
Unfortunately, I´m not able to find my ingress-nginx service.
$ sudo kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
app0-service ClusterIP 10.0.28.3 <none> 80/TCP 3m48s
app1-service ClusterIP 10.0.226.249 <none> 80/TCP 3m47s
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 39m
But my ingress is running:
$ sudo kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
myingress * 23.97.xxx.xxx 80 54m
In browser 23.97.xxx.xxx works partly.
1) If I proxy a domain name to 23.97.xxx.xxx, the domain in a browser will be rewritten by the IP.
2) If I try to browse directly to subroute like 23.97.xxx.xxx/app1/page1. I get every time the main page of app1.
I expected to get an IP from my ingress-service. Because I want to update this IP address by adding loadbalancerIP to spec in cloud-generic.yaml.
(like https://github.com/kubernetes/ingress-nginx/blob/master/docs/examples/static-ip/static-ip-svc.yaml).
Is my IP from ingress the right one to use? And why I can´t find my ingress-service?
Looking at service yaml at https://raw.githubusercontent.com/kubernetes/ingress-nginx/master/deploy/static/provider/cloud-generic.yaml you can see it's get created in namespace ingress-nginx.
You should be able to get your service by running:
kubectl get service -n ingress-nginx
You can also get all services by running kubectl get service --all-namespaces.
I have a timeout problem with my site hosted on Kubernetes cluster provided by DigitalOcean.
u#macbook$ curl -L fork.example.com
curl: (7) Failed to connect to fork.example.com port 80: Operation timed out
I have tried everything listed on the Debug Services page. I use a k8s service named df-stats-site.
u#pod$ nslookup df-stats-site
Server: 10.245.0.10
Address: 10.245.0.10#53
Name: df-stats-site.deepfork.svc.cluster.local
Address: 10.245.16.96
It gives the same output when I do it from node:
u#node$ nslookup df-stats-site.deepfork.svc.cluster.local 10.245.0.10
Server: 10.245.0.10
Address: 10.245.0.10#53
Name: df-stats-site.deepfork.svc.cluster.local
Address: 10.245.16.96
With the help of Does the Service work by IP? part of the page, I tried the following command and got the expected output.
u#node$ curl 10.245.16.96
*correct response*
Which should mean that everything is fine with DNS and service. I confirmed that kube-proxy is running with the following command:
u#node$ ps auxw | grep kube-proxy
root 4194 0.4 0.1 101864 17696 ? Sl Jul04 13:56 /hyperkube proxy --config=...
But I have something wrong with iptables rules:
u#node$ iptables-save | grep df-stats-site
(unfortunately, I was not able to copy the output from node, see the screenshot below)
It is recommended to restart kube-proxy with with the -v flag set to 4, but I don't know how to do it with DigitalOcean provided cluster.
That's the configuration I use:
apiVersion: v1
kind: Service
metadata:
name: df-stats-site
spec:
ports:
- port: 80
targetPort: 8002
selector:
app: df-stats-site
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: df-stats-site
annotations:
kubernetes.io/ingress.class: nginx
certmanager.k8s.io/cluster-issuer: letsencrypt-prod
spec:
tls:
- hosts:
- fork.example.com
secretName: letsencrypt-prod
rules:
- host: fork.example.com
http:
paths:
- backend:
serviceName: df-stats-site
servicePort: 80
Also, I have a NGINX Ingress Controller set up with the help of this answer.
I must note that it worked fine before. I'm not sure what caused this, but restarting the cluster would be great, though I don't know how to do it without removing all the resources.
The solution for me was to add HTTP and HTTPS inbound rules in the Firewall (these are missing by default).
For DigitalOcean provided Kubernetes cluster, you can open it at https://cloud.digitalocean.com/networking/firewalls/.
UPDATE: Make sure to create a new firewall record rather than editing an existing one. Otherwise, your rules will be automatically removed in a couple of hours/days, because DigitalOcean k8s persists the set of rules in the firewall.
ClusterIP services are only accessible from within the cluster. If you want to access it from outside the cluster, it needs to be configured as NodePort or LoadBalancer.
If you are just trying to test something locally, you can use kubectl port-forward to forward a port on your local machine to a ClusterIP service on a remote cluster. Here's an example of creating a deployment from an image, exposing it as a ClusterIP service, then accessing it via kubectl port-forward:
$ kubectl run --image=rancher/hello-world hello-world --replicas 2
$ kubectl expose deployment hello-world --type=ClusterIP --port=8080 --target-port=80
$ kubectl port-forward svc/hello-world 8080:8080
This service is now accessible from my local computer at http://127.0.0.1:8080