Custom resources (CRDs)
This page describes the CRDs (Custom Resource Definitions) of Traefik Hub.
Custom Resource Definitions¶
See the detailed reference guide, below, to learn more about CRD configurations related to API management.
To apply/install the up-to-date Traefik Hub CRDs in your cluster, please use the following command:
kubectl apply -f "https://hub.traefik.io/install/crd"
API¶
This CRD binds and configures an API specification to a service that implements it.
Field | Description | Required |
---|---|---|
metadata.name |
Unique name of an API. We recommend using kebab-case, for example, my-api. |
Yes |
metadata.labels |
Labels and Selectors are used by APIAccess and APICollection to select APIs respectively. | No |
spec.pathPrefix |
The path prefix of the API, for example /customers. The path prefix will append the URL of the API Gateway. |
Yes |
spec.currentVersion |
Marks an API as "versioned" and specifies the default version of the API in the API Portal. If spec.currentVersion is used, the Service must be defined in the APIversion CRD. |
No |
service.name |
Name for the Service, we recommend using kebab-case, for example, my-app. | Yes |
service.port.number |
The Service port where the API is reachable. | Yes |
service.openApiSpec.url |
URL, pointing to a valid OpenAPI file. The file can be external (hosted anywhere). The Portal should be able to connect without any kind of authentication. |
No |
service.openApiSpec.path |
YAML and JSON are supported file formats for OpenAPI files. |
No |
service.openApiSpec.port.number |
In most cases, the same as service.port.number . Required by internal path setting. |
No |
cors.allowCredentials |
The header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials ) is include . Docs on MDN. |
No |
cors.allowOriginList |
The header indicates whether the response can be shared with requesting code from the given origin . Docs on MDN. |
No |
cors.allowOriginListRegex |
Indicates whether a resource can be shared by returning different values. It allows all origins that contain any match of a regular expression in the Access-Control-Allow-Origin list. Docs on MDN. |
No |
cors.allowHeaders |
Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request. Docs on MDN. |
No |
cors.ExposeHeaders |
Indicates which headers are safe to expose to the API of a CORS API specification. Docs on MDN. |
No |
cors.allowMethods |
HTTP defines a set of request methods to indicate the action to be performed for a given resource. Docs on MDN. |
No |
cors.MaxAge |
The header indicates how long the results of a preflight request (that is, the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers ) can be cached. Docs on MDN |
No |
The API resource will not work without service.openApiSpec.url
or service.openApiSpec.path
configured.
An API resource defining both, a service
and a currentVersion
is not valid.
If you version your APIs with the APIVersion CRD you only need to configure CORS there
See the examples below.
Example
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: petstore-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/petstore"
service:
name: petstore-app
port:
number: 3000
openApiSpec:
url: https://raw.githubusercontent.com/OAI/OpenAPI-Specification/main/examples/v3.0/petstore.yaml
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/customers"
service:
name: customer-app
port:
number: 3000
openApiSpec:
path: /openapi.yaml
port:
number: 3000
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/customers"
currentVersion: customers-v2
# The Service definition is part of the APIVersion CRD
---
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: customer-api
namespace: apps
labels:
area: customers
module: crm
spec:
pathPrefix: "/customers"
service:
openApiSpec:
path: /openapi.yaml
port:
number: 3000
name: customer-app
port:
number: 3000
cors:
allowCredentials: true
allowOriginList:
- "*"
allowHeaders:
- "Accept"
- "Accept-Language"
- "Content-Language"
- "Content-Type"
- "Authorization"
- "X-TraefikLabs-User"
allowMethods:
- "GET"
- "HEAD"
- "POST"
- "PUT"
- "CONNECT"
- "OPTIONS"
- "TRACE"
APIAccess¶
This resource binds which APIs are made available, with who can access them.
Use Labels and Selectors to select APIs and API collections.
It is possible to combine apiCollectionSelector
and apiSelector
.
apiSelector
and apiCollectionSelector
basics
This won't select any APIs.
spec:
// no apiSelector
This will select all APIs.
spec:
apiSelector: {}
This will select all APIs with a label key
equals to value.
spec:
apiSelector:
key: value
Field | Description | Required |
---|---|---|
groups |
Name of the user group(s) with permissions for the API(s). Requires apiSelector.matchLabels , apiSelector.matchExpressions or a combination of both to select APIs. |
Yes |
apis.name |
Select APIs based on names You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions . See Labels and Selectors. |
No |
apis.namespace |
Name of the Kubernetes Namespace used by the API(s) defined in apis.name . This is required for apis.name |
No |
apiSelector.matchLabels |
Select APIs based on label matching: Equality-Based Requirements. | No |
apiSelector.matchExpressions |
Select APIs based on advanced labels expressions: Set-Based Requirements. | No |
apiCollectionSelector.matchLabels |
Select API Collections based on label matching: Equality-Based Requirements. | No |
apiCollectionSelector.matchExpressions |
Select API Collections based on advanced labels expressions: Set-Based Requirements. | No |
Example
The examples show different configuration options from configuring access by group to using a combination from API names, matchLables and matchExpressions.
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
name: customer-support
spec:
groups:
- support
apiSelector:
matchLabels:
area: customers
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
name: customer-support
spec:
groups:
- support
apis:
- name: my-api-1
namespace: my-ns
- name: my-api-2
namespace: my-ns
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
name: customer-support
spec:
groups:
- support
apiSelector:
matchLabels:
area: customers
---
# Example of combing selecting APIs by `name`, `matchLabels` and `matchExpressions`.
# The selected APIs will be "my-api-1", "my-api-2" and all APIs with the area Label sets to "product" and audience either "dev" or "admin".
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
name: admin-access
spec:
groups:
- support
apis:
- name: my-api-1
namespace: my-ns
- name: my-api-2
namespace: my-ns
apiSelector:
matchLabels:
area: product
matchExpressions:
- operator: in
key: audience
value: ["dev", "admin"]
APIGateway¶
This resource configures an end point where APIs provided by an API Access object should be available.
Traefik Hub uses APIGateway and APIPortal resources to configure APIs.
In Traefik Hub, an API Gateway is the main entry point to all your APIs. This is where you define the public domains for your APIs and which APIs and API Collections you want to expose via an API Access.
To publish an API, the API must be present in an API Access policy and have an API Gateway endpoint.
Field | Description | Required |
---|---|---|
apiAccesses |
List of allowed API Accesses for the Gateway. | Yes |
customDomains |
Configure a custom domain name for the API Gateway, for example api.example.com. This is an optional setting, if not configured, Traefik Hub will generate a random domain under the traefikhub.io namespace. |
No |
Example
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIGateway
metadata:
name: my-gateway
labels:
area: crm
spec:
apiAccesses:
- customer-admin
- crm-collections
- crm-apis
- custom-pick
customDomains:
- api.example.com
- www.api.example.com
Production deployments
We highly recommend the use of custom domains for production deployments!
Domains generated by Traefik Hub will change with every redeployment, resulting in a new domain.
APIPortal¶
This resource configures an API portal in Traefik Hub.
Traefik Hub uses APIPortal and APIGateway resource to configure APIs.
In Traefik Hub, the API Portal is the landing page for consumers of APIs or API Collections. In the Portal, the consumer can view a representation of the OpenAPI specification and effortlessly interact and try out every API operation.
Field | Description | Required |
---|---|---|
title |
A title for the Portal, for example, your company name. | No |
description |
A short description of the Portal. It will be displayed next to the title. |
No |
apiGateway |
Name of the APIGateway used by the Portal. | Yes |
customDomains |
Configure custom domain name for the API Portal, for example dev.example.com. This is an optional setting, if not configured, Traefik Hub will generate a random domain under the traefikhub.io namespace. |
No |
ui.service |
Configuration for custom API Portals. If not configured, the default Portal UI is used. If you use a custom Portal service, name and port are required. namespace is an optional setting. |
No |
Example
---
apiVersion: hub.traefik.io/v1alpha1
kind: APIPortal
metadata:
name: my-api-portal
spec:
title: "The Portal"
description: "The Ultimate Portal NG Digital Deluxe Edition"
apiGateway: my-gateway
customDomains:
- "dev.example.com"
ui:
logoUrl: https://traefik.io/favicon.png
service:
name: hub-apiportal-ui
namespace: default
port: 8080
Production deployments
We highly recommend the use of custom domains for production deployments!
Domains generated by Traefik Hub will change with every redeployment, resulting in a new domain.
APICollection¶
This resource configures API Collections.
Collections are used to logically group APIs based on their labels.
Collections are API groupings
- An API can be part of multiple collections
- Labels and Selectors are used for grouping
Field | Description | Required |
---|---|---|
pathPrefix |
PathPrefix used by the collection, for example /crm. The PathPrefix will append the URL of the API Gateway. This would make the API collection accessible under api.example.com/crm. Only absolute paths are accepted for this setting. |
No |
apis.name |
Select APIs based on names You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions . See Labels and Selectors. |
No |
apis.namespace |
Name of the Kubernetes Namespace used by the API(s) defined in apis.name . This is required for apis.name . |
No |
apiSelector.matchLabels |
Select APIs based on label matching: Equality-Based Requirements. | No |
apiSelector.matchExpressions |
Select APIs based on advanced labels expressions: Set-Based Requirements. | No |
Example
apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
name: crm-all
labels:
module: crm
spec:
apis:
- name: my-api-1
namespace: my-ns
- name: my-api-2
namespace: my-ns
apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
name: crm-all
labels:
module: crm
spec:
pathPrefix: "/crm"
apiSelector:
matchLabels:
module: crm
apiVersion: hub.traefik.io/v1alpha1
kind: APICollection
metadata:
name: crm-all
labels:
module: crm
spec:
pathPrefix: "/crm"
apiSelector:
matchExpressions:
- key: area
operator: In
values:
- flights
- support
APIRateLimit¶
This resource configures rate limiting.
Read our detailed docs about rate limiting to learn more about how it works.
Field | Description | Required |
---|---|---|
limit |
Number of allowed requests per defined time period . |
Yes |
period |
Time period can be seconds, minutes or hours (s/m/h). Default value is one second. | No |
anyGroups |
Using anyGroups will rate limit all groups which are defined with apiSelector.matchLabels or apiSelector.matchExpressions . See the APIAccess reference for more information. |
No |
groups |
Name of the group(s) which will be rate limited. See the user management reference for more information. |
No |
apis.name |
Select APIs based on names You can combine it with apiSelector.matchLabels and apiSelector.matchExpressions . See Labels and Selectors. |
No |
apis.namespace |
Name of the Kubernetes Namespace used by the API(s) defined in apis.name . This is required for apis.name |
No |
apiSelector.matchLabels |
Select APIs based on label matching: Equality-Based Requirements. | No |
apiSelector.matchExpressions |
Select APIs based on advanced labels expressions: Set-Based Requirements. | No |
You must configure either anyGroups
or groups
for rate limiting.
Without setting one of them, rate limiting will not be applied.
See the examples below.
Examples
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
name: my-rate-limit
spec:
# Rate limit configuration, this config allows 100 requests in one minute.
limit: 100 # 100 requests
period: 1m # One minute
groups:
- support
apis:
- name: my-api-1
namespace: my-ns
- name: my-api-2
namespace: my-ns
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
name: my-rate-limit
spec:
# Rate limit configuration, this config allows 100 requests in one minute.
limit: 100 # 100 requests
period: 1m # One minute
groups:
- support
apiSelector:
matchLabels:
module: crm
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
name: my-rate-limit
spec:
# Rate limit configuration, this config allows 100 requests in one minute.
limit: 100 # 100 requests
period: 1m # One minute
groups:
- support
apiSelector:
matchExpressions:
- key: area
operator: In
values:
- flights
- tickets
- employee
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
name: my-rate-limit
spec:
# Rate limit configuration, this config allows 100 requests in one minute.
limit: 100 # 100 requests
period: 1m # One minute
groups:
- support
- travel-agents
apiSelector:
matchExpressions:
- key: area
operator: In
values:
- flights
- tickets
- employee
apiVersion: hub.traefik.io/v1alpha1
kind: APIRateLimit
metadata:
name: my-rate-limit
spec:
# Rate limit configuration, this config allows 100 requests in one minute.
limit: 100 # 100 requests
period: 1m # One minute
anyGroups: true
apiSelector:
matchExpressions:
- key: area
operator: In
values:
- flights
- tickets
- employee
APIVersion¶
This resource configures API versioning.
Field | Description | Required |
---|---|---|
apiName |
Name of the API, see API CRD reference for more information. | Yes |
release |
Release number following SemVer (Semantic Versioning). release isn't tied to the defined version matcher(s) of your API. |
Yes |
title |
Human friendly name of the release which will be displayed in the UI overview of an API. | No |
stripPathPrefix |
Remove prefixes from the URL path. For example, if the pathPrefix is set to /v1.0, /v1.0 will be removed from the path when passing the request to the service. |
No |
routes[n].pathPrefix |
The URL prefix identifying the API version. It is possible to use multiple pathPrefix and to use it together with headers and queryParams . Check the advanced examples below. |
No |
routes[n].headers |
Set the version number using custom headers in requests and responses. It is possible to use multiple headers and to use it together with pathPrefix and queryParams . Check the advanced examples below for more info. |
No |
routes[n].queryParams |
Use query parameter for versioning. It is possible to use multiple queryParams , for example, version:v2.0.0 and lang:fr. queryParams can be used together with pathPrefix and headers . See the examples below. |
No |
cors.allowCredentials |
The header tells browsers whether to expose the response to the frontend JavaScript code when the request's credentials mode (Request.credentials ) is include . Docs on MDN. |
No |
cors.allowOriginList |
The header indicates whether the response can be shared with requesting code from the given origin . Docs on MDN. |
No |
cors.allowOriginListRegex |
Indicates whether a resource can be shared by returning different values. It allows all origins that contain any match of a regular expression in the Access-Control-Allow-Origin list. Docs on MDN. |
No |
cors.allowHeaders |
Used in response to a preflight request which includes the Access-Control-Request-Headers to indicate which HTTP headers can be used during the actual request. Docs on MDN. |
No |
cors.ExposeHeaders |
Indicates which headers are safe to expose to the API of a CORS API specification. Docs on MDN. |
No |
cors.allowMethods |
HTTP defines a set of request methods to indicate the action to be performed for a given resource. Docs on MDN. |
No |
cors.MaxAge |
The header indicates how long the results of a preflight request (that is, the information contained in the Access-Control-Allow-Methods and Access-Control-Allow-Headers headers ) can be cached. Docs on MDN |
No |
If you don't configure routes[n].pathPrefix
, routes[n].headers
or routes[n].queryParams
for versioning,
APIs will still be reachable under the prefix configured in the API CRD but treated as non versioned.
Examples
See the following versioning examples:
---
# Example of versioning an API using `pathPrefix` for URI path.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: flight-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available on one route using URI path for versioning.
# Example: curl https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using `headers`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: flight-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available on one route using a custom header for versioning.
# Example: curl -H "Version: v2.0.0" https://api.example.com/flights
- headers:
Version: "v2.0.0"
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using a media type headers.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: flight-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available on one route using a `media type` header for versioning.
# Example: curl -H "Content: application/vnd.example.v2.0.0+json" https://api.example.com/flights
- headers:
Content: "application/vnd.example.v1+json"
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using `queryParams` for query parameter versioning.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: flight-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available at one route, using a version `query parameter`.
# Example: curl https://api.example.com/flights?version=2.0.0
- queryParams:
version: "v2.0.0"
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using two `queryParams`, version and language.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: flight-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available at one route, both `queryParams` constraints must match.
# Example: curl https://api.example.com/flights?version=2.0.0&lang=fr
- queryParams:
version: "v2.0.0"
lang: "fr"
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using `pathPrefix` for URI path and CORS.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: my-versioned-flights-api
# SemVer of the release
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available on one route using URI path for versioning.
# Example: curl https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
cors:
allowCredentials: true
allowOriginList:
- "*"
allowHeaders:
- "Accept"
- "Accept-Language"
- "Content-Language"
- "Content-Type"
- "Authorization"
- "X-TraefikLabs-User"
allowMethods:
- "GET"
- "HEAD"
- "POST"
- "PUT"
Combining routes (Advanced)
It is possible to define multiple routes for API versions and Services.
- An API can have a multiple version routes
- An API can use multiple constraints on a route
- It is possible to use different route types per API version
Be aware of the subtile configuration differences.
If you want to make an API available on different routes, for example versioning an API using pathPrefix
OR header
define one block per route.
routes:
# The API will available at two routes.
# 1. At the URI version path https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
# 2. At the URI https://api.example.com/flights using a `header`.
- headers:
Content: "application/vnd.example.v2+json"
If you want to use a constraint that must match, for example, a pathPrefix
AND a header
, define the array item as a map.
routes:
# The API will be available at one route and both constraints must match.
# Example: curl -H "Content: application/vnd.example.v2+json" https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
headers:
Content: "application/vnd.example.v2+json"
See the following examples:
---
# Example of versioning an API using `pathPrefix` and `header`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: my-versioned-flights-api
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will available at two routes.
# 1. At the URI version path https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
# 2. At the URI https://api.example.com/flights using a `header`.
- headers:
Content: "application/vnd.example.v2+json"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
---
# Example of versioning an API using a constraint of `pathPrefix` and `header`.
apiVersion: hub.traefik.io/v1alpha1
kind: APIVersion
metadata:
name: my-flights-api-v2
namespace: apps
spec:
# The API this version is referencing (assumed to be in the same namespace).
apiName: my-versioned-flights-api
release: v2.0.0
title: "An awesome title for this release, like a cheese name"
routes:
# The API will be available at one route and both constraints must match.
# Example: curl -H "Content: application/vnd.example.v2+json" https://api.example.com/flights/v2.0.0
- pathPrefix: "/v2.0.0"
headers:
Content: "application/vnd.example.v2+json"
# The path prefix of the route will be removed and not forwarded with the request.
stripPathPrefix: true
service:
name: flights-svc-v2
port:
number: 8080
openApiSpec:
path: /api/v2/openapi.json
port:
number: 8080
What's next¶
- Follow the tutorial about publishing APIs from CRDs