A Go sample that shows how to use Knative to go from source code in a git repository to a running application with a URL.
This sample uses the Build and Serving components of Knative to orchestrate an end-to-end deployment.
You need:
- A Kubernetes cluster with Knative installed. Follow the installation instructions if you need to create one.
- Go installed and configured. This is optional, and only required if you want to run the sample app locally.
To use this sample, you need to install a build template and register a secret for Docker Hub.
This sample leverages the kaniko build template to perform a source-to-container build on your Kubernetes cluster.
Use kubectl to install the kaniko manifest:
kubectl apply --filename https://raw.githubusercontent.com/knative/build-templates/master/kaniko/kaniko.yaml
In order to push the container that is built from source to Docker Hub, register a secret in Kubernetes for authentication with Docker Hub.
There are detailed instructions available, but these are the key steps:
-
Create a new
Secret
manifest, which is used to store your Docker Hub credentials. Save this file asdocker-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' to generate this string username: BASE64_ENCODED_USERNAME # Use 'echo -n "password" | base64' to generate this string password: BASE64_ENCODED_PASSWORD
-
On macOS or Linux computers, use the following command to generate the base64-encoded values required for the manifest:
$ echo -n "username" | base64 -w 0 dXNlcm5hbWU= $ echo -n "password" | base64 -w 0 cGFzc3dvcmQ=
Note: If you receive the "invalid option -w" error on macOS, try using the
base64 -b 0
command. -
Create a new
Service Account
manifest which is used to link the build process to the secret. Save this file asservice-account.yaml
:apiVersion: v1 kind: ServiceAccount metadata: name: build-bot secrets: - name: basic-user-pass
-
After you have created the manifest files, apply them to your cluster with
kubectl
:$ kubectl apply --filename docker-secret.yaml secret "basic-user-pass" created $ kubectl apply --filename service-account.yaml serviceaccount "build-bot" created
Now that you've configured your cluster accordingly, you are ready to deploy the sample service into your cluster.
This sample uses github.com/mchmarny/simple-app
as a basic Go application, but
you could replace this GitHub repo with your own. The only requirements are that
the repo must contain a Dockerfile
with the instructions for how to build a
container for the application.
-
You need to create a service manifest which defines the service to deploy, including where the source code is and which build-template to use. Create a file named
service.yaml
and copy the following definition. 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 timeout: 10m 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 using
kubectl
, and watch the results:# Apply the manifest $ kubectl apply --filename service.yaml service "app-from-source" created # Watch the pods for build and serving $ kubectl get pods --watch NAME READY STATUS RESTARTS AGE app-from-source-00001-zhddx 0/1 Init:2/3 0 7s app-from-source-00001-zhddx 0/1 PodInitializing 0 37s app-from-source-00001-zhddx 0/1 Completed 0 38s app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Pending 0 0s app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Pending 0 0s app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Init:0/1 0 0s app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 Init:0/1 0 2s app-from-source-00001-deployment-6d6ff665f9-xfhm5 0/3 PodInitializing 0 3s app-from-source-00001-deployment-6d6ff665f9-xfhm5 2/3 Running 0 6s app-from-source-00001-deployment-6d6ff665f9-xfhm5 3/3 Running 0 11s
Note: If the build pod never reaches Completed status and terminates after 10 minutes, Kaniko probably didn't finish pulling the build image within the default timeout period. Try increasing the
timeout
value inservice.yaml
.
-
Once you see the deployment pod switch to the running state, press Ctrl+C to escape the watch. Your container is now built and deployed!
-
To check on the state of the service, get the service object and examine the status block:
$ kubectl get ksvc app-from-source --output yaml [...] status: conditions: - lastTransitionTime: 2018-07-11T20:50:18Z status: "True" type: ConfigurationsReady - lastTransitionTime: 2018-07-11T20:50:56Z status: "True" type: RoutesReady - lastTransitionTime: 2018-07-11T20:50:56Z status: "True" type: Ready domain: app-from-source.default.example.com latestCreatedRevisionName: app-from-source-00007 latestReadyRevisionName: app-from-source-00007 observedGeneration: 10 traffic: - configurationName: app-from-source percent: 100 revisionName: app-from-source-00007
-
Now that your service is created, Knative will perform the following steps:
- Fetch the revision specified from GitHub and build it into a container
- Push the container to Docker Hub
- Create a new immutable revision for this version of the app.
- Network programming to create a route, ingress, service, and load balance for your app.
- Automatically scale your pods up and down (including to zero active pods).
-
To get the ingress IP for your cluster, use the following command. If your cluster is new, it can take some time for the service to get an external IP address:
# In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`. INGRESSGATEWAY=knative-ingressgateway # 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 kubectl get svc $INGRESSGATEWAY --namespace istio-system 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
-
To find the URL for your service, type:
$ kubectl get ksvc app-from-source --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain NAME DOMAIN app-from-source app-from-source.default.example.com
-
Now you can make a request to your app to see the result. Replace
{IP_ADDRESS}
with the address that you got in the previous step:curl -H "Host: app-from-source.default.example.com" http://{IP_ADDRESS} Hello from the sample app!"
To remove the sample app from your cluster, delete the service record:
kubectl delete --filename service.yaml
Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 4.0 License, and code samples are licensed under the Apache 2.0 License.