周志明
周志明 未有知而不行者,知而不行,只是未知。
将自己认为掌握了的知识叙述出来,能够说得有条理清晰,讲得理直气壮;能够让他人听得明白,释去心中疑惑;能够把自己的观点交予别人的审视,乃至质疑,在此过程之中,会挖掘出很多潜藏在“已知”背后的“未知”。
2021年05月03日入驻 合计 1 个作品 累计 56.53 万字 共有 1 订阅
  • 服务质量与优先级

  • 资源模型

    调度是容器编排系统最核心的功能之一,“编排”一词本身便包含有“调度”的含义。调度是指为新创建出来的 Pod 寻找到一个最恰当的宿主机节点来运行它,这个过程成功与否、结果恰当与否,关键取决于容器编排系统是如何管理与分配集群节点的资源的。可以认为调度是必须以容器编排系统的资源管控为前提,那我们就首先从 Kubernetes 的资源模型谈起。
  • 容器存储与生态

    容器存储具有很强的多样性,如何对接后端实际的存储系统,并且完全发挥出它所有的性能与功能并不是 Kubernetes 团队所擅长的工作,这件事情只有存储提供商自己才能做到最好。由此可以理解容器编排系统为何会有很强烈的意愿想把存储功能独立到外部去实现,在前面的讲解中,笔者已经反复提到过多次 In-Tree、Out-of-Tree 插件,这节,我们会以存储插件的接口与实现为中心,去解析 Kubernetes 的容器存储生态。
  • Kubernetes 存储设计

  • 容器网络与生态

  • Linux 网络虚拟化

    Linux 目前提供的八种名称空间里,网络名称空间无疑是隔离内容最多的一种,它为名称空间内的所有进程提供了全套的网络设施,包括独立的设备界面、路由表、ARP 表,IP 地址表、iptables/ebtables 规则、协议栈,等等。虚拟化容器是以 Linux 名称空间的隔离性为基础来实现的,那解决隔离的容器之间、容器与宿主机之间、乃至跨物理网络的不同容器间通信问题的责任,很自然也落在了 Linux 网络虚拟化技术的肩上。本节里,我们暂时放下容器编排、云原生、微服务等这些上层概念,走入 Linux 网络的底层世界,去学习一些与设备、协议、通信相关的基础网络知识。本节的阅读对象设定为以实现业务功能为主、平常并不直接接触网络设备的普通开发人员,对于平台基础设施的开发者或者运维人员,可能会显得有点过于啰嗦或过于基础了,如果你已经提前掌握了这些知识,完全可以快速阅读,或者直接跳过部分内容。
  • 以应用为中心的封装

    看完容器技术发展的历程,不知你会不会感到有种“套娃式”的迷惑感?容器的崛起缘于 chroot、namespaces、cgroups 等内核提供的隔离能力,系统级虚拟化技术使得同一台机器上互不干扰地运行多个服务成为可能;为了降低用户使用内核隔离能力的门槛,随后出现了 LXC,它是 namespaces、cgroups 特性的上层封装,使得“容器”一词真正走出实验室,走入工业界实际应用;为了实现跨机器的软件绿色部署,出现了 Docker,它(最初)是 LXC 的上层封装,彻底改变了软件打包分发的方式,迅速被大量企业广泛采用;为了满足大型系统对服务集群化的需要,出现了 Kubernetes,它(最初)是 Docker 的上层封装,让以多个容器共同协作构建出健壮的分布式系统,成为今天云原生时代的技术基础设施。
  • 以容器构建系统

    自从 Docker 提出“以封装应用为中心”的容器发展理念,成功取代了“以封装系统为中心”的 LXC 以后,一个容器封装一个单进程应用已经成为被广泛认可的最佳实践。然而单体时代过去之后,分布式系统里应用的概念已不再等同于进程,此时的应用需要多个进程共同协作,通过集群的形式对外提供服务,以虚拟化方法实现这个目标的过程就被称为容器编排(Container Orchestration)。
  • 容器的崛起

  • 介绍

  • 向微服务迈进

    这部文档的主体内容是务实的,多谈具体技术,少谈方向理论。只在本章中会集中讨论几点与分布式、微服务、架构等相关的相对务虚的话题。
  • 服务网格

    服务网格(Service Mesh):服务网格是一种用于管控服务间通信的的基础设施,职责是为现代云原生应用支持网络请求在复杂的拓扑环境中可靠地传递。在实践中,服务网格通常会以轻量化网络代理的形式来体现,这些代理与应用程序代码会部署在一起,对应用程序来说,它完全不会感知到代理的存在。
  • 持久化存储

    容器是镜像的运行时实例,为了保证镜像能够重复地产生出具备一致性的运行时实例,必须要求镜像本身是持久而稳定的,这决定了在容器中发生的一切数据变动操作都不能真正写入到镜像当中,否则必然会破坏镜像稳定不变的性质。为此,容器中的数据修改操作,大多是基于写入时复制(Copy-on-Write)策略来实现的,容器会利用叠加式文件系统(OverlayFS)的特性,在用户意图对镜像进行修改时,自动将变更的内容写入到独立区域,再与原有数据叠加到一起,使其外观上看来像是“覆盖”了原有内容。这种改动通常都是临时的,一旦容器终止运行,这些存储于独立区域中的变动信息也将被一并移除,不复存在。由此可见,如果不去进行额外的处理,容器默认是不具备持久化存储能力的。而另一方面,容器作为信息系统的运行载体,必定会产生出有价值的、应该被持久保存的信息,譬如扮演数据库角色的容器,大概没有什么系统能够接受数据库像缓存服务一样重启之后会丢失全部数据;多个容器之间也经常需要通过共享存储来实现某些交互操作,譬如以前曾经举过的例子,Nginx 容器产生日志、Filebeat 容器收集日志,两者就需要共享同一块日志存储区域才能协同工作。正因为镜像的稳定性与生产数据持久性存在矛盾,由此才产生了本章的主题:如何实现容器的持久化存储。
  • 附录

  • 架构安全性

    即使只限定在“软件架构设计”这个语境下,系统安全仍然是一个很大的话题。我们谈论的计算机系统安全,不仅仅是指“防御系统被黑客攻击”这样狭隘的安全,,还至少应包括(不限于)以下这些问题的具体解决方案:

    认证(Authentication):系统如何正确分辨出操作用户的真实身份?
    授权( Authorization):系统如何控制一个用户该看到哪些数据、能操作哪些功能?
    凭证(Credential):系统如何保证它与用户之间的承诺是双方当时真实意图的体现,是准确、完整且不可抵赖的?
    保密(Confidentiality):系统如何保证敏感数据无法被包括系统管理员在内的内外部人员所窃取、滥用?
    传输(Transport Security):系统如何保证通过网络传输的信息无法被第三方窃听、篡改和冒充?
    验证(Verification):系统如何确保提交到每项服务中的数据是合乎规则的,不会对系统稳定性、数据一致性、正确性产生风险?
    与安全相关的问题,一般不会直接创造价值,解决起来又烦琐复杂,费时费力,因此经常性被开发者有意无意地忽略掉。庆幸的是这些问题基本上也都是与具体系统、具体业务无关的通用性问题,这意味着它们往往会存在着业界通行的、已被验证过是行之有效的解决方案,乃至已经形成行业标准,不需要开发者自己从头去构思如何解决。

    在本章中,笔者会围绕系统安全的标准方案,逐一探讨以上问题的处理办法,并会以 Fenix's Bookstore 作为案例实践。因篇幅所限,笔者没有在文中直接贴出代码,如有需要,可以在Fenix's Bookstore 的 GitHub 仓库获取。此外,还有其他一些安全相关的内容主要是由管理、运维、审计领域为主导,尽管也需要软件架构和开发的配合参与,但不列入本章的讨论范围之内,譬如:安全审计、系统备份与恢复、信息系统安全法规与制度、计算机防病毒制度、保护私有信息规则,等等。
  • 透明多级分流系统

    本章,笔者将会根据流量从客户端发出到服务端处理这个过程里,所流经的与功能无关的技术部件为线索,解析这里面每个部件的透明工作原理与起到的分流作用。这节所讲述的客户端缓存、域名服务器、传输链路、内容分发网络、负载均衡器、服务端缓存,都是为了达成“透明分流”这个目标所采用的工具与手段,高可用架构、高并发则是通过“透明分流”所获得的价值。
  • 事务处理

  • 容器间网格

    本章我们将会讨论虚拟化网络方面的话题,如果不加任何限定,“虚拟化网络”是一项内容十分丰富,研究历史十分悠久的计算机技术,是计算机科学中一门独立的分支,完全不依附于虚拟化容器而存在。网络运营商常提及的“网络功能虚拟化”(Network Function Virtualization,NFV),网络设备商和网络管理软件提供商常提及的“软件定义网络”(Software Defined Networking,SDN)等都属于虚拟化网络的范畴。对于普通的软件开发者而言,要完全理解和掌握虚拟化网络,需要储备大量开发中不常用到的专业知识与消耗大量的时间成本,一般并无必要。本节我们讨论的虚拟化网络是狭义的,它特指“如何基于 Linux 系统的网络虚拟化技术来实现的容器间网络通信”,更通俗一点说,就是只关注那些为了相互隔离的 Linux 网络名称空间可相互通信而设计出来的虚拟化网络设施,讨论这个问题所需的网络知识,基本还是在普通开发者应该具有的合理知识范畴之内。在这个语境中的“虚拟化网络”就是直接为容器服务的,说它是依附于容器而存在的亦无不可,因此为避免混淆,笔者在后文中会尽量回避“虚拟化网络”这个范畴过大的概念,后续的讨论将会以“Linux 网络虚拟化”和“容器网络与生态”为题来展开。
  • 虚拟化容器

  • 演进中的架构

    架构并不是被发明出来的,而是持续演进的结果,本章我们暂且放下代码与技术,借讨论历史之名,来梳理软件架构发展历程中出现过的名词术语,以全局的视角,从这些概念的起源去分析它们是什么、它们取代了什么,以及它们为什么能够在竞争中取得成功,为什么变得不可或缺,又或者它们为什么会失败,在斗争中被淘汰,逐渐湮灭于历史的烟尘当中。