[multi-container]Add samples for multi container support (#2732)

* [multi-container]Add samples for multi container support

* Fix review comments

* Fix CI issue

* Fix review comments

* Fix review comments

* Removed trailing whitespaces

* Addressed review comments and updated go version to use 1.15 instead of 1.13

* Addressed review comments
This commit is contained in:
savitaashture 2020-10-13 21:55:30 +05:30 committed by GitHub
parent 139b047371
commit c80a5cc3e9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 438 additions and 0 deletions

View File

@ -17,3 +17,4 @@ Serving resources and how they can be applied across common use cases.
| REST API | A simple Restful service that exposes an endpoint defined by an environment variable described in the Knative Configuration. | [Go](./rest-api-go/README.md) | | REST API | A simple Restful service that exposes an endpoint defined by an environment variable described in the Knative Configuration. | [Go](./rest-api-go/README.md) |
| Telemetry | This sample runs a simple web server that makes calls to other in-cluster services and responds to requests with "Hello World!". The purpose of this sample is to show generating metrics, logs, and distributed traces. | [Go](./telemetry-go/README.md) | | Telemetry | This sample runs a simple web server that makes calls to other in-cluster services and responds to requests with "Hello World!". The purpose of this sample is to show generating metrics, logs, and distributed traces. | [Go](./telemetry-go/README.md) |
| Traffic Splitting | This samples builds off the [Creating a RESTful Service](./rest-api-go) sample to illustrate applying a revision, then using that revision for manual traffic splitting. | [YAML](./traffic-splitting/README.md) | | Traffic Splitting | This samples builds off the [Creating a RESTful Service](./rest-api-go) sample to illustrate applying a revision, then using that revision for manual traffic splitting. | [YAML](./traffic-splitting/README.md) |
| Multi Container | A quick introduction that highlights how to build and deploy an app using Knative Serving for multiple containers. | [Go](./multi-container/README.md) |

View File

@ -0,0 +1,259 @@
A simple web app written in Go that you can use for multi container testing.
## Prerequisites
- A Kubernetes cluster with Knative installed and DNS configured. Follow the
[installation instructions](../../../install/README.md) if you need to
create one.
- [Docker](https://www.docker.com) installed and running on your local machine,
and a Docker Hub account configured (we'll use it for a container registry).
- Make sure multi-container flag is enabled as part of `config-features` configmap.
The following steps show how you can use the sample code and deploy the app to your
cluster.
You can download a working copy of the sample, by entering the
following command:
```shell
git clone -b "{{< branch >}}" https://github.com/knative/docs knative-docs
```
## Using the sample code
To test multi container functionality, you must create two containers: a serving container, and a sidecar container.
The `multi-container` directory is provided in the sample code, and contains predefined code and dockerfiles for creating the containers.
You can update the default files and YAML by using the steps outlined in this section.
### Serving Container
1. After you have cloned the sample repository, navigate to the servingcontainer directory:
`cd knative-docs/docs/serving/samples/multi-container/servingcontainer`
1. Create a basic web server which listens on port 8881.
You can do this by copying the following code into the `servingcontainer.go` file:
```go
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("serving container received a request.")
res, err := http.Get("http://127.0.0.1:8882")
if err != nil {
log.Fatal(err)
}
resp, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(w, string(resp))
}
func main() {
log.Print("serving container started...")
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8881", nil))
}
```
1. Copy the following code into the `Dockerfile` file:
```docker
# Use the official Golang image to create a build artifact.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.15 as builder
# Create and change to the app directory.
WORKDIR /app
# Retrieve application dependencies using go modules.
# Allows container builds to reuse downloaded dependencies.
COPY go.* ./
RUN go mod download
# Copy local code to the container image.
COPY . ./
# Build the binary.
# -mod=readonly ensures immutable go.mod and go.sum in container builds.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o servingcontainer
# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/servingcontainer /servingcontainer
# Run the web service on container startup.
CMD ["/servingcontainer"]
```
### Sidecar Container
1. After you have cloned the sample repository, navigate to the sidecarcontainer directory:
```text
cd -
cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer
```
1. Create a basic web server which listens on port 8882.
You can do this by copying the following code into the `sidecarcontainer.go` file:
```go
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("sidecar container received a request.")
fmt.Fprintln(w, "Yay!! multi-container works")
}
func main() {
log.Print("sidecar container started...")
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8882", nil))
}
```
1. Copy the following code into the `Dockerfile` file:
```docker
# Use the official Golang image to create a build artifact.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.15 as builder
# Create and change to the app directory.
WORKDIR /app
# Retrieve application dependencies using go modules.
# Allows container builds to reuse downloaded dependencies.
COPY go.* ./
RUN go mod download
# Copy local code to the container image.
COPY . ./
# Build the binary.
# -mod=readonly ensures immutable go.mod and go.sum in container builds.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o sidecarcontainer
# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/sidecarcontainer /sidecarcontainer
# Run the web service on container startup.
CMD ["/sidecarcontainer"]
```
### Writing Knative Service YAML
1. After you have cloned the sample repository, navigate to the `multi-container` directory:
1. `cd -`
2. `cd knative-docs/docs/serving/samples/multi-container/`
1. Copy the following YAML service definition into the `service.yaml` file:
```yaml
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: multi-container
namespace: default
spec:
template:
spec:
containers:
- image: docker.io/{username}/servingcontainer
ports:
- containerPort: 8881
- image: docker.io/{username}/sidecarcontainer
```
**NOTE:** Replace `{username}` with your Docker Hub username.
1. Use Go tool to create a
[`go.mod`](https://github.com/golang/go/wiki/Modules#gomod) manifest:
servingcontainer
```shell
cd -
cd knative-docs/docs/serving/samples/multi-container/servingcontainer
go mod init github.com/knative/docs/docs/serving/samples/multi-container/servingcontainer
```
sidecarcontainer
```shell
cd -
cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer
go mod init github.com/knative/docs/docs/serving/samples/multi-container/sidecarcontainer
```
## Building and deploying the sample
After you have modified the sample code files you can build and deploy the sample app.
1. Use Docker to build the sample code into a container. To build and push with
Docker Hub, run these commands replacing `{username}` with your Docker Hub
username:
```shell
# Build the container on your local machine
cd -
cd knative-docs/docs/serving/samples/multi-container/servingcontainer
docker build -t {username}/servingcontainer .
cd -
cd knative-docs/docs/serving/samples/multi-container/sidecarcontainer
docker build -t {username}/sidecarcontainer .
# Push the container to docker registry
docker push {username}/servingcontainer
docker push {username}/sidecarcontainer
```
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
cd -
cd knative-docs/docs/serving/samples/multi-container
kubectl apply --filename service.yaml
```
1. Now that your service is created, Knative will perform the following steps:
- Create a new immutable revision for this version of the app.
- Network programming to create a route, ingress, service, and load balance
for your app.
- Automatically scale your pods up and down (including to zero active pods).
1. Run the following command to find the domain URL for your service:
```shell
kubectl get ksvc multi-container --output=custom-columns=NAME:.metadata.name,URL:.status.url
```
Example:
```shell
NAME URL
multi-container http://multi-container.default.1.2.3.4.xip.io
```
1. Now you can make a request to your app and see the result. Replace
the URL below with the URL returned in the previous command.
```shell
curl http://multi-container.default.1.2.3.4.xip.io
Yay!! multi-container works
```
> Note: Add `-v` option to get more detail if the `curl` command failed.
## Removing the sample app deployment
To remove the sample app from your cluster, delete the service record:
```shell
kubectl delete --filename service.yaml
```

View File

@ -0,0 +1,6 @@
---
title: "Knative multi-container samples"
linkTitle: "A simple golang web app"
weight: 1
type: "docs"
---

View File

@ -0,0 +1,27 @@
# Copyright 2020 The Knative Authors
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
apiVersion: serving.knative.dev/v1
kind: Service
metadata:
name: multi-container
namespace: default
spec:
template:
spec:
containers:
- image: docker.io/savita3020/servingcontainer
ports:
- containerPort: 8881
- image: docker.io/savita3020/sidecarcontainer

View File

@ -0,0 +1,31 @@
# Use the official Golang image to create a build artifact.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.15 as builder
# Create and change to the app directory.
WORKDIR /app
# Retrieve application dependencies using go modules.
# Allows container builds to reuse downloaded dependencies.
COPY go.* ./
RUN go mod download
# Copy local code to the container image.
COPY . ./
# Build the binary.
# -mod=readonly ensures immutable go.mod and go.sum in container builds.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o servingcontainer
# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/servingcontainer /servingcontainer
# Run the web service on container startup.
CMD ["/servingcontainer"]

View File

@ -0,0 +1,3 @@
module github.com/knative/docs/docs/serving/samples/multi-container/servingcontainer
go 1.15

View File

@ -0,0 +1,43 @@
/*
Copyright 2020 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"io/ioutil"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("serving container received a request.")
res, err := http.Get("http://127.0.0.1:8882")
if err != nil {
log.Fatal(err)
}
resp, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Fatal(err)
}
fmt.Fprintln(w, string(resp))
}
func main() {
log.Print("serving container started...")
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8881", nil))
}

View File

@ -0,0 +1,31 @@
# Use the official Golang image to create a build artifact.
# This is based on Debian and sets the GOPATH to /go.
# https://hub.docker.com/_/golang
FROM golang:1.15 as builder
# Create and change to the app directory.
WORKDIR /app
# Retrieve application dependencies using go modules.
# Allows container builds to reuse downloaded dependencies.
COPY go.* ./
RUN go mod download
# Copy local code to the container image.
COPY . ./
# Build the binary.
# -mod=readonly ensures immutable go.mod and go.sum in container builds.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o sidecarcontainer
# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates
# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/sidecarcontainer /sidecarcontainer
# Run the web service on container startup.
CMD ["/sidecarcontainer"]

View File

@ -0,0 +1,3 @@
module github.com/knative/docs/docs/serving/samples/multi-container/sidecarcontainer
go 1.15

View File

@ -0,0 +1,34 @@
/*
Copyright 2020 The Knative Authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package main
import (
"fmt"
"log"
"net/http"
)
func handler(w http.ResponseWriter, r *http.Request) {
log.Println("sidecar container received a request.")
fmt.Fprintln(w, "Yay!! multi-container works")
}
func main() {
log.Print("sidecar container started...")
http.HandleFunc("/", handler)
log.Fatal(http.ListenAndServe(":8882", nil))
}