作者 | Marcos Vallim
编辑 | 田晓旭
本文将详细介绍相关技术栈的构成组件,包括 HAProxy、Corosync、Pacemaker、dnsmasq、cloud-init、LVM、Gluster、Docker 等概念。
想要先睹为快的读者,可直接克隆该项目的 GitHub 代码库。代码库中的文档正在持续改进中,并完全可用。代码库地址为:
mvallim/kubernetes-under-the-hood
1HAProxy
HAProxy 是一种开源、可靠且高性能的解决方案,提供高可用性和负载均衡,用于为基于 TCP 和 HTTP 的应用提供代理。它尤其适用于超高流量的 Web 网站,目前已为全球多个高访问量网站提供支持。近年来,它已成为开源负载均衡器的事实标准,随主流 Linux 发行版提供,并通常在云平台中默认部署。使用 HAProxy 对用户是透明的,只有通过系统管理人员才能确认后台部署情况。
引用自: http://www.haproxy.org/
我们将使用 HAProxy 创建用于 Kubernetes API 的负载均衡器(Load Balancer)。
考虑如下应用场景:只有一个 HAProxy 实例提供负载均衡的情况将会如何?这里我们引出架构单点故障( SPOF,Single Point of Failure)的概念。即无论由于何种原因导致单个 HAProxy 失败,就会完全失去对 Kubernetes API 的访问。当然,考虑到该组件在架构中的重要地位,我们应尽量避免这种情况的发生。
正如前文所述,为解决上述问题,需将 HAProxy 添加到支持浮动 IP 并配置至少两个 HAProxy 服务的高可用集群中。
总而言之,我们将构建支持负载均衡的高可用集群。
2Corosync
Corosync 集群引擎是一种群组通信系统(Group Communication System),为应用内部额外提供支持高可用性特性。一些项目已采用 Corosync 作为高可用框架,其中包括 Apache Qpid、Pacemaker 等。
引用自:https://clusterlabs.org/corosync.html
Corosync 主要目的包括两方面:维持集群的状态(即掌握节点加入和离开集群的时间),以及将消息分发给集群中所有成员。
维持集群状态
节点加入集群
要掌握集群的更新状态,集群的所有节点都应该安装并统一配置 Corosync。一个安装了 Corosync 的集群节点,在每次启动时会产生如下会话:
节点离开集群
一个节点在加入该“独一无二俱乐部”之后,它需要了解集群中所有节点。同样,集群中其它节点也会按对待先前加入的节点一样,以同样方式了解新节点。
为了掌握一个节点何时离开集群,Corosync 会持续监控节点成员的健康状况。由此,假设如下场景:
3Pacemaker
Pacemaker 是一种开源的高可用资源管理器。集群无论规模大小,均可适用 Pacemaker。
引用自:https://clusterlabs.org/pacemaker/
《LINUX Journal》指出,“权威的 Linux 平台开源高可用性堆栈,是构建在 Pacemaker 集群资源管理器之上的。”
在集群中,Pacemaker 创建并配置可由 Corosync 建立和管理的资源。
Pacemaker 的主要目的是支持集群中的负载均衡器高可用。为此,我们使用 Pacemaker 定义浮动 IP 和 HAProxy 资源。上述资源设置在由 Corosync 集群管理的集群中。
Pacemaker 使用了声明式方法。这意味着我们在创建配置文件中,需要指定每个节点上存在哪些资源,以及这些资源间的相关性。对我们而言,相关性定义了浮动 IP 和 HAProxy 资源间的相互依赖关系。相关性意味着资源间相互依赖。对于特定节点,如果 HAProxy 处于活动(Active)状态,那么在同一节点中浮动 IP 也应保持活动状态,反之亦然。
简而言之,如果某个节点处于活动状态,我们希望为该节点指派浮动 IP 和 HAProxy,并在节点上得到执行。同时,所有其它节点将处于非活动状态,直到该节点或该节点所附加的资源由于某种原因产生失败。一旦上述情况发生,活动节点所指派的资源将“迁移”到非活动节点,或在所有依赖条件得到满足的情况下在非活动节点上启动。这时,所选定的节点将成为活动节点,先前的活动节点转变为非活动状态。过程如下图所示:
4dnsmasq
dnsmasq 为小型网络提供了包括 DNS、DHCP、路由通告(router advertisement)和网络启动(network boot)等功能的网络架构。dnsmasq 在设计上是轻量级的,运行代价很小,适用于资源受限的路由器和防火墙。dnsmasq 还广泛应用于智能手机和便携式热点的网络共享,并支持虚拟化框架中的虚拟网络。其所支持平台包括 Linux(具有 glibc 和 uclibc)、安卓、BSD 和 Mac OS X。包括 FreeBSD、OpenBSD 和 NetBSD 移植系统在内的大多数 Linux 发行版中包含了 dnsmasq。dnsmasq 提供完全的 IPv6 支持。
引用自:
http://thekelleys.org.uk/dnsmasq/doc.html
我们使用 dnsmasq,为主机(节点)提供 DNS 和 DCHP 功能。
DHCP 和 DNS 可同步工作。也就是说,对于每台加入网络的新主机,DHCP 将更新 DNS 服务,并将主机名映射到所提供的 IP 上。这样,我们可以通过名字而非 IP 指定主机,无需操心具体的 IP 地址。
下面给出一个更实际的例子。当我们在云平台(例如 GCP、AWS、Azure 等)上创建一个新实例时,所创建的每个新实例将立刻在内部 DNS 中收到一个 IP、DNS 解析项、路由表项和主机注册项。最终,上述配置将由 DHCP 及 DNS 在后台实现。
5VirtualBox
VirutualBox 是一款虚拟化产品,适用于企业和家庭所使用的 x86/AMD64/Intel64 架构。VirutalBox 不仅对企业客户而言是一款特性非常丰富的高性能产品,而且也是唯一开源可用的专业解决方案,它使用 GPL v2 许可。
引用自:https://www.virtualbox.org/。
鉴于实际的裸金属服务器不可能直接访问,为模拟数据中心内的机器和网络,我们将使用 VirtualBox 这种开源替代解决方案。
VirtualBox 技术栈支持本系列文章介绍的所有理念。
6cloud-init
cloud-init 以开源软件开发和发布,它使用 GPLv3 和 Apache License v2.0 许可。它最初设计用于 Amazon EC2 中的 Ubuntu Linux 发行版,但它现在已在所有主流云服务提供商的许多 Linux 和 UNIX 发行版中得到支持。
引用自:https://cloud-init.io/
cloud-init 用于实例初始化的。它支持实例在启动时自动配置,在数秒内将通用 Linux 镜像转换为经配置后的服务器,快速简单。
在最新 Linux 发行版中提供的 cloud-init 工具,适用于执行服务、用户和软件包的设置。其中,cloud-config 文件格式是 user-data 脚本最广泛使用的格式。
cloud-config 文件是一种特殊的脚本,设计用于 cloud-init 工具处理。它们通常用于在服务器首次启动时的配置。
下面的 Youtube 视频给出了 cloud-init 运行情况。降低视频速度,可查看运行细节。
7LVM
LVM 即“逻辑卷管理”(Logical Volume Manager)。什么是逻辑卷管理?LVM 为计算机系统磁盘存储提供了比传统磁盘和分区视图更高层的抽象。LVM 为系统管理员在分配存储给应用和用户时提供更为灵活的分配。在 LVM 控制下创建的存储卷,可任意调整大小,并移动存储位置。
引用自:http://tldp.org/HOWTO/LVM-HOWTO/
假定一家企业要租用会议中心。会议中心所提供的会议室大小各异,即有适合 Google I/O 和 AWS re:Invent 如此规模大会的会议室,也有适合满足用户任何年度聚会需要的会议规模。
为最大化使用会议室空间的效率,每个场地基本上都是一个没有任何固定空间划分的巨大机库。LVM 配置允许企业将整体空间划分为大小各异的空间。
以 Google I/O 大会为例。会议期间可分配更大的空间用于主题演讲。主题演讲结束之后,可以将空间重新配置为更小的部分,用于大会中其他分会的会场。
这基本上就是 LVM 允许我们对磁盘所进行的操作。LVM 支持我们在无需实现明确服务器用途的情况下配置服务器。我们无需知道服务器将运行哪些服务,也不需要了解这些服务将生成的预期数据量。LVM 还允许我们实时操作和调整卷的大小,类似于上面例子中会议场地空间分配一样。
就我们的特定需求而言,我们要创建一个虚拟机镜像,作为许多其他镜像(例如 Gateway、HAProxy、Kubernetes 主节点或工作节点和 Gluster 等)的基础。不同的服务具有不同的空间需求(在此需分隔的会议空间就是 /var、/usr、/tmp、/opt、/etc 等),LVM 将可提供根据需要调整分区卷大小的灵活性,而无需事先操心具体细节。
8Gluster
Gluster 是一种实现可扩展网络文件系统的免费开源软件。
引用自:https://www.gluster.org/
上文中已介绍了 Gluster 的作用。
9Docker
Docker 是一系列部署了 操作系统层级虚拟化 的互操作 “软件即服务”(SaaS) 和 “平台即服务”(PaaS),实现在称为“ 容器”的标准软件包中开发和交付软件。运行容器的软件称为 Docker Engine。Docker 由 Docker, Inc 开发,在 2013 年首次推出。Docker 提供免费服务和高级服务。
引用自:
https://en.wikipedia.org/wiki/Docker_(software), https://www.docker.com/
Docker 最初基于 LXC 技术开发,但是现在技术栈已成独立。它不仅提供运行容器服务,而且更易于创建、构建、上载和控制镜像版本。
上面给出的容器简史,摘自维基等文献。
Docker 本质上是一种以容器格式打包软件的方法。那么这样做有何意义?这意味着,用户的所有软件及依赖项(例如软件库,配置等)都打包在容器中,这使得应用移植更为轻松,无需操心应用部署环境间可能存在的潜在差异。
该方法的一大优势是,用户可在任何其他环境或新机上启动容器,而不会出现意外错误或其他配置问题。因为用户应用所需的所有内容都打包在同一容器中。通过这种方式,容器实现了可预测、可重复和不可变的管理。
有人可能会提出,通过虚拟化也可以实现同样的目标。该说法并没有问题,二者实际在结果上是相同的。但最大的区别在于,使用容器技术时,用户能更好地利用资源。用户的操作系统资源能得到更好的共享,应用无需占用整个操作系统。为了更好地理解上述理念,可查看下图:
图片来自:https://www.redhat.com
尽管上述优势听起来真的很棒,但用户在 Docker 容器上运行应用生态系统时,究竟会发生什么?容器会大大降低系统管理工作的效率、操作繁琐并容易出错。为解决上述问题,Kubernetes 应运而生。Kubernetes 是一种开源容器编排系统,提供应用部署、扩展和管理的自动化,实现容器管理的智能化和整洁化。
10Kubernetes
Kubernetes(K8s)是一种自动部署、扩展和管理容器化应用的开源系统。
引用自:https://kubernetes.io/
正如上文所述,Kubernetes 是一种开源容器编排系统,用于自动化应用的部署、扩展和管理,并可实现容器管理的智能化并整洁化。
Kubernetes 的内部机制,将在本系列后续文章中介绍。
11Debian
Debian 是一种计算机使用的免费操作系统。操作系统是计算机运行一系列的基础程序和工具。
引用自:https://www.debian.org/
12Ubuntu
Ubuntu 是一种可从桌面、云和所有用户连接因特网设备运行的开源软件操作系统。
引用自:https://www.ubuntu.com/
参考阅读:
https://itnext.io/kubernetes-journey-up-and-running-out-of-the-cloud-technology-stack-9c472aafac4e