使用 Ansible 进行 Ceph 滚动升级

shan

Ceph rolling upgrades with Ansible

最近,我对几个月前编写的一个关于 Ceph 滚动升级的 playbook 进行了改进。这个 playbook 是 Ceph Ansible 仓库 的一部分,并且可用作 rolling_update.yml 让我们来看看它。

Ceph 的另一个优点是它能够在集群运行的同时执行滚动升级。对于一些人来说,这可能很明显,但对于像我这样在 OpenStack 上工作过的人来说,情况却大不相同 ;-)。因此,很高兴看到开发人员也考虑到了升级问题。我已经运行了几次不同的 Ceph 升级,并且它们都顺利完成,这要归功于开发人员提供的 极好的说明。几个月前,我在 Ceph Ansible 仓库 中启动了一项滚动升级工作,我对其进行了测试和验证。该 playbook 工作良好,但是它主要依赖于软件包中的 pre/postexec 脚本。我对这一点不太满意,因为在运行 playbook 时,我们没有考虑到集群的状态。现在,由于两个重要的检查,情况发生了变化。让我们深入了解这个 playbook。

I. 一般工作流程

为了正确执行 Ceph 升级,必须按照以下顺序进行,其中组件必须按以下顺序升级

  • 监视器服务器
  • Object Storage Daemons 服务器
  • MetaData Servers
  • Rados Gateway 服务器

这正是我们在 Ansible playbook 中执行的方式。组件升级正在被序列化,所以我们逐个节点进行。

II. 监视器升级

在此过程中,一个监视器将退出法定人数,具体取决于您拥有的监视器数量,这可能会很棘手。提醒一下,生产集群的推荐 最低 监视器数量是 3。这个节点 必须 始终是奇数。用 2 个监视器运行的情况并不舒服。知道如果一个节点在另一个节点升级时丢失,您将丢失法定人数。因此,在其他监视器完成升级之前,您的集群将处于停止状态。

但让我们保持乐观,这个过程并不那么冒险,而且速度也很快。当节点的升级完成并且监视器重新启动后,我们必须确保监视器重新加入法定人数。所以基本上,我们循环执行以下命令,并等待监视器恢复法定人数。

ceph -s | grep monmap | sed 's/.*quorum//' | egrep -q \{\{ ansible_hostname \}\}

我们可能会尝试从一个 peon 开始,我只是不确定这是否真的重要。

III. 对象存储守护程序

在此过程中,一些放置组将处于降级状态,因为 OSD 可能会关闭(或正在重新启动),我们不想触发恢复。为了满足此要求,我们将告诉集群不要在 OSD 关闭时做任何事情。默认行为是在 OSD 离线 5 分钟后将其标记为 CRUSH 映射之外。在这里,我们只是在这些 5 分钟后什么都不做。

所以我们向监视器发送以下命令

bash $ ceph osd set noout

现在我们可以开始(顺序地)运行升级,我们将

  • 升级 Ceph 包
  • 运行 OSD 角色
  • 最终重新启动 OSD 进程

在上述步骤中,放置组将处于降级状态,因此我们必须等待 OSD 重新启动并且所有放置组都干净。所以我们执行以下检查,将放置组的总数与 active+clean 放置组的数量进行比较。当它们不相等时,我们才移动到下一个节点

test "$(ceph pg stat | sed 's/^.*pgs://;s/active+clean.*//;s/ //')"
-eq "$(ceph pg stat | sed 's/pgs.*//;s/^.*://;s/ //')" \
&& ceph health | egrep -sq "HEALTH_OK|HEALTH_WARN"

同时,我们确保集群要么是 HEALTH_OK,要么是 HEALTH_WARN,它显然会因为我们设置的标志而具有 HEALTH_WARN

IV. 元数据服务器

升级非常简单,在软件包升级完成后,除了重新启动守护程序之外,没有太多要做的事情。

V. Rados 网关

根据设置的大小(超过两个?),您的 Rados 网关服务器在负载均衡器后面运行。它可以是 HAProxy 或 F5,在这里这并不重要。要成功完成升级,您必须在 Ceph 之外进行操作。使用负载均衡器,该过程非常简单。您只需从您的均衡器中删除一个 Rados 网关,等待没有请求正在被服务。然后您可以升级并重新启动它。完成后,将 Rados 网关重新添加到您的负载均衡器并移动到下一个节点。

VI. 运行 playbook

只需运行

bash $ ansible-playbook rolling_update.yml

请尝试一下,并帮助我们改进它。在 Ceph Ansible 上也欢迎提交 pull request