Traefik & Kubernetes with Gateway API

When using the Kubernetes Gateway API provider, Traefik leverages the Gateway API Custom Resource Definitions (CRDs) to obtain its routing configuration. For detailed information on the Gateway API concepts and resources, refer to the official documentation.

The Kubernetes Gateway API provider supports version v1.2.0 of the specification.

It fully supports all HTTPRoute core and some extended features, like GRPCRoute, as well as the TCPRoute and TLSRoute resources from the Experimental channel.

For more details, check out the conformance report.

Deploying a Gateway

A Gateway is a core resource in the Gateway API specification that defines the entry point for traffic into a Kubernetes cluster. It is linked to a GatewayClass, which specifies the controller responsible for managing and handling the traffic, ensuring that it is directed to the appropriate Kubernetes backend services.

The GatewayClass is a cluster-scoped resource typically defined by the infrastructure provider. The following GatewayClass defines that gateways attached to it must be managed by the Traefik controller.

GatewayClass

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: GatewayClass
  4. metadata:
  5. name: traefik
  6. spec:
  7. controllerName: traefik.io/gateway-controller

Next, the following Gateway manifest configures the running Traefik controller to handle the incoming traffic.

Listener ports

Please note that Gateway listener ports must match the configured EntryPoint ports of the Traefik deployment. In case they do not match, an ERROR message is logged, and the resource status is updated accordingly.

Gateway

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: Gateway
  4. metadata:
  5. name: traefik
  6. namespace: default
  7. spec:
  8. gatewayClassName: traefik
  9. # Only Routes from the same namespace are allowed.
  10. listeners:
  11. - name: http
  12. protocol: HTTP
  13. port: 80
  14. allowedRoutes:
  15. namespaces:
  16. from: Same
  17. - name: https
  18. protocol: HTTPS
  19. port: 443
  20. tls:
  21. mode: Terminate
  22. certificateRefs:
  23. - name: secret-tls
  24. namespace: default
  25. allowedRoutes:
  26. namespaces:
  27. from: Same
  28. - name: tcp
  29. protocol: TCP
  30. port: 3000
  31. allowedRoutes:
  32. namespaces:
  33. from: Same
  34. - name: tls
  35. protocol: TLS
  36. port: 3443
  37. tls:
  38. mode: Terminate
  39. certificateRefs:
  40. - name: secret-tls
  41. namespace: default
  42. allowedRoutes:
  43. namespaces:
  44. from: Same

Secret

  1. ---
  2. apiVersion: v1
  3. kind: Secret
  4. metadata:
  5. name: secret-tls
  6. namespace: default
  7. type: kubernetes.io/tls
  8. data:
  9. # Self-signed certificate for the whoami.localhost domain.
  10. tls.crt: |
  11. LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUZWakNDQXo2Z0F3SUJBZ0lVZUUrZG94aTUrMTBMVi9DaUdTMkt2Q1dJR1dZd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1JERUxNQWtHQTFVRUJoTUNSbEl4RFRBTEJnTlZCQWNNQkV4NWIyNHhGVEFUQmdOVkJBb01ERlJ5WVdWbQphV3NnVEdGaWN6RVBNQTBHQTFVRUF3d0dWMmh2WVcxcE1DQVhEVEkwTURjeE1ERTFNRGt3TjFvWUR6SXhNalF3Ck5qRTJNVFV3T1RBM1dqQkVNUXN3Q1FZRFZRUUdFd0pHVWpFTk1Bc0dBMVVFQnd3RVRIbHZiakVWTUJNR0ExVUUKQ2d3TVZISmhaV1pwYXlCTVlXSnpNUTh3RFFZRFZRUUREQVpYYUc5aGJXa3dnZ0lpTUEwR0NTcUdTSWIzRFFFQgpBUVVBQTRJQ0R3QXdnZ0lLQW9JQ0FRQ1pNNm1WNUJkV2V0QzZtdnp0YVBobFNjZ0ljbnd6Z3NsOEFxendEMk05ClJWVkZwRUxBbTh2OTNlRWtMZEY2ZnNkY0FhUXQxWlFDSFdYby9mTHBRNVVrUHh1djZNUCt2NG1KMHY4ZEtGWjcKUjcwaTVud1lCMkVlVkw2RUNZaWlxNmZ6VEtsa3F6U0QvNW93elN3L3pqa0dUYTBJdy92SDlhc0g3NEhqM1d0QQo3RythenZjaVlhQTZxK1dWYlZxNlBIanF6em9obEFuMkh1ano2aERqYWllc3ZMbHdBL0IvcmhEc0FLaCtpMHI4CkFKUTFqM0JiTGJuYkJyWmZqYnBJUjNhYVh5amkwK3RQWENnVTkzQmU5dm1LZTZTY0dSNy82T25tYmtTc0xjZFcKaFpVNzcrL2c4WllsZGhwS01nczc4ekJYUlh4bHlzSThHRUtqU1hud3k5WmZNT2RJNEpBTWNtT0lOaVlBY21abgpJTUJIa0xacFl3aUl0eFdseXVJcWxoZFpkSHNrTFdNSjBSTHUxRmhTMnBFV0NOZTM3VDBiOWhtNFg0OXJ1QWJ6Ckl1M01xSmczcXFIdGRMNGRkZ1JZRHNjMXd0cDJrR2dBZGxDaXJIclF6K1l4MEJNT1ZsZEczaG1SUUh5ZHEySHIKWW0xeEFDNWpMZ3FvaVZhY09wd0xKY21PcGsrZWVNQkNZNVo0ekNYN1hXeXdhVmNtMnN2aGlPMThCZFIraDloWQpiMkRNZDFCendDbE95endQcUlvQy9uNGRURG96Ry9GT3NySzgvNEZ4dzY2Q1ZmM3E4MzBNUHdSd2xDSzFDQjdGCjNQK3lKWkpPelRuK05QZ2dGQW9NaGZUYXBQWTFhUGlWajBzVG9vQjBaOGNFV1RkTnJxQU5tUGs5aDNoQjJwbjgKSndJREFRQUJvejR3UERBYkJnTlZIUkVFRkRBU2doQjNhRzloYldrdWJHOWpZV3hvYjNOME1CMEdBMVVkRGdRVwpCQlNGSjF4N01xdG9zQ3UwQmFWbEs1U054K2djampBTkJna3Foa2lHOXcwQkFRc0ZBQU9DQWdFQVdCOVc1eWkzClRpTWpmSThhSCtMZW1wZjc4clhyeWJ6UXJvSXdEazhqQXhnc3Nrc2V2ZEtIaXJIZGJMZ0RoS2krbkJLeEQ5S2QKNWM4RS9VL1VHWUhxaUowTVUzYkpoeTVNM3oyaklKd1hFa3FuVVhRd0dBNzVyU0QxWVBkOTlWeVpuNEJVRlEwdwpCT3loOU5DS3Z3ZTgycUVlOWZmeU5iem5JUEMrNS9pekhaYlNQMEpwRzdtNFQ5TXljdHV1OTlsaVhmSVlCMU1PCkRFRUdpamxhZ3JvdTliVlpsNmovR2xCaVZpU0JVQXhaRlNqdFErV2RFODJaZlFRUFVWdXQrUEY0SEl0N1dmYlgKaUpZbjRsMytJSVczNStvbUZ5QjR5WUJNdU9SVWRsZ3V5N1ZieEU5OTdPdHYzTnpDOGJYcGtaQVM0TkVzQVVFdwpJZ3lOcTFCdExsb3dZdjZXY05HbkJ5RE1NRUMzdUYzNEcxQkJCTzFDRHUrYXBVdW5NbVhUWmU5WlkrbXh4U2Z2CnBZclhHTHBoT2t4ZitQalpMbEpqQVFlcTNxblMvWWtLQmtYQi9zb282ZVVLTTlybyt5RTVMbnFrV20wZXpQWmwKc2Z5NGpqZ0lJUHlUMHhhZ0YyWExzUSs0M3N4aDRYTEhmc3Z3Zis2QnJVK2trTnoydmc2M3duLzJDQUNVVms3bgphSDdwZzZyZGt4T2pOTDJjUGd6ZzhWaExXbkVYYjhhUVJlVjY1WnlRc0xta21oOXBlSFRpYXBUb2xWa0d6TDIwCm9pdExZc3ZUcnhUR2NRd3Jpd3FaT1I3WjEvVEJLVnVoYnp0emxlRjFHRk9LdE52UmNSREVBeWVlbnJDRzRRMmgKMnFNNFh1RFFKcjJrR095OEV0dnlYTitENkNZUkg0ck5vZUk9Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
  12. tls.key: |
  13. LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUpRUUlCQURBTkJna3Foa2lHOXcwQkFRRUZBQVNDQ1Nzd2dna25BZ0VBQW9JQ0FRQ1pNNm1WNUJkV2V0QzYKbXZ6dGFQaGxTY2dJY253emdzbDhBcXp3RDJNOVJWVkZwRUxBbTh2OTNlRWtMZEY2ZnNkY0FhUXQxWlFDSFdYbwovZkxwUTVVa1B4dXY2TVArdjRtSjB2OGRLRlo3UjcwaTVud1lCMkVlVkw2RUNZaWlxNmZ6VEtsa3F6U0QvNW93CnpTdy96amtHVGEwSXcvdkg5YXNINzRIajNXdEE3RythenZjaVlhQTZxK1dWYlZxNlBIanF6em9obEFuMkh1anoKNmhEamFpZXN2TGx3QS9CL3JoRHNBS2graTByOEFKUTFqM0JiTGJuYkJyWmZqYnBJUjNhYVh5amkwK3RQWENnVQo5M0JlOXZtS2U2U2NHUjcvNk9ubWJrU3NMY2RXaFpVNzcrL2c4WllsZGhwS01nczc4ekJYUlh4bHlzSThHRUtqClNYbnd5OVpmTU9kSTRKQU1jbU9JTmlZQWNtWm5JTUJIa0xacFl3aUl0eFdseXVJcWxoZFpkSHNrTFdNSjBSTHUKMUZoUzJwRVdDTmUzN1QwYjlobTRYNDlydUFiekl1M01xSmczcXFIdGRMNGRkZ1JZRHNjMXd0cDJrR2dBZGxDaQpySHJReitZeDBCTU9WbGRHM2htUlFIeWRxMkhyWW0xeEFDNWpMZ3FvaVZhY09wd0xKY21PcGsrZWVNQkNZNVo0CnpDWDdYV3l3YVZjbTJzdmhpTzE4QmRSK2g5aFliMkRNZDFCendDbE95endQcUlvQy9uNGRURG96Ry9GT3NySzgKLzRGeHc2NkNWZjNxODMwTVB3UndsQ0sxQ0I3RjNQK3lKWkpPelRuK05QZ2dGQW9NaGZUYXBQWTFhUGlWajBzVApvb0IwWjhjRVdUZE5ycUFObVBrOWgzaEIycG44SndJREFRQUJBb0lDQUVCa2dKRXA3ODAvamVBQktQSTR2cjhFCkJmblc5UEZKdFpwVUhaQkJSM3NIVzFJTU9xcHVVWTJBNXhLbjEzWmZOemdxMEhFYlpqeUZVc0pkaXU0VW8razYKUlU3b3pRaVVSU0VTK0h1dTZycWlhcEx5d1pIditCZ2hrbm80NzU4Lyt6VytNU3pJOFNmU0ZXTVJ1ZG1QdWxRMQo3ZGJUV1U2d3FaU0tUTlFUeXZMYzdnUHBuZUpybWtkTzNRNnppZ0RoVGdtVDFHRXNzZ3NxN3NzbXhMWnhkZithCnkyNlRtVkJ4UDFlUzV6OVpHTWxYRFBSK044RjdOTFVrMng3S21WT3NCZVBZdjN5bmlpNHZGQUhNQndWRFZadXAKWUlUajRpMjZIaVhtanlLM2t5T0F2anNWSElRMXh1QTBCZFROdC84WXRtYllJL005QitydVg0UDJiRFNUMktRKwo4TlN2Uk9wbVppcnBHZkY3bExMSGpJUjlTMFhCWDd6VDRoWnBRWnpqK3NEWnhDM2Y3TGIwRFlKYkp0TmlDYTQxCmNpTjhNUlNldzNneHZ0RVk0RzdnN3hjbkJNdjdNT3RwQTE3d2gvMHdLd0h0amYzSWh2TmIzdkZwT0k5d1FqSzYKSlRQMng4bENJV0tyalpObVN0UksreHJTN3hTOUZVdnBhSVlyclRLQkZWSmcyMURCYWI1L3hqRlBlQWxXejczSwpvVkhsa0hLdXNMSjZLczZzcXo0ZG9mbzg3dkFsUFJzTXRkZ1ZnZFIzNXhLTGtEWXNIbGxML3Z5dE9oSkNieXB5CkJqQm1TR0RMdzBDdWplaHVtU2czYjdSUGVTNk5rbHNqUEIrMVpzRjhpVGdCcjMyM1hvTmNha2dhWWVYQlg4NFAKaE1WZHUxWk1rbXJZMWhXTzEydnhBb0lCQVFEWU5Vb2xCMkhsdWlDcVFqdmU4UFNhV0YxRmhwNUlOMGJIZEppeApIdkhqMkplVHJ6V1pUZFlIdFNJR2RzalhTOTBESXo2bXJhMW9YZXFRYlgrODVlOUFQQkZnRTJmNU5uTzBCSVVJCk5hMXRiVGpIOUhjRGRzQmJKUkZwYnk1ODZUb3lhdFY3bS9zcjVpQUZlZFMyenFOTm1XUmZOdllZS2xselZoSEUKdUd4ZjZxMHJTWktVQUhja2s1bU5Yais3WFhZaTgyemErVEE3ZjBDVm5OamR3OXFpd3B2aTJKTFB2SnA0bWt6KwpyMEN1RW9yV2NhMUdTL2hTVWdXemw3NzhQdlRpZFI2RW4zMDB2ZlIyTE84aG1xRjhVL3Bpb2UrTDVjSllRNnNKCk1YMngrYThzWFFpZ3dwdG02aUNxQ2FuS3ExN3NUZS9RTmQ1czdwb3ZOaHVKOHd3dEFvSUJBUUMxWmM5ZktPUFgKVzZSN1VoaHRRcmhIc3htQnRIQ1BuNWRLbjN5MElNNWRBaEFSdFZDV1U0M0hOTHpCNW1LbjU2dnZrSVNFaXdBbAoxTGhuY2I3YXQ2cHpTSlZtMm5oTDhjeUZrdGQrNzVyL1FHNFlpNnZQbHNBODV5ZXZpZDhZcWswaHdaZXExY05xCmxETUN3NWsrV0drckM2VW5jZXNIc2FWbDJTUGdZV1c1L3I1NnVxUnBsaVFka1EyZmlEYWRyblVueU8ycHg3bFMKVG1HemZaNmtzTWh2MlZFR1NPRm05aUo0dWlPb0xyZVhoU1RQRmxTdjdZUTZSWWtSaGgwT0tqdXM5bXZacEIxWApjcytYN0UyVTNlM0RZelpCR0NFdmxxaFNWTFRScjdIN21pMWxUMEozR0RzbDdiUk9xOE50WVdQa3hhSlNCUnQ5Ck9TcTlkTm9CcGRvakFvSUJBQ2lQdnN3NW1WVW0yUS80QXhGdE5RWnJ3M3ZTcUlrMXpaS0h2a21rVzQ3NlNGMk4KaGttdmY1TE1tWWlLNmx6eHY1SGlIOVBYUzJ3RUNvaHo4bjMyeVM3TTFobW5LbDlucHNkRC9jMHZmTXpGcTl4ZgpjYUIxdTlxZGxxbW9FUm1nQzZuL3Z2TkVyUmRzUWQrbEhwSDVMRXZYbGl3Q3ZLS0Y5MmdhNHBSOFlPQ1J2MUVhCnFXUVl2a0ZmYTNSSkZUM0taK3BncnJCYUJZRnoreUxXWFIwbHJEUFN2TG9QRldQaHB6MHUvWGplV2cwT0wzdlIKc2NjNVkybldOM21jNDFpaFd3SE5KUitPYUVmbnh5QVFpQUJPNlRMUThtMWtvZk1sOUpMb2h3TGZoUXhKb21KNQpSYkFiTWxwWlhDMXFTSzliL1IvcDh5NmxuSWZsTDRuaDVjSzRsVFVDZ2dFQUpSSHVSQU1tTksrTXVJcjVaUEs2Cm1DUjR0UEg4QXMzWmJDMlZuWFlLMWlVQ3hhdXBFVjkzM05yaExEcjV0Rmg2NFpWR0Q1UWNicDYvSkp5eEpSOWQKblB1YlZJNlhBT1lrSnJQd2lBZE5SSmFWS1R6NTJvMXpNYjhIZEM4WHdZR2tDNTcxY0xzSW1YSTV6bm5NaWxvaworK0FBVzBSRGhLb0FKQVV3K0x6T3ZpamFJbGljR3R2TSs2SFdCK0VkVURJRHpTS1p0eFdTd01nMTNTbHh6elExCmNlNFdTZE9CQkxxT0p0L2JRNVp3ZkcyQUxUWGlEcVhhWE5JekJickRtMDUwTFkrYVVMcmlLQ25WVkxXODBReGQKZDQyQjIrR2pmb2NxVk5Ec3R1RlIzUm9QNXVGQXN2Zm50b09TVW5WMWxaZk9nMFVFUEFEQk1tRUpZL2hLU1FYcwp3d0tDQVFBNWQya2hFQ1c1V3QrMzRYWnl1b3NFTjZ4UDExbC96VDRBZjhGSWtQLzlkb0JXRnBhc28zbG1NcXZHCmhPeFErbnZBSjFhNzhZRjA4N3p1UC9DZkQ0UElOUTV4YzZHMDNQdG5JOVNVT0dpMDB4Zlg5MU5NMHBHYWJqb0QKZ0RqVzJxSkJDaVB5N0RIR1RlZkU5eUNUbkhrY1NBbWllVGc3aGFyeEZPOUREZTJKbzhKQXV2SHI1aGVxazVIcgpLYlgzTy9vNUMwcWVnYW1rWVRLcHZzV2VFdXhkY2l5LzFQd3NnV3BuV1JPWllQNENrSkJweEx1bDNVamVSY3dkCnRhcjBJYU52WlV2NFd4U0JZdWVHMDFyYUd2SDZtTTcyTEExR3MrMytwTnZwUVo3bGo2S09tcFlhQUlhemVxY2MKTjJjT2R5U1RqZmQ5OFlNVFAxbmIyK3N1Yy91VAotLS0tLUVORCBQUklWQVRFIEtFWS0tLS0tCg==

Exposing a Route

Once a Gateway is deployed (see Deploying a Gateway) HTTPRoute, TCPRoute, and/or TLSRoute resources must be deployed to forward some traffic to Kubernetes backend services.

Attaching to Gateways

As demonstrated in the following examples, a Route resource must be configured with ParentRefs that reference the parent Gateway it should be associated with.

HTTP/HTTPS

The HTTPRoute is a core resource in the Gateway API specification, designed to define how HTTP traffic should be routed within a Kubernetes cluster. It allows the specification of routing rules that direct HTTP requests to the appropriate Kubernetes backend services.

For more details on the resource and concepts, check out the Kubernetes Gateway API documentation.

For example, the following manifests configure a whoami backend and its corresponding HTTPRoute, reachable through the deployed Gateway at the http://whoami.localhost address.

HTTPRoute

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: whoami-http
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: http
  11. kind: Gateway
  12. hostnames:
  13. - whoami.localhost
  14. rules:
  15. - matches:
  16. - path:
  17. type: PathPrefix
  18. value: /
  19. backendRefs:
  20. - name: whoami
  21. namespace: default
  22. port: 80

Whoami deployment

  1. ---
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: whoami
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: whoami
  11. template:
  12. metadata:
  13. labels:
  14. app: whoami
  15. spec:
  16. containers:
  17. - name: whoami
  18. image: traefik/whoami
  19. ---
  20. apiVersion: v1
  21. kind: Service
  22. metadata:
  23. name: whoami
  24. namespace: default
  25. spec:
  26. selector:
  27. app: whoami
  28. ports:
  29. - port: 80

To secure the connection with HTTPS and redirect non-secure request to the secure endpoint, we will update the above HTTPRoute manifest to add a RequestRedirect filter, and add a new HTTPRoute which binds to the https Listener and forward the traffic to the whoami backend.

HTTRoute (HTTP)

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: whoami-http
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: http
  11. kind: Gateway
  12. hostnames:
  13. - whoami.localhost
  14. rules:
  15. - filters:
  16. - type: RequestRedirect
  17. requestRedirect:
  18. scheme: https

HTTRoute (HTTPS)

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: whoami-https
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: https
  11. kind: Gateway
  12. hostnames:
  13. - whoami.localhost
  14. rules:
  15. - matches:
  16. - path:
  17. type: PathPrefix
  18. value: /
  19. backendRefs:
  20. - name: whoami
  21. namespace: default
  22. port: 80

Once everything is deployed, sending a GET request to the HTTP and HTTPS endpoints should return the following responses:

  1. $ curl -I http://whoami.localhost
  2. HTTP/1.1 302 Found
  3. Location: https://whoami.localhost/
  4. Date: Thu, 11 Jul 2024 15:11:31 GMT
  5. Content-Length: 5
  6. $ curl -k https://whoami.localhost
  7. Hostname: whoami-697f8c6cbc-2krl7
  8. IP: 127.0.0.1
  9. IP: ::1
  10. IP: 10.42.1.5
  11. IP: fe80::60ed:22ff:fe10:3ced
  12. RemoteAddr: 10.42.2.4:44682
  13. GET / HTTP/1.1
  14. Host: whoami.localhost
  15. User-Agent: curl/7.87.1-DEV
  16. Accept: */*
  17. Accept-Encoding: gzip
  18. X-Forwarded-For: 10.42.1.0
  19. X-Forwarded-Host: whoami.localhost
  20. X-Forwarded-Port: 443
  21. X-Forwarded-Proto: https
  22. X-Forwarded-Server: traefik-6b66d45748-ns8mt
  23. X-Real-Ip: 10.42.1.0

GRPC

The GRPCRoute is an extended resource in the Gateway API specification, designed to define how GRPC traffic should be routed within a Kubernetes cluster. It allows the specification of routing rules that direct GRPC requests to the appropriate Kubernetes backend services.

For more details on the resource and concepts, check out the Kubernetes Gateway API documentation.

For example, the following manifests configure an echo backend and its corresponding GRPCRoute, reachable through the deployed Gateway at the echo.localhost:80 address.

GRPCRoute

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: GRPCRoute
  4. metadata:
  5. name: echo
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: http
  11. kind: Gateway
  12. hostnames:
  13. - echo.localhost
  14. rules:
  15. - matches:
  16. - method:
  17. type: Exact
  18. service: grpc.reflection.v1alpha.ServerReflection
  19. - method:
  20. type: Exact
  21. service: gateway_api_conformance.echo_basic.grpcecho.GrpcEcho
  22. method: Echo
  23. backendRefs:
  24. - name: echo
  25. namespace: default
  26. port: 3000

Echo deployment

  1. ---
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: echo
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: echo
  11. template:
  12. metadata:
  13. labels:
  14. app: echo
  15. spec:
  16. containers:
  17. - name: echo-basic
  18. image: gcr.io/k8s-staging-gateway-api/echo-basic
  19. env:
  20. - name: POD_NAME
  21. valueFrom:
  22. fieldRef:
  23. fieldPath: metadata.name
  24. - name: NAMESPACE
  25. valueFrom:
  26. fieldRef:
  27. fieldPath: metadata.namespace
  28. - name: GRPC_ECHO_SERVER
  29. value: "1"
  30. ---
  31. apiVersion: v1
  32. kind: Service
  33. metadata:
  34. name: echo
  35. namespace: default
  36. spec:
  37. selector:
  38. app: echo
  39. ports:
  40. - port: 3000

Once everything is deployed, sending a GRPC request to the HTTP endpoint should return the following responses:

  1. $ grpcurl -plaintext echo.localhost:80 gateway_api_conformance.echo_basic.grpcecho.GrpcEcho/Echo
  2. {
  3. "assertions": {
  4. "fullyQualifiedMethod": "/gateway_api_conformance.echo_basic.grpcecho.GrpcEcho/Echo",
  5. "headers": [
  6. {
  7. "key": "x-real-ip",
  8. "value": "10.42.2.0"
  9. },
  10. {
  11. "key": "x-forwarded-server",
  12. "value": "traefik-74b4cf85d8-nkqqf"
  13. },
  14. {
  15. "key": "x-forwarded-port",
  16. "value": "80"
  17. },
  18. {
  19. "key": "x-forwarded-for",
  20. "value": "10.42.2.0"
  21. },
  22. {
  23. "key": "grpc-accept-encoding",
  24. "value": "gzip"
  25. },
  26. {
  27. "key": "user-agent",
  28. "value": "grpcurl/1.9.1 grpc-go/1.61.0"
  29. },
  30. {
  31. "key": "content-type",
  32. "value": "application/grpc"
  33. },
  34. {
  35. "key": "x-forwarded-host",
  36. "value": "echo.localhost:80"
  37. },
  38. {
  39. "key": ":authority",
  40. "value": "echo.localhost:80"
  41. },
  42. {
  43. "key": "accept-encoding",
  44. "value": "gzip"
  45. },
  46. {
  47. "key": "x-forwarded-proto",
  48. "value": "http"
  49. }
  50. ],
  51. "authority": "echo.localhost:80",
  52. "context": {
  53. "namespace": "default",
  54. "pod": "echo-78f76675cf-9k7rf"
  55. }
  56. }
  57. }

TCP

Experimental Channel

The TCPRoute resource described below is currently available only in the Experimental channel of the Gateway API specification. To use this resource, the experimentalChannel option must be enabled in the Traefik deployment.

The TCPRoute is a resource in the Gateway API specification designed to define how TCP traffic should be routed within a Kubernetes cluster.

For more details on the resource and concepts, check out the Kubernetes Gateway API documentation.

For example, the following manifests configure a whoami backend and its corresponding TCPRoute, reachable through the deployed Gateway at the localhost:3000 address.

TCPRoute

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1alpha2
  3. kind: TCPRoute
  4. metadata:
  5. name: whoami-tcp
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: tcp
  11. kind: Gateway
  12. rules:
  13. - backendRefs:
  14. - name: whoamitcp
  15. namespace: default
  16. port: 3000

Whoami deployment

  1. ---
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: whoamitcp
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: whoamitcp
  11. template:
  12. metadata:
  13. labels:
  14. app: whoamitcp
  15. spec:
  16. containers:
  17. - name: whoami
  18. image: traefik/whoamitcp
  19. args:
  20. - --port=:3000
  21. ---
  22. apiVersion: v1
  23. kind: Service
  24. metadata:
  25. name: whoamitcp
  26. namespace: default
  27. spec:
  28. selector:
  29. app: whoamitcp
  30. ports:
  31. - port: 3000

Once everything is deployed, sending the WHO command should return the following response:

  1. $ nc localhost 3000
  2. WHO
  3. Hostname: whoamitcp-85d644bfc-ktzv4
  4. IP: 127.0.0.1
  5. IP: ::1
  6. IP: 10.42.1.4
  7. IP: fe80::b89e:85ff:fec2:7d21

TLS

Experimental Channel

The TLSRoute resource described below is currently available only in the Experimental channel of the Gateway API. Therefore, to use this resource, the experimentalChannel option must be enabled.

The TLSRoute is a resource in the Gateway API specification designed to define how TLS (Transport Layer Security) traffic should be routed within a Kubernetes cluster. It specifies routing rules for TLS connections, directing them to appropriate backend services based on the SNI (Server Name Indication) of the incoming connection.

For more details on the resource and concepts, check out the Kubernetes Gateway API documentation.

For example, the following manifests configure a whoami backend and its corresponding TLSRoute, reachable through the deployed Gateway at the localhost:3443 address via a secure connection with the whoami.localhost SNI.

TLSRoute

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1alpha2
  3. kind: TLSRoute
  4. metadata:
  5. name: whoami-tls
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: tls
  11. kind: Gateway
  12. hostnames:
  13. - whoami.localhost
  14. rules:
  15. - backendRefs:
  16. - name: whoamitcp
  17. namespace: default
  18. port: 3000

Whoami deployment

  1. ---
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: whoamitcp
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: whoamitcp
  11. template:
  12. metadata:
  13. labels:
  14. app: whoamitcp
  15. spec:
  16. containers:
  17. - name: whoami
  18. image: traefik/whoamitcp
  19. args:
  20. - --port=:3000
  21. ---
  22. apiVersion: v1
  23. kind: Service
  24. metadata:
  25. name: whoamitcp
  26. namespace: default
  27. spec:
  28. selector:
  29. app: whoamitcp
  30. ports:
  31. - port: 3000

Once everything is deployed, sending the WHO command should return the following response:

  1. $ openssl s_client -quiet -connect localhost:3443 -servername whoami.localhost
  2. Connecting to ::1
  3. depth=0 C=FR, L=Lyon, O=Traefik Labs, CN=Whoami
  4. verify error:num=18:self-signed certificate
  5. verify return:1
  6. depth=0 C=FR, L=Lyon, O=Traefik Labs, CN=Whoami
  7. verify return:1
  8. WHO
  9. Hostname: whoamitcp-85d644bfc-hnmdz
  10. IP: 127.0.0.1
  11. IP: ::1
  12. IP: 10.42.2.4
  13. IP: fe80::d873:20ff:fef5:be86

Using Traefik middleware as HTTPRoute filter

An HTTP filter is an HTTPRoute component which enables the modification of HTTP requests and responses as they traverse the routing infrastructure.

There are three types of filters:

  • Core: Mandatory filters for every Gateway controller, such as RequestHeaderModifier and RequestRedirect.
  • Extended: Optional filters for Gateway controllers, such as ResponseHeaderModifier and RequestMirror.
  • ExtensionRef: Additional filters provided by the Gateway controller. In Traefik, these are the HTTP middlewares supported through the Middleware CRD.

ExtensionRef Filters

To use Traefik middlewares as ExtensionRef filters, the Kubernetes IngressRoute provider must be enabled in the static configuration, as detailed in the documentation.

For example, the following manifests configure an HTTPRoute using the Traefik AddPrefix middleware, reachable through the deployed Gateway at the http://whoami.localhost address:

HTTRoute

  1. ---
  2. apiVersion: gateway.networking.k8s.io/v1
  3. kind: HTTPRoute
  4. metadata:
  5. name: whoami-http
  6. namespace: default
  7. spec:
  8. parentRefs:
  9. - name: traefik
  10. sectionName: http
  11. kind: Gateway
  12. hostnames:
  13. - whoami.localhost
  14. rules:
  15. - backendRefs:
  16. - name: whoami
  17. namespace: default
  18. port: 80
  19. filters:
  20. - type: ExtensionRef
  21. extensionRef:
  22. group: traefik.io
  23. kind: Middleware
  24. name: add-prefix

AddPrefix middleware

  1. ---
  2. apiVersion: traefik.io/v1alpha1
  3. kind: Middleware
  4. metadata:
  5. name: add-prefix
  6. namespace: default
  7. spec:
  8. addPrefix:
  9. prefix: /prefix

Whoami deployment

  1. ---
  2. apiVersion: apps/v1
  3. kind: Deployment
  4. metadata:
  5. name: whoami
  6. namespace: default
  7. spec:
  8. selector:
  9. matchLabels:
  10. app: whoami
  11. template:
  12. metadata:
  13. labels:
  14. app: whoami
  15. spec:
  16. containers:
  17. - name: whoami
  18. image: traefik/whoami
  19. ---
  20. apiVersion: v1
  21. kind: Service
  22. metadata:
  23. name: whoami
  24. namespace: default
  25. spec:
  26. selector:
  27. app: whoami
  28. ports:
  29. - port: 80

Once everything is deployed, sending a GET request should return the following response:

  1. $ curl http://whoami.localhost
  2. Hostname: whoami-697f8c6cbc-kw954
  3. IP: 127.0.0.1
  4. IP: ::1
  5. IP: 10.42.2.6
  6. IP: fe80::a460:ecff:feb6:3a56
  7. RemoteAddr: 10.42.2.4:54758
  8. GET /prefix/ HTTP/1.1
  9. Host: whoami.localhost
  10. User-Agent: curl/7.87.1-DEV
  11. Accept: */*
  12. Accept-Encoding: gzip
  13. X-Forwarded-For: 10.42.2.1
  14. X-Forwarded-Host: whoami.localhost
  15. X-Forwarded-Port: 80
  16. X-Forwarded-Proto: http
  17. X-Forwarded-Server: traefik-6b66d45748-ns8mt
  18. X-Real-Ip: 10.42.2.1

Native Load Balancing

By default, Traefik sends the traffic directly to the pod IPs and reuses the established connections to the backends for performance purposes.

It is possible to override this behavior and configure Traefik to send the traffic to the service IP. The Kubernetes service itself does the load balancing to the pods. It can be done with the annotation traefik.io/service.nativelb on the backend Service.

By default, NativeLB is false.

Default value

Note that it is possible to override the default value by using the option nativeLBByDefault at the provider level.

  1. ---
  2. apiVersion: v1
  3. kind: Service
  4. metadata:
  5. name: myservice
  6. namespace: default
  7. annotations:
  8. traefik.io/service.nativelb: "true"
  9. spec:
  10. [...]

Using Traefik OSS in Production?

If you are using Traefik at work, consider adding enterprise-grade API gateway capabilities or commercial support for Traefik OSS.

Adding API Gateway capabilities to Traefik OSS is fast and seamless. There’s no rip and replace and all configurations remain intact. See it in action via this short video.