5月26日,时速云企业级容器 paas 技术沙龙第9期在深圳成功举办,时速云联合创始人兼技术总监杨乐就 paas 平台落地实施所关注的一些问题、kubernetes 核心组件、kubernetes 资源对象以及 devops 体系、微服务治理等方面做出了深入的探讨和分享。
以下是本次分享的实录:
杨乐:非常感谢大家,在这个天气炎热的周六来到这里。在这里给大家带来的是关于 paas 云平台在企业中落地的经验分享,其中包括了生产环境中关注的问题,kubernetes 的架构和资源对象的利用,以及我们在实际实施过程中遇到的一些问题。另外 paas 平台体系构建完成,是如何在容器云上进行的应用实践的,以及我们基于 docker、kubernetes 所构建 devops 体系持续集成,测试环境和生产环境是如何应用 kubernetes 去构建运行使用的,我们还会介绍微服务治理相关的架构,以及我们部署架构的知识。
基于docker和k8s的平台建设
1、paas 容器云平台落地实施关注的问题
在 paas 云平台落地的时候,会有一些关注点,我们在企业落地实施的过程中,首先关注架构运行的方式,也就是说我们最初架构的选型,以及它的核心组件,比如说我们的日志如何去收集,监控和报警组件是如何运行的。在 paas 平台上运行的应用,相关的应用服务是如何发布出去的,是以何种方式代理出去的。以及我们在落地实施的时候,平台自身的组件以及 kubernetes 本身的组件如何实现它的高可用,真正实现生产运行体系。
为了运行有状态应用,需要分布式存储进行支持。如何构建集群的网络类型,如何将容器服务进行集群内的网络打通。持续集成体系是我们基于 kubernetes 相关的资源对象去构建的开发测试运维一体化的子产品。而最终要去注重用户应用的发布、运行,同时需要以容器的方式在部署到 paas 平台,如何将应用容器进行互联。
我们会关注真正落地实施之后,从它的架构运营、高可用性,到最终成体系的构建、应用的部署。而这几个关键点,会在后面每一个对应到 kubernetes 架构体系上,一一介绍。
在场的各位对 docker 和 kubernetes 有没有一些了解,docker 是单机容器的运行引擎。而 kubernetes 是将容器以及 docker 做集群架构的体系,它的架构方式是 master、slave 的方式。也就是说 master 作为中控调动中心,去控制我的 slave 结点。而 slave 节点上面,所有的这些结点去运行相关的容器。应用服务都会用容器的方式运行在 slave 节点之上。而它的发布是通过 service 以及外部代理的方式向外发布。而每一个容器可以通过设置后端存储的方式进行持久的存储。
在 kubernetes 组件里,需要关注日志组件。当容器运行在 kubernetes 架构体系的时候,我需要关心应用本身产生的日志有没有问题。测试和开发人员需要获取一些调试的信息,然后去判断它的问题在哪里。而运维人员也需要查看发生问题的应用,它的日志在哪里。
当容器的 cpu 或者是内存发生了一些变动,超出负载的阈值时,需要做及时的报警。在内网进行服务发现的时,需要一个 dns 的配置,以此各个应用间可进行探测和调用。
我们后面会有一些存储和网络,网络需要支持我们整个集群之内所有的结点,容器之间需要网络的打通,可以让容器在内网之间做一个互联,做一个架构的连接。
2、kubernetes核心组件
kubernetes 核心组件包括日志、监控、kube-dns。从日志来说,kubernetes 这些日志组件是从 elsaticsearch 构建的。它会从节点里面收集相关的容器日志信息。会把这些信息发送到中控的 elsaticsearch 组件里面去。当这些信息收集完了之后,会通过外部的 ui、开发的ui的组件或者是用 kibana 展示组件去进行合理的展示。
运维人员和开发人员可以通过可视化的展示组件去检索对应的日志。对于日志来说,docker logs 是默认的日志输出的位置。但是通过一些特定的设置,不单单可以收集 docker logs 本身产生的日志,还能够指定应用所能够达到日志的位置,指定相关的目录,并能够随意收集容器内部日志的信息。
在监控体系方面,第一种方式,kubernetes 本身是使用 kubelet 以及 heapster、influxdb 构建的。influxdb 会把相关监控信息存储起来,监控数据从kubelet中通过heapster远程获取的。通过 grafana 去展示相关的监控信息。用户通过一个集中化监控展示平台,可以查看到指定的容器服务所用的 cpu、内存相关的监控信息。
第二种监控体系是使用 prometheus 组件,这两种体系是分别独立的。它的方式也是通过收集每一个节点相关的 cpu、内存等等监控信息,存储到一个中心化存储体系里面去,然后再把相应的监控信息展示出来。
对于报警体系,可以通过 prometheus 本身的一些规则的设置,可以设置达到我 cpu 预值20% 的时候会触发报警事件。它可以调用外部相关操作的动作,比如说调用我们的平台,调用我们平台 api 里面所集成的短信或者邮件 api。就可实现从我们平台发生的监控,比如说超过了预值的 cpu,自动发出报警给我们的管理员,管理员就可以在及时检测到cpu、容器以及节点它的问题所在。
kubernetes 一个核心组件就是 kube-dns,它是为 kubernetes 内部应用之间做服务发现。什么是服务发现,当我们把我们的应用去运行到 kubernetes 体系里面去的时候,每一个应用中需要有一定的机制发现对方。我需要知道我周围的这些应用运行的名字是什么,它的运行位置在哪里,它的 ip 是多少。我需要这样一套发现机制,而 kubernetes 本身提供的一方面把每一个应用和容器的信息记录到 master 里面去。同时用 kubernetes dns 的方式展现给其它的应用工具。
当用户创建应用后,会在内网 kube-dns 里面记录一个域名。 每一个域名对应我一个应用,当其它的应用容器想要连接指定的应用的时候,只需要通过 dns 域名就可以连接到。dns 的 kubedns 组件,不停的跟 master apiserver 进行交互,实时获取所创建或者是删除的这些应用的状态,获取ip地址、名称,并记录在 dns 存储空间里,形成一条条 dns 记录。而 dns 会把相应的记录信息整合成dns的服务出口。这样其它的应用服务可以通过dns的53端口,进行查询,和dns记录检索。这样就实现在整个联网范围之内,通过dns去查询到指定的应用服务的功能。
kube-dns 是可以应用到 kubernetes 本身的编排体系里面去。也就是说当我们运行应用到kubernetes 架构体系里面之后,它不单是一个应用,而是多应用需要编排在一起。编排在一起就需要每一个应用互相之间进行一个发现和连接,而连接就需要用ip地址或者是域名,这里面就是用域名的方式。
所以我在编排的时候,通过一个编排文件,把编排文件每一个应用之间,它是用域名的方式设计到里面去。通过编排文件它可以统一的创建所有的应用,让它同时去启动或者是顺序启动,进行一个架构的建设。
高可用性,高可用对于系统平台来说,包括 kubernetes 本身的高可用,还有我们提供自身产品的高可用,还有各种其它组件和存储的高可用。kubernetes 本身高可用提供的这种方式,首先 master高可用,master 高可用通过多个 master 的方式让它多活,然后通过统一的 keepalived 的方式跟 service 进行一个互联。
而相应的服务对外发布出口的时候,需要有一个对外的出口。底层存储的方式是通过多活的方式进行高可用的设置。平台本身每一个涉及到单点故障问题的组件都设置了高可用性,这个也是在生产环境中必要考虑的。
3、kubernetes的资源对象
kubernetes 的一些资源对象, kubernetes 的 pod 的概念,对容器本身来说,一个 pod 里面可以包含多个容器,而多个容器在同一个 pod 里面是可以共享网络和存储的。这就实现了在多个容器进行编排的时候,每一个容器都可以进行非常紧密的连接。deployment 可以对 pod 进行副本的管理,或者是进行滚动升级的识别。
而 service 这个概念就是一个抽象的服务出口,这就是为了将我的 pod 或者是我的容器运行在 kubernetes 之后,如何将它发布出去,如何让用户从外部进行一个访问,让 service 做这件事情,它实际上是在我们的节点上做了一个负载均衡器。一个基于 ios 一个负载均衡器。它会把用户外部访问的流量分发到内部多个 pod 或者是容器上面进行一个负载均衡。
labels 实际上是指在我 kubernetes 本身资源对象里面作为一个标签,以及标签选择的方式。
configmap 实际上是对数据的管理,我可以通过把我的一些外部配置信息放在 kubernetes 存储里面的一种方式。然后去解决我在构建完我的容器进项之后,我希望把我的这些进项放在不同的环境里面,而不同的环境外部配置信息反而不一样。而我又不希望更改我容器里面的这些内容。那就用外部的方式,将外置的配置信息加载到容器里面。
而这个 configmap 就起外部配置信息加载到容器里面的作用的。secret 本身是解决密码以及 token 相关的问题。job 是任务以及定时任务,我可以设置一个应用程序或者是一个进程让它运行一次,或者我可以设置定时进行。这些可以把它思考成一个 cronjob,也就是说一些定时任务会去做。
水平伸缩也就是说 hpa,在 kubernetes 里面,它可以做到应用容器的一些自动伸缩。可以根据我们的 cpu 或者是内存、网络或者是磁盘 aio,它的参数,进行一个实例的伸缩。如果我们设置了一个预值,如果 cpu 超过了 50%,那么我的容器自动扩展到 10 个或者是 20 个。当 cpu 低于百分之多少的时候,我可以让他自动回缩到指定的数量。这就是在负载变化的情况下,对实例伸缩的功能。
而下面的 stateful、volumes 以及 ingress,stateful 是为了解决有状态服务,以及可以做集群模式对象。volumes 是为了解决相关磁盘存储,还有 ingress 是 kubernetes 本身指定的负载均衡代理。
对于 kubernetes 资源对象 stateful 首先是为了解决有状态存储的一些应用。如果需要手动设置多个 pod 之间的存储配置,就会出现一个问题,pod 重启之后就消失了。所以如果我们手动配置的话,就很难做到他们之间主从的配置。
而 stateful 是为了解决这个问题,stateful 第一个特点是可以挂载相应的动态存储。第二他可以将起来的这些 pod 进行有序的标号,也就是说普通的 pod 的话,它的标号是随机的。但是这种 stateful 是有序的,从 0 开始一直到 n 为止。也就是说这几个 pod 之间是可以用有序的名字互相发现。这就带来一个可能,我在运行 stateful 的时候,我可以设置一些参数或者是脚本,让他们按照这个名字互相发现。这样你通过互相发现的方式,再进行主从之间一些动态设置。这就可以实现我起了多个容器,通过 stateful 进行一些动态设置。他们可以完成主从,进行集群的配置。也就是说 stateful 可以实现各个需要进行主从配置应用软件的集群设置。
ingress 我们之前提到作为一个服务出口,当我们的应用运行在 kubernetes 的时候,我们需要把它进行对外的发布,发布的方式可以通过代理的方式,也可以通过 ingress 的方式。
实际上 ingress 对应的就是我们所关注的服务出口的问题,而 ingress 是解决出口的方式之一,实际上还有其它很多种方式,也可以自研去做这个事情。
volumes 是解决整个 paas 平台它的存储问题,我们应用容器在运行的时候,如果我们用过 kubernetes,如果 pod 起来以后,如果不进行持久化存储的话,重启以后很多内容丢失。为了防止关键信息丢失,我们需要挂在分部式的存储。
一种方式就是我们通过 pvc 的方式,挂在一些文件体系上面。这样 pod 在进行迁移的时候,其中一个 pod 在机器上挂掉以后。它的存储会跟随我们的 pod 从另外一个可用的机器上起来。这样的话,它原来的内容可以在新的 pod 里面读取到,这样就达到存储可用性的效果。
kubernetes 网络类型也有很多种方式,现在我们常用或者是我们现在支持的方式就是包括让 calico、flannel、weave 的方式。实际上一种是隧道的方式,或者是用路由的方式去实现。
4、kubernetes生产环境的实施
从上图我们可以看到生产环境实施的整个架构模式图,首先对于 kubernetes 来说,整个集群各个组件模块是需要多副本的,整个控制台对 api 调用的控制端需要多个节点,以及镜像仓库、文件存储,以及相关的 slave 都是需要多节点的。
而在集群内部,需要一组服务出口。在应用的时候,持续集成所需要运行一组集群,这些都需要高可用去做。每一个功能组件,可以通过一种方式进行合理的分组。每种类型的组件或者应用,可以运行到指定的服务器节点上去。
容器云平台在企业中的应用场景
1、容器云平台功能体系
下面给大家介绍一下容器云平台在企业中应用场景,首先可以看一下整个容器云平台功能体系,首先是最基本的应用管理。可以通过 kubernetes 去创建应用,去管理应用。可以通过 kubernetes job 去实现持续集成的体系,包括代码仓库、镜像构建以及持续部署这些功能。微服务体系包括服务发现、负载均衡等,应用之间可以进行服务...