Is it possible to route Ingress requests based on service labels instead of a service name?
I would like to have 2 services with the same name but different label values. Can Ingress route traffic like this?
service-name.labelA.com -> service with label = A
service-name.labelB.com -> service with label = A
Is it possible to do so? Because in the Docs it uses routing by service name and port (no labels):
spec:
rules:
- http:
paths:
- path: /testpath
backend:
serviceName: test
servicePort: 80
Kubernets won't let you creating two services with the same name
$ cat service_A.yaml apiVersion: v1
kind: Service
metadata:
name: portfwd-srv-a
spec:
ports:
-
nodePort: 30010
port: 88
name: knp1
selector:
app: nginx
type: NodePort
cat service_B.yaml apiVersion: v1
kind: Service
metadata:
name: portfwd-srv-a
spec:
ports:
-
nodePort: 30011
port: 88
name: knp1
selector:
app: nginx
type: NodePort
$ kubectl create -f service_A.yaml
service/portfwd-srv-a created
$ kubectl create -f service_B.yaml
Error from server (AlreadyExists): error when creating "service_B.yaml": services "portfwd-srv-a" already exists
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
kubernetes ClusterIP 10.0.0.1 <none> 443/TCP 6d3h <none>
portfwd-srv-a NodePort 10.0.5.233 <none> 88:30010/TCP 3m app=nginx
web NodePort 10.0.4.73 <none> 8080:31881/TCP 3d run=web
However, it is possible to target the same service (or any service of your choice with the Ingress). The example below is influenced by the Ingress documentation.
$ cat ingress_namebased.yaml
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: name-virtual-host-ingress
spec:
rules:
- host: foo.bar.com
http:
paths:
- backend:
serviceName: web
servicePort: 8080
- host: bar.foo.com
http:
paths:
- backend:
serviceName: web
servicePort: 8080
here I'm serving requests sent to foo.bar.com
and bar.foo.com
with the web
service:
$ kubectl get ingress
NAME HOSTS ADDRESS PORTS AGE
name-virtual-host-ingress foo.bar.com,bar.foo.com 35.186.*.* 80 134m
$ kubectl get svc -o wide
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE SELECTOR
web NodePort 10.0.4.73 <none> 8080:31881/TCP 3d run=web
...
that points to a few pods/end_points:
$ kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
web-ddb799d85-7x2v4 1/1 Running 0 3d 10.12.0.6 cluster-1-pool-1-6v3n <none> <none>
web-ddb799d85-p2cq8 1/1 Running 0 2d21h 10.12.1.8 cluster-1-pool-1-m7z8 <none> <none>
$ kubectl get ep -o wide
NAME ENDPOINTS AGE
web 10.12.0.6:8080,10.12.1.8:8080 3d
and here the example of how it works from "end user" prospective ( round robin because I have 2 end points ):
$ curl foo.bar.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-7x2v4
$ curl foo.bar.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-p2cq8
curl bar.foo.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-p2cq8
$ curl bar.foo.com
Hello, world!
Version: 1.0.0
Hostname: web-ddb799d85-7x2v4