I have created an on-premise kubernetes cluster using kubespray. The cluster consists of 3 master and 3 worker nodes. I have followed the documentation from this website : https://www.linuxtechi.com/install-kubernetes-using-kubespray/
Then I have configured MetalLB and nginx-ingress controller using this github repo : https://github.com/morrismusumi/kubernetes/blob/main/clusters/homelab-k8s/apps/metallb-plus-nginx-ingress/README.md
Right now all my nodes are available and they are working fine but when i deploy the example webapp in the link https://github.com/morrismusumi/kubernetes/blob/main/clusters/homelab-k8s/apps/metallb-plus-nginx-ingress/web-app-ingress.yml i cannot reach it from my local machine unless i make the "type: LoadBalancer" in my web-app-deployment.yaml
My cluster ips are as follows
- M01 - 11.11.120.50
- M02 - 11.11.120.51
- M03 - 11.11.120.52
- W01 - 11.11.120.53
- W02 - 11.11.120.54
- W03 - 11.11.120.55
and for my metal-lb address pool i used 11.11.120.150-11.11.120.170
When i deploy an example nginx web app with "LoadBalancer" type it can assign an External IP and when i curl to this external IP i can successfully see the output "welcome to my first website" from my local. when i change the service type from LoadBalancer to Cluster IP and create ingress yaml, i can see the External IP address in "kubectl get ingress" output. But in this scenario, when i try to curl from my local machine i can not reach to this address. if i try from cluster nodes, i can access.
Manifests files for example web-app are as follows:
web-deployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
labels:
app.kubernetes.io/name: web-app
name: web-app
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: web-app
template:
metadata:
labels:
app.kubernetes.io/name: web-app
spec:
containers:
- image: nginx
name: web-app
command:
- /bin/sh
- -c
- "echo 'welcome to my web app!' > /usr/share/nginx/html/index.html && nginx -g 'daemon off;'"
dnsConfig:
options:
- name: ndots
value: "2"
---
apiVersion: v1
kind: Service
metadata:
name: web-app
labels:
app.kubernetes.io/name: web-app
spec:
selector:
app.kubernetes.io/name: web-app
ports:
- name: http
port: 80
protocol: TCP
targetPort: 80
type: ClusterIP
web-app-ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: example-webapp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: web-app
port:
number: 80
and i added hostname and IP to my /etc/hosts file like "11.11.120.151 example-webapp.com"
my ingress output:
kubectl get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
web-app <none> example-webapp.com 11.11.120.151 80 63m
my service output:
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.233.x.x <none> 443/TCP 42h
web-app ClusterIP 10.233.x.x <none> 80/TCP 70m
By the way, i changed my web-app service externalTrafficPolicy from Cluster to Local. But nothing has changed.
The only way to reach it from my local machine is making the "type: LoadBalancer" as i started before. While i can access via LoadBalancer, i cannot access with Ingress. Can you help me to solve this problem?
Thanks in advance.
I solved the issue;
Instead of the image in the official nginx installation document, I used the image on Kubernetes' own site: https://kubernetes.github.io/ingress-nginx
(changed the nginx helm repo from oci://ghcr.io/nginxinc/charts/nginx-ingress to https://kubernetes.github.io/ingress-nginx)
When I followed this doc my problem was fixed. In fact, the difference was that it created only one controller and a default-backend deployment. When I applied it as in the sample ingress yaml (writing ingressClassName under spec instead of annotation), my problem was solved and I was able to access ingress resources successfully.