创建快照

编辑

本指南将向您展示如何对正在运行的集群进行快照。您可以稍后恢复快照以恢复或传输其数据。

在本指南中,您将学习如何:

  • 使用快照生命周期管理(SLM)自动化快照创建和保留
  • 手动创建快照
  • 监控快照的进度
  • 删除或取消快照
  • 备份集群配置文件

该指南还提供了有关创建专用集群状态快照以及在不同时间间隔拍摄快照的技巧。

先决条件

编辑
  • 要使用Kibana的快照和恢复功能,您必须具有以下权限

    • 集群权限monitormanage_slmcluster:admin/snapshotcluster:admin/repository
    • 索引权限:在 monitor 索引上具有 all 权限
  • 您只能从已选定主节点的正在运行的集群中进行快照。
  • 快照存储库必须已注册并且可用于集群。
  • 集群的全局元数据必须是可读的。 要在快照中包含索引,该索引及其元数据也必须是可读的。 确保没有任何阻止读取访问的集群块索引块

注意事项

编辑
  • 每个快照在其存储库中必须具有唯一的名称。尝试创建与现有快照同名的快照将会失败。
  • 快照会自动去重。您可以频繁地拍摄快照,而对存储开销的影响很小。
  • 每个快照在逻辑上是独立的。 您可以删除快照而不会影响其他快照。
  • 拍摄快照可能会暂时暂停分片分配。请参阅快照和分片分配
  • 拍摄快照不会阻止索引或其他请求。但是,快照不包括快照过程开始后所做的更改。
  • 您可以同时拍摄多个快照。snapshot.max_concurrent_operations集群设置限制了并发快照操作的最大数量。
  • 如果将数据流包含在快照中,则快照还包括该数据流的后备索引和元数据。

    您也可以仅在快照中包含特定的后备索引。但是,快照不会包含数据流的元数据或其其他后备索引。

  • 快照可以包含数据流,但排除特定的后备索引。 当您还原此类数据流时,它将仅包含快照中的后备索引。 如果流的原始写入索引不在快照中,则快照中最新的后备索引将成为流的写入索引。

使用 SLM 自动执行快照

编辑

快照生命周期管理 (SLM) 是定期备份集群的最简单方法。 SLM策略会自动按预设计划拍摄快照。该策略还可以根据您定义的保留规则删除快照。

Elasticsearch 服务部署会自动包含 cloud-snapshot-policy SLM 策略。 Elasticsearch 服务使用此策略来定期拍摄集群的快照。有关更多信息,请参阅Elasticsearch 服务快照文档

SLM 安全性

编辑

启用 Elasticsearch 安全功能后,以下集群权限控制对 SLM 操作的访问

manage_slm
允许用户执行所有 SLM 操作,包括创建和更新策略以及启动和停止 SLM。
read_slm
允许用户执行所有只读 SLM 操作,例如获取策略和检查 SLM 状态。
cluster:admin/snapshot/*
允许用户拍摄和删除任何索引的快照,无论他们是否有权访问该索引。

您可以通过 Kibana Management 创建和管理角色以分配这些权限。

要授予创建和管理 SLM 策略和快照所需的权限,您可以设置具有 manage_slmcluster:admin/snapshot/* 集群权限以及对 SLM 历史索引的完全访问权限的角色。

例如,以下请求创建 slm-admin 角色

resp = client.security.put_role(
    name="slm-admin",
    cluster=[
        "manage_slm",
        "cluster:admin/snapshot/*"
    ],
    indices=[
        {
            "names": [
                ".slm-history-*"
            ],
            "privileges": [
                "all"
            ]
        }
    ],
)
print(resp)
const response = await client.security.putRole({
  name: "slm-admin",
  cluster: ["manage_slm", "cluster:admin/snapshot/*"],
  indices: [
    {
      names: [".slm-history-*"],
      privileges: ["all"],
    },
  ],
});
console.log(response);
POST _security/role/slm-admin
{
  "cluster": [ "manage_slm", "cluster:admin/snapshot/*" ],
  "indices": [
    {
      "names": [ ".slm-history-*" ],
      "privileges": [ "all" ]
    }
  ]
}

要授予对 SLM 策略和快照历史记录的只读访问权限,您可以设置具有 read_slm 集群权限以及对快照生命周期管理历史索引的读取权限的角色。

例如,以下请求创建 slm-read-only 角色

resp = client.security.put_role(
    name="slm-read-only",
    cluster=[
        "read_slm"
    ],
    indices=[
        {
            "names": [
                ".slm-history-*"
            ],
            "privileges": [
                "read"
            ]
        }
    ],
)
print(resp)
const response = await client.security.putRole({
  name: "slm-read-only",
  cluster: ["read_slm"],
  indices: [
    {
      names: [".slm-history-*"],
      privileges: ["read"],
    },
  ],
});
console.log(response);
POST _security/role/slm-read-only
{
  "cluster": [ "read_slm" ],
  "indices": [
    {
      "names": [ ".slm-history-*" ],
      "privileges": [ "read" ]
    }
  ]
}

创建 SLM 策略

编辑

要在 Kibana 中管理 SLM,请转到主菜单并单击堆栈管理 > 快照和恢复 > 策略。要创建策略,请单击创建策略

您还可以使用 SLM API 管理 SLM。要创建策略,请使用创建 SLM 策略 API

以下请求创建一个策略,该策略每天凌晨 1:30(UTC 时间)备份集群状态、所有数据流和所有索引。

resp = client.slm.put_lifecycle(
    policy_id="nightly-snapshots",
    schedule="0 30 1 * * ?",
    name="<nightly-snap-{now/d}>",
    repository="my_repository",
    config={
        "indices": "*",
        "include_global_state": True
    },
    retention={
        "expire_after": "30d",
        "min_count": 5,
        "max_count": 50
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "nightly-snapshots",
  schedule: "0 30 1 * * ?",
  name: "<nightly-snap-{now/d}>",
  repository: "my_repository",
  config: {
    indices: "*",
    include_global_state: true,
  },
  retention: {
    expire_after: "30d",
    min_count: 5,
    max_count: 50,
  },
});
console.log(response);
PUT _slm/policy/nightly-snapshots
{
  "schedule": "0 30 1 * * ?",       
  "name": "<nightly-snap-{now/d}>", 
  "repository": "my_repository",    
  "config": {
    "indices": "*",                 
    "include_global_state": true    
  },
  "retention": {                    
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 50
  }
}

何时拍摄快照,以 Cron 语法编写。

快照名称。支持日期数学。为防止命名冲突,该策略还会将 UUID 附加到每个快照名称。

用于存储策略快照的注册的快照存储库

要包含在策略快照中的数据流和索引。

如果为 true,则策略的快照将包括集群状态。默认情况下,这也包括所有功能状态。要仅包含特定的功能状态,请参阅备份特定的功能状态

可选的保留规则。 此配置将快照保留 30 天,保留至少 5 个快照,并且无论快照的旧新程度,最多保留 50 个快照。请参阅SLM 保留快照保留限制

手动运行 SLM 策略

编辑

您可以手动运行 SLM 策略以立即创建快照。 这对于测试新策略或在升级之前拍摄快照很有用。 手动运行策略不会影响其快照计划。

要在 Kibana 中运行策略,请转到策略页面,然后单击操作列下的运行图标。您还可以使用执行 SLM 策略 API

POST _slm/policy/nightly-snapshots/_execute

快照过程在后台运行。要监控其进度,请参阅监控快照

SLM 保留

编辑

SLM 快照保留是一项集群级任务,与策略的快照计划分开运行。 要控制 SLM 保留任务的运行时间,请配置 slm.retention_schedule 集群设置。

resp = client.cluster.put_settings(
    persistent={
        "slm.retention_schedule": "0 30 1 * * ?"
    },
)
print(resp)
response = client.cluster.put_settings(
  body: {
    persistent: {
      'slm.retention_schedule' => '0 30 1 * * ?'
    }
  }
)
puts response
const response = await client.cluster.putSettings({
  persistent: {
    "slm.retention_schedule": "0 30 1 * * ?",
  },
});
console.log(response);
PUT _cluster/settings
{
  "persistent" : {
    "slm.retention_schedule" : "0 30 1 * * ?"
  }
}

要立即运行保留任务,请使用执行 SLM 保留策略 API

resp = client.slm.execute_retention()
print(resp)
response = client.slm.execute_retention
puts response
const response = await client.slm.executeRetention();
console.log(response);
POST _slm/_execute_retention

SLM 策略的保留规则仅适用于使用该策略创建的快照。 其他快照不计入策略的保留限制。

快照保留限制

编辑

我们建议您在 SLM 策略中包含保留规则,以删除不再需要的快照。

快照存储库可以安全地扩展到数千个快照。 但是,为了管理其元数据,大型存储库需要在主节点上使用更多的内存。 保留规则确保存储库的元数据不会增长到可能使主节点不稳定的程度。

手动创建快照

编辑

要在没有 SLM 策略的情况下拍摄快照,请使用创建快照 API。 快照名称支持日期数学

resp = client.snapshot.create(
    repository="my_repository",
    snapshot="<my_snapshot_{now/d}>",
)
print(resp)
response = client.snapshot.create(
  repository: 'my_repository',
  snapshot: '<my_snapshot_{now/d}>'
)
puts response
const response = await client.snapshot.create({
  repository: "my_repository",
  snapshot: "<my_snapshot_{now/d}>",
});
console.log(response);
# PUT _snapshot/my_repository/<my_snapshot_{now/d}>
PUT _snapshot/my_repository/%3Cmy_snapshot_%7Bnow%2Fd%7D%3E

根据其大小,快照可能需要一段时间才能完成。 默认情况下,创建快照 API 仅启动快照过程,该过程在后台运行。 要阻止客户端直到快照完成,请将 wait_for_completion 查询参数设置为 true

resp = client.snapshot.create(
    repository="my_repository",
    snapshot="my_snapshot",
    wait_for_completion=True,
)
print(resp)
response = client.snapshot.create(
  repository: 'my_repository',
  snapshot: 'my_snapshot',
  wait_for_completion: true
)
puts response
const response = await client.snapshot.create({
  repository: "my_repository",
  snapshot: "my_snapshot",
  wait_for_completion: "true",
});
console.log(response);
PUT _snapshot/my_repository/my_snapshot?wait_for_completion=true

您还可以使用克隆快照 API克隆现有快照。

监控快照

编辑

要监控当前正在运行的任何快照,请使用获取快照 API,并使用 _current 请求路径参数。

resp = client.snapshot.get(
    repository="my_repository",
    snapshot="_current",
)
print(resp)
response = client.snapshot.get(
  repository: 'my_repository',
  snapshot: '_current'
)
puts response
const response = await client.snapshot.get({
  repository: "my_repository",
  snapshot: "_current",
});
console.log(response);
GET _snapshot/my_repository/_current

要获得参与当前正在运行的任何快照的每个分片的完整细分,请使用获取快照状态 API

resp = client.snapshot.status()
print(resp)
response = client.snapshot.status
puts response
const response = await client.snapshot.status();
console.log(response);
GET _snapshot/_status

检查 SLM 历史记录

编辑

要获取有关集群 SLM 执行历史记录的更多信息,包括每个 SLM 策略的统计信息,请使用获取 SLM 统计信息 API。 该 API 还返回有关集群快照保留任务历史记录的信息。

resp = client.slm.get_stats()
print(resp)
response = client.slm.get_stats
puts response
const response = await client.slm.getStats();
console.log(response);
GET _slm/stats

要获取有关特定 SLM 策略的执行历史记录的信息,请使用获取 SLM 策略 API。 响应包括

  • 下一个计划的策略执行。
  • 如果适用,策略上次成功启动快照过程的时间。 成功启动并不能保证快照已完成。
  • 如果适用,策略上次执行失败的时间以及关联的错误。
resp = client.slm.get_lifecycle(
    policy_id="nightly-snapshots",
)
print(resp)
response = client.slm.get_lifecycle(
  policy_id: 'nightly-snapshots'
)
puts response
const response = await client.slm.getLifecycle({
  policy_id: "nightly-snapshots",
});
console.log(response);
GET _slm/policy/nightly-snapshots

删除或取消快照

编辑

要在 Kibana 中删除快照,请转到快照页面,然后单击操作列下的垃圾桶图标。您还可以使用删除快照 API

resp = client.snapshot.delete(
    repository="my_repository",
    snapshot="my_snapshot_2099.05.06",
)
print(resp)
response = client.snapshot.delete(
  repository: 'my_repository',
  snapshot: 'my_snapshot_2099.05.06'
)
puts response
const response = await client.snapshot.delete({
  repository: "my_repository",
  snapshot: "my_snapshot_2099.05.06",
});
console.log(response);
DELETE _snapshot/my_repository/my_snapshot_2099.05.06

如果删除正在进行中的快照,Elasticsearch 会取消它。快照进程会停止,并删除为该快照创建的所有文件。删除快照不会删除其他快照使用的文件。

备份配置文件

编辑

如果您在自己的硬件上运行 Elasticsearch,我们建议除了备份之外,您还应使用您选择的文件备份软件定期备份每个节点的 $ES_PATH_CONF 目录中的文件。快照不会备份这些文件。另请注意,这些文件在每个节点上都不同,因此应单独备份每个节点的文件。

elasticsearch.keystore、TLS 密钥以及 SAMLOIDCKerberos 域私钥文件包含敏感信息。请考虑加密这些文件的备份。

备份特定功能状态

编辑

默认情况下,包含集群状态的快照也包含所有功能状态。类似地,排除集群状态的快照默认排除所有功能状态。

您还可以配置快照仅包含特定的功能状态,而与集群状态无关。

要获取可用功能的列表,请使用获取功能 API

resp = client.features.get_features()
print(resp)
response = client.features.get_features
puts response
const response = await client.features.getFeatures();
console.log(response);
GET _features

该 API 返回

{
  "features": [
    {
      "name": "tasks",
      "description": "Manages task results"
    },
    {
      "name": "kibana",
      "description": "Manages Kibana configuration and reports"
    },
    {
      "name": "security",
      "description": "Manages configuration for Security features, such as users and roles"
    },
    ...
  ]
}

要在快照中包含特定功能状态,请在 feature_states 数组中指定该功能的 name

例如,以下 SLM 策略仅在其快照中包含 Kibana 和 Elasticsearch 安全功能的功能状态。

resp = client.slm.put_lifecycle(
    policy_id="nightly-snapshots",
    schedule="0 30 2 * * ?",
    name="<nightly-snap-{now/d}>",
    repository="my_repository",
    config={
        "indices": "*",
        "include_global_state": True,
        "feature_states": [
            "kibana",
            "security"
        ]
    },
    retention={
        "expire_after": "30d",
        "min_count": 5,
        "max_count": 50
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "nightly-snapshots",
  schedule: "0 30 2 * * ?",
  name: "<nightly-snap-{now/d}>",
  repository: "my_repository",
  config: {
    indices: "*",
    include_global_state: true,
    feature_states: ["kibana", "security"],
  },
  retention: {
    expire_after: "30d",
    min_count: 5,
    max_count: 50,
  },
});
console.log(response);
PUT _slm/policy/nightly-snapshots
{
  "schedule": "0 30 2 * * ?",
  "name": "<nightly-snap-{now/d}>",
  "repository": "my_repository",
  "config": {
    "indices": "*",
    "include_global_state": true,
    "feature_states": [
      "kibana",
      "security"
    ]
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 50
  }
}

作为功能状态一部分的任何索引或数据流都将显示在快照的内容中。例如,如果备份 security 功能状态,则 security-* 系统索引将显示在 获取快照 API 响应中的 indicesfeature_states 下。

专用集群状态快照

编辑

某些功能状态包含敏感数据。例如,security 功能状态包括可能包含用户名和加密密码哈希值的系统索引。由于密码是使用加密哈希存储的,因此泄露快照不会自动使第三方能够以您的用户身份进行身份验证或使用 API 密钥。但是,它会泄露机密信息,如果第三方可以修改快照,他们可能会安装后门。

为了更好地保护这些数据,请考虑为集群状态快照创建专用存储库和 SLM 策略。这使您可以严格限制和审计对存储库的访问。

例如,以下 SLM 策略仅备份集群状态。该策略将这些快照存储在专用存储库中。

resp = client.slm.put_lifecycle(
    policy_id="nightly-cluster-state-snapshots",
    schedule="0 30 2 * * ?",
    name="<nightly-cluster-state-snap-{now/d}>",
    repository="my_secure_repository",
    config={
        "include_global_state": True,
        "indices": "-*"
    },
    retention={
        "expire_after": "30d",
        "min_count": 5,
        "max_count": 50
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "nightly-cluster-state-snapshots",
  schedule: "0 30 2 * * ?",
  name: "<nightly-cluster-state-snap-{now/d}>",
  repository: "my_secure_repository",
  config: {
    include_global_state: true,
    indices: "-*",
  },
  retention: {
    expire_after: "30d",
    min_count: 5,
    max_count: 50,
  },
});
console.log(response);
PUT _slm/policy/nightly-cluster-state-snapshots
{
  "schedule": "0 30 2 * * ?",
  "name": "<nightly-cluster-state-snap-{now/d}>",
  "repository": "my_secure_repository",
  "config": {
    "include_global_state": true,                 
    "indices": "-*"                               
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 50
  }
}

包含集群状态。默认情况下,这也包括所有功能状态。

排除常规数据流和索引。

如果为集群状态拍摄专用快照,则需要从其他快照中排除集群状态。例如

resp = client.slm.put_lifecycle(
    policy_id="nightly-snapshots",
    schedule="0 30 2 * * ?",
    name="<nightly-snap-{now/d}>",
    repository="my_repository",
    config={
        "include_global_state": False,
        "indices": "*"
    },
    retention={
        "expire_after": "30d",
        "min_count": 5,
        "max_count": 50
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "nightly-snapshots",
  schedule: "0 30 2 * * ?",
  name: "<nightly-snap-{now/d}>",
  repository: "my_repository",
  config: {
    include_global_state: false,
    indices: "*",
  },
  retention: {
    expire_after: "30d",
    min_count: 5,
    max_count: 50,
  },
});
console.log(response);
PUT _slm/policy/nightly-snapshots
{
  "schedule": "0 30 2 * * ?",
  "name": "<nightly-snap-{now/d}>",
  "repository": "my_repository",
  "config": {
    "include_global_state": false,    
    "indices": "*"                    
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 5,
    "max_count": 50
  }
}

排除集群状态。默认情况下,这也排除所有功能状态。

包含所有常规数据流和索引。

在不同的时间间隔创建快照

编辑

如果您仅使用单个 SLM 策略,则可能难以进行频繁的快照并保留具有较长时间间隔的快照。

例如,一个每 30 分钟拍摄一次快照,最多保留 100 个快照的策略将仅保留大约两天的快照。虽然此设置非常适合备份最近的更改,但它不允许您从上周或上个月还原数据。

要解决此问题,您可以创建多个 SLM 策略,这些策略使用相同的快照存储库,并以不同的时间表运行。由于策略的保留规则仅适用于其快照,因此策略不会删除另一个策略创建的快照。

例如,以下 SLM 策略每小时拍摄一次快照,最多保留 24 个快照。该策略将其快照保留一天。

resp = client.slm.put_lifecycle(
    policy_id="hourly-snapshots",
    name="<hourly-snapshot-{now/d}>",
    schedule="0 0 * * * ?",
    repository="my_repository",
    config={
        "indices": "*",
        "include_global_state": True
    },
    retention={
        "expire_after": "1d",
        "min_count": 1,
        "max_count": 24
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "hourly-snapshots",
  name: "<hourly-snapshot-{now/d}>",
  schedule: "0 0 * * * ?",
  repository: "my_repository",
  config: {
    indices: "*",
    include_global_state: true,
  },
  retention: {
    expire_after: "1d",
    min_count: 1,
    max_count: 24,
  },
});
console.log(response);
PUT _slm/policy/hourly-snapshots
{
  "name": "<hourly-snapshot-{now/d}>",
  "schedule": "0 0 * * * ?",
  "repository": "my_repository",
  "config": {
    "indices": "*",
    "include_global_state": true
  },
  "retention": {
    "expire_after": "1d",
    "min_count": 1,
    "max_count": 24
  }
}

以下策略在同一快照存储库中每晚拍摄快照。该策略将其快照保留一个月。

resp = client.slm.put_lifecycle(
    policy_id="daily-snapshots",
    name="<daily-snapshot-{now/d}>",
    schedule="0 45 23 * * ?",
    repository="my_repository",
    config={
        "indices": "*",
        "include_global_state": True
    },
    retention={
        "expire_after": "30d",
        "min_count": 1,
        "max_count": 31
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "daily-snapshots",
  name: "<daily-snapshot-{now/d}>",
  schedule: "0 45 23 * * ?",
  repository: "my_repository",
  config: {
    indices: "*",
    include_global_state: true,
  },
  retention: {
    expire_after: "30d",
    min_count: 1,
    max_count: 31,
  },
});
console.log(response);
PUT _slm/policy/daily-snapshots
{
  "name": "<daily-snapshot-{now/d}>",
  "schedule": "0 45 23 * * ?",          
  "repository": "my_repository",
  "config": {
    "indices": "*",
    "include_global_state": true
  },
  "retention": {
    "expire_after": "30d",
    "min_count": 1,
    "max_count": 31
  }
}

每天 UTC 时间晚上 11:45 运行。

以下策略在同一存储库中创建每月快照。该策略将其快照保留一年。

resp = client.slm.put_lifecycle(
    policy_id="monthly-snapshots",
    name="<monthly-snapshot-{now/d}>",
    schedule="0 56 23 1 * ?",
    repository="my_repository",
    config={
        "indices": "*",
        "include_global_state": True
    },
    retention={
        "expire_after": "366d",
        "min_count": 1,
        "max_count": 12
    },
)
print(resp)
const response = await client.slm.putLifecycle({
  policy_id: "monthly-snapshots",
  name: "<monthly-snapshot-{now/d}>",
  schedule: "0 56 23 1 * ?",
  repository: "my_repository",
  config: {
    indices: "*",
    include_global_state: true,
  },
  retention: {
    expire_after: "366d",
    min_count: 1,
    max_count: 12,
  },
});
console.log(response);
PUT _slm/policy/monthly-snapshots
{
  "name": "<monthly-snapshot-{now/d}>",
  "schedule": "0 56 23 1 * ?",            
  "repository": "my_repository",
  "config": {
    "indices": "*",
    "include_global_state": true
  },
  "retention": {
    "expire_after": "366d",
    "min_count": 1,
    "max_count": 12
  }
}

在每月的第一天 UTC 时间晚上 11:56 运行。