构建可伸缩的-PHP-Web-应用-二-

110 阅读42分钟

构建可伸缩的 PHP Web 应用(二)

原文:Building Scalable PHP Web Applications

协议:CC BY-NC-SA 4.0

十、将 AWS 用于托管

虽然这本书的大部分内容都集中在在 Linode 上托管你的应用,但是由于这么多的云托管都是基于 AWS 的,所以我认为值得看看 AWS 上的一些托管选项。

AWS 的一个问题就是它的大量选项。可用选项的数量实际上使管理变得相当困难。

举个例子,有一次我在一个团队中工作,需要访问日志。经过大量搜索,我们终于找到了允许访问日志文件的选项。然而,事实证明查看日志文件实际上是不同于检索日志文件所需的权限。因此,虽然我有权限查看日志文件,但我没有权限实际获取它们。他们最终放弃了细粒度的控制,让我做了管理员。这并不是说 AWS 没有这种能力,只是试图管理它所花费的时间和精力与您通过其他不太“自动化”的方式所节省的时间和精力一样多。拥有大量的选择,并试图成为每个人的一切,很容易让你淹没在没有人有时间和机会掌握的选项和设置中。

有这么多细粒度的控制,每一个都有自己的问题、怪癖和缺陷。AWS“支持”的不同平台和系统的数量非常大。然而,我发现在这种支持中经常有很大的漏洞,虽然可以解决,但这些解决方法有时让我希望我一开始就手工完成了。

10.1 使用亚马逊 Lightsail

亚马逊首次涉足云托管被称为 EC2——弹性计算云。像大多数 AWS 一样,这是一个非常灵活的云托管选项。然而,它存在许多 AWS 固有的问题——成功地设置和使用它确实很复杂。不仅设置复杂,而且定价复杂得离谱。他们不仅对计算机时间收费,而且对硬件 I/O 请求也收费。没错,他们跟踪并向你开出硬盘访问次数的账单。

为了更好地与 Linode 和 DigitalOcean 等更易用的服务竞争,AWS 推出了亚马逊 Lightsail。Lightsail 的功能集和定价结构与我们在 Linode 上看到的非常相似。可以从包含 CloudFront 和 S3 的同一个 AWS 管理控制台访问 Lightsail。只需搜索 Lightsail,仪表盘看起来应该类似于图 10-1 。

出于我们的目的,需要注意 Lightsail 和 Linode 之间的一些细微差异:

  1. 默认情况下,Lightsail 实例通过公钥而不是密码连接,并将您连接到普通用户,而不是以 root 用户身份连接。

  2. Lightsail 的 CentOS 发行版的预装软件包与 Linode 略有不同。

    img/487291_1_En_10_Fig1_HTML.jpg

    图 10-1

    亚马逊 Lightsail 的初始仪表板

  3. 所有 Lightsail 实例都会自动添加到 Amazon 的私有网络中。其实你在盒子上,看到的唯一的 IP 地址就是私网地址。您收到的外部 IP 地址会被路由到内部 IP 地址。

  4. Lightsail 实例的备份必须手动进行。

  5. Lightsail 有一个单独的数据库服务,如果您不想自己管理数据库服务器,可以使用它。

要启动并设置新实例,请单击“创建实例”按钮。这将把你带到一个类似于图 10-2 的屏幕。

在这里,您需要选择将托管您的节点的数据中心(实例位置)。这与 Linode 略有不同,因为 AWS 同时拥有数据中心和可用区域。在 AWS 中,数据中心被组织成多个可用性区域。这些区域可以轻松共享资源以实现负载平衡,但是每个可用性区域都有单独的电源线和外部互联网连接。本质上,它们就像在同一个数据中心一样,但是不同可用性区域中的服务器不太可能受到同一事件的影响(例如断电或互联网)。例如,您可以将主数据库放在一个可用性区域中,而将副本数据库放在另一个可用性区域中。然后,如果主服务器的可用性区域关闭,副本服务器(因为它位于不同的可用性区域)可以升级并充当主服务器。

img/487291_1_En_10_Fig2_HTML.jpg

图 10-2

创建 Lightsail 实例

我们想要选择的平台是“Linux/Unix”然后,选择“仅操作系统”(其他选项允许针对特定任务预配置服务器)。之后,选择“CentOS”

向下滚动,您可以忽略大多数其他问题,并选择您希望的节点大小。然后,为了识别您的实例,像我们之前做的那样称它为template-node。单击“创建实例”创建机器。

AWS 可能需要一段时间来创建您的计算机。当它出现时,你可以点击机器,你将得到一个类似于图 10-3 的仪表板。要登录,只需点击标有“使用 SSH 连接”的按钮这将打开一个终端窗口,您作为用户centos连接到该节点。

您可以使用这个centos用户来代替本书示例中的fred用户。或者,你可以在需要时创建fred。然而,您仍然需要使用这个盒子作为root来配置它。要以root的身份登录,只需发出以下命令:

sudo su -

img/487291_1_En_10_Fig3_HTML.jpg

图 10-3

Lightsail 节点仪表板

现在您的会话将作为root用户。

Lightsail 节点附带的软件包与 Linode 节点略有不同。要让您的 Lightsail 节点类似于 Linode 系统的起始点,请发出以下命令:

yum install -y nano
yum install -y firewalld
systemctl start firewalld
systemctl enable firewalld

从这一点来说,你可以按照第三章和第四章的节点设置说明进行操作。

在第五章中,从备份创建新实例的机制只是略有不同。在 Lightsail 中,使用“快照”功能创建备份。您只需转到节点的“Snapshots”选项卡,为快照命名,然后创建它。创建完成后,您可以从该快照创建一个新节点,如图 10-4 所示。负载平衡器可以从主屏幕的“网络”标签下的 Lightsail 中创建。

img/487291_1_En_10_Fig4_HTML.jpg

图 10-4

从快照创建节点

之后,关于创建云的其余信息不会改变,因为这都是关于节点本身发生了什么。

10.2 托管在弹性豆茎上

虽然本书的大部分内容都集中在基础设施即服务(IaaS)云上,但我确实想花至少一些时间来介绍平台即服务(PaaS)云。AWS 有一个名为“Elastic Beanstalk”的 PaaS 云,它运行各种不同的应用类型,PHP 就是其中之一。

PaaS 云消除了云计算的所有系统管理工作。然而,问题是大多数先进的云系统最终都需要一些系统管理。当您有奇怪的配置需求时,PaaS 系统并不是不可用,而是正确、可维护地配置您的 PaaS 系统,并与您的平台提供商同步的工作量最终会比您像使用 IaaS 云一样完全控制要多。在任何情况下,在这一节中,我们将回顾使用 Elastic Beanstalk 启动和运行我们的应用需要做些什么。

在 PaaS 系统中,我们无法控制机器。因此,我们不能将特定的机器指定为数据库服务器、作业服务器等等。相反,每个应用可以根据 PaaS 系统的需要在任意多的机器上扩展或缩小。这通常意味着 PaaS 系统将管理数据库。

对于 AWS 来说,这意味着使用他们的关系数据库服务—RDS。将应用连接到 RDS 非常简单。Elastic Beanstalk 将为所有连接信息设置环境变量,我们只需编写应用来读取它们。

为了做到这一点,我们只需改变common.php并替换getReadOnlyConnection()getReadWriteConnection()功能。这两个功能应该如图 10-5 所示。

img/487291_1_En_10_Fig5_HTML.png

图 10-5

使用 RDS 访问数据库

这将根据 RDS 发送的环境变量组合成一个连接字符串。

第二,由于您不能直接访问数据库,我们需要一个 PHP 脚本来为我们创建数据库表。创建一个名为createdb.php的文件,其中包含以下代码。

img/487291_1_En_10_Fig6_HTML.png

图 10-6

使用 RDS 创建数据库

请注意,由于我们没有特定的服务器,这些更改是对我们个人计算机硬盘上的应用的本地副本进行的。一旦完成这些更改,您就可以开始了。

要从 Elastic Beanstalk (EB)开始,请返回 AWS 管理控制台并搜索“Elastic Beanstalk”在仪表板上,单击标题为“创建新应用”的按钮给它起个名字,然后点击“创建”

在 EB 上,应用可以划分为“环境”环境可以用于各种各样的事情,包括准备环境和生产环境,为不同的任务准备不同的服务器组,以及在应用的不同版本之间快速切换。出于我们的目的,我们将只有一个环境。因此,单击按钮创建一个新环境。它会问你创建什么类型的环境。我们想要一个“网络服务器环境”

下一个屏幕是配置屏幕,如图 10-7 所示。如果愿意,您可以命名您的环境,但是该屏幕上唯一重要的设置是选择一个“预配置的平台”显然,我们想要“PHP”默认情况下,它将加载一个示例应用。这就是我们现在想要的。单击“创建环境”完成该过程。

img/487291_1_En_10_Fig7_HTML.jpg

图 10-7

创造新环境

创建完成后,您将拥有一个类似图 10-8 的仪表板。在“概述”部分,它给出了应用、版本和平台的基本健康状况。在“最近事件”下,它列出了系统最近经历的所有操作。请注意在 EB 中的一切最终花费的时间比你想象的要长得多,但是“最近的事件”帮助你密切关注它,并在你等待的时候给你一些可看的东西。在左侧,我们将重点关注的三个区域是“仪表板”(我们现在所处的位置)、“配置”(应用的设置方式)和“日志”

img/487291_1_En_10_Fig8_HTML.jpg

图 10-8

EB 环境仪表板

因为我们从一个示例应用开始,所以您已经可以在您的 web 浏览器中加载这个示例应用了。在仪表板上,它有一个指向应用 URL 的链接。您可以单击它,它会将您带到示例应用。

在上传我们的应用之前,我们需要首先设置数据库。为此,请转到“配置”部分,然后转到“数据库”并单击“修改”这将允许您为您的应用创建一个 RDS 实例。将“引擎”设置为postgres,给它一个用户名和密码(一定要记下这些!),然后单击“应用”当健康状态显示为复选标记时(可能需要 10-20 分钟),您就可以上传您的应用了。

要上传您的应用,请将您的所有文件压缩到一个单独的 zip 存档文件中。然后,在仪表板上,单击“上传和部署”按钮从您的硬盘驱动器中选择 zip 文件,为该版本命名(具体名称并不重要),然后单击“部署”健康状态将变为刷新微调器,它将部署您的应用。当微调器变回复选标记时,您的应用就部署好了!

然而,我们还没有完全完成。当你点击链接,它会给你一个“禁止”的信息。这是因为我们没有一个index.php文件(尽管如果您愿意,您可以添加一个)。然而,我们需要创建我们的数据库,所以我们需要首先导航到createdb.php文件来创建数据库(只需在浏览器的 URL 末尾添加/createdb.php并点击 enter)。这会给你带来一个空白页,这很好。

现在,如果您更改 URL 以转到list.php,一切都应该正常工作了!

现在,您可以对您的应用做许多事情来使其可伸缩。这些都可以从您环境的“配置”选项卡中获得。默认情况下,EB 创建单服务器环境。要将其升级到负载平衡的应用,只需进入“Capacity”部分,将“Environment Type”更改为“Load Balanced”这会给你很多选择,你可以玩。最简单(也是最重要)的是“最小”和“最大”数量的实例。将最小值设置为2,以确保它为您启动至少两台机器。单击“应用”,等待几分钟,您的应用现在负载平衡。

您可以进行的其他更改包括

  • 在“实例”下,您可以更改每个单独实例的大小。

  • 在“负载平衡器”下,您可以更改许多变量,包括平衡机制。

  • 在“滚动更新和部署”下,您可以更改部署策略以消除更新期间的停机时间(“不可变”选项最适合生产,但是执行更新需要很长时间)。

  • 在“软件”下,您可以设置环境变量和 web 服务器配置选项。

  • 在“数据库”下,您可以更改数据库的大小。您还可以单击“Endpoint”链接,转到 RDS 管理控制台,使用其他数据库管理实用程序。

进行配置更改后,点击“应用”将使用给定的更改重新部署您的应用,这可能需要几分钟时间。如果您在运行应用时遇到任何问题,您可以转到“日志”部分,下载并查看最新的日志消息。

十一、使用谷歌云平台

既然您已经有了与多家云提供商合作的经验,我希望您能够意识到云的基本组件并不会因为提供商的不同而有太大的变化。每个人可能调用不同的东西,可能有一点点不同的设置过程,或者可能有一些额外的能力或限制。然而,就其核心而言,不同提供商的 IaaS 云托管的基础非常相似。

这本身就是 IaaS 的一个优势。这意味着,如果您想从一个 IaaS 迁移到另一个 IaaS,这实际上是一个相当简单的过程。这可能需要计划和执行时间,但是,由于节点本身在您的控制之下,您可以使环境彼此完全相同。

我们要看的下一个提供商是谷歌云平台(GCP)。GCP 是 2008 年成立的新公司(Linode 成立于 2003 年,AWS 于 2006 年上线)。GCP 与 AWS 非常相似,尽管配置起来有点麻烦。您可以在 https://cloud.google.com 报名,开始体验 GCP。

img/487291_1_En_11_Fig1_HTML.jpg

图 11-1

GCP 欢迎屏幕

11.1 设置模板节点

关于 GCP,首先要知道的是一切都被组织成“项目”每个项目有点像它自己的帐户,每个都有自己的资源、服务等等,但是都可以在同一个登录中访问。

当你登录谷歌云平台时,它应该看起来像图 11-1 。请注意,在顶栏上,文本“Google Cloud Platform”旁边,列出了您当前项目的名称。您可以单击当前项目来更改项目或创建新项目。对于这个例子,我将创建一个名为Book Examples Project的新项目。

屏幕左侧列出了 GCP 服务。要创建新机器,请转到服务的“计算”部分,单击“计算引擎”,然后单击“虚拟机实例”GCP 称它的机器(或节点,正如利诺德所说)“虚拟机实例”要创建新机器,请单击“创建实例”按钮。这将弹出一个类似图 11-2 的屏幕

我们将我们的机器称为template-node,并选择最小的机器类型(本例中为“f1-micro”)。对于启动盘,我们会选择 CentOS 7。向下滚动,有一个“防火墙”部分。确定“允许 HTTP 流量”和“允许 HTTPS 流量”都已启用。其余的默认设置你可以不去管。当一切都设置好了,点击“创建”, GCP 将为你创建一个新的机器,并返回到虚拟机列表屏幕。

img/487291_1_En_11_Fig2_HTML.jpg

图 11-2

创建 GCP 虚拟机实例

创建机器后,您可以使用“连接”选项登录。在“连接”栏的下拉菜单中,选择“在浏览器窗口中打开”,它将在您的浏览器中为您提供一个ssh会话。

CentOS 的这个安装与 Linode 的安装非常相似,除了(a)它不包括nano(您可以用一个简单的yum install -y nano来修复它),以及(b)它自动为您创建一个用户,并让您以该用户的身份登录。您可以通过运行以下命令轻松切换到 root 用户:

sudo su -

从那时起,您可以安装nano并执行第 3 和 4 章中概述的所有配置步骤。

img/487291_1_En_11_Figa_HTML.jpg公共与私有 IP 地址

GCP 和 Linode 之间的一个有趣的区别是,在 Linode 上,您的节点的公共 IP 地址是物理连接到您的节点的。也就是你发出ip addr show的时候,显示的是公有 IP 地址。当您添加专用 IP 地址时,它会将该专用 IP 地址添加到您的节点中。

然而,在 GCP,你的节点以私有地址和公有地址开始。但是,私有地址是唯一物理映射到设备的地址。在网络设备上配置公共 IP 地址,以便将这些请求转发到您的机器。

因此,在机器上的所有配置中,您将使用包装盒上的私有 IP 地址。此外,您不必担心只能监听您的私有 IP 地址,因为这实际上是您所拥有的全部。GCP 网络控制哪些服务可以从外部进入您的机器(这就是为什么您在设置虚拟机实例时选中了 HTTP 和 HTTPS 框,以告诉 GCP 将这些类型的请求路由到您的私有 IP 地址)。

基本上,除非另有说明,GCP 的一切都仅限于本地网络。

11.2 为远程访问设置数据库服务器

为了将我们的template-node用作数据库服务器,我们需要准备好远程访问我们数据库的设备。为此,我们需要做到以下几点:

  1. 修改/var/lib/pgsql/data/postgresql.conf并设置listen_addresses='*'。我们不需要专门将其设置为私有 IP 地址,因为这是我们唯一的 IP 地址,除非我们将 GCP 配置为允许,否则无法从互联网访问它。用systemctl restart postgresql重启 PostgreSQL,这样修改就会生效。

  2. 更改防火墙,以便我们允许连接到 PostgreSQL 服务器。这将是命令firewall-cmd --add-port 5432/tcp和带有--permanent标志的相同命令。

  3. 修改 PHP 代码getReadOnlyConnection()getReadWriteConnection(),使它们连接到正确的私有 IP 地址。

现在,负载平衡集群可以使用服务器了。

11.3 创建复制映像

在 GCP 创建复制映像是一个有点过于复杂的三步过程。首先,您需要为您的实例创建一个“快照”,然后您需要从该快照创建一个“映像”,最后您将需要创建一个“实例模板”快照本质上是机器的备份。该映像本质上是一个快照,旨在用于为机器创建新的引导映像。最后,实例模板将图像与机器设置(大小、配置等)结合在一起。)可用于非常快速地部署相同的机器。

创建快照是一个相当简单的过程。从主菜单(点击“谷歌云平台”旁边的三个栏),转到“计算”部分,选择“计算引擎”,然后选择“快照”单击“创建快照”按钮。它将询问快照的名称、源磁盘和位置。您可以随意命名,选择您现有的 VM 实例作为源磁盘,您可以不考虑位置(“多区域”是最灵活的选择)。点击“创建”, GCP 将为您创建一个新的快照。

现在,GCP 允许你从快照中创建实例。然而,为了利用 GCP 更多的特色,最好是从你的快照中创造出 GCP 所说的“形象”。为了做到这一点,进入主菜单,然后“计算”部分,选择“计算引擎”,然后选择“图像”它将加载一个巨大的预配置图像列表。你可以忽略这些。我们想塑造自己的形象。单击“创建图像”按钮开始。

给图像命名(如template-image),并将“源”设置为“快照”这将弹出一个菜单,询问您希望从哪个快照创建映像。选择您刚刚创建的快照。如果你愿意,你可以加上一个“家庭”的名字。这将使您能够创建带有相同“系列”名称的此实例的更新版本。

现在点击“创建”在这里,您可以根据映像创建新的机器。创建新机器时,在“启动盘”下,您的映像将出现在“自定义映像”选项卡下。

最后,我们需要将这个图像打包成一个实例模板。实例模板位于主菜单的“计算引擎”和“实例模板”下创建实例模板的过程与创建常规虚拟机实例的过程相同。不同之处在于,它不会立即创建任何实例,而是可以在以后用于快速部署完全预配置的机器。确保在创建实例模板时,将引导映像设置为您在上一步中刚刚创建的映像。

img/487291_1_En_11_Figb_HTML.jpg更加小心我们的模板

请注意,因为我们在成为模板的机器上设置了数据库,所以集群中的每个新 web 服务器实际上都有一个运行 PostgreSQL 的未使用的数据库副本。这本身不是问题,但是如果您要进行生产部署,您可能希望确保 PostgreSQL 在模板上是关闭的。因为 GCP 有很多步骤,所以本章的目标是减少为了获得一个运行配置而必须完成的步骤。

11.4 创建负载平衡组

但是,您也可以创建一个自动扩展、负载平衡的计算机组,称为“实例组”这类似于我们在第五章中所做的,但是 GCP 将会为你管理你的应用。换句话说,随着机器上的负载增加,GCP 会自动启动新的、相同的机器,并将它们添加到负载平衡器下。

img/487291_1_En_11_Fig3_HTML.jpg

图 11-3

创建实例组

您可以在主菜单的“计算引擎”下找到实例组单击“创建实例组”开始该过程。图 11-3 显示了该过程的样子。

为您的实例组命名。为确保提高容错能力,请选择“位置”下的“多个区域”。选择我们在 11.3 节中创建的实例模板。确保“自动缩放”设定为“开”如果您愿意,您可以将最小实例数设置为大于 1,以确保 GCP 在多个服务器上平衡您的应用负载。单击“创建”以构建您的实例组。

默认情况下,实例组做得很少。我们需要的是为实例组带来流量的方法。这是通过负载平衡器完成的。

要创建负载平衡器,请在主菜单下查找“网络服务”,然后查找“负载平衡”单击“创建负载平衡器”开始。接下来选择“HTTP(S)负载平衡”接下来选择“从互联网到我的虚拟机”,因为我们希望这个负载平衡器充当互联网和您的机器之间的网关。

下一个屏幕显示了主要的配置区域。首先,给你的平衡器一个名字。接下来,在“后端配置”下,选择“后端服务”,然后“创建后端服务”您需要命名您的后端服务(名称并不重要),然后选择您的实例组,然后创建一个健康检查(健康检查只需要设置为 TCP 端口 80)。然后点击“创建”,它将创建您的后端服务。您可以将“主机和路径规则”和“前端配置”保留为默认值。点按“检查并完成”以查看您的所有设置。最后,单击“创建”来构建您的负载平衡器。您可以访问生成的 IP 地址,它将在您的机器上平衡负载。

请记住,GCP 需要相当长的时间才能真正完成创建您的负载平衡器。即使在 GCP“认为”它已经创建完毕,并告诉您所有的实例都已经添加到负载均衡器中之后,仍然需要几分钟的时间来实现这一点。因此,在您的负载平衡器处于活动状态的最初几分钟,GCP 可能会在访问 URL 时报告错误。

img/487291_1_En_11_Figc_HTML.jpg移除负载平衡器

移除 GCP 负载平衡器比看起来要难。要删除我们以这种方式创建的负载平衡器,我们需要执行以下操作:

  1. 从负载平衡器列表中删除负载平衡器本身。

  2. 在负载平衡器列表屏幕上,有一个名为“后端”的选项卡点击查看您的后端服务。

  3. 在“Backends”选项卡下,单击您为负载平衡器创建的后端,并将其删除。

  4. 现在您的平衡器被移除了,但是您还需要移除您的实例组,否则您将继续为您的机器付费(在其他步骤完成之前,您将无法移除您的实例或实例组)。

  5. 如果您不想为您的映像付费,您还必须删除您的实例模板,然后删除您的映像和快照。

11.5 其他 GCP 服务

和 AWS 一样,GCP 也有许多其他服务,在创建云应用时也很有用。几项类似的服务包括

  • 云 SQL(类似于 RDS)

  • 存储(类似于 S3)

  • Memorystore(类似于 ElastiCache)

此外,GCP 还通过名为谷歌应用引擎的服务提供 PaaS 服务。

总的来说,GCP 有许多与 Linode 和 AWS 相同的服务,但使用起来稍微复杂一些。在某些极端情况下,这种复杂性会增加额外的可配置性,但很少需要。例如,GCP 使得将不同的子目录映射到不同的实例组变得相对简单。这使得在同一个主机名下托管多个应用并使每个应用成为不同的实例组变得更加容易。

对于大多数应用,GCP 的复杂性超过了它提供的可配置性。

十二、服务器管理技术

到目前为止,任何时候我们想要更新我们的云,我们都必须重新映像我们所有的服务器。这并不可怕,但也不是最佳选择。如果您设想运行一个有 20 台不同服务器的服务器群,您真的想每次重新部署代码时都重新映像它们吗?可能不会。如果要安装服务器补丁,是否要重新映像所有服务器?同样,可能不会。

幸运的是,有许多工具可以帮助管理许多机器。它们都有各种不同的侧重点,有些侧重于简化重复性任务,而有些则是完整的管理解决方案。我是一个简单的人,我通常更喜欢简单的工具,而不是大型的、包罗万象的工具。

12.1 在多台服务器上运行命令

假设我们想在集群中的每台机器上安装一个新的软件。ImageMagick 是一个流行的图像处理软件包。如果我们想在所有节点上安装 ImageMagick,过程相当简单。我们只是 ssh 到每个盒子,运行yum install -y ImageMagick,然后退出。

谢天谢地,有一款软件可以帮我们做到这一点,它叫做pssh,代表并行 SSH。您不需要在服务器上安装任何新的东西。pssh安装在本地机器上,然后使用常规的ssh机制在所有远程机器上运行相同的命令。

然而,在您的template_node机器上安装pssh可能更简单,这样您可以从任何地方使用它(也就是说,您可以登录到您的模板节点并从那里运行pssh)。pssh在 EPEL 包中有,所以我们可以通过以下操作将其安装到template_node上:

yum install -y pssh

要使用它,我们需要创建一个文件(我们称之为servers.txt)列出我们管理的所有服务器。使用nano创建文件,并将每个服务器的公共 IP 地址放入文件中。要使用pssh,你所要做的就是键入:

pssh -A -h servers.txt --user root COMMAND

只需用您想要运行的命令替换COMMAND。因此,我们可以发出以下命令将 ImageMagick 安装到每台服务器上:

pssh -A -h servers.txt --user root yum install -y ImageMagick

pssh会要求我们输入密码(这就是-A所做的),然后它会让我们知道它什么时候完成了任务。现在你所要做的就是确保你的servers.txt文件是最新的,你可以很容易地从一台机器上执行大多数管理任务。

当命令运行时,它会告诉您每台服务器的状态,如果出现故障,它会告诉您命令给出的错误代码。例如,对于三台服务器,输出可能如下所示:

[1] 23:00:32 [SUCCESS] 45.79.7.179
[2] 23:00:32 [SUCCESS] 45.79.7.180
[3] 23:00:32 [FAILURE] 45.79.7.181 Exited with error code 1

然后,您可能希望查看命令失败的机器,并确定哪里出错了。

12.2 同步多台服务器上的文件

由于现在在每台服务器上运行一个命令很容易,如果能够将一组文件复制到每台服务器上就好了。谢天谢地,pssh附带了两个文件复制工具,分别叫做pscpprsync,这样你就可以轻松地将文件复制到远程服务器上。这样,当您部署新版本的软件时,就不必重新映像每台服务器。pscp程序有时被称为pscp.pssh,所以如果安装pssh后没有找到命令pscp,尝试使用pscp.pssh

假设您有文件testme.html,并且您希望以用户fred的身份将它复制到每个服务器上的/var/www/html。要执行该任务,只需键入以下内容(全部在一行中):

pscp -A -h servers.txt --user fred
 testme.html /var/www/html/testme.html

如果要复制整个目录,可以使用同样的过程,但是要加上-r进行递归复制。

然而,pscp的一个问题是它不会为你删除文件。如果您想让两个目录保持完全同步,无论是添加还是删除,您都可以使用prsync,尽管它的语法有点严格。

如果我想将本地目录mirror_me镜像到位于/var/www/html/mirror_me的服务器,我将发出以下命令(全部在一行中):

prsync -A -a -x --delete --user fred
 -h hosts.txt mirror_me /var/www/html/

通过对命令使用pssh,对单个文件使用pscp,对整个目录使用prsync,对一组服务器进行基本管理是相当容易的。

还有几个工具专门用于在多台服务器上部署应用。其中比较受欢迎的是 Capistrano。Capistrano 是用 Ruby 编写和定制的,尽管它可以用任何语言部署应用。Capistrano 自动化了许多与文件部署相关的任务,包括

  • git存储库同步

  • 在服务器上维护应用的早期版本,以实现快速回滚

  • 使用符号链接来管理部署,以便整个部署在瞬间切换

  • 运行与部署相关联的自定义任务和脚本

随着您的应用变得越来越复杂,您的工具需求也将变得越来越复杂,拥有一个像 Capistrano 这样的工具将会满足这些需求。

12.3 全方位服务解决方案

虽然pssh允许您向一组机器发出命令,Capistrano 允许您以更健壮的方式自动化部署,但还有其他解决方案可以更进一步,完全为您管理目标系统。这些被称为“配置管理”系统。这些系统虽然可以处理各种各样的情况,但也带来了复杂性。对于大多数系统来说,我认为配置管理系统是多余的,它们增加了比解决问题更多的复杂性。然而,他们做得很好的一件事是强迫您记录您的配置是什么(并且希望记录为什么要这样设置)。简单地拥有一个正确配置的服务器并不能告知未来的管理员(或您自己)您的配置的哪些部分是默认设置的,哪些部分是专门为某个目的而配置的。使用配置管理工具,您的系统配置可以被记录和版本控制。

作为一个喜欢极简方法的人,对于系统配置,我非常欣赏 Ansible 系统,它甚至不需要在远程服务器上安装任何东西。Ansible 通过ssh完成所有的配置,并且很容易启动和运行。 http://ansible.com/ 有一个很好的用户界面,但它带来了额外的金钱成本(尽管也有开源的用户界面)。然而,如果您需要的只是一个命令行工具,那么开源版本是所有配置管理工具中占用空间最小的一个。

您甚至可以从 EPEL 软件仓库安装它,只需简单地:

yum install -y ansible

然而,如果你想全面发展,虽然有几个其他的选择,但许多开发人员选择的是 Chef。Chef 基于 Ruby 编程语言,开发人员可以随心所欲地进行复杂的配置。Chef 还有许多反馈机制,允许您查看所有托管服务器的状态。使用 Chef,您不仅可以随心所欲地配置服务器,还可以收集服务器上的数据和分析。

对于刚刚起步的应用,我建议只保留配置更改的手工日志。随着应用的成长和成熟(有望获得数百万用户),明确配置管理变得更加重要,并且可能值得转向更全面的解决方案。

我们看到的一些云系统内置了一些配置管理。GCP 的实例模板/实例组系统可以被认为是一个极简的配置管理系统。实际上,当您保持实例模板最新时,GCP 将在您的实例组中部署它。Elastic Beanstalk 允许使用称为“EB 扩展”的环境定制来定制部署应用的机器尽管从技术上讲,Elastic Beanstalk 是一个 PaaS,但是这些扩展允许您在要部署到的平台上执行配置管理。

十三、Linux 安全基础知识

本章并不是云安全的完整指南,而仅仅是为您指明正确的方向。安全与其说是一系列步骤,不如说是一个过程和一种思考方式,因此本章将重点介绍您需要如何思考来保护服务器的完整性和数据的完整性。

13.1 基本考虑因素

对于系统管理员来说,最重要的安全注意事项如下:

  • 我如何降低连接到互联网的风险?

  • 我可以在我的系统上运行并保持其功能的最小服务集是多少?

  • 如何限制不是每个人都需要的服务对服务器的访问?

  • 我所有的软件都安装了最新的安全补丁吗?

  • 有人可以通过哪些方式滥用部署在服务器上的服务,我该如何缓解这种情况?

安全性的关键是确定服务器的用途,然后删除与该功能没有直接关系的任何内容,以防止不必要的后果。你运行的每一项服务都是一个潜在的安全漏洞——总有一天有人会发现如何利用它。因此,您不希望暴露在对功能没有直接贡献的点上。

13.2 检查您当前的服务器

检查服务器上当前正在运行和监听的服务的最佳工具是ss(套接字统计)。要查找正在侦听连接的每个 TCP 服务,请以 root 用户身份运行以下命令:

ss -plnt

写有LISTEN的每一行都是一个正在监听 IP 连接的服务。如果“本地地址”是127.0.0.1::1(对于 IPv6 地址)或节点的私有 IP 地址,这意味着服务是受保护的——只有机器本身上的应用可以看到服务(在私有 IP 地址的情况下,在私有网络上)。然而,如果本地地址是*0.0.0.0::(对于 IPv6 地址),这意味着它可供任何人连接。

同样,对于 UDP 连接,您可以:

ss -plnu

对于每个可连接的服务(TCP 或 UDP ),您应该确保它不被您的防火墙允许,除非您完全确定您希望人们连接。要获取防火墙允许的服务列表,请发出以下命令:

firewall-cmd –list-all

“服务”和“端口”下列出的项目是防火墙允许通过的项目。您应该允许的服务有dhcpv6-client(由云用来配置网络)、ssh(以便您可以登录)、http(用于非 SSL HTTP 连接)和https(用于启用 SSL 的 HTTP 连接)。

尽管防火墙会阻止与未列出的任何内容的连接,但如果您有任何正在运行的服务正在侦听您并不特别需要运行的连接,您应该禁用该服务。此外,您应该定期检查您的防火墙,以确保其配置正确。

此外,您应该清点所有正在运行的进程,即使它们没有侦听连接。在 Linux 上最好的方法是使用命令ps -afxww。注意,每个人都有自己喜欢的ps称呼方式,但这是我的。

我不能给你一个应该/不应该运行的列表。但是,最好是了解每一块是做什么的,把不需要的那块关掉。运行的服务越少越好。

您也可以使用命令rpm -qa列出您已经安装的所有软件包。随着你越来越有经验,你应该能够卸载你不需要的程序。

13.3 根用户

Linux 安装中最危险的部分是根用户。这是危险的,原因有二。首先,它是超级用户,因此它对其他一切都有权力。第二,每个人都知道它的用户名,这使得自动黑客工具更容易攻破。

有几种方法可以减轻根用户的问题。它们包括

  1. 根密码应该是安全的(即,即使计算机也很难猜到)。事实上,每个用户的密码应该是安全的。

  2. 服务器不应允许远程直接 root 登录。为了防止通过ssh的直接根登录,修改/etc/ssh/sshd_config。如果已经有一行写着PermitRootLogin,将值从yes改为no。如果那里没有一行,添加一行表示PermitRootLogin no。保存文件后,执行systemctl restart sshd,更改将生效。之后,您需要以普通用户的身份登录,并使用su命令将用户切换到root

  3. 服务应该很少作为根用户运行,除非有压倒性的理由这样做。如果一个服务必须以根用户的身份做一些事情,那么直接与远程计算机对话的那部分服务就不应该是根用户。

  4. 用户不应该花太多时间作为根用户。在这本书里,我们大部分时间都是作为 root 用户度过的。相反,用户应该在自己的帐户下登录,然后使用susudo切换到 root 用户,获得临时 root 权限。

  5. 你应该安装某种类型的服务拒绝程序,比如fail2ban,它会在一定次数的失败尝试后禁止来自特定 IP 地址的登录。

通过防止人们成为 root 用户,运行不以 root 用户身份运行的服务,以及保护 root 帐户免受外部访问,入侵者造成损害的能力大大降低。

大多数管理员使用sudo来管理对根用户的访问。sudo命令允许用户使用自己的密码临时访问根用户*,或者在登录后无需密码。它已经安装在你的机器上,允许任何属于wheel组的用户以根用户身份运行任何命令。要将一个用户(比如,fred)添加到wheel组,发出命令:*

usermod -a -G wheel fred

现在,fred用户可以作为根用户运行任何命令,只需将sudo添加到命令的开头。例如,如果fred想要显示文件/etc/sudoers(sudo命令的配置文件),Linux 通常不会允许他这样做。如果他做了cat /etc/sudoers,操作系统会给他一个错误。但是,如果fredwheel组中,并且他发出了命令sudo cat /etc/sudoers,操作系统会要求他输入密码,并在重新验证他的身份后,为他运行该命令。

为了将psshPermitRootLogin=no一起使用,您需要使用sudo来切换用户。但是,pssh不喜欢交互,在要求用户输入密码时会出问题。因此,您需要修改sudo的默认配置,以便允许用户在不提供密码的情况下使用sudo(他们仍然需要密码才能登录)。为此,作为根用户,向/etc/sudoers添加下面一行:

%wheel ALL=(ALL) NOPASSWD: ALL

现在,要使用pssh,您需要以fredsudo的身份登录来执行您的系统管理命令,如下所示:

pssh -A -h servers.txt --user fred sudo put_your_command_here

13.4 安装 Web 应用防火墙

web 应用防火墙是位于您的 web 应用和互联网之间的一个软件。web 应用防火墙的目的是检查传入流量中已知与恶意意图一致的模式,然后阻止这些请求。web 应用防火墙不能弥补 web 应用中糟糕的编程,但它通常会阻止自动化黑客工具找到漏洞。

Apache 为它提供了一个易于安装的 web 应用防火墙。要安装它,只需以 root 用户身份执行以下操作:

yum install -y mod_security mod_security_crs
systemctl restart httpd

然而,对于我们的测试站点,web 应用防火墙可能会阻止使用 URL 中的 IP 地址的请求,因为这是许多黑客攻击的特征!事实上,我发现对于许多生产系统,我不得不禁用几个单独的规则来让 web 应用防火墙与我的应用一起工作。这可能是痛苦的,但总的来说这是值得做的。

web 应用防火墙将在日志文件/var/log/httpd/error_log中记录拒绝请求的规则。因此,您可以在日志中找到规则 ID 号,然后在配置中禁用它。只需将行SecRuleRemoveById IDNUM添加到文件/etc/httpd/conf.d/mod_security.conf中,禁用不需要的规则。

13.5 检查 Rootkits

一个 rootkit 是一个由入侵你的服务器的人安装的软件,它可以让你更容易地控制你的服务器进行邪恶的行为。如果你的服务器是安全的,就不太可能有人闯入,但是定期检查还是有好处的。

rootkit 检查的两个标准软件是rkhunterchkrootkitrkhunter目前是 EPEL 的一部分,可以安装:

yum install -y rkhunter

要运行程序,只需做rkhunter --check。请注意,它可能会产生错误的警告和误报,因此请务必检查日志,以了解在查看问题时,它具体发现了什么。

13.6 其他安全软件

您可以安装和使用许多其他安全软件包。重要的是要知道有什么措施可用,并看看它们是否符合您的需求。

一些额外的 Linux 通用安全包包括

  • logwatch :该工具在记录到可疑活动时分析日志文件和电子邮件管理员。

  • 这个程序寻找重复登录失败和其他可疑的行为,并将阻止看起来像他们试图闯入的 IP 地址。

  • 安全增强的 Linux 是一种操作模式,在这种模式下,Linux 内核为程序提供了非常细粒度的访问控制,限制了每个程序和用户可以做的事情。SELinux 可以提供很多风险缓解,但是它的设置相当复杂,并且很容易意外地阻止您自己的应用做它们需要做的事情。我们在本书中禁用了 SELinux,因为它需要大量的配置问题。

  • 这是本书中使用的标准防火墙管理应用。

  • AuditD :该程序查找并记录应用的可疑活动。

  • 远程系统日志:这不是一个程序,但是系统日志可以配置为记录到远程服务器,这样入侵者就不能通过修改日志文件来掩盖他们的踪迹。

应用安全性

最难保护的是应用本身。实际上,如果不写另一本书,我无法提供很多建议。尽管如此,要记住的最重要的事情是

  1. 防御性编码。

  2. 验证来自用户的每一条数据。

  3. 正确转义发送给用户的所有内容。

  4. 在执行操作或显示数据之前,一定要仔细检查用户的权限。确保仅仅知道一个 URL 或一个参数不会自动给用户不适当的权力。

  5. 对发送到外部命令或程序的任何内容都要非常小心。仔细检查你是否已经正确地转义或过滤了所有内容。

  6. 想象一下,如果有人恶意操纵数据和请求,会发生什么。

  7. 总是尝试使用“最佳实践”来编码(例如, https://phptherightway.com/ )。在编码时使用最佳实践可以避免其他人引入的安全问题,包括那些您后来在应用增长时不小心引入的问题,以及由于代码库中其他地方的更改而将当前安全的代码变成不安全的代码。

另外,请务必在 www.owasp.org 查看常见漏洞列表

为了保护您的服务器和应用,您可以也应该做许多其他的事情,但是希望这已经给了您一个需要考虑的事情的开始列表。PHP 有时会因为安全问题而获得不必要的坏名声。然而,其原因并不在于语言,而是因为它通常是安全经验较少的新 web 程序员学习的第一门语言。有一些资源可以帮助您开始这方面的工作,包括

  1. 作者 Ben Edmunds :这是一个简明扼要的 PHP 安全实践指南。

*** Chris Snyder,Thomas Myer 和 Michael Southwell 撰写的Pro PHP Security**:这是一个更全面的关于 PHP 安全和安全原则的指南。这是一本较老的书,但核心安全原则没有改变。**

 *   ***掌握 Linux 安全并强化*** **作者 Donald Tevault** :如果你的服务器没有正确配置,编写安全的 PHP 代码对你没有任何帮助。

 *   ***实用信息安全管理*** **作者托尼·坎贝尔**:这本书将帮助你在更高层次上理解什么是安全的,什么是受保护的,如何管理权衡,以及安全的最终目标是什么。

 **

然而,最重要的事情是始终考虑您的应用如何被滥用,并始终学习新的方法来主动防范这些事情。