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",
like AAPL
,AMZN
, GOOG
, MSFT
, etc.
-
A Kubernetes cluster with Knative Serving v0.3 or higher installed.
-
Docker installed locally.
-
Outbound network access enabled for this Service to make external API requests.
-
envsubst
installed locally. This is installed by thegettext
package. If not installed it can be installed by a Linux package manager, or by Homebrew on OS X. -
Download a copy of the code:
git clone -b "release-0.7" https://github.com/knative/docs knative-docs cd knative-docs/serving/samples/rest-api-go
In order to run an application on Knative Serving a container image must be available to fetch from a container registry. Building and pushing a container image can be accomplished locally using Docker or ko as well as remotely using Knative Build.
This sample uses Docker for both building and pushing.
To build and push to a container registry using Docker:
-
Move into the sample directory:
cd $GOPATH/src/github.com/knative/docs
-
Set your preferred container registry endpoint as an environment variable. This sample uses Google Container Registry (GCR):
export REPO="gcr.io/<YOUR_PROJECT_ID>"
-
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.
- Enable the Google Container Registry API.
- Setup an auth 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.
-
Use Docker to build your application container:
docker build \ --tag "${REPO}/rest-api-go" \ --file docs/serving/samples/rest-api-go/Dockerfile .
-
Push your container to a container registry:
docker push "${REPO}/rest-api-go"
-
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
.envsubst < docs/serving/samples/rest-api-go/sample-template.yaml > \ docs/serving/samples/rest-api-go/sample.yaml
Now that our image is available from the container registry, we can deploy the Knative Serving sample:
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.
The Knative Service creates the following child resources:
- Knative Route
- Knative Configuration
- Knative Revision
- Kubernetes Deployment
- Kuberentes Service
You can inspect the created resources with the following kubectl
commands:
-
View the created Service resource:
kubectl get ksvc stock-service-example --output yaml
-
View the created Route resource:
kubectl get route -l \ "serving.knative.dev/service=stock-service-example" --output yaml
-
View the Kubernetes Service created by the Route
kubectl get service -l \ "serving.knative.dev/service=stock-service-example" --output yaml
-
View the created Configuration resource:
kubectl get configuration -l \ "serving.knative.dev/service=stock-service-example" --output yaml
-
View the Revision that was created by our Configuration:
kubectl get revision -l \ "serving.knative.dev/service=stock-service-example" --output yaml
-
View the Deployment created by our Revision
kubectl get deployment -l \ "serving.knative.dev/service=stock-service-example" --output yaml
To access this service and run the stock ticker, you first obtain the ingress
address and service hostname, and then you run curl
commands to send request
with your stock symbol.
Note: This sample assumes that you are using Knative's default Ingress Gateway. If you customized your gateway, you need to adjust the enviornment variables in the following steps.
-
Find the IP address of the ingress gateway:
-
Cloud Provider: To get the IP address of your ingress gateway:
INGRESSGATEWAY=istio-ingressgateway INGRESSGATEWAY_LABEL=istio export INGRESS_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \ --output jsonpath="{.status.loadBalancer.ingress[*].ip}"` echo $INGRESS_IP
-
Minikube: If your cluster is running outside a cloud provider (for example on Minikube), your services will never get an external IP address, and
INGRESS_IP
won't contain a value. In that case, use the IstiohostIP
andnodePort
as the ingress IP:export INGRESS_IP=$(kubectl get po --selector $INGRESSGATEWAY_LABEL=ingressgateway --namespace istio-system \ --output 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc $INGRESSGATEWAY --namespace istio-system \ --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}') echo $INGRESS_IP
-
-
Get the URL of the service:
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.example.com
-
Send requests to the service using
curl
:-
Send a request to the index endpoint:
The
curl
command below makes a request to the Ingress Gateway IP. The Ingress Gateway uses the host header to route the request to the Service. This example passes the host header to skip DNS configuration. If your cluster has DNS configured, you can simply curl the DNS name instead of the ingress gateway IP.curl --header "Host:stock-service-example.default.example.com" http://${INGRESS_IP}
Response body:
Welcome to the stock app!
-
Send a request to the
/stock
endpoint:curl --header "Host:stock-service-example.default.example.com" http://${INGRESS_IP}/stock
Response body:
stock ticker not found!, require /stock/{ticker}
-
Send a request to the
/stock
endpoint with your "stock symbol":curl --header "Host:stock-service-example.default.example.com" http://${INGRESS_IP}/stock/<SYMBOL>
where
<SYMBOL>
is your "stock symbol".Response body:
stock price for ticker <SYMBOL> is <PRICE>
Example
Request:
curl --header "Host:stock-service-example.default.example.com" http://${INGRESS_IP}/stock/FAKE
Response:
stock price for ticker FAKE is 0.00
-
The traffic splitting example continues from here to walk you through how to create new Revisions and then use traffic splitting between those Revisions.
To clean up the sample Service:
kubectl delete --filename docs/serving/samples/rest-api-go/sample.yaml