Hello,
I understand how to use the meshed services via dns names (servicename.namespace.maesh).
How can I ensure that resources like Ingress, IngressRoute from Traefik or ServiceMonitor from Prometheus Operator use the meshed service? In all of these resources the service is addressed via service name (and namespace) not dns name.
You're right! In Ingress and IngressRoute resources, you have to reference services by name and namespace, not by DNS name.
Under the hood, Maesh uses Kubernetes services called shadow services which allow to forward a request through mesh proxies to your service pods when the meshed DNS name is requested.
If you want to forward an Ingress request to the meshed service you have to reference the shadow services in the Ingress or IngressRoute. These services are created in the namespace where Maesh was installed in and have the following name #{maesh.namespace}-#{meshedService.name}-6d61657368-#{meshedService.namespace}.
Please keep in mind that we're planning to work on that subject and as it's not part of our public API it is subject to change between Maesh versions.
If I'm not wrong, in ServiceMonitor you have to use labels to indicate which pods would be scrapped by Prometheus. So, here nothing special to do as you probably want to monitor your service pods and not the mesh proxies.
First off, thanks for the work on Maesh, it's nice run a mesh without sidecars!
I have been having a hard time setting the Ingress to the shadow service when trying out on a local Minikube setup. When using just the server service, I get the expected output, when I change to the default-server-6d61657368-default shadow service I get '404 page not found'. Service to service communication works as expected.
Am I doing anything wrong?
I'm using Minikube 1.13 running Kubernetes 1.19 using the default ingress add-on (nginx). Maesh is installed from Helm as documented. Here's the full config:
apiVersion: apps/v1
kind: Deployment
metadata:
name: server
labels:
app: server
spec:
replicas: 1
selector:
matchLabels:
app: server
template:
metadata:
labels:
app: server
spec:
containers:
- name: server
image: traefik/whoami:v1.6.0
ports:
- containerPort: 80
---
kind: Service
apiVersion: v1
metadata:
name: server
spec:
selector:
app: server
ports:
- name: web
protocol: TCP
port: 80
targetPort: 80
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: example-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$1
spec:
rules:
- host: server
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: default-server-6d61657368-default
port:
number: 80
After thinking a bit more on the subject, as you can see in the issue answers, I've missed that an Ingress can only reference a Service in the same namespace. So, you're not doing something wrong, I think the issue is that the shadow service is not in the namespace of your Ingress.
Thanks for the blazing fast response @kevinpollet!
Indeed the Ingress add-on is in the kube-system namespace by default. I've replaced it with the standard Nginx Ingress and deployed to the default namespace. Unfortunately this didn't seem to have any effect, the call to the ingress still returns a '404 page not found' from the default-server-6d61657368-default shadow service.
Is that anything else that is required for the Ingress link to work? Does the hostname have to match the shadow service name? Or do even the Kubernetes internals (i.e. the DNS server) have to be in the same namespace as the shadow services perhaps?
I've just tried to achieve what you want with Traefik as an Ingress Controller. As I said only the created Ingress resource needs to be in the namespace of the shadow service and you were right the hostname must match the DNS name of the service which is not ideal.
Here is my Ingress resource configuration for a whoami service which is in the default namespace: