前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >(译)在 Knative 上部署 12 要素应用程序

(译)在 Knative 上部署 12 要素应用程序

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

Google Next18 活动中,Google 宣称将会把 GKE 上的无服务器插件以 Knative 的名称进行开源。当时它被描述为无服务器平台的构建块,由此推断,Knative 可能需要 Google、Pivotal 或者 RedHat 的协助才能使用。这可能是开源的古怪时机。从我最初的摸索来看,Knative 能工作;当我把 Heroku/Cloud Foundry buildpacks 加入进来之后,整个系统变得越来越像 Heroku/Cloud Foundry,相对于原始 Kubernetes,我更加了解和喜爱这一系统。

本文中我们会将 Knative 安装到你自己的 Kubernetes 集群中(knctl install),然后用 Knative 做些有趣的事情(knctl deploy)。

Knative 能够为在 Kubernetes 集群上运行无状态应用的运维人员带来很多惊喜。对我来说,最引人入胜的一点就是伸缩性:在高负载时候进行扩容,没人喜欢你的应用了,就会一直缩容到 0。

下载和安装 Knative 客户端工具 knctl,然后就可以在你的 Kubernetes 上部署 Knative,然后发布你的应用了。

在 MacOS 中,可以利用我们的 Homebrew tap 进行安装:

brew install starkandwayne/kubernetes/knctl

这里我假设你再使用 Minikube。在 Minikube 中,可以使用 Node Port 代替 Load balancer:

代码语言:javascript
复制
minikube start --memory=8192 --cpus=3 \
 --kubernetes-version=v1.11.3 \
 --vm-driver=hyperkit \
 --bootstrapper=kubeadmknctl install --node-ports --exclude-monitoring

可以参考 Knative 文档来获取在其它类型 Kubernetes 集群上进行部署的要点。

knctl install 命令可能要花上几分钟,甚至是十分钟或者更多。这个过程中需要下载大概一打镜像。不管是互联网带宽还是镜像尺寸都可能有变化,所以坐下放松一会,或者出去走走也好。

如果 knctl install 失败了,可能是你的 Internet 比较慢,Docker 镜像在命令超时之前还没能完成下载。运行 kubectl get pods --all-namespaces 直到所有 Pod 都在运行,然后再次运行 knctl install 命令继续完成安装过程。

现在你的 Kubernetes 就是无服务器架构了,不错吧。

可以运行 kubectl get pods --all-namespaces 看看原始的 Knative 的 Pod 们。

代码语言:javascript
复制
$ kubectl get pods --all-namespaces
NAMESPACE         NAME                                        READY   STATUS      RESTARTS   AGE
istio-system      istio-citadel-7d8f9748c5-zgm9x              1/1     Running     0          21m
istio-system      istio-cleanup-secrets-j4pkx                 0/1     Completed   0          21m
istio-system      istio-egressgateway-676c8546c5-dnwsd        1/1     Running     0          21m
istio-system      istio-galley-5669f7c9b-g774b                1/1     Running     0          21m
istio-system      istio-ingressgateway-5475685bbb-q5f2x       1/1     Running     0          21m
istio-system      istio-pilot-5795d6d695-9klrz                2/2     Running     0          21m
istio-system      istio-policy-7f945bf487-2wh88               2/2     Running     0          21m
istio-system      istio-sidecar-injector-d96cd9459-7knkm      1/1     Running     0          21m
istio-system      istio-statsd-prom-bridge-549d687fd9-lcmb7   1/1     Running     0          21m
istio-system      istio-telemetry-6c587bdbc4-t4jql            2/2     Running     0          21m
istio-system      knative-ingressgateway-7f4477dd99-n9wz2     1/1     Running     0          4m
knative-build     build-controller-7dcc4b7544-rkgwb           1/1     Running     0          4m
knative-build     build-webhook-fb6484576-sr4fk               1/1     Running     0          4m
knative-serving   activator-77d46b585d-b6g8n                  2/2     Running     0          4m
knative-serving   controller-85768cfd45-t8ktc                 1/1     Running     0          4m
knative-serving   webhook-56dd548f8-hjw44                     1/1     Running     0          4m
...

部署预构建的应用

接下来我们试试用一个现有的 Docker 镜像来作为自动伸缩的无状态应用运行到 Knative 上,在当前 Kubernetes 命令空间中:

代码语言:javascript
复制
kubectl create ns helloworldknctl deploy \
     --namespace helloworld \
     --service hello \
     --image gcr.io/knative-samples/helloworld-go \
     --env TARGET=Rev1

命令执行后会输出一些信息,表明 hello 服务已经创建,它的第一个版本 hello-00001 已经创建,并且被标记为 latestprevious(第一个版本)。

代码语言:javascript
复制
Name  helloWaiting for new revision to be created...Tagging new revision 'hello-00001' as 'latest'Tagging new revision 'hello-00001' as 'previous'Succeeded

我们可以用一个 curl 请求,发送到 Knative 的路由层,来调用我们的 hello 服务:

代码语言:javascript
复制
$ knctl curl --namespace helloworld --service hello
Running: curl '-H' 'Host: hello.helloworld.example.com' 'http://192.168.64.8:32380'Hello World: Rev1!Succeeded

如果没有马上显示 Hello World: Rev1!,可能是因为你的系统还在下载应用镜像、可以稍后重试。

我使用的是 Minikube 中的 NodePort Ingress,这意味着我不能设置漂亮的 DNS 路由。以后我会讨论一下公共负载均衡、DNS、Knative 路由以及 https://github.com/cppforlife/kwt

knctl deploy 之后,我们的 Kubernetes 用单 Pod 的形式运行这一服务:

代码语言:javascript
复制
$ kubectl get pods --namespace helloworld
NAME                                      READY   STATUS    RESTARTS   AGE
hello-00001-deployment-5864685cbc-v8r7n   3/3     Running   0          15s

Knative 中,服务的版本是一个重要特性。我们可以看到我们的唯一版本的服务正在处理 100% 的流量:

代码语言:javascript
复制
$ knctl revisions list --namespace helloworld --service hello
Revisions for service 'hello'Name         Tags      Allocated Traffic %  Serving State  Annotations  Age
hello-00001  latest    100%                 Active         -            3m
            previous1 revisions

下一步我们使用 knctl deploy 创建一个新的版本,然后把所有流量分配到新版本:

代码语言:javascript
复制
$ knctl deploy \
     --namespace helloworld \
     --service hello \
     --image gcr.io/knative-samples/helloworld-go \
     --env TARGET=Rev2Name  helloWaiting for new revision (after revision 'hello-00001') to be created...Tagging new revision 'hello-00002' as 'latest'Tagging older revision 'hello-00001' as 'previous'Succeeded

现在请求被发送到了我们的新版本:

代码语言:javascript
复制
$ knctl revisions list --namespace helloworld --service hello
Revisions for service 'hello'Name         Tags      Allocated Traffic %  Serving State  Annotations  Age
hello-00002  latest    100%                 Active         -            1m
hello-00001  previous  0%                   Active         -            10m$ knctl curl --namespace helloworld --service hello
Running: curl '-H' 'Host: hello.helloworld.example.com' 'http://192.168.64.8:32380'Hello World: Rev2!

部署第二个版本之后,起初两个版本的 Pod 都会持续运行:

代码语言:javascript
复制
$ kubectl get pods --namespace helloworld
NAME                                      READY   STATUS    RESTARTS   AGE
hello-00001-deployment-5864685cbc-v8r7n   3/3     Running   0          1m
hello-00002-deployment-7874bf89b8-4b4k5   3/3     Running   0          29s

我们会看到 Knative 自动将没有路由指向的版本缩容到 0。

路由

下图展示了路由到服务某版本的过程中所涉及到的 Knative Serving 模块:

版本是代码、依赖和配置的的只读快照。没有被路由引用的版本会被放弃,其中的 Kubernetes 资源会被删除。

我们可以看到当前的路由:

代码语言:javascript
复制
$ knctl routes list --namespace helloworld
Routes in namespace 'helloworld'Name   Traffic         All Traffic Assigned  Ready  Domain                        Age
hello  100% -> hello:  true                  true   hello.helloworld.example.com  2h

缩容至 0

如果离开五分钟再回来,你会发现 hello-00002 Pod 正在被终结或者已经不见了:

代码语言:javascript
复制
$ kubectl get pods --namespace helloworld
NAME                                      READY   STATUS        RESTARTS   AGE
hello-00001-deployment-5864685cbc-v8r7n   3/3     Running       0          6m
hello-00002-deployment-7874bf89b8-4b4k5   2/3     Terminating   0          5m

下一次 knctl curl,Knative 会动态的启动一个 Pod 来满足这一请求。

代码语言:javascript
复制
$ knctl curl --namespace helloworld --service hello
$ kubectl get pods --namespace helloworld
NAME                                      READY   STATUS    RESTARTS   AGE
hello-00001-deployment-5864685cbc-v8r7n   3/3     Running   0          8m
hello-00002-deployment-7874bf89b8-kfbm2   3/3     Running   0          10s

我还不太清楚为什么 hello-00001-deployment-... Pod 没有被缩容和终结。

未完待续

后续文章中将会尝试:

  • Knative Build 组件:使用 Dockerfile 或者 Cloud Foundry buildpack 自动从定制代码构建容器镜像(代码可以保存本地或者 Git 仓库之中)。
  • 为 Kubernetes 的负载均衡设置 DNS,从而为 Knative 路由和服务提供公共 URL。
  • 在不同版本之间进行流量分割(例如 10% 到最新版本,90% 到前一版本;然后将 100% 分配给新版本,老版本流量降低到 0%)。
  • Knative Eventing:在应用中进行 CloudEvents的绑定和分发。让你的服务更加“无服务器”。

社区

Knative 核心团队有自己的 Knative Slack,可以在 https://slack.knative.dev 申请加入。

knative-dev Group 中包含了总结和提议。

鸣谢

感谢 Google 的 Mark Chmarny,在 2018 Spring One 上首先回应了我的问题。

感谢 Pivotal 的 Dmitriy Kalinin 花时间帮助我将 Knative 运行起来,并给我展示了他的 knctl Knative CLI,以及 kwt Kubernetes Workstation Tools。相对于 YAML + kubectl 组合来说,一个好用的客户端工具更能够帮助 Knative 走向实用。

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 部署预构建的应用
  • 路由
  • 缩容至 0
  • 未完待续
  • 社区
  • 鸣谢
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档