我们以一个go语言编写的程序代码为例,创建一个简单的Web服务,当该服务接收到HTTP GET请求时会根据环境变量TARGET传递的内容向response输出Hello $TATGET! 内容。
1. 创建一个文件名为helloworld.go的文件。程序源码如下:
package mainimport ("fmt""log""net/http""os")func handler(w http.ResponseWriter, r *http.Request) { log.Print("helloworld: received a request") target := os.Getenv("TARGET")if target == "" { target = "World" } fmt.Fprintf(w, "Hello %s!\n", target)}func main() { log.Print("helloworld: starting server...")http.HandleFunc("/", handler)port := os.Getenv("PORT")if port == "" { port = "8080" }log.Printf("helloworld: listening on port %s", port) log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))}
使用下面内容的Dockerfile构建源码并生成容器:
# 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/_/golangFROM golang:1.13 as builder# Create and change to the app directory.WORKDIR /app# Retrieve application dependencies using go modules.# Allows container builds to reuse downloaded dependencies.COPY go.* ./RUN go mod download# Copy local code to the container image.COPY . ./# Build the binary.# -mod=readonly ensures immutable go.mod and go.sum in container builds.RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server# Use the official Alpine image for a lean production container.# https://hub.docker.com/_/alpine# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-buildsFROM alpine:3RUN apk add --no-cache ca-certificates# Copy the binary to the production image from the builder stage.COPY --from=builder /app/server /server# Run the web service on container startup.CMD ["/server"]
# 在本地主机构建容器。{username}替换为你自己在dockerhub的用户名。docker build -t {username}/helloworld-go .# 将容器Push到Docker容器镜像仓库。{username}替换为你自己在dockerhub的用户名。docker push {username}/helloworld-go
部署Knative Service
Knative Service和其他Kubernetes资源类似,可以通过一个YAML文件进行定义和部署。接下来我们使用上一步构建的容器来部署Knative Service服务。service.yaml配置文件如下:
apiVersion: serving.knative.dev/v1kind: Servicemetadata:name: helloworld-go # Service名称namespace: defaultspec:template:metadata:name: helloworld-go-v1 # Knative Revision名称,如果未设置系统将会自动生成。spec:containers:- image: {username}/helloworld-goenv:- name: TARGETvalue: "Go Sample v1"livenessProbe:httpGet:path: /readinessProbe:httpGet: path: /
运行下面的命令部署helloworld-go Knative Service:
# kubectl apply -f service.yaml
在这个YAML配置文件中,Knative Service的kind的值是Service,为了避免与Kubernetes内置的service混淆,apiVersion的值需要设置为serving.knative.dev/v1。
配置文件中的spec区块与Kubernetes PodSpec的定义几乎完全一样,只是删除了以下属性:
• InitContainers• RestartPolicy• TerminationGracePeriodSeconds• ActiveDeadlineSeconds• DNSPolicy• NodeSelector• AutomountServiceAccountToken• NodeName• HostNetwork• HostPID• HostIPC• ShareProcessNamespace• SecurityContext• Hostname• Subdomain• Affinity• SchedulerName• Tolerations• HostAliases• PriorityClassName• Priority• DNSConfig• ReadinessGates• RuntimeClassName
spec.template.metadata.name定义了Knative Revision的名称,这个名称是可选的,如果被省略,Revision的名称会自动生成。
Knative Service的liveness探针与标准Kubernetes探针有微小区别。Knative Service探针定义中没有port属性定义。Knative Serving控制器在service部署阶段能够自动确定port值。readiness探针也遵循同样的规则。
检查部署结果并验证服务:
# kubectl get ksvc helloworld-goNAME URL LATESTCREATED LATESTREADY READY REASONhelloworld-go http://helloworld-go.default.example.com helloworld-go-v1 helloworld-go-v1 True
通过curl命令访问helloworld-go服务:
##获取集群任一节点的IP地址和nodePort端口# IP_ADDRESS="$(kubectl get nodes -o 'jsonpath={.items[0].status.addresses[0].address}'):$(kubectl get svc istio-ingressgateway --namespace istio-system --output 'jsonpath={.spec.ports[?(@.port==80)].nodePort}')"# curl -H "Host:helloworld-go.default.example.com" http://$IP_ADDRESSHello Go Sample v1!
上面的脚本中为了获取可以访问到helloworld-go服务的ip地址以端口号,我们选取了集群任一节点的ip地址,istio-ingressgateway服务的nodePort端口号。使用带有Service URL的主机名的头信息(例如Host:helloworld-go.default.example.com)即可访问helloworld-go服务了。
当curl访问到服务后,knative Serving自动创建了一个pod副本提供服务,当一段时间没有访问服务后,pod副本将会被销毁。我们可以通过watch kubectl get pods 来监控pod的生命周期。
本文摘编于机械工业出版社出版的图书《Knative实战:基于Kubernetes的无服务器架构实践》。
本书的读者对象:
对Serverless技术感兴趣的读者。
想要将Knative引入当前技术栈的架构师。
想要采用Serverless技术的应用开发者。
想要自己维护Knative Serverless平台的运维开发人员。
关于作者:
李志伟 某网云原生实验室负责人,容器云领域专家。在Kubernetes、Istio、Serverless、DevOps工具等领域有深入的研究和实践。热心于云原生技术的应用与推广,曾荣获“K8sMeetup中国社区”最受欢迎讲师奖项。
游杨 某网云原生实验室高级运维开发工程师。先后参与Kubernetes和Knative项目的落地与实施工作,拥有丰富的容器平台实践经验,聚焦于Kubernetes、Serverless、CI/CD技术领域。
对于Knative,你有哪些了解?
#欢迎来评论区讨论#
CSDN云计算 将选出三名优质留言
携手【机械工业出版社华章分社】送出
《Knative实战:基于Kubernetes的无服务器架构实践》一本
截至4月27日14:00点
60+专家,13个技术领域,CSDN 《IT 人才成长路线图》重磅来袭!
直接扫码或微信搜索「CSDN」公众号,后台回复关键词「路线图」,即可获取完整路线图!
更多精彩推荐
☞5G、射频、奥特曼,这仨有联系吗?☞再见 Nacos,我要玩 Service Mesh 了!☞用根因定位法,让运维效率再高一点!
点分享点收藏点点赞点在看