周志明
未有知而不行者,知而不行,只是未知。
将自己认为掌握了的知识叙述出来,能够说得有条理清晰,讲得理直气壮;能够让他人听得明白,释去心中疑惑;能够把自己的观点交予别人的审视,乃至质疑,在此过程之中,会挖掘出很多潜藏在“已知”背后的“未知”。
2021年05月03日入驻
合计 1
个作品
累计 56.53
万字
共有 1
订阅
-
Linux 网络虚拟化
Linux 目前提供的八种名称空间里,网络名称空间无疑是隔离内容最多的一种,它为名称空间内的所有进程提供了全套的网络设施,包括独立的设备界面、路由表、ARP 表,IP 地址表、iptables/ebtables 规则、协议栈,等等。虚拟化容器是以 Linux 名称空间的隔离性为基础来实现的,那解决隔离的容器之间、容器与宿主机之间、乃至跨物理网络的不同容器间通信问题的责任,很自然也落在了 Linux 网络虚拟化技术的肩上。本节里,我们暂时放下容器编排、云原生、微服务等这些上层概念,走入 Linux 网络的底层世界,去学习一些与设备、协议、通信相关的基础网络知识。本节的阅读对象设定为以实现业务功能为主、平常并不直接接触网络设备的普通开发人员,对于平台基础设施的开发者或者运维人员,可能会显得有点过于啰嗦或过于基础了,如果你已经提前掌握了这些知识,完全可以快速阅读,或者直接跳过部分内容。 -
以应用为中心的封装
看完容器技术发展的历程,不知你会不会感到有种“套娃式”的迷惑感?容器的崛起缘于 chroot、namespaces、cgroups 等内核提供的隔离能力,系统级虚拟化技术使得同一台机器上互不干扰地运行多个服务成为可能;为了降低用户使用内核隔离能力的门槛,随后出现了 LXC,它是 namespaces、cgroups 特性的上层封装,使得“容器”一词真正走出实验室,走入工业界实际应用;为了实现跨机器的软件绿色部署,出现了 Docker,它(最初)是 LXC 的上层封装,彻底改变了软件打包分发的方式,迅速被大量企业广泛采用;为了满足大型系统对服务集群化的需要,出现了 Kubernetes,它(最初)是 Docker 的上层封装,让以多个容器共同协作构建出健壮的分布式系统,成为今天云原生时代的技术基础设施。 -
持久化存储
容器是镜像的运行时实例,为了保证镜像能够重复地产生出具备一致性的运行时实例,必须要求镜像本身是持久而稳定的,这决定了在容器中发生的一切数据变动操作都不能真正写入到镜像当中,否则必然会破坏镜像稳定不变的性质。为此,容器中的数据修改操作,大多是基于写入时复制(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 网络虚拟化”和“容器网络与生态”为题来展开。