当今容器技术被广泛关注,已经有越来越多的企业开始布局或者已经采用容器技术来构建自己的云基础设施。
在用容器设计新的微服务应用架构或者如何改造现有的应用时,应该了解哪些因素和相关特性,是企业在实施容器平台时必须要考虑的。
很多传统行业和互联网企业相比在容器技术方面起步稍晚,但近两年随着容器关注度的空前火热,企业进步也很快,大力推进容器相关能力的建设。
基于 Docker 的容器,是一种更轻量级的虚拟化,我们称之为 CaaS,就是容器级服务。它涵盖了 IaaS 跟 PaaS 两者的优势,可以解决应用的部署、开发运维、微服务这些问题,而且能够更快的加速业务的交付。
企业要用正确的姿态拥抱容器并且使用好容器,需要在应用容器技术之前考虑清楚以下九个关键问题:
- 企业容器云方案设计需要遵循什么原则?
- 容器云技术产品如何选型?
- 容器云的网络应该如何设计?
- 容器的持久化存储方案如何选择和设计?
- 容器云上日志集中管理如何设计?
- 容器应用的监控方案如何设计?
- 容器云的多租户和权限如何设计?
- 容器与 OpenStack 和 Kubernetes 集成的能力?
- 容器云如何实现高可用和跨区部署?
企业容器云方案设计需要遵循什么原则?
Docker 作为新一代的云计算技术,毫无疑问将会给整个虚拟化开发运维、微服务、持续集成与持续交付,传统的中间件以及我们的应用带来深刻的变化,实现更高的性能以及效率,那么企业容器方案设计应该遵循什么原则呢?
首先,我们要明确企业上容器云的目的,容器是为业务服务的,任何技术都是为了能够更好的服务业务,这是我们的出发点。
其次,结合业务特点选择合适的容器框架,比如我们的业务本身是不是可以基于新型微服务架构进行改造,业务是不是具有变化快、弹性大、更新迭代快等特点。
还有要和已有系统较好地对接整合,在上容器之前,企业通常都已经有比较成熟和稳定的其他 IT 系统,例如网络系统、集中监控系统、安全防护系统等。
为避免重复建设,同时也为了容器平台能够更容易被接受和使用,应让容器平台融入企业原有的整个 IT 系统,而不是另起炉灶重新建设。
容器平台要承载生产业务,也需要满足安全的监管合规要求,例如隔离不同安全等级的应用、支持对应用容器的安全漏洞扫描、安全有效的防火墙策略管理等。
生产环境的业务要求高可用性、连续性,还应该考虑整个容器应用层面的高可用性和数据连续性、安全可靠。
建设容器平台的目的是为应用带来灵活、弹性、节省资源等优势,这要求应用最好具备微服务架构、无状态化等特点,让这些优势更好地发挥。
但不适合容器化的应用也不能勉强,否则容器平台建设后,如果不能给应用和业务带来预期的价值,不仅浪费了大量企业投入,还使得容器平台的价值得不到认可。这是每一个投入大量精力和热情进行容器平台建设的人最不愿意看到的结果。
容器云技术产品如何选型?
技术选型这个问题有很多复杂的影响因素,包括技术和非技术两方面,不同的组织情况下也不尽相同。
一个企业在应用新技术前,还需要考虑 IT 部门自身的技术能力,包括开发能力、运维能力,同时对自身业务系统从开发平台、开发过程、开发规范等有决定能力。
如果企业自身的开发和运维能力不强,则采用成熟的 PCF、OpenShift 等方案是不错的选择。
如果考虑现有系统对接需求,包括监控、网络、安全需求等,特别是现有网络架构对容器的网络方案有较大影响时,应该考虑使用 Kubernetes、Mesos、Swarm 等开源方案更便于定制,也能较好的融入现有 IT 系统。
Kubernetes、Mesos、Swarm 这三个开源方案都是行业内比较火热的资源编排解决方案,但它们各自的立足点各有千秋。
从应用的发布环节来比较:Docker 的 Swarm 功能,以及 Kubenetes 的编排,Mesos 的调度管理,很难直接决出高低。
换言之,如果加上企业级应用场景,来辅佐容器技术选型,则会显得更有意义。
企业规模不大,应用不是太复杂
这时 Docker Swarm Mode 还是比较好用的,集群的维护不需要 Zookeeper,Etcd 自己内置,命令行和 Docker 一样用起来顺手,服务发现和 DNS 是内置的,Overlay 网络是内置的。
企业规模大一些、应用够复杂
这时集群规模有几百个节点,很多人就不愿意使用 Docker Swarm Mode 了,而是用 Mesos 和 Marathon。
因为 Mesos 是一个非常优秀的调度器,它的双层调度机制可以使得集群规模大很多,Mesos 的优势在于第一层调度先将整个 Node 分配给一个 Framework,Framework 的调度器面对的集群规模小很多,然后在里面进行二次调度。
如果有多个 Framework,例如有多个 Marathon,则可以并行调度不冲突,同时 Mesos 在传统数据计算方面拥有较多的案例,相信也是企业选型时考虑的要素之一。
企业规模大、业务复杂、应用粒度更细
这时 Kubenetes 就更适合了,因为 Kubernetes 模块划分得更细更多,比 Marathon 和 Mesos 功能丰富,而且模块之间完全的松耦合,可以非常方便地进行定制化。
还有就是 Kubernetes 提供了强大的自动化机制,从而使后期的系统运维难度和运维成本大幅降低,而且 Kubernetes 社区的热度,可以使得使用 Kubernetes 的公司能够很快地得到帮助,方便问题和 Bug 的解决。
任何新的技术都有着各自适用的场景,如何经受住实践的考验,并将新的技术转化为生产力才是重中之重。
容器云的网络应该如何设计?
Docker 一直以来的理念都是“简单为美”,从 Docker 对 Linux 网络协议栈的操作可以看到,Docker 一开始并没有考虑到多主机互联的网络解决方案。
Docker 成名以后,收购了一家网络解决方案公司 Socketplane,将原有的网络部分抽离,单独成了 Docker 的网络库,即 libnetwork。
libnetwork 实现了 5 种驱动,通过插件的形式允许用户根据自己的需求来实现 network driver,但 libnetwork 组件只是将 Docker 平台中的网络子系统模块化为一个独立库的简单尝试,离成熟和完善还有一段距离。
随着容器技术在企业生产系统的逐步落地,用户对于容器云的网络特性要求也越来越高,跨主机容器间的网络互通已经成为最基本的要求。
跨主机的容器网络解决方案不外乎三大类:
隧道方案
比如 Flannel 的 VxLan,特点是对底层的网络没有过高的要求,一般来说只要是三层可达就可以,只要是在一个三层可达网络里,就能构建出一个基于隧道的容器网络。
不过问题也很明显,一个得到大家共识的是随着节点规模的增长、复杂度会提升,而且出了网络问题跟踪起来比较麻烦,大规模集群情况下,这是需要考虑的一个点。
路由方案
路由技术从三层实现跨主机容器互通,没有 NAT,效率比较高,和目前的网络能够融合在一起,每一个容器都可以像虚拟机一样分配一个业务的 IP。
但路由网络也有问题,路由网络对现有网络设备影响比较大,路由器的路由表应该有空间限制,一般是两三万条,而容器的大部分应用场景是运行微服务,数量集很大。
如果几万新的容器 IP 冲击到路由表里,会导致下层的物理设备没办法承受;而且每一个容器都分配一个业务 IP,业务 IP 会很快消耗。
VLAN
所有容器和物理机在同一个 VLAN 中。如下图,是一个网友的测试报告:
图中我们看到 Calico 的方案和基于 HOST 的网络解决方案性能较好。
基于 HOST 的端口冲突和网络资源竞争比较麻烦,相对来说 Calico 的是纯三层的 SDN 实现,它基于 BPG 协议和 Linux 自己的路由转发机制,不依赖特殊硬件,没有使用 NAT 或 Tunnel 等技术。
它能够方便的部署在物理服务器、虚拟机(如 OpenStack)或者容器环境下,同时它自带的基于 Iptables 的 ACL 管理组件非常灵活,能够满足比较复杂的企业安全隔离需求。
关于容器应用的网络隔离还有多种解决方案,基本上就是把不同的应用容器放置在不同的 vlan/vxlan 中,通过让不同的 vlan/vxlan 不能互访而实现隔离。
简单的方案可以尝试用 docker overlay 来解决,首先创建不同的 network,然后在启动不同应用的容器时,使用 --net 参数指定容器所在的对应的 vxlan 即可。
结果是同一个 network 中的容器是互通的,不同的 network 中的容器是不通的。企业里应用目前是 OVS/Linux-bridge +VLAN 方案的比较多,但长远看来 Calico 方案前景不错。
容器的持久化存储方案如何选择和设计?
在讨论持久化存储之前,首先声明,运行容器并不意味着完全摒弃数据持久化。在容器中运行的应用,应用真正需要保存的数据,也可以写入持久化的 Volume 数据卷。
在这个方案中,持久层产生价值,不是通过弹性,而是通过灵活可编程,例如通过优秀设计的 API 来扩展存储。目前,主要支持 Docker 或 Kubernetes 的 Volume。
Docker 的容器卷插件
Docker 发布了容器卷插件规范,允许第三方厂商的数据卷在 Docker 引擎中提供数据服务。
这种机制意味着外置存储可以超过容器的生命周期而独立存在,而且各种存储设备只要满足接口 API 标准,就可接入 Docker 容器的运行平台中。
现有的各种存储可以通过简单的驱动程序封装,从而实现和 Docker 容器的对接。可以说,驱动程序实现了和容器引擎的北向接口,底层则调用后端存储的功能完成数据存取等任务。
目前已经实现的 DockerVolume Plugin 中,后端存储包括常见的 NFS、CIFS、GlusterFS 和块设备等。
K8S 的数据卷
K8S 的每个 Pod 包含一个或多个容器。Pod 可部署在集群的任意节点中,存储设备可通过数据卷提供给 Pod 的容器使用。
为了不绑定特定的容器技术,K8S 没有使用 Docker 的 Volume 机制,而是制定了自己的通用数据卷插件规范,以配合不同的容器运行来使用(如 Docker 和 rkt)。
数据卷分为共享和非共享两种类型,其中非共享型只能被某个节点挂载使用(如 iSCSI、AWS EBS 等网络块设备);共享型则可让不同节点上的多个 Pod 同时使用(如 NFS、GlusterFS 等网络文件系统,以及可支持多方读写的块设备)。
对有状态的应用来说,共享型的卷存储能够很方便地支持容器在集群各节点之间的迁移。
为了给容器提供更细粒度的卷管理,K8s 增加了持久化卷的功能,把外置存储作为资源池,由平台管理并提供给整个集群使用。
K8S 的卷管理架构使用存储可用标准的接入方式,并且通过接口暴露存储设备所支持的能力,在容器任务调度等方面实现了自动化管理。
容器云上日志集中管理如何设计?
容器常被用来运行需要快速故障迁移、弹性伸缩的应用或微服务,因此容器中运行的应用随着迁移、弹性伸缩的发生,应用日志很可能会在不同的运行节点中产生,这对容器应用的日志监控和问题排查带来了很大的麻烦。
相对来说,和大多数传统应用把日志写在本地文件系统不同的是,容器应用需要考虑把日志进行集中收集,然后写入外部的集中日志管理系统中。
传统的日志汇总收集方案主要有商业软件 Splunk、开源软件栈 ELK 和 Facebook 开源的 Scribe 等,其中以 ELK 最为广泛使用。
典型的 ELK 架构,优点是搭建简单、易于上手,缺点是 Logstash 耗费资源较大,运行占用 CPU 和内存高,另外没有消息队列缓存,存在数据丢失隐患,建议小规模集群使用。
如果大规模使用,则可以引入 Kafka(或者 Redis),增加消息队列缓存,均衡网络传输,再把 Logstash 和 Elasticsearch 配置为集群模式,以减轻负荷压力。
Logstash 占用系统资源过多,后来又有了 Fluentd,替代了 Logstash,被称作是社区方案中的 EFK,相比 Logstash 等传统日志收集工具,Fluentd 的日志收集功能对容器支持的更加完备。
在容器日志收集的时候,要注意以下两点:
避免写日志冲突
最简单的方式就是让容器在运行时挂载外部共享存储卷当做应用的日志目录,这样应用的日志会被实时写入外部共享存储以备后续处理。
这种方式需要我们做好控制,不同的容器不能挂载同一个外部卷,否则就会出现写日志冲突的问题,容器迁移的时候还需要重新挂卷。
不可忽视日志标准化
除了日志的集中收集,在应用改造上我们还应该重视容器应用的日志标准化问题。
当我们采用容器来运行微服务架构应用,一个业务调用往往需要经过多个微服务的调用链,整个业务处理过程的日志记录分散在不同的微服务日志中,这对通过日志进行问题诊断带来了很大的不便。
通过标准化日志,例如带上唯一的 ID 信息等,可以实现把同一个业务在不同微服务中的处理过程给关联起来。
通过标准化的应用日志,我们可以对交易率、成功率、响应时间等关键业务指标进行统一关联分析,作为问题预警、诊断分析、容量扩缩的科学依据。
容器应用的监控方案如何设计?
在虚拟机运维的时代,Nagios 和 Zabbix 等都是十分经典的性能监控软件。但在容器时代,这些曾经耳熟能详的软件,大多不能提供方便的容器化服务的监控体验,社区对开发这类插件和数据收集客户端也并不积极。
相反的是许多新生的开源监控项目将对容器的支持放到了关键特性的位置,一代新人换旧人,可以说容器的应用界定了一个全新的监控软件时代。
在这些新生的监控工具中,有三种比较流行且成熟的具体方案,分别是 cAdvisor、cAdvisor + InfluxDB + Grafana 和 Prometheus。
其中基于 InfluxDB 的方案是一个多种开源组件的组合方案,而基于 Prometheus 的方案是作为一种整体解决方案。
它本身对容器信息的收集能力以及图表展示能力相比其他专用开源组件较弱,通常在实际实施的时候依然会将它组合为 cAdvisor + Prometheus 或 cAdvisor + Prometheus+ Grafana 的方式来使用,但它多维度的数据模型,可方便的进行数据过滤和聚合。
说到容器应用的监控设计,在这里要注意监控是分层的,具体可以分为系统层面、应用层面和服务层面,每个层面都有自己的监控重点。
系统层面
主要是针对资源使用情况、网络连通性、节点健康情况的监控。传统的监控系统在这方面已经非常完备,我们直接可以利用传统的监控系统对容器平台的宿主机进行系统层面的监控,对接监控大屏幕等。
宿主机上单个容器本身的性能和资源使用情况,对于外部资源监控意义不大,也没有多大必要传送到外部的传统监控。
应用层面
容器平台本身通常都带有类似 K8S 的 replication control 这样的机制保持某个服务运行实例数量的能力,所以通常情况下容器平台都能保证应用和应用下每个微服务的运行正常。
关于应用层面的健康监控,还是需要来对接传统的监控系统,进行适当的告警输出,比如当遇到应用逻辑错误而导致启动反复失败或资源不足,导致启动总是不成功等问题时,容器平台本身的 replication control 机制就不能解决问题了。
这种情况就需要我们把应用的故障信息传递到外部监控,并根据问题的严重情况进行不同等级的告警通知等,由相关的应用人员介入来解决问题,比如升级补丁或回退等。
服务层面
服务层面则是监控应用提供的服务是否运行正常。例如某个提供 Web 服务的应用,在一些时候虽然应用和应用中微服务的运行实例数量正常,但它的 Web 服务已经失去响应,或者返回的是错误的状态,这种情况在多数容器平台中是无法监测到的。
传统的方式是通过打探针 Agent 方式,但在容器环境下,这种方式不一定可行,这就需要我们丰富容器故障的监测手段或者自己编写服务访问+检测逻辑来判断,并把检测出现的问题上报到外部监控,在监控中设立相应的告警策略和告警等级。
容器云的多租户和权限如何设计?
多租户,顾名思义,就是很多人来租用容器云平台的资源来实现自己的应用托管运维需求。这里面主要涉及多租户、资源管理与分配、安全权限管理这三个问题。
多租户的问题
从多租户的角度考虑,租户租用容器云平台的资源来托管、开发、部署运维自己的应用、服务。
容器云平台需要提供、维护保障租户能正常使用这些资源,同时给租户托管的应用提供服务注册、服务发现、服务配置、日志、监控、预警告警、弹性伸缩、负载均衡、安全等能力。
我们要明白的是租户只是租用这些能力,它并不运维这些能力。租户关注的是托管的应用和服务,它需要做的是利用平台提供的这些能力来无缝的运维他们的应用和服务。
一句话来总结:租户只是使用/租用资源,容器云平台管理运维这些资源。租户侧重于对自己的应用或服务进行运维。资源由租户申请,容器云平台来分配管理资源。
资源管理与分配
这部分功能建议统一由运维团队或者系统团队负责,应用系统上云前一般会进行压测,有个容量估算的过程。
通过容量估算和趋势分析,系统人员可以规划大致的资源池给相关应用,一般可以通过划分底层资源池实现。
如果用 K8S,可以在计算节点上通过 lables 进行规划,另外还需要在编排文件上设置好最小资源和最大资源,让应用可以弹性扩容。
安全权限管理
多租户的安全权限设计涉及到容器云平台整体的权限控制架构,最好是实现一个权限中心,由权限中心来实现对容器云各组件及各功能的动态控制,以适应灵活的不同的场景需求。
具体来说就是:
- 组织结构的实现可采用层次结构,无论多少层多少级,只标注其父结点 ID,树型结构遍历可以获得所有的结点,这也是我们下面权限访问控制实现的基础。
- 角色定义,需要基于用户及用户组织结构,权限和容器云提供给租户的功能列表来实现,可以采用 Oracle 数据库的用户角色权限定义方式来定义。
比如容器云平台初始化时可以预定义角色,比如租户管理员角色、应用管理员角色等,根据定义的角色权限展示不同用户视图。
把权限访问控制提取出来实现一个统一的权限中心组件,是因为整个容器云平台、各个组件都面临着权限访问控制需求。
从云计算的理念来说,松耦合、插件式的组件或模块设计更灵活和适用快速变化的需求。
对一个客户来说,一个组件可能需要也可能不需要,每个组件都可以以插拔的方式来控制,根据客户需求来部署相应的组件,实现相应的权限访问控制,将会更灵活和便利。
容器与 OpenStack 和 Kubernetes 集成的能力?
在开源云计算技术蓬勃发展的这几年中,OpenStack、Kubernetes、Container 无疑成为了改变云计算格局的三项关键技术。
但是这三者之间在技术上仍然存在一个空白:容器运行时强安全隔离的同时保持精简尺寸以及轻量级,以及如何能够很容易与 OpenStack 和 Kubernetes 两大平台集成从而获取多租户以及统一网络和统一存储等诸多好处,这个空白阻碍了用户从中获取更大价值。
为了解决这一问题,OpenStack 基金会在今年 12 月 5 日的 KubeCon 峰会上发布了一项新的开源项目,Kata Containers。
Kata 可以使用户同时拥有虚拟机的安全和容器技术的迅速和易管理性。项目可以屏蔽硬件差异并且和 OCIspeciaification、Kubernetes 容器运行时标准兼容,在支持标准镜像格式的同时具有强隔离、轻量级以及快速启动能力。
更重要的是 Kata 项目的设计初衷强调了能够无缝、便捷的与 OpenStack 和 Kubernetes 集成的能力。
无疑 Kata 项目的发起为 OpenStack、Kubernetes 和 Container 更好的融合提供了有力的支撑,并为用户从中收益铺平了道路。
期待容器真正辉煌时代的降临,但未来的道路,依然任重道远!
容器云如何实现高可用和跨区部署?
容器云需要考虑平台自身的高可用,实现多可用区多数据中心部署。
容器上的应用高可用需要结合应用架构来实现。目前微服务架构是最适合云基础设施的应用架构之一。
微服务应用通过服务注册发现、全局配置管理、熔断、服务追踪等容错设计,保证应用的高可用。
弹性扩容,增加微服务运行的实例数量,配合负载均衡策略的使用,减少因压力过大而导致运行实例宕机的情况。
总结
容器技术在企业的落地,不是一蹴而就的,是一个渐进和价值普及的过程。技术的更迭方式可以是潜移默化的和平演变,亦或是轰轰烈烈的武装革命,容器技术应该归属于前者。
我们可以看到,容器化技术已经成为计算模型演化的一个开端,可以预见在更高效和轻量化的平台实践之后,容器技术还将为整个 IT 领域注入更多新鲜和活力,在未来生存和壮大下去,成为引领潮流的决定性力量!
孙杰,资深系统架构师,专注于系统、数据库、云计算和数据中心管理,先后在外企、互联网、电商、大型企业任职,参与实施数据中心建设、私有云架构规划及运维管理、大数据挖掘等相关工作,在若干大中型项目的建设和部署运维中,积累了丰富的架构设计、项目实施和一线经验。