Skip to content

Commit 9dfb154

Browse files
committed
Initial commit
0 parents  commit 9dfb154

File tree

11 files changed

+406
-0
lines changed

11 files changed

+406
-0
lines changed

README.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# 🚀 **Module 4: Creating and Deploying Your First Serverless Function**
2+
3+
**Technology Stack:**
4+
5+
- Python
6+
- Serverless
7+
8+
---
9+
10+
## 🎯 **Scenario**
11+
12+
Instead of managing servers directly, your applications can scale automatically in response to events, scaling down to zero when idle, which can improve resource efficiency and cost management. In this workspace, you will be required to quickly build an application image, upload it to the internal repository and then load balance it with Red Hat Serverless!
13+
14+
---
15+
16+
## 🐾 **Guided Walkthrough**
17+
18+
1. Create a new project/namespace from the openshift ui and name it <username>-serverless
19+
2. From the openshift UI, start a new terminal
20+
- 2.1. Type in `oc project` to see which project you have enabled
21+
- 2.2. Type in `kn` to download the k-native CLI
22+
3. Create your first Knative service
23+
24+
```sh
25+
kn service create module4-helloworld \
26+
--image quay.io/pknezevich/module4-dotnet-hellolang \
27+
--autoscale-window 20s \
28+
--env countryCode=DE
29+
```
30+
31+
4. Verify your service has been created and you can curl/navigate to your application
32+
5. Tag the revision to **green**
33+
6. NOTE: we will update with ENV VAR but typically you would use: `kn service update <service-name> --image <new-image>`
34+
35+
```sh
36+
kn service update module4-helloworld \
37+
--env countryCode=DE \
38+
--tag module4-helloworld-00001=blue --untag green \
39+
--tag @latest=green \
40+
--traffic blue=100,green=0
41+
```
42+
43+
7. Tag the blue revision to **inactive**
44+
8. To create a third revision:
45+
- 8.1. From OC change the tag from `module4-helloworld-00002` green to blue
46+
- 8.2. Create a new revision
47+
- 8.2.1. ENV change (quick revision, this is usually done via an image change)
48+
- 8.2.1.1. Change a **different country code**
49+
- 8.2.2. Tag the **old revision to blue**
50+
- 8.2.3. Do not allow any traffic to new revision until you’re ready to (traffic distribution still stays on blue)
51+
52+
```sh
53+
kn service update module4-helloworld \
54+
--env countryCode=FR \
55+
--tag module4-helloworld-00002=blue --untag green \
56+
--tag @latest=green \
57+
--traffic blue=100,green=0
58+
```
59+
60+
9. Build a 3-revision load-balanced environment with 3 different country languages, distribute the traffic evenly between each (33%)
61+
10. Add a new image as a revision - `quay.io/pknezevich/helloworld-v2`
62+
63+
```sh
64+
kn service update module4-helloworld \
65+
--image quay.io/pknezevich/helloworld-v2 \
66+
--env countryCode=IT \
67+
--tag module4-helloworld-00001=blue --untag green \
68+
--tag @latest=green \
69+
--traffic blue=100,green=0
70+
```
71+
72+
---
73+
74+
## 🧩 **Challenge**
75+
76+
- [ ] Design your current environment - canary, blue/green, knife edge
77+
- You can rename the revision tags to whatever you’d like them to be
78+
79+
---
80+
81+
## **Key Takeaways**
82+
83+
- First time approach to Red Hat’s Serverless Scale-to-zero and auto-scaling
84+
- Understanding Revisions and Introduced ‘image tagging’ to your container image
85+
- Demonstrated blue-green deployment
86+
- Demonstrated canary deployments (using traffic distribution)
87+
- Demonstrated a knife-edge cutover

catalog-info.yaml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
apiVersion: backstage.io/v1alpha1
2+
kind: Component
3+
metadata:
4+
name: workshop-module4-python
5+
title: Module 4 - Python
6+
description: |
7+
Creating and Deploying Your First Serverless Function
8+
annotations:
9+
backstage.io/techdocs-ref: dir:.
10+
tags:
11+
- serverless
12+
- python
13+
spec:
14+
type: module
15+
lifecycle: production
16+
owner: group:default/cluster-admins
17+
subcomponentOf: component:default/workshop-repository

devfile.yaml

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
schemaVersion: 2.2.2
2+
metadata:
3+
name: workshop-module2-python
4+
version: 1.0.0
5+
description: DevSpaces workspace for Python app
6+
attributes:
7+
che-editor: vscode
8+
components:
9+
- container:
10+
args:
11+
- tail
12+
- -f
13+
- /dev/null
14+
endpoints:
15+
- name: https-py-5000
16+
protocol: https
17+
targetPort: 5000
18+
- name: https-py-5001
19+
protocol: https
20+
targetPort: 5001
21+
- exposure: none
22+
name: debug
23+
targetPort: 5858
24+
env:
25+
- name: DEBUG_PORT
26+
value: "5858"
27+
- name: countryCode
28+
value: "en"
29+
image: image-registry.openshift-image-registry.svc.cluster.local:5000/openshift/devspaces-dotnet-python:latest
30+
mountSources: true
31+
name: py
32+
33+
commands:
34+
- exec:
35+
commandLine: pip install -r requirements.txt
36+
component: py
37+
group:
38+
isDefault: true
39+
kind: build
40+
workingDir: ${PROJECT_SOURCE}/hello-world-v1
41+
id: pip-install-requirements-hello-world-v1
42+
- exec:
43+
commandLine: flask run --host=0.0.0.0 --port=5000
44+
component: py
45+
group:
46+
isDefault: true
47+
kind: run
48+
workingDir: ${PROJECT_SOURCE}/hello-world-v1
49+
id: run-python-hello-world-v1
50+
- exec:
51+
commandLine: pip install -r requirements.txt
52+
component: py
53+
group:
54+
isDefault: true
55+
kind: build
56+
workingDir: ${PROJECT_SOURCE}/hello-world-v2
57+
id: pip-install-requirements-hello-world-v2
58+
- exec:
59+
commandLine: flask run --host=0.0.0.0 --port=5001
60+
component: py
61+
group:
62+
isDefault: true
63+
kind: run
64+
workingDir: ${PROJECT_SOURCE}/hello-world-v2
65+
id: run-python-hello-world-v2

docs/index.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
# 🚀 **Module 4: Creating and Deploying Your First Serverless Function**
2+
3+
**Technology Stack:**
4+
5+
- Python
6+
- Serverless
7+
8+
---
9+
10+
## 🎯 **Scenario**
11+
12+
Instead of managing servers directly, your applications can scale automatically in response to events, scaling down to zero when idle, which can improve resource efficiency and cost management. In this workspace, you will be required to quickly build an application image, upload it to the internal repository and then load balance it with Red Hat Serverless!
13+
14+
---
15+
16+
## 🐾 **Guided Walkthrough**
17+
18+
1. Create a new project/namespace from the openshift ui and name it <username>-serverless
19+
2. From the openshift UI, start a new terminal
20+
- 2.1. Type in `oc project` to see which project you have enabled
21+
- 2.2. Type in `kn` to download the k-native CLI
22+
3. Create your first Knative service
23+
24+
```sh
25+
kn service create module4-helloworld \
26+
--image quay.io/pknezevich/module4-dotnet-hellolang \
27+
--autoscale-window 20s \
28+
--env countryCode=DE
29+
```
30+
31+
4. Verify your service has been created and you can curl/navigate to your application
32+
5. Tag the revision to **green**
33+
6. NOTE: we will update with ENV VAR but typically you would use: `kn service update <service-name> --image <new-image>`
34+
35+
```sh
36+
kn service update module4-helloworld \
37+
--env countryCode=DE \
38+
--tag module4-helloworld-00001=blue --untag green \
39+
--tag @latest=green \
40+
--traffic blue=100,green=0
41+
```
42+
43+
7. Tag the blue revision to **inactive**
44+
8. To create a third revision:
45+
- 8.1. From OC change the tag from `module4-helloworld-00002` green to blue
46+
- 8.2. Create a new revision
47+
- 8.2.1. ENV change (quick revision, this is usually done via an image change)
48+
- 8.2.1.1. Change a **different country code**
49+
- 8.2.2. Tag the **old revision to blue**
50+
- 8.2.3. Do not allow any traffic to new revision until you’re ready to (traffic distribution still stays on blue)
51+
52+
```sh
53+
kn service update module4-helloworld \
54+
--env countryCode=FR \
55+
--tag module4-helloworld-00002=blue --untag green \
56+
--tag @latest=green \
57+
--traffic blue=100,green=0
58+
```
59+
60+
9. Build a 3-revision load-balanced environment with 3 different country languages, distribute the traffic evenly between each (33%)
61+
10. Add a new image as a revision - `quay.io/pknezevich/helloworld-v2`
62+
63+
```sh
64+
kn service update module4-helloworld \
65+
--image quay.io/pknezevich/helloworld-v2 \
66+
--env countryCode=IT \
67+
--tag module4-helloworld-00001=blue --untag green \
68+
--tag @latest=green \
69+
--traffic blue=100,green=0
70+
```
71+
72+
---
73+
74+
## 🧩 **Challenge**
75+
76+
- [ ] Design your current environment - canary, blue/green, knife edge
77+
- You can rename the revision tags to whatever you’d like them to be
78+
79+
---
80+
81+
## **Key Takeaways**
82+
83+
- First time approach to Red Hat’s Serverless Scale-to-zero and auto-scaling
84+
- Understanding Revisions and Introduced ‘image tagging’ to your container image
85+
- Demonstrated blue-green deployment
86+
- Demonstrated canary deployments (using traffic distribution)
87+
- Demonstrated a knife-edge cutover

hello-world-v1/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Use an official Python runtime as a parent image (we won't use the Red Hat UBI as this is a very fast test)
2+
FROM python:3.9-slim
3+
4+
# Set the working directory to /projects
5+
WORKDIR /projects
6+
7+
# Copy requirements.txt into the container
8+
COPY requirements.txt /projects/requirements.txt
9+
10+
# Install dependencies from requirements.txt
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
# Copy the rest of the project files into the container
14+
COPY . /projects
15+
16+
# Make port 5000 available to the world outside this container
17+
EXPOSE 5000
18+
19+
# Define environment variable (optional, you can override this at runtime)
20+
ENV countryCode=EN
21+
22+
# Run the app using uvicorn when the container launches
23+
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

hello-world-v1/app.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from flask import Flask, request
2+
import os
3+
4+
app = Flask(__name__)
5+
6+
@app.route("/")
7+
def hello():
8+
country = os.environ.get('countryCode')
9+
if country and len(country) == 2:
10+
translation = translations.get(country.upper())
11+
if translation:
12+
return translation
13+
else:
14+
return "Translation not available for this country.", 404
15+
return "Hello World!"
16+
17+
18+
translations = {
19+
"EN": "Hello World!",
20+
"SP": "¡Hola Mundo!",
21+
"FR": "Bonjour le monde!",
22+
"DE": "Hallo Welt!",
23+
"IT": "Ciao Mondo!",
24+
"SW": "Hej världen!"
25+
}
26+
27+
if __name__ == "__main__":
28+
app.run(debug=True)

hello-world-v1/requirements.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
flask
2+
python-dotenv
3+
Flask
4+
gunicorn

hello-world-v2/Dockerfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# Use an official Python runtime as a parent image (we won't use the Red Hat UBI as this is a very fast test)
2+
FROM python:3.9-slim
3+
4+
# Set the working directory to /projects
5+
WORKDIR /projects
6+
7+
# Copy requirements.txt into the container
8+
COPY requirements.txt /projects/requirements.txt
9+
10+
# Install dependencies from requirements.txt
11+
RUN pip install --no-cache-dir -r requirements.txt
12+
13+
# Copy the rest of the project files into the container
14+
COPY . /projects
15+
16+
# Make port 5000 available to the world outside this container
17+
EXPOSE 5000
18+
19+
# Define environment variable (optional, you can override this at runtime)
20+
ENV countryCode=EN
21+
22+
# Run the app using uvicorn when the container launches
23+
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]

0 commit comments

Comments
 (0)