Skip to content

Commit 90d5109

Browse files
Leo6LeopierDipi
authored andcommitted
Sample App: Adding the db service (knative#5909)
* Adding the db service * Add the readme * Add the yaml file to create the config map * Change to use the statefulSet * Delete the finished job pod after 50 seconds * Simplify the deployment tutorial for the database service * Explain why we don't use Knative Service * Remove the unnessary empty lines in the file * Update code-samples/eventing/bookstore-sample-app/db/README.md Co-authored-by: Pierangelo Di Pilato <pierangelodipilato@gmail.com> * Update code-samples/eventing/bookstore-sample-app/db-service/sample.sql Co-authored-by: Pierangelo Di Pilato <pierangelodipilato@gmail.com> * Update code-samples/eventing/bookstore-sample-app/db/README.md Co-authored-by: Pierangelo Di Pilato <pierangelodipilato@gmail.com> * Fix the review comment --------- Co-authored-by: Pierangelo Di Pilato <pierangelodipilato@gmail.com>
1 parent 30ced8d commit 90d5109

File tree

8 files changed

+237
-13
lines changed

8 files changed

+237
-13
lines changed
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
apiVersion: v1
2+
kind: ConfigMap
3+
metadata:
4+
name: sql-configmap
5+
data:
6+
sample.sql: |
7+
CREATE DATABASE bookstore;
8+
CREATE TABLE IF NOT EXISTS book_reviews(
9+
id SERIAL PRIMARY KEY,
10+
post_time timestamp NOT NULL,
11+
content TEXT NOT NULL,
12+
sentiment TEXT,
13+
CONSTRAINT sentiment_check CHECK (sentiment IN ('positive', 'negative', 'neutral'))
14+
);
15+
16+
INSERT INTO book_reviews (post_time, content, sentiment) VALUES
17+
('2020-01-01 00:00:00', 'This book is great!', 'positive'),
18+
('2020-01-02 00:02:00', 'This book is terrible!', 'negative'),
19+
('2020-01-03 00:01:30', 'This book is okay.', 'neutral'),
20+
('2020-01-04 00:00:00', 'Meh', 'neutral');
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
apiVersion: v1
2+
kind: Secret
3+
metadata:
4+
name: postgresql-secret
5+
type: Opaque
6+
data:
7+
POSTGRES_DB: bXlkYXRhYmFzZQ==
8+
POSTGRES_USER: bXl1c2Vy
9+
POSTGRES_PASSWORD: bXlwYXNzd29yZA==
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: v1
2+
kind: PersistentVolumeClaim
3+
metadata:
4+
name: postgresql-pvc
5+
spec:
6+
accessModes:
7+
- ReadWriteOnce
8+
resources:
9+
requests:
10+
storage: 1Gi
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
apiVersion: apps/v1
2+
kind: StatefulSet
3+
metadata:
4+
name: postgresql
5+
spec:
6+
replicas: 1
7+
selector:
8+
matchLabels:
9+
app: postgresql
10+
template:
11+
metadata:
12+
labels:
13+
app: postgresql
14+
spec:
15+
containers:
16+
- name: postgresql
17+
image: quay.io/enterprisedb/postgresql
18+
env:
19+
- name: POSTGRES_DB
20+
valueFrom:
21+
secretKeyRef:
22+
name: postgresql-secret
23+
key: POSTGRES_DB
24+
- name: POSTGRES_USER
25+
valueFrom:
26+
secretKeyRef:
27+
name: postgresql-secret
28+
key: POSTGRES_USER
29+
- name: POSTGRES_PASSWORD
30+
valueFrom:
31+
secretKeyRef:
32+
name: postgresql-secret
33+
key: POSTGRES_PASSWORD
34+
ports:
35+
- containerPort: 5432
36+
volumeMounts:
37+
- name: postgresql-storage
38+
mountPath: /var/lib/postgresql/data
39+
volumes:
40+
- name: postgresql-storage
41+
persistentVolumeClaim:
42+
claimName: postgresql-pvc
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
apiVersion: v1
2+
kind: Service
3+
metadata:
4+
name: postgresql
5+
spec:
6+
ports:
7+
- port: 5432
8+
selector:
9+
app: postgresql
10+
type: NodePort
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: postgresql-job
5+
spec:
6+
ttlSecondsAfterFinished: 50
7+
template:
8+
spec:
9+
containers:
10+
- name: postgresql-client
11+
image: quay.io/enterprisedb/postgresql
12+
command: ["psql", "-h", "postgresql", "-U", "myuser", "-d", "mydatabase", "-f", "/sql/sample.sql"]
13+
env:
14+
- name: PGPASSWORD
15+
valueFrom:
16+
secretKeyRef:
17+
name: postgresql-secret
18+
key: POSTGRES_PASSWORD
19+
- name: PGUSER
20+
valueFrom:
21+
secretKeyRef:
22+
name: postgresql-secret
23+
key: POSTGRES_USER
24+
- name: PGDATABASE
25+
valueFrom:
26+
secretKeyRef:
27+
name: postgresql-secret
28+
key: POSTGRES_DB
29+
volumeMounts:
30+
- name: sql-volume
31+
mountPath: /sql
32+
restartPolicy: Never
33+
volumes:
34+
- name: sql-volume
35+
configMap:
36+
name: sql-configmap
37+
backoffLimit: 5
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
CREATE DATABASE bookstore;
2+
CREATE TABLE IF NOT EXISTS book_reviews(
3+
id SERIAL PRIMARY KEY,
4+
post_time timestamp NOT NULL,
5+
content TEXT NOT NULL,
6+
sentiment TEXT,
7+
CONSTRAINT sentiment_check CHECK (sentiment IN ('positive', 'negative', 'neutral'))
8+
);
9+
10+
INSERT INTO book_reviews (post_time, content, sentiment) VALUES
11+
('2020-01-01 00:00:00', 'This book is great!', 'positive'),
12+
('2020-01-02 00:02:00', 'This book is terrible!', 'negative'),
13+
('2020-01-03 00:01:30', 'This book is okay.', 'neutral'),
14+
('2020-01-04 00:00:00', 'Meh', 'neutral');
Lines changed: 95 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,108 @@
1-
# Bookstore Database
1+
# Database Service for Bookstore
2+
To successfully launch the Bookstore sample application, it's essential to set up a dedicated database populated with specific sample data. This guide provides both the schema for the database and the initial data you'll need to get started.
23

3-
1. Database Schema
4-
2. Sample Data
4+
In this tutorial, we'll embark on creating a PostgreSQL database using Kubernetes (K8s) StatefulSets and populating it with the sample data provided.
55

6-
## 1. Database Schema
6+
You might wonder, "Why not leverage Knative Serving to dynamically scale the database service in response to traffic demands?" We'll delve into the optimal scenarios for employing Knative Serving and when it's advantageous for our database service.
77

8-
### BookReviews Table
8+
## What does the final deliverable look like?
9+
Our goal is to deploy a PostgreSQL pod within Kubernetes, loaded with the sample data outlined in the accompanying SQL file. This pod will serve as the foundational database service for our bookstore application.
10+
11+
## Overview
12+
### The Database Schema
913
The BookReviews table contains all reviews made on the bookstore website.
1014

1115
See the columns of the BookReviews table below:
12-
* ID (serial) - Primary Key
13-
* post_time (datetime) - Posting time of the comment
14-
* content (text) - The contents of the comment
15-
* sentiment (text) - The sentiment results (currently, the values it could take on are 'positive' or 'neutral' or 'negative')
16-
17-
## 2. Sample Data
16+
* `ID (serial)` - Primary Key
17+
* `post_time (datetime)` - Posting time of the comment
18+
* `content (text)` - The contents of the comment
19+
* `sentiment (text)` - The sentiment results (currently, the values it could take on are 'positive' or 'neutral' or 'negative')
1820

19-
### BookReviews Table
21+
### The Sample Data
2022
The sample rows inserted for the BookReviews table are shown below:
2123
| id | post_time | content | sentiment |
2224
|----|---------------------|------------------------------|-----------|
2325
| 1 | 2020-01-01 00:00:00 | This book is great! | positive |
2426
| 2 | 2020-01-02 00:02:00 | This book is terrible! | negative |
2527
| 3 | 2020-01-03 00:01:30 | This book is okay. | neutral |
26-
| 4 | 2020-01-04 00:00:00 | Meh | neutral |
28+
| 4 | 2020-01-04 00:00:00 | Meh | neutral |
29+
30+
## Implementation
31+
32+
### Step 1: Acquire Necessary Files from the Repository
33+
The essential files for setting up your database are located within the `db` directory of our repository. Please download these files to proceed.
34+
35+
### Step 2: Deploying the PostgreSQL Database
36+
To deploy the PostgreSQL database and populate it with the provided sample data, you'll apply a series of Kubernetes deployment files. Ensure you're positioned in the `code-sample` directory and not within the `db` subdirectory for this operation.
37+
38+
Within this directory, you will find 6 YAML files, each serving a distinct purpose in the setup process:
39+
- `100-create-configmap.yaml`: Generates a ConfigMap including the SQL file for database initialization.
40+
- `100-create-secret.yaml`: Produces a Secret holding the PostgreSQL database password.
41+
- `100-create-volume.yaml`: Creates both a PersistentVolume and a PersistentVolumeClaim for database storage.
42+
- `200-create-postgre.yaml`: Establishes the StatefulSet for the PostgreSQL database.
43+
- `300-expose-service.yaml`: Launches a Service to expose the PostgreSQL database externally.
44+
- `400-create-job.yaml`: Executes a Job that populates the database with the sample data.
45+
46+
Execute the command below to apply all configuration files located in the `db` directory:
47+
```bash
48+
kubectl apply -f db
49+
```
50+
The filenames prefixed with numbers dictate the application order, ensuring Kubernetes orchestrates the resource setup accordingly.
51+
52+
### Step 3: Confirming the Deployment
53+
Following the application of the deployment files, initialization of the database may require some time. Monitor the deployment's progress by executing:
54+
```bash
55+
kubectl get pods
56+
57+
```
58+
A successful deployment is indicated by the `Running` state of the `postgresql-0` pod, as shown below:
59+
```bash
60+
NAMESPACE NAME READY STATUS RESTARTS AGE
61+
default postgresql-0 1/1 Running 0 1m
62+
```
63+
Upon observing the pod in a `Running` state, access the pod using the command:
64+
```bash
65+
kubectl exec -it postgresql-0 -- /bin/bash
66+
67+
```
68+
Inside the pod, connect to the database with:
69+
```bash
70+
psql -U myuser -d mydatabase
71+
```
72+
A successful connection will present you with:
73+
```bash
74+
mydatabase=#
75+
```
76+
To verify the initialization of the `BookReviews` table, execute:
77+
```
78+
mydatabase=# \dt
79+
```
80+
If the output lists the `BookReviews` table as follows, your database has been correctly initialized:
81+
```bash
82+
List of relations
83+
Schema | Name | Type | Owner
84+
--------+--------------+-------+--------
85+
public | book_reviews | table | myuser
86+
(1 row)
87+
```
88+
89+
## Question & Discussion
90+
1. Why did we choose to deploy our PostgreSQL database using a StatefulSet instead of a Knative Service?
91+
92+
We use [StatefulSet](https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/) for databases instead of Knative Service mainly because databases need to remember data (like a notebook that keeps your notes). StatefulSets are good at remembering things because they can save data and have a special name and place where they live. This is very important for databases.
93+
94+
Knative Services are more like notebooks that you use and then throw away when you're done. They're great for tasks that don't need to keep data for a long time. You can make them go away when you don't need them and come back when you do. But databases need to always remember information, so they can't just disappear and come back.
95+
96+
Also, databases often talk in their own special language, not the usual web language (HTTP) that Knative Services are really good at understanding. Because of this, Knative Services aren't the best choice for databases. That's why we choose StatefulSet for databases in Kubernetes.
97+
98+
---
99+
Note box: However, Knative Service supports Volumes and Persistent Volumes, which can be used to store data. You can read more [here](https://knative.dev/docs/serving/services/storage/) about how to use Volumes and Persistent Volumes with Knative Services specially for your use case.
100+
101+
---
102+
103+
2. When should I use Knative Service, and what would be the best use case for it?
104+
105+
You can read more about the best use cases for Knative Service [here](https://knative.dev/docs/serving/samples/)!
106+
107+
## Conclusion
108+
By following this guide, you have successfully deployed a PostgreSQL server on a Kubernetes cluster, set up persistent storage, and initialized your database using a Kubernetes job. Congratulations! Your bookstore now has the database service.

0 commit comments

Comments
 (0)