The module lifecycle stage: Preview
The module has requirements for installation
This section provides examples of the traffic-ingress infrastructure configuration for the alb module in different environments. The infrastructure is defined by ClusterALBInstance (cluster-scoped) and ALBInstance (namespaced) objects, while the way traffic is accepted is set by the spec.inlet.type parameter.
The module supports three inlet types:
LoadBalancer— traffic is accepted through a Service object of theLoadBalancertype (cloud providers or bare metal with MetalLB). Available for both ClusterALBInstance and ALBInstance.ClusterIP— traffic is accepted through a cluster-internal Service. Available for ALBInstance only.HostPort— traffic is accepted on node ports without an external load balancer. Available for ClusterALBInstance only.
Examples of publishing applications and configuring routes are provided in the “User guide”, and gateway management and diagnostics are covered in the “Administrator guide”.
Example for a cloud provider (LoadBalancer inlet)
In cloud clusters, traffic is usually accepted through the LoadBalancer inlet: the platform creates a Service object of the LoadBalancer type, and the cloud provider assigns an external address to it.
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: main
spec:
gatewayName: public-gw
inlet:
type: LoadBalancer
loadBalancer: {}To configure the cloud load balancer, specify the required Service annotations in the spec.inlet.loadBalancer.serviceAnnotations parameter. For example, for a Network Load Balancer in AWS:
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: main
spec:
gatewayName: public-gw
inlet:
type: LoadBalancer
loadBalancer:
serviceAnnotations:
service.beta.kubernetes.io/aws-load-balancer-type: "nlb"Example for bare metal with the MetalLB load balancer
If there is no external cloud load balancer, you can use the metallb module for the LoadBalancer inlet.
-
Enable the
metallbmodule:apiVersion: deckhouse.io/v1alpha1 kind: ModuleConfig metadata: name: metallb spec: enabled: true version: 2 -
Create a MetalLoadBalancerClass object with an address pool. Place the MetalLB balancers on the same nodes as the Envoy Proxy pods of the
albmodule (in typical scenarios, frontend nodes labelednode-role.deckhouse.io/frontendare used for this):apiVersion: network.deckhouse.io/v1alpha1 kind: MetalLoadBalancerClass metadata: name: alb spec: addressPool: - 192.168.2.100-192.168.2.150 isDefault: false nodeSelector: node-role.deckhouse.io/frontend: "" type: L2 -
Create a ClusterALBInstance object, specifying the created load balancer class in the
spec.inlet.loadBalancer.loadBalancerClassparameter:apiVersion: network.deckhouse.io/v1alpha1 kind: ClusterALBInstance metadata: name: main spec: gatewayName: public-gw inlet: type: LoadBalancer loadBalancer: loadBalancerClass: alb serviceAnnotations: # Number of addresses allocated from the pool declared in MetalLoadBalancerClass. network.deckhouse.io/l2-load-balancer-external-ips-count: "1"
Example for bare metal without an external load balancer (HostPort inlet)
If no external load balancer is used and traffic must be accepted directly on node ports, use the HostPort inlet. This inlet type is available for ClusterALBInstance only.
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: main
spec:
gatewayName: public-gw
inlet:
type: HostPort
hostPort:
httpPort: 80
httpsPort: 443To place the Envoy Proxy pods of the alb module only on dedicated nodes, set the nodeSelector and tolerations parameters for the ClusterALBInstance.
Accepting traffic behind an external L7 balancer (Proxy Protocol)
If the alb module runs behind an external L7 balancer (for example, Cloudflare, Qrator, or a third-party balancer), enable Proxy Protocol to receive the real client addresses. Additionally, use the spec.originalIPDetection parameter to restrict the list of subnets that are allowed to provide headers with the client address.
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: main
spec:
gatewayName: public-gw
inlet:
type: HostPort
hostPort:
httpPort: 80
httpsPort: 443
useProxyProtocol: true
originalIPDetection:
setRealIPFrom:
- 10.0.0.0/16Proxy Protocol and HTTP/3 cannot be enabled at the same time.
Separating public and administrative zones
If public and administrative traffic must be separated, create a dedicated Gateway object for each zone and restrict the acceptance of administrative traffic with the spec.acceptRequestsFrom parameter. The decision to allow a connection is made by the real connection address, not by the request headers.
The public gateway accepts traffic from anywhere:
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: public
spec:
gatewayName: public-gw
inlet:
type: LoadBalancer
loadBalancer: {}The administrative gateway accepts traffic only from trusted subnets:
apiVersion: network.deckhouse.io/v1alpha1
kind: ClusterALBInstance
metadata:
name: admin
spec:
gatewayName: admin-gw
inlet:
type: LoadBalancer
loadBalancer: {}
acceptRequestsFrom:
- 1.2.3.4/32
- 10.0.0.0/16Then create separate ListenerSet objects and routes for each gateway, attaching administrative applications to the admin-gw Gateway object and public ones to public-gw. Examples of creating routes are provided in “GRPCRoute, TLSRoute, TCPRoute, and UDPRoute objects”.
Using cert-manager to issue TLS certificates
The alb module terminates TLS on ListenerSet listeners, each of which references a Secret of the kubernetes.io/tls type in the tls.certificateRefs parameter. The cert-manager module can create such Secrets automatically.
Gateway API integration in cert-manager is enabled automatically, since the alb module installs the Gateway API CRDs in the cluster. Issuing certificates with ListenerSet annotations also requires ListenerSet support, which is disabled by default. Enable it with the enableListenerSet parameter of the cert-manager module:
apiVersion: deckhouse.io/v1alpha1
kind: ModuleConfig
metadata:
name: cert-manager
spec:
enabled: true
version: 1
settings:
enableListenerSet: trueAfter changing the enableListenerSet parameter, wait for the cert-manager pods to restart.
Issuing a certificate using ListenerSet annotations
This method requires ListenerSet support in cert-manager (the enableListenerSet parameter). The alb module manages the Gateway object, so certificate annotations are set on the ListenerSet objects created by the application team. Add the cert-manager.io/cluster-issuer or cert-manager.io/issuer annotation to the ListenerSet object and specify the name of the Secret to be created in tls.certificateRefs:
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: app-listeners
namespace: prod
annotations:
cert-manager.io/cluster-issuer: letsencrypt-alb
acme.cert-manager.io/http01-parentreffallback: "true"
spec:
parentRef:
name: public-gw
namespace: d8-alb
listeners:
- name: app-https
port: 443
protocol: HTTPS
hostname: app.example.com
tls:
mode: Terminate
certificateRefs:
- name: app-tls
namespace: prodwhere:
cert-manager.io/cluster-issuer— name of an existing ClusterIssuer (an example is provided in Issuing a certificate using an Issuer and a Certificate). To use a namespaced Issuer, replace the annotation withcert-manager.io/issuerand create the Issuer in the same namespace as the ListenerSet;acme.cert-manager.io/http01-parentreffallback— use the HTTP listener of the parent Gateway (d8-http-default) for ACME HTTP-01 challenges instead of creating a temporary listener in the ListenerSet. Required for HTTP-01 solvers when the ListenerSet has no HTTP listener;app-tls— name of the Secret that cert-manager will create and that thealbmodule will use for the listener.
cert-manager creates a Certificate named after the Secret and fills its dnsNames with the listener hostname values. A listener is processed only if hostname is set, tls.mode is Terminate, and tls.certificateRefs references a Secret in the same namespace as the ListenerSet. If an ACME HTTP-01 solver is used, the domain must resolve to the Gateway; see How do I add a custom HTTP-01 ClusterIssuer or Issuer for ALB?.
Issuing a certificate using an Issuer and a Certificate
If certificates are managed separately from ListenerSets, create an Issuer or ClusterIssuer and a Certificate object, then reference the resulting Secret in the ListenerSet. Example for a ClusterIssuer with an HTTP-01 solver:
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-alb
spec:
acme:
server: https://acme-v02.api.letsencrypt.org/directory
email: <EMAIL>
privateKeySecretRef:
name: letsencrypt-alb-account-key
solvers:
- http01:
gatewayHTTPRoute:
parentRefs:
- group: gateway.networking.k8s.io
kind: Gateway
name: public-gw
namespace: d8-alb
sectionName: d8-http-default
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: app-tls
namespace: prod
spec:
secretName: app-tls
issuerRef:
kind: ClusterIssuer
name: letsencrypt-alb
dnsNames:
- app.example.comwhere:
<EMAIL>— email address for the ACME account;app-tls— name of the Secret where the issued certificate is stored.
Reference the issued Secret in the ListenerSet:
apiVersion: gateway.networking.k8s.io/v1
kind: ListenerSet
metadata:
name: app-listeners
namespace: prod
spec:
parentRef:
name: public-gw
namespace: d8-alb
listeners:
- name: app-https
port: 443
protocol: HTTPS
hostname: app.example.com
tls:
mode: Terminate
certificateRefs:
- name: app-tls
namespace: prodThe issued Secret is created in the namespace of the Certificate. Place the Certificate in the same namespace as the ListenerSet; if the Secret is in another namespace, create a ReferenceGrant object that allows the ListenerSet to reference it.
Publishing within a namespace (LoadBalancer inlet via ALBInstance)
If the traffic-ingress infrastructure is managed by the application team within its own namespace, use the ALBInstance object. It supports the LoadBalancer and ClusterIP inlets, and the Gateway, ListenerSet, and route objects are located in the same namespace.
apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
name: app-gw
namespace: prod
spec:
gatewayName: app-gw
inlet:
type: LoadBalancer
loadBalancer: {}To accept traffic through a cluster-internal Service instead of an external load balancer, use the ClusterIP inlet:
apiVersion: network.deckhouse.io/v1alpha1
kind: ALBInstance
metadata:
name: app-gw
namespace: prod
spec:
gatewayName: app-gw
inlet:
type: ClusterIP
clusterIP: {}Once the ALBInstance object reaches the Ready state, create ListenerSet and HTTPRoute objects in the same namespace. A complete example is provided in the “Publishing an application through an ALBInstance object” section of the user guide.