Skip to content

Commit 224dfa3

Browse files
committed
fix indenting
Signed-off-by: Karol Szwaj <karol.szwaj@gmail.com> On-behalf-of: @SAP karol.szwaj@sap.com
1 parent 7c9393c commit 224dfa3

1 file changed

Lines changed: 129 additions & 100 deletions

File tree

  • docs/content/usage/integrations

docs/content/usage/integrations/kro.md

Lines changed: 129 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -7,31 +7,48 @@ weight: 30
77

88
# kro Integration (providing LoadBalancer as a Service)
99

10-
This guide demonstrates how to use [kro](https://kro.run/) and [Envoy Gateway](https://gateway.envoyproxy.io/) to offer a "LoadBalancer as a Service" API in multi-cluster environments.
11-
12-
When operating multiple clusters on-premises, managing load balancer infrastructure separately for each cluster becomes operationally expensive. This integration enables a centralized load balancer cluster that serves all tenant clusters connected via converged networking solutions. By running load balancer resources in a dedicated load balancer cluster, organizations can simplify operations for application teams who can self-service load balancers without managing the underlying infrastructure and enforce consistent security policies and configuration across gateways.
10+
This guide demonstrates how to use [kro](https://kro.run/) and
11+
[Envoy Gateway](https://gateway.envoyproxy.io/) to offer a "LoadBalancer as a Service" API in
12+
multi-cluster environments.
13+
14+
When operating multiple clusters on-premises, managing load balancer infrastructure separately
15+
for each cluster becomes operationally expensive. This integration enables a centralized load
16+
balancer cluster that serves all tenant clusters connected via converged networking solutions.
17+
By running load balancer resources in a dedicated load balancer cluster, organizations can simplify
18+
operations for application teams who can self-service load balancers without managing the
19+
underlying infrastructure and enforce consistent security policies and configuration across
20+
gateways.
1321

1422
![kro gateway-api example architecture diagram](kro-gw-api.png)
1523

16-
In this guide in the consumer cluster we create a simple `LoadBalancer` object, and the provider automatically provisions an Envoy Gateway infrastructure and related `Gateway` and `HTTPRoute` to expose the service between two kind clusters.
24+
In this guide in the consumer cluster we create a simple `LoadBalancer` object, and the provider
25+
automatically provisions an Envoy Gateway infrastructure and related `Gateway` and `HTTPRoute` to
26+
expose the service between two kind clusters.
1727

18-
This example includes support for syncing **custom configuration (via ConfigMaps or Secrets)** from consumer clusters to the provider.
28+
This example includes support for syncing **custom configuration (via ConfigMaps or Secrets)** from
29+
consumer clusters to the provider.
1930

2031
!!! note
21-
For this to work end-to-end, the consumer's service (`backend`) must be reachable from the provider cluster (e.g., via multi-cluster networking).
32+
For this to work end-to-end, the consumer's service (`backend`) must be reachable from the
33+
provider cluster (e.g., via multi-cluster networking).
2234

23-
In this example, we simulate multi-cluster networking by exposing the consumer's backend service via NodePort and creating corresponding Service/EndpointSlice in the provider cluster. In production, you would use proper multi-cluster networking solutions like Submariner or Cilium cluster mesh.
35+
In this example, we simulate multi-cluster networking by exposing the consumer's backend
36+
service via NodePort and creating corresponding Service/EndpointSlice in the provider cluster.
37+
In production, you would use proper multi-cluster networking solutions like Submariner or
38+
Cilium cluster mesh.
2439

2540
## Prerequisites
2641

27-
In this integration guide, we will be using `kubectl bind dev` command to provision two kind clusters. More details on the command you can find [here](../../developers/dev-environments.md).
42+
In this integration guide, we will be using `kubectl bind dev` command to provision two kind
43+
clusters. More details on the command you can find [here](../../developers/dev-environments.md).
2844

2945
* **Provider Cluster:** Runs kro, Envoy Gateway, and the kube-bind backend.
3046
* **Consumer Cluster:** Runs the kube-bind konnector.
3147

3248
## Setup On The Provider Cluster
3349

34-
The following sections will guide you through the one-time setup that is required for providing LoadBalancer as a Service using kro and kube-bind.
50+
The following sections will guide you through the one-time setup that is required for providing
51+
LoadBalancer as a Service using kro and kube-bind.
3552

3653
### Install Envoy Gateway
3754

@@ -88,14 +105,14 @@ metadata:
88105
kubernetes.io/service-name: backend
89106
addressType: IPv4
90107
ports:
91-
- name: http
92-
port: 30080
93-
protocol: TCP
108+
- name: http
109+
port: 30080
110+
protocol: TCP
94111
endpoints:
95-
- addresses:
96-
- ${CONSUMER_NODE_IP}
97-
conditions:
98-
ready: true
112+
- addresses:
113+
- ${CONSUMER_NODE_IP}
114+
conditions:
115+
ready: true
99116
EOF
100117
```
101118

@@ -105,14 +122,15 @@ kro allows you to define custom APIs (`ResourceGraphDefinition`) and map them to
105122

106123
```bash
107124
helm install kro oci://registry.k8s.io/kro/charts/kro \
108-
--namespace kro-system \
109-
--create-namespace
125+
--namespace kro-system \
126+
--create-namespace
110127
```
111128

112129
### Define the LoadBalancer ResourceGroup
113130

114131
Create a kro `ResourceGraphDefinition` that defines the API `loadbalancers.networking.kro.run`.
115-
This definition includes referencing a `ConfigMap` for custom routing rules (e.g., adding headers). The same way user could reference a `Secret` with `Certificate` to setup TLS.
132+
This definition includes referencing a `ConfigMap` for custom routing rules (e.g., adding headers).
133+
The same way user could reference a `Secret` with `Certificate` to setup TLS.
116134

117135
```yaml
118136
kubectl apply -f - <<'EOF'
@@ -134,65 +152,65 @@ spec:
134152
status:
135153
address: string
136154
resources:
137-
- id: configmap
138-
externalRef:
139-
apiVersion: v1
140-
kind: ConfigMap
141-
metadata:
142-
name: ${schema.spec.configMapRef}
143-
namespace: ${schema.metadata.namespace}
144-
- id: referencegrant
145-
template:
146-
apiVersion: gateway.networking.k8s.io/v1beta1
147-
kind: ReferenceGrant
148-
metadata:
149-
name: ${schema.metadata.name}-grant
150-
namespace: ${schema.spec.targetServiceNamespace}
151-
spec:
152-
from:
153-
- group: gateway.networking.k8s.io
154-
kind: HTTPRoute
155-
namespace: ${schema.metadata.namespace}
156-
to:
157-
- group: ""
158-
kind: Service
159-
- id: gateway
160-
template:
161-
apiVersion: gateway.networking.k8s.io/v1
162-
kind: Gateway
163-
metadata:
164-
name: ${schema.metadata.name}-gw
165-
namespace: ${schema.metadata.namespace}
166-
spec:
167-
gatewayClassName: eg
168-
listeners:
169-
- name: http
170-
port: 80
171-
protocol: HTTP
172-
hostname: ${schema.spec.domain}
173-
- id: route
174-
template:
175-
apiVersion: gateway.networking.k8s.io/v1
176-
kind: HTTPRoute
177-
metadata:
178-
name: ${schema.metadata.name}-route
179-
namespace: ${schema.metadata.namespace}
180-
spec:
181-
parentRefs:
182-
- name: ${schema.metadata.name}-gw
183-
hostnames:
184-
- ${schema.spec.domain}
185-
rules:
186-
- backendRefs:
187-
- name: ${schema.spec.targetService}
188-
namespace: ${schema.spec.targetServiceNamespace}
189-
port: ${schema.spec.targetPort}
190-
filters:
191-
- type: RequestHeaderModifier
192-
requestHeaderModifier:
193-
add:
194-
- name: X-Custom-Message
195-
value: ${configmap.?data["custom-header"]}
155+
- id: configmap
156+
externalRef:
157+
apiVersion: v1
158+
kind: ConfigMap
159+
metadata:
160+
name: ${schema.spec.configMapRef}
161+
namespace: ${schema.metadata.namespace}
162+
- id: referencegrant
163+
template:
164+
apiVersion: gateway.networking.k8s.io/v1beta1
165+
kind: ReferenceGrant
166+
metadata:
167+
name: ${schema.metadata.name}-grant
168+
namespace: ${schema.spec.targetServiceNamespace}
169+
spec:
170+
from:
171+
- group: gateway.networking.k8s.io
172+
kind: HTTPRoute
173+
namespace: ${schema.metadata.namespace}
174+
to:
175+
- group: ""
176+
kind: Service
177+
- id: gateway
178+
template:
179+
apiVersion: gateway.networking.k8s.io/v1
180+
kind: Gateway
181+
metadata:
182+
name: ${schema.metadata.name}-gw
183+
namespace: ${schema.metadata.namespace}
184+
spec:
185+
gatewayClassName: eg
186+
listeners:
187+
- name: http
188+
port: 80
189+
protocol: HTTP
190+
hostname: ${schema.spec.domain}
191+
- id: route
192+
template:
193+
apiVersion: gateway.networking.k8s.io/v1
194+
kind: HTTPRoute
195+
metadata:
196+
name: ${schema.metadata.name}-route
197+
namespace: ${schema.metadata.namespace}
198+
spec:
199+
parentRefs:
200+
- name: ${schema.metadata.name}-gw
201+
hostnames:
202+
- ${schema.spec.domain}
203+
rules:
204+
- backendRefs:
205+
- name: ${schema.spec.targetService}
206+
namespace: ${schema.spec.targetServiceNamespace}
207+
port: ${schema.spec.targetPort}
208+
filters:
209+
- type: RequestHeaderModifier
210+
requestHeaderModifier:
211+
add:
212+
- name: X-Custom-Message
213+
value: ${configmap.?data["custom-header"]}
196214
EOF
197215
```
198216

@@ -206,7 +224,8 @@ kubectl label crd loadbalancers.networking.kro.run kube-bind.io/exported=true --
206224

207225
### Export the LoadBalancer API
208226

209-
Create an `APIServiceExportTemplate`. Crucially, we add **PermissionClaims** to allow the provider to read the `ConfigMaps` that the consumer will create and reference.
227+
Create an `APIServiceExportTemplate`. Crucially, we add **PermissionClaims** to allow the provider
228+
to read the ConfigMaps that the consumer will create and reference.
210229

211230
```yaml
212231
kubectl apply -f - <<EOF
@@ -225,22 +244,25 @@ spec:
225244
resource: configmaps
226245
selector:
227246
references:
228-
- resource: loadbalancers
229-
group: networking.kro.run
230-
jsonPath:
231-
name: 'spec.configMapRef'
247+
- resource: loadbalancers
248+
group: networking.kro.run
249+
jsonPath:
250+
name: 'spec.configMapRef'
232251
scope: Namespaced
233252
EOF
234253
```
235254

236255
## Setup on the Consumer Cluster
237256

238-
Now that everything is set up, users can begin to bind to your backend and begin consuming the new API.
257+
Now that everything is set up, users can begin to bind to your backend and begin consuming the
258+
new API.
239259

240260
### Login to kube-bind
241261

242262
!!! note
243-
When you run `kubectl bind dev create`, **save the output** as it contains important information (like cluster IPs and configuration) that will be needed throughout this guide. This output is unique for each user and environment.
263+
When you run `kubectl bind dev create`, **save the output** as it contains important
264+
information (like cluster IPs and configuration) that will be needed throughout this guide.
265+
This output is unique for each user and environment.
244266

245267
```bash
246268
kubectl bind login http://kube-bind.dev.local:8080
@@ -250,7 +272,8 @@ kubectl bind --konnector-host-alias 172.18.0.3:kube-bind.dev.local
250272

251273
### Wait for the Binding to be Established
252274

253-
Once the binding is active, you can create `LoadBalancer` resources in your consumer cluster, and you will get `LoadBalancer` objects synced from the provider cluster.
275+
Once the binding is active, you can create `LoadBalancer` resources in your consumer cluster, and
276+
you will get `LoadBalancer` objects synced from the provider cluster.
254277

255278
```bash
256279
kubectl bind
@@ -277,10 +300,10 @@ kubectl apply -f - <<EOF
277300
apiVersion: v1
278301
kind: ConfigMap
279302
metadata:
280-
name: my-lb-config
281-
namespace: default
303+
name: my-lb-config
304+
namespace: default
282305
data:
283-
custom-header: "hello-kube-bind"
306+
custom-header: "hello-kube-bind"
284307
EOF
285308
```
286309

@@ -354,20 +377,21 @@ kubectl apply -f - <<EOF
354377
apiVersion: networking.kro.run/v1alpha1
355378
kind: LoadBalancer
356379
metadata:
357-
name: my-lb
358-
namespace: default
380+
name: my-lb
381+
namespace: default
359382
spec:
360-
domain: "www.example.com"
361-
configMapRef: "my-lb-config"
362-
targetService: "backend"
363-
targetServiceNamespace: "default"
364-
targetPort: 30080
383+
domain: "www.example.com"
384+
configMapRef: "my-lb-config"
385+
targetService: "backend"
386+
targetServiceNamespace: "default"
387+
targetPort: 30080
365388
EOF
366389
```
367390

368391
### Observe the Provisioning
369392

370-
**Provider Side:** kube-bind syncs the `ConfigMap` back to the provider namespace. kro creates the `Gateway`, `HTTPRoute` and `ReferenceGrant`, and Envoy Gateway provisions the load balancer.
393+
**Provider Side:** kube-bind syncs the ConfigMap back to the provider namespace. kro creates the
394+
Gateway, Route and ReferenceGrant, and Envoy Gateway provisions the load balancer.
371395

372396
**Consumer Side:** The status is updated with the provider status.
373397

@@ -405,12 +429,17 @@ my-lb-config 1 15s
405429

406430
## Appendix
407431

408-
Test the connection with provisioned load balancer and verify that `hello-kube-bind` header was added from the `ConfigMap`.
432+
Test the connection with provisioned load balancer and verify that `hello-kube-bind` header was
433+
added from the ConfigMap.
409434

410435
!!! note
411-
For the basic check in this example, we will do port-forward. To be able to use `LoadBalancer` service IP in the kind cluster you would need to setup additional measures like [metalb](https://github.com/metallb/metallb) or [cloud-provider-kind](https://github.com/kubernetes-sigs/cloud-provider-kind).
436+
For the basic check in this example, we will do port-forward. To be able to use LoadBalancer
437+
service IP in the kind cluster you would need to setup additional measures like
438+
[metalb](https://github.com/metallb/metallb) or
439+
[cloud-provider-kind](https://github.com/kubernetes-sigs/cloud-provider-kind).
412440

413-
On the provider cluster list the Envoy services and find corresponding service name for the gateway.
441+
On the provider cluster list the Envoy services and find corresponding service name for the
442+
gateway.
414443

415444
```bash
416445
kubectl get services -n envoy-gateway-system

0 commit comments

Comments
 (0)