From 9f2138f002f8791c695259eca413b19e92e17e11 Mon Sep 17 00:00:00 2001 From: Matt Moore Date: Fri, 6 Nov 2020 09:04:08 -0800 Subject: [PATCH] Switch helloworld-go with kn (#2807) * Try helloworld-go with kn * Add kn as a prereq. * Incorporate Ashleigh's feedback * Fix @abrennan89 feedback --- .../hello-world/helloworld-go/Dockerfile | 1 - .../hello-world/helloworld-go/README.md | 188 -------------- .../hello-world/helloworld-go/index.md | 229 +++++++++++++++++- .../hello-world/helloworld-shell/index.md | 4 +- 4 files changed, 230 insertions(+), 192 deletions(-) delete mode 100644 docs/serving/samples/hello-world/helloworld-go/README.md diff --git a/docs/serving/samples/hello-world/helloworld-go/Dockerfile b/docs/serving/samples/hello-world/helloworld-go/Dockerfile index e141bf2cc4..ef57f8009f 100644 --- a/docs/serving/samples/hello-world/helloworld-go/Dockerfile +++ b/docs/serving/samples/hello-world/helloworld-go/Dockerfile @@ -1,6 +1,5 @@ # Use the official Golang image to create a build artifact. # This is based on Debian and sets the GOPATH to /go. -# https://hub.docker.com/_/golang FROM golang:1.13 as builder # Create and change to the app directory. diff --git a/docs/serving/samples/hello-world/helloworld-go/README.md b/docs/serving/samples/hello-world/helloworld-go/README.md deleted file mode 100644 index f9f4cb71aa..0000000000 --- a/docs/serving/samples/hello-world/helloworld-go/README.md +++ /dev/null @@ -1,188 +0,0 @@ -A simple web app written in Go that you can use for testing. It reads in an env -variable `TARGET` and prints `Hello ${TARGET}!`. If `TARGET` is not specified, -it will use `World` as the `TARGET`. - -Follow the steps below to create the sample code and then deploy the app to your -cluster. You can also download a working copy of the sample, by running the -following commands: - -```shell -git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs -cd knative-docs/docs/serving/samples/hello-world/helloworld-go -``` - -## Before you begin - -- A Kubernetes cluster with Knative installed and DNS configured. Follow the - [installation instructions](../../../../install/README.md) if you need to - create one. -- [Docker](https://www.docker.com) installed and running on your local machine, - and a Docker Hub account configured (we'll use it for a container registry). - -## Recreating the sample code - -1. Create a new file named `helloworld.go` and paste the following code. This - code creates a basic web server which listens on port 8080: - - ```go - package main - - import ( - "fmt" - "log" - "net/http" - "os" - ) - - func handler(w http.ResponseWriter, r *http.Request) { - log.Print("helloworld: received a request") - target := os.Getenv("TARGET") - if target == "" { - target = "World" - } - fmt.Fprintf(w, "Hello %s!\n", target) - } - - func main() { - log.Print("helloworld: starting server...") - - http.HandleFunc("/", handler) - - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } - - log.Printf("helloworld: listening on port %s", port) - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) - } - ``` - -1. In your project directory, create a file named `Dockerfile` and copy the code - block below into it. For detailed instructions on dockerizing a Go app, see - [Deploying Go servers with Docker](https://blog.golang.org/docker). - - ```docker - # Use the official Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - # https://hub.docker.com/_/golang - FROM golang:1.13 as builder - - # Create and change to the app directory. - WORKDIR /app - - # Retrieve application dependencies using go modules. - # Allows container builds to reuse downloaded dependencies. - COPY go.* ./ - RUN go mod download - - # Copy local code to the container image. - COPY . ./ - - # Build the binary. - # -mod=readonly ensures immutable go.mod and go.sum in container builds. - RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server - - # Use the official Alpine image for a lean production container. - # https://hub.docker.com/_/alpine - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM alpine:3 - RUN apk add --no-cache ca-certificates - - # Copy the binary to the production image from the builder stage. - COPY --from=builder /app/server /server - - # Run the web service on container startup. - CMD ["/server"] - ``` - -1. Create a new file, `service.yaml` and copy the following service definition - into the file. Make sure to replace `{username}` with your Docker Hub - username. - - ```yaml - apiVersion: serving.knative.dev/v1 - kind: Service - metadata: - name: helloworld-go - namespace: default - spec: - template: - spec: - containers: - - image: docker.io/{username}/helloworld-go - env: - - name: TARGET - value: "Go Sample v1" - ``` - -1. Use the go tool to create a - [`go.mod`](https://github.com/golang/go/wiki/Modules#gomod) manifest. - - ```shell - go mod init github.com/knative/docs/docs/serving/samples/hello-world/helloworld-go - ``` - -## Building and deploying the sample - -Once you have recreated the sample code files (or used the files in the sample -folder) you're ready to build and deploy the sample app. - -1. Use Docker to build the sample code into a container. To build and push with - Docker Hub, run these commands replacing `{username}` with your Docker Hub - username: - - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-go . - - # Push the container to docker registry - docker push {username}/helloworld-go - ``` - -1. After the build has completed and the container is pushed to docker hub, you - can deploy the app into your cluster. Ensure that the container image value - in `service.yaml` matches the container you built in the previous step. Apply - the configuration using `kubectl`: - - ```shell - kubectl apply --filename service.yaml - ``` - -1. Now that your service is created, Knative will perform the following steps: - - - 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). - -1. Run the following command to find the domain URL for your service: - - ```shell - kubectl get ksvc helloworld-go --output=custom-columns=NAME:.metadata.name,URL:.status.url - ``` - - Example: - - ```shell - NAME URL - helloworld-go http://helloworld-go.default.1.2.3.4.xip.io - ``` - -1. Now you can make a request to your app and see the result. Replace - the URL below with the URL returned in the previous command. - - ```shell - curl http://helloworld-go.default.1.2.3.4.xip.io - Hello Go Sample v1! - ``` - - > Note: Add `-v` option to get more detail if the `curl` command failed. - -## Removing the sample app deployment - -To remove the sample app from your cluster, delete the service record: - -```shell -kubectl delete --filename service.yaml -``` diff --git a/docs/serving/samples/hello-world/helloworld-go/index.md b/docs/serving/samples/hello-world/helloworld-go/index.md index 64864f3407..295cf0e87d 100644 --- a/docs/serving/samples/hello-world/helloworld-go/index.md +++ b/docs/serving/samples/hello-world/helloworld-go/index.md @@ -5,4 +5,231 @@ weight: 1 type: "docs" --- -{{% readfile file="README.md" %}} +This guide describes the steps required to to create the `helloworld-go` sample app +and deploy it to your cluster. +The sample app reads a `TARGET` environment variable, and prints `Hello ${TARGET}!`. +If `TARGET` is not specified, `World` is used as the default value. + +## Prerequisites + +You will need: +- A Kubernetes cluster with [Knative installed and DNS configured](../../../../install/README.md). +- [Docker](https://www.docker.com) installed and running on your local machine, and a Docker Hub account configured. +- Optional: You can use the Knative CLI client [`kn`](https://github.com/knative/client/releases) to simplify resource creation and deployment. Alternatively, you can use `kubectl` to apply resource files directly. + +## Building + +1. Create a basic web server which listens on port 8080, by copying the following code into a new file named `helloworld-go`: + + ```go + package main + + import ( + "fmt" + "log" + "net/http" + "os" + ) + + func handler(w http.ResponseWriter, r *http.Request) { + log.Print("helloworld: received a request") + target := os.Getenv("TARGET") + if target == "" { + target = "World" + } + fmt.Fprintf(w, "Hello %s!\n", target) + } + + func main() { + log.Print("helloworld: starting server...") + + http.HandleFunc("/", handler) + + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } + + log.Printf("helloworld: listening on port %s", port) + log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) + } + ``` + + You can also download a working copy of the sample, by running the + following commands: + + ```shell + git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs + cd knative-docs/docs/serving/samples/hello-world/helloworld-go + ``` + + +1. Navigate to your project directory and copy the following code into a new file named `Dockerfile`: + + ```docker + # Use the official Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + FROM golang:1.13 as builder + + # Create and change to the app directory. + WORKDIR /app + + # Retrieve application dependencies using go modules. + # Allows container builds to reuse downloaded dependencies. + COPY go.* ./ + RUN go mod download + + # Copy local code to the container image. + COPY . ./ + + # Build the binary. + # -mod=readonly ensures immutable go.mod and go.sum in container builds. + RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server + + # Use the official Alpine image for a lean production container. + # https://hub.docker.com/_/alpine + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM alpine:3 + RUN apk add --no-cache ca-certificates + + # Copy the binary to the production image from the builder stage. + COPY --from=builder /app/server /server + + # Run the web service on container startup. + CMD ["/server"] + ``` + +1. Use the Go tool to create a + [`go.mod`](https://github.com/golang/go/wiki/Modules#gomod) manifest. + + ```shell + go mod init github.com/knative/docs/docs/serving/samples/hello-world/helloworld-go + ``` + +## Deploying + +1. To build the sample code into a container, and push using Docker Hub, enter the following commands and replace `{username}` with your Docker Hub username: + + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-go . + + # Push the container to docker registry + docker push {username}/helloworld-go + ``` + +1. After the build has completed and the container is pushed to docker hub, you + can deploy the app into your cluster. Choose one of the following methods: + + + {{< tabs name="helloworld_go" default="kn" >}} + {{% tab name="yaml" %}} + + 1. Create a new file, `service.yaml` and copy the following service definition + into the file. Make sure to replace `{username}` with your Docker Hub + username. + + ```yaml + apiVersion: serving.knative.dev/v1 + kind: Service + metadata: + name: helloworld-go + namespace: default + spec: + template: + spec: + containers: + - image: docker.io/{username}/helloworld-go + env: + - name: TARGET + value: "Go Sample v1" + ``` + + Check that the container image value in the `service.yaml` file matches the container you built in the previous step. + + 1. Apply the configuration using `kubectl`: + + ```shell + kubectl apply --filename service.yaml + ``` + + After your service is created, Knative will perform the following steps: + + - 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). + + 1. Run the following command to find the domain URL for your service: + + ```shell + kubectl get ksvc helloworld-go --output=custom-columns=NAME:.metadata.name,URL:.status.url + ``` + + Example: + + ```shell + NAME URL + helloworld-go http://helloworld-go.default.1.2.3.4.xip.io + ``` + + {{< /tab >}} + {{% tab name="kn" %}} + + Use `kn` to deploy the service: + + ```shell + kn service create helloworld-go --image=docker.io/{username}/helloworld-go --env TARGET="Go Sample v1" + ``` + + You should see output like this: + ```shell + Creating service 'helloworld-go' in namespace 'default': + + 0.031s The Configuration is still working to reflect the latest desired specification. + 0.051s The Route is still working to reflect the latest desired specification. + 0.076s Configuration "helloworld-go" is waiting for a Revision to become ready. + 15.694s ... + 15.738s Ingress has not yet been reconciled. + 15.784s Waiting for Envoys to receive Endpoints data. + 16.066s Waiting for load balancer to be ready + 16.237s Ready to serve. + + Service 'helloworld-go' created to latest revision 'helloworld-go-jjzgd-1' is available at URL: + http://helloworld-go.default.1.2.3.4.xip.io + ``` + + You can then access your service through the resulting URL. + + {{< /tab >}} + {{< /tabs >}} + + +## Verifying + +1. Now you can make a request to your app and see the result. Replace + the URL below with the URL returned in the previous command. + + ```shell + curl http://helloworld-go.default.1.2.3.4.xip.io + Hello Go Sample v1! + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. + +## Removing + +To remove the sample app from your cluster, delete the service record: + +{{< tabs name="service_url" default="kn" >}} +{{% tab name="kubectl" %}} +```shell +kubectl delete --filename service.yaml +``` +{{< /tab >}} +{{% tab name="kn" %}} +```shell +kn service delete helloworld-go +``` +{{< /tab >}} +{{< /tabs >}} diff --git a/docs/serving/samples/hello-world/helloworld-shell/index.md b/docs/serving/samples/hello-world/helloworld-shell/index.md index 4ae90c5bd0..6d86ef5c71 100644 --- a/docs/serving/samples/hello-world/helloworld-shell/index.md +++ b/docs/serving/samples/hello-world/helloworld-shell/index.md @@ -25,9 +25,9 @@ cd knative-docs/docs/serving/samples/hello-world/helloworld-shell [installation instructions](../../../../install/README.md). - [Docker](https://www.docker.com) installed and running on your local machine, and a Docker Hub account configured. -- (optional) The Knatice CLI client [kn](https://github.com/knative/client/releases) that simplifies the deployment. Alternative you can also use [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/) and apply resource files directly. +- Optional: You can use the Knative CLI client [`kn`](https://github.com/knative/client/releases) to simplify resource creation and deployment. Alternatively, you can use `kubectl` to apply resource files directly. -## Build +## Building 1. Create a new file named `script.sh` and paste the script below. This will run netcat (`nc`) in an endless loop, returning a friendly welcome message.