This guide walks us over the set of instructions we followed to get sample applications deployed on Knative.
Before you begin, please verify:
v1.10.11
brew install kubectl
$ kubectl version Client Version: version.Info{Major:"1", Minor:"9", GitVersion:"v1.9.0", GitCommit:"925c127ec6b946659ad0fd596fa959be43f0cc05", GitTreeState:"clean", BuildDate:"2017-12-15T21:07:38Z", GoVersion:"go1.9.2", Compiler:"gc", Platform:"darwin/amd64"} Server Version: version.Info{Major:"1", Minor:"10", GitVersion:"v1.10.11", GitCommit:"637c7e288581ee40ab4ca210618a89a555b6e7e9", GitTreeState:"clean", BuildDate:"2018-11-26T14:25:46Z", GoVersion:"go1.9.3", Compiler:"gc", Platform:"linux/amd64"} $ kubectl get nodes NAME STATUS ROLES AGE VERSION docker-for-desktop Ready master 9m v1.10.11 $ kubectl get pods --all-namespaces NAMESPACE NAME READY STATUS RESTARTS AGE docker compose-74649b4db6-44fz2 1/1 Running 0 6m docker compose-api-65975979ff-p4tqb 1/1 Running 0 6m kube-system etcd-docker-for-desktop 1/1 Running 0 7m kube-system kube-apiserver-docker-for-desktop 1/1 Running 0 6m kube-system kube-controller-manager-docker-for-desktop 1/1 Running 0 7m kube-system kube-dns-86f4d74b45-fg9mz 3/3 Running 0 8m kube-system kube-proxy-j66t6 1/1 Running 0 8m kube-system kube-scheduler-docker-for-desktop 1/1 Running 0 7m
$ curl -L https://github.com/knative/serving/releases/download/v0.2.2/istio.yaml | sed 's/LoadBalancer/NodePort/' | kubectl apply --filename - % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 601 0 601 0 0 1747 0 --:--:-- --:--:-- --:--:-- 1752 0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0namespace "istio-system" created configmap "istio-galley-configuration" created configmap "istio-statsd-prom-bridge" created configmap "istio-security-custom-resources" created 100 106k 100 106k 0 0 44524 0 0:00:02 0:00:02 --:--:-- 68984 configmap "istio" created configmap "istio-sidecar-injector" created serviceaccount "istio-galley-service-account" created serviceaccount "istio-egressgateway-service-account" created serviceaccount "istio-ingressgateway-service-account" created serviceaccount "istio-mixer-service-account" created serviceaccount "istio-pilot-service-account" created serviceaccount "istio-cleanup-secrets-service-account" created clusterrole "istio-cleanup-secrets-istio-system" created clusterrolebinding "istio-cleanup-secrets-istio-system" created job "istio-cleanup-secrets" created ... kubernetesenv "handler" created rule "kubeattrgenrulerule" created rule "tcpkubeattrgenrulerule" created kubernetes "attributes" created destinationrule "istio-policy" created destinationrule "istio-telemetry" created
Verify that the pods under istio-system
are all Running.
$ kubectl get pods --namespace istio-system NAME READY STATUS RESTARTS AGE istio-citadel-84fb7985bf-249lh 1/1 Running 0 4m istio-egressgateway-bd9fb967d-cmlht 1/1 Running 0 4m istio-galley-655c4f9ccd-r8gvw 1/1 Running 0 4m istio-ingressgateway-688865c5f7-gqdhv 1/1 Running 0 4m istio-pilot-6cd69dc444-md6xc 2/2 Running 0 4m istio-policy-6b9f4697d-lzv4f 2/2 Running 0 4m istio-sidecar-injector-8975849b4-qr77x 1/1 Running 0 4m istio-statsd-prom-bridge-7f44bb5ddb-hs47f 1/1 Running 0 4m istio-telemetry-6b5579595f-nqn4q 2/2 Running 0 4m
Now, check the default
namespace for labels:
$ kubectl get namespace default -o yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: 2019-01-17T23:32:06Z name: default resourceVersion: "4" selfLink: /api/v1/namespaces/default uid: 19f44753-1ab0-11e9-a8d0-025000000001 spec: finalizers: - kubernetes status: phase: Active
Notice the default
namespace has no labels under metadata
. Now, add the label istio-injection=enabled
:
$ kubectl label namespace default istio-injection=enabled namespace "default" labeled
Read the default
namespace metadata again and it should have the label we just added.
kubectl get namespace default -o yaml apiVersion: v1 kind: Namespace metadata: creationTimestamp: 2019-01-17T23:32:06Z labels: istio-injection: enabled name: default resourceVersion: "1813" selfLink: /api/v1/namespaces/default uid: 19f44753-1ab0-11e9-a8d0-025000000001 spec: finalizers: - kubernetes status: phase: Active
$ curl -L https://github.com/knative/serving/releases/download/v0.2.2/release-lite.yaml | sed 's/LoadBalancer/NodePort/' | kubectl apply --filename - % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 608 0 608 0 0 1489 0 --:--:-- --:--:-- --:--:-- 1493 0 505k 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0namespace "knative-build" created clusterrole "knative-build-admin" created serviceaccount "build-controller" created clusterrolebinding "build-controller-admin" created customresourcedefinition "builds.build.knative.dev" created customresourcedefinition "buildtemplates.build.knative.dev" created customresourcedefinition "clusterbuildtemplates.build.knative.dev" created customresourcedefinition "images.caching.internal.knative.dev" created service "build-controller" created service "build-webhook" created image "creds-init" created image "git-init" created ... rolebinding "prometheus-system" created rolebinding "prometheus-system" created rolebinding "prometheus-system" created rolebinding "prometheus-system" created clusterrolebinding "prometheus-system" created service "prometheus-system-np" created statefulset "prometheus-system" created
Make sure all the pods under knative-serving
namespace are Running:
$ kubectl get pods --namespace knative-serving NAME READY STATUS RESTARTS AGE activator-df78cb6f9-dxktc 2/2 Running 0 48s activator-df78cb6f9-fdhmd 2/2 Running 0 48s activator-df78cb6f9-zhdnn 2/2 Running 0 48s autoscaler-6fccb66768-ksjrk 2/2 Running 0 48s controller-56cf5965f5-x8hvk 1/1 Running 0 47s webhook-5dcbf967cd-nltpl 1/1 Running 0 47s
Before starting to deploy any app, make sure there are no pods running in the default
namespace where we will be deploying and creating pods for helloworld-go
application.
$ kubectl get pods No resources found.
You can delete all the pods in a single namespace use this command:
$ kubectl delete --all pods --namespace=default
Now, create a new file helloworld-go.yaml
with:
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"
Deploy helloworld-go
with:
$ kubectl apply -f helloworld-go.yaml service "helloworld-go" created
$ kubectl get routes/helloworld-go --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain NAME DOMAIN helloworld-go helloworld-go.default.example.com $ kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}' 32380 $ curl -H "Host: helloworld-go.default.example.com" http://localhost:32380 Hello Go Sample v1!
Yay! We have helloworld-go
application deployed and reachable.
Now, lets try and deploy one more application.
kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml buildtemplate "kaniko" created
Use the following commands to generate base64 encoded values of Docker Hub username and password required to register a new secret
in Kubernetes.
$ echo -n "your username" | base64 -b 0 eW91ciB1c2VybmFtZQ== $ echo -n "your password" | base64 -b 0eW91ciBwYXNzd29yZA==
Create a new secret
manifest named docker-secret.yaml
:
apiVersion: v1 kind: Secret metadata: name: basic-user-pass annotations: build.knative.dev/docker-0: https://index.docker.io/v1/ type: kubernetes.io/basic-auth data: # Use 'echo -n "username" | base64 -b 0' to generate this string username: eW91ciB1c2VybmFtZQ== # Use 'echo -n "password" | base64 -b 0' to generate this string password: 0eW91ciBwYXNzd29yZA==
Apply this manifest:
$ kubectl apply -f docker-secret.yaml secret "basic-user-pass" created
Verify:
$ kubectl get secret NAME TYPE DATA AGE basic-user-pass kubernetes.io/basic-auth 2 21s ...
Create a new Service Account
manifest which is used to link the build process to the docker hub secret. Create service-account.yaml
with:
apiVersion: v1 kind: ServiceAccount metadata: name: build-bot secrets: - name: basic-user-pass
Apply service account
manifest:
kubectl apply -f service-account.yaml serviceaccount "build-bot" created
Verify:
$ kubectl get serviceaccount NAME SECRETS AGE build-bot 2 24s default 1 4d
Note: We are deploying this application under default
namespace. We had deployed helloworld-go
under the same default
namespace. We have noticed a limitation with Kubernetes on Docker which restricts number of pods under one single namespace. Please make sure that there are no pods exist under default
and if they do, delete them all using kubectl delete --all pods --namespace=default
Create a file named service.yaml
and copy the following defintion. Make sure to replace {DOCKER_USERNAME}
with your own Docker Hub username:
apiVersion: serving.knative.dev/v1alpha1 kind: Service metadata: name: app-from-source namespace: default spec: runLatest: configuration: build: apiVersion: build.knative.dev/v1alpha1 kind: Build spec: serviceAccountName: build-bot source: git: url: https://github.com/mchmarny/simple-app.git revision: master template: name: kaniko arguments: - name: IMAGE value: docker.io/{DOCKER_USERNAME}/app-from-source:latest revisionTemplate: spec: container: image: docker.io/{DOCKER_USERNAME}/app-from-source:latest imagePullPolicy: Always env: - name: SIMPLE_MSG value: "Hello from the sample app!"
Apply this manifest:
$ kubectl apply -f service.yaml service "app-from-source" created
Verify:
$ kubectl get pods NAME READY STATUS RESTARTS AGE app-from-source-00001-deployment-74c9cbdd6c-c6qzv 3/3 Running 0 24s
$ kubectl get routes/app-from-source --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain NAME DOMAIN helloworld-go app-from-source.default.example.com $ kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}' 32380 $ curl -H "Host: app-from-source.default.example.com" http://localhost:32380 <h1>Hello from the sample app!</h1>
Hurray! We could deploy applications on Knative and interact with them. Watch this space for more experiments with Knative.