You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
15 KiB
Markdown

2 years ago
# 10 | 经验Serverless架构应该如何选型
你好我是秦粤。通过前面的两节实践课我们体验了在本地环境中搭建K8s并且我们利用K8s的组件扩展能力在本地的K8s上安装了Istio和Knative。正如我在前面课程中所说的K8s可以让我们的集群架构轻松迁移到其他集群上那么今天我就带你将我们本地K8上部署的“待办任务”Web服务部署到云上的K8s集群。
实践课里还有这么个小细节不知道你注意没我们使用Knative时应用和微服务部署都需要关心项目应用中的Dockerfile而我在使用FaaS函数时连Dockerfile都不用管了其实这就是Serverless带来的变革之一。当然现在有很多应用托管PaaS平台也做了Serverless化让我们部署一个应用时只需要关心Release分支的代码合并例如Heroku、SAE等等。
这里我需要先解释一下K8s集群的运维工作对于很多个人开发者来说是有些重的。我们通常了解基本知识用kubectl调用K8s集群就可以了。咱们课程里我是为了让你更好理解Serverless的工作原理所以才向你介绍Knative在K8s上的搭建和使用过程。
实际工作中K8s集群的运维还是应该交给专业的运维人员。另外云服务商的K8s集群都会提供控制面板一键安装组件。我们在使用Serverless的部署应用时不用关心底层“被透明化”的类似Knative、Istio等等插件能力这也是Serverless应用的价值所在虽然它本身的底层构建在复杂且精密的各种服务上但我们使用Serverless却极其精简。
在开始部署K8s上云之前我们要先选择一个云服务商。正如我们上节课所说K8s整体架构迁移能力可以帮我们破解Vendor-lock只要我们部署的云服务商是CNCF的成员支持K8s集群就可以了。实际上目前几乎所有的云服务商都加入了CNCF阵营。因此我们的K8s版本的“待办任务”Web服务可以任意选择云服务商部署你完全可以横向对比云服务商的各项指标去选择适合自己的。当我们有了选择权也反向促进了云服务商的良性竞争。
## 云服务商
我们先看看2019年的[全球云服务商的市场占有率](https://www.canalys.com/newsroom/canalys-worldwide-cloud-infrastructure-Q4-2019-and-full-year-2019)数据,我也将按照这个数据排名,依次向你介绍云服务商和他的主要特色:
1. 亚马逊的AWS市占率32.4%。亚马逊凭借庞大复杂的全球电商业务,让其机房做到了覆盖全球,并引领云服务的发展,提供最全面的生态和最高稳定性的服务。云服务商老大的地位近年内都难以撼动。
2. 微软的Azure市占率17.6%。依赖微软Windows全家桶的优势和近年的JavaScrpit技术社区的收购或者并购他的市场地位紧跟亚马逊之后。整体云服务产品的报价也紧盯AWS所有服务价格略低于AWS。
3. 阿里巴巴的阿里云市占率6.0%。国内市场占有率第一,随着阿里电商业务出海,阿里云机房也部署到了海外。在国内云里生态建设得比较完备,每年都经受双十一流量的洗礼,不断打磨稳定性。客服响应速度是一大亮点。
4. 谷歌的谷歌云市场占有率5.4%。谷歌是后起之秀凭借15年提出CNCF云原生白皮书通过建立规范和开源生态迅速切入云服务领域并占有一席之地。价格策略上紧盯AWS并依靠Google的搜索引擎对大规模集群调度能力的积累。云服务商中最高的物理机资源利用率让谷歌云的价格做到了云服务商中的最低。
5. 其他云市场占有率38.5%。腾讯云、华为云等其他的云服务商都归并到了这里还有一些专门做专有云服务的比如CDN全球加速的AkamaiPaaS应用托管的Heroku等等。值得一提的是腾讯云腾讯云从2019年开始大力发展Serverless并积极和Serverless生态合作估计是希望以此为突破点提升自己的市场占有率。
下面是我按我目前(注意只是目前)掌握的数据和认知整理的表格,在选择云服务商时你可以作为参考。其中访问限制应该是最优先考虑的,国内运营部署的应用,肯定是要首选国内云服务商。
![](https://static001.geekbang.org/resource/image/d3/63/d3f31145aa72d7390db032b81b947663.png)
当我们完成云服务商的选择后理论上我们可以通过Docker容器创建我们所需要的各种服务例如Redis、MySQL、Kafka等等。具体怎么做你应该很熟悉了先去Docker Hub 官网找到我们所需要的服务镜像在这个镜像的基础上加上我们自己的用户名和密码生成私有Docker镜像上传到我们的Registry然后在K8s集群中就可以部署了。这也是前面我们讲到的Docker容器带来的颠覆式体验。
不过我们在重度使用Docker技术的同时也必须深入了解Docker和我们所用的具体镜像的限制。比如如何解决应用镜像硬盘持久化的问题、如何解决MySQL镜像的容器扩缩容的问题、Kafka镜像集群如何搭建等等。这些都是新技术引入的新的问题而且解决方案和传统运维虚拟机也不一样。
另外为了提升我们的研发效能我们还应该进一步了解云服务商还能为我们提供哪些能力节省我们的时间和成本。当我们开发一个云上项目时云服务商已经为我们准备了各种行业解决方案来提升我们的开发速度例如文件存储服务、视频媒体流转码服务、物联网MQTT解决方案等等。利用这些服务和我们前面讲的服务编排可以进一步加速我们的研发速度。
## 云服务如何选型?
现在云服务商都提供数以百计的各种服务但大体上我们可以分为以下3类IaaS、PaaS和SaaS。
![](https://static001.geekbang.org/resource/image/af/42/af06bd8f061823956d558be91b446442.png)
我们先看看图示中的金字塔这里我需要引入新的概念服务级别协议SLA服务提供商与受服务用户之间具体达成了承诺的服务指标——质量、可用性、责任。看上去有些绕简单来说就是服务不达标我们可以向云服务商索赔损失。
我们前面课程中所说的消息队列的稳定性达到10个9其实就是指SLA指标数据可靠性为99.99999999%但是消息队列的服务可用性其实是99.95%也就是说消息队列服务服务一年中不可使用时间为4.38小时,一旦不可用时间超过了这个要求,云服务商则需要向客户赔付(如果这部分知识你没接触过的话,可以看下赵成老师的[这篇文章](https://time.geekbang.org/column/article/212722))。
因此对于云服务商来说要维持资源的高可用性必须保证资源调度及时宁可浪费部分资源也不能牺牲用户的可用性。而云服务的价格则和物理机虚拟化比例强相关虚拟化比例越低说明你对这个资源独占性越高当然价格也就越高。物理机虚拟化比例也是云服务商的资源调度能力对云服务商来说核心指标就是CPU利用率。
了解了一些前提接下来我们具体看看这3类。
* IaaS层是面向运维人员服务器或虚拟机服务。可用性也最高通常可以到4个999.99%。可控性高虚拟机从操作系统开始你可以登录虚拟机并且任意安装各种自己所需的函数库和二进制包。资源的物理机虚拟化比例通常是2:1的性能是最稳定的。
* PaaS层是面向开发者通常部署在IaaS层之上服务种类最为繁多。可用性低于IaaS通常是99.95%。可控性中等PaaS通常都提供特定的服务例如应用托管、数据库等等我们只能通过提供的控制台登录。资源的物理机虚拟化比例通常是4:1性能较稳定。
* SaaS层是面向终端用户通常部署在PaaS层之上。可用性低于PaaS通常是99.9%。可控性低SaaS直接面向用户提供服务我们只能登录后台操作部分数据进行增删改查。资源的物理机虚拟化比例不太确定但肯定超过8:1性能一般。
FaaS则是一个特例虽然它也属于面向开发者的但利用FaaS极速的冷启动特性它并不需要关心底层的高可用性。反而用它可以填满闲置的机器资源提升物理机的资源利用率。这也是为什么在云服务商这么高的运作成本下FaaS还能免费提供给大家使用。
![](https://static001.geekbang.org/resource/image/41/9b/4162456b4550db3be9be6daead865d9b.png)
我介绍SLA主要是希望你能对云服务商提供的服务层级有个认识。我们在设计和运维自己的应用时需要综合考虑到可用性和价格。FaaS是性价比最高的所以我们在日常使用时如果有适合FaaS的场景应该尽可能地使用FaaS。
如果要深入了解云服务我的经验是可以从云服务商网站的行业解决方案出发。先粗略了解一下有哪些行业解决方案便于我们掌握云服务商的能力边界。如果感觉比较凌乱的话最好自己用“脑图”梳理一次。另外再说句题外话我不建议你学习别人的脑图因为脑图都是自己梳理思考的过程你自己大脑的Map不一定适合别人别人的Map也不适合你。
言归正传我们自己在云上搭建K8s集群主要有2种方式购买虚拟机自建和购买K8s集群。当然首推购买K8s集群可以节省我们更多成本。K8s集群的Master节点阿里云K8s集群是不收费的而我们自己搭建则需要至少一台虚拟机。虚拟机自建比较适合大型或拥有强大运维团队的互联网公司。但无论是自建还是购买K8s集群我们搭建的K8s集群的底层都是IaaS。
## 云上部署K8s集群Knative
了解完选型相关的知识,接下来我们还是动手实操一下。
我们这节课的K8s例子选择了阿里云的Serverless K8s集群ASK。这个K8s集群的特点是Master节点是免费的只收取网关的费用Worker节点是虚拟节点而我们Pod中的容器是通过ECI容器创建的。传统的K8s集群ACK的Worker节点需要我们自己购买虚拟机授权K8s集群初始化成Worker节点。ECI是轻量级的Docker容器同时具备高性能和低价格的优势。另外ASK的Knative功能是新上线公测的推荐它还是因为性价比。
我们使用K8s集群同样可以自己安装Istio再安装Knative只需要注意K8s集群的版本就可以了。但云服务商提供的K8s集群通常都已经帮你准备好了控制台操作。所以实际上我们使用云端的K8s集群要比本地搭建还要简单。所以我们只需要在ASK控制台左边Knative公测中选择我们的K8s集群点击“一键部署”就可以了。当然如果你选择的云服务商不支持“一键部署”你可以通过查看K8s集群的版本号选择对应的Istio版本和Knative版本按照我们上节课所讲的内容自行安装K8s组件。
另外为了方便新手我还是需要提示一下如何在本地同时管理多个K8s集群。
首先我们打开本地的kubectl的配置文件$HOME/.kube/config我们可以看到这个K8s集群的配置文件主要分为3个部分clusters、contexts、users。
```
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: xxx
server: https://kubernetes.docker.internal:6443
name: docker-desktop
- cluster:
certificate-authority-data: xxx
server: https://k8s集群IP:6443
name: kubernetes
contexts:
- context:
cluster: docker-desktop
user: docker-desktop
name: docker-desktop
- context:
cluster: kubernetes-ask
user: kubernetes-ask-admin
name: kubernetes-admin-id
current-context: docker-desktop
kind: Config
preferences: {}
users:
- name: docker-desktop
user:
client-certificate-data: xxx
client-key-data: xxx
- name: kubernetes-admin
user:
client-certificate-data: xxx
client-key-data: xxx
```
我们将云上K8s给我们提供的集群凭据的cluster、context、user分别添加到config文件对应的clusters、contexts、users部分下面就可以了。
我们再次查看kubectl config get contexts就可以看到新添加的云上K8s集群了。
```
kubectl config get-contexts
```
剩下的操作就跟我们上节课保持一致了。我们只需要在knative-myapp里面执行kubectl apply就可以让我们的例子运行在云上的K8s集群了。
我们想访问云上K8s集群版本的“待办任务”Web服务时同样也是用kubectl查看kservice我们的域名。
```
kubectl get kservice
```
![](https://static001.geekbang.org/resource/image/d3/20/d3810957c110ba84a71085d20a510820.png)
紧接着通过查看ingress-gateway了解K8s集群的外网入口IP。
```
kubectl get svc -n knative-serving
```
![](https://static001.geekbang.org/resource/image/3c/b2/3cdd4a0a5affe9724a7c15755aa7beb2.png)
我们在本地通过Host绑定域名和EXTERNAL-IP就可以访问了。我再啰嗦一句如果是你自己的域名你可以通过修改域名的DNS解析A值指向这个EXTERNAL-IP就可以了。
![](https://static001.geekbang.org/resource/image/e6/55/e6d014f06a7a6047fef335052372b555.png)
我们同样也可以通过命名空间namespace看看这个K8s集群中都给我们安装了哪些组件。还记得我们讲过的FaaS的HTTP触发器认证方式吗我们部署在云上的K8s集群调用我们的FaaS函数就可以通过我们自己的容器实现函数鉴权的算法走函数鉴权流程了。
到这儿云上部署K8s集群Knative这个例子我们就实践完了不知道你有没有跟着我一起动手操作最后还有一点需要提示你一下如果你为了体验我们这节课的内容在云上自己购买了K8s集群测试那等部署完成后云上的K8s集群你一定要清理干净了除了通过kubectl delete清除我们部署的应用还要在云上删除K8s集群和worker节点否则还会持续产生费用。
## 总结
这节课我们学习了如何让本地的Knative应用打破云服务商的锁定部署上云。因为CNCF的K8s集群的可移植性我们可以在CNCF的云服务商成员中任意选择。我根据我自己的经验总结了一份云服务商的对比表格这个表格的内容对比了我们自身业务的特点还有价格等因素让我们自由选择适合自己的云服务商。
我们在云上创建好K8s集群使用K8s集群就跟我们本地使用是一样的而且很多云服务商还提供“一键部署”让我们快速安装K8s组件。最后我们就可以将Knative的应用部署上云了。
然而我们虽然可以用Knative解决Container Serverless的云服务商锁但却无法解决云服务商用FaaS构建起的新壁垒。每个云服务商FaaS的Runtime都不一样我们的函数代码要兼容多个云服务商部署要写很多额外的代码处理兼容性的问题。那么下节课我们就再看看如何破解FaaS的新Vendor-lock。
## 作业
这节课建议你创建一个云上的K8s集群并且将我们上节课的内容部署到云上的K8s集群。感受一下云上的K8s如何打通部署和提供给互联网用户访问。
期待你的实践总结,欢迎留言与我交流。如果今天的内容让你有所收获,也欢迎你把文章分享给更多的朋友。