一个 Go 语言编写的极简 web 应用,用于测试。它读取环境变量 TARGET
并打印 Hello ${TARGET}!
。如果未指定 TARGET
,将 TARGET
内容替换为 World
。
可以按照下面的步骤创建示例代码,然后将应用程序部署到集群。也可以直接运行以下命令下载示例的代码:
1
2
|
git clone -b branch https://github.com/knative/docs knative-docs
cd knative-docs/docs/serving/samples/hello-world/helloworld-go
|
开始前
- 一个已安装 Knetive 的 Kubernetes 集群。如果需要创建可以参考 安装说明。
- 在本地计算机上安装运行 Docker,并配置 Docker Hub 帐户(将来推送镜像)。
重新创建示例代码
- 创建一个名为
helloworld.go
的新文件,然后粘贴以下代码。这段代码创建了一个监听 8080 端口上的 web 服务:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
package main
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 main() {
log.Print("Hello world sample started.")
http.HandleFunc("/", handler)
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}
|
- 在项目的目录中,创建一个名为
Dockerfile
的文件,并将下面的代码复制到其中。有关对 Go 应用进行容器化的详细说明,请参见使用 Docker 部署 Go 服务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
# 使用 Golang 官方镜像创建构建制品。
# 这是基于 Debian 的,并将GOPATH设置为 /go
# https://hub.docker.com/_/golang
FROM golang:1.13 as builder
# 创建并更改到 app 目录。
WORKDIR /app
# 检索应用依赖项。
# 这允许容器构建重用缓存的依赖项。
COPY go.* ./
RUN go mod download
# 将本地代码复制到容器镜像。
COPY . ./
# 编译二进制
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server
# 使用 Alpine 镜像用于生产
# 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
# 从 builder 阶段拷贝二进制到生产镜像
COPY --from=builder /app/server /server
# 启动时运行 web service
CMD ["/server"]
|
- 创建一个新文件
service.yaml
,并将以下 service 定义复制到该文件中。请确保将 {username}
替换为你的 Docker Hub 用户名。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
apiVersion: serving.knative.dev/v1alpha1
kind: Service
metadata:
name: helloworld-go
namespace: default
spec:
template:
spec:
containers:
- image: docker.io/{username}/helloworld-go
env:
- name: TARGET
value: "Go Sample v1"
|
- 使用 go tool 创建
go.mod
manifest。
1
|
go mod init github.com/knative/docs/docs/serving/samples/hello-world/helloworld-go
|
构建示例并部署
重新创建示例代码文件(或使用 sample 文件夹中的文件)后,就可以构建和部署示例应用了。
- 使用 Docker 将示例代码构建为容器镜像。运行以下命令构建并推送到 Docker Hub,用你的 Docker Hub 用户名替换
{username}
:
1
2
3
4
5
|
# 在本地计算机上构建镜像
docker build -t {username}/helloworld-go .
# 推送镜像到 docker 仓库
docker push {username}/helloworld-go
|
- 构建完成并将镜像推送到 Docker Hub 之后,可以将应用部署到集群中。确保
service.yaml
中的容器镜像与上一步中构建镜像内容一致。使用 kubectl
应用配置:
1
|
kubectl apply --filename service.yaml
|
-
现在你的服务已经创建,Knative 将执行以下步骤:
- 为此版本的应用程序创建一个新的不可变版本。
- 为应用创建路由(route)、入口(ingress)、服务(service)和负载均衡(load balance)的网络编程。
- 自动缩放你的Pod(包括活动的 Pod 为零)。
-
运行以下命令来找到 service 的域名 URL: 返回集群的 ingress IP。如果只是创建集群,则可能需要等待并重新运行命令,直到为 service 分配了外部 IP 地址。
1
2
3
4
5
6
7
8
9
10
11
|
# In Knative 0.2.x and prior versions, the `knative-ingressgateway` service was used instead of `istio-ingressgateway`.
INGRESSGATEWAY=knative-ingressgateway
# The use of `knative-ingressgateway` is deprecated in Knative v0.3.x.
# Use `istio-ingressgateway` instead, since `knative-ingressgateway`
# will be removed in Knative v0.4.
if kubectl get configmap config-istio -n knative-serving &> /dev/null; then
INGRESSGATEWAY=istio-ingressgateway
fi
kubectl get svc $INGRESSGATEWAY --namespace istio-system
|
示例:
1
2
|
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
xxxxxxx-ingressgateway LoadBalancer 10.23.247.74 35.203.155.229 80:32380/TCP,443:32390/TCP,32400:32400/TCP 2d
|
-
运行以下命令来找到 service 的域名 URL:
1
|
kubectl get ksvc helloworld-go --output=custom-columns=NAME:.metadata.name,URL:.status.url
|
示例:
1
2
|
NAME URL
helloworld-go http://helloworld-go.default.example.com
|
-
通过发送请求来测试应用。将以下 curl
命令与在上一个域中获取的域 URL helloworld-go.default.example.com
和 EXTERNAL-IP
地址一起使用脚步:
1
|
curl -H "Host: helloworld-go.default.example.com" http://{EXTERNAL_IP_ADDRESS}
|
示例:
1
2
|
curl -H "Host: helloworld-go.default.example.com" http://35.203.155.229
Hello Go Sample v1!
|
注意:如果 curl
命令失败,请添加 -v
选项以获取更多详细信息。
移除示例应用的 Deployment
要从集群中删除示例应用,请删除 service 记录:
1
|
kubectl delete --filename service.yaml
|
排错
执行 curl 命令与预期不符
检查 isito ingressgateway 是否为 pending 状态,如果是有 2 种方法,给设置个外部 IP 或者 NodePort 方式访问。