首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >(译)在 Knative 中进行应用程序的构建和部署

(译)在 Knative 中进行应用程序的构建和部署

作者头像
崔秀龙
发布2019-07-23 15:20:14
发布2019-07-23 15:20:14
1.4K0
举报
文章被收录于专栏:伪架构师伪架构师

Knative 有三个高级子系统:Serving 用来协调服务 Pod 的自动伸缩以及路由;Build 提供了将代码转换为镜像的工具链;Eventing 则会使用事件的发布订阅来触发松耦合服务。

前一篇文章中我们将一个构件好的容器镜像发布到了 Knative Serving 中。

本篇文章将使用 Knative Build 把我们的应用通过 Dockerfile 以及 Cloud Foundry buildpack 在发布过程中转化为容器镜像。我们还会尝试从本地文件系统以及远程 Git 仓库中进行部署的方式。

前面的操作都很简单,看得出在 Kubernetes 环境中安装 Knative、运行现有容器镜像、使用 curl 与应用进行交互都不难。总结一下就是:

代码语言:javascript
复制
knctl install [--node-ports] [--exclude-monitoring]
knctl deploy --service <service-name> --image <image-name>
knctl curl --service <service-name>

后面的两步 - 把镜像部署为 Kubernetes 并运行,为每个部署进行版本化处理,使用 HTTP 路由进行交互,都是 Serving 子系统的功劳。

Knative 还支持用于构建容器镜像的弹性子系统,构建生成的镜像将会以 Kubernetes Pod 的形式运行。

Knative Build 子系统非常有弹性。我们会探讨集中用例:

  • 上传一个本地目录,使用 Dockerfile 进行构建。
  • 上传一个本地目录,使用 Buildpack 进行构建。
  • 用上面两种方式来构建来自于远程 Git 仓库的代码。

命名空间

前一篇文章中我们在每个 knctl 命令中使用了 --namespace helloworld 参数来显式的指定命名空间。对我来说这样显得更清晰。可能有别的用户希望设置一个缺省命名空间,从而能够缩短命令。

可以给 knctl 配置一个当前命名空间:

代码语言:javascript
复制
kubectl create ns my-simple-app
export KNCTL_NAMESPACE=my-simple-app

所有的 knctl 命令都会使用这一命名空间。

代码语言:javascript
复制
$ knctl service list
Services in namespace 'my-simple-app'Name  Domain  Annotations  Age0 services

可以在 kubectl 命令中复用 $KNCTL_NAMESPACE

kubectl get pods -n $KNCTL_NAMESPACE

上传一个带有 Dockerfile 的本地目录

在所有 Knative Build 的示例中,都会产生一个副产品——容器镜像。这些镜像必须放在什么地方,例如 Docker Hub、GCP 容器库、Azure 容器库,或者借助 Harbor 之类的软件自建的私库。

我们需要在每个应用所在的 Kubernetes 命名空间中给 Knative 配置一个镜像库,然后 knctl basic-auth-secret create 给 Knative 配置一个 Secret。

以 Docker Hub 为例,使用 --docker-hub

代码语言:javascript
复制
knctl basic-auth-secret create -s registry --docker-hub -u <username> -p <password>

GCP 容器仓库可以使用 --gcr 选项:

代码语言:javascript
复制
knctl basic-auth-secret create -s registry --gcr -u <username> -p <password>

其它私库可以使用 --type--url

代码语言:javascript
复制
knctl basic-auth-secret create -s registry --type docker --url https://registry.domain.com/ -u <username> -p <password>

下一步把镜像库 Secret 映射到 Kubernetes Service account,它会在 Knative Build 的 Pod 中提供上面的登录信息。

代码语言:javascript
复制
knctl service-account create --service-account build -s registry

这个操作会体现在 Kubernetes 的 Service account 中:

代码语言:javascript
复制
$ kubectl get serviceaccount -n $KNCTL_NAMESPACE
NAME      SECRETS   AGE
build     2         37s
default   1         3h

这样我们就准备好使用 Knative Build 创建新容器镜像所需的认证凭据了。

Clone 一个 Go 应用作为样例,并从它的本地目录推送到 Docker hub:

代码语言:javascript
复制
git clone https://github.com/cppforlife/simple-app
cd simple-appDOCKER_IMAGE=index.docker.io/<your hub.docker.com org or user>/knative-simple-appknctl deploy \
   --service simple-app \
   --directory=$PWD \
   --service-account build \
   --image ${DOCKER_IMAGE:?required} \
   --env SIMPLE_MSG="Built from local directory using Dockerfile"

容器的显式命名事实上只是从 Build 到 Serve 的工作过程中的一个中间步骤的副产品,但是必须提供。

knctl deploy 的输出大概是这样的:

代码语言:javascript
复制
Name  simple-appWaiting for new revision to be created...Tagging new revision 'simple-app-00001' as 'latest'Tagging new revision 'simple-app-00001' as 'previous'[2018-10-15T13:18:31+10:00] Uploading source code...[2018-10-15T13:19:59+10:00] Finished uploading source code...Watching build logs...build-step-build-and-push | INFO[0000] Downloading base image golang:1.10.1
build-step-build-and-push | ERROR: logging before flag.Parse: E1015 03:20:01.547607       1 metadata.go:142] while reading 'google-dockercfg' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg
build-step-build-and-push | ERROR: logging before flag.Parse: E1015 03:20:01.550268       1 metadata.go:159] while reading 'google-dockercfg-url' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg-url
build-step-build-and-push | INFO[0001] Executing 0 build triggers
build-step-build-and-push | INFO[0001] Extracting layer 0
build-step-build-and-push | INFO[0003] Extracting layer 1
build-step-build-and-push | INFO[0004] Extracting layer 2
build-step-build-and-push | INFO[0004] Extracting layer 3
build-step-build-and-push | INFO[0007] Extracting layer 4
build-step-build-and-push | INFO[0010] Extracting layer 5
build-step-build-and-push | INFO[0015] Extracting layer 6
build-step-build-and-push | INFO[0015] Taking snapshot of full filesystem...
build-step-build-and-push | INFO[0027] WORKDIR /go/src/github.com/mchmarny/simple-app/
build-step-build-and-push | INFO[0027] cmd: workdir
build-step-build-and-push | INFO[0027] Changed working directory to /go/src/github.com/mchmarny/simple-app/
build-step-build-and-push | INFO[0027] Creating directory /go/src/github.com/mchmarny/simple-app/
build-step-build-and-push | INFO[0027] COPY . .
build-step-build-and-push | INFO[0027] RUN CGO_ENABLED=0 GOOS=linux go build -v -o app
build-step-build-and-push | INFO[0027] cmd: /bin/sh
build-step-build-and-push | INFO[0027] args: [-c CGO_ENABLED=0 GOOS=linux go build -v -o app]
build-step-build-and-push | net
build-step-build-and-push | vendor/golang_org/x/net/lex/httplex
build-step-build-and-push | vendor/golang_org/x/net/proxy
build-step-build-and-push | net/textproto
build-step-build-and-push | crypto/x509
build-step-build-and-push | crypto/tls
build-step-build-and-push | net/http/httptrace
build-step-build-and-push | net/http
build-step-build-and-push | github.com/mchmarny/simple-app
build-step-build-and-push | INFO[0030] Taking snapshot of full filesystem...
build-step-build-and-push | INFO[0034] Storing source image from stage 0 at path /kaniko/stages/0
build-step-build-and-push | INFO[0038] trying to extract to /kaniko/0
build-step-build-and-push | INFO[0038] Extracting layer 0
build-step-build-and-push | INFO[0040] Extracting layer 1
build-step-build-and-push | INFO[0041] Extracting layer 2
build-step-build-and-push | INFO[0041] Extracting layer 3
build-step-build-and-push | INFO[0043] Extracting layer 4
build-step-build-and-push | INFO[0046] Extracting layer 5
build-step-build-and-push | INFO[0051] Extracting layer 6
build-step-build-and-push | INFO[0051] Extracting layer 7
build-step-build-and-push | INFO[0051] Deleting filesystem...
build-step-build-and-push | INFO[0053] No base image, nothing to extract
build-step-build-and-push | INFO[0053] Taking snapshot of full filesystem...
build-step-build-and-push | INFO[0062] COPY --from=0 /go/src/github.com/mchmarny/simple-app/app .
build-step-build-and-push | INFO[0063] Taking snapshot of files...
build-step-build-and-push | INFO[0063] EXPOSE 8080
build-step-build-and-push | INFO[0063] cmd: EXPOSE
build-step-build-and-push | INFO[0063] Adding exposed port: 8080/tcp
build-step-build-and-push | INFO[0063] ENTRYPOINT ["/app"]
build-step-build-and-push | ERROR: logging before flag.Parse: E1015 03:21:04.751338       1 metadata.go:142] while reading 'google-dockercfg' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg
build-step-build-and-push | ERROR: logging before flag.Parse: E1015 03:21:04.753927       1 metadata.go:159] while reading 'google-dockercfg-url' metadata: http status code: 404 while fetching url http://metadata.google.internal./computeMetadata/v1/instance/attributes/google-dockercfg-url
build-step-build-and-push | 2018/10/15 03:21:06 pushed blob sha256:72a682eea3309941d5e8e6f993a07ae4d33a413b8b7fa2762f8e969310b5996a
build-step-build-and-push | 2018/10/15 03:21:07 pushed blob sha256:9c24aa788ba416c5e1e631d8af3e3115519ad7ca0f659ac10f40682524c6d9cd
build-step-build-and-push | 2018/10/15 03:21:07 index.docker.io/drnic/knative-simple-app:latest: digest: sha256:b5823ead77d9544998b5bc844f049d1a7dfb0aefe7461b74b3e4f67fb5481fa1 size: 428
nop | Nothing to pushSucceeded

Knative Build 的调试

目前 knctl deploy 没有显示任何来自 Knative Build 系统的内部错误或者警告。只需要看着 Waiting for new revision to be created... 坐享其成就可以了。

一个调试方法就是使用 kail 工具处理来自 Knative Build 子系统的消息:

代码语言:javascript
复制
kail -n knative-build

这样就会看到大量的日志,可以再其中查找错误信息,例如 "msg":"Failed the resource specific validation{error 25 0 serviceaccounts \"build\" not found}"

使用 Buildpack 进行构建

我本人很喜欢 Cloud Foundry 和 Heroku 的镜像构建方式,幸运的是,Knative Build 通过自定义构建模板的方式提供了这种支持。

首先用 buildpack 这个名字在活动命名空间中注册一个构建模板:

代码语言:javascript
复制
kubectl -n $KNCTL_NAMESPACE apply -f \
https://raw.githubusercontent.com/knative/build-templates/master/buildpack/buildpack.yaml

加入 --template buildpack 就可以使用这一自定义模板了。构建模板所需的附加环境变量都可以用 --template-env NAME=value 的方式进行植入。

例如 Cloud Foundry Go Buildpack 需要 $GOPACKNAME(参考文档):

代码语言:javascript
复制
knctl deploy \
   --service simple-app \
   --directory=$PWD \
   --service-account build \
   --image ${DOCKER_IMAGE:?required} \
   --env SIMPLE_MSG="Built from local directory using Buildpack template" \
   --template buildpack \
   --template-env GOPACKAGENAME=main

输出内容和 Cloud Foundry buildpack 是一致的:

代码语言:javascript
复制
Name  simple-appWaiting for new revision (after revision 'simple-app-00001') to be created...Tagging new revision 'simple-app-00002' as 'latest'Tagging older revision 'simple-app-00001' as 'previous'[2018-10-15T13:40:41+10:00] Uploading source code...[2018-10-15T13:42:08+10:00] Finished uploading source code...Watching build logs...build-step-build | -----> Go Buildpack version 1.8.26
build-step-build | -----> Installing godep 80
build-step-build |        Download [https://buildpacks.cloudfoundry.org/dependencies/godep/godep-v80-linux-x64-cflinuxfs2-06cdb761.tgz]
build-step-build | -----> Installing glide 0.13.1
build-step-build |        Download [https://buildpacks.cloudfoundry.org/dependencies/glide/glide-v0.13.1-linux-x64-cflinuxfs2-aab48c6b.tgz]
build-step-build | -----> Installing dep 0.5.0
build-step-build |        Download [https://buildpacks.cloudfoundry.org/dependencies/dep/dep-v0.5.0-linux-x64-cflinuxfs2-52c14116.tgz]
build-step-build | -----> Installing go 1.8.7
build-step-build |        Download [https://buildpacks.cloudfoundry.org/dependencies/go/go1.8.7.linux-amd64-cflinuxfs2-fff10274.tar.gz]
build-step-build |        **WARNING** Installing package '.' (default)
build-step-build | -----> Running: go install -tags cloudfoundry -buildmode pie .
build-step-export | 2018/10/15 03:47:58 mounted blob: sha256:1124eb40dd68654b8ca8f5d9ec7e439988a4be752a58c8f4e06d60ab1589abdb
build-step-export | 2018/10/15 03:47:58 mounted blob: sha256:6be38da025345ffb57d1ddfcdc5a2bc052be5b9491825f648b49913d51e41acb
build-step-export | 2018/10/15 03:47:58 mounted blob: sha256:a5733e6358eec8957e81b1eb93d48ef94d649d65c69a6b1ac49f616a34a74ac1
build-step-export | 2018/10/15 03:47:58 mounted blob: sha256:21324a9f04e76c93078f3a782e3198d2dded46e4ec77958ddd64f701aecb69c0
build-step-export | 2018/10/15 03:47:59 pushed blob sha256:efa2d34b82bc07588a1a8fd4526322257408109547ee089a792b3f51c383f8e6
build-step-export | 2018/10/15 03:47:59 pushed blob sha256:d495696b33936c79216ec8178726b9fbe915fafbffdd0911a7fdabce4297d9a4
build-step-export | 2018/10/15 03:48:00 index.docker.io/drnic/knative-simple-app:latest: digest: sha256:e5ef1d4d255b4bcbb38d4b43bb6302423c33e6eeabd0e20d5fda4e5ce4c46668 size: 1082
nop | Nothing to push

现在就能看到应用已经部署成功:

代码语言:javascript
复制
$ knctl curl -s simple-app
<h1>Built from local directory using Buildpack template</h1>

私有 Git Secret

前面两节我们从本地上传了源码然后构建了 Docker 镜像(使用 Dockerfile 或 Cloud Foundry buildpack),最后运行应用。

Knative 还能从 Git 仓库获取源码(正式的说法是,Knative Build 只支持从 Git 仓库获取源码,本地代码的支持是 knctl 提供的)。

让 Knative Build 获取 Git 仓库中的代码,需要用 --git-url--git-revision 来取代 --directory=$PWD

如果你的 Git 仓库是私有的,那就还需要在 Service account(在上面的例子中的 build)里包含 Git ssh 凭据。knctl ssh-auth-secret create 能够协助用户创建一个 kubernetes.io/ssh-auth secret。

代码语言:javascript
复制
$ knctl ssh-auth-secret create --secret git --github --private-key "$(cat ~/.ssh/id_rsa)"
Name  git
Type  kubernetes.io/ssh-auth$ kubectl get secrets -n $KNCTL_NAMESPACE
NAME                  TYPE                                  DATA   AGE
...
git                   kubernetes.io/ssh-auth                1      5m
registry              kubernetes.io/basic-auth              2      3h

现在需要把 git secret 加入到我们的 build Service account 之中了。

在成文之时,knctl 还没有提供 knctl serviceaccounts update 这样的命令,所以需要删除重新创建:

代码语言:javascript
复制
kubectl delete serviceaccounts -n $KNCTL_NAMESPACE build
knctl service-account create --service-account build -s registry -s git

从 Git 部署

--git-url--git-revision 替代 --directory 来进行 Git 部署:

代码语言:javascript
复制
knctl deploy \
   --service simple-app \
   --git-url git@github.com:cppforlife/simple-app.git \
   --git-revision master \
   --service-account build \
   --image ${DOCKER_IMAGE:?required} \
   --env SIMPLE_MSG="Built from Git repo using Buildpack template" \
   --template buildpack \
   --template-env GOPACKAGENAME=main

总结

knctl deploy 命令在 Knative 的基础上提供了创建新镜像的良好体验,可以从本地目录或者 Git 仓库开始,使用 Dockerfile 或 Cloud Foundry buildpack 进行构建,并支持不同的镜像仓库。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2018-11-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 伪架构师 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 命名空间
  • 上传一个带有 Dockerfile 的本地目录
  • Knative Build 的调试
  • 使用 Buildpack 进行构建
  • 私有 Git Secret
  • 从 Git 部署
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档