如何部署一个Knative Service

我们以一个go语言编写的程序代码为例,创建一个简单的Web服务,当该服务接收到HTTP GET请求时会根据环境变量TARGET传递的内容向response输出Hello $TATGET! 内容。

1. 创建一个文件名为helloworld.go的文件。程序源码如下:

package main




import (
  "fmt"
  "log"
  "net/http"
  "os"
)




func handler(w http.ResponseWriter, r *http.Request) {
  log.Print("helloworld: received a request")
  target := os.Getenv("TARGET")
  if target == "" {
    target = "World"
  }
  fmt.Fprintf(w, "Hello %s!\n", target)
}




func main() {
  log.Print("helloworld: starting server...")




  http.HandleFunc("/", handler)




  port := os.Getenv("PORT")
  if port == "" {
    port = "8080"
  }




  log.Printf("helloworld: listening on port %s", port)
  log.Fatal(http.ListenAndServe(fmt.Sprintf(":%s", port), nil))
}


使用下面内容的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/_/golang
FROM golang:1.13 as builder




# Create and change to the app directory.
WORKDIR /app




# Retrieve application dependencies using go modules.
# Allows container builds to reuse downloaded dependencies.
COPY go.* ./
RUN go mod download




# Copy local code to the container image.
COPY . ./




# Build the binary.
# -mod=readonly ensures immutable go.mod and go.sum in container builds.
RUN CGO_ENABLED=0 GOOS=linux go build -mod=readonly -v -o server




# Use the official Alpine image for a lean production container.
# https://hub.docker.com/_/alpine
# https://docs.docker.com/develop/develop-images/multistage-build/#use-multi-stage-builds
FROM alpine:3
RUN apk add --no-cache ca-certificates




# Copy the binary to the production image from the builder stage.
COPY --from=builder /app/server /server




# Run the web service on container startup.
CMD ["/server"]
# 在本地主机构建容器。{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/v1
kind: Service
metadata:
  name: helloworld-go  # Service名称
  namespace: default
spec:
  template:
    metadata:
      name: helloworld-go-v1 # Knative Revision名称,如果未设置系统将会自动生成。
    spec:
      containers:
      - image: {username}/helloworld-go
        env:
        - name: TARGET
          value: "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-go
NAME            URL                                                      LATESTCREATED      LATESTREADY           READY   REASON
helloworld-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_ADDRESS
Hello 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的无服务器架构实践》。

关于作者:

李志伟 某网云原生实验室负责人,容器云领域专家。在Kubernetes、Istio、Serverless、DevOps工具等领域有深入的研究和实践。热心于云原生技术的应用与推广,曾荣获“K8sMeetup中国社区”最受欢迎讲师奖项。

游杨  某网云原生实验室高级运维开发工程师。先后参与Kubernetes和Knative项目的落地与实施工作,拥有丰富的容器平台实践经验,聚焦于Kubernetes、Serverless、CI/CD技术领域。

本书的读者对象:

  • 对Serverless技术感兴趣的读者。

  • 想要将Knative引入当前技术栈的架构师。

  • 想要采用Serverless技术的应用开发者。

  • 想要自己维护Knative Serverless平台的运维开发人员。

 


扫码关注【图书小编辑】视频号

每天来听华章哥讲书

更多精彩回顾

书讯 | 4月书讯 | 好书和最美四月天一起来了...

资讯 | DB-Engines 4月数据库排名:Redis有望甩掉“千年老七”?

书单 | 8本书助你零基础转行数据分析岗

干货 | 抛开数学,一文了解推荐系统框架及原理

收藏 | 终于有人将金融风险管理讲明白了

赠书 | 【第50期】10本金融科技好书为你转行、升职和加薪助力

点击阅读全文购买

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值