{"id":50040,"date":"2026-06-23T08:23:56","date_gmt":"2026-06-23T08:23:56","guid":{"rendered":"https:\/\/www.devopsschool.com\/blog\/?p=50040"},"modified":"2026-06-23T08:23:59","modified_gmt":"2026-06-23T08:23:59","slug":"openshift-setting-up-and-using-openshift-serverless-functions","status":"publish","type":"post","link":"https:\/\/www.devopsschool.com\/blog\/openshift-setting-up-and-using-openshift-serverless-functions\/","title":{"rendered":"OpenShift Lab 14: Setting Up and Using OpenShift Serverless Functions on OpenShift Local"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Lab Objective<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">In this lab, you will install and use OpenShift Serverless Functions on OpenShift Local.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You will create a simple Node.js serverless function, deploy it to OpenShift, invoke it using HTTP, verify the Knative resources created by OpenShift Serverless, and observe scale-to-zero behavior.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This lab is a modern replacement for the older \u201cSetting up and using OpenShift Serverless Functions\u201d article. The original article explains the concept, but this replacement provides a complete hands-on lab for students.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What You Will Learn<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You will learn how to:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Start OpenShift Local.<\/li>\n\n\n\n<li>Log in as both <code>developer<\/code> and <code>kubeadmin<\/code>.<\/li>\n\n\n\n<li>Install the OpenShift Serverless Operator.<\/li>\n\n\n\n<li>Install Knative Serving.<\/li>\n\n\n\n<li>Install and validate the Knative <code>kn<\/code> CLI.<\/li>\n\n\n\n<li>Prepare an image registry for function images.<\/li>\n\n\n\n<li>Create a new project for functions.<\/li>\n\n\n\n<li>Create a Node.js function using <code>kn func<\/code>.<\/li>\n\n\n\n<li>Modify the function code.<\/li>\n\n\n\n<li>Deploy the function as a Knative Service.<\/li>\n\n\n\n<li>Invoke the function.<\/li>\n\n\n\n<li>Validate Knative Service, Revision, Configuration, and Route resources.<\/li>\n\n\n\n<li>Observe scale-to-zero and scale-from-zero.<\/li>\n\n\n\n<li>View function logs.<\/li>\n\n\n\n<li>Troubleshoot common OpenShift Serverless issues.<\/li>\n\n\n\n<li>Clean up the lab environment.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Lab Architecture<\/h2>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-1\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Developer Machine\n  |\n  | kn func create\n  | kn func deploy\n  | kn func invoke\n  v\nOpenShift Local\n  |\n  v\nOpenShift Serverless Operator\n  |\n  v\nKnative Serving\n  |\n  v\nKnative Service\n  |\n  v\nRevision\n  |\n  v\nPod\n  |\n  v\nKnative Route\n  |\n  v\n<span class=\"hljs-built_in\">Function<\/span> URL\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-1\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What Is OpenShift Serverless?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">OpenShift Serverless allows you to run applications and functions that automatically scale based on demand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is based on Knative.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In simple terms:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-2\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Normal Deployment:\nApplication pod usually keeps running.\n\nServerless <span class=\"hljs-built_in\">Function<\/span>:\n<span class=\"hljs-built_in\">Function<\/span> pod starts when traffic arrives.\nFunction pod can scale down to zero when idle.\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-2\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">What Is a Serverless Function?<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A serverless function is a small piece of code that runs in response to a request or event.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Examples:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-3\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">HTTP request\nCloudEvent\nMessage <span class=\"hljs-keyword\">from<\/span> a queue\nKafka event\nWebhook event\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-3\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">In this beginner lab, you will use a simple HTTP function.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Important Concept: Function vs Deployment<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Area<\/th><th>Normal OpenShift Deployment<\/th><th>OpenShift Serverless Function<\/th><\/tr><\/thead><tbody><tr><td>Main resource<\/td><td>Deployment<\/td><td>Knative Service<\/td><\/tr><tr><td>Scaling<\/td><td>Manual, HPA, or custom autoscaling<\/td><td>Automatic request-based scaling<\/td><\/tr><tr><td>Scale to zero<\/td><td>Not by default<\/td><td>Yes<\/td><\/tr><tr><td>Route handling<\/td><td>OpenShift Route<\/td><td>Knative Route<\/td><\/tr><tr><td>Build\/deploy tool<\/td><td><code>oc<\/code>, Git, pipelines, image deploy<\/td><td><code>kn func<\/code><\/td><\/tr><tr><td>Good for<\/td><td>Long-running apps<\/td><td>Event-driven or request-driven workloads<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Important Concept: Function vs Knative Service<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">A function is a developer workflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">A Knative Service is the runtime resource created after the function is deployed.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-4\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">Function<\/span> source code\n  -&gt; container image\n  -&gt; Knative Service\n  -&gt; Revision\n  -&gt; Pod\n  -&gt; URL\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-4\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">When you run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func deploy\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">OpenShift packages your function into a container image and deploys it as a Knative Service.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Important Lab Note: Admin and Student Responsibilities<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This lab has two parts.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Part<\/th><th>Who Runs It<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td>Admin setup<\/td><td>Instructor or cluster admin<\/td><td>Install OpenShift Serverless Operator and Knative Serving<\/td><\/tr><tr><td>Student lab<\/td><td>Developer user<\/td><td>Create, deploy, invoke, and observe a function<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">A normal <code>developer<\/code> user cannot install cluster operators. The operator setup must be done by <code>kubeadmin<\/code> or another cluster administrator.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 1: Prerequisites<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Required Software<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You need:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>OpenShift Local installed.<\/li>\n\n\n\n<li><code>crc<\/code> command available.<\/li>\n\n\n\n<li><code>oc<\/code> command available.<\/li>\n\n\n\n<li><code>kn<\/code> CLI installed.<\/li>\n\n\n\n<li>Podman or Docker installed.<\/li>\n\n\n\n<li>Browser access to OpenShift web console.<\/li>\n\n\n\n<li>Internet access from OpenShift Local.<\/li>\n\n\n\n<li>Red Hat pull secret configured for OpenShift Local.<\/li>\n\n\n\n<li>Enough CPU and memory for Serverless components.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Recommended OpenShift Local Resources<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">OpenShift Serverless needs more resources than a simple Deployment lab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recommended OpenShift Local configuration:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Resource<\/th><th>Recommended<\/th><\/tr><\/thead><tbody><tr><td>CPU<\/td><td>6 cores<\/td><\/tr><tr><td>Memory<\/td><td>16 GB<\/td><\/tr><tr><td>Disk<\/td><td>50 GB<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">Configure CRC before starting the cluster:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-5\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">crc config <span class=\"hljs-keyword\">set<\/span> preset openshift\ncrc config <span class=\"hljs-keyword\">set<\/span> cpus 6\ncrc config <span class=\"hljs-keyword\">set<\/span> memory 16384\ncrc config <span class=\"hljs-keyword\">set<\/span> disk-size 50\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-5\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If CRC is already running, stop it first:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc stop\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then start again after changing resources.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 2: Start OpenShift Local<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc version\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Run setup:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc setup\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Start OpenShift Local:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc start\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">View credentials:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-6\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">crc <span class=\"hljs-built_in\">console<\/span> --credentials\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-6\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Open the console:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-7\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">crc <span class=\"hljs-built_in\">console<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-7\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 3: Configure the <code>oc<\/code> CLI<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc oc-env\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">On Linux or macOS:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-8\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">eval<\/span> $(crc oc-env)\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-8\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">On Windows PowerShell, use the command printed by <code>crc oc-env<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Log in as <code>developer<\/code> first:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-9\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc login -u developer https:<span class=\"hljs-comment\">\/\/api.crc.testing:6443<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-9\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc whoami\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">developer\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Now log in as <code>kubeadmin<\/code> for the admin setup section:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-10\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc login -u kubeadmin https:<span class=\"hljs-comment\">\/\/api.crc.testing:6443<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-10\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Use the <code>kubeadmin<\/code> password from:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-11\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">crc <span class=\"hljs-built_in\">console<\/span> --credentials\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-11\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc whoami\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kubeadmin\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check the node:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-12\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> nodes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-12\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc-xxxxx-master-0   Ready\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 4: Install the OpenShift Serverless Operator<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This section must be done by <code>kubeadmin<\/code> or a cluster administrator.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can install the Operator from the web console or CLI.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option A: Install from the Web Console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Log in to the OpenShift web console as <code>kubeadmin<\/code>.<\/li>\n\n\n\n<li>Switch to <strong>Administrator<\/strong> perspective.<\/li>\n\n\n\n<li>Go to <strong>Operators > OperatorHub<\/strong>.<\/li>\n\n\n\n<li>Search for:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">OpenShift Serverless Operator\n<\/code><\/span><\/pre>\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li>Click the Operator.<\/li>\n\n\n\n<li>Click <strong>Install<\/strong>.<\/li>\n\n\n\n<li>Use these settings:<\/li>\n<\/ol>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Setting<\/th><th>Value<\/th><\/tr><\/thead><tbody><tr><td>Installation mode<\/td><td>All namespaces on the cluster<\/td><\/tr><tr><td>Installed namespace<\/td><td><code>openshift-serverless<\/code><\/td><\/tr><tr><td>Update channel<\/td><td><code>stable<\/code><\/td><\/tr><tr><td>Approval strategy<\/td><td>Automatic<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<ol start=\"8\" class=\"wp-block-list\">\n<li>Click <strong>Install<\/strong>.<\/li>\n\n\n\n<li>Wait until the Operator status shows:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Succeeded\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option B: Install from CLI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create the Operator subscription YAML:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-13\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cat &lt;&lt;<span class=\"hljs-string\">'EOF'<\/span> &gt; serverless-operator.yaml\n<span class=\"hljs-attr\">apiVersion<\/span>: v1\n<span class=\"hljs-attr\">kind<\/span>: Namespace\n<span class=\"hljs-attr\">metadata<\/span>:\n  name: openshift-serverless\n---\napiVersion: operators.coreos.com\/v1\n<span class=\"hljs-attr\">kind<\/span>: OperatorGroup\n<span class=\"hljs-attr\">metadata<\/span>:\n  name: serverless-operators\n  <span class=\"hljs-attr\">namespace<\/span>: openshift-serverless\n<span class=\"hljs-attr\">spec<\/span>: {}\n---\napiVersion: operators.coreos.com\/v1alpha1\n<span class=\"hljs-attr\">kind<\/span>: Subscription\n<span class=\"hljs-attr\">metadata<\/span>:\n  name: serverless-operator\n  <span class=\"hljs-attr\">namespace<\/span>: openshift-serverless\n<span class=\"hljs-attr\">spec<\/span>:\n  channel: stable\n  <span class=\"hljs-attr\">installPlanApproval<\/span>: Automatic\n  <span class=\"hljs-attr\">name<\/span>: serverless-operator\n  <span class=\"hljs-attr\">source<\/span>: redhat-operators\n  <span class=\"hljs-attr\">sourceNamespace<\/span>: openshift-marketplace\nEOF\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-13\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Apply it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-14\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">apply<\/span> <span class=\"hljs-selector-tag\">-f<\/span> <span class=\"hljs-selector-tag\">serverless-operator<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-14\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Watch the installation:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-15\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-15\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check ClusterServiceVersion status:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-16\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-16\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Wait until the CSV phase is:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Succeeded\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You can watch it with:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-17\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">watch oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-17\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If <code>watch<\/code> is not available, run this repeatedly:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-18\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-18\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 5: Install Knative Serving<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">OpenShift Serverless Operator alone is not enough. To run functions, you must install Knative Serving.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Knative Serving allows you to create Knative Services and serverless functions.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option A: Install Knative Serving from Web Console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Log in as <code>kubeadmin<\/code>.<\/li>\n\n\n\n<li>Switch to <strong>Administrator<\/strong> perspective.<\/li>\n\n\n\n<li>Go to <strong>Operators > Installed Operators<\/strong>.<\/li>\n\n\n\n<li>Select project:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">knative-serving\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If the project does not exist yet, create it from <strong>Home &gt; Projects &gt; Create Project<\/strong>.<\/p>\n\n\n\n<ol start=\"5\" class=\"wp-block-list\">\n<li>Click <strong>OpenShift Serverless Operator<\/strong>.<\/li>\n\n\n\n<li>Find <strong>Knative Serving<\/strong> under provided APIs.<\/li>\n\n\n\n<li>Click <strong>Create Knative Serving<\/strong>.<\/li>\n\n\n\n<li>Keep the default settings.<\/li>\n\n\n\n<li>Click <strong>Create<\/strong>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">Wait until the <code>KnativeServing<\/code> resource is ready.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option B: Install Knative Serving from CLI<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Create the <code>knative-serving<\/code> namespace and <code>KnativeServing<\/code> resource:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-19\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cat &lt;&lt;<span class=\"hljs-string\">'EOF'<\/span> &gt; knative-serving.yaml\n<span class=\"hljs-attr\">apiVersion<\/span>: v1\n<span class=\"hljs-attr\">kind<\/span>: Namespace\n<span class=\"hljs-attr\">metadata<\/span>:\n  name: knative-serving\n---\napiVersion: operator.knative.dev\/v1beta1\n<span class=\"hljs-attr\">kind<\/span>: KnativeServing\n<span class=\"hljs-attr\">metadata<\/span>:\n  name: knative-serving\n  <span class=\"hljs-attr\">namespace<\/span>: knative-serving\nEOF\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-19\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Apply it:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-20\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">apply<\/span> <span class=\"hljs-selector-tag\">-f<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-20\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify the custom resource:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-21\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">get<\/span> <span class=\"hljs-selector-tag\">knativeserving<\/span><span class=\"hljs-selector-class\">.operator<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span> <span class=\"hljs-selector-tag\">-n<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-21\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check Knative Serving conditions:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-22\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">oc get knativeserving.operator.knative.dev knative-serving -n knative-serving \\\n  --template=<span class=\"hljs-string\">'{{range .status.conditions}}{{printf \"%s=%s\\n\" .type .status}}{{end}}'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-22\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result should show conditions with:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-23\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\"><span class=\"hljs-keyword\">True<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-23\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check pods:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-24\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n knative-serving\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-24\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see Knative Serving pods running.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Example components may include:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">activator\nautoscaler\ncontroller\nwebhook\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The exact pod names can vary by OpenShift Serverless version.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 6: Validate Serverless Installation<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc api-resources | grep -i knative\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check for Knative Service API:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc api-resources | grep ksvc\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result should include:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-25\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">services<\/span>   <span class=\"hljs-selector-tag\">ksvc<\/span>   <span class=\"hljs-selector-tag\">serving<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-25\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check Knative Serving namespace:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-26\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n knative-serving\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-26\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check OpenShift Serverless namespace:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-27\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-27\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If the Operator and Knative Serving pods are running, the platform setup is ready.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 7: Install and Validate the <code>kn<\/code> CLI<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>kn<\/code> CLI is the Knative command-line tool.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">It is required for the <code>kn func<\/code> workflow.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Install from Web Console<\/h2>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the OpenShift web console.<\/li>\n\n\n\n<li>Click the <strong>?<\/strong> icon in the upper-right corner.<\/li>\n\n\n\n<li>Click <strong>Command Line Tools<\/strong>.<\/li>\n\n\n\n<li>Download the Knative CLI for your operating system.<\/li>\n\n\n\n<li>Extract the archive.<\/li>\n\n\n\n<li>Move the <code>kn<\/code> binary into a directory on your <code>PATH<\/code>.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">On Linux or macOS, a typical location is:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">\/usr\/local\/bin\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">On Windows, put <code>kn.exe<\/code> in a folder included in your <code>PATH<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Validate <code>kn<\/code><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn version\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check that the function commands are available:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func --help\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-28\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Available Commands:\n  build\n  create\n  deploy\n  invoke\n  run\n  <span class=\"hljs-keyword\">delete<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-28\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The exact output may vary, but <code>kn func<\/code> should be recognized.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 8: Validate Podman or Docker<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">OpenShift Serverless Functions need a local container engine to build function images.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Podman is recommended for this lab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check Podman:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">podman version\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If you use Docker instead:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">docker version\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">For macOS or Windows with Podman, make sure the Podman machine is running:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-29\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">podman machine <span class=\"hljs-keyword\">list<\/span>\npodman machine start\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-29\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If Podman or Docker is not working, <code>kn func deploy<\/code> will fail during the build step.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 9: Prepare an Image Registry<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">When you deploy a function, the function image must be pushed to a container image registry.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You have two options:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Option<\/th><th>Best For<\/th><\/tr><\/thead><tbody><tr><td>OpenShift internal registry<\/td><td>Local OpenShift lab<\/td><\/tr><tr><td>Quay.io or another external registry<\/td><td>Real team workflow or if internal registry is difficult<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">For OpenShift Local classroom labs, use the OpenShift internal registry.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option A: Use OpenShift Internal Registry<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Log in as <code>kubeadmin<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-30\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc login -u kubeadmin https:<span class=\"hljs-comment\">\/\/api.crc.testing:6443<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-30\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expose the default OpenShift image registry route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-31\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc patch configs.imageregistry.operator.openshift.io\/cluster \\\n  --type=merge \\\n  -p <span class=\"hljs-string\">'{\"spec\":{\"defaultRoute\":true}}'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-31\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Wait for the default registry route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-32\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> route default-route -n openshift-image-registry\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-32\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Save the registry hostname:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-33\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">REGISTRY_HOST=$(oc get route <span class=\"hljs-keyword\">default<\/span>-route -n openshift-image-registry -o jsonpath=<span class=\"hljs-string\">'{.spec.host}'<\/span>)\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"$REGISTRY_HOST\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-33\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Log in to the registry with Podman:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-34\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">podman login --tls-verify=<span class=\"hljs-literal\">false<\/span> \\\n  -u <span class=\"hljs-string\">\"$(oc whoami)\"<\/span> \\\n  -p <span class=\"hljs-string\">\"$(oc whoami -t)\"<\/span> \\\n  <span class=\"hljs-string\">\"$REGISTRY_HOST\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-34\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If login succeeds, you are ready to push function images to the internal registry.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Option B: Use Quay.io<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Use this option only if the OpenShift internal registry route does not work in your local environment.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Log in to Quay.io:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-35\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">podman<\/span> <span class=\"hljs-selector-tag\">login<\/span> <span class=\"hljs-selector-tag\">quay<\/span><span class=\"hljs-selector-class\">.io<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-35\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">When deploying the function later, use an image name such as:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-36\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">quay.io\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">your-quay-username<\/span>&gt;<\/span>\/lab14-hello-func:latest\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-36\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Replace <code>&lt;your-quay-username&gt;<\/code> with your actual Quay username.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 10: Create a Student Project<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Log in as <code>developer<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-37\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc login -u developer https:<span class=\"hljs-comment\">\/\/api.crc.testing:6443<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-37\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create a new project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-38\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">new<\/span>-project lab14-serverless-functions\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-38\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc project\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-39\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Using project <span class=\"hljs-string\">\"lab14-serverless-functions\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-39\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 11: Create a Node.js Serverless Function<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Create a function:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func create -l node -t http lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-40\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Created node <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">in<\/span> <span class=\"hljs-title\">lab14<\/span>-<span class=\"hljs-title\">hello<\/span>-<span class=\"hljs-title\">func<\/span>\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-40\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Go into the function directory:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">cd lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">List the files:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">ls -la\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected files include:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-41\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">func<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<span class=\"hljs-selector-tag\">index<\/span><span class=\"hljs-selector-class\">.js<\/span>\n<span class=\"hljs-selector-tag\">package<\/span><span class=\"hljs-selector-class\">.json<\/span>\n<span class=\"hljs-selector-tag\">README<\/span><span class=\"hljs-selector-class\">.md<\/span>\n<span class=\"hljs-selector-tag\">test<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-41\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 12: Understand the Function Project<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">The function project contains:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>File or Directory<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><code>func.yaml<\/code><\/td><td>Function configuration<\/td><\/tr><tr><td><code>index.js<\/code><\/td><td>Function source code<\/td><\/tr><tr><td><code>package.json<\/code><\/td><td>Node.js dependencies and scripts<\/td><\/tr><tr><td><code>README.md<\/code><\/td><td>Function documentation<\/td><\/tr><tr><td><code>test\/<\/code><\/td><td>Unit and integration tests<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">The most important files for this beginner lab are:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-42\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">func<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<span class=\"hljs-selector-tag\">index<\/span><span class=\"hljs-selector-class\">.js<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-42\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 13: Replace the Function Code<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Open <code>index.js<\/code> and replace the content with the following code.<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-43\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cat &lt;&lt;<span class=\"hljs-string\">'EOF'<\/span> &gt; index.js\n<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">Function<\/span> = {\n  <span class=\"hljs-attr\">handle<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">context, body<\/span>) =&gt;<\/span> {\n    context.log.info(<span class=\"hljs-string\">'Lab 14 function was invoked'<\/span>);\n\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">'Hello from OpenShift Serverless Functions - Lab 14'<\/span>;\n  }\n};\n\n<span class=\"hljs-built_in\">module<\/span>.exports = <span class=\"hljs-built_in\">Function<\/span>;\nEOF\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-43\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This function returns a simple text response.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 14: Review <code>func.yaml<\/code><\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">View the function configuration:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-44\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">cat<\/span> <span class=\"hljs-selector-tag\">func<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-44\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see values such as:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-45\" data-shcb-language-name=\"HTTP\" data-shcb-language-slug=\"http\"><span><code class=\"hljs language-http\"><span class=\"hljs-attribute\">name<\/span>: lab14-hello-func\n<span class=\"hljs-attribute\">runtime<\/span>: node\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-45\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTTP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">http<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The exact content may vary depending on your <code>kn<\/code> version.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not manually change the file unless your instructor asks you to.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 15: Optional Local Run<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You can run the function locally before deploying it.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This step requires Podman or Docker to work correctly.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func run\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Open a second terminal and go into the same function directory:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">cd lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Invoke the local function:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func invoke\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-46\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Hello <span class=\"hljs-keyword\">from<\/span> OpenShift Serverless Functions - Lab <span class=\"hljs-number\">14<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-46\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Stop the local function by pressing:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Ctrl + C\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If local run does not work because of Podman or Docker networking, continue with cluster deployment.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 16: Deploy the Function to OpenShift<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Make sure you are in the function directory:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">pwd\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected path should end with:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Set the project:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc project lab14-serverless-functions\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Get the internal registry hostname if you are using the OpenShift internal registry:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-47\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">REGISTRY_HOST=$(oc get route <span class=\"hljs-keyword\">default<\/span>-route -n openshift-image-registry -o jsonpath=<span class=\"hljs-string\">'{.spec.host}'<\/span>)\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"$REGISTRY_HOST\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-47\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Deploy the function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-48\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">kn func deploy -i <span class=\"hljs-string\">\"$REGISTRY_HOST\/lab14-serverless-functions\/lab14-hello-func:latest\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-48\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output should include:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-49\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">Function<\/span> deployed at:\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-49\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This command builds the function image, pushes it to the image registry, and deploys it as a Knative Service.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Quay.io Alternative<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">If you are using Quay.io instead of the OpenShift internal registry, run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-50\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">kn func deploy -i \"quay.io\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">your-quay-username<\/span>&gt;<\/span>\/lab14-hello-func:latest\"\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-50\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Replace <code>&lt;your-quay-username&gt;<\/code> with your actual Quay username.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 17: Verify the Function Deployment<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Check Knative Services:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-51\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> ksvc\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-51\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-52\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">NAME                 URL                                      LATESTCREATED              LATESTREADY                READY\nlab14-hello-func     http:<span class=\"hljs-comment\">\/\/lab14-hello-func-...              lab14-hello-func-00001     lab14-hello-func-00001     True<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-52\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check with <code>kn<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-53\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">kn service <span class=\"hljs-keyword\">list<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-53\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result should include:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check all related Knative resources:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-54\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">get<\/span> <span class=\"hljs-selector-tag\">ksvc<\/span>,<span class=\"hljs-selector-tag\">revision<\/span>,<span class=\"hljs-selector-tag\">configuration<\/span>,<span class=\"hljs-selector-tag\">routes<\/span><span class=\"hljs-selector-class\">.serving<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-54\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see resources related to:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 18: Get the Function URL<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Get the function URL:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-55\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">FUNC_URL=$(oc get ksvc lab14-hello-func -o jsonpath=<span class=\"hljs-string\">'{.status.url}'<\/span>)\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-55\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected output:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-56\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">http:<span class=\"hljs-comment\">\/\/lab14-hello-func-lab14-serverless-functions.apps-crc.testing<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-56\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The exact hostname may be different.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 19: Invoke the Function<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Invoke using <code>kn func<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func invoke\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-57\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Hello <span class=\"hljs-keyword\">from<\/span> OpenShift Serverless Functions - Lab <span class=\"hljs-number\">14<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-57\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Invoke using <code>curl<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-58\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-58\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-59\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Hello <span class=\"hljs-keyword\">from<\/span> OpenShift Serverless Functions - Lab <span class=\"hljs-number\">14<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-59\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If the first request is slow, that can be normal. A scaled-to-zero function may need a few seconds to start.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 20: View Function Logs<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Check the Knative Service:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-60\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> ksvc lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-60\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check pods:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-61\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-61\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">View logs from the function pod:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc logs -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected log message:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-62\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Lab <span class=\"hljs-number\">14<\/span> <span class=\"hljs-function\"><span class=\"hljs-keyword\">function<\/span> <span class=\"hljs-title\">was<\/span> <span class=\"hljs-title\">invoked<\/span>\n<\/span><\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-62\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If no pod exists because the function scaled to zero, invoke the function again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-63\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-63\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then check logs again:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc logs -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 21: Observe Scale-to-Zero<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Knative Serving can scale a function down to zero pods when it is idle.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-64\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-64\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see a running pod shortly after invoking the function.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Now wait for a short idle period.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Run the command again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-65\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-65\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">After the function has been idle, the pod may disappear.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Expected result after scale-to-zero:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">No resources found\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">The exact time can vary based on cluster configuration.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 22: Observe Scale-from-Zero<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Invoke the function again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-66\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-66\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-67\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Hello <span class=\"hljs-keyword\">from<\/span> OpenShift Serverless Functions - Lab <span class=\"hljs-number\">14<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-67\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Immediately check pods:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-68\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-68\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see a new pod created for the function.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This proves that the function can scale from zero when traffic arrives.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 23: Inspect the Knative Service<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Describe the Knative Service:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">oc describe ksvc lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Look for:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">URL\nLatestCreatedRevisionName\nLatestReadyRevisionName\nReady\nRoutesReady\nConfigurationsReady\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check the latest revision:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-69\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> revision\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-69\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check the Knative configuration:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-70\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> configuration\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-70\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check the Knative route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-71\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">get<\/span> <span class=\"hljs-selector-tag\">routes<\/span><span class=\"hljs-selector-class\">.serving<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-71\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">These resources are created and managed by Knative Serving.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 24: Update the Function<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Modify the function response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-72\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cat &lt;&lt;<span class=\"hljs-string\">'EOF'<\/span> &gt; index.js\n<span class=\"hljs-keyword\">const<\/span> <span class=\"hljs-built_in\">Function<\/span> = {\n  <span class=\"hljs-attr\">handle<\/span>: <span class=\"hljs-function\">(<span class=\"hljs-params\">context, body<\/span>) =&gt;<\/span> {\n    context.log.info(<span class=\"hljs-string\">'Lab 14 function version 2 was invoked'<\/span>);\n\n    <span class=\"hljs-keyword\">return<\/span> <span class=\"hljs-string\">'Hello from OpenShift Serverless Functions - Lab 14 - Version 2'<\/span>;\n  }\n};\n\n<span class=\"hljs-built_in\">module<\/span>.exports = <span class=\"hljs-built_in\">Function<\/span>;\nEOF\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-72\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Deploy again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-73\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">kn func deploy -i <span class=\"hljs-string\">\"$REGISTRY_HOST\/lab14-serverless-functions\/lab14-hello-func:latest\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-73\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Invoke the function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-74\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-74\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected response:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-75\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">Hello <span class=\"hljs-keyword\">from<\/span> OpenShift Serverless Functions - Lab <span class=\"hljs-number\">14<\/span> - Version <span class=\"hljs-number\">2<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-75\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check revisions:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-76\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> revision\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-76\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">You should see more than one revision.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This shows that updating a function creates a new Knative revision.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 25: Validate from the Web Console<\/h1>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Open the OpenShift web console.<\/li>\n\n\n\n<li>Log in as <code>developer<\/code>.<\/li>\n\n\n\n<li>Select project:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">lab14-serverless-functions\n<\/code><\/span><\/pre>\n\n\n<ol start=\"4\" class=\"wp-block-list\">\n<li>Switch to <strong>Developer<\/strong> perspective.<\/li>\n\n\n\n<li>Go to <strong>Topology<\/strong>.<\/li>\n\n\n\n<li>You should see:<\/li>\n<\/ol>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">lab14-hello-func\n<\/code><\/span><\/pre>\n\n\n<ol start=\"7\" class=\"wp-block-list\">\n<li>Click the function.<\/li>\n\n\n\n<li>Check the <strong>Resources<\/strong> tab.<\/li>\n\n\n\n<li>Check pods, revisions, and routes if shown.<\/li>\n\n\n\n<li>Open the function URL from the console if available.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\">The web console layout can vary by OpenShift version, but the function should be visible as a serverless workload.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 26: Full Student Validation Script<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Run this from the function directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-77\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">oc project lab14-serverless-functions\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Checking Knative Service...\"<\/span>\noc get ksvc lab14-hello-func\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Checking URL...\"<\/span>\nFUNC_URL=$(oc get ksvc lab14-hello-func -o jsonpath=<span class=\"hljs-string\">'{.status.url}'<\/span>)\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Invoking function...\"<\/span>\ncurl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<span class=\"hljs-keyword\">echo<\/span>\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Checking Knative resources...\"<\/span>\noc get ksvc,revision,configuration,routes.serving.knative.dev\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Checking pods...\"<\/span>\noc get pods -l serving.knative.dev\/service=lab14-hello-func\n\n<span class=\"hljs-keyword\">echo<\/span> <span class=\"hljs-string\">\"Checking logs...\"<\/span>\noc logs -l serving.knative.dev\/service=lab14-hello-func --tail=<span class=\"hljs-number\">50<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-77\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Knative Service exists.<\/li>\n\n\n\n<li>Function URL exists.<\/li>\n\n\n\n<li>Function returns a response.<\/li>\n\n\n\n<li>Revision exists.<\/li>\n\n\n\n<li>Configuration exists.<\/li>\n\n\n\n<li>Knative Route exists.<\/li>\n\n\n\n<li>Pod exists after invocation.<\/li>\n\n\n\n<li>Logs show invocation output.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 27: Troubleshooting<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 1: <code>kn: command not found<\/code><\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Cause<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The Knative CLI is not installed or not in your <code>PATH<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Download <code>kn<\/code> from:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-78\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">OpenShift web <span class=\"hljs-built_in\">console<\/span> &gt; ? &gt; Command Line Tools\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-78\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Move the binary to a directory in your <code>PATH<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn version\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 2: <code>kn func<\/code> Is Not Recognized<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Cause<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">You may have an older or incorrect <code>kn<\/code> binary.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install the <code>kn<\/code> CLI version provided by your OpenShift Serverless installation.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Check:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func --help\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If this fails, reinstall the CLI from the OpenShift web console Command Line Tools page.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 3: OpenShift Serverless Operator Is Not Installed<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Symptom<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-79\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-79\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">fails or shows no serverless operator pods.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Install the OpenShift Serverless Operator using OperatorHub or the CLI YAML from this lab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-80\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-80\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected phase:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">Succeeded\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 4: Knative Serving Is Missing<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Symptom<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-81\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> ksvc\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-81\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">returns an error such as:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">the server doesn't have a resource type \"ksvc\"\n<\/code><\/span><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Cause<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Knative Serving is not installed.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Create the <code>KnativeServing<\/code> resource:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-82\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">apply<\/span> <span class=\"hljs-selector-tag\">-f<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span><span class=\"hljs-selector-class\">.yaml<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-82\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-83\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -n knative-serving\noc api-resources | grep ksvc\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-83\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 5: Function Build Fails<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Possible Causes<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Podman or Docker is not running.<\/li>\n\n\n\n<li>Image registry login failed.<\/li>\n\n\n\n<li>Registry route is not exposed.<\/li>\n\n\n\n<li>TLS verification failed.<\/li>\n\n\n\n<li>Laptop does not have enough CPU or memory.<\/li>\n\n\n\n<li>Network\/VPN blocks registry access.<\/li>\n<\/ol>\n\n\n\n<h3 class=\"wp-block-heading\">Check<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">podman version\npodman info\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check registry route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-84\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> route default-route -n openshift-image-registry\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-84\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check registry login:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-85\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">REGISTRY_HOST=$(oc get route <span class=\"hljs-keyword\">default<\/span>-route -n openshift-image-registry -o jsonpath=<span class=\"hljs-string\">'{.spec.host}'<\/span>)\n\npodman login --tls-verify=<span class=\"hljs-keyword\">false<\/span> \\\n  -u <span class=\"hljs-string\">\"$(oc whoami)\"<\/span> \\\n  -p <span class=\"hljs-string\">\"$(oc whoami -t)\"<\/span> \\\n  <span class=\"hljs-string\">\"$REGISTRY_HOST\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-85\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Try deploy again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-86\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">kn func deploy -i <span class=\"hljs-string\">\"$REGISTRY_HOST\/lab14-serverless-functions\/lab14-hello-func:latest\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-86\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 6: Function Deploy Fails with Registry Push Error<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Cause<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">The function image cannot be pushed to the registry.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Fix Option 1: Re-login to OpenShift Registry<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-87\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">REGISTRY_HOST=$(oc get route <span class=\"hljs-keyword\">default<\/span>-route -n openshift-image-registry -o jsonpath=<span class=\"hljs-string\">'{.spec.host}'<\/span>)\n\npodman login --tls-verify=<span class=\"hljs-keyword\">false<\/span> \\\n  -u <span class=\"hljs-string\">\"$(oc whoami)\"<\/span> \\\n  -p <span class=\"hljs-string\">\"$(oc whoami -t)\"<\/span> \\\n  <span class=\"hljs-string\">\"$REGISTRY_HOST\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-87\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Deploy again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-88\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">kn func deploy -i <span class=\"hljs-string\">\"$REGISTRY_HOST\/lab14-serverless-functions\/lab14-hello-func:latest\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-88\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<h3 class=\"wp-block-heading\">Fix Option 2: Use Quay.io<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-89\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">podman login quay.io\nkn func deploy -i \"quay.io\/<span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">your-quay-username<\/span>&gt;<\/span>\/lab14-hello-func:latest\"\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-89\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 7: Function URL Does Not Open<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Check<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-90\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> ksvc lab14-hello-func\noc describe ksvc lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-90\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check URL:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-91\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">oc get ksvc lab14-hello-func -o jsonpath=<span class=\"hljs-string\">'{.status.url}'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-91\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check Knative route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-92\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">get<\/span> <span class=\"hljs-selector-tag\">routes<\/span><span class=\"hljs-selector-class\">.serving<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-92\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Check pods:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-93\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-93\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Invoke again:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-94\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -v <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-94\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If DNS fails on your laptop, check CRC status:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">crc status\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 8: Function Returns Slowly on First Request<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This can be normal.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the function scaled to zero, the first request must start a new pod.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">This is called:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-95\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">scale-<span class=\"hljs-keyword\">from<\/span>-zero\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-95\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Second and later requests are usually faster while the pod is still running.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 9: No Function Pod Is Running<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This may be normal if the function scaled to zero.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Invoke the function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-96\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">curl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-96\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Then check pods immediately:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-97\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> pods -l serving.knative.dev\/service=lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-97\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Problem 10: Web Console Function Creation Is Not Available<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The web console function workflow requires additional setup, including OpenShift Pipelines and function pipeline tasks.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For this lab, use the CLI workflow with:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func create\nkn func deploy\nkn func invoke\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This is simpler and more reliable for beginner students.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 28: Cleanup Student Resources<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Delete the function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-98\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">delete<\/span> ksvc lab14-hello-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-98\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Or, from the function directory:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-99\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">kn func <span class=\"hljs-keyword\">delete<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-99\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete the project:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-100\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">delete<\/span> project lab14-serverless-functions\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-100\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Verify:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-101\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> project lab14-serverless-functions\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-101\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Expected result:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">NotFound\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 29: Optional Admin Cleanup<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Only run this if the OpenShift Local cluster is used only for this lab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Do not remove shared Serverless components from a classroom cluster unless the instructor confirms.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Log in as <code>kubeadmin<\/code>:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-102\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc login -u kubeadmin https:<span class=\"hljs-comment\">\/\/api.crc.testing:6443<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-102\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete Knative Serving:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-103\" data-shcb-language-name=\"CSS\" data-shcb-language-slug=\"css\"><span><code class=\"hljs language-css\"><span class=\"hljs-selector-tag\">oc<\/span> <span class=\"hljs-selector-tag\">delete<\/span> <span class=\"hljs-selector-tag\">knativeserving<\/span><span class=\"hljs-selector-class\">.operator<\/span><span class=\"hljs-selector-class\">.knative<\/span><span class=\"hljs-selector-class\">.dev<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span> <span class=\"hljs-selector-tag\">-n<\/span> <span class=\"hljs-selector-tag\">knative-serving<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-103\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">CSS<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">css<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete Knative Serving namespace:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-104\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">delete<\/span> namespace knative-serving\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-104\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete the Serverless Operator subscription:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-105\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">delete<\/span> subscription serverless-operator -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-105\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">List CSVs:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-106\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-106\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete the Serverless CSV shown in the output if required:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-107\" data-shcb-language-name=\"HTML, XML\" data-shcb-language-slug=\"xml\"><span><code class=\"hljs language-xml\">oc delete csv <span class=\"hljs-tag\">&lt;<span class=\"hljs-name\">serverless-csv-name<\/span>&gt;<\/span> -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-107\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">HTML, XML<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">xml<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Delete the Serverless namespace:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-108\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">delete<\/span> namespace openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-108\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 30: Lab Summary<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">In this lab, you installed and used OpenShift Serverless Functions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You created:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Resource<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td>OpenShift Serverless Operator<\/td><td>Manages Knative components<\/td><\/tr><tr><td>KnativeServing<\/td><td>Installs Knative Serving<\/td><\/tr><tr><td>Project<\/td><td>Isolated namespace for the function<\/td><\/tr><tr><td>Function source<\/td><td>Node.js function code<\/td><\/tr><tr><td>Container image<\/td><td>Built function runtime image<\/td><\/tr><tr><td>Knative Service<\/td><td>Serverless runtime resource<\/td><\/tr><tr><td>Revision<\/td><td>Immutable version of the function<\/td><\/tr><tr><td>Configuration<\/td><td>Knative configuration state<\/td><\/tr><tr><td>Knative Route<\/td><td>Function URL routing<\/td><\/tr><tr><td>Pod<\/td><td>Runtime instance created when traffic arrives<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">You verified that:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>OpenShift Serverless is installed.<\/li>\n\n\n\n<li>Knative Serving is running.<\/li>\n\n\n\n<li><code>kn func<\/code> can create functions.<\/li>\n\n\n\n<li>A Node.js function can be deployed.<\/li>\n\n\n\n<li>The function can be invoked by URL.<\/li>\n\n\n\n<li>The function can scale to zero.<\/li>\n\n\n\n<li>The function can scale from zero when traffic arrives.<\/li>\n\n\n\n<li>Updating the function creates a new revision.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 31: Review Questions<\/h1>\n\n\n\n<h2 class=\"wp-block-heading\">Question 1<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">What is OpenShift Serverless based on?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Knative.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 2<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Which OpenShift Serverless component is required to run functions?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Knative Serving.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 3<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Which CLI command creates a function?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func create\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 4<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Which CLI command deploys a function?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func deploy\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 5<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Which CLI command invokes a function?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn func invoke\n<\/code><\/span><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 6<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">What OpenShift resource is created when a function is deployed?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">A Knative Service.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 7<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">What command lists Knative Services?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-109\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> ksvc\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-109\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 8<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">What is scale-to-zero?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Scale-to-zero means the function pod is removed when the function is idle.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 9<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">What is scale-from-zero?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Scale-from-zero means a new function pod is created automatically when a request arrives.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Question 10<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Why does the first request sometimes take longer?<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Answer<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Because the function may need to start from zero pods before it can serve the request.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 32: Instructor Notes<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">This lab intentionally uses the CLI-based <code>kn func<\/code> workflow instead of the web-console function creation workflow.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Reason:<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The web-console function workflow requires additional setup such as OpenShift Pipelines and function-specific pipeline tasks. That is useful for an advanced lab, but it adds too much complexity for a first serverless functions lab.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Recommended follow-up labs:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create functions from the OpenShift web console.<\/li>\n\n\n\n<li>Install OpenShift Pipelines for function builds.<\/li>\n\n\n\n<li>Connect an event source to a function.<\/li>\n\n\n\n<li>Use Knative Eventing.<\/li>\n\n\n\n<li>Trigger functions from Kafka.<\/li>\n\n\n\n<li>Configure function environment variables.<\/li>\n\n\n\n<li>Use ConfigMaps and Secrets with functions.<\/li>\n\n\n\n<li>Configure function concurrency.<\/li>\n\n\n\n<li>Configure autoscaling.<\/li>\n\n\n\n<li>Configure custom domains and TLS.<\/li>\n\n\n\n<li>Observe serverless metrics.<\/li>\n\n\n\n<li>Deploy Quarkus, Python, Go, and TypeScript functions.<\/li>\n\n\n\n<li>Deploy serverless applications using GitOps.<\/li>\n<\/ol>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Part 33: Instructor Pre-Validation Checklist<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">Before delivering this lab to students, run:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-110\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">crc status\noc whoami\noc <span class=\"hljs-keyword\">get<\/span> nodes\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-110\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Validate Serverless Operator:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-111\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> csv -n openshift-serverless\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-111\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Validate Knative Serving:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-112\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">oc get pods -n knative-serving\noc get knativeserving.operator.knative.dev knative-serving -n knative-serving \\\n  --template=<span class=\"hljs-string\">'{{range .status.conditions}}{{printf \"%s=%s\\n\" .type .status}}{{end}}'<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-112\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Validate CLI:<\/p>\n\n\n<pre class=\"wp-block-code\"><span><code class=\"hljs\">kn version\nkn func --help\npodman version\n<\/code><\/span><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Validate registry route:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-113\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">oc <span class=\"hljs-keyword\">get<\/span> route default-route -n openshift-image-registry\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-113\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Create a test function:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-114\" data-shcb-language-name=\"PHP\" data-shcb-language-slug=\"php\"><span><code class=\"hljs language-php\">oc <span class=\"hljs-keyword\">new<\/span>-project lab14-validation\nkn func create -l node -t http lab14-test-func\ncd lab14-test-func\n\nREGISTRY_HOST=$(oc get route <span class=\"hljs-keyword\">default<\/span>-route -n openshift-image-registry -o jsonpath=<span class=\"hljs-string\">'{.spec.host}'<\/span>)\n\nkn func deploy -i <span class=\"hljs-string\">\"$REGISTRY_HOST\/lab14-validation\/lab14-test-func:latest\"<\/span>\n\nFUNC_URL=$(oc get ksvc lab14-test-func -o jsonpath=<span class=\"hljs-string\">'{.status.url}'<\/span>)\ncurl -s <span class=\"hljs-string\">\"$FUNC_URL\"<\/span>\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-114\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">PHP<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">php<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">Clean up:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-115\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\">cd ..\noc <span class=\"hljs-keyword\">delete<\/span> project lab14-validation\nrm -rf lab14-test-func\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-115\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">If the function deploys and responds successfully, the lab is ready for students.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h1 class=\"wp-block-heading\">Final Outcome<\/h1>\n\n\n\n<p class=\"wp-block-paragraph\">You have successfully completed OpenShift Lab 14.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You installed OpenShift Serverless, installed Knative Serving, created a Node.js serverless function, deployed it as a Knative Service, invoked it through a URL, checked the generated Knative resources, and observed serverless scale-to-zero behavior.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The final workflow is:<\/p>\n\n\n<pre class=\"wp-block-code\" aria-describedby=\"shcb-language-116\" data-shcb-language-name=\"JavaScript\" data-shcb-language-slug=\"javascript\"><span><code class=\"hljs language-javascript\"><span class=\"hljs-built_in\">Function<\/span> source code\n  -&gt; kn func build\/deploy\n  -&gt; container image\n  -&gt; Knative Service\n  -&gt; Revision\n  -&gt; Pod on demand\n  -&gt; <span class=\"hljs-built_in\">Function<\/span> URL\n  -&gt; scale to zero when idle\n<\/code><\/span><small class=\"shcb-language\" id=\"shcb-language-116\"><span class=\"shcb-language__label\">Code language:<\/span> <span class=\"shcb-language__name\">JavaScript<\/span> <span class=\"shcb-language__paren\">(<\/span><span class=\"shcb-language__slug\">javascript<\/span><span class=\"shcb-language__paren\">)<\/span><\/small><\/pre>\n\n\n<p class=\"wp-block-paragraph\">This is one of the most important OpenShift developer workflows for event-driven and request-driven workloads.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Lab Objective In this lab, you will install and use OpenShift Serverless Functions on OpenShift Local. You will create a simple Node.js serverless function, deploy it to&#8230; <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_joinchat":[],"footnotes":""},"categories":[5153],"tags":[],"class_list":["post-50040","post","type-post","status-publish","format-standard","hentry","category-openshift"],"_links":{"self":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50040","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/comments?post=50040"}],"version-history":[{"count":4,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50040\/revisions"}],"predecessor-version":[{"id":77172,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/posts\/50040\/revisions\/77172"}],"wp:attachment":[{"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/media?parent=50040"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/categories?post=50040"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.devopsschool.com\/blog\/wp-json\/wp\/v2\/tags?post=50040"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}