I'm trying to deploy a simple nginx ingress object in my local kubernetes (Docker-Desktop) but I noticed that the class name is showing as "none" when I do:
➜ localk8 k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
ingress-resource none * localhost 80 15m
My ingress definition file is defined as:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello-app
port:
number: 8080
I'm also running on a M1 macbook if that makes any difference. Thanks all for the help!
I am not sure what version of kubernetes you're using, but that annotation was deprecated in 1.18.
Also, you need to define an IngressClass resource that describes the class and then reference it with the new field ingressClassName:
apiVersion: networking.k8s.io/v1
kind: IngressClass
metadata:
name: nginx
spec:
controller: example.com/ingress-controller
Then in your ingress resource add the new field under spec and reference the class name:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: ingress-resource
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "false"
spec:
// use new field
ingressClassName: nginx
rules:
- http:
paths:
- path: /hello
pathType: Prefix
backend:
service:
name: hello-app
port:
number: 8080
Related
I have 3 services in 3 different namespaces I want my ingress rules to map to these backends, on path based routes.
Can someone please guide on the same.
I am using nginx ingress inside azure Kubernetes cluster.
A basic example with an assumption that your nginx ingress is working correctly inside your AKS would be following:
List of Pods with their Services:
Pod
Namespace
Service name
nginx
alpha
alpha-nginx
nginx
beta
beta-nginx
nginx
omega
omega-nginx
Ingress definition for this particular setup:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: alpha-ingress
namespace: alpha
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: "kubernetes.kruk.lan"
http:
paths:
- path: /alpha(/|$)(.*)
pathType: Prefix
backend:
service:
name: alpha-nginx
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: beta-ingress
namespace: beta
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: "kubernetes.kruk.lan"
http:
paths:
- path: /beta(/|$)(.*)
pathType: Prefix
backend:
service:
name: beta-nginx
port:
number: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: omega-ingress
namespace: omega
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
ingressClassName: nginx
rules:
- host: "kubernetes.kruk.lan"
http:
paths:
- path: /omega(/|$)(.*)
pathType: Prefix
backend:
service:
name: omega-nginx
port:
number: 80
In this example Ingress will analyze and rewrite the requests for the same domain name to send the traffic to different namespaces i.e. alpha, beta, omega.
When you've have finalized your Ingress resource, you can use curl to validate your configuration.
curl kubernetes.kruk.lan/alpha | grep -i "<h1>"
<h1>Welcome to nginx from ALPHA namespace!</h1>
curl kubernetes.kruk.lan/beta | grep -i "<h1>"
<h1>Welcome to nginx from BETA namespace!</h1>
curl kubernetes.kruk.lan/omega | grep -i "<h1>"
<h1>Welcome to nginx from OMEGA namespace!</h1>
I'd encourage you to check following docs on rewrites:
Kubernetes.github.io: Ingress-nginx: Examples: Rewrite
PS: Pods are default nginx containers/images with added text to /usr/share/nginx/html/index.html
With host ingress manifest file is not working. Below is my manifest file with host
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: ingress-admin
namespace: default
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
external-dns.alpha.kubernetes.io/hostname: "rakesblog.co"
spec:
rules:
- host: rakesblog.co
http:
paths:
- path: /*
backend:
serviceName: bi-admin-service
servicePort: 8080
But when I remove and host then it works file. Below is the manifest file
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
namespace: default
name: ingress-admin
annotations:
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/scheme: internet-facing
alb.ingress.kubernetes.io/target-type: ip
spec:
rules:
- http:
paths:
- path: /app
backend:
serviceName: bi-admin-service
servicePort: 8080
Here is the screenshot of when I applied the ingress file with the host and then describe the ingress.
Here is my service file
apiVersion: v1
kind: Service
metadata:
name: bi-admin-service
# namespace: fargate
labels:
app: bi-admin
spec:
type: NodePort
selector:
app: bi-admin
ports:
- protocol:
port: 8080
targetPort: 8080
Kubernetes version 1.21
and I followed this doc to install ingress on my EKS cluster
Please help me out to run my ingress service by adding host in the ingress manifest file.
The ingress I config to run with the controller ingress-nginx.
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: app-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
tls:
- hosts:
- XXX.XX.com
secretName: app-tls
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
---
apiVersion: v1
kind: Service
metadata:
name: my-api
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
I can run the api locally curl localIP:3000/testapi, but it can not run remotely.
# kubectl describe ingress app-ingress
Name: app-ingress
Namespace: default
Address: XX.XX.XX.XX
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
TLS:
app-tls terminates www.daichenchen.cn
Rules:
Host Path Backends
---- ---- --------
XXX.XX.com
/my-api(/|$)(.*) app:80 (<error: endpoints "app" not found>)
I already succeed install the ingress-nginx and all the pod work without error.
Your defined serviceName in Ingress rules and Service should be same.
Like this :
...
rules:
- host: XXX.XX.com
http:
paths:
- path: /my-api(/|$)(.*)
backend:
serviceName: app
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: app
spec:
selector:
app: my-api
ports:
- name: app
port: 3000
targetPort: 3000
If Ingress and the Service is in different namespace, you can also add the service name to the ingress rule. In this case you need to use dns name for service <service-name>.<namespace>.
For example:
rules:
- host: example.com
http:
paths:
- path: /my-api
backend:
serviceName: test-service.test-namespace
servicePort: 80
apiVersion: v1
kind: Service
metadata:
name: test-service
namespace: test-namespace
The way ingress controller finds out Endpoints of a service is it searches for a kubernetes service with the serviceName provided in the ingress resource in the namespace where you have created the ingress resource. If there is no kubernetes service with serviceName found you get endpoints not found.
The Endpoints of the service contains the IPs of pods behind the kubernetes service.
So in your case either the kubernetes service does not exist or it's in a different namespace than where ingress resource is created.
Some variant of nginx ingress controller does not support default backend and for this it's expected to have the error: endpoints "default-http-backend" not found
Another variant of nginx ingress controller supports default backend.
Double check which variant of nginx ingress controller you installed
I'm running microk8s v1.18.5 from snap on Ubuntu 20.04 with addons ingress, dns, dashboard, helm3, storage.
I'm trying to externally access running services such as grafana and dashboard. I've configured proxy services and ingresses as per docs:
kind: Service
apiVersion: v1
metadata:
name: grafana
namespace: ingress
spec:
type: ExternalName
externalName: monitoring-grafana.kube-system.svc.cluster.local
ports:
- port: 80
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: grafana-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- "grafana.example.com"
secretName: grafana-tls
rules:
- host: grafana.example.com
http:
paths:
- backend:
serviceName: grafana
servicePort: 80
path: /
---
and
kind: Service
apiVersion: v1
metadata:
name: dashboard
namespace: ingress
spec:
type: ExternalName
externalName: kubernetes-dashboard.kube-system.svc.cluster.local
ports:
- port: 443
---
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: dashboard-ingress
annotations:
kubernetes.io/ingress.class: "nginx"
cert-manager.io/cluster-issuer: "letsencrypt-prod"
kubernetes.io/tls-acme: "true"
spec:
tls:
- hosts:
- "dashboard.example.com"
secretName: dashboard-tls
rules:
- host: dashboard.example.com
http:
paths:
- backend:
serviceName: dashboard
servicePort: 443
path: /
---
Trying to access either dashboard or grafana I get:
503 Service Temporarily Unavailable
openresty/1.15.8.1
What can I do to find the root cause?
I'm also running cert-manager and external-dns from helm3, could their config be related to the issue?
First you have to change your dashboard and grafana service type to NodePort for ingress to work correctly.
Besides that Kubernetes dashboard for microk8s is accessible under <master_node_ip>:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/ path so you have to mention it in either your URL or in your ingress manifest. When you curl dashboard.example.com
it gives you 503 Service Temporarily Unavailable error. However when you enter full path it will show the website:
curl http://dashboard.example.com:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy
<!--
Copyright 2017 The Kubernetes Authors.
[...]
This is an example of ingress that will rewrite /api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy to /dashboard/
kind: Ingress
apiVersion: networking.k8s.io/v1beta1
metadata:
name: grafana-ingress
namespace: kube-system
annotations:
kubernetes.io/ingress.class: nginx
# Add https backend protocol support for ingress-nginx
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS"
nginx.ingress.kubernetes.io/configuration-snippet: |
proxy_set_header Accept-Encoding "";
sub_filter '<base href="/">' '<base href="/dashboard/">';
sub_filter_once on;
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: dashboard.example.com
http:
paths:
- path: /dashboard(/|$)(.*)
backend:
serviceName: kubernetes-dashboard
servicePort: 443
Say I have a service that isn't hosted on Kubernetes. I also have an ingress controller and cert-manager set up on my kubernetes cluster.
Because it's so much simpler and easy to use kubernetes ingress to control access to services, I wanted to have a kubernetes ingress that points to a non-kubernetes service.
For example, I have a service that's hosted at https://10.0.40.1:5678 (ssl required, but self signed certificate) and want to access at service.example.com.
You can do it by manual creation of Service and Endpoint objects for your external server.
Objects will looks like that:
apiVersion: v1
kind: Service
metadata:
name: external-ip
spec:
ports:
- name: app
port: 80
protocol: TCP
targetPort: 5678
clusterIP: None
type: ClusterIP
---
apiVersion: v1
kind: Endpoints
metadata:
name: external-ip
subsets:
- addresses:
- ip: 10.0.40.1
ports:
- name: app
port: 5678
protocol: TCP
Then, you can create an Ingress object which will point to Service external-ip with port 80:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: external-service
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: external-ip
servicePort: 80
path: /
So I got this working using ingress-nginx to proxy an managed external service over a non-standard port
apiVersion: v1
kind: Service
metadata:
name: external-service-expose
namespace: default
spec:
type: ExternalName
externalName: <external-service> # eg example.example.com
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: external-service-expose
namespace: default
annotations:
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #important
spec:
rules:
- host: <some-host-on-your-side> # eg external-service.yourdomain.com
http:
- path: /
pathType: Prefix
backend:
service:
name: external-service
port:
number: <port of external service> # eg 4589
tls:
- hosts:
- external-service.yourdomain.com
secretName: <tls secret for your domain>
of-course you need to make sure that the managed url is reachable from inside the cluster, a simple check can be done by launching a debug pod and doing
curl -v https://example.example.com:4589
If your external service has a dns entry configured on it, you can use kubernetes externalName service.
---
apiVersion: v1
kind: Service
metadata:
name: my-service
namespace: prod
spec:
type: ExternalName
externalName: myexternal.http.service.com
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: externalNameservice
namespace: prod
spec:
rules:
- host: service.example.com
http:
paths:
- backend:
serviceName: my-service
servicePort: 80
path: /
In this way, kubernetes create cname record my-service pointing to myexternal.http.service.com
I just want to update #Moulick answer here according to Kubernetes version v1.21.1, as for ingress the configuration has changed a little bit.
In my example I am using Let's Encrypt for my nginx controller:
apiVersion: v1
kind: Service
metadata:
name: external-service
namespace: default
spec:
type: ExternalName
externalName: <some-host-on-your-side> eg managed.yourdomain.com
ports:
- port: <port of external service> eg 4589
---
kind: Ingress
apiVersion: networking.k8s.io/v1
metadata:
name: external-service
namespace: default
annotations:
cert-manager.io/cluster-issuer: "letsencrypt-prod"
nginx.ingress.kubernetes.io/proxy-body-size: 100m
nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" #important
spec:
tls:
- hosts:
- <some-host-on-your-side> eg managed.yourdomain.com
secretName: tls-external-service
rules:
- host: <some-host-on-your-side> eg managed.yourdomain.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: external-service
port:
number: <port of external service> eg 4589