This is a walk-through example that demonstrates deploying a dockerized
application that accesses external dependencies to Knative Serving. In this demo
we will use a sample golang
application that takes a video URL as an input and
generates its thumbnail image using the ffmpeg
framework.
If you want to test and run the app locally:
In this demo we are going to use a simple golang
REST app called
rester-tester. It's important to
point out that this application doesn't use any special Knative Serving
components, nor does it have any Knative Serving SDK dependencies.
Let's start by cloning the public rester-tester
repository:
git clone [email protected]:mchmarny/rester-tester.git
cd rester-tester
The rester-tester
application uses godep to
manage its own dependencies. Download godep
and restore the app dependencies:
go get github.com/tools/godep
godep restore
To make sure the application is ready, run the integrated tests:
go test ./...
You can now run the rester-tester
application locally in go
or using Docker.
Local
To run the app:
go build
./rester-tester
Docker
When running the application locally using Docker, you do not need to install
ffmpeg
; Docker will install it for you 'inside' of the Docker image.
To run the app:
docker build -t rester-tester:latest .
docker run -p 8080:8080 rester-tester:latest
To test the thumbnailing service, use curl
to submit the src
, a video URL:
curl -X POST -H "Content-Type: application/json" http://localhost:8080/image \
-d '{"src":"https://www.youtube.com/watch?v=DjByja9ejTQ"}'
From this point, you can either deploy a prebuilt image of the app, or build the app locally and then deploy it.
You can deploy a prebuilt image of the rester-tester
app to Knative Serving
using kubectl
and the included sample-prebuilt.yaml
file:
# From inside the thumbnailer-go directory
kubectl apply --filename sample-prebuilt.yaml
If you want to build the image yourself, follow these instructions. This sample uses the Kaniko build template from the build-templates repo.
# Replace the token string with a suitable registry
REPO="gcr.io/<your-project-here>"
perl -pi -e "s@DOCKER_REPO_OVERRIDE@$REPO@g" sample.yaml
# Install the Kaniko build template used to build this sample (in the
# build-templates repo).
kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
# Create the Knative route and configuration for the application
kubectl apply --filename sample.yaml
Now, if you look at the status
of the revision, you will see that a build is
in progress:
$ kubectl get revisions --output yaml
apiVersion: v1
items:
- apiVersion: serving.knative.dev/v1alpha1
kind: Revision
...
status:
conditions:
- reason: Building
status: "False"
type: BuildComplete
...
Once BuildComplete
has a status: "True"
, the revision will be deployed.
To confirm that the app deployed, you can check for the Knative Serving service
using kubectl
. First, is there an ingress service, and does it have an
EXTERNAL-IP
:
kubectl get svc knative-ingressgateway --namespace istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
knative-ingressgateway LoadBalancer 10.23.247.74 35.203.155.229 80:32380/TCP,443:32390/TCP,32400:32400/TCP 2d
Note: It can take a few seconds for the service to show an
EXTERNAL-IP
.
The newly deployed app may take few seconds to initialize. You can check its status by entering the following command:
kubectl --namespace default get pods
The Knative Serving ingress service will automatically be assigned an external
IP, so let's capture the IP and Host URL in variables so that we can use them in
curl
commands:
# Put the Host URL into an environment variable.
export SERVICE_HOST=`kubectl get route thumb --output jsonpath="{.status.domain}"`
# Put the ingress IP into an environment variable.
export SERVICE_IP=`kubectl get svc knative-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.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:
export SERVICE_IP=$(kubectl get po --selector knative=ingressgateway --namespace istio-system --output 'jsonpath={.items[0].status.hostIP}'):$(kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')
Let's start with a simple ping
to make sure the app is deployed:
curl -H "Content-Type: application/json" -H "Host: $SERVICE_HOST" \
http://$SERVICE_IP/ping
Now, supply the video URL and generate a video thumbnail:
curl -X POST -H "Content-Type: application/json" -H "Host: $SERVICE_HOST" \
http://$SERVICE_IP/image -d '{"src":"https://www.youtube.com/watch?v=DjByja9ejTQ"}'
You can then download the newly created thumbnail. Make sure to replace the image file name with the one returned by the previous curl request:
curl -H "Host: $SERVICE_HOST" \
http://$SERVICE_IP/thumb/img_b43ffcc2-0c80-4862-8423-60ec1b4c4926.png > demo.png
Although this demo uses an external application, the Knative Serving deployment
steps would be similar for any 'dockerized' app you may already have. Just copy
the sample.yaml
and change a few variables.