Skip to content

Commit 853657a

Browse files
authored
Added documentation on EKS and KEDA (#232)
1 parent 054b8a9 commit 853657a

File tree

4 files changed

+270
-9
lines changed

4 files changed

+270
-9
lines changed

docs/user-guide/cookbooks/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
- [x] [Start/Stop EC2/RDS instances using schedule or manual endpoint](./schedule-start-stop-ec2.md)
55
- [x] [Calculate VPC subnet CIDRs](./VPC-subnet-calculator.md)
66
- [x] [Kubernetes in different stages](./k8s.md)
7+
- [x] [KEDA: Kubernetes autoscaling](./k8s.keda.md)
78
- [x] [Encrypting/decrypting files with SOPS+KMS](./sops-kms.md)
89
- [x] [Enable/Disable nat gateway](./enable-nat-gateway.md)
910
- [x] [ArgoCD add external cluster](./argocd-external-cluster.md)

docs/user-guide/cookbooks/k8s.keda.md

Lines changed: 202 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,202 @@
1+
# K8s pod autoscaling with KEDA
2+
3+
Kubernetes, a powerful container orchestration platform, revolutionized the way applications are deployed and managed. However, scaling applications to meet fluctuating workloads can be a complex task. KEDA, a Kubernetes-based Event-Driven Autoscaler, provides a simple yet effective solution to automatically scale Kubernetes Pods based on various metrics, including resource utilization, custom metrics, and external events.
4+
5+
## Goal
6+
7+
To install and configure KEDA on an EKS Cluster created on the [**binbash Leverage**](https://leverage.binbash.co/) way.
8+
9+
!!! Note
10+
To read more on how to create the EKS Cluster on the [**binbash Leverage**](https://leverage.binbash.co/) way, read [here](./k8s.md).
11+
12+
**Note** for the following example we will be using a Kedacore plugin called [http-add-on](https://github.com/kedacore/http-add-on/).
13+
14+
!!! Note
15+
To lear more about KEDA read [the official site](https://keda.sh/docs/2.15/).
16+
17+
![KEDA](https://keda.sh/img/logos/keda-icon-color.png)
18+
19+
### Assumptions
20+
21+
We are assuming the [**binbash Leverage**](https://leverage.binbash.co/) [Landing Zone](https://leverage.binbash.co/try-leverage/) is deployed, an account called `apps-devstg` was created and region `us-east-1` is being used. In any case you can adapt these examples to other scenarios.
22+
23+
---
24+
25+
---
26+
27+
## Installation
28+
29+
To install KEDA, just enable it in the components layer [here](https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks/k8s-components).
30+
31+
Note `enable_keda` has to be enabled and, for the next example, also enable `enable_keda_http_add_on`.
32+
33+
To read more on how to enable components see [here](./k8s.md#eks).
34+
35+
## Giving it a try!
36+
37+
Now, let's create an example so we can show how KEDA Works
38+
39+
We will deploy a simple NGINX server.
40+
41+
These are the manifests for NGINX.
42+
43+
Let's create a namespace:
44+
45+
```yaml
46+
apiVersion: v1
47+
kind: Namespace
48+
metadata:
49+
name: demoapps
50+
labels:
51+
name: demoapps
52+
```
53+
54+
This is the `nginx.yaml`:
55+
56+
```yaml
57+
apiVersion: apps/v1
58+
kind: Deployment
59+
metadata:
60+
name: nginx-deployment
61+
namespace: demoapps
62+
labels:
63+
app: nginx
64+
spec:
65+
replicas: 1
66+
selector:
67+
matchLabels:
68+
app: nginx
69+
template:
70+
metadata:
71+
labels:
72+
app: nginx
73+
spec:
74+
containers:
75+
- name: nginx-container
76+
image: nginx:latest
77+
```
78+
79+
And this is the `service.yaml`:
80+
81+
```yaml
82+
apiVersion: v1
83+
kind: Service
84+
metadata:
85+
name: nginx-svc
86+
namespace: demoapps
87+
spec:
88+
type: NodePort
89+
selector:
90+
app: nginx
91+
ports:
92+
- protocol: TCP
93+
port: 80
94+
targetPort: 80
95+
```
96+
97+
Deploy the resources using `kubectl`.
98+
99+
!!! Info
100+
Note you can use `kubectl` through [**binbash Leverage**](https://leverage.binbash.co/), for more info read [here](../../leverage-cli/reference/kubectl/).
101+
102+
These are the deployed resources:
103+
104+
```shell
105+
NAME READY STATUS RESTARTS AGE
106+
pod/nginx-deployment-5bb85d69d8-g997n 1/1 Running 0 55s
107+
108+
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
109+
service/nginx-svc NodePort 10.100.222.129 <none> 80:30414/TCP 54s
110+
111+
NAME READY UP-TO-DATE AVAILABLE AGE
112+
deployment.apps/nginx-deployment 1/1 1 1 56s
113+
114+
NAME DESIRED CURRENT READY AGE
115+
replicaset.apps/nginx-deployment-5bb85d69d8 1 1 1 56s
116+
```
117+
118+
To try it, create a port-forward to the service and hit it from your browser.
119+
120+
```shell
121+
kubectl port-forward -n demoapps svc/nginx-svc 8080:80
122+
```
123+
124+
Try it!
125+
126+
```shell
127+
curl localhost:8080
128+
```
129+
130+
Now, it has no horizontal autoscaling tool (HPA), so it won't scale. I.e. it always will have one pod (as per the manifests).
131+
132+
Let's create then a KEDA autoscaler!
133+
134+
This is the manifest:
135+
136+
```yaml
137+
apiVersion: http.keda.sh/v1alpha1
138+
kind: HTTPScaledObject
139+
metadata:
140+
name: nginx-scaledobject
141+
namespace: demoapps
142+
spec:
143+
hosts:
144+
- "thehostname.internal"
145+
targetPendingRequests: 100
146+
scaleTargetRef:
147+
deployment: nginx-deployment
148+
service: nginx-svc
149+
port: 80
150+
replicas:
151+
min: 0
152+
max: 10
153+
```
154+
155+
It can be seen an HPA and a custom resource were created:
156+
157+
158+
```shell
159+
NAME REFERENCE TARGETS MINPODS MAXPODS REPLICAS AGE
160+
horizontalpodautoscaler.autoscaling/keda-hpa-nginx-scaledobject Deployment/nginx-deployment <unknown>/100 (avg) 1 10 0 15s
161+
162+
NAME TARGETWORKLOAD TARGETSERVICE MINREPLICAS MAXREPLICAS AGE ACTIVE
163+
nginx-scaledobject apps/v1/Deployment/nginx-deployment nginx-svc:80 0 10 52s
164+
```
165+
166+
Note in the HPA no replicas are in place, i.e. no pods for our app. Now if you try:
167+
168+
```shell
169+
kubectl port-forward -n demoapps svc/nginx-svc 8080:80
170+
```
171+
172+
...it will fail, since no pod are available to answer the service.
173+
174+
Instead we have to hit a KEDA intercepter, that will route the traffic using the Hosts in the `HTTPScaledObject` object.
175+
176+
We've set `thehostname.internal` as the name, so let's port-forward the intercepter...
177+
178+
```shell
179+
kubectl port-forward -n keda svc/keda-add-ons-http-interceptor-proxy 8080:8080
180+
```
181+
182+
...and hit it with the Host header set:
183+
184+
```shell
185+
curl localhost:8080 -H "Host: thehostname.internal"
186+
```
187+
188+
If you check the HPA now it will have at least one replica.
189+
190+
!!! Note
191+
Note the first query will have a delay since the pod has to be created.
192+
193+
Then if you cancel the port-forward and wait for a while, the deployment will be scaled-down to zero again.
194+
195+
Voilà!
196+
197+
!!! Note
198+
There are other ways to configure KEDA, e.g. using Prometheus metrics, read more [here](https://keda.sh/docs/2.15/concepts/).
199+
200+
## Final thoughts
201+
202+
Given the scale-to-zero feature for pods, KEDA is a great match to Karpenter!

docs/user-guide/cookbooks/k8s.md

Lines changed: 66 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,7 @@ See also [here](/user-guide/ref-architecture-eks/overview/).
265265

266266
### Goal
267267

268-
A cluster with one node (worker) and the control plane managed by AWS is deployed here.
268+
A cluster with one node (worker) per AZ and the control plane managed by AWS is deployed here.
269269

270270
Cluster autoscaler is used to create more nodes.
271271

@@ -275,26 +275,83 @@ These are the steps:
275275

276276
- 0 - copy the [K8s EKS layer](https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks) to your [**binbash Leverage**](https://leverage.binbash.co/) project.
277277
- paste the layer under the `apps-devstg/us-east-1` account/region directory
278-
- 1 - apply layers
279-
- 2 - access the cluster
278+
- 1 - create the network
279+
- 2 - Add path to the VPN Server
280+
- 3 - create the cluster and dependencies/components
281+
- 4 - access the cluster
280282

281283
---
282284

283285
#### 0 - Copy the layer
284286

285-
A few methods can be used to download the [KOPS layer](https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks) directory into the [**binbash Leverage**](https://leverage.binbash.co/) project.
287+
A few methods can be used to download the [K8s EKS layer](https://github.com/binbashar/le-tf-infra-aws/tree/master/apps-devstg/us-east-1/k8s-eks) directory into the [**binbash Leverage**](https://leverage.binbash.co/) project.
286288

287289
E.g. [this addon](https://addons.mozilla.org/en-US/firefox/addon/gitzip/?utm_source=addons.mozilla.org&utm_medium=referral&utm_content=search) is a nice way to do it.
288290

289-
Paste this layer into the account/region chosen to host this, e.g. `apps-devstg/us-east-1/`, so the final layer is `apps-devstg/us-east-1/k8s-eks/`.
291+
Paste this layer into the account/region chosen to host this, e.g. `apps-devstg/us-east-1/`, so the final layer is `apps-devstg/us-east-1/k8s-eks/`. Note you can change the layer name (and CIDRs and cluster name) if you already have an EKS cluster in this Account/Region.
290292

291-
#### 1 - Apply layers
293+
#### 1 - Create the network
292294

293-
First go into each layer and config the Terraform S3 background key, CIDR for the network, names, addons, etc.
295+
First go into the network layer (e.g. `apps-devstg/us-east-1/k8s-eks/network`) and config the Terraform S3 background key, CIDR for the network, names, etc.
296+
297+
```shell
298+
cd apps-devstg/us-east-1/k8s-eks/network
299+
```
300+
301+
Then, from inside the layer run:
302+
303+
```shell
304+
leverage tf init
305+
leverage tf apply
306+
```
307+
308+
#### 2 - Add the path to the VPN server
309+
310+
Since we are working on a private subnet (as per the [**binbash Leverage**](https://leverage.binbash.co/) and the AWS Well Architected Framework best practices), we need to set the VPN routes up.
311+
312+
If you are using the [Pritunl VPN server](../VPN-server/) (as per the [**binbash Leverage**](https://leverage.binbash.co/) recommendations), add the route to the CIDR set in the step 1 to the server you are using to connect to the VPN.
313+
314+
Then, connect to the VPN to access the private space.
315+
316+
#### 3 - Create the cluster
317+
318+
First go into each layer and config the Terraform S3 background key, names, addons, the components to install, etc.
319+
320+
```shell
321+
cd apps-devstg/us-east-1/k8s-eks/
322+
```
294323

295324
Then apply layers as follow:
296325

297326
```shell
298-
leverage tf init --layers network,cluster,identities,addons,k8s-components
299-
leverage tf apply --layers network,cluster,identities,addons,k8s-components
327+
leverage tf init --layers cluster,identities,addons,k8s-components
328+
leverage tf apply --layers cluster,identities,addons,k8s-components
300329
```
330+
331+
#### 4 - Access the cluster
332+
333+
Go into the cluster layer:
334+
335+
```shell
336+
cd apps-devstg/us-east-1/k8s-eks/cluster
337+
```
338+
339+
Use the embedded `kubectl` to config the context:
340+
341+
```shell
342+
leverage kubectl configure
343+
```
344+
345+
!!! Info
346+
You can export the context to use it with stand alone `kubectl`.
347+
348+
Once this process is done, you'll end up with temporary credentials created for `kubectl`.
349+
350+
Now you can try a `kubectl` command, e.g.:
351+
352+
```shell
353+
leverage kubectl get ns
354+
```
355+
356+
!!! Info
357+
If you've followed the [**binbash Leverage**](https://leverage.binbash.co/) recommendations, your cluster will live on a private subnet, so you need to connect to the VPN in order to access the K8s API.

mkdocs.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,7 @@ nav:
298298
- Start/Stop EC2/RDS instances using schedule or manual endpoint: "user-guide/cookbooks/schedule-start-stop-ec2.md"
299299
- Calculate VPC cubnet CIDRs: "user-guide/cookbooks/VPC-subnet-calculator.md"
300300
- Kubernetes in different stages: "user-guide/cookbooks/k8s.md"
301+
- KEDA, Kubernetes autoscaling: "user-guide/cookbooks/k8s.keda.md"
301302
- Encrypting/decrypting files with SOPS+KMS: "user-guide/cookbooks/sops-kms.md"
302303
- Enable/Disable nat gateway: "user-guide/cookbooks/enable-nat-gateway.md"
303304
- ArgoCD add external cluster: "user-guide/cookbooks/argocd-external-cluster.md"

0 commit comments

Comments
 (0)