ingress can not get the default http backend - kubernetes

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

Related

Warning: Rejected - All hosts are taken by other resources

I'm trying to setup Nginx-ingress controller to manage two paths on the same hostname in bare metal based cluster.
In the app1 namespace i have below nginx resource:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app1-ingress
namespace: app1
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
And in the app2 namespace i have below nginx resource:-
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app2-ingress
namespace: app2
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
My app1-service applied first and it is running fine, now when i applied the second app2-service it shows below warning and not able to access it on browser.
Annotations: <none>
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
Warning Rejected 54s nginx-ingress-controller All hosts are taken by other resources
How do i configure my nginx ingress resource to connect multiple service paths on the same hostname?
Default Nginx Ingress controller doesn't support having different Ingress resources with the same hostname. You can have one Ingress resource that contains multiple paths, but in this case all apps should live in one namespace. Like this:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app1-ingress
namespace: app1
spec:
ingressClassName: nginx
rules:
- host: web.example.com
http:
paths:
- path: /app1
pathType: Prefix
backend:
service:
name: app1-service
port:
number: 80
- path: /app2
pathType: Prefix
backend:
service:
name: app2-service
port:
number: 80
Splitting ingresses between namespaces is currently not supported by standard Nginx Ingress controller.
You may however take a look at an alternative implementation of Nginx Ingress by Nginx Inc. They have support for Mergeable Ingresses.

Kuberenetes - Custom domain ingress

I have a cluster IP service and a Ingress. What should my custom domain name point to if I need to route traffic using Ingress? Backend is plain http.
Do I have to create a AWS Loadbalancer with target groups pointing to k8s nodes? And use domain alias pointing to aws loadbalancer? I was reading this K8s article and they're pointing to a subdomain.
Ingress.yaml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
creationTimestamp: "2022-08-05T00:50:41Z"
generation: 1
labels:
app: testing
name: httpd
namespace: default
spec:
rules:
- host: www.example.com
http:
paths:
- backend:
service:
name: httpd
port:
number: 8080
path: /
pathType: ImplementationSpecific
tls:
- hosts:
- www.example.com
secretName: tls-secret
status:
loadBalancer: {}
service.yaml:
kind: Service
metadata:
creationTimestamp: "2022-08-05T00:50:41Z"
labels:
app: testing
name: httpd
namespace: default
spec:
clusterIP: 100.65.xxx.xx
clusterIPs:
- 100.65.xxx.xx
internalTrafficPolicy: Cluster
ipFamilies:
- IPv4
ipFamilyPolicy: SingleStack
ports:
- name: http
port: 8080
protocol: TCP
targetPort: 8080
selector:
name: httpd
sessionAffinity: None
type: ClusterIP
status:
loadBalancer: {}
Yes you have to create the Load Balancer however that will auto managed by the K8s service.
You can use the Nginx or other ingress controller as per requirement.
You can checkout this Nice official doc from AWS : https://aws.amazon.com/blogs/opensource/network-load-balancer-nginx-ingress-controller-eks/
Once you deploy the Nginx ingress controller it will manage the ingress resource and the Nginx controller will get the public LB.
Example :
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/force-ssl-redirect: "false"
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
tls:
- hosts:
- anthonycornell.com
secretName: tls-secret
rules:
- host: anthonycornell.com
http:
paths:
- path: /apple
backend:
serviceName: apple-service
servicePort: 5678
- path: /banana
backend:
serviceName: banana-service
servicePort: 5678

Ingress to redirect to service from LB ip

I'm trying to create an Ingress rule to redirect requests from LoadBalancer to Service.
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless
backend:
serviceName: node-red
servicePort: 1880
The above yaml script is supposed to redirect all requests from https://LOAD_BALANCER_IP/hostless to node-red on port 1880
If I try to request the above URL, I got an error Cannot GET /hostless. Requesting the root gives 404 page not found.
I can access my services with the direct URL (eg. http://LOAD_BALANCER_IP:1880 will redirect to Node-red service).
Service yaml looks like that:
apiVersion: v1
kind: Service
metadata:
labels:
app: node-red
name: node-red
spec:
ports:
- name: "1880"
port: 1880
protocol: TCP
targetPort: 1880
selector:
app: node-red
sessionAffinity: None
type: LoadBalancer
How to use ingress to reach a service whereas a custom port ?
I've found a way to make it works !
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
cert-manager.io/cluster-issuer: letsencrypt-prod
traefik.ingress.kubernetes.io/redirect-entry-point: https
kubernetes.io/ingress.class: "traefik"
traefik.ingress.kubernetes.io/router.middlewares: "kube-system-traefik-stripprefix#kubernetescrd"
name: traefik-all
namespace: partner
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: nginx-demo
servicePort: 2222
- path: /node
backend:
serviceName: node-red
servicePort: 1880
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: traefik-stripprefix
namespace: kube-system
spec:
stripPrefixRegex:
regex:
- "/[^/]+"
I use a middleware to remove the prefix as K3S Traefik does not support the traefik.ingress.kubernetes.io/rewrite-target annotation.
With the above code, all trafic from LOAD_BALANCER_IP/* will be redirected to nginx-demo:2222 service. All trafic from LOAD_BALANCER_IP/node/* will be redicted to node-red:1880 service.
I hope this could help someone !
Try setting a rewrite-target annotation, which will effectively rewrite /hostless requests to /, i.e. http://LOAD_BALANCER_IP:1880/hostless externally to http://node-red:1880 internally.
For example:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: hostlessendpoint
spec:
rules:
- http:
paths:
- path: /hostless(/|$)(.*)
backend:
serviceName: node-red
servicePort: 1880
See this link, assuming you are using Nginx ingress controller.

Can I use ip address in Kubernetes Ingress instead of domain name?

I am using Traefik as Kubernetes Ingress and I would like to know if I can use an IP address instead of a domain name. Example:
http://ipaddress/service1
http://ipdadress/service2
My ingress configuration:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: service1
namespace: staging
annotations:
kubernetes.io/ingress.class: traefik
traefik.frontend.rule.type: PathPrefixStrip
spec:
rules:
- host: mydomain.dev
http:
paths:
- path: /service1
backend:
serviceName: service1
servicePort: 3000
Since it is a Layer 7 Load Balancer you can't use IP address directly. But if you use nip.io and for example 192-168-1-1.nip.io as your hostname it would work and you can do all the things you can regularly do with normal hostnames such as redirect app1.192-168-1-1.nip.io to app1 and 192-168-1-1.nip.io/app2 to app2 etc.
I have done this with kong but i believe it should also work with traefik, by simply removing the host. unfortunately now you can't access it with the domain name
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: service1
namespace: staging
annotations:
kubernetes.io/ingress.class: traefik
traefik.frontend.rule.type: PathPrefixStrip
spec:
rules:
# - host: mydomain.dev
- http:
paths:
- path: /service1
backend:
serviceName: service1
servicePort: 3000
Hope it helps!

Kubernetes Ingress to External Service?

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