Getting started with knative
This post is based on https://github.com/knative/docs/blob/master/install/getting-started-knative-app.md
This post uses the Hello World sample app in Go to demonstrate the basic workflow for deploying an app.
Install knative
Following the instructions at https://github.com/knative/docs/blob/master/install/Knative-with-any-k8s.md
Install Istio
Try to install Istio using the following command:
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.4.0/istio-crds.yaml && \
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.4.0/istio.yaml
You will probably see the error:
The Service "istio-ingressgateway" is invalid: spec.ports[0].nodePort: Invalid value: 31380: provided port is not in the valid range. The range of valid ports is 32768-35535
You need to download the https://github.com/knative/serving/releases/download/v0.4.0/istio-crds.yaml file locally and modify the ports used, to fall within this range:
Change the nodePort
values from 31380, 31390, 31400 to 33380, 33390, 33400:
...
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway
namespace: istio-system
annotations:
labels:
chart: gateways-1.0.1
release: RELEASE-NAME
heritage: Tiller
app: istio-ingressgateway
istio: ingressgateway
spec:
type: LoadBalancer
selector:
app: istio-ingressgateway
istio: ingressgateway
ports:
-
name: http2
nodePort: 31380
port: 80
targetPort: 80
-
name: https
nodePort: 31390
port: 443
-
name: tcp
nodePort: 31400
port: 31400
....
to:
...
apiVersion: v1
kind: Service
metadata:
name: istio-ingressgateway
namespace: istio-system
annotations:
labels:
chart: gateways-1.0.1
release: RELEASE-NAME
heritage: Tiller
app: istio-ingressgateway
istio: ingressgateway
spec:
type: LoadBalancer
selector:
app: istio-ingressgateway
istio: ingressgateway
ports:
-
name: http2
nodePort: 33380
port: 80
targetPort: 80
-
name: https
nodePort: 33390
port: 443
-
name: tcp
nodePort: 33400
port: 31400
...
Re-apply, using the modified local file:
kubectl apply --filename istio.yaml
Label the default namespace with istio-injection=enabled
:
# kubectl label namespace default istio-injection=enabled
Monitor the Istio components until all of the components show a STATUS of Running or Completed:
# kubectl get pods --namespace istio-system
Install knative and dependencies
kubectl apply --filename https://github.com/knative/serving/releases/download/v0.4.0/serving.yaml \
--filename https://github.com/knative/build/releases/download/v0.4.0/build.yaml \
--filename https://github.com/knative/eventing/releases/download/v0.4.0/release.yaml \
--filename https://github.com/knative/eventing-sources/releases/download/v0.4.0/release.yaml \
--filename https://github.com/knative/serving/releases/download/v0.4.0/monitoring.yaml \
--filename https://raw.githubusercontent.com/knative/serving/v0.4.0/third_party/config/build/clusterrole.yaml
If you see an error such as:
unable to recognize "https://github.com/knative/eventing/releases/download/v0.4.0/release.yaml": no matches for kind "ClusterChannelProvisioner" in version "eventing.knative.dev/v1alpha1"
unable to recognize "https://github.com/knative/eventing/releases/download/v0.4.0/release.yaml": no matches for kind "ClusterChannelProvisioner" in version "eventing.knative.dev/v1alpha1"
you may be hitting a known issue:
https://github.com/knative/eventing/issues/680
It fails the first time because the `ClusterChannelProvisioner` CRD hasn't been fully reconciled yet when the in-memory-channel provisioner is created. The second time usually succeeds (because the CRD has been reconciled by then).
Simply re-run the command a second time to re-apply the same files.
Monitor the Knative components until all of the components show a STATUS of Running:
kubectl get pods --namespace knative-serving
kubectl get pods --namespace knative-build
kubectl get pods --namespace knative-eventing
kubectl get pods --namespace knative-sources
kubectl get pods --namespace knative-monitoring
Deploying your serverless app
To deploy an app using Knative, you need a configuration .yaml file that defines a Service.
This configuration file specifies metadata about the application, points to the hosted image of the app for deployment, and allows the deployment to be configured.
Create a new file named service.yaml
with the following content:
# cat service.yaml
apiVersion: serving.knative.dev/v1alpha1 # Current version of Knative
kind: Service
metadata:
name: helloworld-go # The name of the app
namespace: default # The namespace the app will use
spec:
runLatest:
configuration:
revisionTemplate:
spec:
container:
image: gcr.io/knative-samples/helloworld-go # The URL to the image of the app
env:
- name: TARGET # The environment variable printed out by the sample app
value: "Go Sample v1"
From the directory where the new service.yaml
file was created, apply the configuration:
# kubectl apply --filename service.yaml
service.serving.knative.dev/helloworld-go created
Now that your service is created, Knative will perform the following steps:
- Create a new immutable revision for this version of the app.
- Perform network programming to create a route, ingress, service, and load balancer for your app.
- Automatically scale your pods up and down based on traffic, including to zero active pods.
Interacting with your app
To see if your app has been deployed succesfully, you need the host URL and IP address created by Knative.
Use kubectl get svc
to see the details of the service:
[root@hpe-ansible knative]# kubectl get svc istio-ingressgateway --namespace istio-system
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
istio-ingressgateway LoadBalancer 10.96.72.109 <pending> 80:33380/TCP,443:33390/TCP,31400:33400/TCP,15011:33994/TCP,8060:34944/TCP,853:35094/TCP,15030:33326/TCP,15031:34179/TCP 1h
Patch the type to be NodePort
:
# kubectl -n istio-system patch svc istio-ingressgateway --type='json' -p '[{"op":"replace","path":"/spec/type","value":"NodePort"}]'
service/istio-ingressgateway patched
And patch the port to be, for example, 33333
:
# kubectl -n istio-system patch svc istio-ingressgateway --type='json' -p '[{"op": "add", "path":"/spec/ports/0/nodePort", "value":33333}]'
service/istio-ingressgateway patched
Check that the changes to the service have been made:
# kubectl get svc istio-ingressgateway --namespace istio-system -o yaml
Test service
To find the host URL for your service, enter:
# kubectl get ksvc helloworld-go --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain
NAME DOMAIN
helloworld-go helloworld-go.default.example.com
Simply use curl
to test the service, specifing the appropriate port and domain:
# curl -vH "Host: helloworld-go.default.example.com" http://hpe2-ucp01.am2.cloudra.local:33333
Hello Go Sample v1!
Teardown
To remove the sample app from your cluster, delete the service record:
# kubectl delete --filename service.yaml