diff --git a/blog/config/nav.yml b/blog/config/nav.yml index 332365851b..6a6444c214 100644 --- a/blog/config/nav.yml +++ b/blog/config/nav.yml @@ -1,7 +1,6 @@ nav: - Home: /docs/ - Tutorial: /docs/getting-started/ - - E2E-Tutorial: /docs/bookstore/ - Concepts: /docs/concepts/ - Installing: /docs/install/ - Functions: /docs/functions/ diff --git a/config/nav.yml b/config/nav.yml index 5fc6854f3d..930d698bc1 100644 --- a/config/nav.yml +++ b/config/nav.yml @@ -24,6 +24,7 @@ nav: # Getting started ############################################################################### - Tutorial: + - Overview: getting-started/tutorial.md - Quickstart: - Tutorial introduction: getting-started/README.md - Install Knative using quickstart: getting-started/quickstart-install.md @@ -48,6 +49,9 @@ nav: - Environment Setup: bookstore/page-0.5/pg0.5-env-setup.md - 1 - Send Review Comment to Broker: bookstore/page-1/pg1-review-svc-1.md - 2 - Create Sentiment Analysis Service: bookstore/page-2/pg2-sentiment-svc.md + - 3 - Create Bad Word Service: bookstore/page-3/pg3-badword-svc.md + - 4 - Create Sequence: bookstore/page-4/pg4-sequence.md + - 5 - Create DB service: bookstore/page-5/pg5-db-svc.md ############################################################################### # Installing ############################################################################### diff --git a/docs/bookstore/page-2/pg2-sentiment-svc.md b/docs/bookstore/page-2/pg2-sentiment-svc.md index de98ff00e0..a54387c57b 100644 --- a/docs/bookstore/page-2/pg2-sentiment-svc.md +++ b/docs/bookstore/page-2/pg2-sentiment-svc.md @@ -43,8 +43,11 @@ In order to do so, you need to install the func CLI. You can follow the [officia ![Image3](images/image3.png) The process is straightforward: + 1. Begin by utilizing the `func create` command to generate your code template. + 2. Next, incorporate your unique code into this template. + 3. Finally, execute `func deploy` to deploy your application seamlessly to the Kubernetes cluster. This workflow ensures a smooth transition from development to deployment within the Knative Functions ecosystem. @@ -100,81 +103,82 @@ You can find all the supported language templates [here](https://knative.dev/doc `func.py` is the file that contains the code for the function. You can replace the generated code with the sentiment analysis logic. You can use the following code as a starting point: -_sentiment-analysis-app/func.py_ -```python -from parliament import Context -from flask import Request, request, jsonify -import json -from textblob import TextBlob -from time import sleep -from cloudevents.http import CloudEvent, to_structured - -# The function to convert the sentiment analysis result into a CloudEvent -def create_cloud_event(inputText, badWordResult, data): - attributes = { - "type": "moderated-comment", - "source": "sentiment-analysis", - "datacontenttype": "application/json", - "sentimentResult": data, - "badwordfilter": badWordResult, - } - - # Put the sentiment analysis result into a dictionary - data = { - "reviewText": inputText, - "badWordResult": badWordResult, - "sentimentResult": data, - } - - # Create a CloudEvent object - event = CloudEvent(attributes, data) - return event - -def analyze_sentiment(text): - analysis = TextBlob(text["reviewText"]) - sentiment = "neutral" - - if analysis.sentiment.polarity > 0: - sentiment = "positive" - elif analysis.sentiment.polarity < 0: - sentiment = "negative" - - badWordResult = "" - try: - badWordResult = text["badWordResult"] - except: - pass - - # Convert the sentiment into a CloudEvent - sentiment = create_cloud_event(text["reviewText"], badWordResult, sentiment) - return sentiment - -def main(context: Context): - """ - Function template - The context parameter contains the Flask request object and any - CloudEvent received with the request. - """ - - print("Sentiment Analysis Received CloudEvent: ", context.cloud_event) - - # Add your business logic here - return analyze_sentiment(context.cloud_event.data) -``` +???+ abstract "_sentiment-analysis-app/func.py_" + + ```python + from parliament import Context + from flask import Request, request, jsonify + import json + from textblob import TextBlob + from time import sleep + from cloudevents.http import CloudEvent, to_structured + + # The function to convert the sentiment analysis result into a CloudEvent + def create_cloud_event(inputText, badWordResult, data): + attributes = { + "type": "moderated-comment", + "source": "sentiment-analysis", + "datacontenttype": "application/json", + "sentimentResult": data, + "badwordfilter": badWordResult, + } + + # Put the sentiment analysis result into a dictionary + data = { + "reviewText": inputText, + "badWordResult": badWordResult, + "sentimentResult": data, + } + + # Create a CloudEvent object + event = CloudEvent(attributes, data) + return event + + def analyze_sentiment(text): + analysis = TextBlob(text["reviewText"]) + sentiment = "neutral" + + if analysis.sentiment.polarity > 0: + sentiment = "positive" + elif analysis.sentiment.polarity < 0: + sentiment = "negative" + + badWordResult = "" + try: + badWordResult = text["badWordResult"] + except: + pass + + # Convert the sentiment into a CloudEvent + sentiment = create_cloud_event(text["reviewText"], badWordResult, sentiment) + return sentiment + + def main(context: Context): + """ + Function template + The context parameter contains the Flask request object and any + CloudEvent received with the request. + """ + + print("Sentiment Analysis Received CloudEvent: ", context.cloud_event) + + # Add your business logic here + return analyze_sentiment(context.cloud_event.data) + ``` ### **Step 3: Configure the dependencies** ![Image9](images/image9.png) The `requirements.txt` file contains the dependencies for the function. You can add the following dependencies to the `requirements.txt` file: +???+ abstract "_sentiment-analysis-app/requirements.txt_" -_sentiment-analysis-app/requirements.txt_ -``` -Flask==3.0.2 -textblob==0.18.0.post0 -parliament-functions==0.1.0 -cloudevents==1.10.1 -``` + ``` + Flask==3.0.2 + textblob==0.18.0.post0 + parliament-functions==0.1.0 + cloudevents==1.10.1 + ``` Knative function will automatically install the dependencies listed here when you build the function. @@ -185,35 +189,35 @@ Knative function will automatically install the dependencies listed here when yo In order to properly use the `textblob` library, you need to download the corpora, which is a large collection of text data that is used to train the sentiment analysis model. You can do this by creating a new file called `setup.py`, knative function will ensure that the `setup.py` file is executed after the dependencies have been installed. The `setup.py` file should contain the following code for your bookstore: - -_sentiment-analysis-app/setup.py_ -```python -from setuptools import setup, find_packages -from setuptools.command.install import install -import subprocess - -class PostInstallCommand(install): - """Post-installation for installation mode.""" - def run(self): - # Call the superclass run method - install.run(self) - # Run the command to download the TextBlob corpora - subprocess.call(['python', '-m', 'textblob.download_corpora', 'lite']) - -setup( - name="download_corpora", - version="1.0", - packages=find_packages(), - cmdclass={ - 'install': PostInstallCommand, - } -) -``` + +???+ abstract "_sentiment-analysis-app/setup.py_" + ```python + from setuptools import setup, find_packages + from setuptools.command.install import install + import subprocess + + class PostInstallCommand(install): + """Post-installation for installation mode.""" + def run(self): + # Call the superclass run method + install.run(self) + # Run the command to download the TextBlob corpora + subprocess.call(['python', '-m', 'textblob.download_corpora', 'lite']) + + setup( + name="download_corpora", + version="1.0", + packages=find_packages(), + cmdclass={ + 'install': PostInstallCommand, + } + ) + ``` ### **Step 5: Try to build and run your Knative Function locally (Optional)** -??? abstract "Click here to expand" +??? info "Click here to expand" ![Image4](images/image4.png) @@ -244,7 +248,7 @@ setup( --- - **An alert box Issue you may experience:** + **Troubleshooting** `❗Error: '/home/Kuack/Documents/knative/docs/code-samples' does not contain an initialized function` @@ -365,27 +369,29 @@ func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v - `--data` flag is the input text - `-t` flag is the URI to the Knative Function. -If you see the response, it means that the function is running successfully. -``` -Context Attributes, - specversion: 1.0 - type: new-review-comment - source: book-review-broker - id: ebbcd761-3a78-4c44-92e3-de575d1f2d38 - time: 2024-05-27T04:44:07.549303Z - datacontenttype: application/json -Extensions, - badwordfilter: good -Data, - { - "reviewText": "I love Knative so much", - "badWordResult": "", - "sentimentResult": "positive" - } -``` +???+ success "Verify" + + If you see the response, it means that the function is running successfully. + + ``` + Context Attributes, + specversion: 1.0 + type: new-review-comment + source: book-review-broker + id: ebbcd761-3a78-4c44-92e3-de575d1f2d38 + time: 2024-05-27T04:44:07.549303Z + datacontenttype: application/json + Extensions, + badwordfilter: good + Data, + { + "reviewText": "I love Knative so much", + "badWordResult": "", + "sentimentResult": "positive" + } + ``` ---- ## **Next Step** diff --git a/docs/bookstore/page-3/images/image1.png b/docs/bookstore/page-3/images/image1.png new file mode 100644 index 0000000000..58f842eba9 Binary files /dev/null and b/docs/bookstore/page-3/images/image1.png differ diff --git a/docs/bookstore/page-3/images/image10.png b/docs/bookstore/page-3/images/image10.png new file mode 100644 index 0000000000..40f9e4eba2 Binary files /dev/null and b/docs/bookstore/page-3/images/image10.png differ diff --git a/docs/bookstore/page-3/images/image2.png b/docs/bookstore/page-3/images/image2.png new file mode 100644 index 0000000000..9f7b25ec3b Binary files /dev/null and b/docs/bookstore/page-3/images/image2.png differ diff --git a/docs/bookstore/page-3/images/image3.png b/docs/bookstore/page-3/images/image3.png new file mode 100644 index 0000000000..7b2bb4021b Binary files /dev/null and b/docs/bookstore/page-3/images/image3.png differ diff --git a/docs/bookstore/page-3/images/image4.png b/docs/bookstore/page-3/images/image4.png new file mode 100644 index 0000000000..b207a358d1 Binary files /dev/null and b/docs/bookstore/page-3/images/image4.png differ diff --git a/docs/bookstore/page-3/images/image5.png b/docs/bookstore/page-3/images/image5.png new file mode 100644 index 0000000000..4115060719 Binary files /dev/null and b/docs/bookstore/page-3/images/image5.png differ diff --git a/docs/bookstore/page-3/images/image6.png b/docs/bookstore/page-3/images/image6.png new file mode 100644 index 0000000000..87f4255411 Binary files /dev/null and b/docs/bookstore/page-3/images/image6.png differ diff --git a/docs/bookstore/page-3/images/image7.png b/docs/bookstore/page-3/images/image7.png new file mode 100644 index 0000000000..96a877c97e Binary files /dev/null and b/docs/bookstore/page-3/images/image7.png differ diff --git a/docs/bookstore/page-3/images/image8.png b/docs/bookstore/page-3/images/image8.png new file mode 100644 index 0000000000..f231603bc2 Binary files /dev/null and b/docs/bookstore/page-3/images/image8.png differ diff --git a/docs/bookstore/page-3/images/image9.png b/docs/bookstore/page-3/images/image9.png new file mode 100644 index 0000000000..0e55fa6c26 Binary files /dev/null and b/docs/bookstore/page-3/images/image9.png differ diff --git a/docs/bookstore/page-3/pg3-badword-svc.md b/docs/bookstore/page-3/pg3-badword-svc.md new file mode 100644 index 0000000000..bb5e02caa9 --- /dev/null +++ b/docs/bookstore/page-3/pg3-badword-svc.md @@ -0,0 +1,169 @@ + +# 3 - Simplified - Create Bad Word Filter Service + +![Image 4](images/image4.png) + +As a bookstore owner, you aim to receive instant notifications in a Slack channel whenever a customer submits a new negative review comment. By leveraging Knative Function, you can set up a serverless function that contains a simple bad word filter service to tell whether the text contains any hateful/insultive speech. + +## **What Knative features will we learn about?** + +- The easiness to use Knative Function to deploy your service, and make it be managed by Knative Serving, which gives you the ability to auto-scale your service to zero, and scale up to handle the demand. + +## **What does the final deliverable look like?** + +![Image 2](images/image2.png) + +A running serverless Knative function that contains a python application that receives the new review comments as CloudEvent and returns the result that tells your input text contains any inappropriate languages or not. The result is sent back as CloudEvent. + +!!! info + We are using the `profanity_check` library to detect the bad words in the text. It is a open source library. Please see the disclaimer here. The result may not be 100% accurate. + +The function's output will be only from: + +- good +- bad + +## **Implementation** + +![Image 10](images/image10.png) + +The process is straightforward: + +1. Begin by utilizing the `func create` command to generate your code template. +2. Next, incorporate your unique code into this template. +3. Finally, execute `func deploy` to deploy your application seamlessly to the Kubernetes cluster. + +This workflow ensures a smooth transition from development to deployment within the Knative Functions ecosystem. + +--- + +### **Step 1: Create a Knative Function template** + +![Image 6](images/image6.png) + +???+ success "Verify" + + The file tree will look like this: + + ``` + bad-word-filter + ├── func.yaml + ├── .funcignore + ├── .gitignore + ├── requirements.txt + ├── app.sh + ├── test_func.py + ├── README.md + └── Procfile + └── func.py + ``` + +### **Step 2: Replace the generated code with the sentiment analysis logic** + +![Image 5](images/image5.png) + +`func.py` is the file that contains the code for the function. You can replace the generated code with the sentiment analysis logic. You can use the following code as a starting point: + +???+ abstract "_bad-word-filter/func.py_" + ```python + from parliament import Context + from profanity_check import predict + from cloudevents.http import CloudEvent + + # The function to convert the bad word filter result into a CloudEvent + def create_cloud_event(inputText, data): + attributes = { + "type": "new-review-comment", + "source": "book-review-broker", + "datacontenttype": "application/json", + "badwordfilter": data, + } + + # Put the bad word filter result into a dictionary + data = {"reviewText": inputText, "badWordResult": data} + + # Create a CloudEvent object + event = CloudEvent(attributes, data) + return event + + def inappropriate_language_filter(text): + profanity_result = predict([text["reviewText"]]) + result = "good" + if profanity_result[0] == 1: + result = "bad" + + profanity_event = create_cloud_event(text["reviewText"], result) + return profanity_event + + def main(context: Context): + """ + Function template + The context parameter contains the Flask request object and any + CloudEvent received with the request. + """ + print("Received CloudEvent: ", context.cloud_event) + + # Add your business logic here + return inappropriate_language_filter(context.cloud_event.data) + ``` + +### **Step 3: Configure the dependencies** + +![Image 8](images/image8.png) + +???+ abstract "_sentiment-analysis-app/requirements.txt_" + ```plaintext + parliament-functions==0.1.0 + alt-profanity-check==1.4.1.post1 + cloudevents==1.10.1 + ``` + +### **Step 4: Deploy the function to the cluster** + +![Image 1](images/image1.png) + +```plaintext +func deploy -b=s2i -v +``` +???+ success "Verify" + ![Image 3](images/image3.png) + +## **Verify** + +![Image 7](images/image7.png) + +```plaintext +func invoke -f=cloudevent --data='{"reviewText":"I love Knative so much"}' -v +``` + +???+ success "Verify" + Expect to receive a CloudEvent response: + + ```plaintext + Context Attributes, + specversion: 1.0 + type: new-review-comment + source: book-review-broker + id: ebbcd761-3a78-4c44-92e3-de575d1f2d38 + time: 2024-05-27T04:44:07.549303Z + datacontenttype: application/json + Extensions, + badwordfilter: good + Data, + { + "reviewText": "I love Knative so much", + "badWordResult": "good" + } + ``` + +If you see the response, it means that the function is running successfully. + +## **Next Step** + +![Image 9](images/image9.png) + +In this tutorial, you learned how to create a serverless function for a simple service that can detect inappropriate languages in text with Knative. + +Next, we'll be learning how to use Knative Sequence to connect the 2 ML workflow and make sure they are executed in the order you want. + +[Copy of 4 - Create analysis sequence with both analysis ksvc and send final result to broker](https://www.google.com/url?q=https://docs.google.com/document/d/1RnIiPIeFWQuGQ5xVjtHTEQwtcKErjAWfsjwiFx-RHU0/edit%23heading%3Dh.shzm2ken29oj&sa=D&source=editors&ust=1717645264197441&usg=AOvVaw2qCc6N9Q2NggkmSqnAmPeR) \ No newline at end of file diff --git a/docs/bookstore/page-4/images/image1.png b/docs/bookstore/page-4/images/image1.png new file mode 100644 index 0000000000..0fc0198ef2 Binary files /dev/null and b/docs/bookstore/page-4/images/image1.png differ diff --git a/docs/bookstore/page-4/images/image10.png b/docs/bookstore/page-4/images/image10.png new file mode 100644 index 0000000000..724ce1712b Binary files /dev/null and b/docs/bookstore/page-4/images/image10.png differ diff --git a/docs/bookstore/page-4/images/image11.png b/docs/bookstore/page-4/images/image11.png new file mode 100644 index 0000000000..96a877c97e Binary files /dev/null and b/docs/bookstore/page-4/images/image11.png differ diff --git a/docs/bookstore/page-4/images/image12.png b/docs/bookstore/page-4/images/image12.png new file mode 100644 index 0000000000..c1a870b498 Binary files /dev/null and b/docs/bookstore/page-4/images/image12.png differ diff --git a/docs/bookstore/page-4/images/image2.png b/docs/bookstore/page-4/images/image2.png new file mode 100644 index 0000000000..aa078130c5 Binary files /dev/null and b/docs/bookstore/page-4/images/image2.png differ diff --git a/docs/bookstore/page-4/images/image3.png b/docs/bookstore/page-4/images/image3.png new file mode 100644 index 0000000000..01e12abd2e Binary files /dev/null and b/docs/bookstore/page-4/images/image3.png differ diff --git a/docs/bookstore/page-4/images/image4.png b/docs/bookstore/page-4/images/image4.png new file mode 100644 index 0000000000..0e55fa6c26 Binary files /dev/null and b/docs/bookstore/page-4/images/image4.png differ diff --git a/docs/bookstore/page-4/images/image5.png b/docs/bookstore/page-4/images/image5.png new file mode 100644 index 0000000000..3f70343256 Binary files /dev/null and b/docs/bookstore/page-4/images/image5.png differ diff --git a/docs/bookstore/page-4/images/image6.png b/docs/bookstore/page-4/images/image6.png new file mode 100644 index 0000000000..d490d6f6f1 Binary files /dev/null and b/docs/bookstore/page-4/images/image6.png differ diff --git a/docs/bookstore/page-4/images/image7.png b/docs/bookstore/page-4/images/image7.png new file mode 100644 index 0000000000..56e2de64eb Binary files /dev/null and b/docs/bookstore/page-4/images/image7.png differ diff --git a/docs/bookstore/page-4/images/image8.png b/docs/bookstore/page-4/images/image8.png new file mode 100644 index 0000000000..8edc0f3007 Binary files /dev/null and b/docs/bookstore/page-4/images/image8.png differ diff --git a/docs/bookstore/page-4/images/image9.png b/docs/bookstore/page-4/images/image9.png new file mode 100644 index 0000000000..7390ed50c4 Binary files /dev/null and b/docs/bookstore/page-4/images/image9.png differ diff --git a/docs/bookstore/page-4/pg4-sequence.md b/docs/bookstore/page-4/pg4-sequence.md new file mode 100644 index 0000000000..802e5c03f5 --- /dev/null +++ b/docs/bookstore/page-4/pg4-sequence.md @@ -0,0 +1,192 @@ + +# **4 - Create Knative sequence with both ML service and send final result to broker and to event-display** + +![image](images/image8.png) + +## **What Knative features will we learn about?** + +- Knative Sequence + +## **What does the final deliverable look like?** + +![image](images/image1.png) + +- Create a Knative sequence with bad word filter service as step 1 and sentiment analysis service as step 2 +- The final result is sent back to broker as reply of the sequence + +## **Implementation** + +### **Step 0: Learn Sequence** + +Sequence provides a way to define an in-order list of functions that will be invoked. Each step can modify, filter or create a new kind of an event. + +If you hope your event to pass through different services **in an order you like**, Knative Sequence is your choice. + +![image](images/image3.png) + + +```yaml +apiVersion: flows.knative.dev/v1 +kind: Sequence +metadata: + name: sequence +spec: + channelTemplate: + apiVersion: messaging.knative.dev/v1 + kind: InMemoryChannel + steps: + - ref: + apiVersion: serving.knative.dev/v1 + kind: Service + name: first + - ref: + apiVersion: serving.knative.dev/v1 + kind: Service + name: second + reply: + ref: + kind: Service + apiVersion: serving.knative.dev/v1 + name: event-display +``` + +### **Step 1: Create the sequence** + +![image](images/image9.png) + +???+ abstract "sequence/config/100-create-sequence.yaml" + ```yaml + apiVersion: flows.knative.dev/v1 + kind: Sequence + metadata: + name: sequence + spec: + channelTemplate: # Under the hood, the Sequence will create a Channel for each step in the sequence + apiVersion: messaging.knative.dev/v1 + kind: InMemoryChannel + steps: + - ref: # This is the first step of the sequence, it will send the event to the bad-word-filter service + apiVersion: serving.knative.dev/v1 + kind: Service + name: bad-word-filter + - ref: # This is the second step of the sequence, it will send the event to the sentiment-analysis-app service + apiVersion: serving.knative.dev/v1 + kind: Service + name: sentiment-analysis-app + reply: # This is the last step of the sequence, it will send the event back to the broker as reply + ref: + kind: Broker + apiVersion: eventing.knative.dev/v1 + name: bookstore-broker + ``` + +Create the sequence yaml file and apply it to your cluster. + +![image](images/image10.png) + +???+ success "Verify" + + You can verify the status of the sequence very easily + + ```bash + kubectl get sequences + ``` + + You should expect the Ready state for `sequence` to be True. + + + ![image](images/image6.png) + + +### **Step 2: Create the trigger that pass the event to Sequence** + + + +![image](images/image7.png) + +Sequence now is ready to accept the request, then we need to tell broker to forward the event to sequence, so that the new comments will go through our ML workflows. + + +???+ abstract "sequence/200-create-trigger.yaml" + + ```yaml + apiVersion: eventing.knative.dev/v1 + kind: Trigger + metadata: + name: sequence-trigger + spec: + broker: bookstore-broker + filter: + attributes: + type: new-review-comment # This is the filter that will be applied to the event, only events with the ce-type new-review-comment will be processed + subscriber: + ref: + apiVersion: flows.knative.dev/v1 + kind: Sequence + name: sequence + ``` + +Create the trigger yaml file and apply it to your cluster. + +![image](images/image2.png) + +???+ success "Verify" + You can verify the status of the trigger very easily + + ```bash + kubectl get triggers + ``` + + You should see the trigger has the ready state as True. + And until this point, **your cluster should have the following triggers**. + ![image](images/image12.png) + + + +### **Verification** + +![image](images/image11.png) + +Open the log for event-display with the following command: + +```bash +kubectl logs event-display-XXXXX -f +``` + +Type something in the comment box in the UI and click the submit button. All the events that the bookstore-broker received will be displayed in the event-display. + +???+ success "Verify" + + The comment should appear in the event-display service with the following output: + + ```yaml + ☁️cloudevents.Event + Validation: valid + Context Attributes, + specversion: 1.0 + type: moderated-comment + source: sentiment-analysis + id: 2f703218-15d4-4ff8-b2bc-11200e209315 + time: 2024-04-21T01:26:27.608365Z + datacontenttype: application/json + Extensions, + badwordfilter: bad + knativearrivaltime: 2024-04-21T01:26:27.617405597Z + sentimentresult: negative + Data, + { + "reviewText": "XXXXXXXXXXXX", + "badWordResult": "bad", + "sentimentResult": "negative" + } + ``` + +## **Next Step** + +![image](images/image4.png) + +In this tutorial, you learned how to create a sequence to build a ML pipeline. + +Next, we'll be learning how to spin up book store’s database services, while learning what will be the best case to use Knative Serving. + +[Copy of 5 - Deploy database service](https://www.google.com/url?q=https://docs.google.com/document/d/1So0wmBQImRo6Eq2SQit9fXs_AC_Lt8Pwdkht-pQPi6Q/edit%23heading%3Dh.c3ftz2uxlpje&sa=D&source=editors&ust=1717646720174763&usg=AOvVaw0Nlgq42ml46PcA5Zq6kMPQ) diff --git a/docs/bookstore/page-5/images/image1.png b/docs/bookstore/page-5/images/image1.png new file mode 100644 index 0000000000..b5b1453a43 Binary files /dev/null and b/docs/bookstore/page-5/images/image1.png differ diff --git a/docs/bookstore/page-5/images/image2.png b/docs/bookstore/page-5/images/image2.png new file mode 100644 index 0000000000..15118a3363 Binary files /dev/null and b/docs/bookstore/page-5/images/image2.png differ diff --git a/docs/bookstore/page-5/images/image3.png b/docs/bookstore/page-5/images/image3.png new file mode 100644 index 0000000000..96a877c97e Binary files /dev/null and b/docs/bookstore/page-5/images/image3.png differ diff --git a/docs/bookstore/page-5/images/image4.png b/docs/bookstore/page-5/images/image4.png new file mode 100644 index 0000000000..effdae2408 Binary files /dev/null and b/docs/bookstore/page-5/images/image4.png differ diff --git a/docs/bookstore/page-5/images/image5.png b/docs/bookstore/page-5/images/image5.png new file mode 100644 index 0000000000..549137176a Binary files /dev/null and b/docs/bookstore/page-5/images/image5.png differ diff --git a/docs/bookstore/page-5/images/image6.png b/docs/bookstore/page-5/images/image6.png new file mode 100644 index 0000000000..b9420ea73c Binary files /dev/null and b/docs/bookstore/page-5/images/image6.png differ diff --git a/docs/bookstore/page-5/images/image7.png b/docs/bookstore/page-5/images/image7.png new file mode 100644 index 0000000000..0e55fa6c26 Binary files /dev/null and b/docs/bookstore/page-5/images/image7.png differ diff --git a/docs/bookstore/page-5/images/image8.png b/docs/bookstore/page-5/images/image8.png new file mode 100644 index 0000000000..8da55e337f Binary files /dev/null and b/docs/bookstore/page-5/images/image8.png differ diff --git a/docs/bookstore/page-5/images/image9.png b/docs/bookstore/page-5/images/image9.png new file mode 100644 index 0000000000..62f56cab1e Binary files /dev/null and b/docs/bookstore/page-5/images/image9.png differ diff --git a/docs/bookstore/page-5/pg5-db-svc.md b/docs/bookstore/page-5/pg5-db-svc.md new file mode 100644 index 0000000000..2fc85b1b9b --- /dev/null +++ b/docs/bookstore/page-5/pg5-db-svc.md @@ -0,0 +1,76 @@ + +# **5 - Deploy database service** + +![image1](images/image1.png) + +## **What Knative features will we learn about?** + +- When is the best time to use Knative Service + +## **What does the final deliverable look like?** + +- Running postgreSQL StatefulSet that contains the valid table and some sample data + +## **Concept Learning** +![image4](images/image4.png) + + +**Knative Services** are a powerful feature within the Knative ecosystem, designed to handle a wide range of use cases, especially in modern cloud-native applications, it can be controlled by Knative Serving, and achieve scale to 0 feature. Here’s an expanded explanation of when and why you should consider using Knative Services: + +???+ danger "Stateless Workloads" + - **Definition:** Stateless applications do not store any data locally between requests. Each request is independent and does not rely on any previous interaction. + - **Use Case:** Examples include web servers, APIs, and microservices where the state is managed externally, such as in a database or a cache. + - **Benefits:** Simplifies scaling and failover because any instance can handle any request without requiring session persistence. + +???+ example "Event-Driven Workloads" + - **Definition:** Event-driven architectures respond to events or triggers, such as HTTP requests, messages in a queue, or changes in a database. + - **Use Case:** Use Knative Services to deploy functions that react to events, such as processing incoming data, triggering workflows, or integrating with third-party APIs. + - **Benefits:** Efficient resource utilization, as services can scale down to zero when not handling events, reducing costs and improving performance. + + + + +![image6](images/image6.png) + +… More? Try to ask in the Knative Slack community [#knative](https://cloud-native.slack.com/archives/C04LGHDR9K7) whether it is the best use case or not. + +## **Implementation** + +### **Step 1: apply all the config yaml files** + +![image9](images/image9.png) + +In this section, we will just be simply running a PostgreSQL service. We have all config files ready. Simply run the following command to apply all yamls at once. + +```sh +kubectl apply -f db-service +``` + +???+ success "Verify" + + ![image8](images/image8.png) + + Wait a moment until all the pods become available and the database migration job is completed. If you see some job pods are failing and **having errors, don’t worry**, please wait until at least one job becomes “**Completed**”. + + ![image5](images/image5.png) + +## **Verification** + +![image3](images/image3.png) + +Open the UI page at [http://localhost:3000](http://localhost:3000), you should see some new comments popping up at the bottom of the page. + +![image2](images/image2.png) + +???+ bug "Troubleshoot" + If you see “No comments available”, that means your database is not initialized yet. Try to see the health of database service pods and figure out what happened. + +## **Next Step** + +![image7](images/image7.png) + +You have successfully set up the database services, and it is ready to receive requests and store user comments. + +Next, we'll complete our event-driven architecture by connecting all the components you created. This is where the magic happens. + +[Copy of 6 - Implement Book review v2 - receives "analyzed reviews" via Broker (using a trigger) and stores them into database](https://www.google.com/url?q=https://docs.google.com/document/d/1gYDi2sycWkgdFXpdglIGhh4XZruLJVJRJoFa4B-VnGI/edit%23heading%3Dh.c3ftz2uxlpje&sa=D&source=editors&ust=1717647663562112&usg=AOvVaw0EVw-mtIPgjCVVs9CzbemB) diff --git a/docs/getting-started/tutorial.md b/docs/getting-started/tutorial.md new file mode 100644 index 0000000000..27b66a4cfc --- /dev/null +++ b/docs/getting-started/tutorial.md @@ -0,0 +1,14 @@ +# Welcome to the Knative Tutorial + +### **Quick Start Tutorial** +Quickstart tutorial provides a simplified local installation to explore Knative Serving and Eventing features. + +[Get Started :octicons-arrow-right-24:](../getting-started/README.md){ .md-button } + +### **New: Knative's End-to-End Sample Application Tutorial** +Good starting point to learn Knative from scratch. Build an online bookstore application with Knative's powerful features. + +[Get Started :octicons-arrow-right-24:](../bookstore/page-0/page-0-intro.md){ .md-button } + + +![image1](../bookstore/page-0/images/1.png)