<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Shashank Sharma</title>
    <description>The latest articles on DEV Community by Shashank Sharma (@shashankft9).</description>
    <link>https://dev.to/shashankft9</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F840377%2Fa38b03df-0881-4cd8-8aa2-0a36391e141d.jpeg</url>
      <title>DEV Community: Shashank Sharma</title>
      <link>https://dev.to/shashankft9</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shashankft9"/>
    <language>en</language>
    <item>
      <title>Building functions with Knative and Tekton</title>
      <dc:creator>Shashank Sharma</dc:creator>
      <pubDate>Mon, 18 Apr 2022 05:39:57 +0000</pubDate>
      <link>https://dev.to/kcdchennai/building-functions-with-knative-and-tekton-php</link>
      <guid>https://dev.to/kcdchennai/building-functions-with-knative-and-tekton-php</guid>
      <description>&lt;p&gt;Knative was recently &lt;a href="https://www.cncf.io/blog/2022/03/02/knative-accepted-as-a-cncf-incubating-project/" rel="noopener noreferrer"&gt;accepted as a CNCF incubation project&lt;/a&gt; and there are so many exciting things about it(!), one of them being the evolution and adoption of its components. Through this blog, we will be looking at one such component - &lt;code&gt;func&lt;/code&gt; plugin; creating a function in &lt;code&gt;go&lt;/code&gt; runtime in our local machine and then pushing it to a github repository and finally initiating its deployment. Once the function is deployed, we will be provided with a URL through which we can access it.&lt;/p&gt;

&lt;p&gt;The expectation out of this is for a developer to get as comfortable as possible with writing functions, and essentially reach a point where they no longer have to worry about low level k8s resources (and ops in general). This would also mean that to run our code in a k8s cluster, we'd essentially need to run &lt;strong&gt;just one&lt;/strong&gt; command. &lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;A v1.21 k8s cluster or later versions. It is possible to run this blog on older versions, but for that, knative and tekton versions will have to be installed accordingly - check their releases for more details. &lt;br&gt;
&lt;em&gt;Warning: This blog requires administrator privileges on the k8s cluster, and the function builds happen on privileged containers.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Installing Knative and Tekton
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Knative has many components but for this blog we will stick to &lt;em&gt;serving&lt;/em&gt; which is the only component required to run functions and enable features like deployment, scaling, ingress configuration - basically the component that helps with the lifecycle of a function. &lt;br&gt;
For installation refer to &lt;a href="https://knative.dev/docs/install/yaml-install/serving/install-serving-with-yaml/" rel="noopener noreferrer"&gt;installing Serving documentation&lt;/a&gt; or run the following commands:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://github.com/knative/serving/releases/download/knative-v1.3.0/serving-crds.yaml" rel="noopener noreferrer"&gt;https://github.com/knative/serving/releases/download/knative-v1.3.0/serving-crds.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://github.com/knative/serving/releases/download/knative-v1.3.0/serving-core.yaml" rel="noopener noreferrer"&gt;https://github.com/knative/serving/releases/download/knative-v1.3.0/serving-core.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://github.com/knative/net-kourier/releases/download/knative-v1.3.0/kourier.yaml" rel="noopener noreferrer"&gt;https://github.com/knative/net-kourier/releases/download/knative-v1.3.0/kourier.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kubectl patch configmap/config-network \
--namespace knative-serving \
--type merge \
--patch '{"data":{"ingress.class":"kourier.ingress.networking.knative.dev"}}'&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;For this blog we are going to use slightly changed &lt;code&gt;func&lt;/code&gt; cli (which usually can be installed from &lt;a href="https://https://github.com/knative-sandbox/kn-plugin-func/releases" rel="noopener noreferrer"&gt;kn-pluging-func releases&lt;/a&gt;), so we can clone the &lt;a href="https://github.com/Shashankft9/kn-plugin-func/tree/pipeline-configure" rel="noopener noreferrer"&gt;forked repo&lt;/a&gt; and run &lt;code&gt;make install&lt;/code&gt; to generate the binary, and use it like any other cli. This change is still a WIP in upstream, to know more about it, you can follow this &lt;a href="https://github.com/knative-sandbox/kn-plugin-func/issues/827" rel="noopener noreferrer"&gt;issue&lt;/a&gt; and this &lt;a href="https://github.com/knative-sandbox/kn-plugin-func/pull/830" rel="noopener noreferrer"&gt;pr&lt;/a&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;To install Tekton Pipelines refer to &lt;a href="https://github.com/tektoncd/pipeline/blob/main/docs/install.md" rel="noopener noreferrer"&gt;Tekton Pipelines documentation&lt;/a&gt; or run the following command:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;kubectl apply -f &lt;a href="https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml" rel="noopener noreferrer"&gt;https://storage.googleapis.com/tekton-releases/pipeline/latest/release.yaml&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check that both Knative Serving and Tekton Pipelines components are running by checking the status of pods in &lt;code&gt;knative-serving&lt;/code&gt; and &lt;code&gt;tekton-pipelines&lt;/code&gt; namespaces. &lt;/p&gt;
&lt;h2&gt;
  
  
  Writing the function
&lt;/h2&gt;

&lt;p&gt;Following command will create a local repository &lt;code&gt;kcd-chennai&lt;/code&gt; containing the function signature in &lt;code&gt;handle.go&lt;/code&gt; and the function configuration parameters in &lt;code&gt;func.yaml&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ func create -l go kcd-chennai
Created go Function in /home/shashank/kcd-chennai
$ ls
func.yaml  go.mod  handle.go  handle_test.go  README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can edit the &lt;code&gt;handle.go&lt;/code&gt; file to add our custom code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package function

import (
        "context"
        "fmt"
        "net/http"
)

// Handle an HTTP Request.
func Handle(ctx context.Context, res http.ResponseWriter, req *http.Request) {
        fmt.Println("received a request")       
        fmt.Fprintln(res, "Hello from KCD Chennai! Read more about us here: https://community.cncf.io/events/details/cncf-kcd-chennai-presents-kubernetes-community-days-chennai-2022/") // Send KCD community link back to the client
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Info: Notice that we didnt have to write most of the go code that we'd usually write, we simply just added our business logic. &lt;br&gt;
This is an &lt;code&gt;http&lt;/code&gt; template, but there is also a &lt;a href="https://cloudevents.io/" rel="noopener noreferrer"&gt;&lt;code&gt;cloudevent&lt;/code&gt;&lt;/a&gt; template which is more relevant in the world of FaaS and serverless, but out of scope for this blog.&lt;/em&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Building the function
&lt;/h2&gt;

&lt;p&gt;Now we will see, how we can build this code and deploy it on kubernetes and successfully invoke it using a URL.&lt;/p&gt;
&lt;h4&gt;
  
  
  Building locally
&lt;/h4&gt;

&lt;p&gt;We can run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ func deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FLr6XUKw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FLr6XUKw.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Our function is now available on the URL &lt;code&gt;http://kcd-chennai.default.example.com&lt;/code&gt;.&lt;br&gt;
To access this URL from outside the k8s cluster, ideally we'd need the &lt;code&gt;kourier&lt;/code&gt; service in &lt;code&gt;kourier-system&lt;/code&gt; namespace to have a discoverable &lt;code&gt;ExternalIP&lt;/code&gt;, but for this blog we can try to hit the function URL from within the cluster using the following two commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export ingressIP=$(kubectl get svc kourier --namespace kourier-system -ojsonpath='{.spec.clusterIP}')
curl $ingressIP -H "Host: kcd-chennai.default.example.com"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Info: It's possible to configure the hostname of this function to a custom value, or to even explicitly make the function private to our cluster and then access it using &lt;code&gt;http://kcd-chennai.default.svc.cluster.local&lt;/code&gt; (we can also use this URL to access the function instead of the above 2 commands).&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Building from github repo on-cluster
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FwL56Kvo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fi.imgur.com%2FwL56Kvo.png"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To do this, we'd need to push our local code to a github repo and create some tekton resources as describe below, tekton being a cloud native CICD system, will use those resources to run a pipeline for things like - cloning our code, building it and then deploying the function.&lt;br&gt;
&lt;em&gt;Warning: We'd need persistent volume claims to be working in our cluster, since the code will be cloned in there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;For tekton to do its job, we need to run following commands:&lt;/p&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-clone/0.4/git-clone.yaml" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/tektoncd/catalog/master/task/git-clone/0.4/git-clone.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://raw.githubusercontent.com/Shashankft9/kn-plugin-func/pipeline-configure/pipelines/resources/tekton/task/buildpacks/0.3/buildpacks.yaml" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/Shashankft9/kn-plugin-func/pipeline-configure/pipelines/resources/tekton/task/buildpacks/0.3/buildpacks.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;kubectl apply -f &lt;a href="https://raw.githubusercontent.com/knative-sandbox/kn-plugin-func/main/pipelines/resources/tekton/task/func-deploy/0.1/func-deploy.yaml" rel="noopener noreferrer"&gt;https://raw.githubusercontent.com/knative-sandbox/kn-plugin-func/main/pipelines/resources/tekton/task/func-deploy/0.1/func-deploy.yaml&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next we have to change the configuration in &lt;code&gt;func.yaml&lt;/code&gt; to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;build: git
git:
  url: https://github.com/Shashankft9/kcd-chennai.git
  revision: master
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, run the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ func deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Follow the video below to see the progress of build and how we can access the function.&lt;br&gt;
&lt;a href="http://www.youtube.com/watch?v=qt90X0xTfFc" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fimg.youtube.com%2Fvi%2Fqt90X0xTfFc%2F0.jpg" alt="function build using tekton"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Inherent function features from Knative
&lt;/h2&gt;

&lt;p&gt;Since the functions are running with knative serving layer, it leverages some of the features listed below (non exhaustive):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;autoscaling on the basis of rps/concurrency.&lt;/li&gt;
&lt;li&gt;automatic ingress configuration, we use tls as well.&lt;/li&gt;
&lt;li&gt;scale to and from zero by default.&lt;/li&gt;
&lt;li&gt;can work with many languages like go, python, rust, node, springboot etc.&lt;/li&gt;
&lt;li&gt;readiness and liveness probes configured automatically for functions.&lt;/li&gt;
&lt;li&gt;no need to create service, deployment and other resource files with labels, ports etc.&lt;/li&gt;
&lt;li&gt;easier and faster deployments.&lt;/li&gt;
&lt;li&gt;prometheus metrics like &lt;code&gt;http_requests_total&lt;/code&gt; with respective response codes are exposed.&lt;/li&gt;
&lt;li&gt;traffic splitting, progressive rollouts available.&lt;/li&gt;
&lt;li&gt;ability to handle unstable windows, sudden traffic bursts with scaling configuration. &lt;/li&gt;
&lt;li&gt;easy integration with an event driven architecture because of the usage of cloudevents.&lt;/li&gt;
&lt;li&gt;more secure deployments because function builds use &lt;a href="https://buildpacks.io/" rel="noopener noreferrer"&gt;Buildpacks&lt;/a&gt; under the hood.&lt;/li&gt;
&lt;li&gt;by using Tekton for builds, we can easily configure the pipeline to add features like cloning code from a private github repo and more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Things you can explore as a follow-up to get more comfortable with what we did in this blog:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/knative-sandbox/kn-plugin-func" rel="noopener noreferrer"&gt;https://github.com/knative-sandbox/kn-plugin-func&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://knative.dev/docs/serving/" rel="noopener noreferrer"&gt;https://knative.dev/docs/serving/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.youtube.com/c/KnativeProject/videos" rel="noopener noreferrer"&gt;https://www.youtube.com/c/KnativeProject/videos&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://slack.knative.dev/" rel="noopener noreferrer"&gt;https://slack.knative.dev/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cloudevents/sdk-go" rel="noopener noreferrer"&gt;https://github.com/cloudevents/sdk-go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you got stuck at any of the steps in the blog or want to report any issues, feel free to ping me (Shashank Sharma) in the knative slack - thanks!&lt;/p&gt;

</description>
      <category>knative</category>
      <category>functions</category>
      <category>tekton</category>
      <category>faas</category>
    </item>
  </channel>
</rss>
