tekton-pipeline ingress route conflicts with kubesphere-console - kubernetes

I have two ingress routes created as below,
kubesphere-console
tekton-pipelines
My manifest files are as like below.
**cat ingress-tekton-dashboard.yaml **
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: tekton-dashboard
annotations:
ingress.kubernetes.io/ssl-redirect: "false"
nginx.ingress.kubernetes.io/ssl-redirect: "false"
ingressClassName: nginx
spec:
ingressClassName: nginx
rules:
- http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: tekton-dashboard
port:
number: 9097
#host: *
...
cat ../kubesphere/ingress-route-kubesphere.yaml
cat ../kubesphere/ingress-route-kubesphere.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: kubesphere-console
annotations:
kubesphere.io/creator: admin
spec:
ingressClassName: nginx
rules:
- host: crashandburn.australiaeast.cloudapp.azure.com
http:
paths:
- path: /
pathType: ImplementationSpecific
backend:
service:
name: ks-console
port:
number: 80
---
My ingress are as below:
k get ing -nkubesphere-system
NAME CLASS HOSTS ADDRESS PORTS AGE
kubesphere-console nginx * 20.92.133.79 80 28h
ameya#Azure:~/tekton$ k get ing -ntekton-pipelines
NAME CLASS HOSTS ADDRESS PORTS AGE
tekton-dashboard <none> * 80 2m32s
My service for tekton dashboard is like below:
k get svc -n tekton-pipelines
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
tekton-dashboard ClusterIP 10.0.202.127 <none> 9097/TCP 2d3h
tekton-pipelines-controller ClusterIP 10.0.53.46 <none> 9090/TCP,8008/TCP,8080/TCP 2d6h
tekton-pipelines-webhook ClusterIP 10.0.222.121 <none> 9090/TCP,8008/TCP,443/TCP,8080/TCP 2d6h
However, I get the error like below:
k apply -f ingress-tekton-dashboard.yaml -ntekton-pipelines
Error from server (BadRequest): error when applying patch:
{"metadata":{"annotations":{"kubectl.kubernetes.io/last-applied-configuration":"{\"apiVersion\":\"networking.k8s.io/v1\",\"kind\":\"Ingress\",\"metadata\":{\"annotations\":{\"ingress.kubernetes.io/ssl-redirect\":\"false\",\"ingressClassName\":\"nginx\",\"nginx.ingress.kubernetes.io/ssl-redirect\":\"false\"},\"name\":\"tekton-dashboard\",\"namespace\":\"tekton-pipelines\"},\"spec\":{\"ingressClassName\":\"nginx\",\"rules\":[{\"http\":{\"paths\":[{\"backend\":{\"service\":{\"name\":\"tekton-dashboard\",\"port\":{\"number\":9097}}},\"path\":\"/\",\"pathType\":\"Prefix\"}]}}]}}\n"}},"spec":{"ingressClassName":"nginx"}}
to:
Resource: "networking.k8s.io/v1, Resource=ingresses", GroupVersionKind: "networking.k8s.io/v1, Kind=Ingress"
Name: "tekton-dashboard", Namespace: "tekton-pipelines"
for: "ingress-tekton-dashboard.yaml": admission webhook "validate.nginx.ingress.kubernetes.io" denied the request: host "_" and path "/" is already defined in ingress kubesphere-system/kubesphere-console
However, I am using two differnt ports for tekton-dashboard and kubesphere-console so wondering why it is complaining.

Related

How to manage two paths on the same hostname?

I'm using Kubernetes v1.23.16 cluster (One master and three workers) bare metal based.
I have created couple of services in a separate namespace. The same as follows.
$ kubectl get services --all-namespaces
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 11d
app1 app1-service ClusterIP 10.103.151.235 <none> 80/TCP 19h
app2 app2-service ClusterIP 10.105.88.151 <none> 80/TCP 11d
kube-system kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP,9153/TCP 11d
Now I'm having below nginx resource yml to access the service outside. For example i would like access as given below.
http://web.example.com/app1
http://web.example.com/app2
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
name: app-ingress
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
When i apply the nginx resource yml file it says service not found error.
$ kubectl describe ingress app-ingress
Name: app-ingress
Labels: <none>
Namespace: default
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
web.example.com
/app1 app1-service:80 (<error: endpoints "app1-service" not found>)
/app2 app2-service:80 (<error: endpoints "app2-service" not found>)
Annotations: nginx.ingress.kubernetes.io/rewrite-target: /$2
Since my applications services are running in different namespace separately and my nginx resource yml is running in default namespace. So now how do i configure nginx resource file to access both of my service?
An Ingress resource can only refer to Services in the same namespace as the Ingress. To manage two paths on the same hostname that lead to backends in different namespaces, you will need two separate Ingress resources.
In the app1 namespace:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-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:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-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
With these resources in place, requests for http://web.example.com/app1 will go to app1-service, and requests for http://web.example.com/app2 will go to app2-service.
NB: I've removed your nginx.ingress.kubernetes.io/rewrite-target annotation because you're not doing any regex-based path rewriting in this example.
I've put a deployable example online here.
Just remove your rewrite path in single ingress you can achieve it.
If you are creating the multiple make sure to change the name as Larsks suggested else it will overwrite the existing one.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: app-ingress
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

Error: endpoints "default-http-backend" not found

I have Kubernetes cluster v1.19.16 set up in bare metal Ubuntu-18.04 server and currently i want to connect cluster jenkins service through http://jenkins.company.com. Haproxy server side frontend & backend already been configured.
My service.yaml file content as follows,
apiVersion: v1
kind: Service
metadata:
name: jenkins-svc
namespace: jenkins
annotations:
prometheus.io/scrape: 'true'
prometheus.io/path: /
prometheus.io/port: '8080'
spec:
selector:
app: jenkins-server
type: ClusterIP
ports:
- protocol: TCP
port: 8080
targetPort: 80
ingress-resource.yaml file content as follows,
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: jenkins-ingress
namespace: jenkins
annotations:
kubernetes.io/ingress.class: "nginx"
spec:
rules:
- host: "jenkins.company.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
serviceName: jenkins-svc
servicePort: 8080
# kubectl get service -n jenkins
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
jenkins-svc ClusterIP 10.96.136.255 <none> 8080/TCP 20m
# kubectl get ing jenkins-ingress
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
jenkins-ingress <none> jenkins.company.com 80 5h42m
# kubectl describe ingress -n jenkins
Warning: extensions/v1beta1 Ingress is deprecated in v1.14+, unavailable in v1.22+; use networking.k8s.io/v1 Ingress
Name: jenkins-ingress
Namespace: jenkins
Address:
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>)
Rules:
Host Path Backends
---- ---- --------
jenkins.dpi.com
/ jenkins-svc:8080 (10.244.0.16:80)
Annotations: ingress.kubernetes.io/rewrite-target: /
kubernetes.io/ingress.class: nginx
Events: <none>
When i tried to access http://jenkins.company.com it shows below error message on browser.
Please let me know what i'm missing here?
The issue with the service port and container port. Jenkins default port is 8080, so I assume your service port is 80
ports:
- protocol: TCP
port: 80
targetPort: 8080
and ingress should be
spec:
rules:
- host: "jenkins.company.com"
http:
paths:
- pathType: Prefix
path: "/"
backend:
serviceName: jenkins-svc
servicePort: 80
port: The port of this service
targetPort The target port on the pod(s) to forward traffic to
Difference between targetPort and port in Kubernetes Service definition

Ingress cannot route the apis

My ingress cannot route to endpoint.
I provided everything. Nginx-controller works properly. I added the hostname bago.com as loadbalancerip. But it doesn't work.
Here is my ingres's yaml file
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
rules:
- host: bago.com
- http:
paths:
- path: /web1/
pathType: Exact
backend:
service:
name: web1-clusterip
port:
number: 8081
- path: /web2/
pathType: Exact
backend:
service:
name: web2-clusterip
port:
number: 8082
svc and ingress running
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$ k get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kubernetes ClusterIP 10.12.0.1 <none> 443/TCP 154m
web1-clusterip ClusterIP 10.12.6.102 <none> 8081/TCP 145m
web2-clusertip ClusterIP 10.12.9.22 <none> 8082/TCP 149m
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$ k get ingress
NAME CLASS HOSTS ADDRESS PORTS AGE
minimal-ingress <none> bago.com 34.102.241.199 80 121m
bahaddin#bahaddin-ThinkPad-E15-Gen-2:~/projects/personal/exposer/k8s-ingress$
Here is my API java code.
#RequestMapping("/web1")
#RestController
public class Controller {
#GetMapping("/hello")
public String foo() {
return "hello from web1 ms";
}
}
server.port=8081 on container level
my service
Web1-service.
apiVersion: v1
kind: Service
metadata:
name: web1-clusterip
spec:
ports:
- protocol: "TCP"
port: 8081
selector:
app: web1-dp
type: ClusterIP
But when I type in the browser
http://bago.com/web1/hello
http://bago.com/web1/hello
I got a 404 not found error
Screenshot
You have an issue in your ingress manifest. You have two items in the list, while you want to have one. Additionally, you are missing the ingress class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
rules:
# these are indivudal list items
- host: bago.com
- http: ...
You have to change the manifest so that you have a single item. You should also add the ingress class.
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: minimal-ingress
spec:
# this should be the ingress class, i.e. nginx
ingressClassName: my-ingress-class
rules:
# this list has only 1 items, which is an object.
# note the dash (-)
- host: bago.com
http: ...
I see that for the ingress, you have class as <none> if your nginx-controller is making use of a class then you have to define that as ingressClassName under the spec section while creating ingress (rules).
you can identify the classname by describing the ingress-controller.
kubectl describe deployments.apps <your-ingress-controller-deployment> -n=<namespace> and look for --ingress-class parameter by default the classname should be nginx.
This class name is useful if more than one ingress-controller are present on the cluster, by defining the class we can tell which ingress-controller is responsible for which specific ingress rules.

Kubernetes: load-balance across two different namespaces

I want to deploy different versions of the same application in production:
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:1.0 -n test-a
kubectl create deployment hello-server --image=gcr.io/google-samples/hello-app:2.0 -n test-b
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-a
kubectl expose deployment hello-server --port 80 --target-port 8080 -n test-b
I've tried to load-balance it like this:
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: test
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.org/server-snippets: |
upstream test-servers-upstream {
server hello-server.test-a:80;
server hello-server.test-b:80;
}
spec:
rules:
- host: test-servers.example.com
http:
paths:
- path: /
backend:
serviceName: test-servers-upstream
servicePort: 80
but it returns an error:
/ test-servers-upstream:80 (<error: endpoints "test-servers-upstream" not found>)
Services:
$ kubectl get services -n test-b
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server ClusterIP 10.128.199.113 <none> 80/TCP 75m
$ kubectl get services -n test-a
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-server ClusterIP 10.128.207.6 <none> 80/TCP 75m
How can I load-balance it?
Fresh ingress-nginx supports weight-based canary deployments out of box.
Looks like what you're asking for.
https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/annotations/#canary.
Great example here.
https://medium.com/#domi.stoehr/canary-deployments-on-kubernetes-without-service-mesh-425b7e4cc862
Basically, you create 2 identical ingresses, one for each namespace.
They are different only in annotations and in pointing to different services.
# ingress for a service A in namespace A
kind: Ingress
metadata:
name: demo-ingress
namespace: demo-prod
spec:
rules:
- host: canary.example.com
http:
paths:
- backend:
serviceName: demo-prod
servicePort: 80
path: /
# ingress for a service B in namespace B
# note canary annotations
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "20"
name: demo-ingress
namespace: demo-canary
spec:
rules:
- host: canary.example.com
http:
paths:
- backend:
serviceName: demo-canary
servicePort: 80
path: /
Note, that ingress-nginx canary implementation actually requires your services to be in different namespaces.

K8s ingress for path based routing for multiple services

I am using nginx ingress for path based routing for multiple services .
My services output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S)
ingress-nginx-controller LoadBalancer X.X.X.33 X.X.X.112 80:30853/TCP,443:31386/TCP
ingress-nginx-controller-admission ClusterIP X.X.X.139 <none> 443/TCP
test1 ClusterIP X.X.X.197 <none> 9080/TCP
test2 ClusterIP X.X.X.30 <none> 9995/TCP
My ingress.yaml file
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress-resource
annotations:
nginx.ingress.kubernetes.io/rewrite-target: "/"
spec:
rules:
- http:
paths:
- path: /test2
backend:
serviceName: test2
servicePort: 9995
- path: /test1
backend:
serviceName: test1
servicePort: 9080
and kubectl ingress output
NAME HOSTS ADDRESS PORTS AGE
ingress-resource * 80 45m
When i am trying to access service from outside cluster -
I am getting 404
-> http:// X.X.X.112/test1 return 404
-> http:// X.X.X.112/test2 return 404
Where X.X.X.112 is external ip of ingress-nginx-controller
-> When I create ingress to services running on port 8080, it seems to be working fine.
What the issue ?
I figured out the issue. I was missing
annotations:
kubernetes.io/ingress.class: nginx
Now I have other issue.
When I use
spec:
rules:
- http:
paths:
- path: /
backend:
serviceName: test2
servicePort: 9995
My http:// X.X.X.112/ works fine and it points to serviceName - test2
Similarly it works for other service.
but when I use
spec:
rules:
- http:
paths:
- path: /test2
backend:
serviceName: test2
servicePort: 9995
- path: /test1
backend:
serviceName: test1
servicePort: 9080
and I get 405 method not allowed, when doing
-> http:// X.X.X.112/test1 return 405
-> http:// X.X.X.112/test2 return 405
I tired adding few more annotations .
nginx.ingress.kubernetes.io/cors-allow-credentials: "true"
nginx.ingress.kubernetes.io/cors-allow-methods: PUT, GET, POST, OPTIONS, DELETE, PATCH
nginx.ingress.kubernetes.io/enable-cors: "true"
I am missing something else ?
Ive tried your example on GKE (with changed deployment as you didnt provide which one you have used).
As I mentioned in comments, to force Nginx Ingress on GKE you must use annotation:
annotations:
kubernetes.io/ingress.class: nginx
Otherwise GKE will use default gce ingress which do not support rewrite annotation.
apiVersion: apps/v1
kind: Deployment
metadata:
name: test1
spec:
replicas: 1
selector:
matchLabels:
key: test1
template:
metadata:
labels:
key: test1
spec:
containers:
- name: hello1
image: gcr.io/google-samples/hello-app:1.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: test1
spec:
selector:
key: test1
ports:
- port: 80
targetPort: 8080
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: test2
labels:
app: mycha-app
spec:
replicas: 1
selector:
matchLabels:
app: test2
template:
metadata:
labels:
app: test2
spec:
containers:
- name: nginx2
image: nginx
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: test2
labels:
app: test2
spec:
ports:
- port: 80
targetPort: 80
protocol: TCP
selector:
app: test2
---
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ingress
annotations:
kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- http:
paths:
- path: /test1
backend:
serviceName: test1
servicePort: 80
- path: /test2
backend:
serviceName: test2
servicePort: 80
$ kubectl get svc -A
NAMESPACE NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
default kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 7h59m
default test1 ClusterIP 10.0.14.220 <none> 80/TCP 9m18s
default test2 ClusterIP 10.0.0.243 <none> 80/TCP 9m16s
ingress-nginx ingress-nginx-controller LoadBalancer 10.0.7.75 35.228.2XX.XX 80:32643/TCP,443:32733/TCP 18m
$ curl 35.228.2XX.XX/test1
Hello, world!
Version: 1.0.0
Hostname: test1-5844dc9688-n95tj
$ curl 35.228.2XX.XX/test2
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
body {
width: 35em;
...
If this example will not work on your cluster, you will need to create Firewall rules to allow traffic.
If this example will work it means that you have configuration mismatch in your Deployment/Service.
It might be selector misconfigure between service and deployment (in first one it was key: test1 and in second deployment app: test2).
Application is listening on different port that was set in containerPort. If you set only port in service, the same value will be set in containerPort. In test1 deployment it would not work as hello-app:1.0 listening only on port 8080.
Hello pod
# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 :::8080 :::* LISTEN 1/hello-app
Nginx pod
# netstat -plnt
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 1/nginx: master pro
Please comment if you will still have issue.