copyright | lastupdated | ||
---|---|---|---|
|
2019-04-11 |
{:new_window: target="_blank"} {:shortdesc: .shortdesc} {:screen: .screen} {:pre: .pre} {:table: .aria-labeledby="caption"} {:codeblock: .codeblock} {:tip: .tip} {:note: .note} {:important: .important} {:deprecated: .deprecated} {:download: .download}
{: #knative_tutorial}
With this tutorial, you can learn how to install Knative in a Kubernetes cluster in {{site.data.keyword.containerlong_notm}}. {: shortdesc}
What is Knative and why should I use it?
Knative is an open source platform that was developed by IBM, Google, Pivotal, Red Hat, Cisco, and others with the target to extend the capabilities of Kubernetes to help you create modern, source-centric containerized and serverless apps on top of your Kubernetes cluster. The platform is designed to address the needs of developers who today must decide what type of app they want to run in the cloud: 12-factor apps, containers, or functions. Each type of app requires an open source or proprietary solution that is tailored to these apps: Cloud Foundry for 12-factor apps, Kubernetes for containers, and OpenWhisk, and others for functions. In the past, developers had to decide what approach they wanted to follow, which led to inflexibility and complexity when different types of apps had to be combined.
Knative uses a consistent approach across programming languages and frameworks to abstract the operational burden of building, deploying and managing workloads in Kubernetes so that developers can focus on what matters most to them: the source code. You can use proven build packs that you are already familiar with, such as Cloud Foundry, Kaniko, Dockerfile, Bazel, and others. By integrating with Istio, Knative ensures that your serverless and containerized workloads can be easily exposed on the internet, monitored, and controlled, and that your data is encrypted during transit.
How does Knative work?
Knative comes with 3 key components, or primitives, that help you to build, deploy, and manage your serverless apps in your Kubernetes cluster:
- Build: The
Build
primitive supports creating a set of steps to build your app from source code to a container image. Imagine using a simple build template where you specify the source repo to find your app code and the container registry where you want to host the image. With just a single command, you can instruct Knative to take this build template, pull the source code, create the image and push the image to your container registry so that you can use the image in your container. - Serving: The
Serving
primitive helps to deploy serverless apps as Knative services and to automatically scale them, even down to zero instances. By using the traffic management and intelligent routing capabilities of Istio, you can control what traffic is routed to a specific version of your service which makes it easy for a developer to test and roll out a new app version or do A-B testing. - Eventing: With the
Eventing
primitive, you can create triggers or event streams that other services can subscribe to. For example, you might want to kick off a new build of your app every time code is pushed to your GitHub master repo. Or you want to run a serverless app only if the temperature drops below freezing point. TheEventing
primitive can be integrated into your CI/CD pipeline to automate the build and deployment of apps in case a specific event occurs.
What is the Managed Knative on {{site.data.keyword.containerlong_notm}} (experimental) add-on?
Managed Knative on {{site.data.keyword.containerlong_notm}} is a managed add-on that integrates Knative and Istio directly with your Kubernetes cluster. The Knative and Istio version in the add-on are tested by IBM and supported for the use in {{site.data.keyword.containerlong_notm}}. For more information about managed add-ons, see Adding services by using managed add-ons.
Are there any limitations?
If you installed the container image security enforcer admission controller in your cluster, you cannot enable the managed Knative add-on in your cluster.
Sounds good? Follow this tutorial to get started with Knative in {{site.data.keyword.containerlong_notm}}.
{: #knative_objectives}
- Learn the basics about Knative and the Knative primitives.
- Install the managed Knative and managed Istio add-on in your cluster.
- Deploy your first serverless app with Knative and expose the app on the internet by using the Knative
Serving
primitive. - Explore the Knative scaling and revision capabilities.
{: #knative_time}
30 minutes
{: #knative_audience}
This tutorial is designed for developers who are interested in learning how to use Knative to deploy a serverless app in a Kubernetes cluster, and for cluster administrators who want to learn how to set up Knative in a cluster.
{: #knative_prerequisites}
- Install the IBM Cloud CLI, the {{site.data.keyword.containerlong_notm}} plug-in, and the Kubernetes CLI. Make sure to install the
kubectl
CLI version that matches the Kubernetes version of your cluster. - Create a cluster with at least 3 worker nodes that each have 4 cores and 16 GB memory (
b3c.4x16
) or more. Every worker node must run Kubernetes version 1.12 or higher. - Ensure you have the Writer or Manager {{site.data.keyword.Bluemix_notm}} IAM service role for {{site.data.keyword.containerlong_notm}}.
- Target the CLI to your cluster.
{: #knative_setup}
Knative builds on top of Istio to ensure that your serverless and containerized workloads can be exposed within the cluster and on the internet. With Istio, you can also monitor and control network traffic between your services and ensure that your data is encrypted during transit. When you install the managed Knative add-on, the managed Istio add-on is automatically installed as well. {: shortdesc}
-
Enable the managed Knative add-on in your cluster. When you enable Knative in your cluster, Istio and all Knative components are installed in your cluster.
ibmcloud ks cluster-addon-enable knative --cluster <cluster_name_or_ID> -y
{: pre}
Example output:
Enabling add-on knative for cluster knative... OK
{: screen}
The installation of all Knative components might take a few minutes to complete.
-
Verify that Istio is successfully installed. All pods for the 9 Istio services and the pod for Prometheus must be in a
Running
status.kubectl get pods --namespace istio-system
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE istio-citadel-748d656b-pj9bw 1/1 Running 0 2m istio-egressgateway-6c65d7c98d-l54kg 1/1 Running 0 2m istio-galley-65cfbc6fd7-bpnqx 1/1 Running 0 2m istio-ingressgateway-f8dd85989-6w6nj 1/1 Running 0 2m istio-pilot-5fd885964b-l4df6 2/2 Running 0 2m istio-policy-56f4f4cbbd-2z2bk 2/2 Running 0 2m istio-sidecar-injector-646655c8cd-rwvsx 1/1 Running 0 2m istio-statsd-prom-bridge-7fdbbf769-8k42l 1/1 Running 0 2m istio-telemetry-8687d9d745-mwjbf 2/2 Running 0 2m prometheus-55c7c698d6-f4drj 1/1 Running 0 2m
{: screen}
-
Optional: If you want to use Istio for all apps in the
default
namespace, add theistio-injection=enabled
label to the namespace. Each serverless app pod must run an Envoy proxy sidecar so that the app can be included in the Istio service mesh. This label allows Istio to automatically modify the pod template specification in new app deployments so that pods are created with Envoy proxy sidecar containers.
kubectl label namespace default istio-injection=enabled
{: pre}
- Verify that all Knative components are successfully installed.
-
Verify that all pods of the Knative
Serving
component are in aRunning
state.kubectl get pods --namespace knative-serving
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE activator-598b4b7787-ps7mj 2/2 Running 0 21m autoscaler-5cf5cfb4dc-mcc2l 2/2 Running 0 21m controller-7fc84c6584-qlzk2 1/1 Running 0 21m webhook-7797ffb6bf-wg46v 1/1 Running 0 21m
{: screen}
-
Verify that all pods of the Knative
Build
component are in aRunning
state.kubectl get pods --namespace knative-build
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE build-controller-79cb969d89-kdn2b 1/1 Running 0 21m build-webhook-58d685fc58-twwc4 1/1 Running 0 21m
{: screen}
-
Verify that all pods of the Knative
Eventing
component are in aRunning
state.kubectl get pods --namespace knative-eventing
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE eventing-controller-847d8cf969-kxjtm 1/1 Running 0 22m in-memory-channel-controller-59dd7cfb5b-846mn 1/1 Running 0 22m in-memory-channel-dispatcher-67f7497fc-dgbrb 2/2 Running 1 22m webhook-7cfff8d86d-vjnqq 1/1 Running 0 22m
{: screen}
-
Verify that all pods of the Knative
Sources
component are in aRunning
state.kubectl get pods --namespace knative-sources
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE controller-manager-0 1/1 Running 0 22m
{: screen}
-
Verify that all pods of the Knative
Monitoring
component are in aRunning
state.kubectl get pods --namespace knative-monitoring
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE elasticsearch-logging-0 1/1 Running 0 22m elasticsearch-logging-1 1/1 Running 0 21m grafana-79cf95cc7-mw42v 1/1 Running 0 21m kibana-logging-7f7b9698bc-m7v6r 1/1 Running 0 22m kube-state-metrics-768dfff9c5-fmkkr 4/4 Running 0 21m node-exporter-dzlp9 2/2 Running 0 22m node-exporter-hp6gv 2/2 Running 0 22m node-exporter-hr6vs 2/2 Running 0 22m prometheus-system-0 1/1 Running 0 21m prometheus-system-1 1/1 Running 0 21m
{: screen}
-
Great! With Knative and Istio all set up, you can now deploy your first serverless app to your cluster.
{: #deploy_app}
In this lesson, you deploy your first serverless Hello World
app in Go. When you send a request to your sample app, the app reads the environment variable TARGET
and prints "Hello ${TARGET}!"
. If this environment variable is empty, "Hello World!"
is returned.
{: shortdesc}
-
Create a YAML file for your first serverless
Hello World
app in Knative. To deploy an app with Knative, you must specify a Knative Service resource. A service is managed by the KnativeServing
primitive and is responsible to manage the entire lifecycle of the workload. The service ensures that each deployment has a Knative revision, a route, and a configuration. When you update the service, a new version of the app is created and added to the revision history of the service. Knative routes ensure that each revision of the app is mapped to a network endpoint so that you can control how much network traffic is routed to a specific revision. Knative configurations hold the settings of a specific revision so that you can always rollback to an older revision or switch between revisions. For more information about KnativeServing
resources, see the Knative documentation.apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata: name: kn-helloworld namespace: default spec: runLatest: configuration: revisionTemplate: spec: container: image: docker.io/ibmcom/kn-helloworld env: - name: TARGET value: "Go Sample v1"
{: codeblock}
Understanding the YAML file components -
Create the Knative service in your cluster. When you create the service, the Knative
Serving
primitive creates an immutable revision, a Knative route, an Ingress routing rule, a Kubernetes service, a Kubernetes pod and a load balancer for your app. Your app is assigned a subdomain from your Ingress subdomain in the format<knative_service_name>.<namespace>.<ingress_subdomain>
that you can use to access the app from the internet.kubectl apply -f service.yaml
{: pre}
Example output:
service.serving.knative.dev "kn-helloworld" created
{: screen}
-
Verify that your pod is created. Your pod consists of two containers. One container runs your
Hello World
app and the other container is a side car that runs Istio and Knative monitoring and logging tools. Your pod is assigned a00001
revision number.kubectl get pods
{: pre}
Example output:
NAME READY STATUS RESTARTS AGE kn-helloworld-00001-deployment-55db6bf4c5-2vftm 2/2 Running 0 16s
{: screen}
-
Try out your
Hello World
app.-
Get the default domain that is assigned to your Knative service. If you changed the name of your Knative service, or deployed the app to a different namespace, update these values in your query.
kubectl get ksvc/kn-helloworld
{: pre}
Example output:
NAME DOMAIN LATESTCREATED LATESTREADY READY REASON kn-helloworld kn-helloworld.default.mycluster.us-south.containers.appdomain.cloud kn-helloworld-rjmwt kn-helloworld-rjmwt True
{: screen}
-
Make a request to your app by using the subdomain that you retrieved in the previous step.
curl -v <service_domain>
{: pre}
Example output:
* Rebuilt URL to: kn-helloworld.default.mycluster.us-south.containers.appdomain.cloud/ * Trying 169.46.XX.XX... * TCP_NODELAY set * Connected to kn-helloworld.default.mycluster.us-south.containers.appdomain.cloud (169.46.XX.XX) port 80 (#0) > GET / HTTP/1.1 > Host: kn-helloworld.default.mycluster.us-south.containers.appdomain.cloud > User-Agent: curl/7.54.0 > Accept: */* > < HTTP/1.1 200 OK < Date: Thu, 21 Mar 2019 01:12:48 GMT < Content-Type: text/plain; charset=utf-8 < Content-Length: 20 < Connection: keep-alive < x-envoy-upstream-service-time: 17 < Hello Go Sample v1! * Connection #0 to host kn-helloworld.default.mycluster.us-south.containers.appdomain.cloud left intact
{: screen}
-
-
Wait a few minutes to let Knative scale down your pod. Knative evaluates the number of pods that must be up at a time to process incoming workload. If no network traffic is received, Knative automatically scales down your pods, even to zero pods as shown in this example.
Want to see how Knative scales up your pods? Try to increase workload for your app, for example by using tools like the Simple cloud-based load tester. {: tip}
kubectl get pods
{: pre}
If you do not see any
kn-helloworld
pods, Knative scaled down your app to zero pods. -
Update your Knative service sample and enter a different value for the
TARGET
environment variable.Example service YAML:
apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata: name: kn-helloworld namespace: default spec: runLatest: configuration: revisionTemplate: spec: container: image: docker.io/ibmcom/kn-helloworld env: - name: TARGET value: "Mr. Smith"
{: codeblock}
-
Apply the change to your service. When you change the configuration, Knative automatically creates a new revision, assigns a new route and by default instructs Istio to route incoming network traffic to the latest revision.
kubectl apply -f service.yaml
{: pre}
-
Make a new request to your app to verify that your change was applied.
curl -v <service_domain>
Example output:
... Hello Mr. Smith!
{: screen}
-
Verify that Knative scaled up your pod again to account for the increased network traffic. Your pod is assigned a
00002
revision number. You can use the revision number to reference a specific version of your app, for example when you want to instruct Istio to split incoming traffic between the two revisions.kubectl get pods
Example output:
NAME READY STATUS RESTARTS AGE kn-helloworld-00002-deployment-55db6bf4c5-2vftm 3/3 Running 0 16s
{: screen}
-
Optional: Clean up your Knative service.
kubectl delete -f service.yaml
{: pre}
Awesome! You successfully deployed your first Knative app to your cluster and explored the revision and scaling capabilities of the Knative Serving
primitive.
{: #whats-next}
- Try out this Knative workshop
to deploy your first
Node.js
fibonacci app to your cluster.- Explore how to use the Knative
Build
primitive to build an image from a Dockerfile in GitHub and automatically push the image to your namespace in {{site.data.keyword.registrylong_notm}}. - Learn how you can set up routing for network traffic from the IBM-provided Ingress subdomain to the Istio Ingress gateway that is provided by Knative.
- Roll out a new version of your app and use Istio to control the amount of traffic that is routed to each app version.
- Explore how to use the Knative
- Explore Knative
Eventing
samples.
- Learn more about Knative with the Knative documentation
.