如何通过Red Hat Openshift实现K8S容灾?
越来越多的K8S应用采用RedHat OpenShift进行部署,IT团队需要部署容灾功能,来防范系统崩溃导致业务受损。一部分行业通常有较强的监管要求,在出现大规模错误的时候必须有数据保护。例如HIPAA 监管要求中的CFR 164.308(7)(ii)(B),要求公司必须能够在出现系统错误的时候“恢复所有数据”。这种情况下对于Openshift上的关键应用来说,容灾是必须的。
本文讲解了用户如何使用OpenShift和Portworx来实现零RPO的容灾。Portworx是Redhad容器目录认证的厂商,在OperaterHub上也有经过认证的Operator。能够为Red Hat客户提供完整的OpenShift体验。在我们进入如何在OpenShift上达到零RPO容灾之前,让我们首先来分析一下,传统的容灾方案为什么不适用于K8S。
传统的备份和恢复方案是在虚拟机(VM)层面来实现的。如果一个单一应用运行在单一虚拟机上,这种方案很合适。因为备份虚拟机和备份应用一样的。而运行在OpenShift上的容器化应用,却很不一样。一个虚拟机通常可以运行多个Pods,但不是所有的这些Pods都是为一个应用服务的。同样,一个应用也可能跨越多个虚拟机。容器化应用的通常架构模式中应用是分布在一组服务器集群上的。所以仅仅备份虚拟机就不合适了。要么过多备份了无用的内容,要么没有备份关键的应用数据。例如我想备份应用A,备份虚拟机的过程中,也会备份包括应用B和应用C的数据,这就会导致过多的备份。如果我备份了整个VM,而应用A运行在其他VM上的部分就没有被有效的备份,这就导致没有备份关键的应用数据。
为了解决这个问题,Openshift上的容灾需要的解决方案应是:
- 容器颗粒度的
- Kubernetes命名空间可感知的
- 应用一致的
- 能够备份数据和应用配置
- 能够为数据中心提供同步和异步备份的不同方式
Portworx企业版数据平台的PX-DR就是按照以上的原则设计的。
容器颗粒度的Openshift容灾
PX-DR是一个容器颗粒度的DR方案。它不是去备份VM或者物理机上的所有数据,而是备份运行在主机上的特定的Pod,或者备份一组Pod。在下面的图中,我们看到一个3节点的OpenShift集群、一个三节点的Cassandra环,和三个单独节点的PostgreSQL数据库。
通过PX-DR我们可以去备份我们想要备份的特定Pods。例如,我们想备份3节点的Cassandra环,或者想备份一个单独的PostgreSQL数据库。通过提供容器颗粒度的备份,我们避免了在备份所有VM过程中复杂的数据提取,转化和加载(ETL)过程。通过仅仅备份单独的应用,我们可以大量节省存储成本,以及保持很低的RTO。
对整个Kubernetes命名空间的容灾
具备容器颗粒度的备份代表我们也可以对整个命名空间进行备份。Kubernetes上的命名空间,通常可以运行有关联的一组应用。例如,某企业的一个命名空间代表了该企业的一个分支机构的所有应用。通常在备份命名空间的时候,我们会备份整个命名空间,而不是仅备份命名空间里的某一个应用。传统的备份方案是无法对命名空间进行备份的,因为命名空间是跨VM边界的。PX-DR,可以备份整个命名空间,不论与这个命名空间关联的Pods在哪里。
对 OpenShift备份过程中保持应用的一致性
PX-DR可以保持应用的一致性。如上面的例子,3个Cassandr pods是一个分布式系统。通过对它们进行快照的过程中,如果需要支持应用在无数据损失的情况下恢复,就需要在快照过程中保持所有的Pods被锁定。对VM进行快照无法锁定所有Pods。而进行系列快照也不能达到。Portworx提供了Kubernetes组快照规则引擎,允许Operators自动的执行前置和后置快照命令。例如对Cassandra,我们必须运行nodetool flush命令来达到对多个Cassandra容器快照过程中保持应用的一致性。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: Rule
metadata:
name: cassandra-presnap-rule
spec:
– podSelector:
app: cassandra
actions:
– type: command
value: nodetool flush
为Openshift应用备份数据和应用配置
我们已经叙述了容器颗粒度备份、命名空间感知、应用一致性备份的重要性。现在我们来看一下为什么OpenShift的DR要求能够备份数据和应用配置。在OpenShift上备份和恢复一个应用需要两件事情:数据、和应用配置。如果我们仅仅备份数据,恢复应用的时间会非常长,因为我们需要重建应用配置,会增加RTO。如果我们仅仅备份应用的配置 – 所有的Yaml文件(定义了应用的部署、服务账户、PVCs等),但我们却没有应用数据。因此我们需要同时备份应用数据和应用配置。PX-DR可以通过一个OpenShift命令备份应用数据和应用配置。恢复OpenShift应用的时候使用 `oc -f apply myapp.yml` 命令,因为恢复应用的过程与最初部署应用过程是一样的。
对Openshift的同步或异步DR
针对我们的目标和数据中心的不同架构,我们可以选择正确的OpenShift容灾策略。我们可以选择同步或者异步的备份模式。在一些情况下,也可以同时选取同步和异步备份,因为同步和异步提供了不同层级的系统保护。
例如,一个银行有本地部署的数据中心,并且通过专线连接到了一个AWS数据中心,可能会需要为一个重要商业应用选择零RPO的DR策略,同时要求RTO<1分钟。在这种情况下,我们倾向于推荐同步备份的PX-DR,由于两个环境的延时极低,因此可以提供零数据损失的恢复。
另一个例子,如果一个制造业的公司在较远的两地有两个数据中心,应用要求较低的RTO,但按每小时的备份频率对于RPO的目标来说已经足够了,在这种情况下,异步备份的PX-DR,使用连续增量式的备份就已经足够。
下面是不同情况下OpenShift DR策略的选择
较远网络的OpenShift容灾策略(两个站点之间的往返延迟 >10毫秒的情况)
近距离网络的OpenShift的容灾策略(两个站点之间的往返延迟 < 10毫秒的情况)
如何在OpenShift上通过PX-DR实现零RPO的DR
PX-DR支持在OpenShift上的同步和异步容灾,下面我们来关注下零RPO的同步容灾。我们先看一下通过Portworx和OpenShift同步容灾的相关概念和配置,包括初始setup和模拟出一个系统错误。一个单独的Portworx数据管理层横跨多个站点,如上图所示,同步PX-DR使用位于多个OpenShift集群下的、一个单独的Portworx数据管理层。这会在每一个OpenShift站点上提供永远可用的数据复制。一个单独的数据管理层意味着:有两个Portworx集群域,其中总有一个Portworx集群是可用的。
通过集群域,Portworx数据管理层来区分主站点和容灾站点。集群域在Portworx集群被安装的时候就会配置完成。在每一个OpenShift集群上(主集群或DR集群)配置Portworx来包括同一个Key-value的存储端点和集群名称,但使用不同的集群域来区分主站点和DR站点,看下面的例子。
Primary DR Site args: [“-k”, “etcd:http://etcd:2379”, “-c”, “px-cluster-synchronous”, “-s”, “type=gp2,size=250”, “-secret_type”, “k8s”, “-cluster_domain”, “primary” “-x”, “kubernetes”] “` args: [“-k”, “etcd:http://etcd:2379”, “-c”, “px-cluster-synchronous”, “-s”, “type=gp2,size=250”, “-secret_type”, “k8s”, “-cluster_domain”, “dr-site” “-x”, “kubernetes”]
低延时要求
同步PX-DR需要很低的延时。因为每一个写入操作都会被同步的复制到容灾站点上,如果延时较高,应用的性能就会受到很大影响。这也是为什么在这样的架构中,卷必须设定复制因子在2以上。到DR站点的往返延迟不能够超过10毫秒,甚至有一些应用要求的延时比10毫秒还要低。当设计应用时,同时需要思考DR的架构和延时的要求。可以在两个站点间使用Ping来测试延时。测试延时可以返回最小、最大和平均延时以及分布。
$ ping ip-10-0-131-167 PING (10.0.131.167) 56(84) bytes of data. 64 bytes from (10.0.131.167): icmp_seq=1 ttl=255 time=0.019 ms 64 bytes from (10.0.131.167): icmp_seq=2 ttl=255 time=0.028 ms 64 bytes from (10.0.131.167): icmp_seq=3 ttl=255 time=0.035 ms 64 bytes from (10.0.131.167): icmp_seq=4 ttl=255 time=0.029 ms 64 bytes from (10.0.131.167): icmp_seq=5 ttl=255 time=0.028 ms ^C — ip-10-0-131-167.us-west-2.compute.internal ping statistics — 5 packets transmitted, 5 received, 0% packet loss, time 4080ms rtt min/avg/max/mdev = 0.019/0.027/0.035/0.008 ms
Setup Openshift集群配对
一旦完成两个站点都在运行Portworx,在正确的集群域设定基础上,它们就可以正常的来Sync了。我们可以通过Portworx命令 “` $ pxctl cluster domains show “` 来进行验证。验证完成后,并且两个集群域都是正常的情况下,就可以创建集群配对对象。这样两个站点就可以共享一个OpenShift应用YAML文件。这些YAML文件代表了应用的配置,对于在出问题时保证低RTO有着重要的作用。首先为目标命名空间产生集群配对,然后把YAML文件应用到主站点上。
$ storkctl generate clusterpair -n appns dr-site > dr-site.yaml
$ oc create -f dr-site.yaml
可以通过下面的命令来验证集群配对。
$ storkctl get clusterdomainsstatus
创建一个调度和迁移
取决于你的组织的RTO要求,你可以选择应用的sync频率。通过创建一个策略来定义调度,然后把调度和应用的迁移关联起来。
首先,创建一个调度,下面的例子中在每一分钟迁移应用配置。把它保存成一个Yaml文件,然后使用`oc create -f` 来创建策略。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: SchedulePolicy
metadata:
name: sched-policy
namespace: appns
policy:
interval:
intervalMinutes: 1
daily:
time: “10:14PM”
weekly:
day: “Thursday”
time: “10:13PM”
monthly:
date: 14
time: “8:05PM”
接下来,创建一个迁移:针对 “appns”命名空间、“dr-site”集群配对、和使用这个调度。注意文件最下方的“schedulePolicyName”。存成一个yaml文件,然后通过` oc create -f` 来应用它。
apiVersion: stork.libopenstorage.org/v1alpha1
kind: MigrationSchedule
metadata:
name: migrationschedule
namespace: appns
spec:
template:
spec:
clusterPair: dr-site
includeResources: true
startApplications: false
includeVolumes: false
namespaces:
– demo
schedulePolicyName: sched-policy
注意以上仅仅设定includeResources是true,而设定其他的都是false,因为同步DR集群已经在两个集群上都配置了数据,因此我们不再需要include卷,并且直到有系统错误发生前,我们也不想启动这个应用。如果我们使用异步PX-DR方式,我们需要把`includeVolumes` 改为true。
你可以通过运行下面的命令来验证迁移是否已经完成。
$ storkctl get migration
通过OpenShift DR站点来恢复
现在OpenShift集群都已经sync完成,应用也sync完成。我们准备好来恢复应用了。当一个主站点的灾难发生后,下面的步骤即可在DR站点上恢复,并且是零RPO。
首先,关闭主站点,等待域变成 (NotInSync)
$ storkctl deactivate clusterdomain ocs-primary
$ storkctl get clusterdomainsstatus
接下来,如果你有权限访问主站点,把复制集变成0。如果你没有权限访问主站点,直接走到下一步,在容灾站点上恢复应用。
$ oc scale deploy -n demo –replicas=0 –all
通过向迁移调度增加 `suspend:true` ,并且更新spec,可以暂停迁移
apiVersion: stork.libopenstorage.org/v1alpha1
kind: MigrationSchedule
metadata:
name: migrationschedule
namespace: appns
spec:
template:
spec:
clusterPair: dr-site
includeResources: true
startApplications: false
includeVolumes: false
namespaces:
– demo
schedulePolicyName: sched-policy
suspend: true
$oc apply -f migration-schedule.yaml
最后,在DR站点上,启动迁移,打开DR站点上的Pods。
$ storkctl activate migration -n appns
你的“appns”命名空间里的应用现在已经在OpenShift DR站点上重启了,并且是0数据损失。
PX-DR包括一个API可以自动化的实现上面的步骤,另外,当主站点又重新启动后,应用的配置和数据会重新被sync,这样就可以重新在主站点上启动应用。