Skip to main content

External APIs

Traefik Hub API Management allows you to manage and expose APIs not only within your Kubernetes cluster but also external services residing outside of it. This is particularly useful when you need to expose legacy systems or third-party APIs.

Enabling ExternalName Services in Traefik Hub

To allow Traefik Hub to interact with external services, you need to enable specific parameters in your deployment.

Update Traefik Deployment

First, you need to add the following arguments to your Traefik deployment configuration:

- --providers.kubernetescrd.allowExternalNameServices=true

These arguments enable Traefik Hub to:

  • allowexternalnameservices: Use ExternalName services, which point to external DNS names.

After including this, you can now upgrade your deployment with the updated values.yaml file:

helm upgrade traefik traefik/traefik -n traefik -f values.yaml
Note

You can also include - --providers.kubernetescrd.allowCrossNamespace=true in your Helm values to enable referencing services across different namespaces.

If this feature has been enabled in your deployment sucessfully, you should see the following when you inspect the Traefik pod:

"Traefik Deploymentg Logs"

Configuring External API Access

With Traefik Hub configured to allow external services, you can now set up the necessary Kubernetes resources.

Create an ExternalName Service

Define a Service of type ExternalName that maps to the external API DNS name.

Example

world-time-api.yaml
apiVersion: v1
kind: Service
metadata:
name: world-time-api
namespace: traefik
spec:
type: ExternalName
externalName: worldtimeapi.org
ports:
- port: 443
FieldDescription
typeIndicates that the service maps to a DNS name.
externalNameThe external API DNS name.
portsThe port on which the external service listens.

Apply the resource:

kubectl apply -f world-time-api.yaml

Define the API Resource

Create an API resource to represent the external API within Traefik Hub.

Example

time-api.yaml
apiVersion: hub.traefik.io/v1alpha1
kind: API
metadata:
name: time-api
namespace: traefik
spec:
openApiSpec:
url: https://worldtimeapi.org/api
FieldDescription
openApiSpec.urlThe URL to the API's OpenAPI specification.

Apply the resource:

kubectl apply -f time-api.yaml

Set Up API Access

Configure an APIAccess resource to define who can access the API.

Example

time-api-access.yaml
apiVersion: hub.traefik.io/v1alpha1
kind: APIAccess
metadata:
name: time-api
namespace: traefik
spec:
apis:
- name: time-api
everyone: true
FieldDescription
everyone : trueAllows every authenticated user to access the API.

Apply the resource:

kubectl apply -f time-api-access.yaml

Create an IngressRoute

Define an IngressRoute to route incoming traffic to the external service.

Example

time-api-ingressroute.yaml
apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: time-api
namespace: traefik
annotations:
hub.traefik.io/api: time-api
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.yourdomain.com`) && PathPrefix(`/time`)
kind: Rule
services:
- name: world-time-api
port: 443
FieldDescription
annotations.hub.traefik.io/apiAssociates the route with the API resource
matchDefines routing rules based on host and path.
services.nameReferences the ExternalName service

Apply the resource:

kubectl apply -f time-api-ingressroute.yaml

With the above example, you should be able to replicate a working set up with the External API service feature.

Notes
  • Ensure that your DNS records point to Traefik's ingress controller.
  • Verify that the external API you want to make use of is accessible from your Kubernetes cluster.
  • When using websecure, make sure TLS is properly configured.

Securing External APIs with mTLS

To enhance security when connecting to external APIs, you can configure mutual TLS (mTLS) between Traefik and the external service. This ensures that both parties authenticate each other before establishing a connection.

Before you can make use of mTLS with your external APIs, you need to do the following:

Create a Secret for Client CA Certificate

First, you need to create a Kubernetes Secret containing the CA certificate used to verify client certificates.

Example

kubectl create secret generic client-ca-cert \
--from-file=ca.crt \
-n traefik
FieldDescription
ca.crtCertificate Authority certificate used to verify the server's certificate.

Create a TLSOption Resource with clientAuth

To require client certificates when clients connect to Traefik, define a TLSOption resource with clientAuth.

Example

tls-option.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: TLSOption
metadata:
name: mtls
namespace: traefik
spec:
clientAuth:
clientAuthType: RequireAndVerifyClientCert
secretNames:
- client-ca-cert
FieldDescription
clientAuthTypeSpecifies the client authentication type.
clientAuthType: RequireAndVerifyClientCertenforces mTLS, requiring clients to present valid certificates.
secretNamesList of secrets containing CA certificates to verify client certificates.

Apply the TLSOption resource:

kubectl apply -f tls-option.yaml

Define a ServersTransport Resource

Create a ServersTransport resource to specify TLS settings for communication with the external service.

Example

serverstransport.yaml
apiVersion: traefik.containo.us/v1alpha1
kind: ServersTransport
metadata:
name: world-time-api-transport
namespace: traefik
spec:
serverName: worldtimeapi.org
insecureSkipVerify: false
rootCAsSecrets:
- world-time-api-cert
certificatesSecrets:
- world-time-api-cert
FieldDescription
serverNameExpected server name in the server's certificate.
insecureSkipVerifyClient certificate presented to the server.
rootCAsSecretsReferences secrets containing CA certificates to verify the server.
certificatesSecretsReferences secrets containing client certificates for mTLS.

Apply the ServersTransport resource:

kubectl apply -f serverstransport.yaml

Update the IngressRoute to Use ServersTransport and TLS

Modify your IngressRoute to reference the ServersTransport and TLSOption resource.

Example

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
name: time-api
namespace: traefik
annotations:
hub.traefik.io/api: time-api
spec:
entryPoints:
- websecure
routes:
- match: Host(`api.yourdomain.com`) && PathPrefix(`/time`)
kind: Rule
services:
- name: world-time-api
port: 443
scheme: https
serversTransport: world-time-api-transport@kubernetescrd
tls:
options:
name: mtls
namespace: traefik

Apply the updated IngressRoute:

kubectl apply -f time-api-ingressroute.yaml

Testing the mTLS Configuration

To test mTLS between clients and Traefik, use a client certificate signed by the CA specified in client-ca-cert.

curl --cert client.crt --key client.key https://api.yourdomain.com/time

You should receive a response from the external API, confirming that client mTLS is correctly configured.

Note
  • Ensure that the external API supports mTLS and that the certificates are valid.
  • Replace client.crt and client.key with your client certificate and key files.
  • Ensure the client certificate is signed by the CA in client-ca-cert.

Troubleshooting

Error: ExternalName Services Not Allowed

If you encounter the following error:

ERR error="externalName services not allowed: traefik/world-time-api"

This indicates that the allowexternalnameservices parameter is not enabled in Traefik's configuration. Ensure you've added --providers.kubernetescrd.allowexternalnameservices=true to your Traefik deployment arguments.