diff --git a/docs/serving/samples/README.md b/docs/serving/samples/README.md deleted file mode 100644 index 47fe4076f..000000000 --- a/docs/serving/samples/README.md +++ /dev/null @@ -1,19 +0,0 @@ -Use the following code samples to help you understand the various Knative -Serving resources and how they can be applied across common use cases. -[Learn more about Knative Serving resources](../README.md). - -[**See all Knative code samples**](../../samples.md) - -| Name | Description | Languages | -| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | -| Hello World | A quick introduction that highlights how to deploy an app using Knative Serving. | [C#](./hello-world/helloworld-csharp/README.md), [Go](./hello-world/helloworld-go/README.md), [Java (Spark)](./hello-world/helloworld-java-spark/README.md), [Java (Spring)](./hello-world/helloworld-java-spring/README.md), [Kotlin](./hello-world/helloworld-kotlin/README.md), [Node.js](./hello-world/helloworld-nodejs/README.md), [PHP](./hello-world/helloworld-php/README.md), [Python](./hello-world/helloworld-python/README.md), [Ruby](./hello-world/helloworld-ruby/README.md), [Scala](./hello-world/helloworld-scala/README.md), [Shell](./hello-world/helloworld-shell/README.md) | -| Cloud Events | A quick introduction that highlights how to send and receive Cloud Events. | [C#](./cloudevents/cloudevents-dotnet/README.md), [Go](./cloudevents/cloudevents-go/README.md), [Node.js](./cloudevents/cloudevents-nodejs/README.md), [Rust](./cloudevents/cloudevents-rust/README.md), [Java (Vert.x)](./cloudevents/cloudevents-vertx/README.md) | -| Advanced Deployment | Simple blue/green-like application deployment pattern illustrating the process of updating a live application without dropping any traffic. | [YAML](./blue-green-deployment.md) | -| Autoscale | A demonstration of the autoscaling capabilities of Knative. | [Go](../autoscaling/autoscale-go/README.md) | -| Github Webhook | A simple webhook handler that demonstrates interacting with Github. | [Go](./gitwebhook-go/README.md) | -| gRPC | A simple gRPC server. | [Go](./grpc-ping-go/README.md) | -| Knative Routing | An example of mapping multiple Knative services to different paths under a single domain name using the Istio VirtualService concept. | [Go](./knative-routing-go/README.md) | -| Knative Secrets | A simple app that demonstrates how to use a Kubernetes secret as a Volume in Knative. | [Go](./secrets-go/README.md) | -| REST API | A simple Restful service that exposes an endpoint defined by an environment variable described in the Knative Configuration. | [Go](./rest-api-go/README.md) | -| Traffic Splitting | This samples builds off the [Creating a RESTful Service](./rest-api-go) sample to illustrate applying a revision, then using that revision for manual traffic splitting. | [YAML](./traffic-splitting/README.md) | -| Multi Container | A quick introduction that highlights how to build and deploy an app using Knative Serving for multiple containers. | [Go](./multi-container/README.md) | diff --git a/docs/serving/samples/_index.md b/docs/serving/samples/_index.md index 29a1997a0..9fc07cd49 100644 --- a/docs/serving/samples/_index.md +++ b/docs/serving/samples/_index.md @@ -5,4 +5,22 @@ weight: 100 type: "docs" --- -{{% readfile file="README.md" %}} +Use the following code samples to help you understand the various Knative +Serving resources and how they can be applied across common use cases. +[Learn more about Knative Serving resources](../README.md). + +[**See all Knative code samples**](../../samples.md) + +| Name | Description | Languages | +| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | +| Hello World | A quick introduction that highlights how to deploy an app using Knative Serving. | [C#](./hello-world/helloworld-csharp/README.md), [Go](./hello-world/helloworld-go/README.md), [Java (Spark)](./hello-world/helloworld-java-spark/README.md), [Java (Spring)](./hello-world/helloworld-java-spring/README.md), [Kotlin](./hello-world/helloworld-kotlin/README.md), [Node.js](./hello-world/helloworld-nodejs/README.md), [PHP](./hello-world/helloworld-php/README.md), [Python](./hello-world/helloworld-python/README.md), [Ruby](./hello-world/helloworld-ruby/README.md), [Scala](./hello-world/helloworld-scala/README.md), [Shell](./hello-world/helloworld-shell/README.md) | +| Cloud Events | A quick introduction that highlights how to send and receive Cloud Events. | [C#](./cloudevents/cloudevents-dotnet/README.md), [Go](./cloudevents/cloudevents-go/README.md), [Node.js](./cloudevents/cloudevents-nodejs/README.md), [Rust](./cloudevents/cloudevents-rust/README.md), [Java (Vert.x)](./cloudevents/cloudevents-vertx/README.md) | +| Advanced Deployment | Simple blue/green-like application deployment pattern illustrating the process of updating a live application without dropping any traffic. | [YAML](./blue-green-deployment.md) | +| Autoscale | A demonstration of the autoscaling capabilities of Knative. | [Go](../autoscaling/autoscale-go/README.md) | +| Github Webhook | A simple webhook handler that demonstrates interacting with Github. | [Go](./gitwebhook-go/README.md) | +| gRPC | A simple gRPC server. | [Go](./grpc-ping-go/README.md) | +| Knative Routing | An example of mapping multiple Knative services to different paths under a single domain name using the Istio VirtualService concept. | [Go](./knative-routing-go/README.md) | +| Knative Secrets | A simple app that demonstrates how to use a Kubernetes secret as a Volume in Knative. | [Go](./secrets-go/README.md) | +| REST API | A simple Restful service that exposes an endpoint defined by an environment variable described in the Knative Configuration. | [Go](./rest-api-go/README.md) | +| Traffic Splitting | This samples builds off the [Creating a RESTful Service](./rest-api-go) sample to illustrate applying a revision, then using that revision for manual traffic splitting. | [YAML](./traffic-splitting/README.md) | +| Multi Container | A quick introduction that highlights how to build and deploy an app using Knative Serving for multiple containers. | [Go](./multi-container/README.md) | diff --git a/docs/serving/samples/cloudevents/cloudevents-dotnet/README.md b/docs/serving/samples/cloudevents/cloudevents-dotnet/README.md deleted file mode 100644 index b70ab02bb..000000000 --- a/docs/serving/samples/cloudevents/cloudevents-dotnet/README.md +++ /dev/null @@ -1,111 +0,0 @@ -A simple web app written in ASP.NET and C# that can receive and send Cloud Events that you -can use for testing. It supports running in two modes: - -1. The default mode has the app reply to your input events with the output - event, which is simplest for demonstrating things working in isolation, but - is also the model for working for the Knative Eventing `Broker` concept. - -2. `K_SINK` mode has the app send events to the destination encoded in - `$K_SINK`, which is useful to demonstrate how folks can synthesize events to - send to a Service or Broker when not initiated by a Broker invocation (e.g. - implementing an event source) - -The application will use `$K_SINK`-mode whenever the environment variable is -specified. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/cloudevents/cloudevents-dotnet -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## The sample code - -1. If you look in `controllers\CloudEventsController.cs`, you will see two key functions for the - different modes of operation: - - ```csharp - private async Task ReceiveAndSend(CloudEvent receivedEvent) { - // This is called whenever an event is received if $K_SINK is set, and sends a new event - // to the url in $K_SINK. - } - - private IActionResult ReceiveAndReply(CloudEvent receivedEvent) { - // This is called whenever an event is received if $K_SINK is NOT set, and it replies with - // the new event instead. - } - ``` - -1. If you look in `Dockerfile`, you will see a method for pulling in the - dependencies and building an ASP.NET container based on Alpine. You can build - and push this to your registry of choice via: - - ```shell - docker build -t . - docker push - ``` - -1. If you look in `service.yaml`, take the `` name above and insert it - into the `image:` field. - - ```shell - kubectl apply -f service.yaml - ``` - -## Testing the sample - -Get the URL for your Service with: - -```shell -$ kubectl get ksvc -NAME URL LATESTCREATED LATESTREADY READY REASON -cloudevents-dotnet http://cloudevents-dotnet... cloudevents-dotnet-ss5pj cloudevents-dotnet-ss5pj True -``` - -Then send a cloud event to it with: - -```shell -$ curl -X POST \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - -``` - -You will get back: - -```json -{ - "specversion": "1.0", - "type": "dev.knative.docs.sample", - "source": "https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-dotnet", - "id": "d662b6f6-35ff-4b98-bffd-5ae9eee23dab", - "time": "2020-05-19T01:26:23.3500138Z", - "datacontenttype": "application/json", - "data": { - "message": "Hello, Dave" - } -} -``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/cloudevents/cloudevents-dotnet/index.md b/docs/serving/samples/cloudevents/cloudevents-dotnet/index.md index c843b7131..8dcf8ef7d 100644 --- a/docs/serving/samples/cloudevents/cloudevents-dotnet/index.md +++ b/docs/serving/samples/cloudevents/cloudevents-dotnet/index.md @@ -5,4 +5,114 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in ASP.NET and C# that can receive and send Cloud Events that you +can use for testing. It supports running in two modes: + +1. The default mode has the app reply to your input events with the output + event, which is simplest for demonstrating things working in isolation, but + is also the model for working for the Knative Eventing `Broker` concept. + +2. `K_SINK` mode has the app send events to the destination encoded in + `$K_SINK`, which is useful to demonstrate how folks can synthesize events to + send to a Service or Broker when not initiated by a Broker invocation (e.g. + implementing an event source) + +The application will use `$K_SINK`-mode whenever the environment variable is +specified. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/cloudevents/cloudevents-dotnet +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## The sample code + +1. If you look in `controllers\CloudEventsController.cs`, you will see two key functions for the + different modes of operation: + + ```csharp + private async Task ReceiveAndSend(CloudEvent receivedEvent) { + // This is called whenever an event is received if $K_SINK is set, and sends a new event + // to the url in $K_SINK. + } + + private IActionResult ReceiveAndReply(CloudEvent receivedEvent) { + // This is called whenever an event is received if $K_SINK is NOT set, and it replies with + // the new event instead. + } + ``` + +1. If you look in `Dockerfile`, you will see a method for pulling in the + dependencies and building an ASP.NET container based on Alpine. You can build + and push this to your registry of choice via: + + ```shell + docker build -t . + docker push + ``` + +1. If you look in `service.yaml`, take the `` name above and insert it + into the `image:` field. + + ```shell + kubectl apply -f service.yaml + ``` + +## Testing the sample + +Get the URL for your Service with: + +```shell +$ kubectl get ksvc +NAME URL LATESTCREATED LATESTREADY READY REASON +cloudevents-dotnet http://cloudevents-dotnet... cloudevents-dotnet-ss5pj cloudevents-dotnet-ss5pj True +``` + +Then send a cloud event to it with: + +```shell +$ curl -X POST \ + -H "content-type: application/json" \ + -H "ce-specversion: 1.0" \ + -H "ce-source: curl-command" \ + -H "ce-type: curl.demo" \ + -H "ce-id: 123-abc" \ + -d '{"name":"Dave"}' \ + +``` + +You will get back: + +```json +{ + "specversion": "1.0", + "type": "dev.knative.docs.sample", + "source": "https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-dotnet", + "id": "d662b6f6-35ff-4b98-bffd-5ae9eee23dab", + "time": "2020-05-19T01:26:23.3500138Z", + "datacontenttype": "application/json", + "data": { + "message": "Hello, Dave" + } +} +``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/cloudevents/cloudevents-nodejs/README.md b/docs/serving/samples/cloudevents/cloudevents-nodejs/README.md deleted file mode 100644 index 8c71f93e6..000000000 --- a/docs/serving/samples/cloudevents/cloudevents-nodejs/README.md +++ /dev/null @@ -1,128 +0,0 @@ -A simple web app written in Node.js that can receive and send Cloud Events that you -can use for testing. It supports running in two modes: - -1. The default mode has the app reply to your input events with the output - event, which is simplest for demonstrating things working in isolation, but - is also the model for working for the Knative Eventing `Broker` concept. - -2. `K_SINK` mode has the app send events to the destination encoded in - `$K_SINK`, which is useful to demonstrate how folks can synthesize events to - send to a Service or Broker when not initiated by a Broker invocation (e.g. - implementing an event source) - -The application will use `$K_SINK`-mode whenever the environment variable is -specified. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/cloudevents/cloudevents-nodejs -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## The Sample Code - -In the `index.js` file, you will see two key functions for the different modes -of operation: - - ```js - const receiveAndSend = (cloudEvent, res) => { - // This is called whenever an event is received if $K_SINK is set, and sends a new event - // to the url in $K_SINK. - } - - const receiveAndReply = (cloudEvent, res) => { - // This is called whenever an event is received if $K_SINK is NOT set, and it replies with - // the new event instead. - } - ``` - -## Build and Deploy the Application - -In the `Dockerfile`, you can see how the dependencies are installed using npm. - You can build and push this to your registry of choice via: - - ```shell - docker build -t . - docker push - ``` - -{{< tabs name="cloudevents_nodejs_deploy" default="kn" >}} {{% tab name="yaml" %}} - -To deploy the Knative service, edit the `service.yaml` file and replace -`` with the image you have just created. - - ```shell - kubectl apply -f service.yaml - ``` - -{{< /tab >}} {{% tab name="kn" %}} - -To deploy using the `kn` CLI: - - ```shell - kn service create cloudevents-nodejs --image= - ``` - -{{ /tab }}{{ /tabs }} - -## Testing the sample - -Get the URL for your Service with: - -```shell -$ kubectl get ksvc -NAME URL LATESTCREATED LATESTREADY READY REASON -cloudevents-nodejs http://cloudevents-nodejs.default.1.2.3.4.xip.io cloudevents-nodejs-ss5pj cloudevents-nodejs-ss5pj True -``` - -Then send a cloud event to it with: - -```shell -$ curl -X POST \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - http://cloudevents-nodejs.default.1.2.3.4.xip.io -``` - -You will get back: - -```shell -{"message":"Hello, Dave"} -``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service. - -{{< tabs name="cloudevents_nodejs_delete" default="kn" >}} {{% tab name="yaml" %}} - -Run: - -```shell -kubectl delete --filename service.yaml -``` - -{{< /tab >}} {{% tab name="kn" %}} - -Run: - -```shell -kn service delete cloudevents-nodejs -``` - -{{ /tab }}{{ /tabs }} diff --git a/docs/serving/samples/cloudevents/cloudevents-nodejs/index.md b/docs/serving/samples/cloudevents/cloudevents-nodejs/index.md index 11d2a9af7..e2f6db983 100644 --- a/docs/serving/samples/cloudevents/cloudevents-nodejs/index.md +++ b/docs/serving/samples/cloudevents/cloudevents-nodejs/index.md @@ -5,4 +5,131 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Node.js that can receive and send Cloud Events that you +can use for testing. It supports running in two modes: + +1. The default mode has the app reply to your input events with the output + event, which is simplest for demonstrating things working in isolation, but + is also the model for working for the Knative Eventing `Broker` concept. + +2. `K_SINK` mode has the app send events to the destination encoded in + `$K_SINK`, which is useful to demonstrate how folks can synthesize events to + send to a Service or Broker when not initiated by a Broker invocation (e.g. + implementing an event source) + +The application will use `$K_SINK`-mode whenever the environment variable is +specified. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/cloudevents/cloudevents-nodejs +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## The Sample Code + +In the `index.js` file, you will see two key functions for the different modes +of operation: + + ```js + const receiveAndSend = (cloudEvent, res) => { + // This is called whenever an event is received if $K_SINK is set, and sends a new event + // to the url in $K_SINK. + } + + const receiveAndReply = (cloudEvent, res) => { + // This is called whenever an event is received if $K_SINK is NOT set, and it replies with + // the new event instead. + } + ``` + +## Build and Deploy the Application + +In the `Dockerfile`, you can see how the dependencies are installed using npm. + You can build and push this to your registry of choice via: + + ```shell + docker build -t . + docker push + ``` + +{{< tabs name="cloudevents_nodejs_deploy" default="kn" >}} {{% tab name="yaml" %}} + +To deploy the Knative service, edit the `service.yaml` file and replace +`` with the image you have just created. + + ```shell + kubectl apply -f service.yaml + ``` + +{{< /tab >}} {{% tab name="kn" %}} + +To deploy using the `kn` CLI: + + ```shell + kn service create cloudevents-nodejs --image= + ``` + +{{ /tab }}{{ /tabs }} + +## Testing the sample + +Get the URL for your Service with: + +```shell +$ kubectl get ksvc +NAME URL LATESTCREATED LATESTREADY READY REASON +cloudevents-nodejs http://cloudevents-nodejs.default.1.2.3.4.xip.io cloudevents-nodejs-ss5pj cloudevents-nodejs-ss5pj True +``` + +Then send a cloud event to it with: + +```shell +$ curl -X POST \ + -H "content-type: application/json" \ + -H "ce-specversion: 1.0" \ + -H "ce-source: curl-command" \ + -H "ce-type: curl.demo" \ + -H "ce-id: 123-abc" \ + -d '{"name":"Dave"}' \ + http://cloudevents-nodejs.default.1.2.3.4.xip.io +``` + +You will get back: + +```shell +{"message":"Hello, Dave"} +``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service. + +{{< tabs name="cloudevents_nodejs_delete" default="kn" >}} {{% tab name="yaml" %}} + +Run: + +```shell +kubectl delete --filename service.yaml +``` + +{{< /tab >}} {{% tab name="kn" %}} + +Run: + +```shell +kn service delete cloudevents-nodejs +``` + +{{ /tab }}{{ /tabs }} diff --git a/docs/serving/samples/cloudevents/cloudevents-spring/README.md b/docs/serving/samples/cloudevents/cloudevents-spring/README.md deleted file mode 100644 index 1eaf8de93..000000000 --- a/docs/serving/samples/cloudevents/cloudevents-spring/README.md +++ /dev/null @@ -1,139 +0,0 @@ -# Spring + CloudEvents + Knative - -A simple web app written in Java using Spring Cloud Function that can receive CloudEvents. It -supports running in two modes: - -1. The default mode has the app reply to your input events with the output - event, which is simplest for demonstrating things working in isolation, but - is also the model for working with the Knative Eventing `Broker` concept. The - input event is modified assigning a new source and type attribute. - -2. `K_SINK` mode has the app send events to the destination encoded in - `$K_SINK`, which is useful to demonstrate how folks can synthesize events to - send to a Service or Broker when not initiated by a Broker invocation (e.g. - implementing an event source). The input event is modified assigning a new - source and type attribute. - -The application will use `$K_SINK`-mode whenever the environment variable is -specified. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/cloudevents/cloudevents-spring -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Build and deploy the sample - -To build the image, run: - -```shell -mvn compile jib:build -Dimage= -``` - -To deploy the Knative Service, edit the `service.yaml` file and replace `` -with the deployed image name. Then run: - -```shell -kubectl apply -f service.yaml -``` - -## Testing the sample - -Get the URL for your Service with: - -```shell -$ kubectl get ksvc -NAME URL LATESTCREATED LATESTREADY READY REASON -cloudevents-spring http://cloudevents-java.xip.io cloudevents-spring-86h28 cloudevents-spring-86h28 True -``` - -Then send a CloudEvent to it with: - -```shell -$ curl -v \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: http://curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - http://cloudevents-java.xip.io -``` - -You can also use the "structured" message format from Cloud Events using a more specific content type: - -```shell -$ curl -v \ - -H "content-type: application/cloudevents+json" \ - -d '{ - "specversion": "1.0", - "source": "http://curl-command", - "type": "curl.demo", - "id": "123-abc", - "data": {"name":"Dave"} - }' \ - http://cloudevents-java.xip.io -``` - -Note that the response from the server is "binary", not "structured", so you get the same response as if you sent a binary message. - -You can also send CloudEvents spawning a temporary curl pod in your cluster -with: - -```shell -$ kubectl run curl \ - --image=curlimages/curl --rm=true --restart=Never -ti -- \ - -X POST -v \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: http://curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - http://cloudevents-java.default.svc -``` - -You'll see on the console: - -```shell -> POST / HTTP/1.1 -> Host: localhost:8080 -> User-Agent: curl/7.69.1 -> Accept: */* -> content-type: application/json -> ce-specversion: 1.0 -> ce-source: http://curl-command -> ce-type: curl.demo -> ce-id: 123-abc -> Content-Length: 15 -> -< HTTP/1.1 202 Accepted -< ce-specversion: 1.0 -< ce-id: 123-abc -< ce-source: https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-spring -< ce-type: curl.demo -< content-type: application/json -< content-length: 15 -< -{"name":"Dave"} -``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/cloudevents/cloudevents-vertx/README.md b/docs/serving/samples/cloudevents/cloudevents-vertx/README.md deleted file mode 100644 index a801ca47f..000000000 --- a/docs/serving/samples/cloudevents/cloudevents-vertx/README.md +++ /dev/null @@ -1,123 +0,0 @@ -# Vert.x + CloudEvents + Knative - -A simple web app written in Java using Vert.x that can receive CloudEvents. It -supports running in two modes: - -1. The default mode has the app reply to your input events with the output - event, which is simplest for demonstrating things working in isolation, but - is also the model for working for the Knative Eventing `Broker` concept. The - input event is modified assigning a new source and type attribute. - -2. `K_SINK` mode has the app send events to the destination encoded in - `$K_SINK`, which is useful to demonstrate how folks can synthesize events to - send to a Service or Broker when not initiated by a Broker invocation (e.g. - implementing an event source). The input event is modified assigning a new - source and type attribute. - -The application will use `$K_SINK`-mode whenever the environment variable is -specified. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/cloudevents/cloudevents-vertx -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Build and deploy the sample - -To build the image, run: - -```shell -mvn compile jib:build -Dimage= -``` - -To deploy the Knative Service, look in the `service.yaml` and replace `` -with the deployed image name. Then run: - -```shell -kubectl apply -f service.yaml -``` - -## Testing the sample - -Get the URL for your Service with: - -```shell -$ kubectl get ksvc -NAME URL LATESTCREATED LATESTREADY READY REASON -cloudevents-vertx http://cloudevents-java.xip.io cloudevents-vertx-86h28 cloudevents-vertx-86h28 True -``` - -Then send a CloudEvent to it with: - -```shell -$ curl \ - -X POST -v \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: http://curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - http://cloudevents-java.xip.io -``` - -You can also send CloudEvents spawning a temporary curl pod in your cluster -with: - -```shell -$ kubectl run curl \ - --image=curlimages/curl --rm=true --restart=Never -ti -- \ - -X POST -v \ - -H "content-type: application/json" \ - -H "ce-specversion: 1.0" \ - -H "ce-source: http://curl-command" \ - -H "ce-type: curl.demo" \ - -H "ce-id: 123-abc" \ - -d '{"name":"Dave"}' \ - http://cloudevents-java.default.svc -``` - -You'll see on the console: - -```shell -> POST / HTTP/1.1 -> Host: localhost:8080 -> User-Agent: curl/7.69.1 -> Accept: */* -> content-type: application/json -> ce-specversion: 1.0 -> ce-source: http://curl-command -> ce-type: curl.demo -> ce-id: 123-abc -> Content-Length: 15 -> -< HTTP/1.1 202 Accepted -< ce-specversion: 1.0 -< ce-id: 123-abc -< ce-source: https://github.com/knative/docs/docs/serving/samples/cloudevents/cloudevents-vertx -< ce-type: curl.demo -< content-type: application/json -< content-length: 15 -< -{"name":"Dave"} -``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/gitwebhook-go/README.md b/docs/serving/samples/gitwebhook-go/README.md deleted file mode 100644 index 871c47bff..000000000 --- a/docs/serving/samples/gitwebhook-go/README.md +++ /dev/null @@ -1,194 +0,0 @@ -A handler written in Go that demonstrates interacting with GitHub through a -webhook. - -## Before you begin - -You must meet the following requirements to run this sample: - -- Own a public domain. For example, you can create a domain with - [Google Domains](https://domains.google/). -- A Kubernetes cluster running with the following: - - Knative Serving must be installed. For details about setting up a Knative - cluster, see the [installation guides](../../../install/README.md). - - Your Knative cluster must be - [configured to use your custom domain](../../using-a-custom-domain.md). - - You must ensure that your Knative cluster uses a static IP address: - - For Google Kubernetes Engine, see - [assigning a static IP address](../../gke-assigning-static-ip-address.md). - - For other cloud providers, refer to your provider's documentation. -- An installed version of [Docker](https://www.docker.com). -- A [Docker Hub account](https://hub.docker.com/) to which you are able to - upload your sample's container image. - -## Build the sample code - -1. Download a copy of the code: - - ```shell - git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs - cd knative-docs/docs/serving/samples/gitwebhook-go - ``` - -1. Use Docker to build a container image for this service. Replace - `{DOCKER_HUB_USERNAME}` with your Docker Hub username in the following - commands. - - ```shell - export DOCKER_HUB_USERNAME=username - - # Build the container, run from the project folder - docker build -t ${DOCKER_HUB_USERNAME}/gitwebhook-go . - - # Push the container to the registry - docker push ${DOCKER_HUB_USERNAME}/gitwebhook-go - ``` - -1. Create a secret that holds two values from GitHub: - - - A - [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) - that you will use to make API requests to GitHub. - - Ensure that you grant `read/write` permission in the repo for that personal - access token. - - 1. Follow the GitHub instructions to - - - A webhook secret that you will use to validate requests. - - 1. Base64 encode the access token: - - ```shell - $ echo -n "45d382d4a9a93c453fb7c8adc109121e7c29fa3ca" | base64 - NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E= - ``` - - 1. Copy the encoded access token into `github-secret.yaml` next to - `personalAccessToken:`. - - 1. Create a webhook secret value unique to this sample, base64 encode it, and - copy it into `github-secret.yaml` next to `webhookSecret:`: - - ```shell - $ echo -n "mygithubwebhooksecret" | base64 - bXlnaXRodWJ3ZWJob29rc2VjcmV0 - ``` - - 1. Apply the secret to your cluster: - - ```shell - kubectl apply --filename github-secret.yaml - ``` - -1. Next, update the `service.yaml` file in the project to reference the tagged - image from step 1. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: gitwebhook - namespace: default - spec: - template: - spec: - containers: - - # Replace {DOCKER_HUB_USERNAME} with your actual docker hub username - image: docker.io/{DOCKER_HUB_USERNAME}/gitwebhook-go:latest - env: - - name: GITHUB_PERSONAL_TOKEN - valueFrom: - secretKeyRef: - name: githubsecret - key: personalAccessToken - - name: WEBHOOK_SECRET - valueFrom: - secretKeyRef: - name: githubsecret - key: webhookSecret - ``` - -1. Use `kubectl` to apply the `service.yaml` file. - - ```shell - $ kubectl apply --filename service.yaml - ``` - - Response: - - ```shell - service "gitwebhook" created - ``` - -1. Create a webhook in your GitHub repo using the URL for your `gitwebhook` - service: - - 1. Retrieve the hostname for this service, using the following command: - - ```shell - $ kubectl get ksvc gitwebhook \ - --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - ``` - - Example response: - - ```shell - NAME DOMAIN - gitwebhook gitwebhook.default.MYCUSTOMDOMAIN.com - ``` - - where `MYCUSTOMDOMAIN` is the domain that you set as your - [custom domain](../../using-a-custom-domain.md). - - 1. Go to the GitHub repository for which you have privileges to create a - webhook. - - 1. Click **Settings** > **Webhooks** > **Add webhook** to open the Webhooks - page. - - 1. Enter the **Payload URL** as `http://{DOMAIN}`, where `{DOMAIN}` is the - address from the `kubectl get ksvc gitwebhook` command. For example: - `http://gitwebhook.default.MYCUSTOMDOMAIN.com` - - 1. Set the **Content type** to `application/json`. - - 1. Enter your webhook secret in **Secret** using the original base value that - you set in `webhookSecret` (not the base64 encoded value). For example: - `mygithubwebhooksecret` - - 1. If you did not [enabled TLS certificates](../../using-a-tls-cert.md), - click **Disable** under **SSL Validation**. - - 1. Click **Add webhook** to create the webhook. - -## Exploring - -Once deployed, you can inspect the created resources with `kubectl` commands: - -```shell -# This will show the Knative service that we created: -kubectl get ksvc --output yaml - -# This will show the Route, created by the service: -kubectl get route --output yaml - -# This will show the Configuration, created by the service: -kubectl get configurations --output yaml - -# This will show the Revision, created by the Configuration: -kubectl get revisions --output yaml -``` - -## Testing the service - -Now that you have the service running and the webhook created, send a Pull -Request to the same GitHub repo where you added the webhook. If all is working -right, you'll see the title of the PR will be modified, with the text -`(looks pretty legit)` appended the end of the title. - -## Cleaning up - -To clean up the sample service: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/gitwebhook-go/index.md b/docs/serving/samples/gitwebhook-go/index.md index 625512ea0..03779fce5 100644 --- a/docs/serving/samples/gitwebhook-go/index.md +++ b/docs/serving/samples/gitwebhook-go/index.md @@ -5,4 +5,197 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A handler written in Go that demonstrates interacting with GitHub through a +webhook. + +## Before you begin + +You must meet the following requirements to run this sample: + +- Own a public domain. For example, you can create a domain with + [Google Domains](https://domains.google/). +- A Kubernetes cluster running with the following: + - Knative Serving must be installed. For details about setting up a Knative + cluster, see the [installation guides](../../../install/README.md). + - Your Knative cluster must be + [configured to use your custom domain](../../using-a-custom-domain.md). + - You must ensure that your Knative cluster uses a static IP address: + - For Google Kubernetes Engine, see + [assigning a static IP address](../../gke-assigning-static-ip-address.md). + - For other cloud providers, refer to your provider's documentation. +- An installed version of [Docker](https://www.docker.com). +- A [Docker Hub account](https://hub.docker.com/) to which you are able to + upload your sample's container image. + +## Build the sample code + +1. Download a copy of the code: + + ```shell + git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs + cd knative-docs/docs/serving/samples/gitwebhook-go + ``` + +1. Use Docker to build a container image for this service. Replace + `{DOCKER_HUB_USERNAME}` with your Docker Hub username in the following + commands. + + ```shell + export DOCKER_HUB_USERNAME=username + + # Build the container, run from the project folder + docker build -t ${DOCKER_HUB_USERNAME}/gitwebhook-go . + + # Push the container to the registry + docker push ${DOCKER_HUB_USERNAME}/gitwebhook-go + ``` + +1. Create a secret that holds two values from GitHub: + + - A + [personal access token](https://help.github.com/articles/creating-a-personal-access-token-for-the-command-line/) + that you will use to make API requests to GitHub. + - Ensure that you grant `read/write` permission in the repo for that personal + access token. + + 1. Follow the GitHub instructions to + + - A webhook secret that you will use to validate requests. + + 1. Base64 encode the access token: + + ```shell + $ echo -n "45d382d4a9a93c453fb7c8adc109121e7c29fa3ca" | base64 + NDVkMzgyZDRhOWE5M2M0NTNmYjdjOGFkYzEwOTEyMWU3YzI5ZmEzY2E= + ``` + + 1. Copy the encoded access token into `github-secret.yaml` next to + `personalAccessToken:`. + + 1. Create a webhook secret value unique to this sample, base64 encode it, and + copy it into `github-secret.yaml` next to `webhookSecret:`: + + ```shell + $ echo -n "mygithubwebhooksecret" | base64 + bXlnaXRodWJ3ZWJob29rc2VjcmV0 + ``` + + 1. Apply the secret to your cluster: + + ```shell + kubectl apply --filename github-secret.yaml + ``` + +1. Next, update the `service.yaml` file in the project to reference the tagged + image from step 1. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: gitwebhook + namespace: default + spec: + template: + spec: + containers: + - # Replace {DOCKER_HUB_USERNAME} with your actual docker hub username + image: docker.io/{DOCKER_HUB_USERNAME}/gitwebhook-go:latest + env: + - name: GITHUB_PERSONAL_TOKEN + valueFrom: + secretKeyRef: + name: githubsecret + key: personalAccessToken + - name: WEBHOOK_SECRET + valueFrom: + secretKeyRef: + name: githubsecret + key: webhookSecret + ``` + +1. Use `kubectl` to apply the `service.yaml` file. + + ```shell + $ kubectl apply --filename service.yaml + ``` + + Response: + + ```shell + service "gitwebhook" created + ``` + +1. Create a webhook in your GitHub repo using the URL for your `gitwebhook` + service: + + 1. Retrieve the hostname for this service, using the following command: + + ```shell + $ kubectl get ksvc gitwebhook \ + --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + ``` + + Example response: + + ```shell + NAME DOMAIN + gitwebhook gitwebhook.default.MYCUSTOMDOMAIN.com + ``` + + where `MYCUSTOMDOMAIN` is the domain that you set as your + [custom domain](../../using-a-custom-domain.md). + + 1. Go to the GitHub repository for which you have privileges to create a + webhook. + + 1. Click **Settings** > **Webhooks** > **Add webhook** to open the Webhooks + page. + + 1. Enter the **Payload URL** as `http://{DOMAIN}`, where `{DOMAIN}` is the + address from the `kubectl get ksvc gitwebhook` command. For example: + `http://gitwebhook.default.MYCUSTOMDOMAIN.com` + + 1. Set the **Content type** to `application/json`. + + 1. Enter your webhook secret in **Secret** using the original base value that + you set in `webhookSecret` (not the base64 encoded value). For example: + `mygithubwebhooksecret` + + 1. If you did not [enabled TLS certificates](../../using-a-tls-cert.md), + click **Disable** under **SSL Validation**. + + 1. Click **Add webhook** to create the webhook. + +## Exploring + +Once deployed, you can inspect the created resources with `kubectl` commands: + +```shell +# This will show the Knative service that we created: +kubectl get ksvc --output yaml + +# This will show the Route, created by the service: +kubectl get route --output yaml + +# This will show the Configuration, created by the service: +kubectl get configurations --output yaml + +# This will show the Revision, created by the Configuration: +kubectl get revisions --output yaml +``` + +## Testing the service + +Now that you have the service running and the webhook created, send a Pull +Request to the same GitHub repo where you added the webhook. If all is working +right, you'll see the title of the PR will be modified, with the text +`(looks pretty legit)` appended the end of the title. + +## Cleaning up + +To clean up the sample service: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/grpc-ping-go/README.md b/docs/serving/samples/grpc-ping-go/README.md deleted file mode 100644 index a05e76b34..000000000 --- a/docs/serving/samples/grpc-ping-go/README.md +++ /dev/null @@ -1,110 +0,0 @@ -A [gRPC](https://grpc.io) server written in Go. - -This sample can be used to try out gRPC, HTTP/2, and custom port configuration -in a knative service. - -The container image is built with two binaries: the server and the client. -This is done for ease of testing and is not a recommended practice -for production containers. - -## Prerequisites - -- [Install the latest version of Knative Serving](../../../install/README.md). - -- Install [docker](https://www.docker.com/). - -- A [Docker Hub account](https://hub.docker.com) to which you can upload the sample's container image. - -## Build and Deploy the sample code - -1. Download a copy of the code: - - ```shell - git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs - cd knative-docs/docs/serving/samples/grpc-ping-go - ``` - -2. Use Docker to build a container image for this service and push to Docker Hub. - - Replace `{username}` with your Docker Hub username then run the commands: - - ```shell - # Build the container on your local machine. - docker build --tag "{username}/grpc-ping-go" . - - # Push the container to docker registry. - docker push "{username}/grpc-ping-go" - ``` - -3. Update the `service.yaml` file in the project to reference the published image from step 1. - - Replace `{username}` in `service.yaml` with your Docker Hub user name: - - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: grpc-ping - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/grpc-ping-go - ports: - - name: h2c - containerPort: 8080 - ``` - -4. Use `kubectl` to deploy the service. - - ```shell - kubectl apply --filename service.yaml - ``` - - Response: - - ```shell - service "grpc-ping" created - ``` - -## Exploring - -Once deployed, you can inspect the created resources with `kubectl` commands: - -```shell -# This will show the Knative service that we created: -kubectl get ksvc --output yaml - -# This will show the Route, created by the service: -kubectl get route --output yaml - -# This will show the Configuration, created by the service: -kubectl get configurations --output yaml - -# This will show the Revision, created by the Configuration: -kubectl get revisions --output yaml -``` - -## Testing the service - -Testing the gRPC service requires using a gRPC client built from the same -protobuf definition used by the server. - -The Dockerfile builds the client binary. To run the client you will use the -same container image deployed for the server with an override to the -entrypoint command to use the client binary instead of the server binary. - -Replace `{username}` with your Docker Hub user name and run the command: - -```shell -docker run --rm {username}/grpc-ping-go \ - /client \ - -server_addr="grpc-ping.default.1.2.3.4.xip.io:80" \ - -insecure -``` - -The arguments after the container tag `{username}/grpc-ping-go` are used -instead of the entrypoint command defined in the Dockerfile `CMD` statement. - diff --git a/docs/serving/samples/grpc-ping-go/index.md b/docs/serving/samples/grpc-ping-go/index.md index e8900fbfc..32dfe08b5 100644 --- a/docs/serving/samples/grpc-ping-go/index.md +++ b/docs/serving/samples/grpc-ping-go/index.md @@ -5,4 +5,113 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A [gRPC](https://grpc.io) server written in Go. + +This sample can be used to try out gRPC, HTTP/2, and custom port configuration +in a knative service. + +The container image is built with two binaries: the server and the client. +This is done for ease of testing and is not a recommended practice +for production containers. + +## Prerequisites + +- [Install the latest version of Knative Serving](../../../install/README.md). + +- Install [docker](https://www.docker.com/). + +- A [Docker Hub account](https://hub.docker.com) to which you can upload the sample's container image. + +## Build and Deploy the sample code + +1. Download a copy of the code: + + ```shell + git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs + cd knative-docs/docs/serving/samples/grpc-ping-go + ``` + +2. Use Docker to build a container image for this service and push to Docker Hub. + + Replace `{username}` with your Docker Hub username then run the commands: + + ```shell + # Build the container on your local machine. + docker build --tag "{username}/grpc-ping-go" . + + # Push the container to docker registry. + docker push "{username}/grpc-ping-go" + ``` + +3. Update the `service.yaml` file in the project to reference the published image from step 1. + + Replace `{username}` in `service.yaml` with your Docker Hub user name: + + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: grpc-ping + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/grpc-ping-go + ports: + - name: h2c + containerPort: 8080 + ``` + +4. Use `kubectl` to deploy the service. + + ```shell + kubectl apply --filename service.yaml + ``` + + Response: + + ```shell + service "grpc-ping" created + ``` + +## Exploring + +Once deployed, you can inspect the created resources with `kubectl` commands: + +```shell +# This will show the Knative service that we created: +kubectl get ksvc --output yaml + +# This will show the Route, created by the service: +kubectl get route --output yaml + +# This will show the Configuration, created by the service: +kubectl get configurations --output yaml + +# This will show the Revision, created by the Configuration: +kubectl get revisions --output yaml +``` + +## Testing the service + +Testing the gRPC service requires using a gRPC client built from the same +protobuf definition used by the server. + +The Dockerfile builds the client binary. To run the client you will use the +same container image deployed for the server with an override to the +entrypoint command to use the client binary instead of the server binary. + +Replace `{username}` with your Docker Hub user name and run the command: + +```shell +docker run --rm {username}/grpc-ping-go \ + /client \ + -server_addr="grpc-ping.default.1.2.3.4.xip.io:80" \ + -insecure +``` + +The arguments after the container tag `{username}/grpc-ping-go` are used +instead of the entrypoint command defined in the Dockerfile `CMD` statement. + diff --git a/docs/serving/samples/hello-world/helloworld-csharp/README.md b/docs/serving/samples/hello-world/helloworld-csharp/README.md deleted file mode 100644 index 34de1bd68..000000000 --- a/docs/serving/samples/hello-world/helloworld-csharp/README.md +++ /dev/null @@ -1,186 +0,0 @@ -A simple web app written in C# using .NET Core 3.1 that you can use for testing. -It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET -is not specified, it will use "World" as the TARGET. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-csharp -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). -- You have installed [.NET Core SDK 3.1](https://www.microsoft.com/net/core). - -## Recreating the sample code - -1. First, make sure you have - [.NET Core SDK 3.1](https://www.microsoft.com/net/core) installed: - - ```shell - dotnet --version - 3.1.100 - ``` - -1. From the console, create a new empty web project using the dotnet command: - - ```shell - dotnet new web -o helloworld-csharp - ``` - -1. Update the `CreateHostBuilder` definition in `Program.cs` by adding - `.UseUrls()` to define the serving port: - - ```csharp - public static IHostBuilder CreateHostBuilder(string[] args) - { - string port = Environment.GetEnvironmentVariable("PORT") ?? "8080"; - string url = String.Concat("http://0.0.0.0:", port); - - return Host.CreateDefaultBuilder(args) - .ConfigureWebHostDefaults(webBuilder => - { - webBuilder.UseStartup().UseUrls(url); - }); - } - ``` - -1. Update the `app.UseEndpoints(...)` statement in `Startup.cs` to read and return the - TARGET environment variable: - - ```csharp - app.UseEndpoints(endpoints => - { - endpoints.MapGet("/", async context => - { - var target = Environment.GetEnvironmentVariable("TARGET") ?? "World"; - await context.Response.WriteAsync($"Hello {target}!\n"); - }); - }); - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. For detailed instructions on dockerizing an ASP.NET Core - app, see - [Docker images for ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/building-net-docker-images). - - ```docker - # Use Microsoft's official build .NET image. - FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build - WORKDIR /app - - # Install production dependencies. - # Copy csproj and restore as distinct layers. - COPY *.csproj ./ - RUN dotnet restore - - # Copy local code to the container image. - COPY . ./ - WORKDIR /app - - # Build a release artifact. - RUN dotnet publish -c Release -o out - - # Use Microsoft's official runtime .NET image. - FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime - WORKDIR /app - COPY --from=build /app/out ./ - - # Run the web service on container startup. - ENTRYPOINT ["dotnet", "helloworld-csharp.dll"] - ``` - -1. Create a `.dockerignore` file to ensure that any files related to a local - build do not affect the container that you build for deployment. - - ```ignore - Dockerfile - README.md - **/obj/ - **/bin/ - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-csharp - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-csharp - env: - - name: TARGET - value: "C# Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-csharp . - - # Push the container to docker registry - docker push {username}/helloworld-csharp - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-csharp --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-csharp http://helloworld-csharp.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-csharp.default.1.2.3.4.xip.io - Hello C# Sample v1! - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/hello-world/helloworld-csharp/index.md b/docs/serving/samples/hello-world/helloworld-csharp/index.md index 343e572dd..768e7ef50 100644 --- a/docs/serving/samples/hello-world/helloworld-csharp/index.md +++ b/docs/serving/samples/hello-world/helloworld-csharp/index.md @@ -5,4 +5,189 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in C# using .NET Core 3.1 that you can use for testing. +It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET +is not specified, it will use "World" as the TARGET. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-csharp +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). +- You have installed [.NET Core SDK 3.1](https://www.microsoft.com/net/core). + +## Recreating the sample code + +1. First, make sure you have + [.NET Core SDK 3.1](https://www.microsoft.com/net/core) installed: + + ```shell + dotnet --version + 3.1.100 + ``` + +1. From the console, create a new empty web project using the dotnet command: + + ```shell + dotnet new web -o helloworld-csharp + ``` + +1. Update the `CreateHostBuilder` definition in `Program.cs` by adding + `.UseUrls()` to define the serving port: + + ```csharp + public static IHostBuilder CreateHostBuilder(string[] args) + { + string port = Environment.GetEnvironmentVariable("PORT") ?? "8080"; + string url = String.Concat("http://0.0.0.0:", port); + + return Host.CreateDefaultBuilder(args) + .ConfigureWebHostDefaults(webBuilder => + { + webBuilder.UseStartup().UseUrls(url); + }); + } + ``` + +1. Update the `app.UseEndpoints(...)` statement in `Startup.cs` to read and return the + TARGET environment variable: + + ```csharp + app.UseEndpoints(endpoints => + { + endpoints.MapGet("/", async context => + { + var target = Environment.GetEnvironmentVariable("TARGET") ?? "World"; + await context.Response.WriteAsync($"Hello {target}!\n"); + }); + }); + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. For detailed instructions on dockerizing an ASP.NET Core + app, see + [Docker images for ASP.NET Core](https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/docker/building-net-docker-images). + + ```docker + # Use Microsoft's official build .NET image. + FROM mcr.microsoft.com/dotnet/core/sdk:3.1 AS build + WORKDIR /app + + # Install production dependencies. + # Copy csproj and restore as distinct layers. + COPY *.csproj ./ + RUN dotnet restore + + # Copy local code to the container image. + COPY . ./ + WORKDIR /app + + # Build a release artifact. + RUN dotnet publish -c Release -o out + + # Use Microsoft's official runtime .NET image. + FROM mcr.microsoft.com/dotnet/core/aspnet:3.1 AS runtime + WORKDIR /app + COPY --from=build /app/out ./ + + # Run the web service on container startup. + ENTRYPOINT ["dotnet", "helloworld-csharp.dll"] + ``` + +1. Create a `.dockerignore` file to ensure that any files related to a local + build do not affect the container that you build for deployment. + + ```ignore + Dockerfile + README.md + **/obj/ + **/bin/ + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-csharp + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-csharp + env: + - name: TARGET + value: "C# Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-csharp . + + # Push the container to docker registry + docker push {username}/helloworld-csharp + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ``` + kubectl get ksvc helloworld-csharp --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-csharp http://helloworld-csharp.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-csharp.default.1.2.3.4.xip.io + Hello C# Sample v1! + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/hello-world/helloworld-kotlin/README.md b/docs/serving/samples/hello-world/helloworld-kotlin/README.md deleted file mode 100644 index c262b78ac..000000000 --- a/docs/serving/samples/hello-world/helloworld-kotlin/README.md +++ /dev/null @@ -1,191 +0,0 @@ -A simple web app written in Kotlin using [Ktor](https://ktor.io/) that you can -use for testing. It reads in an env variable `TARGET` and prints "Hello -\${TARGET}". If TARGET is not specified, it will use "World" as the TARGET. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-kotlin -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new directory and cd into it: - - ```shell - mkdir hello - cd hello - ``` - -2. Create a file named `Main.kt` at `src/main/kotlin/com/example/hello` and copy - the code block below into it: - - ```shell - mkdir -p src/main/kotlin/com/example/hello - ``` - - ```kotlin - package com.example.hello - - import io.ktor.application.* - import io.ktor.http.* - import io.ktor.response.* - import io.ktor.routing.* - import io.ktor.server.engine.* - import io.ktor.server.netty.* - - fun main(args: Array) { - val target = System.getenv("TARGET") ?: "World" - val port = System.getenv("PORT") ?: "8080" - embeddedServer(Netty, port.toInt()) { - routing { - get("/") { - call.respondText("Hello $target!\n", ContentType.Text.Html) - } - } - }.start(wait = true) - } - ``` - -3. Switch back to `hello` directory - -4. Create a new file, `build.gradle` and copy the following setting - - ```groovy - plugins { - id "org.jetbrains.kotlin.jvm" version "1.4.10" - } - apply plugin: 'application' - - mainClassName = 'com.example.hello.MainKt' - - jar { - manifest { - attributes 'Main-Class': mainClassName - } - from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } - } - - repositories { - mavenCentral() - } - - dependencies { - compile "io.ktor:ktor-server-netty:1.3.1" - } - ``` - -5. Create a file named `Dockerfile` and copy the code block below into it. - - ```docker - # Use the official gradle image to create a build artifact. - # https://hub.docker.com/_/gradle - FROM gradle:6.7 as builder - - # Copy local code to the container image. - COPY build.gradle . - COPY src ./src - - # Build a release artifact. - RUN gradle clean build --no-daemon - - # Use the Official OpenJDK image for a lean production stage of our multi-stage build. - # https://hub.docker.com/_/openjdk - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM openjdk:8-jre-alpine - - # Copy the jar to the production image from the builder stage. - COPY --from=builder /home/gradle/build/libs/gradle.jar /helloworld.jar - - # Run the web service on container startup. - CMD [ "java", "-jar", "-Djava.security.egd=file:/dev/./urandom", "/helloworld.jar" ] - ``` - -6. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-kotlin - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-kotlin - env: - - name: TARGET - value: "Kotlin Sample v1" - ``` - -## Build and deploy this sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-kotlin . - - # Push the container to docker registry - docker push {username}/helloworld-kotlin - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ```shell - kubectl get ksvc helloworld-kotlin --output=custom-columns=NAME:.metadata.name,URL:.status.url - - NAME URL - helloworld-kotlin http://helloworld-kotlin.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-kotlin.default.1.2.3.4.xip.io - Hello Kotlin Sample v1! - ``` - -## Remove the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/hello-world/helloworld-kotlin/index.md b/docs/serving/samples/hello-world/helloworld-kotlin/index.md index 1448a8282..12e5eea5e 100644 --- a/docs/serving/samples/hello-world/helloworld-kotlin/index.md +++ b/docs/serving/samples/hello-world/helloworld-kotlin/index.md @@ -5,4 +5,194 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Kotlin using [Ktor](https://ktor.io/) that you can +use for testing. It reads in an env variable `TARGET` and prints "Hello +\${TARGET}". If TARGET is not specified, it will use "World" as the TARGET. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-kotlin +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). + +## Recreating the sample code + +1. Create a new directory and cd into it: + + ```shell + mkdir hello + cd hello + ``` + +2. Create a file named `Main.kt` at `src/main/kotlin/com/example/hello` and copy + the code block below into it: + + ```shell + mkdir -p src/main/kotlin/com/example/hello + ``` + + ```kotlin + package com.example.hello + + import io.ktor.application.* + import io.ktor.http.* + import io.ktor.response.* + import io.ktor.routing.* + import io.ktor.server.engine.* + import io.ktor.server.netty.* + + fun main(args: Array) { + val target = System.getenv("TARGET") ?: "World" + val port = System.getenv("PORT") ?: "8080" + embeddedServer(Netty, port.toInt()) { + routing { + get("/") { + call.respondText("Hello $target!\n", ContentType.Text.Html) + } + } + }.start(wait = true) + } + ``` + +3. Switch back to `hello` directory + +4. Create a new file, `build.gradle` and copy the following setting + + ```groovy + plugins { + id "org.jetbrains.kotlin.jvm" version "1.4.10" + } + apply plugin: 'application' + + mainClassName = 'com.example.hello.MainKt' + + jar { + manifest { + attributes 'Main-Class': mainClassName + } + from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } + } + + repositories { + mavenCentral() + } + + dependencies { + compile "io.ktor:ktor-server-netty:1.3.1" + } + ``` + +5. Create a file named `Dockerfile` and copy the code block below into it. + + ```docker + # Use the official gradle image to create a build artifact. + # https://hub.docker.com/_/gradle + FROM gradle:6.7 as builder + + # Copy local code to the container image. + COPY build.gradle . + COPY src ./src + + # Build a release artifact. + RUN gradle clean build --no-daemon + + # Use the Official OpenJDK image for a lean production stage of our multi-stage build. + # https://hub.docker.com/_/openjdk + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM openjdk:8-jre-alpine + + # Copy the jar to the production image from the builder stage. + COPY --from=builder /home/gradle/build/libs/gradle.jar /helloworld.jar + + # Run the web service on container startup. + CMD [ "java", "-jar", "-Djava.security.egd=file:/dev/./urandom", "/helloworld.jar" ] + ``` + +6. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-kotlin + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-kotlin + env: + - name: TARGET + value: "Kotlin Sample v1" + ``` + +## Build and deploy this sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-kotlin . + + # Push the container to docker registry + docker push {username}/helloworld-kotlin + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ```shell + kubectl get ksvc helloworld-kotlin --output=custom-columns=NAME:.metadata.name,URL:.status.url + + NAME URL + helloworld-kotlin http://helloworld-kotlin.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-kotlin.default.1.2.3.4.xip.io + Hello Kotlin Sample v1! + ``` + +## Remove the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/hello-world/helloworld-nodejs/README.md b/docs/serving/samples/hello-world/helloworld-nodejs/README.md deleted file mode 100644 index 054d3f7cd..000000000 --- a/docs/serving/samples/hello-world/helloworld-nodejs/README.md +++ /dev/null @@ -1,198 +0,0 @@ -A simple web app written in Node.js that you can use for testing. It reads in an -env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not -specified, it will use "World" as the TARGET. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-nodejs -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). -- [Node.js](https://nodejs.org/en/) installed and configured. - -## Recreating the sample code - -1. Create a new directory and initialize `npm`: - - ```shell - npm init - - package name: (helloworld-nodejs) - version: (1.0.0) - description: - entry point: (index.js) - test command: - git repository: - keywords: - author: - license: (ISC) Apache-2.0 - ``` - -1. Install the `express` package: - - ```shell - npm install express - ``` - -1. Create a new file named `index.js` and paste the following code: - - ```js - const express = require('express'); - const app = express(); - - app.get('/', (req, res) => { - console.log('Hello world received a request.'); - - const target = process.env.TARGET || 'World'; - res.send(`Hello ${target}!\n`); - }); - - const port = process.env.PORT || 8080; - app.listen(port, () => { - console.log('Hello world listening on port', port); - }); - ``` - -1. Modify the `package.json` file to add a start command to the scripts section: - - ```json - { - "name": "knative-serving-helloworld", - "version": "1.0.0", - "description": "Simple hello world sample in Node", - "main": "index.js", - "scripts": { - "start": "node index.js" - }, - "author": "", - "license": "Apache-2.0", - "dependencies": { - "express": "^4.16.4" - } - } - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. For detailed instructions on dockerizing a Node.js app, - see - [Dockerizing a Node.js web app](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/). - - ```Dockerfile - # Use the official lightweight Node.js 12 image. - # https://hub.docker.com/_/node - FROM node:12-slim - - # Create and change to the app directory. - WORKDIR /usr/src/app - - # Copy application dependency manifests to the container image. - # A wildcard is used to ensure both package.json AND package-lock.json are copied. - # Copying this separately prevents re-running npm install on every code change. - COPY package*.json ./ - - # Install production dependencies. - RUN npm install --only=production - - # Copy local code to the container image. - COPY . ./ - - # Run the web service on container startup. - CMD [ "npm", "start" ] - ``` - -1. Create a `.dockerignore` file to ensure that any files related to a local - build do not affect the container that you build for deployment. - - ```ignore - Dockerfile - README.md - node_modules - npm-debug.log - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-nodejs - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-nodejs - env: - - name: TARGET - value: "Node.js Sample v1" - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-nodejs . - - # Push the container to docker registry - docker push {username}/helloworld-nodejs - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-nodejs --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-nodejs http://helloworld-nodejs.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-nodejs.default.1.2.3.4.xip.io - Hello Node.js Sample v1! - ``` - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/hello-world/helloworld-nodejs/index.md b/docs/serving/samples/hello-world/helloworld-nodejs/index.md index b4c0b8895..a7458e554 100644 --- a/docs/serving/samples/hello-world/helloworld-nodejs/index.md +++ b/docs/serving/samples/hello-world/helloworld-nodejs/index.md @@ -5,4 +5,201 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Node.js that you can use for testing. It reads in an +env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not +specified, it will use "World" as the TARGET. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/hello-world/helloworld-nodejs +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). +- [Node.js](https://nodejs.org/en/) installed and configured. + +## Recreating the sample code + +1. Create a new directory and initialize `npm`: + + ```shell + npm init + + package name: (helloworld-nodejs) + version: (1.0.0) + description: + entry point: (index.js) + test command: + git repository: + keywords: + author: + license: (ISC) Apache-2.0 + ``` + +1. Install the `express` package: + + ```shell + npm install express + ``` + +1. Create a new file named `index.js` and paste the following code: + + ```js + const express = require('express'); + const app = express(); + + app.get('/', (req, res) => { + console.log('Hello world received a request.'); + + const target = process.env.TARGET || 'World'; + res.send(`Hello ${target}!\n`); + }); + + const port = process.env.PORT || 8080; + app.listen(port, () => { + console.log('Hello world listening on port', port); + }); + ``` + +1. Modify the `package.json` file to add a start command to the scripts section: + + ```json + { + "name": "knative-serving-helloworld", + "version": "1.0.0", + "description": "Simple hello world sample in Node", + "main": "index.js", + "scripts": { + "start": "node index.js" + }, + "author": "", + "license": "Apache-2.0", + "dependencies": { + "express": "^4.16.4" + } + } + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. For detailed instructions on dockerizing a Node.js app, + see + [Dockerizing a Node.js web app](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/). + + ```Dockerfile + # Use the official lightweight Node.js 12 image. + # https://hub.docker.com/_/node + FROM node:12-slim + + # Create and change to the app directory. + WORKDIR /usr/src/app + + # Copy application dependency manifests to the container image. + # A wildcard is used to ensure both package.json AND package-lock.json are copied. + # Copying this separately prevents re-running npm install on every code change. + COPY package*.json ./ + + # Install production dependencies. + RUN npm install --only=production + + # Copy local code to the container image. + COPY . ./ + + # Run the web service on container startup. + CMD [ "npm", "start" ] + ``` + +1. Create a `.dockerignore` file to ensure that any files related to a local + build do not affect the container that you build for deployment. + + ```ignore + Dockerfile + README.md + node_modules + npm-debug.log + ``` + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-nodejs + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-nodejs + env: + - name: TARGET + value: "Node.js Sample v1" + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-nodejs . + + # Push the container to docker registry + docker push {username}/helloworld-nodejs + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. To find the URL for your service, use + + ``` + kubectl get ksvc helloworld-nodejs --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + helloworld-nodejs http://helloworld-nodejs.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-nodejs.default.1.2.3.4.xip.io + Hello Node.js Sample v1! + ``` + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/hello-world/helloworld-python/README.md b/docs/serving/samples/hello-world/helloworld-python/README.md deleted file mode 100644 index 94cf4eb4d..000000000 --- a/docs/serving/samples/hello-world/helloworld-python/README.md +++ /dev/null @@ -1,163 +0,0 @@ -A simple web app written in Python that you can use for testing. It reads in an -env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not -specified, it will use "World" as the TARGET. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-python -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new directory and cd into it: - - ```shell - mkdir app - cd app - ``` - -1. Create a file named `app.py` and copy the code block below into it: - - ```python - import os - - from flask import Flask - - app = Flask(__name__) - - @app.route('/') - def hello_world(): - target = os.environ.get('TARGET', 'World') - return 'Hello {}!\n'.format(target) - - if __name__ == "__main__": - app.run(debug=True,host='0.0.0.0',port=int(os.environ.get('PORT', 8080))) - ``` - -1. Create a file named `Dockerfile` and copy the code block below into it. See - [official Python docker image](https://hub.docker.com/_/python/) for more - details. - - ```docker - # Use the official lightweight Python image. - # https://hub.docker.com/_/python - FROM python:3.7-slim - - # Allow statements and log messages to immediately appear in the Knative logs - ENV PYTHONUNBUFFERED True - - # Copy local code to the container image. - ENV APP_HOME /app - WORKDIR $APP_HOME - COPY . ./ - - # Install production dependencies. - RUN pip install Flask gunicorn - - # Run the web service on container startup. Here we use the gunicorn - # webserver, with one worker process and 8 threads. - # For environments with multiple CPU cores, increase the number of workers - # to be equal to the cores available. - CMD exec gunicorn --bind :$PORT --workers 1 --threads 8 --timeout 0 app:app - ``` - -1. Create a `.dockerignore` file to ensure that any files related to a local - build do not affect the container that you build for deployment. - - ```ignore - Dockerfile - README.md - *.pyc - *.pyo - *.pyd - __pycache__ - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-python - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-python - env: - - name: TARGET - value: "Python Sample v1" - ``` - -## Build and deploy this sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-python . - - # Push the container to docker registry - docker push {username}/helloworld-python - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. To find the URL for your service, use - - ``` - kubectl get ksvc helloworld-python --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - helloworld-python http://helloworld-python.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-python.default.1.2.3.4.xip.io - Hello Python Sample v1! - ``` - -## Remove the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/knative-routing-go/README.md b/docs/serving/samples/knative-routing-go/README.md deleted file mode 100644 index dca09531e..000000000 --- a/docs/serving/samples/knative-routing-go/README.md +++ /dev/null @@ -1,264 +0,0 @@ -This example shows how to map multiple Knative services to different paths under -a single domain name using the Istio VirtualService concept. Istio is a -general-purpose reverse proxy, therefore these directions can also be used to -configure routing based on other request data such as headers, or even to map -Knative and external resources under the same domain name. - -In this sample, we set up two web services: `Search` service and `Login` -service, which simply read in an env variable `SERVICE_NAME` and prints -`"${SERVICE_NAME} is called"`. We'll then create a VirtualService with host -`example.com`, and define routing rules in the VirtualService so that -`example.com/search` maps to the Search service, and `example.com/login` maps to -the Login service. - -## Prerequisites - -1. A Kubernetes cluster with [Knative Serving](../../../install/README.md) - installed. -2. Install - [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment). -3. Acquire a domain name. - - In this example, we use `example.com`. If you don't have a domain name, you - can modify your hosts file (on Mac or Linux) to map `example.com` to your - cluster's ingress IP. - - If you have configured a custom domain for your Knative installation, we - will refer to it as in the rest of this document -4. Check out the code: - -``` -go get -d github.com/knative/docs/docs/serving/samples/knative-routing-go -``` - -## Setup - -To check the domain name, run the following command: - -``` -kubectl get cm -n knative-serving config-domain -o yaml -``` - -Then, check the value for `data`. The domain name should be in the format of -`: ""`, if it is available. - -Build the application container and publish it to a container registry: - -1. Move into the sample directory: - -```shell -cd $GOPATH/src/github.com/knative/docs -``` - -2. Set your preferred container registry: - -If you use Google Container Registry (GCR), you will need to enable the -[GCR API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com) -in your GCP project. - -```shell -export REPO="gcr.io/" -``` - -If you use Docker Hub as your docker image registry, replace with -your dockerhub username and run the following command: - -```shell -export REPO="docker.io/" -``` - -3. Use Docker to build your application container: - -``` -docker build \ - --tag "${REPO}/knative-routing-go" \ - --file=docs/serving/samples/knative-routing-go/Dockerfile . -``` - -4. Push your container to a container registry: - -``` -docker push "${REPO}/knative-routing-go" -``` - -5. Replace the image reference path with our published image path in the - configuration file `docs/serving/samples/knative-routing-go/sample.yaml`: - - - Manually replace: - `image: github.com/knative/docs/docs/serving/samples/knative-routing-go` - with `image: ${REPO}/knative-routing-go` If you manually changed the .yaml - file, you must replace \${REPO} with the correct path on your local - machine. - - Or - - - Run this command: - - ``` - perl -pi -e "s@github.com/knative/docs/docs/serving/samples@${REPO}@g" docs/serving/samples/knative-routing-go/sample.yaml - ``` - -## Deploy the Service - -Deploy the Knative Serving sample: - -``` -kubectl apply --filename docs/serving/samples/knative-routing-go/sample.yaml -``` - -## Exploring the Routes - -A shared Gateway `knative-ingress-gateway` is used within Knative service mesh -for serving all incoming traffic. You can inspect it and its corresponding -Kubernetes service with: - -- Check the shared Gateway: - -``` -kubectl get Gateway --namespace knative-serving --output yaml -``` - -- Check the corresponding Kubernetes service for the shared Gateway: - -``` -INGRESSGATEWAY=istio-ingressgateway - -kubectl get svc $INGRESSGATEWAY --namespace istio-system --output yaml -``` - -- Inspect the deployed Knative services with: - -``` -kubectl get ksvc -``` - -You should see 2 Knative services: `search-service` and `login-service`. - -### Access the Services - -1. Find the shared Gateway IP and export as an environment variable: - -```shell -INGRESSGATEWAY=istio-ingressgateway - -export GATEWAY_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \ - --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` -``` - -2. Find the `Search` service URL with: - -```shell -# kubectl get route search-service --output=custom-columns=NAME:.metadata.name,URL:.status.url -NAME URL -search-service http://search-service.default.example.com -``` - -3. Make a curl request to the service: - -```shell -curl http://${GATEWAY_IP} --header "Host:search-service.default.example.com" -``` - -You should see: `Search Service is called !` - -4. Similarly, you can also directly access "Login" service with: - -```shell -curl http://${GATEWAY_IP} --header "Host:login-service.default.example.com" -``` - -You should see: `Login Service is called !` - -## Apply Custom Routing Rule - -1. Apply the custom routing rules defined in `routing.yaml` file with: - -``` -kubectl apply --filename docs/serving/samples/knative-routing-go/routing.yaml -``` - -If you have configured a custom domain name for your service, please replace all -mentions of "example.com" in `routing.yaml` with "" for -spec.hosts and spec.http.rewrite.authority. - -In addition, you need to verify how your domain template is defined. By default, -we use the format of {{.Name}}.{{.Namespace}}, like search-service.default and -login-service.default. However, some Knative environments may use other format -like {{.Name}}-{{.Namespace}}. You can find out the format by running the -command: - -``` -kubectl get cm -n knative-serving config-network -o yaml -``` - -Then look for the value for `domainTemplate`. If it is -`{{.Name}}-{{.Namespace}}.{{.Domain}}`, you need to change -`search-service.default` into `search-service-default` and -`login-service.default` into `login-service-default` as well in `routing.yaml`. - -2. The `routing.yaml` file will generate a new VirtualService `entry-route` for - domain `example.com` or your own domain name. View the VirtualService: - -``` -kubectl get VirtualService entry-route --output yaml -``` - -3. Send a request to the `Search` service and the `Login` service by using - corresponding URIs. You should get the same results as directly accessing - these services. Get the ingress IP: - - ```shell - INGRESSGATEWAY=istio-ingressgateway - - export GATEWAY_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \ - --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` - ``` - -* Send a request to the Search service: - - ```shell - curl http://${GATEWAY_IP}/search --header "Host: example.com" - ``` - - or - - ```shell - curl http://${GATEWAY_IP}/search --header "Host: " - ``` - - for the case using your own domain. - -* Send a request to the Login service: - - ```shell - curl http://${GATEWAY_IP}/login --header "Host: example.com" - ``` - - or - - ```shell - curl http://${GATEWAY_IP}/login --header "Host: " - ``` - - for the case using your own domain. - -## How It Works - -When an external request with host `example.com` or your own domain name reaches -`knative-ingress-gateway` Gateway, the `entry-route` VirtualService will check -if it has `/search` or `/login` URI. If the URI matches, then the host of -request will be rewritten into the host of `Search` service or `Login` service -correspondingly. This resets the final destination of the request. The request -with updated host will be forwarded to `knative-ingress-gateway` Gateway again. -The Gateway proxy checks the updated host, and forwards it to `Search` or -`Login` service according to its host setting. - -![Object model](./images/knative-routing-sample-flow.png) - -## Clean Up - -To clean up the sample resources: - -```shell -kubectl delete --filename docs/serving/samples/knative-routing-go/sample.yaml -kubectl delete --filename docs/serving/samples/knative-routing-go/routing.yaml -``` - diff --git a/docs/serving/samples/knative-routing-go/index.md b/docs/serving/samples/knative-routing-go/index.md index 4ab7d2aa9..4152ebbf6 100644 --- a/docs/serving/samples/knative-routing-go/index.md +++ b/docs/serving/samples/knative-routing-go/index.md @@ -5,4 +5,267 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +This example shows how to map multiple Knative services to different paths under +a single domain name using the Istio VirtualService concept. Istio is a +general-purpose reverse proxy, therefore these directions can also be used to +configure routing based on other request data such as headers, or even to map +Knative and external resources under the same domain name. + +In this sample, we set up two web services: `Search` service and `Login` +service, which simply read in an env variable `SERVICE_NAME` and prints +`"${SERVICE_NAME} is called"`. We'll then create a VirtualService with host +`example.com`, and define routing rules in the VirtualService so that +`example.com/search` maps to the Search service, and `example.com/login` maps to +the Login service. + +## Prerequisites + +1. A Kubernetes cluster with [Knative Serving](../../../install/README.md) + installed. +2. Install + [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment). +3. Acquire a domain name. + - In this example, we use `example.com`. If you don't have a domain name, you + can modify your hosts file (on Mac or Linux) to map `example.com` to your + cluster's ingress IP. + - If you have configured a custom domain for your Knative installation, we + will refer to it as in the rest of this document +4. Check out the code: + +``` +go get -d github.com/knative/docs/docs/serving/samples/knative-routing-go +``` + +## Setup + +To check the domain name, run the following command: + +``` +kubectl get cm -n knative-serving config-domain -o yaml +``` + +Then, check the value for `data`. The domain name should be in the format of +`: ""`, if it is available. + +Build the application container and publish it to a container registry: + +1. Move into the sample directory: + +```shell +cd $GOPATH/src/github.com/knative/docs +``` + +2. Set your preferred container registry: + +If you use Google Container Registry (GCR), you will need to enable the +[GCR API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com) +in your GCP project. + +```shell +export REPO="gcr.io/" +``` + +If you use Docker Hub as your docker image registry, replace with +your dockerhub username and run the following command: + +```shell +export REPO="docker.io/" +``` + +3. Use Docker to build your application container: + +``` +docker build \ + --tag "${REPO}/knative-routing-go" \ + --file=docs/serving/samples/knative-routing-go/Dockerfile . +``` + +4. Push your container to a container registry: + +``` +docker push "${REPO}/knative-routing-go" +``` + +5. Replace the image reference path with our published image path in the + configuration file `docs/serving/samples/knative-routing-go/sample.yaml`: + + - Manually replace: + `image: github.com/knative/docs/docs/serving/samples/knative-routing-go` + with `image: ${REPO}/knative-routing-go` If you manually changed the .yaml + file, you must replace \${REPO} with the correct path on your local + machine. + + Or + + - Run this command: + + ``` + perl -pi -e "s@github.com/knative/docs/docs/serving/samples@${REPO}@g" docs/serving/samples/knative-routing-go/sample.yaml + ``` + +## Deploy the Service + +Deploy the Knative Serving sample: + +``` +kubectl apply --filename docs/serving/samples/knative-routing-go/sample.yaml +``` + +## Exploring the Routes + +A shared Gateway `knative-ingress-gateway` is used within Knative service mesh +for serving all incoming traffic. You can inspect it and its corresponding +Kubernetes service with: + +- Check the shared Gateway: + +``` +kubectl get Gateway --namespace knative-serving --output yaml +``` + +- Check the corresponding Kubernetes service for the shared Gateway: + +``` +INGRESSGATEWAY=istio-ingressgateway + +kubectl get svc $INGRESSGATEWAY --namespace istio-system --output yaml +``` + +- Inspect the deployed Knative services with: + +``` +kubectl get ksvc +``` + +You should see 2 Knative services: `search-service` and `login-service`. + +### Access the Services + +1. Find the shared Gateway IP and export as an environment variable: + +```shell +INGRESSGATEWAY=istio-ingressgateway + +export GATEWAY_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \ + --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` +``` + +2. Find the `Search` service URL with: + +```shell +# kubectl get route search-service --output=custom-columns=NAME:.metadata.name,URL:.status.url +NAME URL +search-service http://search-service.default.example.com +``` + +3. Make a curl request to the service: + +```shell +curl http://${GATEWAY_IP} --header "Host:search-service.default.example.com" +``` + +You should see: `Search Service is called !` + +4. Similarly, you can also directly access "Login" service with: + +```shell +curl http://${GATEWAY_IP} --header "Host:login-service.default.example.com" +``` + +You should see: `Login Service is called !` + +## Apply Custom Routing Rule + +1. Apply the custom routing rules defined in `routing.yaml` file with: + +``` +kubectl apply --filename docs/serving/samples/knative-routing-go/routing.yaml +``` + +If you have configured a custom domain name for your service, please replace all +mentions of "example.com" in `routing.yaml` with "" for +spec.hosts and spec.http.rewrite.authority. + +In addition, you need to verify how your domain template is defined. By default, +we use the format of {{.Name}}.{{.Namespace}}, like search-service.default and +login-service.default. However, some Knative environments may use other format +like {{.Name}}-{{.Namespace}}. You can find out the format by running the +command: + +``` +kubectl get cm -n knative-serving config-network -o yaml +``` + +Then look for the value for `domainTemplate`. If it is +`{{.Name}}-{{.Namespace}}.{{.Domain}}`, you need to change +`search-service.default` into `search-service-default` and +`login-service.default` into `login-service-default` as well in `routing.yaml`. + +2. The `routing.yaml` file will generate a new VirtualService `entry-route` for + domain `example.com` or your own domain name. View the VirtualService: + +``` +kubectl get VirtualService entry-route --output yaml +``` + +3. Send a request to the `Search` service and the `Login` service by using + corresponding URIs. You should get the same results as directly accessing + these services. Get the ingress IP: + + ```shell + INGRESSGATEWAY=istio-ingressgateway + + export GATEWAY_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \ + --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` + ``` + +* Send a request to the Search service: + + ```shell + curl http://${GATEWAY_IP}/search --header "Host: example.com" + ``` + + or + + ```shell + curl http://${GATEWAY_IP}/search --header "Host: " + ``` + + for the case using your own domain. + +* Send a request to the Login service: + + ```shell + curl http://${GATEWAY_IP}/login --header "Host: example.com" + ``` + + or + + ```shell + curl http://${GATEWAY_IP}/login --header "Host: " + ``` + + for the case using your own domain. + +## How It Works + +When an external request with host `example.com` or your own domain name reaches +`knative-ingress-gateway` Gateway, the `entry-route` VirtualService will check +if it has `/search` or `/login` URI. If the URI matches, then the host of +request will be rewritten into the host of `Search` service or `Login` service +correspondingly. This resets the final destination of the request. The request +with updated host will be forwarded to `knative-ingress-gateway` Gateway again. +The Gateway proxy checks the updated host, and forwards it to `Search` or +`Login` service according to its host setting. + +![Object model](./images/knative-routing-sample-flow.png) + +## Clean Up + +To clean up the sample resources: + +```shell +kubectl delete --filename docs/serving/samples/knative-routing-go/sample.yaml +kubectl delete --filename docs/serving/samples/knative-routing-go/routing.yaml +``` + diff --git a/docs/serving/samples/multi-container/README.md b/docs/serving/samples/multi-container/README.md deleted file mode 100644 index 82fae8040..000000000 --- a/docs/serving/samples/multi-container/README.md +++ /dev/null @@ -1,259 +0,0 @@ -A simple web app written in Go that you can use for multi container testing. - -## Prerequisites - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). -- Make sure multi-container flag is enabled as part of `config-features` configmap. - -The following steps show how you can use the sample code and deploy the app to your -cluster. - -You can download a working copy of the sample, by entering the -following command: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -``` - -## Using the sample code - -To test multi container functionality, you must create two containers: a serving container, and a sidecar container. - -The `multi-container` directory is provided in the sample code, and contains predefined code and dockerfiles for creating the containers. - -You can update the default files and YAML by using the steps outlined in this section. - -### Serving Container -1. After you have cloned the sample repository, navigate to the servingcontainer directory: - - `cd knative-docs/docs/serving/samples/multi-container/servingcontainer` -1. Create a basic web server which listens on port 8881. -You can do this by copying the following code into the `servingcontainer.go` file: - - ```go - package main - import ( - "fmt" - "io/ioutil" - "log" - "net/http" - ) - func handler(w http.ResponseWriter, r *http.Request) { - log.Println("serving container received a request.") - res, err := http.Get("http://127.0.0.1:8882") - if err != nil { - log.Fatal(err) - } - resp, err := ioutil.ReadAll(res.Body) - if err != nil { - log.Fatal(err) - } - fmt.Fprintln(w, string(resp)) - } - func main() { - log.Print("serving container started...") - http.HandleFunc("/", handler) - log.Fatal(http.ListenAndServe(":8881", nil)) - } - ``` -1. Copy the following code into the `Dockerfile` file: - - ```docker - # Use the official Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - # https://hub.docker.com/_/golang - FROM golang:1.15 as builder - # Create and change to the app directory. - WORKDIR /app - # Retrieve application dependencies using go modules. - # Allows container builds to reuse downloaded dependencies. - COPY go.* ./ - RUN go mod download - # Copy local code to the container image. - COPY . ./ - # Build the binary. - # -mod=readonly ensures immutable go.mod and go.sum in container builds. - RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o servingcontainer - # Use the official Alpine image for a lean production container. - # https://hub.docker.com/_/alpine - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM alpine:3 - RUN apk add --no-cache ca-certificates - # Copy the binary to the production image from the builder stage. - COPY --from=builder /app/servingcontainer /servingcontainer - # Run the web service on container startup. - CMD ["/servingcontainer"] - ``` - -### Sidecar Container -1. After you have cloned the sample repository, navigate to the sidecarcontainer directory: - ```text - cd - - cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer - ``` - -1. Create a basic web server which listens on port 8882. -You can do this by copying the following code into the `sidecarcontainer.go` file: - - ```go - package main - import ( - "fmt" - "log" - "net/http" - ) - func handler(w http.ResponseWriter, r *http.Request) { - log.Println("sidecar container received a request.") - fmt.Fprintln(w, "Yay!! multi-container works") - } - func main() { - log.Print("sidecar container started...") - http.HandleFunc("/", handler) - log.Fatal(http.ListenAndServe(":8882", nil)) - } - ``` - -1. Copy the following code into the `Dockerfile` file: - - ```docker - # Use the official Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - # https://hub.docker.com/_/golang - FROM golang:1.15 as builder - # Create and change to the app directory. - WORKDIR /app - # Retrieve application dependencies using go modules. - # Allows container builds to reuse downloaded dependencies. - COPY go.* ./ - RUN go mod download - # Copy local code to the container image. - COPY . ./ - # Build the binary. - # -mod=readonly ensures immutable go.mod and go.sum in container builds. - RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o sidecarcontainer - # Use the official Alpine image for a lean production container. - # https://hub.docker.com/_/alpine - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM alpine:3 - RUN apk add --no-cache ca-certificates - # Copy the binary to the production image from the builder stage. - COPY --from=builder /app/sidecarcontainer /sidecarcontainer - # Run the web service on container startup. - CMD ["/sidecarcontainer"] - ``` - -### Writing Knative Service YAML - -1. After you have cloned the sample repository, navigate to the `multi-container` directory: - 1. `cd -` - 2. `cd knative-docs/docs/serving/samples/multi-container/` - -1. Copy the following YAML service definition into the `service.yaml` file: - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: multi-container - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/servingcontainer - ports: - - containerPort: 8881 - - image: docker.io/{username}/sidecarcontainer - ``` - -**NOTE:** Replace `{username}` with your Docker Hub username. - -1. Use Go tool to create a - [`go.mod`](https://github.com/golang/go/wiki/Modules#gomod) manifest: - - servingcontainer - ```shell - cd - - cd knative-docs/docs/serving/samples/multi-container/servingcontainer - go mod init github.com/knative/docs/docs/serving/samples/multi-container/servingcontainer - ``` - sidecarcontainer - ```shell - cd - - cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer - go mod init github.com/knative/docs/docs/serving/samples/multi-container/sidecarcontainer - ``` - -## Building and deploying the sample - -After you have modified the sample code files you can build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - cd - - cd knative-docs/docs/serving/samples/multi-container/servingcontainer - docker build -t {username}/servingcontainer . - cd - - cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer - docker build -t {username}/sidecarcontainer . - # Push the container to docker registry - docker push {username}/servingcontainer - docker push {username}/sidecarcontainer - ``` - -1. After the build has completed and the container is pushed to Docker Hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - cd - - cd knative-docs/docs/serving/samples/multi-container - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc multi-container --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - multi-container http://multi-container.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://multi-container.default.1.2.3.4.xip.io - Yay!! multi-container works - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/multi-container/index.md b/docs/serving/samples/multi-container/index.md index ede09b5f5..a4aa1ce9f 100644 --- a/docs/serving/samples/multi-container/index.md +++ b/docs/serving/samples/multi-container/index.md @@ -5,4 +5,262 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Go that you can use for multi container testing. + +## Prerequisites + +- A Kubernetes cluster with Knative installed and DNS configured. Follow the + [installation instructions](../../../install/README.md) if you need to + create one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). +- Make sure multi-container flag is enabled as part of `config-features` configmap. + +The following steps show how you can use the sample code and deploy the app to your +cluster. + +You can download a working copy of the sample, by entering the +following command: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +``` + +## Using the sample code + +To test multi container functionality, you must create two containers: a serving container, and a sidecar container. + +The `multi-container` directory is provided in the sample code, and contains predefined code and dockerfiles for creating the containers. + +You can update the default files and YAML by using the steps outlined in this section. + +### Serving Container +1. After you have cloned the sample repository, navigate to the servingcontainer directory: + + `cd knative-docs/docs/serving/samples/multi-container/servingcontainer` +1. Create a basic web server which listens on port 8881. +You can do this by copying the following code into the `servingcontainer.go` file: + + ```go + package main + import ( + "fmt" + "io/ioutil" + "log" + "net/http" + ) + func handler(w http.ResponseWriter, r *http.Request) { + log.Println("serving container received a request.") + res, err := http.Get("http://127.0.0.1:8882") + if err != nil { + log.Fatal(err) + } + resp, err := ioutil.ReadAll(res.Body) + if err != nil { + log.Fatal(err) + } + fmt.Fprintln(w, string(resp)) + } + func main() { + log.Print("serving container started...") + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":8881", nil)) + } + ``` +1. Copy the following code into the `Dockerfile` file: + + ```docker + # Use the official Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + # https://hub.docker.com/_/golang + FROM golang:1.15 as builder + # Create and change to the app directory. + WORKDIR /app + # Retrieve application dependencies using go modules. + # Allows container builds to reuse downloaded dependencies. + COPY go.* ./ + RUN go mod download + # Copy local code to the container image. + COPY . ./ + # Build the binary. + # -mod=readonly ensures immutable go.mod and go.sum in container builds. + RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o servingcontainer + # Use the official Alpine image for a lean production container. + # https://hub.docker.com/_/alpine + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM alpine:3 + RUN apk add --no-cache ca-certificates + # Copy the binary to the production image from the builder stage. + COPY --from=builder /app/servingcontainer /servingcontainer + # Run the web service on container startup. + CMD ["/servingcontainer"] + ``` + +### Sidecar Container +1. After you have cloned the sample repository, navigate to the sidecarcontainer directory: + ```text + cd - + cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer + ``` + +1. Create a basic web server which listens on port 8882. +You can do this by copying the following code into the `sidecarcontainer.go` file: + + ```go + package main + import ( + "fmt" + "log" + "net/http" + ) + func handler(w http.ResponseWriter, r *http.Request) { + log.Println("sidecar container received a request.") + fmt.Fprintln(w, "Yay!! multi-container works") + } + func main() { + log.Print("sidecar container started...") + http.HandleFunc("/", handler) + log.Fatal(http.ListenAndServe(":8882", nil)) + } + ``` + +1. Copy the following code into the `Dockerfile` file: + + ```docker + # Use the official Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + # https://hub.docker.com/_/golang + FROM golang:1.15 as builder + # Create and change to the app directory. + WORKDIR /app + # Retrieve application dependencies using go modules. + # Allows container builds to reuse downloaded dependencies. + COPY go.* ./ + RUN go mod download + # Copy local code to the container image. + COPY . ./ + # Build the binary. + # -mod=readonly ensures immutable go.mod and go.sum in container builds. + RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o sidecarcontainer + # Use the official Alpine image for a lean production container. + # https://hub.docker.com/_/alpine + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM alpine:3 + RUN apk add --no-cache ca-certificates + # Copy the binary to the production image from the builder stage. + COPY --from=builder /app/sidecarcontainer /sidecarcontainer + # Run the web service on container startup. + CMD ["/sidecarcontainer"] + ``` + +### Writing Knative Service YAML + +1. After you have cloned the sample repository, navigate to the `multi-container` directory: + 1. `cd -` + 2. `cd knative-docs/docs/serving/samples/multi-container/` + +1. Copy the following YAML service definition into the `service.yaml` file: + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: multi-container + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/servingcontainer + ports: + - containerPort: 8881 + - image: docker.io/{username}/sidecarcontainer + ``` + +**NOTE:** Replace `{username}` with your Docker Hub username. + +1. Use Go tool to create a + [`go.mod`](https://github.com/golang/go/wiki/Modules#gomod) manifest: + + servingcontainer + ```shell + cd - + cd knative-docs/docs/serving/samples/multi-container/servingcontainer + go mod init github.com/knative/docs/docs/serving/samples/multi-container/servingcontainer + ``` + sidecarcontainer + ```shell + cd - + cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer + go mod init github.com/knative/docs/docs/serving/samples/multi-container/sidecarcontainer + ``` + +## Building and deploying the sample + +After you have modified the sample code files you can build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + cd - + cd knative-docs/docs/serving/samples/multi-container/servingcontainer + docker build -t {username}/servingcontainer . + cd - + cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer + docker build -t {username}/sidecarcontainer . + # Push the container to docker registry + docker push {username}/servingcontainer + docker push {username}/sidecarcontainer + ``` + +1. After the build has completed and the container is pushed to Docker Hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + cd - + cd knative-docs/docs/serving/samples/multi-container + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc multi-container --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + multi-container http://multi-container.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://multi-container.default.1.2.3.4.xip.io + Yay!! multi-container works + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +``` diff --git a/docs/serving/samples/rest-api-go/README.md b/docs/serving/samples/rest-api-go/README.md deleted file mode 100644 index 958e2506c..000000000 --- a/docs/serving/samples/rest-api-go/README.md +++ /dev/null @@ -1,208 +0,0 @@ -This "stock ticker" sample demonstrates how to create and run a simple RESTful -service on Knative Serving. The exposed endpoint outputs the stock price for a -given "[stock symbol](https://www.marketwatch.com/tools/quotes/lookup.asp)", -like `AAPL`,`AMZN`, `GOOG`, `MSFT`, etc. - -## Prerequisites - -1. A Kubernetes cluster with [Knative Serving](../../../install/README.md) installed - and DNS configured. -1. [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment) - installed locally. -1. `envsubst` installed locally. This is installed by the `gettext` package. If - not installed it can be installed by a Linux package manager, or by - [Homebrew](https://brew.sh/) on OS X. -1. Download a copy of the code: - - ```shell - git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs - cd knative-docs - ``` - -## Setup - -In order to run an application on Knative Serving a container image must be -available to fetch from a container registry. - -This sample uses Docker for both building and pushing. - -To build and push to a container registry using Docker: - -1. From the `knative-docs` directory, run the following command to set your - container registry endpoint as an environment variable. - - This sample uses - [Google Container Registry (GCR)](https://cloud.google.com/container-registry/): - - ```shell - export REPO="gcr.io/" - ``` - -1. Set up your container registry to make sure you are ready to push. - - To push to GCR, you need to: - - - Create a - [Google Cloud Platform project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project). - - Enable the - [Google Container Registry API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). - - Setup an - [auth helper](https://cloud.google.com/container-registry/docs/advanced-authentication#gcloud_as_a_docker_credential_helper) - to give the Docker client the permissions it needs to push. - - If you are using a different container registry, you will want to follow the - registry specific instructions for both setup and authorizing the image push. - -1. Use Docker to build your application container: - - ```shell - docker build \ - --tag "${REPO}/rest-api-go" \ - --file docs/serving/samples/rest-api-go/Dockerfile . - ``` - -1. Push your container to a container registry: - - ```shell - docker push "${REPO}/rest-api-go" - ``` - -1. Substitute the image reference path in the template with our published image - path. The command below substitutes using the \${REPO} variable into a new - file called `docs/serving/samples/rest-api-go/sample.yaml`. - - ```shell - envsubst < docs/serving/samples/rest-api-go/sample-template.yaml > \ - docs/serving/samples/rest-api-go/sample.yaml - ``` - -## Deploy the Service - -Now that our image is available from the container registry, we can deploy the -Knative Serving sample: - -```shell -kubectl apply --filename docs/serving/samples/rest-api-go/sample.yaml -``` - -The above command creates a Knative Service within your Kubernetes cluster in -the default namespace. - -## Explore the Service - -The Knative Service creates the following child resources: - -- Knative Route -- Knative Configuration -- Knative Revision -- Kubernetes Deployment -- Kubernetes Service - -You can inspect the created resources with the following `kubectl` commands: - -- View the created Service resource: - - ```shell - kubectl get ksvc stock-service-example --output yaml - ``` - -- View the created Route resource: - - ```shell - kubectl get route -l \ - "serving.knative.dev/service=stock-service-example" --output yaml - ``` - -- View the Kubernetes Service created by the Route - - ```shell - kubectl get service -l \ - "serving.knative.dev/service=stock-service-example" --output yaml - ``` - -- View the created Configuration resource: - - ```shell - kubectl get configuration -l \ - "serving.knative.dev/service=stock-service-example" --output yaml - ``` - -- View the Revision that was created by our Configuration: - - ```shell - kubectl get revision -l \ - "serving.knative.dev/service=stock-service-example" --output yaml - ``` - -- View the Deployment created by our Revision - - ```shell - kubectl get deployment -l \ - "serving.knative.dev/service=stock-service-example" --output yaml - ``` - -## Access the Service - -To access this service and run the stock ticker, you first obtain the service URL, -and then you run `curl` commands to send request with your stock symbol. - -1. Get the URL of the service: - - ```shell - kubectl get ksvc stock-service-example --output=custom-columns=NAME:.metadata.name,URL:.status.url - NAME URL - stock-service-example http://stock-service-example.default.1.2.3.4.xip.io - ``` - -2. Send requests to the service using `curl`: - - 1. Send a request to the index endpoint: - - ```shell - curl http://stock-service-example.default.1.2.3.4.xip.io - ``` - - Response body: `Welcome to the stock app!` - - 2. Send a request to the `/stock` endpoint: - - ```shell - curl http://stock-service-example.default.1.2.3.4.xip.io/stock - ``` - - Response body: `stock ticker not found!, require /stock/{ticker}` - - 3. Send a request to the `/stock` endpoint with your - "[stock symbol](https://www.marketwatch.com/tools/quotes/lookup.asp)": - - ```shell - curl http://stock-service-example.default.1.2.3.4.xip.io/stock/ - ``` - - where `` is your "stock symbol". - - Response body: `stock price for ticker is ` - - **Example** - - Request: - - ```shell - curl http://stock-service-example.default.1.2.3.4.xip.io/stock/FAKE - ``` - - Response: `stock price for ticker FAKE is 0.00` - -## Next Steps - -The [traffic splitting example](../traffic-splitting/README.md) continues from -here to walk you through how to create new Revisions and then use traffic -splitting between those Revisions. - -## Clean Up - -To clean up the sample Service: - -```shell -kubectl delete --filename docs/serving/samples/rest-api-go/sample.yaml -``` diff --git a/docs/serving/samples/rest-api-go/index.md b/docs/serving/samples/rest-api-go/index.md index f9e69b79e..03565786a 100644 --- a/docs/serving/samples/rest-api-go/index.md +++ b/docs/serving/samples/rest-api-go/index.md @@ -5,4 +5,211 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +This "stock ticker" sample demonstrates how to create and run a simple RESTful +service on Knative Serving. The exposed endpoint outputs the stock price for a +given "[stock symbol](https://www.marketwatch.com/tools/quotes/lookup.asp)", +like `AAPL`,`AMZN`, `GOOG`, `MSFT`, etc. + +## Prerequisites + +1. A Kubernetes cluster with [Knative Serving](../../../install/README.md) installed + and DNS configured. +1. [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment) + installed locally. +1. `envsubst` installed locally. This is installed by the `gettext` package. If + not installed it can be installed by a Linux package manager, or by + [Homebrew](https://brew.sh/) on OS X. +1. Download a copy of the code: + + ```shell + git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs + cd knative-docs + ``` + +## Setup + +In order to run an application on Knative Serving a container image must be +available to fetch from a container registry. + +This sample uses Docker for both building and pushing. + +To build and push to a container registry using Docker: + +1. From the `knative-docs` directory, run the following command to set your + container registry endpoint as an environment variable. + + This sample uses + [Google Container Registry (GCR)](https://cloud.google.com/container-registry/): + + ```shell + export REPO="gcr.io/" + ``` + +1. Set up your container registry to make sure you are ready to push. + + To push to GCR, you need to: + + - Create a + [Google Cloud Platform project](https://cloud.google.com/resource-manager/docs/creating-managing-projects#creating_a_project). + - Enable the + [Google Container Registry API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). + - Setup an + [auth helper](https://cloud.google.com/container-registry/docs/advanced-authentication#gcloud_as_a_docker_credential_helper) + to give the Docker client the permissions it needs to push. + + If you are using a different container registry, you will want to follow the + registry specific instructions for both setup and authorizing the image push. + +1. Use Docker to build your application container: + + ```shell + docker build \ + --tag "${REPO}/rest-api-go" \ + --file docs/serving/samples/rest-api-go/Dockerfile . + ``` + +1. Push your container to a container registry: + + ```shell + docker push "${REPO}/rest-api-go" + ``` + +1. Substitute the image reference path in the template with our published image + path. The command below substitutes using the \${REPO} variable into a new + file called `docs/serving/samples/rest-api-go/sample.yaml`. + + ```shell + envsubst < docs/serving/samples/rest-api-go/sample-template.yaml > \ + docs/serving/samples/rest-api-go/sample.yaml + ``` + +## Deploy the Service + +Now that our image is available from the container registry, we can deploy the +Knative Serving sample: + +```shell +kubectl apply --filename docs/serving/samples/rest-api-go/sample.yaml +``` + +The above command creates a Knative Service within your Kubernetes cluster in +the default namespace. + +## Explore the Service + +The Knative Service creates the following child resources: + +- Knative Route +- Knative Configuration +- Knative Revision +- Kubernetes Deployment +- Kubernetes Service + +You can inspect the created resources with the following `kubectl` commands: + +- View the created Service resource: + + ```shell + kubectl get ksvc stock-service-example --output yaml + ``` + +- View the created Route resource: + + ```shell + kubectl get route -l \ + "serving.knative.dev/service=stock-service-example" --output yaml + ``` + +- View the Kubernetes Service created by the Route + + ```shell + kubectl get service -l \ + "serving.knative.dev/service=stock-service-example" --output yaml + ``` + +- View the created Configuration resource: + + ```shell + kubectl get configuration -l \ + "serving.knative.dev/service=stock-service-example" --output yaml + ``` + +- View the Revision that was created by our Configuration: + + ```shell + kubectl get revision -l \ + "serving.knative.dev/service=stock-service-example" --output yaml + ``` + +- View the Deployment created by our Revision + + ```shell + kubectl get deployment -l \ + "serving.knative.dev/service=stock-service-example" --output yaml + ``` + +## Access the Service + +To access this service and run the stock ticker, you first obtain the service URL, +and then you run `curl` commands to send request with your stock symbol. + +1. Get the URL of the service: + + ```shell + kubectl get ksvc stock-service-example --output=custom-columns=NAME:.metadata.name,URL:.status.url + NAME URL + stock-service-example http://stock-service-example.default.1.2.3.4.xip.io + ``` + +2. Send requests to the service using `curl`: + + 1. Send a request to the index endpoint: + + ```shell + curl http://stock-service-example.default.1.2.3.4.xip.io + ``` + + Response body: `Welcome to the stock app!` + + 2. Send a request to the `/stock` endpoint: + + ```shell + curl http://stock-service-example.default.1.2.3.4.xip.io/stock + ``` + + Response body: `stock ticker not found!, require /stock/{ticker}` + + 3. Send a request to the `/stock` endpoint with your + "[stock symbol](https://www.marketwatch.com/tools/quotes/lookup.asp)": + + ```shell + curl http://stock-service-example.default.1.2.3.4.xip.io/stock/ + ``` + + where `` is your "stock symbol". + + Response body: `stock price for ticker is ` + + **Example** + + Request: + + ```shell + curl http://stock-service-example.default.1.2.3.4.xip.io/stock/FAKE + ``` + + Response: `stock price for ticker FAKE is 0.00` + +## Next Steps + +The [traffic splitting example](../traffic-splitting/README.md) continues from +here to walk you through how to create new Revisions and then use traffic +splitting between those Revisions. + +## Clean Up + +To clean up the sample Service: + +```shell +kubectl delete --filename docs/serving/samples/rest-api-go/sample.yaml +``` diff --git a/docs/serving/samples/secrets-go/README.md b/docs/serving/samples/secrets-go/README.md deleted file mode 100644 index 023fea383..000000000 --- a/docs/serving/samples/secrets-go/README.md +++ /dev/null @@ -1,253 +0,0 @@ -A simple web app written in Go that you can use for testing. It demonstrates how -to use a Kubernetes secret as a Volume with Knative. We will create a new Google -Service Account and place it into a Kubernetes secret, then we will mount it -into a container as a Volume. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/secrets-go -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed. Follow the - [installation instructions](../../../install/README.md) if you need to create - one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). -- Create a - [Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects) - and install the `gcloud` CLI and run `gcloud auth login`. This sample will use - a mix of `gcloud` and `kubectl` commands. The rest of the sample assumes that - you've set the `$PROJECT_ID` environment variable to your Google Cloud project - id, and also set your project ID as default using - `gcloud config set project $PROJECT_ID`. - -## Recreating the sample code - -1. Create a new file named `secrets.go` and paste the following code. This code - creates a basic web server which listens on port 8080: - - ```go - package main - - import ( - "context" - "fmt" - "log" - "net/http" - "os" - - "cloud.google.com/go/storage" - ) - - func main() { - log.Print("Secrets sample started.") - - // This sets up the standard GCS storage client, which will pull - // credentials from GOOGLE_APPLICATION_CREDENTIALS if specified. - ctx := context.Background() - client, err := storage.NewClient(ctx) - if err != nil { - log.Fatalf("Unable to initialize storage client: %v", err) - } - - http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { - // This GCS bucket has been configured so that any authenticated - // user can access it (Read Only), so any Service Account can - // run this sample. - bkt := client.Bucket("knative-secrets-sample") - - // Access the attributes of this GCS bucket, and write it back to the - // user. On failure, return a 500 and the error message. - attrs, err := bkt.Attrs(ctx) - if err != nil { - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } - fmt.Fprintln(w, - fmt.Sprintf("bucket %s, created at %s, is located in %s with storage class %s\n", - attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass)) - - }) - - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } - - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) - } - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. For detailed instructions on dockerizing a Go app, see - [Deploying Go servers with Docker](https://blog.golang.org/docker). - - ```docker - # Use the official Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - # https://hub.docker.com/_/golang - FROM golang as builder - - # Copy local code to the container image. - WORKDIR /go/src/github.com/knative/docs/hellosecrets - COPY . . - - # Build the output command inside the container. - RUN CGO_ENABLED=0 GOOS=linux go build -v -o hellosecrets - - # Use a Docker multi-stage build to create a lean production image. - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM alpine - - # Enable the use of outbound https - RUN apk add --no-cache ca-certificates - - # Copy the binary to the production image from the builder stage. - COPY --from=builder /go/src/github.com/knative/docs/hellosecrets/hellosecrets /hellosecrets - - # Service must listen to $PORT environment variable. - # This default value facilitates local development. - ENV PORT 8080 - - # Run the web service on container startup. - CMD ["/hellosecrets"] - ``` - -1. [Create a new Google Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts). - This Service Account doesn't need any privileges, the GCS bucket has been - configured so that any authenticated identity may read it. - - ```shell - gcloud iam service-accounts create knative-secrets - ``` - -1. Create a new JSON key for this account - - ```shell - gcloud iam service-accounts keys create robot.json \ - --iam-account=knative-secrets@$PROJECT_ID.iam.gserviceaccount.com - ``` - -1. Create a new Kubernetes secret from this JSON key: - - ```shell - kubectl create secret generic google-robot-secret --from-file=./robot.json - ``` - - You can achieve a similar result by editting `secret.yaml`, copying the - contents of `robot.json` as instructed there, and running - `kubectl apply --filename secret.yaml`. - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: secrets-go - namespace: default - spec: - template: - spec: - containers: - # Replace {username} with your DockerHub username - - image: docker.io/{username}/secrets-go - - env: - # This directs the Google Cloud SDK to use the identity and project - # defined by the Service Account (aka robot) in the JSON file at - # this path. - # - `/var/secret` is determined by the `volumeMounts[0].mountPath` - # below. This can be changed if both places are changed. - # - `robot.json` is determined by the "key" that is used to hold the - # secret content in the Kubernetes secret. This can be changed - # if both places are changed. - - name: GOOGLE_APPLICATION_CREDENTIALS - value: /var/secret/robot.json - - # This section specified where in the container we want the - # volume containing our secret to be mounted. - volumeMounts: - - name: robot-secret - mountPath: /var/secret - - # This section attaches the secret "google-robot-secret" to - # the Pod holding the user container. - volumes: - - name: robot-secret - secret: - secretName: google-robot-secret - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/secrets-go . - - # Push the container to docker registry - docker push {username}/secrets-go - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - Create a new immutable revision for this version of the app. - - Network programming to create a route, ingress, service, and load balance - for your app. - - Automatically scale your pods up and down (including to zero active pods). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc secrets-go --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - secrets-go http://secrets-go.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://secrets-go.default.1.2.3.4.xip.io - bucket knative-secrets-sample, created at 2019-02-01 14:44:05.804 +0000 UTC, is located in US with storage class MULTI_REGIONAL - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -kubectl delete secret google-robot-secret -``` diff --git a/docs/serving/samples/secrets-go/index.md b/docs/serving/samples/secrets-go/index.md index 21c186b13..1b7f255a0 100644 --- a/docs/serving/samples/secrets-go/index.md +++ b/docs/serving/samples/secrets-go/index.md @@ -5,4 +5,256 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +A simple web app written in Go that you can use for testing. It demonstrates how +to use a Kubernetes secret as a Volume with Knative. We will create a new Google +Service Account and place it into a Kubernetes secret, then we will mount it +into a container as a Volume. + +Follow the steps below to create the sample code and then deploy the app to your +cluster. You can also download a working copy of the sample, by running the +following commands: + +```shell +git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs +cd knative-docs/docs/serving/samples/secrets-go +``` + +## Before you begin + +- A Kubernetes cluster with Knative installed. Follow the + [installation instructions](../../../install/README.md) if you need to create + one. +- [Docker](https://www.docker.com) installed and running on your local machine, + and a Docker Hub account configured (we'll use it for a container registry). +- Create a + [Google Cloud project](https://cloud.google.com/resource-manager/docs/creating-managing-projects) + and install the `gcloud` CLI and run `gcloud auth login`. This sample will use + a mix of `gcloud` and `kubectl` commands. The rest of the sample assumes that + you've set the `$PROJECT_ID` environment variable to your Google Cloud project + id, and also set your project ID as default using + `gcloud config set project $PROJECT_ID`. + +## Recreating the sample code + +1. Create a new file named `secrets.go` and paste the following code. This code + creates a basic web server which listens on port 8080: + + ```go + package main + + import ( + "context" + "fmt" + "log" + "net/http" + "os" + + "cloud.google.com/go/storage" + ) + + func main() { + log.Print("Secrets sample started.") + + // This sets up the standard GCS storage client, which will pull + // credentials from GOOGLE_APPLICATION_CREDENTIALS if specified. + ctx := context.Background() + client, err := storage.NewClient(ctx) + if err != nil { + log.Fatalf("Unable to initialize storage client: %v", err) + } + + http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { + // This GCS bucket has been configured so that any authenticated + // user can access it (Read Only), so any Service Account can + // run this sample. + bkt := client.Bucket("knative-secrets-sample") + + // Access the attributes of this GCS bucket, and write it back to the + // user. On failure, return a 500 and the error message. + attrs, err := bkt.Attrs(ctx) + if err != nil { + http.Error(w, err.Error(), http.StatusInternalServerError) + return + } + fmt.Fprintln(w, + fmt.Sprintf("bucket %s, created at %s, is located in %s with storage class %s\n", + attrs.Name, attrs.Created, attrs.Location, attrs.StorageClass)) + + }) + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) + } + ``` + +1. In your project directory, create a file named `Dockerfile` and copy the code + block below into it. For detailed instructions on dockerizing a Go app, see + [Deploying Go servers with Docker](https://blog.golang.org/docker). + + ```docker + # Use the official Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + # https://hub.docker.com/_/golang + FROM golang as builder + + # Copy local code to the container image. + WORKDIR /go/src/github.com/knative/docs/hellosecrets + COPY . . + + # Build the output command inside the container. + RUN CGO_ENABLED=0 GOOS=linux go build -v -o hellosecrets + + # Use a Docker multi-stage build to create a lean production image. + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM alpine + + # Enable the use of outbound https + RUN apk add --no-cache ca-certificates + + # Copy the binary to the production image from the builder stage. + COPY --from=builder /go/src/github.com/knative/docs/hellosecrets/hellosecrets /hellosecrets + + # Service must listen to $PORT environment variable. + # This default value facilitates local development. + ENV PORT 8080 + + # Run the web service on container startup. + CMD ["/hellosecrets"] + ``` + +1. [Create a new Google Service Account](https://cloud.google.com/iam/docs/creating-managing-service-accounts). + This Service Account doesn't need any privileges, the GCS bucket has been + configured so that any authenticated identity may read it. + + ```shell + gcloud iam service-accounts create knative-secrets + ``` + +1. Create a new JSON key for this account + + ```shell + gcloud iam service-accounts keys create robot.json \ + --iam-account=knative-secrets@$PROJECT_ID.iam.gserviceaccount.com + ``` + +1. Create a new Kubernetes secret from this JSON key: + + ```shell + kubectl create secret generic google-robot-secret --from-file=./robot.json + ``` + + You can achieve a similar result by editting `secret.yaml`, copying the + contents of `robot.json` as instructed there, and running + `kubectl apply --filename secret.yaml`. + +1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: secrets-go + namespace: default + spec: + template: + spec: + containers: + # Replace {username} with your DockerHub username + - image: docker.io/{username}/secrets-go + + env: + # This directs the Google Cloud SDK to use the identity and project + # defined by the Service Account (aka robot) in the JSON file at + # this path. + # - `/var/secret` is determined by the `volumeMounts[0].mountPath` + # below. This can be changed if both places are changed. + # - `robot.json` is determined by the "key" that is used to hold the + # secret content in the Kubernetes secret. This can be changed + # if both places are changed. + - name: GOOGLE_APPLICATION_CREDENTIALS + value: /var/secret/robot.json + + # This section specified where in the container we want the + # volume containing our secret to be mounted. + volumeMounts: + - name: robot-secret + mountPath: /var/secret + + # This section attaches the secret "google-robot-secret" to + # the Pod holding the user container. + volumes: + - name: robot-secret + secret: + secretName: google-robot-secret + ``` + +## Building and deploying the sample + +Once you have recreated the sample code files (or used the files in the sample +folder) you're ready to build and deploy the sample app. + +1. Use Docker to build the sample code into a container. To build and push with + Docker Hub, run these commands replacing `{username}` with your Docker Hub + username: + + ```shell + # Build the container on your local machine + docker build -t {username}/secrets-go . + + # Push the container to docker registry + docker push {username}/secrets-go + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Ensure that the container image value + in `service.yaml` matches the container you built in the previous step. Apply + the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + +1. Now that your service is created, Knative will perform the following steps: + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balance + for your app. + - Automatically scale your pods up and down (including to zero active pods). + +1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc secrets-go --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + secrets-go http://secrets-go.default.1.2.3.4.xip.io + ``` + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://secrets-go.default.1.2.3.4.xip.io + bucket knative-secrets-sample, created at 2019-02-01 14:44:05.804 +0000 UTC, is located in US with storage class MULTI_REGIONAL + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing the sample app deployment + +To remove the sample app from your cluster, delete the service record: + +```shell +kubectl delete --filename service.yaml +kubectl delete secret google-robot-secret +``` diff --git a/docs/serving/samples/tag-header-based-routing/README.md b/docs/serving/samples/tag-header-based-routing/README.md deleted file mode 100644 index 769d779ac..000000000 --- a/docs/serving/samples/tag-header-based-routing/README.md +++ /dev/null @@ -1,118 +0,0 @@ -This sample explains the use of tag header based routing. - -## Tag Header Based Routing Feature - -Tag header based routing allows users to send requests directly to specific tagged revisions with -the same URL of Knative Service. To do this, you must set the specific header `Knative-Serving-Tag: -{revision-tag}` in the request. - -Currently Istio, Contour and Kourier ingress support this feature. - -## Prerequestie - -1. A Knative cluster that has an ingress controller installed -with Knative version 0.16 and above. - -1. Move into the docs directory: - -```shell -cd $GOPATH/src/github.com/knative/docs -``` - -## Enabling tag header based routing - -This feature is disabled by default. To enable this feature, run the following command: - -``` -kubectl patch cm config-features -n knative-serving -p '{"data":{"tag-header-based-routing":"Enabled"}}' -``` - -## Build images - -Follow the instructions in [helloworld-go](../hello-world/helloworld-go) to build the `helloworld` image and upload it -to your container repository. - -Replace `{username}` in the [sample.yaml](./sample.yaml) with your Docker Hub username. - -## Setting up the revisions with tag - -In this sample, two Revisions are created. The first Revision is tagged with `rev1`. -With this configuration, users can send requests directly to the first Revision -using the URL of Knative Service plus the header `Knative-Serving-Tag: rev1`. - -The Knative Service is configured to route all of the traffic to the second Revision, which means if users do not -provide the `Knative-Serving-Tag` or they provide an incorrect value for `Knative-Serving-Tag`, the requests will be -routed to the second Revision. - -Run the following command to set up the Knative Service and Revisions. - -``` -kubectl apply -f docs/serving/samples/tag-header-based-routing/sample.yaml -``` - -## Check the created resources - -Check the two created Revisions using the following command -``` -kubectl get revisions -``` - -You should see there are two Revisions: `tag-header-revision-1` and `tag-header-revision-2`. It may take a few minutes -for the Revisions to become ready. - - -Check the Knative Service using the following command - -``` -kubectl get ksvc tag-header -oyaml -``` - -You should see the following block which indicates the tag `rev1` is successfully added to the first Revision. - -``` - - revisionName: tag-header-revision-1 - percent: 0 - tag: rev1 - - revisionName: tag-header-revision-2 - percent: 100 -``` - - -## Sending request with tag header - -1. Run the following command to send a request to the first Revision. - - ``` - curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" -H "Knative-Serving-Tag:rev1" - ``` - where `${INGRESS_IP}` is the IP of your ingress. - - You should get the following response: - - ``` - Hello First Revision! - ``` - -1. Run the following command to send requests without the `Knative-Serving-Tag` header: - - ``` - curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" - ``` - - You should get the response from the second Revision: - - ``` - Hello Second Revision! - ``` - -1. Run the following command to send requests with an incorrect `Knative-Serving-Tag` header: - - ``` - curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" -H "Knative-Serving-Tag:wrongHeader" - ``` - - You should get the response from the second Revision: - - ``` - Hello Second Revision! - ``` diff --git a/docs/serving/samples/tag-header-based-routing/index.md b/docs/serving/samples/tag-header-based-routing/index.md index 3747a8b4e..993962368 100644 --- a/docs/serving/samples/tag-header-based-routing/index.md +++ b/docs/serving/samples/tag-header-based-routing/index.md @@ -4,4 +4,121 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +This sample explains the use of tag header based routing. + +## Tag Header Based Routing Feature + +Tag header based routing allows users to send requests directly to specific tagged revisions with +the same URL of Knative Service. To do this, you must set the specific header `Knative-Serving-Tag: +{revision-tag}` in the request. + +Currently Istio, Contour and Kourier ingress support this feature. + +## Prerequestie + +1. A Knative cluster that has an ingress controller installed +with Knative version 0.16 and above. + +1. Move into the docs directory: + +```shell +cd $GOPATH/src/github.com/knative/docs +``` + +## Enabling tag header based routing + +This feature is disabled by default. To enable this feature, run the following command: + +``` +kubectl patch cm config-features -n knative-serving -p '{"data":{"tag-header-based-routing":"Enabled"}}' +``` + +## Build images + +Follow the instructions in [helloworld-go](../hello-world/helloworld-go) to build the `helloworld` image and upload it +to your container repository. + +Replace `{username}` in the [sample.yaml](./sample.yaml) with your Docker Hub username. + +## Setting up the revisions with tag + +In this sample, two Revisions are created. The first Revision is tagged with `rev1`. +With this configuration, users can send requests directly to the first Revision +using the URL of Knative Service plus the header `Knative-Serving-Tag: rev1`. + +The Knative Service is configured to route all of the traffic to the second Revision, which means if users do not +provide the `Knative-Serving-Tag` or they provide an incorrect value for `Knative-Serving-Tag`, the requests will be +routed to the second Revision. + +Run the following command to set up the Knative Service and Revisions. + +``` +kubectl apply -f docs/serving/samples/tag-header-based-routing/sample.yaml +``` + +## Check the created resources + +Check the two created Revisions using the following command +``` +kubectl get revisions +``` + +You should see there are two Revisions: `tag-header-revision-1` and `tag-header-revision-2`. It may take a few minutes +for the Revisions to become ready. + + +Check the Knative Service using the following command + +``` +kubectl get ksvc tag-header -oyaml +``` + +You should see the following block which indicates the tag `rev1` is successfully added to the first Revision. + +``` + - revisionName: tag-header-revision-1 + percent: 0 + tag: rev1 + - revisionName: tag-header-revision-2 + percent: 100 +``` + + +## Sending request with tag header + +1. Run the following command to send a request to the first Revision. + + ``` + curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" -H "Knative-Serving-Tag:rev1" + ``` + where `${INGRESS_IP}` is the IP of your ingress. + + You should get the following response: + + ``` + Hello First Revision! + ``` + +1. Run the following command to send requests without the `Knative-Serving-Tag` header: + + ``` + curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" + ``` + + You should get the response from the second Revision: + + ``` + Hello Second Revision! + ``` + +1. Run the following command to send requests with an incorrect `Knative-Serving-Tag` header: + + ``` + curl ${INGRESS_IP} -H "Host:tag-header.default.example.com" -H "Knative-Serving-Tag:wrongHeader" + ``` + + You should get the response from the second Revision: + + ``` + Hello Second Revision! + ``` diff --git a/docs/serving/samples/traffic-splitting/README.md b/docs/serving/samples/traffic-splitting/README.md deleted file mode 100644 index 394436533..000000000 --- a/docs/serving/samples/traffic-splitting/README.md +++ /dev/null @@ -1,154 +0,0 @@ -This samples builds off of the [Creating a RESTful Service](../rest-api-go) -sample to illustrate updating a Service to create a new Revision as well as -splitting traffic between the two created Revisions. - -## Prerequisites - -1. Complete the Service creation steps in - [Creating a RESTful Service](../rest-api-go). -1. Move into the docs directory: - -```shell -cd $GOPATH/src/github.com/knative/docs -``` - -## Using the `traffic:` block - -The service was originally created without a `traffic:` block, which means that -it will automatically deploy the latest updates as they become ready. To split -traffic between multiple Revisions, we will start to use a customized `traffic:` -block. The `traffic:` block enables users to split traffic over any number of -fixed Revisions, or the floating "latest revision" for the Service. It also -enables users to name the specific sub-routes, so that they can be directly -addressed for qualification or debugging. - -The first thing we will do is look at the traffic block that was defaulted for -us in the previous sample: - -1. Fetch the state of the Service, and note the `traffic:` block that will run - the latest ready revision, each time we update our template. Also note that - under `status:` we see a specific `revisionName:` here, which is what it has - resolved to (in this case the name we asked for). - -```shell -$ kubectl get ksvc -oyaml stock-service-example -apiVersion: serving.knative.dev/v1 -kind: Service -metadata: - name: stock-service-example - ... -spec: - template: ... # A defaulted version of what we provided. - - traffic: - - latestRevision: true - percent: 100 - -status: - ... - traffic: - - percent: 100 - revisionName: stock-service-example-first -``` - -1. The `release_sample.yaml` in this directory overwrites the defaulted traffic - block with a block that fixes traffic to the revision - `stock-service-example-first`, while keeping the latest ready revision - available via the sub-route "latest". - -```shell -kubectl apply --filename docs/serving/samples/traffic-splitting/release_sample.yaml -``` - -1. The `spec` of the Service should now show our `traffic` block with the - Revision name we specified above. - -```shell -kubectl get ksvc stock-service-example --output yaml -``` - -## Updating the Service - -This section describes how to create a new Revision by updating your Service. - -A new Revision is created every time a value in the `template` section of the -Service `spec` is updated. The `updated_sample.yaml` in this folder changes the -environment variable `RESOURCE` from `stock` to `share`. Applying this change -will result in a new Revision. - -For comparison, you can diff the `release_sample.yaml` with the -`updated_sample.yaml`. - -```shell -diff serving/samples/traffic-splitting/release_sample.yaml \ -serving/samples/traffic-splitting/updated_sample.yaml -``` - -1. Execute the command below to update Service, resulting in a new Revision. - -```shell -kubectl apply --filename docs/serving/samples/traffic-splitting/updated_sample.yaml -``` - -2. With our `traffic` block, traffic will _not_ shift to the new Revision - automatically. However, it will be available via the URL associated with our - `latest` sub-route. This can be verified through the Service status, by - finding the entry of `status.traffic` for `latest`: - -```shell -kubectl get ksvc stock-service-example --output yaml -``` - -3. The readiness of the Service can be verified through the Service Conditions. - When the Service conditions report it is ready again, you can access the new - Revision using the same method as found in the - [previous sample](../rest-api-go/README.md#access-the-service) using the - Service hostname found above. - -```shell -# Replace "latest" with whichever tag for which we want the hostname. -export LATEST_HOSTNAME=`kubectl get ksvc stock-service-example --output jsonpath="{.status.traffic[?(@.tag=='latest')].url}" | cut -d'/' -f 3` -curl --header "Host: ${LATEST_HOSTNAME}" http://${INGRESS_IP} -``` - -- Visiting the Service's domain will still hit the original Revision, since we - configured it to receive 100% of our main traffic (you can also use the - `current` sub-route). - -```shell -curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP} -``` - -## Traffic Splitting - -Updating the service to split traffic between the two revisions is done by -extending our `traffic` list, and splitting the `percent` across them. - -1. Execute the command below to update Service, resulting in a 50/50 traffic - split. - -```shell -kubectl apply --filename docs/serving/samples/traffic-splitting/split_sample.yaml -``` - -2. Verify the deployment by checking the service status: - -```shell -kubectl get ksvc --output yaml -``` - -3. Once updated, `curl` requests to the base domain should result in responses - split evenly between `Welcome to the share app!` and - `Welcome to the stock app!`. - -```shell -curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP} -``` - -## Clean Up - -To clean up the sample service: - -```shell -kubectl delete --filename docs/serving/samples/traffic-splitting/split_sample.yaml -``` diff --git a/docs/serving/samples/traffic-splitting/index.md b/docs/serving/samples/traffic-splitting/index.md index a3d7e7e7b..e9fa78772 100644 --- a/docs/serving/samples/traffic-splitting/index.md +++ b/docs/serving/samples/traffic-splitting/index.md @@ -5,4 +5,157 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +This samples builds off of the [Creating a RESTful Service](../rest-api-go) +sample to illustrate updating a Service to create a new Revision as well as +splitting traffic between the two created Revisions. + +## Prerequisites + +1. Complete the Service creation steps in + [Creating a RESTful Service](../rest-api-go). +1. Move into the docs directory: + +```shell +cd $GOPATH/src/github.com/knative/docs +``` + +## Using the `traffic:` block + +The service was originally created without a `traffic:` block, which means that +it will automatically deploy the latest updates as they become ready. To split +traffic between multiple Revisions, we will start to use a customized `traffic:` +block. The `traffic:` block enables users to split traffic over any number of +fixed Revisions, or the floating "latest revision" for the Service. It also +enables users to name the specific sub-routes, so that they can be directly +addressed for qualification or debugging. + +The first thing we will do is look at the traffic block that was defaulted for +us in the previous sample: + +1. Fetch the state of the Service, and note the `traffic:` block that will run + the latest ready revision, each time we update our template. Also note that + under `status:` we see a specific `revisionName:` here, which is what it has + resolved to (in this case the name we asked for). + +```shell +$ kubectl get ksvc -oyaml stock-service-example +apiVersion: serving.knative.dev/v1 +kind: Service +metadata: + name: stock-service-example + ... +spec: + template: ... # A defaulted version of what we provided. + + traffic: + - latestRevision: true + percent: 100 + +status: + ... + traffic: + - percent: 100 + revisionName: stock-service-example-first +``` + +1. The `release_sample.yaml` in this directory overwrites the defaulted traffic + block with a block that fixes traffic to the revision + `stock-service-example-first`, while keeping the latest ready revision + available via the sub-route "latest". + +```shell +kubectl apply --filename docs/serving/samples/traffic-splitting/release_sample.yaml +``` + +1. The `spec` of the Service should now show our `traffic` block with the + Revision name we specified above. + +```shell +kubectl get ksvc stock-service-example --output yaml +``` + +## Updating the Service + +This section describes how to create a new Revision by updating your Service. + +A new Revision is created every time a value in the `template` section of the +Service `spec` is updated. The `updated_sample.yaml` in this folder changes the +environment variable `RESOURCE` from `stock` to `share`. Applying this change +will result in a new Revision. + +For comparison, you can diff the `release_sample.yaml` with the +`updated_sample.yaml`. + +```shell +diff serving/samples/traffic-splitting/release_sample.yaml \ +serving/samples/traffic-splitting/updated_sample.yaml +``` + +1. Execute the command below to update Service, resulting in a new Revision. + +```shell +kubectl apply --filename docs/serving/samples/traffic-splitting/updated_sample.yaml +``` + +2. With our `traffic` block, traffic will _not_ shift to the new Revision + automatically. However, it will be available via the URL associated with our + `latest` sub-route. This can be verified through the Service status, by + finding the entry of `status.traffic` for `latest`: + +```shell +kubectl get ksvc stock-service-example --output yaml +``` + +3. The readiness of the Service can be verified through the Service Conditions. + When the Service conditions report it is ready again, you can access the new + Revision using the same method as found in the + [previous sample](../rest-api-go/README.md#access-the-service) using the + Service hostname found above. + +```shell +# Replace "latest" with whichever tag for which we want the hostname. +export LATEST_HOSTNAME=`kubectl get ksvc stock-service-example --output jsonpath="{.status.traffic[?(@.tag=='latest')].url}" | cut -d'/' -f 3` +curl --header "Host: ${LATEST_HOSTNAME}" http://${INGRESS_IP} +``` + +- Visiting the Service's domain will still hit the original Revision, since we + configured it to receive 100% of our main traffic (you can also use the + `current` sub-route). + +```shell +curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP} +``` + +## Traffic Splitting + +Updating the service to split traffic between the two revisions is done by +extending our `traffic` list, and splitting the `percent` across them. + +1. Execute the command below to update Service, resulting in a 50/50 traffic + split. + +```shell +kubectl apply --filename docs/serving/samples/traffic-splitting/split_sample.yaml +``` + +2. Verify the deployment by checking the service status: + +```shell +kubectl get ksvc --output yaml +``` + +3. Once updated, `curl` requests to the base domain should result in responses + split evenly between `Welcome to the share app!` and + `Welcome to the stock app!`. + +```shell +curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP} +``` + +## Clean Up + +To clean up the sample service: + +```shell +kubectl delete --filename docs/serving/samples/traffic-splitting/split_sample.yaml +```