We are using Traefik v2 running in kubernetes in a shared namespace (called shared), with multiple namespaces for different projects/services. We are utilising the IngressRoute CRD along with middlewares.
We need to mirror (duplicate) all incoming traffic to a specific URL (blah.example.com/newservice) and forward it to 2 backend services in 2 different namespaces. Because they are separated between 2 namespaces, they are running as the same name, with the same port.
I've looked at the following link, but don't seem to understand it:
https://doc.traefik.io/traefik/v2.3/routing/providers/kubernetes-crd/#mirroring
This is my config:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: shared-ingressroute
namespace: shared
spec:
entryPoints: []
routes:
- kind: Rule
match: Host(`blah.example.com`) && PathPrefix(`/newservice/`)
middlewares:
- name: shared-middleware-testing-middleware
namespace: shared
priority: 0
services:
- kind: Service
name: customer-mirror
namespace: namespace1
port: TraefikService
---
apiVersion: traefik.containo.us/v1alpha1
kind: Middleware
metadata:
name: shared-middleware-testing-middleware
namespace: shared
spec:
stripPrefix:
prefixes:
- /newservice/
---
apiVersion: traefik.containo.us/v1alpha1
kind: TraefikService
metadata:
name: customer-mirror
namespace: namespace1
spec:
mirroring:
name: newservice
port: 8011
namespace: namespace1
mirrors:
- name: newservice
port: 8011
percent: 100
namespace: namespace2
What am I doing wrong?
based on docs, for Your case kind should be TraefikService
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
annotations:
kubernetes.io/ingress.class: traefik
name: shared-ingressroute
namespace: shared
spec:
entryPoints: []
routes:
- kind: Rule
match: Host(`blah.example.com`) && PathPrefix(`/newservice/`)
middlewares:
- name: shared-middleware-testing-middleware
namespace: shared
services:
- kind: TraefikService
name: customer-mirror
namespace: namespace1
Related
I'm using Traefik 2.7.0 on an AKS Kubernetes Cluster 1.22.6.
Currently, everything routes to the same service:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`)
kind: Rule
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-my-domain-com-cert
I'm currently in the process of externalizing an API resource from this service to a dedicated new service ("/users") because there will be other services in the future that will need the same functionality.
What I'm trying (and failing) to do, is to route calls to "/users" to the new service:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`) && Path(`/users`)
kind: Rule
services:
- name: users-api
namespace: namespace2
port: 80
- match: Host(`api.my-domain.com`)
kind: Rule
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-baywa-lusy-com-cert
I tried Path(..) and PathPrefix(..). No success. Everything is still routed to the old service. The new service has slightly different output. So I can tell with certainty that it's still routed to the old service.
Adding the priority manually didn't help either:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: api
namespace: namespace1
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.my-domain.com`) && Path(`/users`)
kind: Rule
priority: 2000
services:
- name: users-api
namespace: namespace2
port: 80
- match: Host(`api.my-domain.com`)
kind: Rule
priority: 1000
services:
- name: api
namespace: namespace1
port: 80
tls:
secretName: api-baywa-lusy-com-cert
Am I Missing something here? Any help is appreciated!
Thanks,
best regards,
Pascal
You can only expose services in the same namespace as your IngressRoute resource. If you watch the logs of your Traefik pod when you deploy your IngressRoute, you should see something like:
time="2023-01-26T13:57:17Z" level=error msg="service namespace2/users-api not in the parent resource namespace namespace1" providerName=kubernetescrd ingress=namespace1 namespace=namespace1
To do what you want, you need to create two separate IngressRoute resources, one in namespace1 and one in namespace2.
In namespace1:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: old-api
name: old-api
namespace: namespace1
spec:
entryPoints:
- web
routes:
- kind: Rule
priority: 1000
match: Host(`api.my-domain.com`)
services:
- name: old-api
port: 80
In namespace2:
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
labels:
app: new-api
name: new-api
namespace: namespace2
spec:
entryPoints:
- web
routes:
- kind: Rule
priority: 2000
match: Host(`api.my-domain.com`) && PathPrefix(`/users`)
services:
- name: new-api
port: 80
You can find all the files I used to test this configuration here.
I don't know if the explicit priorities are necessary or not; it worked for me without them but maybe I was just lucky so I left them there. I would generally assume that a "more specific route" takes precedence over a "less specific route", but I don't know if that's actually true.
I am testing istio 1.10.3 to add headers with minikube but I am not able to do so.
Istio is installed in the istio-system namespaces.
The namespace where the deployment is deployed is labeled with istio-injection=enabled.
In the config_dump I can see the LUA code only when the context is set to ANY. When I set it to SIDECAR_OUTBOUND the code is not listed:
"name": "envoy.lua",
"typed_config": {
"#type": "type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua",
"inline_code": "function envoy_on_request(request_handle)\n request_handle:headers():add(\"request-body-size\", request_handle:body():length())\nend\n\nfunction envoy_on_response(response_handle)\n response_handle:headers():add(\"response-body-size\", response_handle:body():length())\nend\n"
}
Someone can give me some tips?
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: headers-envoy-filter
namespace: nginx-echo-headers
spec:
configPatches:
- applyTo: HTTP_FILTER
match:
context: SIDECAR_OUTBOUND
listener:
filterChain:
filter:
name: envoy.filters.network.http_connection_manager
subFilter:
name: envoy.filters.http.router
patch:
operation: INSERT_BEFORE
value:
name: envoy.lua
typed_config:
'#type': type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
function envoy_on_request(request_handle)
request_handle:headers():add("request-body-size", request_handle:body():length())
end
function envoy_on_response(response_handle)
response_handle:headers():add("response-body-size", response_handle:body():length())
end
workloadSelector:
labels:
app: nginx-echo-headers
version: v1
Below is my deployment and Istio configs:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-echo-headers-v1
namespace: nginx-echo-headers
labels:
version: v1
spec:
selector:
matchLabels:
app: nginx-echo-headers
version: v1
replicas: 2
template:
metadata:
labels:
app: nginx-echo-headers
version: v1
spec:
containers:
- name: nginx-echo-headers
image: brndnmtthws/nginx-echo-headers:latest
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: nginx-echo-headers-svc
namespace: nginx-echo-headers
labels:
version: v1
service: nginx-echo-headers-svc
spec:
type: ClusterIP
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: nginx-echo-headers
version: v1
---
# ISTIO GATEWAY
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: nginx-echo-headers-gateway
namespace: istio-system
spec:
selector:
app: istio-ingressgateway
servers:
- port:
number: 80
name: http
protocol: HTTP
hosts:
- "api.decchi.com.ar"
# ISTIO VIRTUAL SERVICE
---
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: nginx-echo-headers-virtual-service
namespace: nginx-echo-headers
spec:
hosts:
- 'api.decchi.com.ar'
gateways:
- istio-system/nginx-echo-headers-gateway
http:
- route:
- destination:
# k8s service name
host: nginx-echo-headers-svc
port:
# Services port
number: 80
# workload selector
subset: v1
## ISTIO DESTINATION RULE
---
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: nginx-echo-headers-dest
namespace: nginx-echo-headers
spec:
host: nginx-echo-headers-svc
subsets:
- name: "v1"
labels:
app: nginx-echo-headers
version: v1
It is only working when I configure the context in GATEWAY. The envoyFilter is running in the istio-system namespace and the workloadSelector is configured like this:
workloadSelector:
labels:
istio: ingressgateway
But my idea is to configure it in SIDECAR_OUTBOUND.
it is only working when I configure the context in GATEWAY, the envoyFilter is running in the istio-system namespace
That's correct! You should apply your EnvoyFilter in the config root namespace istio-system- in your case.
And the most important part, just omit context field, when matching your configPatches, so that this applies to both sidecars and gateways. You can see the examples of usage in this Istio Doc.
Here is an example I managed to come up with
apiVersion: networking.istio.io/v1alpha3
kind: EnvoyFilter
metadata:
name: add-x-cluster-client-ip-header
namespace: istio-system
spec:
configPatches:
- applyTo: ROUTE_CONFIGURATION
match:
context: SIDECAR_INBOUND
patch:
operation: MERGE
value:
request_headers_to_add:
- header:
key: 'x-cluster-client-ip'
value: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
append: false
# the following is used to debug
response_headers_to_add:
- header:
key: 'x-cluster-client-ip'
value: '%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT%'
append: false
https://gist.github.com/qudongfang/75cf0230c0b2291006f72cd23d45f297
Following this tutorial:
https://medium.com/kubernetes-tutorials/deploying-traefik-as-ingress-controller-for-your-kubernetes-cluster-b03a0672ae0c
I am able to access the site by visiting www.domain.com:nodePort
Is it possible to omit nodePort part? Could you provide example?
Is it possible to omit nodePort part?
Yes and No.
Not directly. Kubernetes always exposes external services even LoadBalancer type of services on a node port.
Yes. If you front it with a load balancer. Either your own that forwards port 80 and/or 443 to your NodePort or a LoadBalancer type of service which essentially sets up an external load balancer that forwards traffic to your NodePort.
Could you provide an example?
The NodePort service to expose your ingress is basically the same, you just need to setup your own external load balancer. (i.e AWS ELB/ALB/NLB, GCP load balancer, Azure load balancer, F5, etc, etc)
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
type: NodePort
The LoadBalancer type is just a change on the type of service:
kind: Service
apiVersion: v1
metadata:
name: traefik-ingress-service
namespace: kube-system
spec:
selector:
k8s-app: traefik-ingress-lb
ports:
- protocol: TCP
port: 80
name: web
- protocol: TCP
port: 8080
name: admin
type: LoadBalancer
In the case above, Kubernetes will automatically manage the load balancer in the provider.
Try deploying the below code. This is a simple whoami pod which can be deployed along traefik and can be accessed at http://localhost/whoami-app-api when deployed on the local machine. The dashboard is also available at http://localhost:8080/dashboard.
Deployment File:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.1
args:
- --accesslog=true
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.kubernetescrd
- --configfile=/config/traefik.toml
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
- name: websecure
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 443
name: websecure
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: whoami
labels:
app: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- name: web
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-whoami
namespace: default
spec:
entryPoints:
- web
- websecure
routes:
- match: PathPrefix(`/whoami-app-api`)
kind: Rule
services:
- name: whoami
port: 80
I am trying to setup traefik ingress route using the configuration that is provided at https://docs.traefik.io/routing/providers/kubernetes-crd/
I can see traefik is up & running, can also see the dashboard. But I dont see the whoami service on dashboard and cannot access it via url.
crd.yaml
# All resources definition must be declared
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
ingress.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: myingressroute
namespace: default
annotations:
kubernetes.io/ingress.class: traefik
spec:
entryPoints:
- web
routes:
- match: Host(`test`) && PathPrefix(`/bar`)
kind: Rule
services:
- name: whoami
port: 80
rbac.yaml
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
traefik.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.2
args:
- --log.level=DEBUG
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --providers.kubernetescrd
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
whoami.yaml
kind: Deployment
apiVersion: apps/v1
metadata:
name: whoami
namespace: default
labels:
app: containous
name: whoami
spec:
replicas: 1
selector:
matchLabels:
app: containous
task: whoami
template:
metadata:
labels:
app: containous
task: whoami
spec:
containers:
- name: containouswhoami
image: containous/whoami
ports:
- containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
namespace: default
spec:
ports:
- name: http
port: 80
selector:
app: containous
task: whoami
UPDATE
After resources from link
E0708 21:34:10.222538 1 reflector.go:153] pkg/mod/k8s.io/client-go#v0.17.3/tools/cache/reflector.go:105: Failed to list *v1alpha1.IngressRouteUDP: ingressrouteudps.traefik.containo.us is forbidden: User "system:serviceaccount:default:traefik-ingress-controller" cannot list resource "ingressrouteudps" in API group "traefik.containo.us" at the cluster scope
E0708 21:34:10.223416 1 reflector.go:153] pkg/mod/k8s.io/client-go#v0.17.3/tools/cache/reflector.go:105: Failed to list *v1alpha1.TLSStore: tlsstores.traefik.containo.us is forbidden: User "system:serviceaccount:default:traefik-ingress-controller" cannot list resource "tlsstores" in API group "traefik.containo.us" at the cluster scope
E0708 21:34:11.225368 1 reflector.go:153] pkg/mod/k8s.io/client-go#v0.17.3/tools/cache/reflector.go:105: Failed to list *v1alpha1.TLSStore: tlsstores.traefik.containo.us is forbidden: User "system:serviceaccount:default:traefik-ingress-controller" cannot list resource "tlsstores" in API group "traefik.containo.us" at the cluster scope
Its working for me with with treafik 2.1 using following set of resources.
link to example
Can you try these once and let me know if this helps.
I deployed the below code and the whoami is now accessible without any issues. Things I changed are, updated the CRD, RBAC with the latest available in Traefik and changed the apiVersion for the deployment to "apps/v1". Simply copy the below code all together and deploy on kubernetes. Once it is up access http://localhost/whoami-app-api.
Deployment File:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutes.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRoute
plural: ingressroutes
singular: ingressroute
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: middlewares.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: Middleware
plural: middlewares
singular: middleware
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressroutetcps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteTCP
plural: ingressroutetcps
singular: ingressroutetcp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: ingressrouteudps.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: IngressRouteUDP
plural: ingressrouteudps
singular: ingressrouteudp
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsoptions.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSOption
plural: tlsoptions
singular: tlsoption
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: tlsstores.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TLSStore
plural: tlsstores
singular: tlsstore
scope: Namespaced
---
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: traefikservices.traefik.containo.us
spec:
group: traefik.containo.us
version: v1alpha1
names:
kind: TraefikService
plural: traefikservices
singular: traefikservice
scope: Namespaced
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
rules:
- apiGroups:
- ""
resources:
- services
- endpoints
- secrets
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses
verbs:
- get
- list
- watch
- apiGroups:
- extensions
resources:
- ingresses/status
verbs:
- update
- apiGroups:
- traefik.containo.us
resources:
- middlewares
- ingressroutes
- traefikservices
- ingressroutetcps
- ingressrouteudps
- tlsoptions
- tlsstores
verbs:
- get
- list
- watch
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: traefik-ingress-controller
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: traefik-ingress-controller
subjects:
- kind: ServiceAccount
name: traefik-ingress-controller
namespace: default
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: traefik-ingress-controller
---
kind: Deployment
apiVersion: apps/v1
metadata:
name: traefik
labels:
app: traefik
spec:
replicas: 1
selector:
matchLabels:
app: traefik
template:
metadata:
labels:
app: traefik
spec:
serviceAccountName: traefik-ingress-controller
containers:
- name: traefik
image: traefik:v2.1
args:
- --accesslog=true
- --api
- --api.insecure
- --entrypoints.web.address=:80
- --entrypoints.websecure.address=:443
- --providers.kubernetescrd
- --configfile=/config/traefik.toml
ports:
- name: web
containerPort: 80
- name: admin
containerPort: 8080
- name: websecure
containerPort: 443
---
apiVersion: v1
kind: Service
metadata:
name: traefik
spec:
type: LoadBalancer
selector:
app: traefik
ports:
- protocol: TCP
port: 80
name: web
targetPort: 80
- protocol: TCP
port: 443
name: websecure
targetPort: 80
- protocol: TCP
port: 8080
name: admin
targetPort: 8080
---
kind: Deployment
apiVersion: apps/v1
metadata:
namespace: default
name: whoami
labels:
app: whoami
spec:
replicas: 1
selector:
matchLabels:
app: whoami
template:
metadata:
labels:
app: whoami
spec:
containers:
- name: whoami
image: containous/whoami
ports:
- name: web
containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
name: whoami
spec:
ports:
- protocol: TCP
name: web
port: 80
selector:
app: whoami
---
apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
name: whoami-whoami
namespace: default
spec:
entryPoints:
- web
- websecure
routes:
- match: PathPrefix(`/whoami-app-api`)
kind: Rule
services:
- name: whoami
port: 80
I am trying this example and got very stupid issue as mentioned.
After hours to try, I figure out that the issue is at "match" rule.
-match: PathPrefix(`/whoami-app-api`)
-match: Host(`whoami.localhost`) && PathPrefix(`/notls`)
Match without host will work by http:localhost/<prefix>.
Match with a host that don't like real URI like ".net" ".com".. will work
Some host like real URI like abc.com, scx.net, the browser will try to reach it by DNS instead of local host "0.0.0.0", so it cant not reach our Traefik.
Otherwise, Host with single word won't work also. I don't know why. I think in URL, there are at least 2 words splitting by dot
I am trying to enable the rate-limit for my istio enabled service. But it doesn't work. How do I debug if my configuration is correct?
apiVersion: config.istio.io/v1alpha2
kind: memquota
metadata:
name: handler
namespace: istio-system
spec:
quotas:
- name: requestcount.quota.istio-system
maxAmount: 5
validDuration: 1s
overrides:
- dimensions:
engine: myEngineValue
maxAmount: 5
validDuration: 1s
---
apiVersion: config.istio.io/v1alpha2
kind: quota
metadata:
name: requestcount
namespace: istio-system
spec:
dimensions:
source: request.headers["x-forwarded-for"] | "unknown"
destination: destination.labels["app"] | destination.service | "unknown"
destinationVersion: destination.labels["version"] | "unknown"
engine: destination.labels["engine"] | "unknown"
---
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpec
metadata:
name: request-count
namespace: istio-system
spec:
rules:
- quotas:
- charge: 1
quota: requestcount
---
apiVersion: config.istio.io/v1alpha2
kind: QuotaSpecBinding
metadata:
name: request-count
namespace: istio-system
spec:
quotaSpecs:
- name: request-count
namespace: istio-system
services:
# - service: '*' ; I tried with this as well
- name: my-service
namespace: default
---
apiVersion: config.istio.io/v1alpha2
kind: rule
metadata:
name: quota
namespace: istio-system
spec:
actions:
- handler: handler.memquota
instances:
- requestcount.quota
I tried with - service: '*' as well in the QuotaSpecBinding; but no luck.
How, do I confirm if my configuration was correct? the my-service is the kubernetes service for my deployment. (Does this have to be a VirtualService of istio for rate limits to work? Edit: Yes, it has to!)
I followed this doc except the VirtualService part.
I have a feeling somewhere in the namespaces I am doing a mistake.
You have to define the virtual service for the service my-service:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
name: myservice
spec:
hosts:
- myservice
http:
- route:
- destination:
host: myservice
This way, you allow Istio to know which service are you host you are referring to.
In terms of debugging, I know that there is a project named Kiali that aims to leverage observability in Istio environments. I know that they have validations for some Istio and Kubernetes objects: Istio configuration browse.