企业在 Kubernetes 落地的过程当中都会面临这样那样的问题,今天我把才云 Caicloud 过去在企业落地的过程当中出现的一些问题做个归纳总结,同时也把才云 Caicloud 在银联项目里的工作做一个分享和汇报。
微服务架构 VS 容器云平台
微服务架构和 Kubernetes 等容器云平台的结合,我们应该怎么去考虑。
两个框架之所以在企业中引发强烈讨论,基本有两个原因:
第一,在容器技术诞生之前,微服务框架就已经在开发人员的工作环境中出现了。微服务框架功能设计和实现,没有考虑到未来容器框架的出现。
第二,容器编排框架在设计、研发和开源之时,也没有考虑市面上还有很多像 SpringCloud,Dubbo,Sofa 等微服务框架。
两者都是对微服务支撑较好的技术方式,自然而然,在企业落地过程中,很多企业都面临微服务架构和 Kubernetes 容器框架的功能取舍问题。
互联网企业,几乎所有的服务都是微服务的框架形态。这时候遇到容器平台的时候,大部分情况需要做出选择。许多企业正在致力于传统企业向互联网企业转型,数字化转型的过程中,大服务拆分成微服务,是不是一定要用一整套微服务框架来治理微服务,答案是不一定。因为企业开发所使用的技术栈、开发语言可能是比较综合的,可能用了 Java、 Python 或 Ruby 等,用一套 SpringCloud 可能解决不了所有的问题,或许不采用微服务框架是更好的选择。
微服务框架在技术栈是相对封闭的,对语言的支持也比较有限,同时对代码的侵入性比较强。所以如果还有机会选择,建议可以考虑使用 Kubernetes,进而获取到微服务治理较松耦合的方式,后续逐步过渡到 Service Mesh。
刚才有同学问到 Kubernetes 相对于 Cloud Foundry 有什么优势?优势有不少,这里主要提两个:
第一,Kubernetes 框架优美,Kubernetes 不同于其他的开源项目,不少开源项目头脑风暴一下可能就开源了,但是 Kubernetes 开源的时候,有大量论文和论证支撑,开源是非常谨慎认真的,得以框架优美,后续的潜力也比较大;
第二,Kubernetes 技术框架非常有创新能力,使用 CRD 和 Controller,很容易实现松耦合的二次创新和开发。这些二次开发的内容,即便在 Kubernetes 的版本不断地更新迭代后,仍然可以无缝运行在 Kubernetes 中继续使用。
另外,微服务框架里面的一些场景在容器云平台中已不复存在了,比如说服务熔断,过去在微服务框架里头从代码层面、设计开发层面非常需要,但是到容器技术中,在资源可保障的前提下,所有业务都可以通过自动弹性伸缩,来迎接高并发高流量挑战。
由于把所有的业务同时一次性迁移到容器的平台上,非常冒险,当微服务逐步迁移到容器框架时,会出现业务在不同框架下的并行状态,有些微服务是在容器平台之外的,有些微服务是在容器平台之上的,微服务治理框架,比如说 Spring Cloud 中的服务发现系统应该跑在容器平台之外呢,还是容器平台之上呢?这是很多企业都面临的问题。
这些问题怎么造成的呢?是因为在底层的网络环境上面没有很好地进行考虑,当使用了 overlay 网络方式,如果恰好规划把注册服务放在容器平台之外,就会发现容器平台里面的服务在注册出来的时候产生问题,因为在网络层面容器不是合法 IP,注册到服务发现服务时,用 Node IP 还是用负载均衡 IP 来去注册,有可能造成服务无法访问的情况。所以,当应用业务不断容器化、不断微服务化、不断迁移到微服务容器平台时,需要考虑微服务框架存在于哪里,网络方案的选择,如何承载混合模式以及逐步迁移的模式。
多环境适配
企业也可能面临这样的问题:企业具有开发环境,测试环境,生产环境可能分成蓝绿环境;也可能是主中心,同城中心,异地灾备中心。在多环境里规划容器方案的时候会需要具有多集群的能力在不同环境当中进行物理隔离:
第一是多集群,在原生的 Kubernetes 中 Federation 支持多集群还不理想,需要考虑怎么样把多个集群更好地管理起来;
第二是多镜像仓库,多集群之后的如果是单镜像仓库,风险上还是比较大,我们通常认为在开发环境和运维环境之间是有一堵墙的,即镜像仓库,镜像在开发测试环境迭代很多次之后进入到开发的镜像仓库,但是并不是所有版本的镜像都会被推到生产环境中运行,需要在不同的环境里配置不同的镜像仓库,不同的镜像仓库之间可以单向或双向复制。复制的前提是什么呢?是审批。在被审批的情况下,什么样版本的镜像可以复制到运维中心的镜像仓库上线。还有一些企业的镜像通过后端的统一的存储进行传递和复制,不同的部门、不同的环境会对 NAS 有相应的访问权限,通过镜像在 NAS 里面存储的方式复制,进行多环境适配。
CaaS 和 IaaS
容器服务是 CaaS,CaaS 遇到 laaS 的时候他们两个的关系是什么?
有的企业认为 CaaS 就是 PaaS,PaaS 放在 IaaS 之上是天经地义的,底层可能是 VMware、OpenStack 或某种公有云,VM 上面可以把容器集群运行起来。还有一些企业认为容器只是一种虚拟化运行时。它跟 KVM 没有任何的区别,这些企业希望把容器变成虚拟化的一种,存储和网络打通,这样就可以在云平台的管理界面中同时使用容器和虚拟机的计算资源。
还有一些企业把容器完全看成是替代 IaaS 的一种方式,不使用 KVM,应用全部微服务化,只把容器作为虚拟化的运行时,但是仍然通过云的方式去管理存储网络。比如:京东和谷歌。
为了让 IaaS 能够更好地去运维,容易升级,我们可以把 IaaS 的一些服务容器化,也就是说把容器打包 IaaS 的管理服务。
Caicloud 在银联项目中采用的是第二种方式,把容器看成与 KVM 并列的虚拟化运行时,用于承载很多适合于容器的微服务应用。架构图如下:
左侧蓝色部分是 Caicloud 所做的容器平台,为了把容器变成跟 KVM 一样的虚拟化的选择,我们把容器和 OpenStack 在账户、租户、权限多个层面做了打通,当一个用户登陆系统的时候,他可以同时看到容器和虚拟机的资源,容器底层的存储,采用统一存储 NAS 和分布式存储 Ceph。网络包括硬件的 SDN 和软件的 SDN 都做了打通,在上层在云平台的管理界面实现总体管理,总的来讲,整个云平台打造成了一个既有 KVM 又有容器的混合云平台。
容器的存储问题
容器应用到企业之后,需要考虑容器平台和底层的存储融合和集成。可以使用两级架构:存储后端是容器中的存储服务;前端存储在提供给租户时,使用存储方案。
Kubernetes 难做到对于后端存储容量的管理。但是在真正企业落地的时候,如果你只能做到有限的存储读写和使用的功能是不够的,还要做到更深入可管理后端的存储容量,修改容量等,有时需要额外开发。
Caicloud 容器平台支持多种存储后端,包括公有云存储,开源的分布式存储,如 Ceph,GlusterFS 和商业存储。
拥有多种存储后端,管理员可以灵活地把存储后端暴露给前端的租户,每个租户在使用存储的时候,租户获取到的是多个存储方案,可以选定存储后端,选定读写方式,只读单读写还是多读写,同时指定在存储方案里用到多少容量可以创建多少个卷,用这样一个 package 的方式来提供给租户使用,比较灵活。
同时通过本地存储支持一些历史包袱的应用,如果不对本地存储做限制,就会把宿主机的存储空间越用越满,影响宿主机上的其他应用,当宿主机出现问题的时候或者容器出现问题的时候,容器被重新调度,使用亲和性调度到本地存储的宿主机上。
这里我们做了两件事:
第一,对本地磁盘的限额的管理。比如限制应用在这台宿主机上用本地存储只能用到三百兆,突破三百兆时就会被禁止。
第二,容器在发生问题被重新调度后还会被调度回到这台宿主机上,通过亲和性的方式来保证这个应用永远都不会出这台宿主机。
容器网络
在网络上也是一样的,容器平台进入到企业内部时需要与负载均衡器、防火墙,软硬件 SDN、网络控制和策略进行集成和适配。
这个案例当中,二三层网络跟 OpenStack 做集成,对应关系如下:
OpenStack 虚拟网络的关键要素:
第一是 Network,第二是 subnet,第三是 port。Kubernetes 中的 Namespace 对应到 Network, cidr 对应到 subnet,gateway 对应到 OpenStack 的 gateway 上。
利用 Kubernetes 中的 CRD 功能,这是比较综合且创新的一种方式。用 CRD 关联开发的 Controller 会一直 list watch Kubernetes 里的 etcd。只要创建出一个网络元素, Controller 就会看到,然后到 OpenStack 网络组件里去调用 Neutron API,创建相应的网络插件、Network、subnet 和 port。创建好之后,创建的信息再填回到 etcd 数据库里,这些数据会被 CNI Driver 看到,之后去配置 pod 网络。
具体方式如上图所示,容器在宿主机当中会挂在一个虚拟的网桥上,这个虚拟网桥可以给容器提供通断控制和流量控制。容器不同流量会通过不同的网桥和 vlan 发出。
对于 L4 层负载均衡,通过设计两个 CRUD 加上两个 controller 去 list watch etcd 里创建的 service,这个 service 会自动选择和添加 endpoint,并且写入 etcd。Controller 看到 etcd 中创建的 service 和 endpoint 之后,会去请求 OpenStack Neutron 的 LBaaS 来实现负载均衡器的创建。LBaaS 里的 Loadbalance VIP 使用 service 的 Cluster IP。Endpoint 的 IP 对应到 Neutron LBaaS 的 memberlist 中,比较巧妙地运用 Kubernetes 现有的资源对应到了 OpenStack 的 LBaaS 的相关资源,来实现负载均衡。在企业内部会很少用软件负载均衡器或者防火墙,所以我们在产品上做了大量 CRD 的资源,用于管理 F5,管理公有云 SLB。
如果把二层到四层全部都画到一张图上就如上图所示。
因为在容器的网络环境里加了一些网桥,所以同时可以实现应用的通断控制。同时在容器访问可以进行带宽控制,限定容器访问的最大流量。
多集群服务发现
服务发现系统上,Kubernetes 里有 CoreDNS。在多集群环境,不同的集群里面和集群之间也可以相互做服务发现,但需要改造。每个集群里有一个 kube-dns,中心集群里面有 dnsmasq,所有访问请求都会到 dnsmasq 去请求域名对应的 IP。如果 dnsmasq 保有这样的数据,它就会直接返回给请求的应用。如果没有这条记录,dnsmasq 会根据访问域名的后缀,提取集群名称,到相应集群的 kube-dns 查询,再返回给客户端。
固定 IP
在很多金融企业里也会有固定 IP 要求。如果 IP 不固定,应用有一个副本,这个副本在运行的过程中会产生一些日志和监控数据。当这个副本失败时,即使再把它重新漂移出来或者重新在其他节点创建出来,之前产生的数据也不会带过来,应用的生命周期数据是断开的。固定 IP 可以解决此类问题,当一个应用被迁移时,过去产生的日志信息和监控信息将会被保持,这样就可以记录到应用运行的历史情况。
服务访问
外部访问到容器云平台时,通过一个唯一的入口,四层通过负载均衡器方式来导入流量。在七层上使用 ingress controller 在 7 层实现不同域名或域名的子路径对应到不同的后端服务的实例中。
本文转载自才云 Caicloud 公众号。
原文链接:https://mp.weixin.qq.com/s/_NK77K6oDMRFUrp6nkEiNA
评论