+

Welcome to Knative and Elixir

@@ -291,6 +295,7 @@ knative-ingressgateway LoadBalancer 10.35.254.218 35.225.171.32 80:32380
+ ``` diff --git a/serving/samples/helloworld-go/README.md b/serving/samples/helloworld-go/README.md index f159a7558..34c5135e1 100644 --- a/serving/samples/helloworld-go/README.md +++ b/serving/samples/helloworld-go/README.md @@ -6,10 +6,10 @@ It reads in an env variable `TARGET` and prints `Hello ${TARGET}!`. If ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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 @@ -21,92 +21,92 @@ following instructions recreate the source files from this folder. 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 + ```go + package main - import ( - "fmt" - "log" - "net/http" - "os" - ) + import ( + "fmt" + "log" + "net/http" + "os" + ) - func handler(w http.ResponseWriter, r *http.Request) { - log.Print("Hello world received a request.") - target := os.Getenv("TARGET") - if target == "" { - target = "World" - } - fmt.Fprintf(w, "Hello %s!\n", target) - } + func handler(w http.ResponseWriter, r *http.Request) { + log.Print("Hello world received a request.") + target := os.Getenv("TARGET") + if target == "" { + target = "World" + } + fmt.Fprintf(w, "Hello %s!\n", target) + } - func main() { - log.Print("Hello world sample started.") + func main() { + log.Print("Hello world sample started.") - http.HandleFunc("/", handler) + http.HandleFunc("/", handler) - port := os.Getenv("PORT") - if port == "" { - port = "8080" - } + port := os.Getenv("PORT") + if port == "" { + port = "8080" + } - log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil)) - } - ``` + 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 offical Golang image to create a build artifact. - # This is based on Debian and sets the GOPATH to /go. - FROM golang as builder + ```docker + # Use the offical Golang image to create a build artifact. + # This is based on Debian and sets the GOPATH to /go. + FROM golang as builder - # Copy local code to the container image. - WORKDIR /go/src/github.com/knative/docs/helloworld - COPY . . + # Copy local code to the container image. + WORKDIR /go/src/github.com/knative/docs/helloworld + COPY . . - # Build the helloworld command inside the container. - # (You may fetch or manage dependencies here, - # either manually or with a tool like "godep".) - RUN CGO_ENABLED=0 GOOS=linux go build -v -o helloworld + # Build the helloworld command inside the container. + # (You may fetch or manage dependencies here, + # either manually or with a tool like "godep".) + RUN CGO_ENABLED=0 GOOS=linux go build -v -o helloworld - # Use a Docker multi-stage build to create a lean production image. - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM alpine + # Use a Docker multi-stage build to create a lean production image. + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM alpine - # Copy the binary to the production image from the builder stage. - COPY --from=builder /go/src/github.com/knative/docs/helloworld/helloworld /helloworld + # Copy the binary to the production image from the builder stage. + COPY --from=builder /go/src/github.com/knative/docs/helloworld/helloworld /helloworld - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD ["/helloworld"] - ``` + # Run the web service on container startup. + CMD ["/helloworld"] + ``` 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/v1alpha1 - kind: Service - metadata: - name: helloworld-go - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-go - env: - - name: TARGET - value: "Go Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-go + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-go + env: + - name: TARGET + value: "Go Sample v1" + ``` ## Building and deploying the sample @@ -117,69 +117,74 @@ folder) you're ready to build and deploy the sample app. 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 . + ```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 - ``` + # 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 - ``` + ```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). + + - 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 external IP address for your service. The ingress IP for your cluster is returned. If you just created your cluster, you might need to wait and rerun the command until your service gets asssigned an external IP address. - ```shell - kubectl get svc knative-ingressgateway --namespace istio-system - ``` - - Example: - ```shell - 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 + ```shell + kubectl get svc knative-ingressgateway --namespace istio-system + ``` - ``` + Example: + + ```shell + 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 + + ``` 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,DOMAIN:.status.domain - ``` - - Example: - ```shell - NAME DOMAIN - helloworld-go helloworld-go.default.example.com - ``` + + ```shell + kubectl get ksvc helloworld-go --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + ``` + + Example: + + ```shell + NAME DOMAIN + helloworld-go helloworld-go.default.example.com + ``` 1. Test your app by sending it a request. Use the following - `curl` command with the domain URL `helloworld-go.default.example.com` and `EXTERNAL-IP` address that you retrieved + `curl` command with the domain URL `helloworld-go.default.example.com` and `EXTERNAL-IP` address that you retrieved in the previous steps: - ```shell - curl -H "Host: helloworld-go.default.example.com" http://{EXTERNAL_IP_ADDRESS} - ``` - - Example: - ```shell - curl -H "Host: helloworld-go.default.example.com" http://35.203.155.229 - Hello World: Go Sample v1! - ``` + ```shell + curl -H "Host: helloworld-go.default.example.com" http://{EXTERNAL_IP_ADDRESS} + ``` - > Note: Add `-v` option to get more detail if the `curl` command failed. + Example: + + ```shell + curl -H "Host: helloworld-go.default.example.com" http://35.203.155.229 + Hello World: Go Sample v1! + ``` + + > Note: Add `-v` option to get more detail if the `curl` command failed. ## Removing the sample app deployment diff --git a/serving/samples/helloworld-haskell/README.md b/serving/samples/helloworld-haskell/README.md index 98d531c46..b58262b63 100644 --- a/serving/samples/helloworld-haskell/README.md +++ b/serving/samples/helloworld-haskell/README.md @@ -1,15 +1,15 @@ # Hello World - Haskell sample A simple web app written in Haskell that you can use for testing. -It reads in an env variable `TARGET` and prints "Hello ${TARGET}!". If +It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not specified, it will use "World" as the TARGET. ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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 @@ -20,114 +20,115 @@ following instructions recreate the source files from this folder. 1. Create a new file named `stack.yaml` and paste the following code: - ```yaml - flags: {} - packages: - - . - extra-deps: [] - resolver: lts-10.7 - ``` + ```yaml + flags: {} + packages: + - . + extra-deps: [] + resolver: lts-10.7 + ``` + 1. Create a new file named `package.yaml` and paste the following code - ```yaml - name: helloworld-haskell - version: 0.1.0.0 - dependencies: - - base >= 4.7 && < 5 - - scotty - - text + ```yaml + name: helloworld-haskell + version: 0.1.0.0 + dependencies: + - base >= 4.7 && < 5 + - scotty + - text - executables: - helloworld-haskell-exe: - main: Main.hs - source-dirs: app - ghc-options: - - -threaded - - -rtsopts - - -with-rtsopts=-N - ``` + executables: + helloworld-haskell-exe: + main: Main.hs + source-dirs: app + ghc-options: + - -threaded + - -rtsopts + - -with-rtsopts=-N + ``` 1. Create a `app` folder, then create a new file named `Main.hs` in that folder and paste the following code. This code creates a basic web server which listens on port 8080: - ```haskell - {-# LANGUAGE OverloadedStrings #-} + ```haskell + } - import Data.Maybe - import Data.Monoid ((<>)) - import Data.Text.Lazy (Text) - import Data.Text.Lazy - import System.Environment (lookupEnv) - import Web.Scotty (ActionM, ScottyM, scotty) - import Web.Scotty.Trans + e + ) + ) + y + ) + ) + s - main :: IO () - main = do - t <- fromMaybe "World" <$> lookupEnv "TARGET" - pStr <- fromMaybe "8080" <$> lookupEnv "PORT" - let p = read pStr :: Int - scotty p (route t) + ) + o + " + " + t + ) - route :: String -> ScottyM() - route t = get "/" $ hello t + ) + t - hello :: String -> ActionM() - hello t = text $ pack ("Hello " ++ t) - ``` + ) + ) + ``` 1. In your project directory, create a file named `Dockerfile` and copy the code block below into it. - ```docker - # Use the official Haskell image to create a build artifact. - # https://hub.docker.com/_/haskell/ - FROM haskell:8.2.2 as builder + ```docker + # Use the official Haskell image to create a build artifact. + # https://hub.docker.com/_/haskell/ + FROM haskell:8.2.2 as builder - # Copy local code to the container image. - WORKDIR /app - COPY . . + # Copy local code to the container image. + WORKDIR /app + COPY . . - # Build and test our code, then build the “helloworld-haskell-exe” executable. - RUN stack setup - RUN stack build --copy-bins + # Build and test our code, then build the “helloworld-haskell-exe” executable. + RUN stack setup + RUN stack build --copy-bins - # Use a Docker multi-stage build to create a lean production image. - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM fpco/haskell-scratch:integer-gmp + # Use a Docker multi-stage build to create a lean production image. + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM fpco/haskell-scratch:integer-gmp - # Copy the "helloworld-haskell-exe" executable from the builder stage to the production image. - WORKDIR /root/ - COPY --from=builder /root/.local/bin/helloworld-haskell-exe . + # Copy the "helloworld-haskell-exe" executable from the builder stage to the production image. + WORKDIR /root/ + COPY --from=builder /root/.local/bin/helloworld-haskell-exe . - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD ["./helloworld-haskell-exe"] - ``` + # Run the web service on container startup. + CMD ["./helloworld-haskell-exe"] + ``` 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/v1alpha1 - kind: Service - metadata: - name: helloworld-haskell - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-haskell + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: image: docker.io/{username}/helloworld-haskell env: - - name: TARGET - value: "Haskell Sample v1" - ``` + - name: TARGET + value: "Haskell Sample v1" + ``` ## Build and deploy this sample @@ -138,62 +139,64 @@ folder) you're ready to build and deploy the sample app. Docker Hub, enter these commands replacing `{username}` with your Docker Hub username: - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-haskell . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-haskell . - # Push the container to docker registry - docker push {username}/helloworld-haskell - ``` + # Push the container to docker registry + docker push {username}/helloworld-haskell + ``` 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 - ``` + ```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). + + - 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. To find the IP address for your service, enter `kubectl get svc knative-ingressgateway --namespace istio-system` to get the ingress IP for your cluster. If your cluster is new, it may take some time for the service to get assigned an external IP address. - ```shell - kubectl get svc knative-ingressgateway --namespace istio-system + ```shell + 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 + 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 - ``` + ``` - For minikube or bare-metal, get IP_ADDRESS by running the following command + For minikube or bare-metal, get IP_ADDRESS by running the following command - ```shell - echo $(kubectl get node --output 'jsonpath={.items[0].status.addresses[0].address}'):$(kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}') + ```shell + echo $(kubectl get node --output 'jsonpath={.items[0].status.addresses[0].address}'):$(kubectl get svc knative-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}') - ``` + ``` 1. To find the URL for your service, enter: - ``` - kubectl get ksvc helloworld-haskell --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - NAME DOMAIN - helloworld-haskell helloworld-haskell.default.example.com - ``` + + ``` + kubectl get ksvc helloworld-haskell --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + NAME DOMAIN + helloworld-haskell helloworld-haskell.default.example.com + ``` 1. Now you can make a request to your app and see the result. Replace `{IP_ADDRESS}` with the address you see returned in the previous step. - ```shell - curl -H "Host: helloworld-haskell.default.example.com" http://{IP_ADDRESS} - Hello world: Haskell Sample v1 - ``` + ```shell + curl -H "Host: helloworld-haskell.default.example.com" http://{IP_ADDRESS} + Hello world: Haskell Sample v1 + ``` ## Removing the sample app deployment @@ -202,4 +205,3 @@ To remove the sample app from your cluster, delete the service record: ```shell kubectl delete --filename service.yaml ``` - diff --git a/serving/samples/helloworld-java/README.md b/serving/samples/helloworld-java/README.md index 5ddcdd331..80ddc4e30 100644 --- a/serving/samples/helloworld-java/README.md +++ b/serving/samples/helloworld-java/README.md @@ -1,17 +1,17 @@ # Hello World - Spring Boot Java sample A simple web app written in Java using Spring Boot 2.0 that you can use for testing. -It reads in an env variable `TARGET` and prints "Hello ${TARGET}!". If +It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not specified, it will use "World" as the TARGET. ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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). -* You have installed [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). +- You have installed [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). ## Recreating the sample code @@ -21,53 +21,54 @@ recreate the source files from this folder. 1. From the console, create a new empty web project using the curl and unzip commands: - ```shell - curl https://start.spring.io/starter.zip \ - -d dependencies=web \ - -d name=helloworld \ - -d artifactId=helloworld \ - -o helloworld.zip - unzip helloworld.zip - ``` + ```shell + curl https://start.spring.io/starter.zip \ + -d dependencies=web \ + -d name=helloworld \ + -d artifactId=helloworld \ + -o helloworld.zip + unzip helloworld.zip + ``` - If you don't have curl installed, you can accomplish the same by visiting the - [Spring Initializr](https://start.spring.io/) page. Specify Artifact as `helloworld` - and add the `Web` dependency. Then click `Generate Project`, download and unzip the - sample archive. + If you don't have curl installed, you can accomplish the same by visiting the + [Spring Initializr](https://start.spring.io/) page. Specify Artifact as `helloworld` + and add the `Web` dependency. Then click `Generate Project`, download and unzip the + sample archive. 1. Update the `SpringBootApplication` class in `src/main/java/com/example/helloworld/HelloworldApplication.java` by adding a `@RestController` to handle the "/" mapping and also add a `@Value` field to provide the TARGET environment variable: - ```java - package com.example.helloworld; + ```java + package com.example.helloworld; - import org.springframework.beans.factory.annotation.Value; - import org.springframework.boot.SpringApplication; - import org.springframework.boot.autoconfigure.SpringBootApplication; - import org.springframework.web.bind.annotation.GetMapping; - import org.springframework.web.bind.annotation.RestController; + import org.springframework.beans.factory.annotation.Value; + import org.springframework.boot.SpringApplication; + import org.springframework.boot.autoconfigure.SpringBootApplication; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RestController; - @SpringBootApplication - public class HelloworldApplication { + @SpringBootApplication + public class HelloworldApplication { - @Value("${TARGET:World}") - String target; + @Value("${TARGET:World}") + String target; - @RestController - class HelloworldController { - @GetMapping("/") - String hello() { - return "Hello " + target + "!"; - } - } + @RestController + class HelloworldController { + @GetMapping("/") + String hello() { + return "Hello " + target + "!"; + } + } + + public static void main(String[] args) { + SpringApplication.run(HelloworldApplication.class, args); + } + } + ``` - public static void main(String[] args) { - SpringApplication.run(HelloworldApplication.class, args); - } - } - ``` 1. Run the application locally: ```shell @@ -82,55 +83,55 @@ recreate the source files from this folder. For additional information on multi-stage docker builds for Java see [Creating Smaller Java Image using Docker Multi-stage Build](http://blog.arungupta.me/smaller-java-image-docker-multi-stage-build/). - ```docker - # Use the official maven/Java 8 image to create a build artifact. - # https://hub.docker.com/_/maven - FROM maven:3.5-jdk-8-alpine as builder + ```docker + # Use the official maven/Java 8 image to create a build artifact. + # https://hub.docker.com/_/maven + FROM maven:3.5-jdk-8-alpine as builder - # Copy local code to the container image. - WORKDIR /app - COPY pom.xml . - COPY src ./src + # Copy local code to the container image. + WORKDIR /app + COPY pom.xml . + COPY src ./src - # Build a release artifact. - RUN mvn package -DskipTests + # Build a release artifact. + RUN mvn package -DskipTests - # Use the Official OpenJDK image for a lean production stage of our multi-stage build. - # https://hub.docker.com/_/openjdk - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM openjdk:8-jre-alpine + # Use the Official OpenJDK image for a lean production stage of our multi-stage build. + # https://hub.docker.com/_/openjdk + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM openjdk:8-jre-alpine - # Copy the jar to the production image from the builder stage. - COPY --from=builder /app/target/helloworld-*.jar /helloworld.jar + # Copy the jar to the production image from the builder stage. + COPY --from=builder /app/target/helloworld-*.jar /helloworld.jar - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD ["java","-Djava.security.egd=file:/dev/./urandom","-Dserver.port=${PORT}","-jar","/helloworld.jar"] - ``` + # Run the web service on container startup. + CMD ["java","-Djava.security.egd=file:/dev/./urandom","-Dserver.port=${PORT}","-jar","/helloworld.jar"] + ``` 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/v1alpha1 - kind: Service - metadata: - name: helloworld-java - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-java - env: - - name: TARGET - value: "Spring Boot Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-java + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-java + env: + - name: TARGET + value: "Spring Boot Sample v1" + ``` ## Building and deploying the sample @@ -141,56 +142,57 @@ folder) you're ready to build and deploy the sample app. 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-java . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-java . - # Push the container to docker registry - docker push {username}/helloworld-java - ``` + # Push the container to docker registry + docker push {username}/helloworld-java + ``` 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 - ``` + ```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 balancer for your app. - * Automatically scale your pods up and down (including to zero active pods). + + - Create a new immutable revision for this version of the app. + - Network programming to create a route, ingress, service, and load balancer for your app. + - Automatically scale your pods up and down (including to zero active pods). 1. To find the IP address for your service, use. If your cluster is new, it may take sometime for the service to get asssigned an external IP address. - ```shell - kubectl get svc knative-ingressgateway --namespace istio-system + ```shell + 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 - ``` + 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 + ``` 1. To find the URL for your service, use - ```shell - kubectl get ksvc helloworld-java \ - --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + ```shell + kubectl get ksvc helloworld-java \ + --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - NAME DOMAIN - helloworld-java helloworld-java.default.example.com - ``` + NAME DOMAIN + helloworld-java helloworld-java.default.example.com + ``` 1. Now you can make a request to your app to see the result. Replace `{IP_ADDRESS}` with the address you see returned in the previous step. - ```shell - curl -H "Host: helloworld-java.default.example.com" http://{IP_ADDRESS} + ```shell + curl -H "Host: helloworld-java.default.example.com" http://{IP_ADDRESS} - Hello World: Spring Boot Sample v1 - ``` + Hello World: Spring Boot Sample v1 + ``` ## Removing the sample app deployment diff --git a/serving/samples/helloworld-kotlin/README.md b/serving/samples/helloworld-kotlin/README.md index c9cf285af..a3ae86dcf 100644 --- a/serving/samples/helloworld-kotlin/README.md +++ b/serving/samples/helloworld-kotlin/README.md @@ -1,15 +1,15 @@ # Hello World - Kotlin sample A simple web app written in Kotlin using [Ktor](https://ktor.io/) 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. +It reads in an env variable `TARGET` and prints "Hello \${TARGET}". If +TARGET is not specified, it will use "World" as the TARGET. ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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). ## Steps to recreate the sample code @@ -20,38 +20,40 @@ The following instructions recreate the source files from this folder. 1. Create a new directory and cd into it: - ```shell - mkdir hello - cd hello - ``` + ```shell + mkdir hello + cd hello + ``` + 2. Create a file named `Main.kt` at `src/main/kotlin/com/example/hello` and copy the code block below into it: - ```shell - mkdir -p src/main/kotlin/com/example/hello - ``` - - ```kotlin - package com.example.hello + ```shell + mkdir -p src/main/kotlin/com/example/hello + ``` - import io.ktor.application.* - import io.ktor.http.* - import io.ktor.response.* - import io.ktor.routing.* - import io.ktor.server.engine.* - import io.ktor.server.netty.* + ```kotlin + package com.example.hello + + import io.ktor.application.* + import io.ktor.http.* + import io.ktor.response.* + import io.ktor.routing.* + import io.ktor.server.engine.* + import io.ktor.server.netty.* + + fun main(args: Array) { + val target = System.getenv("TARGET") ?: "World" + val port = System.getenv("PORT") ?: "8080" + embeddedServer(Netty, port.toInt()) { + routing { + get("/") { + call.respondText("Hello $target", ContentType.Text.Html) + } + } + }.start(wait = true) + } + ``` - fun main(args: Array) { - val target = System.getenv("TARGET") ?: "World" - val port = System.getenv("PORT") ?: "8080" - embeddedServer(Netty, port.toInt()) { - routing { - get("/") { - call.respondText("Hello $target", ContentType.Text.Html) - } - } - }.start(wait = true) - } - ``` 3. Switch back to `hello` directory 4. Create a new file, `build.gradle` and copy the following setting @@ -77,7 +79,7 @@ The following instructions recreate the source files from this folder. compileKotlin { kotlinOptions.jvmTarget = "1.8" } - + compileTestKotlin { kotlinOptions.jvmTarget = "1.8" } @@ -105,54 +107,54 @@ The following instructions recreate the source files from this folder. 5. Create a file named `Dockerfile` and copy the code block below into it. - ```docker - # Use the official gradle image to create a build artifact. - # https://hub.docker.com/_/gradle - FROM gradle as builder + ```docker + # Use the official gradle image to create a build artifact. + # https://hub.docker.com/_/gradle + FROM gradle as builder - # Copy local code to the container image. - COPY build.gradle . - COPY src ./src + # Copy local code to the container image. + COPY build.gradle . + COPY src ./src - # Build a release artifact. - RUN gradle clean build --no-daemon + # Build a release artifact. + RUN gradle clean build --no-daemon - # Use the Official OpenJDK image for a lean production stage of our multi-stage build. - # https://hub.docker.com/_/openjdk - # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds - FROM openjdk:8-jre-alpine + # Use the Official OpenJDK image for a lean production stage of our multi-stage build. + # https://hub.docker.com/_/openjdk + # https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds + FROM openjdk:8-jre-alpine - # Copy the jar to the production image from the builder stage. - COPY --from=builder /home/gradle/build/libs/gradle.jar /helloworld.jar + # Copy the jar to the production image from the builder stage. + COPY --from=builder /home/gradle/build/libs/gradle.jar /helloworld.jar - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD [ "java", "-jar", "-Djava.security.egd=file:/dev/./urandom", "/helloworld.jar" ] - ``` + # Run the web service on container startup. + CMD [ "java", "-jar", "-Djava.security.egd=file:/dev/./urandom", "/helloworld.jar" ] + ``` 6. 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/v1alpha1 - kind: Service - metadata: - name: helloworld-kotlin - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-kotlin - env: - - name: TARGET - value: "Kotlin Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-kotlin + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-kotlin + env: + - name: TARGET + value: "Kotlin Sample v1" + ``` ## Build and deploy this sample @@ -163,59 +165,64 @@ folder) you're ready to build and deploy the sample app. 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-kotlin . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-kotlin . - # Push the container to docker registry - docker push {username}/helloworld-kotlin - ``` + # Push the container to docker registry + docker push {username}/helloworld-kotlin + ``` 2. 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 - ``` + ```shell + kubectl apply --filename service.yaml + ``` 3. 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). + + - 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). 4. To find the IP address for your service, use `kubectl get service knative-ingressgateway --namespace istio-system` to get the ingress IP for your cluster. If your cluster is new, it may take sometime for the service to get assigned an external IP address. - ```shell - kubectl get service knative-ingressgateway --namespace istio-system - ``` - ```shell - 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 - ``` + ```shell + kubectl get service knative-ingressgateway --namespace istio-system + ``` + + ```shell + 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 + ``` 5. To find the URL for your service, use - ```shell - kubectl get ksvc helloworld-kotlin --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - ``` - ```shell - NAME DOMAIN - helloworld-kotlin helloworld-kotlin.default.example.com - ``` + + ```shell + kubectl get ksvc helloworld-kotlin --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + ``` + + ```shell + NAME DOMAIN + helloworld-kotlin helloworld-kotlin.default.example.com + ``` 6. Now you can make a request to your app to see the result. Replace `{IP_ADDRESS}` with the address you see returned in the previous step. - ```shell - curl -H "Host: helloworld-kotlin.default.example.com" http://{IP_ADDRESS} - ``` - ```shell - Hello Kotlin Sample v1 - ``` + ```shell + curl -H "Host: helloworld-kotlin.default.example.com" http://{IP_ADDRESS} + ``` + + ```shell + Hello Kotlin Sample v1 + ``` ## Remove the sample app deployment diff --git a/serving/samples/helloworld-nodejs/README.md b/serving/samples/helloworld-nodejs/README.md index 762c863bd..5f8cfc96b 100644 --- a/serving/samples/helloworld-nodejs/README.md +++ b/serving/samples/helloworld-nodejs/README.md @@ -1,17 +1,17 @@ # Hello World - Node.js sample A simple web app written in Node.js that you can use for testing. -It reads in an env variable `TARGET` and prints "Hello ${TARGET}!". If +It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not specified, it will use "World" as the TARGET. ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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). -* [Node.js](https://nodejs.org/en/) installed and configured. +- [Node.js](https://nodejs.org/en/) installed and configured. ## Recreating the sample code @@ -23,112 +23,112 @@ recreate the source files from this folder. but change the entry point to `app.js` to be consistent with the sample code here. - ```shell - npm init + ```shell + npm init - package name: (helloworld-nodejs) - version: (1.0.0) - description: - entry point: (index.js) app.js - test command: - git repository: - keywords: - author: - license: (ISC) Apache-2.0 - ``` + package name: (helloworld-nodejs) + version: (1.0.0) + description: + entry point: (index.js) app.js + test command: + git repository: + keywords: + author: + license: (ISC) Apache-2.0 + ``` 1. Install the `express` package: - ```shell - npm install express --save - ``` + ```shell + npm install express --save + ``` 1. Create a new file named `app.js` and paste the following code: - ```js - const express = require('express'); - const app = express(); + ```js + const express = require("express"); + const app = express(); - app.get('/', function (req, res) { - console.log('Hello world received a request.'); + app.get("/", function(req, res) { + console.log("Hello world received a request."); - const target = process.env.TARGET || 'World'; - res.send('Hello ' + target + '!'); - }); + const target = process.env.TARGET || "World"; + res.send("Hello " + target + "!"); + }); - const port = process.env.PORT || 8080; - app.listen(port, function () { - console.log('Hello world listening on port', port); - }); - ``` + const port = process.env.PORT || 8080; + app.listen(port, function() { + console.log("Hello world listening on port", port); + }); + ``` 1. Modify the `package.json` file to add a start command to the scripts section: - ```json - { - "name": "knative-serving-helloworld", - "version": "1.0.0", - "description": "", - "main": "app.js", - "scripts": { - "start": "node app.js" - }, - "author": "", - "license": "Apache-2.0" - } - ``` + ```json + { + "name": "knative-serving-helloworld", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "start": "node app.js" + }, + "author": "", + "license": "Apache-2.0" + } + ``` 1. In your project directory, create a file named `Dockerfile` and copy the code block below into it. For detailed instructions on dockerizing a Node.js app, see [Dockerizing a Node.js web app](https://nodejs.org/en/docs/guides/nodejs-docker-webapp/). - ```Dockerfile - # Use the official Node 8 image. - # https://hub.docker.com/_/node - FROM node:8 + ```Dockerfile + # Use the official Node 8 image. + # https://hub.docker.com/_/node + FROM node:8 - # Create and change to the app directory. - WORKDIR /usr/src/app + # Create and change to the app directory. + WORKDIR /usr/src/app - # Copy application dependency manifests to the container image. - # A wildcard is used to ensure both package.json AND package-lock.json are copied. - # Copying this separately prevents re-running npm install on every code change. - COPY package*.json ./ + # Copy application dependency manifests to the container image. + # A wildcard is used to ensure both package.json AND package-lock.json are copied. + # Copying this separately prevents re-running npm install on every code change. + COPY package*.json ./ - # Install production dependencies. - RUN npm install --only=production + # Install production dependencies. + RUN npm install --only=production - # Copy local code to the container image. - COPY . . + # Copy local code to the container image. + COPY . . - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD [ "npm", "start" ] - ``` + # Run the web service on container startup. + CMD [ "npm", "start" ] + ``` 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/v1alpha1 - kind: Service - metadata: - name: helloworld-nodejs - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-nodejs - env: - - name: TARGET - value: "Node.js Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-nodejs + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-nodejs + env: + - name: TARGET + value: "Node.js Sample v1" + ``` ## Building and deploying the sample @@ -139,55 +139,57 @@ folder) you're ready to build and deploy the sample app. 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-nodejs . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-nodejs . - # Push the container to docker registry - docker push {username}/helloworld-nodejs - ``` + # Push the container to docker registry + docker push {username}/helloworld-nodejs + ``` 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 - ``` + ```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). + + - 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. To find the IP address for your service, use `kubectl get svc knative-ingressgateway --namespace istio-system` to get the ingress IP for your cluster. If your cluster is new, it may take sometime for the service to get asssigned an external IP address. - ```shell - kubectl get svc knative-ingressgateway --namespace istio-system + ```shell + 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 + 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 - ``` + ``` 1. To find the URL for your service, use - ``` - kubectl get ksvc helloworld-nodejs --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - NAME DOMAIN - helloworld-nodejs helloworld-nodejs.default.example.com - ``` + + ``` + kubectl get ksvc helloworld-nodejs --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + NAME DOMAIN + helloworld-nodejs helloworld-nodejs.default.example.com + ``` 1. Now you can make a request to your app to see the result. Replace `{IP_ADDRESS}` with the address you see returned in the previous step. - ```shell - curl -H "Host: helloworld-nodejs.default.example.com" http://{IP_ADDRESS} - Hello Node.js Sample v1! - ``` + ```shell + curl -H "Host: helloworld-nodejs.default.example.com" http://{IP_ADDRESS} + Hello Node.js Sample v1! + ``` ## Removing the sample app deployment diff --git a/serving/samples/helloworld-php/README.md b/serving/samples/helloworld-php/README.md index bad9608a2..48b3e6543 100644 --- a/serving/samples/helloworld-php/README.md +++ b/serving/samples/helloworld-php/README.md @@ -1,15 +1,15 @@ # Hello World - PHP sample A simple web app written in PHP that you can use for testing. -It reads in an env variable `TARGET` and prints "Hello ${TARGET}!". If +It reads in an env variable `TARGET` and prints "Hello \${TARGET}!". If TARGET is not specified, it will use "World" as the TARGET. ## Prerequisites -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* [Docker](https://www.docker.com) installed and running on your local machine, +- [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 @@ -20,58 +20,58 @@ following instructions recreate the source files from this folder. 1. Create a new directory and cd into it: - ````shell - mkdir app - cd app - ```` + ```shell + mkdir app + cd app + ``` 1. Create a file named `index.php` and copy the code block below into it: - ```php - { - match p.parse::() { - Ok(n) => {port = n;}, - Err(_e) => {}, - }; - } - Err(_e) => {}, - }; - let addr = ([0, 0, 0, 0], port).into(); + let mut port: u16 = 8080; + match env::var("PORT") { + Ok(p) => { + match p.parse::() { + Ok(n) => {port = n;}, + Err(_e) => {}, + }; + } + Err(_e) => {}, + }; + let addr = ([0, 0, 0, 0], port).into(); - let new_service = || { - service_fn_ok(|_| { + let new_service = || { + service_fn_ok(|_| { - let mut hello = "Hello ".to_string(); - match env::var("TARGET") { - Ok(target) => {hello.push_str(&target);}, - Err(_e) => {hello.push_str("World")}, - }; + let mut hello = "Hello ".to_string(); + match env::var("TARGET") { + Ok(target) => {hello.push_str(&target);}, + Err(_e) => {hello.push_str("World")}, + }; - Response::new(Body::from(hello)) - }) - }; + Response::new(Body::from(hello)) + }) + }; - let server = Server::bind(&addr) - .serve(new_service) - .map_err(|e| eprintln!("server error: {}", e)); + let server = Server::bind(&addr) + .serve(new_service) + .map_err(|e| eprintln!("server error: {}", e)); - println!("Listening on http://{}", addr); + println!("Listening on http://{}", addr); - rt::run(server); - } - ``` + rt::run(server); + } + ``` 1. In your project directory, create a file named `Dockerfile` and copy the code block below into it. - ```docker - # Use the official Rust image. - # https://hub.docker.com/_/rust - FROM rust:1.27.0 + ```docker + # Use the official Rust image. + # https://hub.docker.com/_/rust + FROM rust:1.27.0 - # Copy local code to the container image. - WORKDIR /usr/src/app - COPY . . + # Copy local code to the container image. + WORKDIR /usr/src/app + COPY . . - # Install production dependencies and build a release artifact. - RUN cargo install + # Install production dependencies and build a release artifact. + RUN cargo install - # Configure and document the service HTTP port. - ENV PORT 8080 - EXPOSE $PORT + # Configure and document the service HTTP port. + ENV PORT 8080 + EXPOSE $PORT - # Run the web service on container startup. - CMD ["hellorust"] - ``` + # Run the web service on container startup. + CMD ["hellorust"] + ``` 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/v1alpha1 - kind: Service - metadata: - name: helloworld-rust - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-rust - env: - - name: TARGET - value: "Rust Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-rust + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-rust + env: + - name: TARGET + value: "Rust Sample v1" + ``` ## Build and deploy this sample @@ -137,55 +137,57 @@ folder) you're ready to build and deploy the sample app. Docker Hub, enter these commands replacing `{username}` with your Docker Hub username: - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-rust . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-rust . - # Push the container to docker registry - docker push {username}/helloworld-rust - ``` + # Push the container to docker registry + docker push {username}/helloworld-rust + ``` 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 - ``` - + ```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). + + - 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. To find the IP address for your service, enter `kubectl get svc knative-ingressgateway --namespace istio-system` to get the ingress IP for your cluster. If your cluster is new, it may take sometime for the service to get asssigned an external IP address. - ```shell - kubectl get svc knative-ingressgateway --namespace istio-system + ```shell + 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 + 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 - ``` + ``` 1. To find the URL for your service, enter: - ``` - kubectl get ksvc helloworld-rust --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain - NAME DOMAIN - helloworld-rust helloworld-rust.default.example.com - ``` + + ``` + kubectl get ksvc helloworld-rust --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain + NAME DOMAIN + helloworld-rust helloworld-rust.default.example.com + ``` 1. Now you can make a request to your app and see the result. Replace `{IP_ADDRESS}` with the address you see returned in the previous step. - ```shell - curl -H "Host: helloworld-rust.default.example.com" http://{IP_ADDRESS} - Hello World! - ``` + ```shell + curl -H "Host: helloworld-rust.default.example.com" http://{IP_ADDRESS} + Hello World! + ``` ## Removing the sample app deployment diff --git a/serving/samples/helloworld-vertx/README.md b/serving/samples/helloworld-vertx/README.md index fbb115153..74e6f73d8 100644 --- a/serving/samples/helloworld-vertx/README.md +++ b/serving/samples/helloworld-vertx/README.md @@ -1,8 +1,8 @@ # Hello World - Eclipse Vert.x sample Learn how to deploy a simple web app that is written in Java and uses Eclipse Vert.x. -This samples uses Docker to build locally. The app reads in a `TARGET` env variable and then -prints "Hello World: ${TARGET}!". If a value for `TARGET` is not specified, +This samples uses Docker to build locally. The app reads in a `TARGET` env variable and then +prints "Hello World: \${TARGET}!". If a value for `TARGET` is not specified, the "NOT SPECIFIED" default value is used. Use this sample to walk you through the steps of creating and modifying the sample app, building and pushing your @@ -12,15 +12,15 @@ container image to a registry, and then deploying your app to your Knative clust You must meet the following requirements to complete this sample: -* A version of the Knative Serving component installed and running on your Kubernetes cluster. Follow the +- A version of the Knative Serving component installed and running on your Kubernetes cluster. Follow the [Knative installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create a Knative cluster. -* The following software downloaded and install on your loacal machine: - * [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). - * [Eclipse Vert.x v3.5.4](https://vertx.io/). - * [Docker](https://www.docker.com) for building and pushing your container image. - * [curl](https://curl.haxx.se/) to test the sample app after deployment. -* A [Docker Hub](https://hub.docker.com/) account where you can push your container image. +- The following software downloaded and install on your loacal machine: + - [Java SE 8 or later JDK](http://www.oracle.com/technetwork/java/javase/downloads/index.html). + - [Eclipse Vert.x v3.5.4](https://vertx.io/). + - [Docker](https://www.docker.com) for building and pushing your container image. + - [curl](https://curl.haxx.se/) to test the sample app after deployment. +- A [Docker Hub](https://hub.docker.com/) account where you can push your container image. **Tip**: You can clone the [Knatve/docs repo](https://github.com/knative/docs) and then modify the source files. Alternatively, learn more by manually creating the files youself. @@ -31,74 +31,74 @@ To create and configure the source files in the root of your working directory: 1. Create the `pom.xml` file: - ```xml - - 4.0.0 - com.example.vertx - helloworld - 1.0.0-SNAPSHOT + ```xml + + 4.0.0 + com.example.vertx + helloworld + 1.0.0-SNAPSHOT - - - io.vertx - vertx-core - ${version.vertx} - - - io.vertx - vertx-rx-java2 - ${version.vertx} - - + + + io.vertx + vertx-core + ${version.vertx} + + + io.vertx + vertx-rx-java2 + ${version.vertx} + + - - - - maven-compiler-plugin - 3.8.0 - - 1.8 - 1.8 - - - - org.apache.maven.plugins - maven-shade-plugin - 3.2.0 - - - package - - shade - - - - - - io.vertx.core.Launcher - com.example.helloworld.HelloWorld - - - - - - - - + + + + maven-compiler-plugin + 3.8.0 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-shade-plugin + 3.2.0 + + + package + + shade + + + + + + io.vertx.core.Launcher + com.example.helloworld.HelloWorld + + + + + + + + - - - - 3.5.4 - - - ``` + + + + 3.5.4 + + + ``` -1. Create the `HelloWorld.java` file in the `src/main/java/com/example/helloworld` directory. The +1. Create the `HelloWorld.java` file in the `src/main/java/com/example/helloworld` directory. The `[ROOT]/src/main/java/com/example/helloworld/HelloWorld.java` file creates a basic web server that listens on port `8080`. ```java @@ -136,33 +136,33 @@ To create and configure the source files in the root of your working directory: 1. Create the `Dockerfile` file: - ```docker - FROM fabric8/s2i-java:2.0 - ENV JAVA_APP_DIR=/deployments - EXPOSE 8080 - COPY target/helloworld-1.0.0-SNAPSHOT.jar /deployments/ - ``` + ```docker + FROM fabric8/s2i-java:2.0 + ENV JAVA_APP_DIR=/deployments + EXPOSE 8080 + COPY target/helloworld-1.0.0-SNAPSHOT.jar /deployments/ + ``` 1. Create the `service.yaml` file. You must specify your Docker Hub username in `{username}`. You can also configure the `TARGET`, for example you can modify the `Eclipse Vert.x Sample v1` value. - ```yaml - apiVersion: serving.knative.dev/v1alpha1 - kind: Service - metadata: - name: helloworld-vertx - namespace: default - spec: - runLatest: - configuration: - revisionTemplate: - spec: - container: - image: docker.io/{username}/helloworld-vertx - env: - - name: TARGET - value: "Eclipse Vert.x Sample v1" - ``` + ```yaml + apiVersion: serving.knative.dev/v1alpha1 + kind: Service + metadata: + name: helloworld-vertx + namespace: default + spec: + runLatest: + configuration: + revisionTemplate: + spec: + container: + image: docker.io/{username}/helloworld-vertx + env: + - name: TARGET + value: "Eclipse Vert.x Sample v1" + ``` ## Building and deploying the sample @@ -171,37 +171,38 @@ To build a container image, push your image to the registry, and then deploy you 1. Use Docker to build your container image and then push that image to your Docker Hub registry. You must replace the `{username}` variables in the following commands with your Docker Hub username. - ```shell - # Build the container on your local machine - docker build -t {username}/helloworld-vertx . + ```shell + # Build the container on your local machine + docker build -t {username}/helloworld-vertx . - # Push the container to docker registry - docker push {username}/helloworld-vertx - ``` + # Push the container to docker registry + docker push {username}/helloworld-vertx + ``` 1. Now that your container image is in the registry, you can deploy it to your Knative cluster by running the `kubectl apply` command: - ```shell - kubectl apply --filename service.yaml - ``` + ```shell + kubectl apply --filename service.yaml + ``` - Result: A service name `helloworld-vertx` is created in your cluster along with the following resources: - * A new immutable revision for the version of the app that you just deployed. - * The following networking resources are created for your app: - * route - * ingress - * service - * load balancer - * Auto scaling is enable to allow your pods to scale up to meet traffic, and also back down to zero when there is no traffic. + Result: A service name `helloworld-vertx` is created in your cluster along with the following resources: + + - A new immutable revision for the version of the app that you just deployed. + - The following networking resources are created for your app: + - route + - ingress + - service + - load balancer + - Auto scaling is enable to allow your pods to scale up to meet traffic, and also back down to zero when there is no traffic. ## Testing the sample app To verify that your sample app has been successfully deployed: -1. View your the ingress IP address of your service by running the following -`kubectl get` command. Note that it may take sometime for the new service to get asssigned -an external IP address, especially if your cluster was newly created. +1. View your the ingress IP address of your service by running the following + `kubectl get` command. Note that it may take sometime for the new service to get asssigned + an external IP address, especially if your cluster was newly created. ```shell kubectl get svc knative-ingressgateway --namespace istio-system @@ -215,6 +216,7 @@ an external IP address, especially if your cluster was newly created. ``` 1. Retrieve the URL for your service, by running the following `kubectl get` command: + ```shell kubectl get services.serving.knative.dev helloworld-vertx --output=custom-columns=NAME:.metadata.name,DOMAIN:.status.domain ``` @@ -229,17 +231,17 @@ an external IP address, especially if your cluster was newly created. 1. Run the following `curl` command to test your deployed sample app. You must replace the `{IP_ADDRESS}` variable the URL that your retrieve in the previous step. - ```shell - curl -H "Host: helloworld-vertx.default.example.com" http://{IP_ADDRESS} + ```shell + curl -H "Host: helloworld-vertx.default.example.com" http://{IP_ADDRESS} ``` Example result: ```shell Hello World: Eclipse Vert.x Sample v1 - ``` + ``` -Congtratualations on deploying your sample Java app to Knative! +Congtratualations on deploying your sample Java app to Knative! ## Removing the sample app deployment diff --git a/serving/samples/knative-routing-go/README.md b/serving/samples/knative-routing-go/README.md index fb8b3c7b4..180e17ad3 100644 --- a/serving/samples/knative-routing-go/README.md +++ b/serving/samples/knative-routing-go/README.md @@ -19,9 +19,10 @@ to the Login service. 2. Install [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment). 3. Acquire a domain name. - In this example, we use `example.com`. If you don't have a domain name, -you can modify your hosts file (on Mac or Linux) to map `example.com` to your -cluster's ingress IP. + you can modify your hosts file (on Mac or Linux) to map `example.com` to your + cluster's ingress IP. 4. Check out the code: + ``` go get -d github.com/knative/docs/serving/samples/knative-routing-go ``` @@ -30,44 +31,52 @@ go get -d github.com/knative/docs/serving/samples/knative-routing-go Build the application container and publish it to a container registry: -1. Move into the sample directory: +1. Move into the sample directory: + ```shell cd $GOPATH/src/github.com/knative/docs ``` -2. Set your preferred container registry: +2. Set your preferred container registry: + ```shell export REPO="gcr.io/" ``` - This example shows how to use Google Container Registry (GCR). You will need a Google Cloud Project and to enable the [Google Container Registry -API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). -3. Use Docker to build your application container: +This example shows how to use Google Container Registry (GCR). You will need a Google Cloud Project and to enable the [Google Container Registry +API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). + +3. Use Docker to build your application container: + ``` docker build \ --tag "${REPO}/serving/samples/knative-routing-go" \ --file=serving/samples/knative-routing-go/Dockerfile . ``` -4. Push your container to a container registry: -``` +4. Push your container to a container registry: + +``` docker push "${REPO}/serving/samples/knative-routing-go" ``` -5. Replace the image reference path with our published image path in the configuration file `serving/samples/knative-routing-go/sample.yaml`: - * Manually replace: - `image: github.com/knative/docs/serving/samples/knative-routing-go` with `image: /serving/samples/knative-routing-go` +5. Replace the image reference path with our published image path in the configuration file `serving/samples/knative-routing-go/sample.yaml`: - Or + - Manually replace: + `image: github.com/knative/docs/serving/samples/knative-routing-go` with `image: /serving/samples/knative-routing-go` - * Run this command: - ``` - perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/knative-routing-go/sample.yaml - ``` + Or + + - Run this command: + + ``` + perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/knative-routing-go/sample.yaml + ``` ## Deploy the Service Deploy the Knative Serving sample: + ``` kubectl apply --filename serving/samples/knative-routing-go/sample.yaml ``` @@ -78,43 +87,51 @@ A shared Gateway "knative-shared-gateway" is used within Knative service mesh for serving all incoming traffic. You can inspect it and its corresponding Kubernetes service with: -* Check the shared Gateway: +- Check the shared Gateway: + ``` kubectl get Gateway --namespace knative-serving --output yaml ``` -* Check the corresponding Kubernetes service for the shared Gateway: +- Check the corresponding Kubernetes service for the shared Gateway: + ``` kubectl get svc knative-ingressgateway --namespace istio-system --output yaml ``` -* Inspect the deployed Knative services with: +- Inspect the deployed Knative services with: + ``` kubectl get ksvc ``` + You should see 2 Knative services: `search-service` and `login-service`. -### Access the Services +### Access the Services + +1. Find the shared Gateway IP and export as an environment variable: -1. Find the shared Gateway IP and export as an environment variable: ```shell export GATEWAY_IP=`kubectl get svc knative-ingressgateway --namespace istio-system \ --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` ``` -2. Find the `Search` service route and export as an environment variable: +2. Find the `Search` service route and export as an environment variable: + ```shell export SERVICE_HOST=`kubectl get route search-service --output jsonpath="{.status.domain}"` ``` -3. Make a curl request to the service: +3. Make a curl request to the service: + ```shell curl http://${GATEWAY_IP} --header "Host:${SERVICE_HOST}" ``` You should see: `Search Service is called !` -4. Similarly, you can also directly access "Login" service with: +4. Similarly, you can also directly access "Login" service with: + ```shell export SERVICE_HOST=`kubectl get route login-service --output jsonpath="{.status.domain}"` ``` @@ -127,34 +144,36 @@ You should see: `Login Service is called !` ## Apply Custom Routing Rule -1. Apply the custom routing rules defined in `routing.yaml` file with: +1. Apply the custom routing rules defined in `routing.yaml` file with: + ``` kubectl apply --filename serving/samples/knative-routing-go/routing.yaml ``` 2. The `routing.yaml` file will generate a new VirtualService `entry-route` for -domain `example.com`. View the VirtualService: + domain `example.com`. View the VirtualService: + ``` kubectl get VirtualService entry-route --output yaml ``` -3. Send a request to the `Search` service and the `Login` service by using -corresponding URIs. You should get the same results as directly accessing these services. - * Get the ingress IP: - ```shell +3. Send a request to the `Search` service and the `Login` service by using + corresponding URIs. You should get the same results as directly accessing these services. + _ Get the ingress IP: + ```shell export GATEWAY_IP=`kubectl get svc knative-ingressgateway --namespace istio-system \ - --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}"` + --output jsonpath="{.status.loadBalancer.ingress[_]['ip']}"` ``` - * Send a request to the Search service: - ```shell - curl http://${GATEWAY_IP}/search --header "Host:example.com" - ``` + * Send a request to the Search service: + ```shell + curl http://${GATEWAY_IP}/search --header "Host:example.com" + ``` - * Send a request to the Login service: - ```shell - curl http://${GATEWAY_IP}/login --header "Host:example.com" - ``` + * Send a request to the Login service: + ```shell + curl http://${GATEWAY_IP}/login --header "Host:example.com" + ``` ## How It Works @@ -169,10 +188,10 @@ Gateway again. The Gateway proxy checks the updated host, and forwards it to ![Object model](images/knative-routing-sample-flow.png) - ## Clean Up To clean up the sample resources: + ``` kubectl delete --filename serving/samples/knative-routing-go/sample.yaml kubectl delete --filename serving/samples/knative-routing-go/routing.yaml diff --git a/serving/samples/rest-api-go/README.md b/serving/samples/rest-api-go/README.md index 15347952f..1a6d60e0f 100644 --- a/serving/samples/rest-api-go/README.md +++ b/serving/samples/rest-api-go/README.md @@ -8,6 +8,7 @@ This sample demonstrates creating a simple RESTful service. The exposed endpoint 2. Install [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment). 3. You need to [configure outbound network access](https://github.com/knative/docs/blob/master/serving/outbound-network-access.md) because this application makes an external API request. 4. Check out the code: + ``` go get -d github.com/knative/docs/serving/samples/rest-api-go ``` @@ -16,44 +17,52 @@ go get -d github.com/knative/docs/serving/samples/rest-api-go Build the application container and publish it to a container registry: -1. Move into the sample directory: +1. Move into the sample directory: + ``` cd $GOPATH/src/github.com/knative/docs ``` -2. Set your preferred container registry: +2. Set your preferred container registry: + ``` export REPO="gcr.io/" ``` - To run the sample, you need to have a Google Cloud Platform project, and you also need to enable the [Google Container Registry -API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). -3. Use Docker to build your application container: +To run the sample, you need to have a Google Cloud Platform project, and you also need to enable the [Google Container Registry +API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). + +3. Use Docker to build your application container: + ``` docker build \ --tag "${REPO}/serving/samples/rest-api-go" \ --file serving/samples/rest-api-go/Dockerfile . ``` -4. Push your container to a container registry: -``` +4. Push your container to a container registry: + +``` docker push "${REPO}/serving/samples/rest-api-go" ``` -5. Replace the image reference path with our published image path in the configuration files (`serving/samples/rest-api-go/sample.yaml`: - * Manually replace: - `image: github.com/knative/docs/serving/samples/rest-api-go` with `image: /serving/samples/rest-api-go` +5. Replace the image reference path with our published image path in the configuration files (`serving/samples/rest-api-go/sample.yaml`: - Or + - Manually replace: + `image: github.com/knative/docs/serving/samples/rest-api-go` with `image: /serving/samples/rest-api-go` - * Use run this command: - ``` - perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/rest-api-go/sample.yaml - ``` + Or + + - Use run this command: + + ``` + perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/rest-api-go/sample.yaml + ``` ## Deploy the Configuration Deploy the Knative Serving sample: + ``` kubectl apply --filename serving/samples/rest-api-go/sample.yaml ``` @@ -62,17 +71,20 @@ kubectl apply --filename serving/samples/rest-api-go/sample.yaml Inspect the created resources with the `kubectl` commands: -* View the created Route resource: +- View the created Route resource: + ``` kubectl get route --output yaml ``` -* View the created Configuration resource: +- View the created Configuration resource: + ``` kubectl get configurations --output yaml ``` -* View the Revision that was created by our Configuration: +- View the Revision that was created by our Configuration: + ``` kubectl get revisions --output yaml ``` @@ -82,55 +94,65 @@ kubectl get revisions --output yaml To access this service via `curl`, you need to determine its ingress address. 1. To determine if your service is ready: - ``` - kubectl get svc knative-ingressgateway --namespace istio-system --watch - ``` - When the service is ready, you'll see an IP address in the `EXTERNAL-IP` field: +``` +kubectl get svc knative-ingressgateway --namespace istio-system --watch +``` - ``` - 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 - ``` +When the service is ready, you'll see an IP address in the `EXTERNAL-IP` field: + +``` +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 +``` 2. When the service is ready, export the ingress hostname and IP as environment variables: - ``` - export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"` - 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), +``` +export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"` +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}') - ``` + +``` +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}') +``` 3. Now use `curl` to make a request to the service: - * Make a request to the index endpoint: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP} - ``` - Response body: `Welcome to the stock app!` - * Make a request to the `/stock` endpoint: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock - ``` - Response body: `stock ticker not found!, require /stock/{ticker}` +- Make a request to the index endpoint: - * Make a request to the `/stock` endpoint with a `ticker` parameter: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock/ - ``` - Response body: `stock price for ticker is ` +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP} +``` +Response body: `Welcome to the stock app!` + +- Make a request to the `/stock` endpoint: + +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock +``` + +Response body: `stock ticker not found!, require /stock/{ticker}` + +- Make a request to the `/stock` endpoint with a `ticker` parameter: + +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/stock/ +``` + +Response body: `stock price for ticker is ` ## Clean Up To clean up the sample service: + ``` kubectl delete --filename serving/samples/rest-api-go/sample.yaml ``` diff --git a/serving/samples/source-to-url-go/README.md b/serving/samples/source-to-url-go/README.md index 6be54ea56..d1278c266 100644 --- a/serving/samples/source-to-url-go/README.md +++ b/serving/samples/source-to-url-go/README.md @@ -1,4 +1,4 @@ -# Orchestrating a source-to-URL deployment on Kubernetes +# Orchestrating a source-to-URL deployment on Kubernetes 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. @@ -10,10 +10,10 @@ components of Knative to orchestrate an end-to-end deployment. You need: -* A Kubernetes cluster with Knative installed. Follow the +- A Kubernetes cluster with Knative installed. Follow the [installation instructions](https://github.com/knative/docs/blob/master/install/README.md) if you need to create one. -* Go installed and configured. This is optional, and only required if you want to run the sample app +- Go installed and configured. This is optional, and only required if you want to run the sample app locally. ## Configuring Knative @@ -33,7 +33,7 @@ kubectl apply --filename https://raw.githubusercontent.com/knative/build-templat ### Register secrets for Docker Hub -In order to push the container that is built from source to Docker Hub, register a secret in +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](https://github.com/knative/docs/blob/master/build/auth.md#basic-authentication-docker) @@ -74,15 +74,14 @@ available, but these are the key steps: 1. Create a new `Service Account` manifest which is used to link the build process to the secret. Save this file as `service-account.yaml`: - - ```yaml - apiVersion: v1 - kind: ServiceAccount - metadata: - name: build-bot - secrets: - - name: basic-user-pass - ``` +```yaml +apiVersion: v1 +kind: ServiceAccount +metadata: + name: build-bot +secrets: + - name: basic-user-pass +``` 1. After you have created the manifest files, apply them to your cluster with `kubectl`: @@ -93,7 +92,6 @@ available, but these are the key steps: serviceaccount "build-bot" created ``` - ## Deploying the sample Now that you've configured your cluster accordingly, you are ready to deploy the @@ -130,16 +128,16 @@ container for the application. template: name: kaniko arguments: - - name: IMAGE - value: docker.io/{DOCKER_USERNAME}/app-from-source:latest + - name: IMAGE + value: docker.io/{DOCKER_USERNAME}/app-from-source:latest revisionTemplate: spec: container: - image: docker.io/{DOCKER_USERNAME}/app-from-source:latest + image: docker.io/{DOCKER_USERNAME}/app-from-source:latest imagePullPolicy: Always env: - - name: SIMPLE_MSG - value: "Hello from the sample app!" + - name: SIMPLE_MSG + value: "Hello from the sample app!" ``` 1. Apply this manifest using `kubectl`, and watch the results: @@ -167,7 +165,7 @@ container for the application. 1. 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! -1. To check on the state of the service, get the service object and examine the +1. To check on the state of the service, get the service object and examine the status block: ```shell @@ -196,38 +194,39 @@ container for the application. ``` 1. 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). -1. To get the ingress IP for your cluster, use the following command. If your cluster is new, + - 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). + +1. 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: - ```shell - $ kubectl get svc knative-ingressgateway --namespace istio-system + ```shell + $ 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 + 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 - ``` + ``` 1. To find the URL for your service, type: - ```shell - $ 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 - ``` + ```shell + $ 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 + ``` 1. 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: - ```shell - curl -H "Host: app-from-source.default.example.com" http://{IP_ADDRESS} - Hello from the sample app!" - ``` + ```shell + curl -H "Host: app-from-source.default.example.com" http://{IP_ADDRESS} + Hello from the sample app!" + ``` ## Removing the sample app deployment diff --git a/serving/samples/telemetry-go/README.md b/serving/samples/telemetry-go/README.md index f5df17c11..12c91f718 100644 --- a/serving/samples/telemetry-go/README.md +++ b/serving/samples/telemetry-go/README.md @@ -10,14 +10,18 @@ using the default installation. ## Prerequisites 1. A Kubernetes cluster with [Knative Serving](https://github.com/knative/docs/blob/master/install/README.md) -installed. + installed. 2. Check if Knative monitoring components are installed: + ``` kubectl get pods --namespace knative-monitoring ``` - * If pods aren't found, install [Knative monitoring component](../../installing-logging-metrics-traces.md). + +- If pods aren't found, install [Knative monitoring component](../../installing-logging-metrics-traces.md). + 3. Install [Docker](https://docs.docker.com/get-started/#prepare-your-docker-environment). 4. Check out the code: + ``` go get -d github.com/knative/docs/serving/samples/telemetry-go ``` @@ -26,47 +30,57 @@ go get -d github.com/knative/docs/serving/samples/telemetry-go Build the application container and publish it to a container registry: -1. Move into the sample directory: +1. Move into the sample directory: + ``` cd $GOPATH/src/github.com/knative/docs ``` -2. Set your preferred container registry: +2. Set your preferred container registry: + ``` export REPO="gcr.io/" ``` - This example shows how to use Google Container Registry (GCR). You will need - a Google Cloud Project and to enable the [Google Container Registry -API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). -3. Use Docker to build your application container: +This example shows how to use Google Container Registry (GCR). You will need +a Google Cloud Project and to enable the [Google Container Registry +API](https://console.cloud.google.com/apis/library/containerregistry.googleapis.com). + +3. Use Docker to build your application container: + ``` docker build \ --tag "${REPO}/serving/samples/telemetry-go" \ --file=serving/samples/telemetry-go/Dockerfile . ``` -4. Push your container to a container registry: -``` +4. Push your container to a container registry: + +``` docker push "${REPO}/serving/samples/telemetry-go" ``` -5. Replace the image reference path with our published image path in the -configuration file (`serving/samples/telemetry-go/sample.yaml`): - * Manually replace: - `image: github.com/knative/docs/serving/samples/telemetry-go` with - `image: /serving/samples/telemetry-go` +5. Replace the image reference path with our published image path in the + configuration file (`serving/samples/telemetry-go/sample.yaml`): - Or + - Manually replace: + `image: github.com/knative/docs/serving/samples/telemetry-go` with + `image: /serving/samples/telemetry-go` - * Use run this command: - ``` - perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/telemetry-go/sample.yaml - ``` + + Or + + - Use run this command: + + + ``` + perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/telemetry-go/sample.yaml + ``` ## Deploy the Service Deploy this application to Knative Serving: + ``` kubectl apply --filename serving/samples/telemetry-go/ ``` @@ -75,81 +89,97 @@ kubectl apply --filename serving/samples/telemetry-go/ Inspect the created resources with the `kubectl` commands: - * View the created Route resource: - ``` - kubectl get route --output yaml - ``` +- View the created Route resource: - * View the created Configuration resource: - ``` - kubectl get configurations --output yaml - ``` +``` +kubectl get route --output yaml +``` - * View the Revision that was created by the Configuration: - ``` - kubectl get revisions --output yaml - ``` +- View the created Configuration resource: + +``` +kubectl get configurations --output yaml +``` + +- View the Revision that was created by the Configuration: + +``` +kubectl get revisions --output yaml +``` ## Access the Service To access this service via `curl`, you need to determine its ingress address. 1. To determine if your service is ready: - Check the status of your Knative gateway: - ``` - kubectl get svc knative-ingressgateway --namespace istio-system --watch - ``` + Check the status of your Knative gateway: - When the service is ready, you'll see an IP address in the `EXTERNAL-IP` field: - ``` - 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 - ``` - CTRL+C to end watch. +``` +kubectl get svc knative-ingressgateway --namespace istio-system --watch +``` - Check the status of your route: - ``` - kubectl get route --output yaml - ``` - When the route is ready, you'll see the following fields reported as: - ```YAML - status: - conditions: - ... - status: "True" - type: Ready - domain: telemetrysample-route.default.example.com - ``` +When the service is ready, you'll see an IP address in the `EXTERNAL-IP` field: + +``` +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 +``` + +CTRL+C to end watch. + +Check the status of your route: + +``` +kubectl get route --output yaml +``` + +When the route is ready, you'll see the following fields reported as: + +```YAML +status: + conditions: + ... + status: "True" + type: Ready + domain: telemetrysample-route.default.example.com +``` 2. Export the ingress hostname and IP as environment -variables: + variables: + ``` export SERVICE_HOST=`kubectl get route telemetrysample-route --output jsonpath="{.status.domain}"` export SERVICE_IP=`kubectl get svc knative-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.ingress[*].ip}"` ``` 3. Make a request to the service to see the `Hello World!` message: + ``` curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP} ``` 4. Make a request to the `/log` endpoint to generate logs to the `stdout` file -and generate files under `/var/log` in both `JSON` and plain text formats: + and generate files under `/var/log` in both `JSON` and plain text formats: + ``` curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/log ``` ## Access Logs + You can access to the logs from Kibana UI - see [Logs](../../accessing-logs.md) for more information. ## Access per Request Traces + You can access to per request traces from Zipkin UI - see [Traces](../../accessing-traces.md) for more information. ## Accessing Custom Metrics + You can see published metrics using Prometheus UI. To access to the UI, forward the Prometheus server to your machine: + ``` kubectl port-forward $(kubectl get pods --selector=app=prometheus,prometheus=test --output=jsonpath="{.items[0].metadata.name}") 9090 ``` @@ -159,6 +189,7 @@ Then browse to http://localhost:9090. ## Clean up To clean up the sample service: + ``` kubectl delete --filename serving/samples/telemetry-go/ ``` diff --git a/serving/samples/thumbnailer-go/README.md b/serving/samples/thumbnailer-go/README.md index 22a08394c..ea1db8cb6 100644 --- a/serving/samples/thumbnailer-go/README.md +++ b/serving/samples/thumbnailer-go/README.md @@ -7,11 +7,12 @@ generates its thumbnail image using the `ffmpeg` framework. ## Before you begin -* [Install Knative Serving](../../../install/README.md) +- [Install Knative Serving](../../../install/README.md) If you want to test and run the app locally: -* [Install Go](https://golang.org/doc/install) -* [Download `ffmpeg`](https://www.ffmpeg.org/download.html) + +- [Install Go](https://golang.org/doc/install) +- [Download `ffmpeg`](https://www.ffmpeg.org/download.html) ## Sample code @@ -114,7 +115,6 @@ kubectl apply --filename https://raw.githubusercontent.com/knative/build-templat kubectl apply --filename sample.yaml ``` - Now, if you look at the `status` of the revision, you will see that a build is in progress: ```shell @@ -134,7 +134,6 @@ items: Once `BuildComplete` has a `status: "True"`, the revision will be deployed. - ## Using the app To confirm that the app deployed, you can check for the Knative Serving service using `kubectl`. diff --git a/serving/samples/traffic-splitting/README.md b/serving/samples/traffic-splitting/README.md index 0e662bc46..88f5c819e 100644 --- a/serving/samples/traffic-splitting/README.md +++ b/serving/samples/traffic-splitting/README.md @@ -11,62 +11,75 @@ to illustrate applying a revision, then using that revision for manual traffic s This section describes how to create an revision by deploying a new configuration. -1. Replace the image reference path with our published image path in the configuration files (`serving/samples/traffic-splitting/updated_configuration.yaml`: - * Manually replace: - `image: github.com/knative/docs/serving/samples/rest-api-go` with `image: /serving/samples/rest-api-go` +1. Replace the image reference path with our published image path in the configuration files (`serving/samples/traffic-splitting/updated_configuration.yaml`: - Or + - Manually replace: + `image: github.com/knative/docs/serving/samples/rest-api-go` with `image: /serving/samples/rest-api-go` - * Use run this command: - ``` - perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/rest-api-go/updated_configuration.yaml - ``` + Or + + - Use run this command: + + ``` + perl -pi -e "s@github.com/knative/docs@${REPO}@g" serving/samples/rest-api-go/updated_configuration.yaml + ``` 2. Deploy the new configuration to update the `RESOURCE` environment variable -from `stock` to `share`: + from `stock` to `share`: + ``` kubectl apply --filename serving/samples/traffic-splitting/updated_configuration.yaml ``` 3. Once deployed, traffic will shift to the new revision automatically. Verify the deployment by checking the route status: + ``` kubectl get route --output yaml ``` 4. When the new route is ready, you can access the new endpoints: - The hostname and IP address can be found in the same manner as the [Creating a RESTful Service](../rest-api-go) sample: - ``` - export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"` - export SERVICE_IP=`kubectl get svc knative-ingressgateway --namespace istio-system \ - --output jsonpath="{.status.loadBalancer.ingress[*].ip}"` - ``` + The hostname and IP address can be found in the same manner as the [Creating a RESTful Service](../rest-api-go) sample: - * Make a request to the index endpoint: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP} - ``` - Response body: `Welcome to the share app!` +``` +export SERVICE_HOST=`kubectl get route stock-route-example --output jsonpath="{.status.domain}"` +export SERVICE_IP=`kubectl get svc knative-ingressgateway --namespace istio-system \ +--output jsonpath="{.status.loadBalancer.ingress[*].ip}"` +``` - * Make a request to the `/share` endpoint: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share - ``` - Response body: `share ticker not found!, require /share/{ticker}` +- Make a request to the index endpoint: - * Make a request to the `/share` endpoint with a `ticker` parameter: - ``` - curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share/ - ``` - Response body: `share price for ticker is ` +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP} +``` + +Response body: `Welcome to the share app!` + +- Make a request to the `/share` endpoint: + +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share +``` + +Response body: `share ticker not found!, require /share/{ticker}` + +- Make a request to the `/share` endpoint with a `ticker` parameter: + +``` +curl --header "Host:$SERVICE_HOST" http://${SERVICE_IP}/share/ +``` + +Response body: `share price for ticker is ` ## Manual Traffic Splitting This section describes how to manually split traffic to specific revisions. 1. Get your revisions names via: + ``` kubectl get revisions ``` + ``` NAME AGE stock-configuration-example-00001 11m @@ -74,6 +87,7 @@ stock-configuration-example-00002 4m ``` 2. Update the `traffic` list in `serving/samples/rest-api-go/sample.yaml` as: + ```yaml traffic: - revisionName: @@ -83,14 +97,17 @@ traffic: ``` 3. Deploy your traffic revision: + ``` kubectl apply --filename serving/samples/rest-api-go/sample.yaml ``` 4. Verify the deployment by checking the route status: + ``` kubectl get route --output yaml ``` + Once updated, you can make `curl` requests to the API using either `stock` or `share` endpoints. diff --git a/serving/setting-up-a-logging-plugin.md b/serving/setting-up-a-logging-plugin.md index 0de828660..76219f7be 100644 --- a/serving/setting-up-a-logging-plugin.md +++ b/serving/setting-up-a-logging-plugin.md @@ -41,7 +41,7 @@ collecting log files under `/var/log`. An is in process to get rid of the sidecar. The steps to configure are: 1. Replace `logging.fluentd-sidecar-output-config` flag in - [config-observability](https://github.com/knative/serving/blob/master/config/config-observability.yaml) with the + [config-observability](https://github.com/knative/serving/blob/master/config/config-observability.yaml) with the desired output configuration. **NOTE**: The Fluentd DaemonSet is in `monitoring` namespace while the Fluentd sidecar is in the namespace same with the app. There may be small differences between the configuration for DaemonSet diff --git a/serving/using-a-custom-domain.md b/serving/using-a-custom-domain.md index a467b4873..99afdca14 100644 --- a/serving/using-a-custom-domain.md +++ b/serving/using-a-custom-domain.md @@ -14,7 +14,7 @@ To change the {default-domain} value there are a few steps involved: kubectl edit cm config-domain --namespace knative-serving ``` - This command opens your default text editor and allows you to edit the config map. + This command opens your default text editor and allows you to edit the config map. ```yaml apiVersion: v1 @@ -25,7 +25,7 @@ To change the {default-domain} value there are a few steps involved: ``` 1. Edit the file to replace `example.com` with the domain you'd like to use and save your changes. - In this example, we configure `mydomain.com` for all routes: + In this example, we configure `mydomain.com` for all routes: ```yaml apiVersion: v1 @@ -43,29 +43,29 @@ You can also apply an updated domain configuration: replacing the `example.org` and `example.com` values with the new domain you want to use: - ```yaml - apiVersion: v1 - kind: ConfigMap - metadata: - name: config-domain - namespace: knative-serving - data: - # These are example settings of domain. - # example.org will be used for routes having app=prod. - example.org: | - selector: - app: prod - # Default value for domain, for routes that does not have app=prod labels. - # Although it will match all routes, it is the least-specific rule so it - # will only be used if no other domain matches. - example.com: "" - ``` + ```yaml + apiVersion: v1 + kind: ConfigMap + metadata: + name: config-domain + namespace: knative-serving + data: + # These are example settings of domain. + # example.org will be used for routes having app=prod. + example.org: | + selector: + app: prod + # Default value for domain, for routes that does not have app=prod labels. + # Although it will match all routes, it is the least-specific rule so it + # will only be used if no other domain matches. + example.com: "" + ``` 1. Apply updated domain configuration to your cluster: - ```shell - kubectl apply --filename config-domain.yaml - ``` + ```shell + kubectl apply --filename config-domain.yaml + ``` ## Deploy an application @@ -73,23 +73,25 @@ You can also apply an updated domain configuration: > the configuration map and automatically update the host name for all of the deployed > services and routes. - -Deploy an app (for example, [`helloworld-go`](./samples/helloworld-go/README.md)), to -your cluster as normal. You can check the customized domain in Knative Route "helloworld-go" with +Deploy an app (for example, [`helloworld-go`](./samples/helloworld-go/README.md)), to +your cluster as normal. You can check the customized domain in Knative Route "helloworld-go" with the following command: + ```shell kubectl get route helloworld-go --output jsonpath="{.status.domain}" ``` + You should see the full customized domain: `helloworld-go.default.mydomain.com`. And you can check the IP address of your Knative gateway by running: + ```shell kubectl get svc knative-ingressgateway --namespace istio-system --output jsonpath="{.status.loadBalancer.ingress[*]['ip']}" ``` ## Local DNS setup -You can map the domain to the IP address of your Knative gateway in your local +You can map the domain to the IP address of your Knative gateway in your local machine with: ```shell @@ -103,6 +105,7 @@ export DOMAIN_NAME=`kubectl get route helloworld-go --output jsonpath="{.status. echo -e "$GATEWAY_IP\t$DOMAIN_NAME" | sudo tee -a /etc/hosts ``` + You can now access your domain from the browser in your machine and do some quick checks. ## Publish your Domain @@ -111,36 +114,35 @@ Follow these steps to make your domain publicly accessible: ### Set static IP for Knative Gateway -You might want to [set a static IP for your Knative gateway](gke-assigning-static-ip-address.md), +You might want to [set a static IP for your Knative gateway](gke-assigning-static-ip-address.md), so that the gateway IP does not change each time your cluster is restarted. ### Update your DNS records -To publish your domain, you need to update your DNS provider to point to the +To publish your domain, you need to update your DNS provider to point to the IP address for your service ingress. -* Create a [wildcard record](https://support.google.com/domains/answer/4633759) - for the namespace and custom domain to the ingress IP Address, which would enable - hostnames for multiple services in the same namespace to work without creating +- Create a [wildcard record](https://support.google.com/domains/answer/4633759) + for the namespace and custom domain to the ingress IP Address, which would enable + hostnames for multiple services in the same namespace to work without creating additional DNS entries. - ```dns - *.default.mydomain.com 59 IN A 35.237.28.44 - ``` + ```dns + *.default.mydomain.com 59 IN A 35.237.28.44 + ``` -* Create an A record to point from the fully qualified domain name to the IP - address of your Knative gateway. This step needs to be done for each Knative Service or +- Create an A record to point from the fully qualified domain name to the IP + address of your Knative gateway. This step needs to be done for each Knative Service or Route created. - - ```dns - helloworld-go.default.mydomain.com 59 IN A 35.237.28.44 - ``` + + ```dns + helloworld-go.default.mydomain.com 59 IN A 35.237.28.44 + ``` If you are using Google Cloud DNS, you can find step-by-step instructions in the [Cloud DNS quickstart](https://cloud.google.com/dns/quickstart). - -Once the domain update has propagated, you can access your app using +Once the domain update has propagated, you can access your app using the fully qualified domain name of the deployed route, for example `http://helloworld-go.default.mydomain.com` diff --git a/serving/using-an-ssl-cert.md b/serving/using-an-ssl-cert.md index a53df42e8..deb0ef338 100644 --- a/serving/using-an-ssl-cert.md +++ b/serving/using-an-ssl-cert.md @@ -52,22 +52,22 @@ spec: selector: knative: ingressgateway servers: - - hosts: - - '*' - port: - name: http - number: 80 - protocol: HTTP - - hosts: - - '*' - port: - name: https - number: 443 - protocol: HTTPS - tls: - mode: SIMPLE - privateKey: /etc/istio/ingressgateway-certs/tls.key - serverCertificate: /etc/istio/ingressgateway-certs/tls.crt + - hosts: + - "*" + port: + name: http + number: 80 + protocol: HTTP + - hosts: + - "*" + port: + name: https + number: 443 + protocol: HTTPS + tls: + mode: SIMPLE + privateKey: /etc/istio/ingressgateway-certs/tls.key + serverCertificate: /etc/istio/ingressgateway-certs/tls.crt ``` Once the change has been made, you can now use the HTTPS protocol to access @@ -88,9 +88,9 @@ Encrypt][le] to obtain a certificate manually. 1. Use the certbot to request a certificate, using DNS validation. The certbot tool will walk you through validating your domain ownership by creating TXT records in your domain. - ```shell - ./certbot-auto certonly --manual --preferred-challenges dns -d '*.default.yourdomain.com' - ``` + ```shell + ./certbot-auto certonly --manual --preferred-challenges dns -d '*.default.yourdomain.com' + ``` 1. When certbot is complete, you will have two output files, `privkey.pem` and `fullchain.pem`. These files map to the `cert.pk` and `cert.pem` files used above. @@ -107,20 +107,20 @@ To install cert-manager into your cluster, use kubectl to apply the cert-manager ``` kubectl apply --filename https://raw.githubusercontent.com/jetstack/cert-manager/release-0.5/contrib/manifests/cert-manager/with-rbac.yaml ``` + or see the [cert-manager docs](https://cert-manager.readthedocs.io/en/latest/getting-started/) for more ways to install and customize. ### Configure cert-manager for your DNS provider -Once you have installed cert-manager, you'll need to configure it for your DNS -hosting provider. +Once you have installed cert-manager, you'll need to configure it for your DNS +hosting provider. Knative currently only works with the `DNS01` challenge type for LetsEncrypt, which is only supported by a [small number of DNS providers through cert-manager](http://docs.cert-manager.io/en/latest/reference/issuers/acme/dns01.html?highlight=DNS#supported-dns01-providers). Instructions for configuring cert-manager are provided for the following DNS hosts: -* [Google Cloud DNS](using-cert-manager-on-gcp.md) - +- [Google Cloud DNS](using-cert-manager-on-gcp.md) --- diff --git a/serving/using-cert-manager-on-gcp.md b/serving/using-cert-manager-on-gcp.md index 66605351d..8de29f218 100644 --- a/serving/using-cert-manager-on-gcp.md +++ b/serving/using-cert-manager-on-gcp.md @@ -12,6 +12,7 @@ to their zone to prove ownership. Other challenge types are not currently suppor Knative. ## Creating a Cloud DNS service account + To add the TXT record, configure Knative with a service account that can be used by cert-manager to create and update the DNS record. @@ -57,7 +58,7 @@ rm ~/key.json ## Configuring CertManager to use your DNS admin service account -Next, configure cert-manager to request new certificates and +Next, configure cert-manager to request new certificates and verify the challenges using DNS. ### Specifying a certificate issuer @@ -105,24 +106,24 @@ To check if your ClusterIssuer is valid, enter: kubectl get clusterissuer --namespace cert-manager letsencrypt-issuer --output yaml ``` -Then confirm that its conditions have `Ready=True`. For example: +Then confirm that its conditions have `Ready=True`. For example: ```yaml status: acme: uri: https://acme-v02.api.letsencrypt.org/acme/acct/40759665 conditions: - - lastTransitionTime: 2018-08-23T01:44:54Z - message: The ACME account was registered with the ACME server - reason: ACMEAccountRegistered - status: "True" - type: Ready + - lastTransitionTime: 2018-08-23T01:44:54Z + message: The ACME account was registered with the ACME server + reason: ACMEAccountRegistered + status: "True" + type: Ready ``` ### Specifying the certificate Next, configure which certificate issuer to use -and which secret you will publish the certificate into. Use the Secret `istio-ingressgateway-certs`. +and which secret you will publish the certificate into. Use the Secret `istio-ingressgateway-certs`. The following steps will overwrite this Secret if it already exists. ```shell @@ -173,23 +174,25 @@ To check that your certificate setting is valid, enter: kubectl get certificate --namespace istio-system my-certificate --output yaml ``` -Verify that its `Status.Conditions` have `Ready=True`. For example: +Verify that its `Status.Conditions` have `Ready=True`. For example: + ```yaml status: acme: order: url: https://acme-v02.api.letsencrypt.org/acme/order/40759665/45358362 conditions: - - lastTransitionTime: 2018-08-23T02:28:44Z - message: Certificate issued successfully - reason: CertIssued - status: "True" - type: Ready + - lastTransitionTime: 2018-08-23T02:28:44Z + message: Certificate issued successfully + reason: CertIssued + status: "True" + type: Ready ``` + A condition with `Ready=False` is a failure to obtain certificate, and such condition usually has an error message to indicate the reason of failure. -### Configuring the gateway +### Configuring the gateway In the last step, configure the knative-shared-gateway to use the certificate that is generated and stored automatically by cert-manager. @@ -230,4 +233,3 @@ EOF Now you can access your services via HTTPS; cert-manager will keep your certificates up-to-date, replacing them before the certificate expires. - diff --git a/serving/using-external-dns.md b/serving/using-external-dns.md index fe5d674fc..d5ceba24f 100644 --- a/serving/using-external-dns.md +++ b/serving/using-external-dns.md @@ -1,6 +1,6 @@ # Using ExternalDNS to automate DNS setup -[ExternalDNS](https://github.com/kubernetes-incubator/external-dns) is a tool +[ExternalDNS](https://github.com/kubernetes-incubator/external-dns) is a tool that synchronizes exposed Kubernetes Services and Ingresses with DNS providers. This doc explains how to set up ExternalDNS within a Knative cluster using @@ -18,11 +18,14 @@ of publishing the Knative domain. 1. [Knative Serving](https://github.com/knative/docs/blob/master/install/README.md) installed on your cluster. 1. A public domain that will be used in Knative. 1. Knative configured to use your custom domain. + ```shell kubectl edit cm config-domain --namespace knative-serving ``` -This command opens your default text editor and allows you to edit the config + +This command opens your default text editor and allows you to edit the config map. + ``` apiVersion: v1 data: @@ -30,9 +33,11 @@ data: kind: ConfigMap [...] ``` -Edit the file to replace `example.com` with the domain you'd like to use and + +Edit the file to replace `example.com` with the domain you'd like to use and save your changes. In this example, we use domain `external-dns-test.my-org.do` - for all routes: +for all routes: + ``` apiVersion: v1 data: @@ -43,7 +48,7 @@ kind: ConfigMap ## Setup steps -This guide uses Google Cloud Platform as an example to show how to set up +This guide uses Google Cloud Platform as an example to show how to set up ExternalDNS. You can find detailed instructions for other cloud providers in the [ExternalDNS documentation](https://github.com/kubernetes-incubator/external-dns#deploying-to-a-cluster). @@ -56,38 +61,45 @@ of DNS providers supported by ExternalDNS. Choose a DNS provider from the list. ### Create a DNS zone for managing DNS records -Skip this step if you already have a zone for managing the DNS records of your +Skip this step if you already have a zone for managing the DNS records of your custom domain. A DNS zone which will contain the managed DNS records needs to be created. Assume your custom domain is `external-dns-test.my-org.do`. Use the following command to create a DNS zone with [Google Cloud DNS](https://cloud.google.com/dns/): + ```shell gcloud dns managed-zones create "external-dns-zone" \ --dns-name "external-dns-test.my-org.do." \ --description "Automatically managed zone by kubernetes.io/external-dns" ``` + Make a note of the nameservers that were assigned to your new zone. + ```shell gcloud dns record-sets list \ --zone "external-dns-zone" \ --name "external-dns-test.my-org.do." \ --type NS ``` + You should see output similar to the following: + ``` NAME TYPE TTL DATA external-dns-test.my-org.do. NS 21600 ns-cloud-e1.googledomains.com.,ns-cloud-e2.googledomains.com.,ns-cloud-e3.googledomains.com.,ns-cloud-e4.googledomains.com. ``` -In this case, the DNS nameservers are `ns-cloud-{e1-e4}.googledomains.com`. + +In this case, the DNS nameservers are `ns-cloud-{e1-e4}.googledomains.com`. Yours could differ slightly, e.g. {a1-a4}, {b1-b4} etc. -If this zone has the parent zone, you need to add NS records of this zone into +If this zone has the parent zone, you need to add NS records of this zone into the parent zone so that this zone can be found from the parent. -Assuming the parent zone is `my-org-do` and the parent domain is `my-org.do`, -and the parent zone is also hosted at Google Cloud DNS, you can follow these -steps to add the NS records of this zone into the parent zone: +Assuming the parent zone is `my-org-do` and the parent domain is `my-org.do`, +and the parent zone is also hosted at Google Cloud DNS, you can follow these +steps to add the NS records of this zone into the parent zone: + ```shell gcloud dns record-sets transaction start --zone "my-org-do" gcloud dns record-sets transaction add ns-cloud-e{1..4}.googledomains.com. \ @@ -97,15 +109,18 @@ gcloud dns record-sets transaction execute --zone "my-org-do" ### Deploy ExternalDNS -Use the following command to apply the [manifest](https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/gke.md#manifest-for-clusters-without-rbac-enabled) to install ExternalDNS +Use the following command to apply the [manifest](https://github.com/kubernetes-incubator/external-dns/blob/master/docs/tutorials/gke.md#manifest-for-clusters-without-rbac-enabled) to install ExternalDNS + ```shell cat < EOF ``` + Note that you need to set the argument `domain-filter` to your custom domain. You should see ExternalDNS is installed by running: + ```shell kubectl get deployment external-dns ``` @@ -115,12 +130,15 @@ kubectl get deployment external-dns In order to publish the Knative Gateway service, the annotation `external-dns.alpha.kubernetes.io/hostname: '*.external-dns-test.my-org.do'` needs to be added into Knative gateway service: + ```shell kubectl edit svc knative-ingressgateway --namespace istio-system ``` -This command opens your default text editor and allows you to add the + +This command opens your default text editor and allows you to add the annotation to `knative-ingressgateway` service. After you've added your annotation, your file may look similar to this: + ``` apiVersion: v1 kind: Service @@ -132,12 +150,13 @@ metadata: ### Verify ExternalDNS works -After roughly two minutes, check that a corresponding DNS record for your +After roughly two minutes, check that a corresponding DNS record for your service was created. ```shell gcloud dns record-sets list --zone "external-dns-zone" --name "*.external-dns-test.my-org.do." ``` + You should see output similar to: ``` @@ -150,12 +169,16 @@ NAME TYPE TTL DATA You can check if the domain has been published to the Internet be entering the following command: + ```shell host test.external-dns-test.my-org.do ``` + You should see the below result after the domain is published: + ``` test.external-dns-test.my-org.do has address 35.231.248.30 ``` -> Note: The process of publishing the domain to the Internet can take several -minutes. + +> Note: The process of publishing the domain to the Internet can take several +> minutes. diff --git a/test/README.md b/test/README.md index a08970af4..81f379ee9 100644 --- a/test/README.md +++ b/test/README.md @@ -2,9 +2,8 @@ This directory contains tests and testing docs. -* [Unit tests](#running-unit-tests) currently reside in the codebase alongside the code they test -* [End-to-end tests](#running-end-to-end-tests) - +- [Unit tests](#running-unit-tests) currently reside in the codebase alongside the code they test +- [End-to-end tests](#running-end-to-end-tests) ## Running unit tests