Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,24 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# 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/docs/serving/samples/rest-api-go
env:
- name: RESOURCE
value: share
readinessProbe:
httpGet:
path: /
initialDelaySeconds: 3
periodSeconds: 3
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: ${REPO}/rest-api-go
env:
- name: RESOURCE
value: stock
readinessProbe:
httpGet:
path: /
initialDelaySeconds: 0
periodSeconds: 3

8 changes: 4 additions & 4 deletions docs/serving/samples/rest-api-go/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,10 +177,10 @@ echo $INGRESS_IP

#### Minikube

1. If your cluster is running outside a cloud provider (for example on Minikube),
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:
1. 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 Istio `hostIP`
and `nodePort` as the ingress IP:

```shell
export INGRESS_IP=$(kubectl get po --selector $INGRESSGATEWAY_LABEL=ingressgateway --namespace istio-system \
Expand Down
191 changes: 108 additions & 83 deletions docs/serving/samples/traffic-splitting/README.md
Original file line number Diff line number Diff line change
@@ -1,137 +1,162 @@

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.
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. [Creating a RESTful Service](../rest-api-go).
1. Complete the Service creation steps in [Creating a RESTful Service](../rest-api-go).
1. Move into the docs directory:

## Updating the Service
```shell
cd $GOPATH/src/github.com/knative/docs
```

This section describes how to create an revision by deploying a new
configuration.
## Updating to Release Mode

1. Replace the image reference path with our published image path in the
configuration files
(`docs/serving/samples/traffic-splitting/updated_configuration.yaml`:
The service was originally created with a mode of `runLatest`. In `runLatest`
mode, the service serves the latest Revision that is ready to handle incoming
traffic. To split traffic between multiple Revisions, the Service mode will need
to be changed to `release` mode. The `release` mode differs from `runLatest` in that
it requires a `revisions` list. The `revisions` list accepts 1 or 2 Revisions
that will be served by the base domain of the service. When 2 Revisions are
present in the list a `rolloutPercent` parameter specifies the percentage of
traffic to send to each Revision.

- Manually replace:
`image: github.com/knative/docs/docs/serving/samples/rest-api-go` with
`image: <YOUR_CONTAINER_REGISTRY>/docs/serving/samples/rest-api-go`
This first step will update the Service to release mode with a single Revision.

Or
1. To populate the `revisions` list the name of the created Revision is required.
The command below captures the names of all created Revisions as an array so it
can be substituted it into the YAML.

- Use run this command:
```shell
REVISIONS=($(kubectl get revision -l "serving.knative.dev/service=stock-service-example" -o \
jsonpath="{.items[*].metadata.name}"))
echo ${REVISIONS[*]}
```

```
perl -pi -e "s@github.com/knative/docs@${REPO}@g" docs/serving/samples/rest-api-go/updated_configuration.yaml
```
2. The `release_sample.yaml` is setup in this directory to allow enable substituting the
Revision name into the file with the `envsubst` utility. Executing the
command below will update the Service to release mode with the queried Revision name.

2. Deploy the new configuration to update the `RESOURCE` environment variable
from `stock` to `share`:
- Note: The command below expects `$REPO` to still be exported. See
[RESTful Service Setup](https://github.com/knative/docs/tree/master/serving/samples/rest-api-go#setup) to set it.

```
kubectl apply --filename docs/serving/samples/traffic-splitting/updated_configuration.yaml
```shell
CURRENT=${REVISIONS[0]} \
envsubst < serving/samples/traffic-splitting/release_sample.yaml \
| kubectl apply --filename -
```

3. Once deployed, traffic will shift to the new revision automatically. Verify
the deployment by checking the route status:
3. The `spec` of the Service should now show `release` with the Revision name
retrieved above.

```
kubectl get route --output yaml
```shell
kubectl get ksvc stock-service-example --output yaml
```

4. When the new route is ready, you can access the new endpoints: The hostname
and IP address can be found in the same manner as the
[Creating a RESTful Service](../rest-api-go) sample:
## Updating the Service

```
export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"`
This section describes how to create a new Revision by updating your Service.

# In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`.
INGRESSGATEWAY=knative-ingressgateway
A new Revision is created every time a value in the `revisionTemplate` 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.

# 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
fi
For comparison, you can diff the `release_sample.yaml` with the `updated_sample.yaml`.

export SERVICE_IP=`kubectl get svc $INGRESSGATEWAY --namespace istio-system \
--output jsonpath="{.status.loadBalancer.ingress[*].ip}"`
```shell
diff serving/samples/traffic-splitting/release_sample.yaml \
serving/samples/traffic-splitting/updated_sample.yaml
```

- Make a request to the index endpoint:
1. Execute the command below to update the environment variable in the Service
resulting in a new Revision.

```
curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}
```shell
CURRENT=${REVISIONS[0]} \
envsubst < serving/samples/traffic-splitting/updated_sample.yaml \
| kubectl apply --filename -
```

Response body: `Welcome to the share app!`
2. Since we are using a `release` service, traffic will _not_ shift to the new
Revision automatically. However, it will be available from the subdomain
`latest`. This can be verified through the Service status:

- Make a request to the `/share` endpoint:

```
curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share
```shell
kubectl get ksvc stock-service-example --output yaml
```

Response body: `share ticker not found!, require /share/{ticker}`
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)
by prefixing the Service hostname with `latest.`.

- Make a request to the `/share` endpoint with a `ticker` parameter:

```
curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share/<ticker>
```shell
curl --header "Host:latest.${SERVICE_HOSTNAME}" http://${INGRESS_IP}
```

Response body: `share price for ticker <ticker> is <price>`
- Hitting the top domain (or `current.`) will hit the Revision at the first
index of the `revisions` list:

## Manual Traffic Splitting
```shell
curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP}
curl --header "Host:current.${SERVICE_HOSTNAME}" http://${INGRESS_IP}
```

This section describes how to manually split traffic to specific revisions.
## Traffic Splitting

1. Get your revisions names via:
Updating the service to split traffic between the two revisions is done by
placing a second revision in of the `revisions` list and specifying a `rolloutPercent`.
The `rolloutPercent` is the percentage of traffic to send to the second element in
the list. When the Service is Ready the traffic will be split as desired for the
base domain, and a subdomain of `candidate` will be available pointing to the
second Revision.

```
kubectl get revisions
```
1. Get the latest list of revisions by executing the command below:

```
NAME AGE
stock-configuration-example-00001 11m
stock-configuration-example-00002 4m
```shell
REVISIONS=($(kubectl get revision -l "serving.knative.dev/service=stock-service-example" --output \
jsonpath="{.items[*].metadata.name}"))
echo ${REVISIONS[*]}
```

2. Update the `traffic` list in `docs/serving/samples/rest-api-go/sample.yaml` as:
2. Update the `revisions` list in
`serving/samples/traffic-splitting/split_sample.yaml`. A `rolloutPercent` of
50 has already been specified, but can be changed if desired by editing the
`split_sample.yaml` file.

```yaml
traffic:
- revisionName: <YOUR_FIRST_REVISION_NAME>
percent: 50
- revisionName: <YOUR_SECOND_REVISION_NAME>
percent: 50
```shell
CURRENT=${REVISIONS[0]} CANDIDATE=${REVISIONS[1]} \
envsubst < serving/samples/traffic-splitting/split_sample.yaml \
| kubectl apply --filename -
```

3. Deploy your traffic revision:
3. Verify the deployment by checking the service status:

```
kubectl apply --filename docs/serving/samples/rest-api-go/sample.yaml
```shell
kubectl get ksvc --output yaml
```

4. Verify the deployment by checking the route status:
4. 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!`.

```
kubectl get route --output yaml
```shell
curl --header "Host:${SERVICE_HOSTNAME}" http://${INGRESS_IP}
```

Once updated, you can make `curl` requests to the API using either `stock` or
`share` endpoints.
5. Much like the `current` and `latest` subdomains there should now be a
`candidate` subdomain that should return `Welcome to the share app!` as it hits
the second index of the `revisions` list.

```shell
curl --header "Host:candidate.${SERVICE_HOSTNAME}" http://${INGRESS_IP}
```

## Clean Up

To clean up the sample service:

```
kubectl delete --filename docs/serving/samples/traffic-splitting/updated_configuration.yaml
```shell
kubectl delete --filename serving/samples/traffic-splitting/split_sample.yaml
```