Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Replace LoadBalancer with Ingress #105

Merged
merged 8 commits into from
Jan 18, 2024
Merged
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
4 changes: 2 additions & 2 deletions .test/lint_kube.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
KUBERNETES_RESOURCE_FILES=$(find * -type f \( -iname '*.yml' -or -iname '*.yaml' \) -and ! \( -iname "helmfile.yaml" -or -iname "values-*.yaml" -or -iname "*docker-compose*" \))

excludes=(
deployments-loadbalancing/start/frontend-deployment.yaml
deployments-loadbalancing/start/backend-deployment.yaml
deployments-ingress/start/frontend-deployment.yaml
deployments-ingress/start/backend-deployment.yaml
manifests/start/frontend-pod.yaml
services/start/backend-svc.yaml
services/start/frontend-svc.yaml
Expand Down
2 changes: 0 additions & 2 deletions configmap-secrets/done/postgres-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ spec:
selector:
app: postgres
type: ClusterIP
status:
loadBalancer: {}
2 changes: 0 additions & 2 deletions configmap-secrets/start/postgres-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ spec:
selector:
app: postgres
type: ClusterIP
status:
loadBalancer: {}
6 changes: 5 additions & 1 deletion configmaps-secrets.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,12 +189,13 @@ We want to change the database user into a configmap, so that we can change it i
```yaml
data:
DB_HOST: postgres
DB_PORT: "5432'
DB_PORT: "5432"
DB_USER: superuser
DB_PASSWORD: complicated
DB_NAME: quotes
```


:bulb: If you are unsure how to do this, look at the [configmap section](#configmaps) above.

<details>
Expand Down Expand Up @@ -225,6 +226,9 @@ data:

</details>


- apply the configmap with `kubectl apply -f postgres-config.yaml`

- In the `backend-deployment.yaml`, change the environment variables to use the configmap instead of the hardcoded values.

Change this:
Expand Down
162 changes: 95 additions & 67 deletions deployments-loadbalancing.md → deployments-ingress.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@

## Learning Goals

- Learn how to expose a deployment using Ingress
- Learn how to use `deployments`
- Learn how to scale deployments
- Learn how to use `services` to do loadbalance between the pods of a scaled deployment
- Learn how to expose a deployment using a service type LoadBalancer

## Introduction

In this exercise you'll learn how to deploy a pod using a deployment, and how to scale it. You'll also learn how to expose a deployment using a service type LoadBalancer.
In this exercise, you'll learn how to deploy a pod using a deployment, how to scale it, and how to expose it using an `Ingress` resource with URL routing.

## Deployments

Expand Down Expand Up @@ -76,39 +76,56 @@ In Kubernetes this is done in practice by `scaling` a deployment, e.g. by adding

To scale a deployment, we change the number of `replicas` in the manifest file, and then apply the changes using `kubectl apply -f <manifest-file>`.

### Service type: LoadBalancer
## Ingress

Similar to pods, deployments can also be exposed using services.
For all practical purposes, deployments are used along with services.
We have seen how to expose a pod using a service type `ClusterIP`.
This service type is only accessible from within the cluster.
We have also seen how to expose a pod using a service type `NodePort`.
This service type is accessible from the internet, but only on the port that is exposed on the worker nodes.
We do not expect the users to know the IP addresses of our worker nodes, nor do we necessarily want to expose the worker nodes to the internet.
Ingress in Kubernetes that manages external access to the services in a cluster, typically HTTP and HTTPS.

The only thing that changes when we change the service type from NodePort to LoadBalancer is that the service type LoadBalancer will create a load balancer in the cloud provider, and will expose the service on an IP and port that is accessible from the internet.
Ingress can provide load balancing, SSL termination, and name-based virtual routing.

This also means that the exact behaviour of `services` of type `LoadBalancer` is different from Kubernetes provider to Kubernetes provider!
Ingress builds on top of the `service` concept, and is implemented by an `ingress controller`.

<details>
<summary>
:bulb: More Details
</summary>
An example Ingress manifest to be used in AWS looks like this:

The type LoadBalancer is only available for use, if your Kubernetes cluster is setup in one of the public cloud providers like GCE, AWS, etc. or if the admin of a local cluster has set it up, using for example [metallb](https://metallb.org/).

</details>
```yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
#annotations are used to configure the ingress controller behavior.
alb.ingress.kubernetes.io/scheme: internet-facing
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
name: quotes-ingress
spec:
# rules are used to configure the routing behavior.
rules:
# each rule has a host and a list of paths. The host is used to match the host header of the request, normally the domain name.
- host: quotes-1.prosa.eficode.academy
http:
paths:
- pathType: Prefix
path: "/"
# each path has a backend, which is used to route the request to a service.
backend:
service:
# This is the name of the service to route to.
name: quotes-frontend
port:
number: 80
```

When you apply this manifest, an A-record will be created in Route53, pointing to our ingress-controller called ALB, and the ALB will route traffic to the service.

## Exercise

### Overview

- Add frontend Ingress and let it reconcile
- Turn the backend pod manifests into a deployment manifest
- Apply the backend deployment manifest
- Scale the deployment by adding a replicas key
- Turn frontend pod manifests into a deployment manifest
- Apply the frontend deployment manifest
- Add frontend service type LoadBalancer
- Test service promise of high availability

> :bulb: If you get stuck somewhere along the way, you can check the solution in the done directory.
Expand All @@ -120,12 +137,49 @@ The type LoadBalancer is only available for use, if your Kubernetes cluster is s
Step by step:
</summary>

- Go into the `deployments-loadbalancing/start` directory.
- Go into the `deployments-ingress/start` directory.

In the directory we have the pod manifests for the backend and frontend that have created in the previous exercises.
We also have two services, one for the backend (type ClusterIP) and one for the frontend (type NodePort).
We also have two services, one for the backend (type ClusterIP) and one for the frontend (type NodePort) as well as an ingress manifest for the frontend.

**Add Ingress to frontend service**

As it might take a while for the ingress to work, we will start by adding the ingress to the frontend service, even though we have not applied the service yet.

- Open the `frontend-ingress.yaml` file in your editor.
- Change the hostname to `quotes-<yourname>.<prefix>.eficode.academy`. Just as long as it is unique.
- Change the service name to match the name of the frontend service.
- Apply the ingress manifest.

```
kubectl apply -f frontend-ingress.yaml
```

Expected output:

```
ingress.networking.k8s.io/frontend-ingress created
```

- Check that the ingress has been created.

- Deploy the frontend pod as well as the two services.
```
kubectl get ingress
```

Expected output:

```
NAME HOSTS ADDRESS PORTS AGE
frontend-ingress quotes-<yourname>.<prefix>.eficode.academy 80 1m
```

Congratulations, you have now added an ingress to the frontend service.
It will take a while for the ingress to work, so we will continue with the backend deployment.

**Turn the backend pod manifests into a deployment manifest**

- Deploy the frontend pod as well as the two services `backend-svc.yaml` and `frontend-svc.yaml`.
Use the `kubectl apply -f` command.

- Verify that the frontend is accessible from the browser.
Expand Down Expand Up @@ -259,8 +313,17 @@ NAME READY STATUS RESTARTS AGE
backend-5f4b8b7b4-5x7xg 1/1 Running 0 1m
```

- Access the frontend again from the browser.
It should now be able to access the backend.
- Access the frontend again from the browser. Now the Ingress should work and you should be able to access the frontend from the browser using the hostname you specified in the ingress manifest.

The url should look something like this:

```
http://quotes-<yourname>.<prefix>.eficode.academy
```

- If it still does not work, you can check it through NodePort service instead.

- You should now see the backend.

- If this works, please delete the `backend-pod.yaml` file, as we now have upgraded to a deployment and no longer need it!

Expand Down Expand Up @@ -393,47 +456,6 @@ frontend-47b45fb8b-4x7xg 1/1 Running 0 1m

- If this works, please delete the `frontend-pod.yaml` file, as we now have upgraded to a deployment and no longer need it!

**Add frontend service type loadbalancer**

- Change the frontend service type to `LoadBalancer` in the frontend-svc.yaml file.

- Apply the frontend service manifest file again.

```
kubectl apply -f frontend-svc.yaml
```

Expected output:

```
service/frontend-svc configured
```

- Check that the service has been created.

```
kubectl get services
```

Expected output:

```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
backend ClusterIP 172.20.211.99 <none> 5000/TCP 3h13m
frontend LoadBalancer 172.20.30.195 a99b267dc38c94ec3b0507427c1a2665-362778330.eu-west-1.elb.amazonaws.com 5000:32146/TCP 13m
```

> Note: The EXTERNAL-IP will be different for you.

> Note: It may take a few minutes for the EXTERNAL-IP to be assigned.

> Note: Even though it is called "EXTERNAL-IP" it is actually a DNS name (this is an AWS quirk).

- Access the frontend through the EXTERNAL-IP from the browser. Remember to add the port to the url like:

```
http://a99b267dc38c94ec3b0507427c1a2665-362778330.eu-west-1.elb.amazonaws.com:5000
```

</details>

Expand All @@ -453,7 +475,13 @@ kubectl delete -f frontend-svc.yaml
kubectl delete -f backend-svc.yaml
```

> :bulb: If you ever want to delete all resources from a particular directory, you can use a shell wildcard: `kubectl delete -f *.yaml` which will point at **all** `.yaml` files in that directory!
- Delete the ingress

```
kubectl delete -f frontend-ingress.yaml
```

> :bulb: If you ever want to delete all resources from a particular directory, you can use: `kubectl delete -f .` which will point at **all** files in that directory!

# Extra Exercise

Expand Down
23 changes: 23 additions & 0 deletions deployments-ingress/done/frontend-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# These annotations are required to use ALB Ingress Controller
alb.ingress.kubernetes.io/scheme: internet-facing
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
name: frontend-ingress
spec:
rules:
# you need to change the host to match your own
- host: quotes-sal.prosa.eficode.academy
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
# change this to match your service name
name: frontend
port:
number: 5000
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,4 @@ spec:
targetPort: 5000
selector:
run: frontend
type: LoadBalancer
type: NodePort
24 changes: 24 additions & 0 deletions deployments-ingress/start/frontend-ingress.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
# These annotations are required to use ALB Ingress Controller
alb.ingress.kubernetes.io/scheme: internet-facing
kubernetes.io/ingress.class: alb
alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}]'
name: frontend-ingress
spec:
rules:
# you need to change the host to match your own
- host: quotes-<yourname>.<prefix>.eficode.academy
http:
paths:
- pathType: Prefix
path: "/"
backend:
service:
# change this to match your service name
name: <name of the frontend service>
port:
# this is the port your service is listening on
number: 5000
15 changes: 15 additions & 0 deletions intro.md
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,18 @@ To clean up, run the following command:
kubectl delete -f quotes-flask/
```

### Extra

If you have more time, take a look at the YAML manifests that we used to deploy the application.
They are in the `quotes-flask` folder.
First take a look at the deployment manifest, and see if you can find the following information:

- The name of the deployment
- The number of replicas
- The image used for the container

Then take a look at the service manifest, and see if you can find the following information:

- The name of the service
- The port the service listens on

2 changes: 0 additions & 2 deletions persistent-storage/done/backend-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ spec:
selector:
app: backend
type: ClusterIP
status:
loadBalancer: {}
5 changes: 1 addition & 4 deletions persistent-storage/done/frontend-service.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
apiVersion: v1
kind: Service
metadata:
creationTimestamp: null
labels:
app: frontend
name: frontend
Expand All @@ -12,6 +11,4 @@ spec:
targetPort: 5000
selector:
app: frontend
type: LoadBalancer
status:
loadBalancer: {}
type: NodePort
2 changes: 0 additions & 2 deletions persistent-storage/done/postgres-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,3 @@ spec:
selector:
app: postgres
type: ClusterIP
status:
loadBalancer: {}
4 changes: 1 addition & 3 deletions persistent-storage/start/backend-service.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,4 @@ spec:
targetPort: 5000
selector:
app: backend
type: ClusterIP
status:
loadBalancer: {}
type: ClusterIP
Loading