Update Serving Rest API example ()

* Update Serving Rest API example

This change updates the sample to use a Knative Service instead of a
Route and Configuration directly.

It also updates the instructions to:
* Add links to relevant external documentation
* Clarify steps and actions occuring in each step
* Use label selectors for querying child resources
* Require Knative 0.3 to simplify instructions

* Add missing backticks

* Updating numbering to use 1.
This commit is contained in:
Dan Gerdesmeier 2019-02-15 17:10:44 -08:00 committed by Knative Prow Robot
parent 8016ad1a48
commit fc28f9071c
2 changed files with 133 additions and 92 deletions
serving/samples/rest-api-go

View File

@ -1,21 +1,16 @@
# Creating a RESTful Service
This sample demonstrates creating a simple RESTful service. The exposed endpoint
takes a stock ticker (i.e. stock symbol), then outputs the stock price. The
endpoint resource name is defined by an environment variable set in the
configuration file.
This sample demonstrates creating and running a simple RESTful service on Knative Serving.
The exposed endpoint takes a stock ticker (i.e. stock symbol), then outputs the stock price.
## Prerequisites
1. A Kubernetes cluster with
[Knative Serving](https://github.com/knative/docs/blob/master/install/README.md)
installed.
2. Install
[Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment).
3. You need to
[configure outbound network access](https://github.com/knative/docs/blob/master/serving/outbound-network-access.md)
because this application makes an external API request.
4. Check out the code:
[Knative Serving](https://github.com/knative/docs/blob/master/install/README.md) v0.3 or higher installed.
1. [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment) installed locally.
1. [Outbound network access](https://github.com/knative/docs/blob/master/serving/outbound-network-access.md) enabled for
this Service to amke external API requests.
1. The code checked out locally.
```
go get -d github.com/knative/docs/serving/samples/rest-api-go
@ -23,7 +18,15 @@ go get -d github.com/knative/docs/serving/samples/rest-api-go
## Setup
Build the application container and publish it to a container registry:
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](https://docs.docker.com/get-started) or
[ko](https://github.com/google/go-containerregistry/tree/master/cmd/ko) as well as
remotely using [Knative Build](https://github.com/knative/docs/tree/master/build).
This sample uses Docker for both building and pushing.
To build and push to a container registry using Docker:
1. Move into the sample directory:
@ -31,17 +34,29 @@ Build the application container and publish it to a container registry:
cd $GOPATH/src/github.com/knative/docs
```
2. Set your preferred container registry:
2. Set your preferred container registry endpoint as an environment variable. This sample uses [Google Container
Registry (GCR)](https://cloud.google.com/container-registry/):
```
export REPO="gcr.io/<YOUR_PROJECT_ID>"
```
To run the sample, you need to have a Google Cloud Platform project, and you
also need to enable the
[Google Container Registry API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com).
3. Set up your container registry to make sure you are ready to push.
3. Use Docker to build your application container:
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.
4. Use Docker to build your application container:
```
docker build \
@ -49,13 +64,13 @@ docker build \
--file serving/samples/rest-api-go/Dockerfile .
```
4. Push your container to a container registry:
5. Push your container to a container registry:
```
docker push "${REPO}/serving/samples/rest-api-go"
```
5. Replace the image reference path with our published image path in the
6. Replace the image reference path with our published image path in the
configuration files (`serving/samples/rest-api-go/sample.yaml`:
- Manually replace:
@ -70,90 +85,117 @@ docker push "${REPO}/serving/samples/rest-api-go"
perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/rest-api-go/sample.yaml
```
## Deploy the Configuration
## Deploy the Service
Deploy the Knative Serving sample:
Now that our image is available from the container registry, we can deploy the Knative Serving sample:
```
kubectl apply --filename serving/samples/rest-api-go/sample.yaml
```
## Explore the Configuration
The above command creates a Knative Service within your Kubernetes cluster in
the default namespace.
Inspect the created resources with the `kubectl` commands:
## Explore the Service
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 -o yaml
```
- View the created Route resource:
```
kubectl get route --output yaml
kubectl get route -l
"serving.knative.dev/service=stock-service-example" -o yaml
```
- View the Kubernetes Service created by the Route
```
kubectl get service -l
"serving.knative.dev/service=stock-service-example" -o yaml
```
- View the created Configuration resource:
```
kubectl get configurations --output yaml
kubectl get configuration -l
"serving.knative.dev/service=stock-service-example" -o yaml
```
- View the Revision that was created by our Configuration:
```
kubectl get revisions --output yaml
kubectl get revision -l
"serving.knative.dev/service=stock-service-example" -o yaml
```
- View the Deployment created by our Revision
```
kubectl get deployment -l
"serving.knative.dev/service=stock-service-example" -o yaml
```
## Access the Service
To access this service via `curl`, you need to determine its ingress address.
This example assumes you are using the default Ingress Gateway setup for Knative. If you
customized your gateway, you will want to adjust the enviornment variables below.
1. To determine if your service is ready:
1. To get the IP address of your Ingress Gateway:
```
# In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`.
INGRESSGATEWAY=knative-ingressgateway
INGRESSGATEWAY_LABEL=knative
INGRESSGATEWAY=istio-ingressgateway
INGRESSGATEWAY_LABEL=istio
# The use of `knative-ingressgateway` is deprecated in Knative v0.3.x.
# Use `istio-ingressgateway` instead, since `knative-ingressgateway`
# will be removed in Knative v0.4.
if kubectl get configmap config-istio -n knative-serving &> /dev/null; then
INGRESSGATEWAY=istio-ingressgateway
INGRESSGATEWAY_LABEL=istio
fi
kubectl get svc $INGRESSGATEWAY --namespace istio-system --watch
```
When the service is ready, you'll see an IP address in the `EXTERNAL-IP` field:
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
xxxxxxx-ingressgateway LoadBalancer 10.23.247.74 35.203.155.229 80:32380/TCP,443:32390/TCP,32400:32400/TCP 2d
```
2. When the service is ready, export the ingress hostname and IP as environment
variables:
```
export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"`
export SERVICE_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \
export INGRESS_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \
--output jsonpath="{.status.loadBalancer.ingress[*].ip}"`
echo $INGRESS_IP
```
- If your cluster is running outside a cloud provider (for example on Minikube),
your services will never get an external IP address. In that case, use the
istio `hostIP` and `nodePort` as the service IP:
your services will never get an external IP address, and your INGRESS_IP will
be empty. In that case, use the istio `hostIP` and `nodePort` as the ingress IP:
```
export SERVICE_IP=$(kubectl get po --selector $INGRESSGATEWAY_LABEL=ingressgateway --namespace istio-system \
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
```
3. Now use `curl` to make a request to the service:
2. To get the hostname of the Service:
```
export SERVICE_HOSTNAME=`kubectl get ksvc stock-service-example --output jsonpath="{.status.domain}"`
echo $SERVICE_HOSTNAME
```
3. Now use `curl` to make a request to the Service:
- Make 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:$SERVICE_HOST" http://${SERVICE_IP}
curl --header "Host:$SERVICE_HOSTNAME" http://${INGRESS_IP}
```
Response body: `Welcome to the stock app!`
@ -161,7 +203,7 @@ Response body: `Welcome to the stock app!`
- Make a request to the `/stock` endpoint:
```
curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock
curl --header "Host:$SERVICE_HOSTNAME" http://${INGRESS_IP}/stock
```
Response body: `stock ticker not found!, require /stock/{ticker}`
@ -169,14 +211,21 @@ Response body: `stock ticker not found!, require /stock/{ticker}`
- Make a request to the `/stock` endpoint with a `ticker` parameter:
```
curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock/<ticker>
curl --header "Host:$SERVICE_HOSTNAME" http://${INGRESS_IP}/stock/<ticker>
```
Response body: `stock price for ticker <ticker> is <price>`
## Next Steps
The [traffic splitting
example](https://github.com/knative/docs/tree/master/serving/samples/traffic-splitting)
continues from here to walk through creating new Revisions and splitting traffic
between multiple Revisions.
## Clean Up
To clean up the sample service:
To clean up the sample Service:
```
kubectl delete --filename serving/samples/rest-api-go/sample.yaml

View File

@ -12,35 +12,27 @@
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: serving.knative.dev/v1alpha1
kind: Configuration
kind: Service
metadata:
name: stock-configuration-example
name: stock-service-example
namespace: default
spec:
revisionTemplate:
metadata:
labels:
knative.dev/type: container
spec:
container:
# This is the Go import path for the binary to containerize
# and substitute here.
image: github.com/knative/docs/serving/samples/rest-api-go
env:
- name: RESOURCE
value: stock
readinessProbe:
httpGet:
path: /
initialDelaySeconds: 3
periodSeconds: 3
---
apiVersion: serving.knative.dev/v1alpha1
kind: Route
metadata:
name: stock-route-example
namespace: default
spec:
traffic:
- configurationName: stock-configuration-example
percent: 100
runLatest:
configuration:
revisionTemplate:
metadata:
labels:
knative.dev/type: container
spec:
container:
# This is the Go import path for the binary to containerize
# and substitute here.
image: github.com/knative/docs/serving/samples/rest-api-go
env:
- name: RESOURCE
value: stock
readinessProbe:
httpGet:
path: /
initialDelaySeconds: 0
periodSeconds: 3