How to expose Traefik v2 dashboard with Kubernetes Ingress - kubernetes

Currently I use Traefik IngressRoute to expose the Traefik dashboard. I am using this configuration:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard
namespace: my-namespace
spec:
routes:
- match: Host(`traefik.example.com`) && (PathPrefix(`/api`) || PathPrefix(`/dashboard`))
kind: Rule
services:
- name: api#internal
kind: TraefikService
middlewares:
- name: traefik-dashboard-https-redirect
- name: traefik-dashboard-basic-auth
tls:
certResolver: le
and it works fine.
However I would like to expose it with a native Kubernetes Ingress. I can't find any resource which shows how to access api#internal from an Ingress. Is it even possible?

It is not possible to reference api#internal from an Ingress.
There is a workaround I think, which could be:
expose the api as insecure, it exposes the dashboard by default on an entrypoint called traefik on port 8080.
update the entrypoint manually in the static conf: entrypoints.traefik.address=<what-you-want>
create a service pointing to the traefik entrypoint (port 8080 by default).
create an ingress pointing to the service

Related

Traefik TCP service + routing

I'm having a hard time routing TCP traffic to a Pod with Traefik.
This pod I'm trying to proxy is named "realtime" and namespaced under "default"
According to the doc provided by traefik, I have created the following
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRouteTCP
metadata:
name: realtime-tcp-route
namespace: default
spec:
routes:
- match: HostSNI(`subdomain.hostname.com`)
services:
- name: realtime
port: 3002
According to the traefik dashboard, something is wrong: the service "default-realtime-tcp-ingress-542127811efa012038fd#kubernetescrd" does not exist, what am I doing wrong ?
Thanks

Correct way to expose ingress service using baremetal Kubernetes Cluster

I have the following topology in my kubernetes cluster:
So, I have 2 Nodes: 1 Master and 1 Worker Node.
Now I created an application with my deployment.yml and my service.yml, using nodePort configuration, see:
apiVersion: v1
kind: Service
metadata:
name: administrativo-service
spec:
type: NodePort
selector:
app: administrativo
ports:
- protocol: TCP
port: 80
targetPort: 8080
And this is my service:
Now I need to access this API using my DNS, something like: myapi.localdns, so I followed this steps to install Ingress Controller based on nginx:
https://kubernetes.github.io/ingress-nginx/deploy/#quick-start
https://kubernetes.github.io/ingress-nginx/deploy/#bare-metal-clusters
After 1 hour this is POD status in ingress-nginx namespace:
And finally, this is my Ingress yml:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: administrativo-ingress
annotations:
kubernetes.io/ingress.class: nginx
spec:
rules:
- host: myapi.localdns
http:
paths:
- pathType: Prefix
path: /
backend:
service:
name: administrativo-service
port:
number: 80
Well, my idea is to create an entry in my company to DNS to point to this DNS myapi.localdns:
but to do it I need the Ingress Address, that don't show in my ingress resource, see:
I solved the problem, using this steps:
First create in my company DNS the CNAMEs pointing to my kubernetes workernode IP.
Reinstall ingress-nginx controller using bare-metal configuration: kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.0.5/deploy/static/provider/baremetal/deploy.yaml.
Change the deploy.yaml to use NodePort before use kubectl apply
Use externalIPS to expose my service in port 80.

why treafik https config not work in kubernetes cluster

I am trying to configure https with traefik(v2.1.6) in kubernetes cluster(v1.15.2) by following this documentation.
My traefik deployment YAML looks like this:
And this is my IngressRoute config:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: traefik-dashboard-route
namespace: kube-system
spec:
entryPoints:
- websecure
tls:
certresolver: ali
routes:
- match: Host(`traefik.example.com`)
kind: Rule
services:
- name: traefik
port: 8080
When I access the website, it gives me following message: not secure.
What should I do to make it work?
Since this certificate is from acme staging its root ca not present in browsers. You need to add it to your systems trust store.

Expose opensource Helm charts through Istio Gateway/VirtualService

I want to expose some Helm Charts through Istio ingress.
For example, today I can expose Kubernetes Dashboard via Ingress type (with NginX Ingress):
helm install stable/kubernetes-dashboard --set ingress.enabled=true
However, for Istio would I have to fork the Kubernetes Dashboard Helm chart to add the required Gateway and VirtualService yaml?
Or is there a better way to patch opensource charts to work with Istio ingress?
You could create your own chart that includes the stable/kubernetes-dashboard as dependency in the requirements.yaml. Then you effectively have a wrapper chart that includes the dashboard and you can include the Istio ingress configuration at the wrapper level.
Actually you can do this without wrapping. In my case I had to expose Keycloak as VirtualService. Also keycloak was in other namespace.
I wrote Gateway
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: keycloak-gateway
namespace: keycloak
spec:
selector:
istio: ingressgateway # use Istio default gateway implementation
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "*"
I wrote VirtualService
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: demo-keycloak-http
namespace: keycloak
spec:
gateways:
- keycloak-gateway
hosts:
- '*'
http:
- match:
- uri:
prefix: /auth
route:
- destination:
host: demo-keycloak-http.keycloak.svc.cluster.local
port:
number: 80
Notice that I am routing the service name.
As you can see, it is possible to expose the helm chart from other namespace, in addition. In your case, maybe you will not need to have to write Gateway
You just need find the name of service and write for it VirtualService.

Route traffic to a service in a different namespace with Traefik and Kubernetes

Using Traefik as an ingress controller (on a kube cluster in GCP).
Is it possible to create an ingress rule that uses a backend service from a different namespace?
We have a namespace for each of our "major" versions of code.
1-service.com -> 1-service.com ingress in the 1-service ns -> 1-service svc in the same ns
2-service.com -> 2-service.com ingress in the 2-service ns... and so on
I also would like another ingress rule in the "unversioned" namespace that will route traffic to one of the major releases.
service.com -> service.com ingress in the "service" ns -> X-service in the X-service namespace
I would like to keep major versions separate in k8s using versioned host names (1-service.com etc), but still have a "latest" that points to the latest of the releases.
I believe voyager can do cross namespace ingress -> svc. can Traefik do the same??
You can use a workaround like this:
Create a Service with type ExternalName in your namespace when you want to create an ingress:
apiVersion: v1
kind: Service
metadata:
name: service-1
namespace: unversioned
spec:
type: ExternalName
externalName: service-1.service-1-ns.svc.cluster.local
ports:
- name: http
port: 8080
protocol: TCP
Create an ingress that point to this service:
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: ingress-to-other-ns
namespace: service-1-ns
spec:
rules:
- host: latest.example.com
http:
paths:
- backend:
serviceName: service-1
servicePort: 8080
path: /
Just tested with the following example on EKS. Traefik is deployed in default namespace. This is the config used for the k8s service:
---
apiVersion: v1
kind: Service
metadata:
name: 1-service
namespace: 1-service
labels:
app: 1-service
spec:
selector:
app: 1-service
ports:
- name: http
port: 80
targetPort: 80
And this is the config used for Traefik service that will send the request to different namespace:
services:
1-service:
loadBalancer:
servers:
- url: http://1-service.1-service.svc.cluster.local:80
# - url: http://1-service.1-service:80 # This should work perfectly as well, didn't test it explicitly
As you probably already get that, you can reference to services from different namespace by using SERVICE.NAMESPACE notation, instead of the SERVICE, which will automatically assume that you are referencing a service from the current namespace.