InfluxDB从/到Docker容器的备份/还原

导航到

过去几年中一些令人兴奋的发展之一是容器的出现,这允许软件在一个包含所有依赖和库的安全隔离环境中部署。

Docker已成为市场上领先的容器产品之一,我们看到它们被用于各个方面。很多时候InfluxDB正在监控容器的指标,而TICK Stack(Telegraf、InfluxDB、Chronograf和Kapacitor)的产品也经常在容器中运行。事实上,如果您想查看这些内容,有一篇之前的博客文章向您展示了如何设置InfluxData沙盒,它不仅可以在容器中运行,还可以收集您本地系统、容器环境和InfluxDB数据库的指标。这是开始使用产品的绝佳方式。

挑战

不可避免地,您可能会发现自己正在Docker容器中运行InfluxDB。人们喜欢容器的地方在于它们是运行时的一个隔离环境。当您关闭正在运行的程序时,按照设计,您正在运行的容器也会关闭。在这些环境中的挑战在于当您想要恢复在容器中运行的InfluxDB数据库时。问题是,为了从备份中恢复InfluxDB数据库,实例需要停止。当您在容器中运行InfluxDB并停止数据库时,容器也会关闭。那么,您如何解决这个两难的情况呢?这正是我将在这篇博客中要讲述的内容。

设置

创建运行InfluxDB的Docker容器并将一些测试数据加载到其中。

我将详细介绍我的整个设置,以便您可以在您的实验室中轻松地复制这些步骤。您可以在GitHub上找到InfluxDB的示例Dockerfile,以帮助您在Docker容器中设置InfluxDB实例。我将使用它来设置我的数据库。我还创建了一个示例数据集stocks.txt,我将使用它来演示这个例子。

我修改了位于先前提到的 influxdata-docker 仓库下的 influxdb 目录中的 Dockerfile,并添加了一些额外的端口以暴露,还添加了一条复制语句,将位于我的本地服务器上的 stocks.txt 文件复制到 Docker 容器中。这样,我就可以有一些数据来工作了。以下是我的 Dockerfile 的样子:

FROM buildpack-deps:jessie-curl

RUN set -ex && \
    for key in \
        05CE15085FC09D18E99EFB22684A14CF2582E0C5 ; \
    do \
        gpg --keyserver ha.pool.sks-keyservers.net --recv-keys "$key" || \
        gpg --keyserver pgp.mit.edu --recv-keys "$key" || \
        gpg --keyserver keyserver.pgp.com --recv-keys "$key" ; \
    done

ENV INFLUXDB_VERSION 1.3.5
RUN wget -q https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB_VERSION}_amd64.deb.asc && \
    wget -q https://dl.influxdata.com/influxdb/releases/influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    gpg --batch --verify influxdb_${INFLUXDB_VERSION}_amd64.deb.asc influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    dpkg -i influxdb_${INFLUXDB_VERSION}_amd64.deb && \
    rm -f influxdb_${INFLUXDB_VERSION}_amd64.deb*
COPY influxdb.conf /etc/influxdb/influxdb.conf

EXPOSE 8086 8125/udp 8092/udp 8094

VOLUME /var/lib/influxdb

COPY stocks.txt /stocks.txt
COPY entrypoint.sh /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["influxd"]

在您的 Dockerfile 所在的目录下工作,按照以下步骤构建 InfluxDB 容器。

$ docker build -t test_influxdb .

完成后,您可以列出 docker 镜像,并且现在应该看到 influxdb-container 被列出。

$ docker images
REPOSITORY    TAG     IMAGE ID      CREATED      SIZE
test_influxdb latest  7b7def77ff12  5 mins ago   224MB

启动容器并打开一个 bash shell。 注意:您本地服务器上的两个目录已映射到容器内的目录。第一个是 InfluxDB 数据目录,第二个是我们将备份数据的目录。

$ export INFLUXDIR="$HOME/influxdb-test"
$ export BACKUPDIR="$HOME/backup-test"

$ CONTAINER_ID=$(docker run --rm \
  --detach \
  -v $INFLUXDIR:/var/lib/influxdb \
  -v $BACKUPDIR:/backups \
  -p 8086 \
  test_influxdb:latest
  )

$ docker exec –it "$CONTAINER_ID" /bin/bash

这应在容器中启动一个终端会话,其中运行着 InfluxDB。您应该看到当我们构建它时复制到容器中的 stocks.txt 文件位于根目录中。

# ls –l stocks.txt
-rw-r--r-- 1 root root 3070 Jul 20 01:45 stocks.txt

现在让我们将其导入到 stocks 数据库中,然后将其备份。

# influx -import -path=stocks.txt -precision s

2017/09/25 18:58:36 Processed 1 commands
2017/09/25 18:58:36 Processed 38 inserts
2017/09/25 18:58:36 Failed 0 inserts

# influx -execute "select count(*) from stocks.autogen.stock_price"
name: stock_price
time count_high count_low count_open count_volume
---- ---------- --------- ---------- ------------
0    38         38        38        38

过程

现在我们已经有一个工作环境,让我们首先备份我们的容器化 InfluxDB 实例。这将在构建容器时我们映射的目录 $HOME/backup-test 中备份。以下是我们将遵循的步骤,首先是备份数据库,然后删除数据库,最后恢复被删除的数据库。

  1. 捕获容器的 ID、镜像名称以及用于与容器中的 InfluxDB 通信的端口。
  2. 在 Docker 容器启动时,将 InfluxDB 备份到上面定义的备份目录。
  3. 从 InfluxDB 中删除数据库。
  4. 检查以确保数据库已删除。
  5. 停止 Docker 容器,因为必须停止 InfluxDB 才能运行恢复操作。
  6. 在临时容器中运行恢复命令。
  7. 启动 InfluxDB 容器。
  8. 查询 InfluxDB 以显示数据库存在并且记录已恢复。

细节

  • 首先,捕获容器的 ID 和临时端口。
$ CONTAINER_ID=`docker ps | grep test_influxdb | cut –c 1-12`
$ PORT=$(docker port "$CONTAINER_ID" 8086 | cut -d: -f2)
  • 其次,备份 stocks 数据库。
$ docker exec "$CONTAINER_ID" influx backup –database stocks "/backup/stocks.backup"
  • 运行一个 SHOW DATABASES 查询,然后 DROP 数据库,然后再次运行 SHOW DATABASES 查询以显示它已被删除。
$ curl https://127.0.0.1:${PORT}/query?q=SHOW+DATABASES
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"],["stocks"]]}]}]}

$ curl –XPOST https://127.0.0.1:${PORT}/query?q=DROP+DATABASE+stocks
{"results":[{"statement_id":0}]}

$ curl "https://127.0.0.1:${PORT}/query?q=SHOW+DATABASES"
{"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"]]}]}]}
  • 停止 Docker 容器,这将停止 InfluxDB 数据库。
$ docker stop "$CONTAINER_ID"
  • 在临时容器中运行恢复命令。下面的 docker 命令影响之前挂载到 /var/lib/influxdb 的卷。
$ docker run --rm \
  --entrypoint /bin/bash \
  -v $INFLUXDIR:/var/lib/influxdb \
  -v $BACKUPDIR:/backups \
  test_influxdb:latest \
  -c "influxd restore -metadir /var/lib/influxdb/meta -datadir /var/lib/influxdb/data -database stocks /backups/stocks.backup"

Using metastore snapshot: /backups/stocks.backup/meta.00
Restoring from backup /backups/stocks.backup/stocks.*
unpacking /var/lib/influxdb/data/stocks/autogen/3/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/4/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/5/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/6/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/7/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/8/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/9/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/10/000000001-000000001.tsm
unpacking /var/lib/influxdb/data/stocks/autogen/11/000000001-000000001.tsm
  • 如我们之前所做的那样,在后台启动容器,并显示已恢复的数据库。
$ CONTAINER_ID=$(docker run --rm \
  --detach \
  -v $INFLUXDIR:/var/lib/influxdb \
  -v $BACKUPDIR:/backups \
  -p 8086 \
  test_influxdb:latest
  )
$ PORT=$(docker port "$CONTAINER_ID" 8086 | cut -d: -f2)
$ curl -G "https://127.0.0.1:${PORT}/query?pretty=true"  --data-urlencode "q=SHOW DATABASES"
{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "databases",
                    "columns": [
                        "name"
                    ],
                    "values": [
                        [
                            "_internal"
                        ],
                        [
                            "stocks"
                        ]
                    ]
                }
            ]
        }
    ]
}
  • 让我们也进行计数,以显示所有记录都已恢复。
$ curl -G "https://127.0.0.1:${PORT}/query?pretty=true" --data-urlencode "db=stocks" --data-urlencode "q=SELECT count(*) FROM \"stock_price\""

{
    "results": [
        {
            "statement_id": 0,
            "series": [
                {
                    "name": "stock_price",
                    "columns": [
                        "time",
                        "count_high",
                        "count_low",
                        "count_open",
                        "count_volume"
                    ],
                    "values": [
                        [
                            "1970-01-01T00:00:00Z",
                            38,
                            38,
                            38,
                            38
                        ]
                    ]
                }
            ]
        }
    ]
}

下一步

我希望这对您有所帮助。如果您是第一次在 Docker 容器中运行 InfluxDB,上面设置部分中有许多有用的链接。官方 InfluxDB Docker 仓库位于 这里。此外,如前所述,查看 InfluxData Sandbox。它是快速开始整个 TICK Stack 的好方法,并可以快速开始收集和可视化来自您的本地系统、InfluxDB 实例以及运行 TICK Stack 的 Docker 环境的指标。

致谢

上述在容器中运行 InfluxDB 时恢复 InfluxDB 的技术是由 InfluxData 工程团队的 Mark Rushakoff 开发的。