diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/_index.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/_index.md index 855f60a830e..aa481df5529 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-cluster/_index.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/_index.md @@ -216,123 +216,7 @@ If an app's MDA was built using a newer Java version, Mendix Operator 2.15.0 (an ### Endpoint (network) Configuration {#advanced-network-settings} -The OperatorConfiguration contains the following user-editable options for network configuration: - -When using **Ingress** for network endpoints: - -```yaml -apiVersion: privatecloud.mendix.com/v1alpha1 -kind: OperatorConfiguration -# ... -# omitted lines for brevity -# ... -spec: - # Endpoint (Network) configuration - endpoint: - # Endpoint type: ingress, openshiftRoute or service - type: ingress - # Optional, can be omitted: Service annotations - serviceAnnotations: - # example: custom AWS CLB configuration - service.beta.kubernetes.io/aws-load-balancer-backend-protocol: tcp - service.beta.kubernetes.io/aws-load-balancer-ssl-cert: arn:aws:acm:eu-west-1:account:certificate/id - service.beta.kubernetes.io/aws-load-balancer-ssl-ports: "443" - # Ingress configuration: used only when type is set to ingress - ingress: - # Optional, can be omitted: annotations which should be applied to all Ingress Resources - annotations: - # default annotation: allow uploads of files up 500 MB in the NGINX Ingress Controller - nginx.ingress.kubernetes.io/proxy-body-size: 500m - # example: use the specified cert-manager ClusterIssuer to generate TLS certificates with Let's Encrypt - cert-manager.io/cluster-issuer: staging-issuer - # example: deny access to /rest-doc - nginx.ingress.kubernetes.io/configuration-snippet: | - location /rest-doc { - deny all; - return 403; - } - # App URLs will be generated for subdomains of this domain, unless an app is using a custom appURL - domain: mendix.example.com - # Enable or disable TLS - enableTLS: true - # Optional: name of a kubernetes.io/tls secret containing the TLS certificate - # This example is a template which lets cert-manager to generate a unique certificate for each app - tlsSecretName: '{{.Name}}-tls' - # Optional: specify the Ingress class name - ingressClassName: alb - # Optional, can be omitted : specify the Ingress path - path: "/" - # Optional, can be omitted : specify the Ingress pathType - pathType: ImplementationSpecific -# ... -# omitted lines for brevity -# ... -``` - -When using **OpenShift Routes** for network endpoints: - -```yaml -apiVersion: privatecloud.mendix.com/v1alpha1 -kind: OperatorConfiguration -spec: - # Endpoint (Network) configuration - endpoint: - # Endpoint type: ingress, openshiftRoute, or service - type: openshiftRoute - # OpenShift Route configuration: used only when type is set to openshiftRoute - openshiftRoute: - # Optional, can be omitted: annotations which should be applied to all Ingress Resources - annotations: - # example: use HSTS headers - haproxy.router.openshift.io/hsts_header: max-age=31536000;includeSubDomains;preload - # Optional: App URLs will be generated for subdomains of this domain, unless an app is using a custom appURL - domain: mendix.example.com - # Enable or disable TLS - enableTLS: true - # Optional: name of a kubernetes.io/tls secret containing the TLS certificate - # This example is the name of an existing secret, which should be a wildcard matching subdomains of the domain name - tlsSecretName: 'mendixapps-tls' -``` - -When using **Services** for network endpoints (without an Ingress or OpenShift route): - -```yaml -apiVersion: privatecloud.mendix.com/v1alpha1 -kind: OperatorConfiguration -spec: - # Endpoint (Network) configuration - endpoint: - # Endpoint type: ingress, openshiftRoute, or service - type: service - # Optional, can be omitted: the Service type - serviceType: LoadBalancer - # Optional, can be omitted: Service annotations - serviceAnnotations: - # example: annotations required for AWS NLB - service.beta.kubernetes.io/aws-load-balancer-type: external - service.beta.kubernetes.io/aws-load-balancer-nlb-target-type: ip - service.beta.kubernetes.io/aws-load-balancer-scheme: internet-facing - # Optional, can be omitted: Service ports - servicePorts: - - 80 - - 443 -``` - -You can change the following options: - -* **type**: – select the Endpoint type, possible options are `ingress`, `openshiftRoute` and `service`; this parameter is also configured through the **Configuration Tool** -* **ingress**: - specify the Ingress configuration, required when **type** is set to `ingress` -* **openshiftRoute**: - specify the OpenShift Route configuration, required when **type** is set to `openshiftRoute` -* **annotations**: - optional, can be used to specify the Ingress or OpenShift Route annotations, can be a template: `{{.Name}}` will be replaced with the name of the CR for the Mendix app, and {{.Domain}} will be replaced with the application's domain name -* **serviceAnnotations**: - optional, can be used to specify the Service annotations, can be a template: `{{.Name}}` will be replaced with the name of the CR for the Mendix app, and {{.Domain}} will be replaced with the application's domain name -* **ingressClassName**: - optional, can be used to specify the Ingress Class name -* **path**: - optional, can be used to specify the Ingress path; default value is `/` -* **pathType**: - optional, can be used to specify the Ingress pathType; if not set, no pathType will be specified in Ingress objects -* **domain**: - optional for `openshiftRoute`, required for `ingress`, used to generate the app domain in case no app URL is specified; if left empty when using OpenShift Routes, the default OpenShift `apps` domain will be used; this parameter is also configured through the **Configuration Tool** -* **enableTLS**: - allows you to enable or disable TLS for the Mendix App's Ingress or OpenShift Route -* **tlsSecretName**: - optional name of a `kubernetes.io/tls` secret containing the TLS certificate, can be a template: `{{.Name}}` will be replaced with the name of the CR for the Mendix app; if left empty, the default TLS certificate from the Ingress Controller or OpenShift Router will be used -* **serviceType**: - can be used to specify the Service type, possible options are `ClusterIP` and `LoadBalancer`; if not specified, Services will be created with the `ClusterIP` type -* **servicePorts**: - can be used to specify a list of custom ports for the Service; if not specified, Services will use be created with port `8080` +For information on using advanced network configuration settings, see [Network Ingress Settings section](/developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/). {{% alert color="info" %}} When switching between Ingress and OpenShift Routes, you need to [restart the Mendix Operator](#restart-after-changing-network-cr) for the changes to be fully applied. @@ -938,6 +822,54 @@ Alternatively, for Standalone clusters, pod labels can be specified in the `Mend The Mendix Operator uses some labels for internal use. To avoid conflicts with these internal pod labels, please avoid using labels starting with the `privatecloud.mendix.com/` prefix. {{% /alert %}} +### Pod Annotations (General) {#pod-annotations} + +Mendix Operator version 2.27.0 or above allows you to specify default pod annotations for task pods (build and storage provisioners) and runtime (app) pods. + +To specify the default pod annotations for a namespace, specify them in `customPodAnnotations.general` in `OperatorConfiguration`: + +```yaml +apiVersion: privatecloud.mendix.com/v1alpha1 +kind: OperatorConfiguration +spec: + # ... + # Other configuration options values + # Optional: custom pod annotations + customPodAnnotations: + # Optional: general pod annotations (applied to all app-related pods) + general: + # Example: use FQDN instead of IP addresses when communicating with the Kubernetes API server + kubernetes.azure.com/set-kube-service-host-fqdn: "true" +``` + +Alternatively, for Standalone clusters, pod annotations for an app can be specified in the `MendixApp` CR. + +{{% alert color="warning" %}} +The Mendix Operator uses some annotations for internal use. To avoid conflicts with these internal pod annotations, please avoid using labels starting with the `privatecloud.mendix.com/` prefix. +{{% /alert %}} + +### Node Selector (General) {#node-selector} + +Mendix Operator version 2.27.0 or above allows you to specify the default `nodeSelector` for task pods (build and storage provisioners) and runtime (app) pods. + +To configure the default pod `nodeSelector` for a namespace, specify them in `customPodNodeSelector.general` in `OperatorConfiguration`: + +```yaml +apiVersion: privatecloud.mendix.com/v1alpha1 +kind: OperatorConfiguration +spec: + # ... + # Other configuration options values + # Optional: custom pod nodeSelector + customPodNodeSelector: + # Optional: general pod nodeSelector (applied to all app-related pods) + general: + # Example: use Amazon EKS Auto Mode + eks.amazonaws.com/compute-type: auto +``` + +Alternatively, for Standalone clusters, pod `nodeSelector` configuration can be specified in the `MendixApp` CR for a specific app. + ### Delaying App Shutdown {#termination-delay} In some situations, shutting down a replica immediately can cause isses. For example, the [Azure Gateway Ingress Controller](https://azure.github.io/application-gateway-kubernetes-ingress/how-tos/minimize-downtime-during-deployments/) needs up to 90 seconds to remove a pod from its routing table. Stopping an app pod immediately would still send traffic to the pod for a few minutes, causing random 502 errors to appear in the client web browser. diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/_index.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/_index.md index eb53809a173..66b7653e857 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/_index.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/_index.md @@ -8,7 +8,7 @@ weight: 10 ## Introduction -Based on your organization's networking and security needs, you must configure the available networking components of your Mendix web applications to be accessible to end users, either over a private network or the Internet. This article describes three possible network configurations: Kubernetes Ingress, OpenShift Routes, and Service-Only. Each configuration is tailored to meet specific use cases. +Based on your organization's networking and security needs, you must configure the available networking components of your Mendix web applications to be accessible to end users, either over a private network or the Internet. This article describes three possible network configurations: Kubernetes Ingress, Gateway Routes, OpenShift Routes, and Service-Only. Each configuration is tailored to meet specific use cases. ## Prerequisites @@ -22,6 +22,8 @@ Mendix on Kubernetes supports the following Ingress configurations: {{< figure src="/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/k8s-ingress.png" class="no-border" >}} +* [Gateway Routes](/developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/gateway-route/) - A next generation Kubernetes standard for Ingresses and load balancing. Supported by Mendix Operator v2.27.0 or later versions. + * [OpenShift Routes](/developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/openshift/) - The OpenShift-native method for exposing services externally provides a more streamlined setup, though it offers less flexibility compared to Kubernetes Ingress. {{< figure src="/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/openshift-routes.png" class="no-border" >}} @@ -42,17 +44,17 @@ The following table compares the functionality of the three supported options, i When switching between Ingress, OpenShift Routes, and Service Only, you must restart the Mendix Operator for the changes to be fully applied. {{% /alert %}} -| Feature | Kubernetes Ingress | Openshift Routes | Service Only | -| --- | --- | --- | --- | -| Ease of use | Requires setup, but offers more flexibility. | Simplest option for OpenShift users, built-in. | Fine-grained control over networking and security offers maximum flexibility, but requires significant effort and expertise to configure and maintain. Note that the networking setup beyond the Mendix Operator's scope, up to the service object, is not supported by Mendix. | -| Native cloud integration | Can integrate with cloud-native services like AWS Application Load Balancer. | No direct integration with cloud providers. | Full control over networking setup. | -| Performance and scalability | Scales with cloud load balancers, better supports horizontal scaling. | Limited to OpenShift Router performance. | Full flexibility - scales according to your load balancer and proxy setup. | -| Supported providers | [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/); [Traefik](https://traefik.io/traefik/); [AWS Application Load Balancer](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html); [Ingress for External Application Load Balancer](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-xlb); [Azure Application Gateway Ingress Controller](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview) | [OpenShift Router (HAProxy-based Ingress Controller)](https://docs.openshift.com/container-platform/4.17/networking/networking_operators/ingress-operator.html) | None | -| TLS/SSL termination | Can leverage cloud provider-managed TLS; supports Cert-Manager. | Supported with OpenShift's HAProxy router. | Fully flexible but requires manual setup; TLS can terminate at application load balancer, network load balancer, or app level | -| Security (WAF, ACLs, Auth) | More advanced security integrations (for example AWS Web Application Firewall, authentication). | Basic access control via OpenShift OAuth. | Full control - can integrate with AWS Web Application Firewall, API Gateway, authentication proxies with manual configuration. | -| Traffic splitting | Fully supported through ingress rules. | Supported through HAProxy-based Route annotations. | Depends on external networking setup. | -| External DNS support | Some ingress controllers (for example, application load balancers) support native DNS updates. | Requires ExternalDNS integration. | Fully configurable - can use ExternalDNS, Amazon Route 53, or others. | -| Custom annotations | Supports Kubernetes Ingress annotations, provider-specific features.| Supports OpenShift-specific annotations. | No restrictions - fully customizable in external networking. | +| Feature | Kubernetes Ingress | Gateway Routes | Openshift Routes | Service Only | +| --- | --- | --- | --- | --- | +| Ease of use | Requires setup, but offers more flexibility. | Requires setup, offers flexibility with separation of scope by [roles and personas](https://gateway-api.sigs.k8s.io/docs/concepts/roles-and-personas/) | Simplest option for OpenShift users, built-in. | Fine-grained control over networking and security offers maximum flexibility, but requires significant effort and expertise to configure and maintain. Note that the networking setup beyond the Mendix Operator's scope, up to the service object, is not supported by Mendix. | +| Native cloud integration | Can integrate with cloud-native services like AWS Application Load Balancer. | Can integrate with cloud-native services like AWS Application Load Balancer. | No direct integration with cloud providers. | Full control over networking setup. | +| Performance and scalability | Scales with cloud load balancers, better supports horizontal scaling. | Scales with cloud load balancers, better supports horizontal scaling. | Limited to OpenShift Router performance. | Full flexibility - scales according to your load balancer and proxy setup. | +| Supported providers | [NGINX Ingress Controller](https://kubernetes.github.io/ingress-nginx/); [Traefik](https://traefik.io/traefik/); [AWS Application Load Balancer](https://docs.aws.amazon.com/eks/latest/userguide/alb-ingress.html); [Ingress for External Application Load Balancer](https://cloud.google.com/kubernetes-engine/docs/concepts/ingress-xlb); [Azure Application Gateway Ingress Controller](https://learn.microsoft.com/en-us/azure/application-gateway/ingress-controller-overview) | [Gateway API v1.4 compliant implementations](https://gateway-api.sigs.k8s.io/docs/implementations/versions/v1.4/) | [OpenShift Router (HAProxy-based Ingress Controller)](https://docs.openshift.com/container-platform/4.17/networking/networking_operators/ingress-operator.html) | None | +| TLS/SSL termination | Can leverage cloud provider-managed TLS; supports Cert-Manager. | Configured in the Gateway [listener](https://gateway-api.sigs.k8s.io/guides/user-guides/tls/#listeners-and-tls) by the cluster operator | Supported with OpenShift's HAProxy router. | Fully flexible but requires manual setup; TLS can terminate at application load balancer, network load balancer, or app level | +| Security (WAF, ACLs, Auth) | More advanced security integrations (for example AWS Web Application Firewall, authentication). | Provided by the Gateway implementation | Basic access control via OpenShift OAuth. | Full control - can integrate with AWS Web Application Firewall, API Gateway, authentication proxies with manual configuration. | +| Traffic splitting | Fully supported through ingress rules. | Fully supported. | Supported through HAProxy-based Route annotations. | Depends on external networking setup. | +| External DNS support | Some ingress controllers (for example, application load balancers) support native DNS updates. | Fully configurable - can use ExternalDNS, Amazon Route 53, or others. | Requires ExternalDNS integration. | Fully configurable - can use ExternalDNS, Amazon Route 53, or others. | +| Custom annotations | Supports Kubernetes Ingress annotations, provider-specific features. | Gateway implementations typically use vendor-specific CRDs, annotations are supported as well. | Supports OpenShift-specific annotations. | No restrictions - fully customizable in external networking. | ## Recommended Configuration @@ -75,6 +77,9 @@ While OpenShift Routes are a viable option, we recommend NGINX Ingress Controlle OpenShift Routes remain a suitable choice if meet your current needs and you do not require advanced features. {{% /alert %}} +If your cluster has a configured and working Gateway API implementation, using it might be a preferrable option. +The Gateway API standardized typical use cases, and the Mendix Operator only uses HTTPRoute features defined in the [v1.4 standard](https://gateway-api.sigs.k8s.io/reference/api-spec/1.4/spec/), without relying on any vendor-specific feature. + ## Known Issues * AWS Application Load Balancers do not work correctly with HTTP2 WebSockets. @@ -83,3 +88,4 @@ OpenShift Routes remain a suitable choice if meet your current needs and you do * Some application load balancer firewall rules can block file uploads or other Mendix app features. * Linkerd does not work correctly with AWS Application Load Balancer and Azure Gateway Ingress Controller. +* Some Gateway API implementations do not fully implement the base v1.4 spec, or are experimental (unsupported). diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-advanced-ingress-settings.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-advanced-ingress-settings.md index 8a3b96d0d68..7e8bd86b6f5 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-advanced-ingress-settings.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-advanced-ingress-settings.md @@ -3,7 +3,7 @@ title: "Advanced Ingress Settings in Mendix on Kubernetes" linktitle: "Advanced Settings" url: /developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/advanced/ description: "Describes how to configure advanced Ingress settings." -weight: 40 +weight: 50 --- ## Introduction diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-gateway.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-gateway.md new file mode 100644 index 00000000000..ed40c57b172 --- /dev/null +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-gateway.md @@ -0,0 +1,108 @@ +--- +title: "Gateway Routes in Mendix on Kubernetes" +linktitle: "Gateway Routes" +url: /developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/gateway-route/ +description: "Describes how to configure Gateway HTTPRoutes for Mendix on Kubernetes." +weight: 20 +--- + +## Introduction + +Gateway API is the successor to the Ingress API. Gateway API splits configuration across different roles: + +* Cluster operators manage **Gateway** resources, configuring central rules and policies such as TLS and IP filtering. +* Application developers manage **HTTPRoute** resources, specifying configuration relevant for a specific destination, such as a Mendix app environment. + +{{% alert color="info" %}} +Gateway API is supported by Mendix Operator version 2.27.0 and newer. +{{% /alert %}} + +## What is Kubernetes Gateway? + +In a Mendix environment, the Mendix Operator automatically creates both the Service and HTTPRoute resources based on the app environment's configuration. The Service defines how traffic is routed to application pods within the cluster, while the HTTPRoute links the app to a specific Gateway and configures relevant HTTP options. + +The Gateway resource, and the Gateway controller (implementation) must be created and configured by the cluster admin. The Mendix Operator manages HTTPRoute resources and links them to a Gateway resource through the `parentRefs` field. + +For each app environment, the URL is automatically generated based on the domain name. For example, if the domain name is set to `mendix.example.com`, the apps have URLs such as `myapp1-dev.mendix.example.com`, `myapp1-prod.mendix.example.com`, and so on. + +To ensure proper routing, the DNS server must be configured to direct all subdomains (`*.mendix.example.com`) to the Gateway or Load Balancer. This option is easy to configure, and adding new apps or changing domain names works instantly. Alternatively, you can manage DNS records with Kubernetes External DNS. + +## Basic Installation and Configuration + +Refer to the installation and configuration guide of your Gateway implementation. Any Gateway [implementation](https://gateway-api.sigs.k8s.io/docs/implementations/list/) that supports HTTPRoute resources and Gateway API v1.4 should be compatible with the Mendix Operator. + +### Configuring Gateway HTTPRoute in the Mxpc-cli Tool + +To use the Gateway and configure how Mendix on Kubernetes should use HTTPRoutes, configure the following settings: + +* **Enable TLS** - Enable if the Gateway supports TLS. This will use `https://` in the AppURL by default. TLS options such as HTTP-to-HTTPS redirection, HSTS and certificates must be configured on the Gateway level. +* **Domain** - Provide the default domain name which you want to use for new apps. For existing apps, the domain name and HTTP path can be configured on a per-app basis. +* In the **Gateway Route Parent Reference**, specify settings for the HTTPRoute's [parentRefs](https://gateway-api.sigs.k8s.io/reference/api-spec/1.4/spec/#parentreference). This is usually a Gateway resource configured by a cluster admin. + + * **Group** - Specifies the ParentReference `group` value (usually `gateway.networking.k8s.io`). + * **Kind** - Specifies the ParentReference `kind` value (usually `Gateway`). + * **Name** and **Namespace** - Specify the existing ParentReference's Kubernetes name and namespace. + +{{< figure src="/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/configure-gateway-route.png" class="no-border" >}} + +#### Additional Settings + +You can configure additional settings in the **gatewayRoute** section of your OperatorConfiguration. The following section shows an example configuration. Adjust them as needed based on your specific requirements. + +```text +apiVersion: privatecloud.mendix.com/v1alpha1 +kind: OperatorConfiguration +# ... +# omitted lines for brevity +# ... +spec: + # Endpoint (Network) configuration + endpoint: + type: gatewayRoute + gatewayRoute: + # The following parameters are already configured by mxpc-cli + domain: mendix.example.com + enableTLS: true + gatewayParentReference: + group: gateway.networking.k8s.io + kind: Gateway + name: example-gateway + namespace: kube-ingress + # Additional configuration + # Modify response headers + gatewayRouteResponseHeaderModifiers: + # Specify configuration for a Gateway ResponseHeaderModifier + # For more detauls, see https://gateway-api.sigs.k8s.io/guides/user-guides/http-header-modifier/#http-response-header-modifier + add: + # Add the following headers to all requests + "X-response-header-1": "example-value-1" + "X-response-header-2": "example-value-2" + set: + # Set the following headers to in all requests (overwriting existing values if present) + # This is where security headers such as HSTS would typically be specified + "X-response-header-3": "example-value-3" + "X-response-header-4": "example-value-4" + remove: + # Remove the following headers + - "X-response-header-5" + - "X-response-header-6" + # Modify request headers + gatewayRouteRequestHeaderModifiers: + # Specify configuration for a Gateway RequestHeaderModifier + # For more detauls, see https://gateway-api.sigs.k8s.io/guides/user-guides/http-header-modifier/#http-request-header-modifier + add: + # Add the following headers to all requests + "X-request-header-1": "example-value-1" + "X-request-header-2": "example-value-2" + set: + # Set the following headers to in all requests (overwriting existing values if present) + "X-request-header-3": "example-value-3" + "X-request-header-4": "example-value-4" + remove: + # Remove the following headers + - "X-request-header-5" + - "X-request-header-6" +# ... +# omitted lines for brevity +# ... +``` diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-openshift.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-openshift.md index 993f6dab806..a01b4232e46 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-openshift.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-openshift.md @@ -3,7 +3,7 @@ title: "OpenShift Route in Mendix on Kubernetes" linktitle: "OpenShift Route" url: /developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/openshift/ description: "Describes how to configure OpenShift routes for Mendix on Kubernetes." -weight: 20 +weight: 30 --- ## Introduction diff --git a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-services-only.md b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-services-only.md index 45ffa667194..1e16461b619 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-services-only.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-cluster/networking/private-cloud-services-only.md @@ -3,7 +3,7 @@ title: "Service without Ingress in Mendix on Kubernetes" linktitle: "Service Only" url: /developerportal/deploy/private-cloud-cluster/private-cloud-ingress-settings/services-only/ description: "Describes how to configure Mendix on Kubernetes to create services without an Ingress." -weight: 30 +weight: 40 --- ## Introduction diff --git a/content/en/docs/deployment/private-cloud/private-cloud-monitor.md b/content/en/docs/deployment/private-cloud/private-cloud-monitor.md index 9e2554a8ede..453f3e826c4 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-monitor.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-monitor.md @@ -29,15 +29,15 @@ You can customize this solution to match the requirements of your team or organi Mendix Operator v2.4.0 and above offers several modes for collecting and generating metrics. -| Mode | Native | Compatibility | -| ------------------------- | ---------------- | ---------------------- | -| Mendix Operator version | v2.4.0 and above | v2.1.0 and above | -| Supported Mendix versions | 9.7 and above | 7.23 and above | -| Metrics activities | Yes | No | -| Microflow execution times | Yes | No | -| Custom metrics | Yes | No | -| Rigid format | No | Yes | -| Metrics generated by | Mendix Runtime | `m2ee-metrics` sidecar | +| Mode | Native | Compatibility (deprecated) | +| ------------------------- | ---------------- | -------------------------- | +| Mendix Operator version | v2.4.0 and above | v2.1.0 to v2.26.1 | +| Supported Mendix versions | 9.7 and above | 7.23 and above | +| Metrics activities | Yes | No | +| Microflow execution times | Yes | No | +| Custom metrics | Yes | No | +| Rigid format | No | Yes | +| Metrics generated by | Mendix Runtime | `m2ee-metrics` sidecar | Mendix 9.7 and above can generate [Prometheus metrics](/refguide/metrics/) directly in the Runtime, which allows the generation of custom or [app-specific metrics](/refguide/metrics-activities/). Setting the metrics generation of a Mendix on Kubernetes environment to `native` mode will collect Prometheus metrics directly from the Mendix Runtime. @@ -52,6 +52,12 @@ The metrics names and labels generated by the `m2ee-metrics` sidecar are rigid a For backwards compatibility reasons, `native` and `compatibility` metrics use different labels and metrics names. Each mode requires a separate dashboard. +{{% alert color="warning" %}} +Mendix Operator v2.27.0 removed support for `compatibility` metrics. + +If you are planning to upgrade to Mendix Operator v2.27.0 (or a later version), switch environments to `native` mode, and update your dashboards accordingly. +{{% /alert %}} + ## Installing Monitoring Tools{#install-grafana-loki} If you already have installed Prometheus, Loki, and Grafana in your cluster, you can skip this section and go directly to [enable metrics scraping](#enable-metrics-scraping). @@ -391,8 +397,8 @@ The reference dashboards are compatible with Prometheus installed as described i To install the reference dashboard, download the dashboard JSON to a local file using the links below. There are two dashboards available at the moment. If necessary you can install both at the same time: -* [compatibility mode dashboard](https://cdn.mendix.com/mendix-for-private-cloud/grafana-dashboard/mendix_app_dashboard_compatibility-1.1.1.json) for metrics generated in compatibility mode * [native dashboard](https://cdn.mendix.com/mendix-for-private-cloud/grafana-dashboard/mendix_app_dashboard_native-1.2.0.json) for metrics generated in native mode +* (deprecated) [compatibility mode dashboard](https://cdn.mendix.com/mendix-for-private-cloud/grafana-dashboard/mendix_app_dashboard_compatibility-1.1.1.json) for metrics generated in compatibility mode [Import](https://grafana.com/docs/grafana/latest/dashboards/export-import/#import-dashboard) the downloaded JSON into Grafana: @@ -509,15 +515,18 @@ spec: # … ``` -{{% alert color="info" %}}When Mendix Operator v2.4.0 is installed into a new namespace, it will use `native` metrics by default. -However, if Mendix Operator v2.3.\* or below is upgraded to v2.4.0 or above, the upgrade process will set the default metrics mode to `compatibility`. -This way, upgrading an older Mendix Operator will not change the way it generates metrics.{{% /alert %}} +{{% alert color="info" %}}Starting from Mendix Operator v2.27.0, only the `native` mode is supported. +Installing or upgrading to Operator v2.27.0 or a later version will switch the default metrics mode to `native`.{{% /alert %}} -### Compatibility Metrics Mode +{{% alert color="info" %}}This way, upgrading an older Mendix Operator will not change the way it generates metrics.{{% /alert %}} + +### Compatibility Metrics Mode (deprecated) To enable `compatibility` metrics mode, set the `mode` attribute to `compatibility`. In this mode, all other `runtimeMetricsConfiguration` attributes are ignored. +Compatibility mode is removed in Mendix Operator v2.27.0. + #### Enable Compatibility Metrics in Connected Mode 1. Open your app in [Apps](https://sprintr.home.mendix.com/). @@ -632,7 +641,7 @@ It is also possible to add extra tags (Prometheus labels) by specifying them in 1. Open your app in [Apps](https://sprintr.home.mendix.com/). 2. Go to the **Environments** page. -3. Click **Details** next to the environment where compatibility mode should be used. +3. Click **Details** next to the environment where native mode should be used. {{< figure src="/attachments/deployment/private-cloud/private-cloud-monitor/environment-overview.png" class="no-border" >}} @@ -648,7 +657,7 @@ It is also possible to add extra tags (Prometheus labels) by specifying them in {{< figure src="/attachments/deployment/private-cloud/private-cloud-monitor/environment-metrics-default.png" class="no-border" >}} -7. Set **Mode** to **default**, then click **Save**. +7. Set **Mode** to **native**, then click **Save**. {{< figure src="/attachments/deployment/private-cloud/private-cloud-monitor/environment-metrics-mode-native.png" class="no-border" >}} diff --git a/content/en/docs/deployment/private-cloud/private-cloud-operator.md b/content/en/docs/deployment/private-cloud/private-cloud-operator.md index 73b14d43b27..5adadbc6ca2 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-operator.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-operator.md @@ -150,6 +150,7 @@ spec: pinTo: # Optional, list of web services or domain names where this certificate should be used - "www.example.com" - "service.www.example.com" + - certificateSecret: "example-api-secret" # use the example-api-secret Kubernetes secret as a client certificate for TLS authenticaiton # All custom Mendix Runtime parameters go here, in JSON format; validated and applied by the mx-m2ee-sidecar container customConfiguration: |- { @@ -170,6 +171,9 @@ spec: customPodLabels: # Optional: custom pod labels general: # Optional: general pod labels (applied to all app-related pods) azure.workload.identity/use: "true" # Example: enable Azure Workload Identity + customPodNodeSelector: # Optional: custom pod nodeSelector + general: # Optional: general pod nodeSelector (applied to all app-related pods) + eks.amazonaws.com/compute-type: auto # Example: use Amazon EKS Auto Mode runtimeLicenseProduct: # Optional: Specify the type of product required for the Runtime License. This is applicable when PCLM is used for licensing. By default, the value is set to Standard, if left empty deploymentStrategy: # Optional: Specify a deployment strategy to reduce app downtime switchoverThreshold: 50% @@ -235,6 +239,10 @@ You must make the following changes: * **jettyOptions** and **customConfiguration** - If you have any custom Mendix Runtime parameters, you must add them to this section. Otions for the Mendix runtime must be provided in JSON format. See the examples in the CR for the correct format and the information below for more information on [setting app constants](#set-app-constants) and [configuring scheduled events](#configure-scheduled-events). * **environmentVariables** - Set the environment variables for the Mendix app container, and JVM arguments through the `JAVA_TOOL_OPTIONS` environment variable. * **clientCertificates** - Specify client certificates to be used for TLS calls to Web Services and REST services. + + * When **key** and **password** are specified, will use the client TLS certificate specified directly in the **MendixApp** CR. + * When **certificateSecret** is specified without a **key** and **password**, will load a client TLS certificate from the specified Kubernetes Secret. This feature requires Mendix Operator 2.27 or newer. + * **runtimeMetricsConfiguration** - Specify how metrics should be collected. Any non-empty values override the [default values](/developerportal/deploy/private-cloud-cluster/#customize-runtime-metrics) from `OperatorConfiguration`. Refer to [Monitoring Environments in Mendix on Kubernetes](/developerportal/deploy/private-cloud-monitor/) for details on how to monitor your environment. * **runtimeLeaderSelection** - Specify how the leader replica should be selected. The following options are available: * `assigned` (default mode) - The `master` deployment runs one leader replica, while the `worker` deployment runs all additional replicas. @@ -242,6 +250,8 @@ You must make the following changes: * `leaderless` - A mode where the nodes dynamically choose a leader. This feature is in preview mode. It requires Mendix Runtime 10.24 or newer, and Mendix Operator 2.23 or newer. * **customPodLabels** - Specify additional pod labels. Avoid using labels that start with the `privatecloud.mendix.com/` prefix. * **general** - Specify additional labels for all pods of the app. +* **customPodNodeSelector** - Specify the pod `nodeSelector` configuration. + * **general** - Specify `nodeSelector` configuration for all pods of the app. * **deploymentStrategy** - Specify parameters for the deployment strategy. For more information, see the [reduced downtime deployment](/developerportal/deploy/private-cloud-reduced-downtime/#deployment-strategy-in-standalone) documentation. * **podDisruptionBudget** - Specify parameters for the pod disruption budget. For more information, see the [reduced downtime deployment](/developerportal/deploy/private-cloud-reduced-downtime/#pod-disruption-budget-in-standalone) documentation. * **runtimeReadOnlyRootFilesystem** - Specify if the Runtime container should mount the root filesystem in [read-only mode](/developerportal/deploy/private-cloud-cluster/#readonlyrootfs). @@ -299,6 +309,55 @@ spec: The **MyScheduledEvents** value should be removed from **customConfiguration** if **ScheduledEventExecution** is set to `ALL` or `NONE`. +#### Loading Client Certificates from a Kubernetes Secret {#client-cert-from-k8s-secret} + +Instead of providing a client certificate directly in the MendixApp CR, Mendix Operator 2.27.0 (and newer versions) can load the client certificate from an existing Kubernetes secret. + +1. Create a Kubernetes secret with the following contents: + + ```yaml + kind: Secret + apiVersion: v1 + metadata: + # Specify the secret name + name: example-api-secret + annotations: + # Specify that this secret is safe to use as a Mendix app environment client cert + privatecloud.mendix.com/environment-client-cert: 'true' + stringData: + # base64-encoded PKCS12 certificate + key: Q0VSVElGSUNBVEU= + # base64-encoded password for the certificate, cannot be empty + password: Q2hhbmdlLW1lNDI= + # Optional, list of web services or domain names where this certificate should be used + pinTo: "www.example.com,service.www.example.com" + ``` + +2. To allow an application to use the secret, ensure that it has the `privatecloud.mendix.com/environment-client-cert: true` annotation. For security reasons, any secret referenced by a MendixApp CR but without this annotation cannot be attached to environments. + +{{% alert color="info" %}} +This example provides contents of a Kubernetes secret as a `stringData`, and Kubernetes will base64-encode the contents again when viewing the secret contents. + +If you read the secret and see `data` instead of `stringData`, the values of the `key` and `password` fields will be base64-encoded twice. + +This ensures that a binary PKCS12 file can be safely stored and edited as a plaintext string. +{{% /alert %}} + + +```yaml +apiVersion: privatecloud.mendix.com/v1alpha1 +kind: MendixApp +metadata: + name: example-mendixapp +spec: + runtime: + clientCertificates: + # Specify the name of the secret created above + - certificateSecret: "example-api-secret" +``` + +The **MyScheduledEvents** value should be removed from **customConfiguration** if **ScheduledEventExecution** is set to `ALL` or `NONE`. + ### Building and Deploying Your App You now need to supply the CR you have just created to the platform so that the Mendix Operator can use it to build and deploy the app. diff --git a/content/en/docs/deployment/private-cloud/private-cloud-supported-environments.md b/content/en/docs/deployment/private-cloud/private-cloud-supported-environments.md index f4310608221..eb2679e0bae 100644 --- a/content/en/docs/deployment/private-cloud/private-cloud-supported-environments.md +++ b/content/en/docs/deployment/private-cloud/private-cloud-supported-environments.md @@ -36,7 +36,7 @@ If deploying to Red Hat OpenShift, you need to specify that specifically when cr Mendix on Kubernetes Operator `v2.*.*` is the latest version which officially supports: -* Kubernetes versions 1.19 through 1.35 +* Kubernetes versions 1.19 through 1.36 * OpenShift 4.6 through 4.21 {{% alert color="warning" %}} @@ -418,10 +418,39 @@ There are multiple ways of managing TLS certificates: Starting from Mendix Operator v1.11.0, Mendix app environments can use a [Linkerd](https://linkerd.io/) Service Mesh. Linkerd can be used to monitor and re-encrypt HTTP (or HTTPs) traffic between the Ingress Controller and the Pod running a Mendix app. +### Gateway API + +Starting from Mendix Operator v2.27.0, the [Gateway API](https://gateway-api.sigs.k8s.io/) is supported. + +For each environment, the Mendix Operator creates and manages an [HTTPRoute](https://gateway-api.sigs.k8s.io/reference/api-types/httproute/) resource. + +Mendix Operator only uses API features that are defined in the official Gateway API [v1.4 standard](https://gateway-api.sigs.k8s.io/reference/api-spec/1.4/spec/), and does not rely on any other features. + +Any implementation compliant with the Gateway API v1.4 spec should be compatible with HTTPRoute objects created and managed by the Mendix Operator. + +For more information, refer to the documentation of your Gateway API implementation, or check the status on the [Gateway API Implementations list](https://gateway-api.sigs.k8s.io/docs/implementations/list/). + +#### Using the Gateway API + +When using the Gateway API, it is possible to do the following: + +* Enable TLS (use the `https://` schema in app URLs). +* Add service annotations. +* Specify the HTTPRoute [parentRefs](https://gateway-api.sigs.k8s.io/reference/api-spec/1.4/spec/#httproutespec), to specify which Gateway to use. +* Provide a domain name (for example, `mendix.example.com`). +* Configure request and response [HTTPHeaderFilters](https://gateway-api.sigs.k8s.io/reference/api-spec/1.4/spec/#httpheaderfilter). + +For each environment, the URL is automatically generated based on the domain name. For example, if the domain name is set to `mendix.example.com`, the apps will have URLs such as `myapp1-dev.mendix.example.com`, `myapp1-prod.mendix.example.com`, and so on. + +The DNS server should be configured to route all subdomains (the `*` subdomain, for example, `*.mendix.example.com`) to the ingress/load balancer. + +{{% alert color="warning" %}} +HTTPRoute resources do not provide any APIs to manage or set TLS configuration. In the Gateway API resource model, TLS certificates are managed by the *cluster operator* persona, usually through the Gateway resource. This is allows Cluster Operators to manage security policies and settings from a central location. +{{% /alert %}} + ### Service Only -Mendix on Kubernetes can create Services without an Ingress. -In this way, the Ingress objects can be managed separately from Mendix on Kubernetes. +Mendix on Kubernetes can create Services without an Ingress. In this way, the Ingress objects can be managed separately from Mendix on Kubernetes. Mendix on Kubernetes can create Services that are compatible with: diff --git a/content/en/docs/releasenotes/deployment/mendix-for-private-cloud.md b/content/en/docs/releasenotes/deployment/mendix-for-private-cloud.md index 03717d4cf46..69a0f425405 100644 --- a/content/en/docs/releasenotes/deployment/mendix-for-private-cloud.md +++ b/content/en/docs/releasenotes/deployment/mendix-for-private-cloud.md @@ -12,6 +12,22 @@ For information on the current status of deployment to Mendix on Kubernetes and ## 2026 +### June 1, 2026 + +#### Mendix Operator v2.27.0 {#2.27.0} + +* We have added support for the Kubernetes Gateway API. +* We have added an option to load client certificates from Kubernetes secrets created on the cluster side. +* We have added an option to specify default `nodeSelectors` for pods created and managed by the Operator. +* We have added an option to specify default labels for pods created and managed by the Operator. +* We have addressed an issue where enabling OpenTelemetry auto-instrumentation would show a **processing** spinner on the Runtime status. +* We have updated the components to use the latest dependency versions in order to improve security score ratings for container images. +* We have updated the list of supported platforms to include Kubernetes 1.36. + +#### Deprecations + +* We have removed support for the **compatibility** Prometheus metrics mode. Any environments still using **compatibility** metrics should be switched into **native** metrics mode. + ### May 21, 2026 #### License Manager CLI v0.10.10 {#0.10.10} diff --git a/static/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/configure-gateway-route.png b/static/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/configure-gateway-route.png new file mode 100644 index 00000000000..bcb89f21e17 Binary files /dev/null and b/static/attachments/deployment/private-cloud/private-cloud-cluster/private-cloud-networking/configure-gateway-route.png differ