From 3c16c8141bcad31f0af80dd845b0399e92e78086 Mon Sep 17 00:00:00 2001 From: Vlad Vitan <23100181+vlasebian@users.noreply.github.com> Date: Wed, 10 Dec 2025 15:15:55 +0200 Subject: [PATCH 1/3] doc: Add updates for helm chart v1.10 release --- .../generic/prerequisites/_index.md | 10 +-- .../sample-ingress-controllers.md | 82 ++++++++++++++++--- .../generic/troubleshooting/_index.md | 12 ++- 3 files changed, 88 insertions(+), 16 deletions(-) diff --git a/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md b/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md index 5a18e97969..bcbfa417ca 100644 --- a/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md +++ b/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md @@ -40,7 +40,7 @@ Please [contact our sales team](mailto:sales@thethingsindustries.com) for access 1. A Kubernetes cluster 2. PostgreSQL 14 or above -3. Redis 6.2 or above +3. Redis 6.2 or above (with cluster mode disabled) 4. Blob Storage 5. An ingress controller to handle the ingress routes 6. TLS Certificates @@ -63,7 +63,7 @@ For testing purposes, [Bitnami's Helm Charts for PostgreSQL](https://artifacthub #### 3. Redis Compatible Database -Multiple components of The Things Stack use Redis to store data and for task-based operations. We recommend using a managed database for High Availability with backups enabled. +Multiple components of The Things Stack use Redis to store data and for task-based operations. We recommend using a managed database for High Availability with backups enabled. **Cluster mode must be disabled in Redis**, as it is not supported by {{% tts %}}. For testing purposes, [Bitnami's Helm Charts for Redis](https://artifacthub.io/packages/helm/bitnami/redis) can be installed in the Kubernetes Cluster. @@ -119,9 +119,9 @@ $ sudo chown -R 886:886 #### 5. An ingress controller -An ingress controller is needed to route the incoming traffic. {{% tts %}} Helm chart uses Kubernetes ingress resources for routing requests to the components of {{% tts %}}. This allows the users of {{% tts %}} Helm chart to configure an ingress controller of their choice. However, Kubernetes ingress routes support only L7 traffic (HTTP/gRPC). For this reason, the configuration for routing UDP Packet Forwarder traffic for gateways is not handled by the Helm chart. +An ingress controller is needed to route the incoming traffic. {{% tts %}} Helm chart uses Kubernetes ingress resources for routing requests to the components of {{% tts %}}. This allows the users of {{% tts %}} Helm chart to configure an ingress controller of their choice. However, Kubernetes ingress routes support only L7 traffic (HTTP/gRPC). For this reason, the configuration for the UDP Packet Forwarder or integrations such as MQTT is not handled by the Helm chart. -{{% tts %}} needs several [port allocations with various protocols]({{< ref "/concepts/networking/#port-allocations" >}}). We recommend using an ingress controller that natively supports L4 and L7 protocols. Depending on your preferred setup for gateways, an ingress controller that supports only L7 protocols (such as Ingress-Nginx) can be used too, but the connecting gateways will be either limited to L7 protocols or more complex to setup and maintain if using L4 protocols. +{{% tts %}} needs several [port allocations with various protocols]({{< ref "/concepts/networking/#port-allocations" >}}). We recommend using an ingress controller that natively supports L4 and L7 protocols. Depending on your preferred setup for gateways, an ingress controller that supports only L7 protocols can be used too, but the connecting gateways will be either limited to L7 protocols or will have a more complex setup. Although we do support UDP Packet Forwarder as a gateway connection option, it requires [more configuration on your side]({{< ref "enterprise/kubernetes/generic/#udp-gateway-support" >}}). We recommend using LoRa Basics™ Station or The Things Industries Gateway protocols for connecting gateways. @@ -129,7 +129,7 @@ To configure the ingress controller for {{% tts %}}: 1. Specify the ingress controller by setting the `global.ingress.controller` to the class name of the ingress controller deployed in the cluster. This will be used to set the ingress class name in the ingress routes that handle {{% tts %}} traffic. 2. Specify the TLS secret by setting the `global.ingress.controller.tls.secretName`. The secret has to be accessible from the namespace where the {{% tts %}} Helm Chart is deployed. This will be used to terminate TLS for {{% tts %}} traffic 3. Add annotations for the ingress routes if needed by setting `global.ingress.annotations.http`, `global.ingress.annotations.grpc`, `global.ingress.annotations.semtechws` or `global.ingress.annotations.ttigw`. -4. Add ingress specific service annotations for {{% tts %}} services by setting `global.ingress.serviceAnnotations` if needed. +4. Add service annotations for {{% tts %}} services by setting `global.services.annotations` if needed. 5. Expose the ports used by {{% tts %}} in your ingress controller. A list of all the ports can be found [here]({{< ref "/concepts/networking/#port-allocations" >}}). For production environments, make sure to expose only TLS ports. Examples of ingress controllers configurations can be found [here](https://www.thethingsindustries.com/docs/the-things-stack/host/kubernetes/generic/prerequisites/sample-ingress-controllers/). diff --git a/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md b/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md index c019bf0ec1..386a1277c3 100644 --- a/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md +++ b/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md @@ -31,14 +31,27 @@ global: grpc: traefik.ingress.kubernetes.io/router.entrypoints: grpc,grpcsecure traefik.ingress.kubernetes.io/router.tls: "true" + # LoRa Basics™ Station LNS. semtechws: traefik.ingress.kubernetes.io/router.entrypoints: semtechws,semtechwssecure traefik.ingress.kubernetes.io/router.tls: "true" - serviceAnnotations: - traefik.ingress.kubernetes.io/service.serversscheme: h2c + # LoRa Basics™ Station CUPS (in addition to the LNS configuration above). New in v1.1.0. + semtechcups: + traefik.ingress.kubernetes.io/router.middlewares: "-buffering@kubernetescrd" + # The Things Industries Gateway Protocol. + ttigw: + traefik.ingress.kubernetes.io/router.entrypoints: ttigw,ttigwsecure + traefik.ingress.kubernetes.io/router.middlewares: traefik-passtlsclientcert@kubernetescrd + traefik.ingress.kubernetes.io/router.tls: "true" + services: + annotations: + grpc: + traefik.ingress.kubernetes.io/service.serversscheme: h2c ``` -Traefik Helm chart port mapping configuration: +{{< note "The `global.ingress.serviceAnnotations` settings are deprecated starting with version 1.1.0. Use the `global.services.annotations` settings instead." />}} + +Traefik Helm chart port mapping configuration for {{% tts %}} (including both plain-text and TLS ports): ```yaml deployment: @@ -129,6 +142,45 @@ ports: exposedPort: 1700 ``` +Traefik middleware for LoRa Basics™ Station buffering: + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: buffering + namespace: +spec: + buffering: {} +``` + +Traefik Middleware for The Things Industries Gateway Protocol TLS client certificate passthrough: + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: Middleware +metadata: + name: traefik-passtlsclientcert + namespace: +spec: + passTLSClientCert: + pem: true +``` + + +Traefik default TLS options for The Things Industries Gateway: + +```yaml +apiVersion: traefik.io/v1alpha1 +kind: TLSOption +metadata: + name: default + namespace: +spec: + clientAuth: + clientAuthType: RequestClientCert +``` + UDP Ingress Route for the UDP Packet Forwarder: {{< warning "The UDP Packet Forwarder requires session affinity to work properly. Traefik does not support session affinity for UDP. Session affinity can usually be set up on the Load Balancer of the cluster. We recommend using the newer {{% lbs %}} instead of the UDP Packet Forwarder." />}} @@ -162,7 +214,7 @@ spec: routes: - match: HostSNI(`*`) services: - - name: tts-as # -as + - name: tts-as-mqtt # -as-mqtt port: 1883 --- apiVersion: traefik.io/v1alpha1 @@ -176,7 +228,7 @@ spec: routes: - match: HostSNI(`*`) services: - - name: tts-as # -as + - name: tts-as-mqtt # -as-mqtt port: 1883 tls: secretName: ingress-tls-secret @@ -184,6 +236,8 @@ spec: ## Ingress-Nginx Controller +{{< warning "We strongly recommend against using Ingress-Nginx as the Kubernetes SIG for Network and Security [announced its retirement](https://kubernetes.io/blog/2025/11/11/ingress-nginx-retirement/)." />}} + Example of an Ingress-Nginx Controller configuration. More info about the Helm chart can be found [here](https://kubernetes.github.io/ingress-nginx/). {{% tts %}} Helm chart ingress configuration: @@ -201,9 +255,17 @@ global: http: nginx.ingress.kubernetes.io/backend-protocol: HTTP nginx.ingress.kubernetes.io/use-http2: "true" - semtechws: {} - ttigw: {} - serviceAnnotations: {} + ttigw: + nginx.ingress.kubernetes.io/backend-protocol: HTTP + nginx.ingress.kubernetes.io/use-http2: "true" + semtechws: + nginx.ingress.kubernetes.io/backend-protocol: HTTP + nginx.ingress.kubernetes.io/use-http2: "false" + semtechcups: # new in v1.1.0 + nginx.ingress.kubernetes.io/backend-protocol: HTTP + nginx.ingress.kubernetes.io/use-http2: "false" + services: + annotations: {} ``` Ingress-Nginx Helm chart port mapping configuration: @@ -215,9 +277,9 @@ controller: config: use-http2: true strict-validate-path-type: false # This is needed to allow gRPC paths that contain dots. - default-ssl-certificate: / # Make sure to set this. + default-ssl-certificate: / tcp: - # Plain-text ports. + # Plain-text ports. Not recommended for production usage. "1881": tts/the-things-stack-gs:1881 # /-gs:1881 "1882": tts/the-things-stack-gs:1882 "1883": tts/the-things-stack-as:1883 diff --git a/doc/content/enterprise/kubernetes/generic/troubleshooting/_index.md b/doc/content/enterprise/kubernetes/generic/troubleshooting/_index.md index 3043838225..a34419a066 100644 --- a/doc/content/enterprise/kubernetes/generic/troubleshooting/_index.md +++ b/doc/content/enterprise/kubernetes/generic/troubleshooting/_index.md @@ -37,4 +37,14 @@ For this error, make sure that the value set in `ingress.traefik.tls.secretName` ## Failed to check version update (certificate signed by unknown authority) -If the `skip-version-check` flag is disabled, the stack will check for new updates. To check for updates, requests are going to be sent to [thethingsindustries.com](https://thethingsindustries.com). For the requests to succeed, a CA certificate must be present in the trust store of the cluster that accepts the thethingsindustries.com domain (e.g. [Amazon Root CA 1](https://www.amazontrust.com/repository/)). Another alternative is adding it to the list of certificates in the `rootCA` field in the Helm chart. +If the `skip-version-check` flag is disabled, the stack will check for new updates. To check for updates, requests are going to be sent to [thethingsindustries.com](https://thethingsindustries.com). For the requests to succeed, a CA certificate must be present in the trust store of the cluster that accepts the thethingsindustries.com domain (e.g. [Amazon Root CA 1](https://www.amazontrust.com/repository/)). Another alternative is adding it to the list of certificates in the `rootCA` field in the Helm chart. + +## My gateway is configured to use LoRa Basics Station, but it is not connecting. + +There are multiple possible causes for this issue. Check the logs of the gateway to see if there are any errors. Incorrectly configured TLS certificates are one of the most common ones. Check if the trust store used by the gateway contains the CA certificate that signed the TLS certificate used by Helm chart. + +If you see an error similar to `Malformed CUPS response: URI segments lengths (110) exceed available data (0)` that means your ingress controller needs to have buffering enabled explicitly for LoRa Basics Station connections. LoRa Basics Station CUPS does not support chunked transfer encoding and the gateway must receive a 'Content-Length' header in the HTTP responses. Enabling buffering will ensure that the entire response is buffered before being sent to the gateway, allowing the 'Content-Length' header to be set. + +E.g., if you are using Traefik as ingress controller, you can enable buffering by creating a Traefik middleware and adding the middleware annotations to the Helm chart. Check the example Traefik configuration in the [sample ingress controllers guide]({{< ref "/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers/" >}}). + +You can find more info in the LoRa Basics Station gateway setup guide: [LoRa Basics™ Station Gateway Setup]({{< ref "/hardware/gateways/concepts/lora-basics-station/">}})). From 2ffb33ec47a2a5d19b40525100681b8f296319f4 Mon Sep 17 00:00:00 2001 From: Vlad Vitan <23100181+vlasebian@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:20:49 +0200 Subject: [PATCH 2/3] doc: Add notes about boundaries around prerequisites --- .../enterprise/kubernetes/generic/prerequisites/_index.md | 2 +- .../generic/prerequisites/sample-ingress-controllers.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md b/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md index bcbfa417ca..0cdad01c43 100644 --- a/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md +++ b/doc/content/enterprise/kubernetes/generic/prerequisites/_index.md @@ -10,7 +10,7 @@ aliases: ] --- -The following are required for {{% tts %}} on Kubernetes. +The following are required for {{% tts %}} on Kubernetes. These prerequisites may be provisioned through various methods depending on the infrastructure specifics and it is the responsibility of the cluster operator to ensure they are correctly set up to be used reliably with the {{% tts %}} Helm chart. diff --git a/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md b/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md index 386a1277c3..bbd6597b57 100644 --- a/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md +++ b/doc/content/enterprise/kubernetes/generic/prerequisites/sample-ingress-controllers.md @@ -8,7 +8,7 @@ aliases: [ ] --- -The following are examples of ingress controller configurations for {{% tts %}} deployment on Kubernetes. +The following are examples of ingress controller configurations for {{% tts %}} deployment on Kubernetes. These examples serve only as general guidelines — the exact configuration may vary based on the user's environment and infrastructure. From aae460a783befe7feea8b069e091ed832559a093 Mon Sep 17 00:00:00 2001 From: Vlad Vitan <23100181+vlasebian@users.noreply.github.com> Date: Thu, 11 Dec 2025 11:20:17 +0200 Subject: [PATCH 3/3] doc: Fix k8s generic summary delimiter --- doc/content/enterprise/kubernetes/generic/_index.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/content/enterprise/kubernetes/generic/_index.md b/doc/content/enterprise/kubernetes/generic/_index.md index 8052259471..3c7437e6ca 100644 --- a/doc/content/enterprise/kubernetes/generic/_index.md +++ b/doc/content/enterprise/kubernetes/generic/_index.md @@ -10,7 +10,7 @@ aliases: [/the-things-stack/host/kubernetes/generic] This guide helps the user to install and configure {{% tts %}} on a Kubernetes cluster. - + {{< warning "Operating The Things Stack on a Kubernetes cluster is only meant for advanced users with sufficient experience with the chosen infrastructure platform and with Kubernetes." />}}