Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cmd/application-load-balancer-controller-manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import (
"sigs.k8s.io/controller-runtime/pkg/healthz"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
metricsserver "sigs.k8s.io/controller-runtime/pkg/metrics/server"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"sigs.k8s.io/controller-runtime/pkg/webhook/admission"
)

var (
Expand Down Expand Up @@ -133,6 +135,20 @@ func main() {
os.Exit(1)
}

decoder := admission.NewDecoder(mgr.GetScheme())
mgr.GetWebhookServer().Register("/validate-ingress", &webhook.Admission{
Handler: &ingress.IngressValidator{
Client: mgr.GetAPIReader(),
Decoder: decoder,
},
})
mgr.GetWebhookServer().Register("/validate-ingressclass", &webhook.Admission{
Handler: &ingress.IngressClassValidator{
Client: mgr.GetAPIReader(),
Decoder: decoder,
},
})

setupLog.Info("starting manager")
if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
setupLog.Error(err, "problem running manager")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ spec:
selector:
matchLabels:
app: stackit-application-load-balancer-controller-manager
networking.gardener.cloud/from-seed: allowed # Allow traffic from seed to shoot for webhook calls
networking.gardener.cloud/to-dns: allowed # Allow traffic to CoreDNS for webhook calls
networking.gardener.cloud/to-apiserver: allowed # Allow traffic to API server for webhook calls
template:
metadata:
labels:
Expand Down Expand Up @@ -43,6 +46,9 @@ spec:
hostPort: 8081
name: probe
protocol: TCP
- containerPort: 9443
name: webhook
protocol: TCP
resources:
limits:
cpu: "0.5"
Expand All @@ -53,7 +59,14 @@ spec:
volumeMounts:
- mountPath: /etc/serviceaccount
name: cloud-secret
- mountPath: /tmp/k8s-webhook-server/serving-certs
name: webhook-cert
readOnly: true
volumes:
- name: cloud-secret
secret:
secretName: stackit-cloud-secret
- name: webhook-cert
secret:
secretName: stackit-application-load-balancer-controller-manager-webhook-cert

Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ resources:
- deployment.yaml
- rbac.yaml
- service.yaml
- validating-webhook.yaml
- validating-webhook-issuer.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,8 @@ spec:
port: 8080
targetPort: metrics
protocol: TCP
- name: webhook
port: 443
targetPort: 9443
protocol: TCP
type: ClusterIP
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: stackit-application-load-balancer-controller-manager
namespace: kube-system
spec:
selfSigned: {}
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: stackit-application-load-balancer-controller-manager-webhook-cert
namespace: kube-system
spec:
dnsNames:
- stackit-application-load-balancer-controller-manager.kube-system.svc
- stackit-application-load-balancer-controller-manager.kube-system.svc.cluster.local
issuerRef:
kind: Issuer
name: stackit-application-load-balancer-controller-manager
secretName: stackit-application-load-balancer-controller-manager-webhook-cert # cert-manager will create this secret
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata:
name: stackit-application-load-balancer-controller-manager
annotations:
cert-manager.io/inject-ca-from: kube-system/stackit-application-load-balancer-controller-manager-webhook-cert
webhooks:
- name: validate-ingress.stackit.cloud
rules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["ingresses"]
scope: "Namespaced"
clientConfig:
service:
namespace: kube-system
name: stackit-application-load-balancer-controller-manager
path: "/validate-ingress"
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 5
- name: validate-ingressclass.stackit.cloud
rules:
- apiGroups: ["networking.k8s.io"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["ingressclasses"]
scope: "Cluster"
clientConfig:
service:
namespace: kube-system
name: stackit-application-load-balancer-controller-manager
path: "/validate-ingressclass"
admissionReviewVersions: ["v1"]
sideEffects: None
timeoutSeconds: 5
10 changes: 9 additions & 1 deletion docs/albcm.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,13 @@ If you need to explicitly prioritize certain rules over others, you can override

Note that this sorting only applies across different Ingress resources. The top-to-bottom sequence of rules and paths defined within a single Ingress YAML is not preserved and is processed non-deterministically. If you need to preserve the exact top-to-bottom order specified in your YAML, you must separate them into distinct Ingress resources and use the priority annotation.

### Network Routing Mode
The network routing mode determines how the ALB forwards external traffic to your applications within the cluster. Specifying this mode is mandatory. If omitted, your resource will be rejected by the validation webhook.

You must set the `alb.stackit.cloud/network-mode` annotation on your IngressClass.

Currently `NodePort` is the only supported mode. The ALB routes traffic to the cluster nodes, which then forward it to your pods. Future releases will introduce direct-to-pod routing as an additional mode. Setting `NodePort` now ensures your current configurations remain backwards compatible when new modes are added.

### WebSockets Support
You can enable WebSocket support for your applications by adding a specific annotation to your Ingress resource. Note that in this initial release, enabling this annotation applies globally to all routing rules defined within that specific Ingress.

Expand Down Expand Up @@ -69,6 +76,7 @@ metadata:

| Annotation | Allowed On | Requirement | Description |
| :--- | :--- | :--- | :--- |
| `alb.stackit.cloud/network-mode` | IngressClass | Mandatory | Routing mode (currently only `NodePort` supported). |
| `alb.stackit.cloud/external-address` | IngressClass | Optional | Uses a specific STACKIT floating IP instead of an ephemeral one. |
| `alb.stackit.cloud/internal` | IngressClass | Optional | If `true`, the ALB is not exposed via a public IP. |
| `alb.stackit.cloud/plan-id` | IngressClass | Optional | Sets the service plan for the ALB. |
Expand All @@ -82,4 +90,4 @@ metadata:
| `alb.stackit.cloud/priority` | Ingress | Optional | Defines the evaluation priority of the Ingress. |
| `alb.stackit.cloud/traget-pool-tls-enabled` | IngressClass, Ingress, Service | Optional | Enables TLS bridging using OS trusted CAs. |
| `alb.stackit.cloud/traget-pool-tls-custom-ca` | IngressClass, Ingress, Service | Optional | Enables TLS bridging with a custom CA. |
| `alb.stackit.cloud/traget-pool-tls-skip-certificate-validation`| IngressClass, Ingress, Service | Optional | Enables TLS bridging but skips certificate validation. |
| `alb.stackit.cloud/traget-pool-tls-skip-certificate-validation`| IngressClass, Ingress, Service | Optional | Enables TLS bridging but skips certificate validation. |
4 changes: 4 additions & 0 deletions pkg/alb/ingress/annotations.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ const (
// AnnotationPlanID sets the plan for the ALB.
// Can be set on IngressClass.
AnnotationPlanID = "alb.stackit.cloud/plan-id"
// AnnotationNetworkMode specifies the network routing mode.
// It currently validates the presence of "NodePort" to ensure backward compatibility for future direct-to-pod routing.
// Can be set on IngressClass.
AnnotationNetworkMode = "alb.stackit.cloud/network-mode"

// AnnotationTargetPoolTLSEnabled If true, the application load balancer enables TLS bridging.
// It uses the trusted CAs from the operating system for validation.
Expand Down
Loading