拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 如何在Docker中处理数据库?

如何在Docker中处理数据库?

白鹭 - 2021-11-21 2307 0 2

1.概述

本文中,我们将回顾如何与Docker一起使用来管理数据库。


在第一章中,我们将介绍在本地计算机上数据库的安装。然后,我们将发现数据持久性如何跨容器工作。


总之,我们将讨论在Docker生产环境中实现数据库的可靠性。

2.在本地运行Docker映像

2.1 从标准Docker映像开始

首先,我们必须安装Docker Desktop 。 **然后,我们应该从Docker Hub找到我们数据库的现有映像**。找到它后,我们将从页面右上角docker pull


在本教程中,我们将使用PostgreSQL,因此命令为:

$docker pull postgres

下载完成后, docker run命令将在Docker容器中创建一个正在运行的数据库。对于PostgreSQL,必须使用-e选项POSTGRES_PASSWORD

$docker run -e POSTGRES_PASSWORD=password postgres

接下来,我们将测试数据库容器连接。

2.2 将Java项目连接到数据库

让我们尝试一个简单的测试。我们将使用JDBC数据源将本地Java项目连接到数据库。连接字符串应使用localhost上5432 :

jdbc:postgresql://localhost:5432/postgres?user=postgres&password=password

错误应通知我们该端口未打开。实际上,数据库正在侦听来自容器网络内部的连接,而我们的Java项目正在其外部运行。


要修复它,我们需要将容器端口映射到我们的localhost端口。我们将为PostgreSQL使用默认端口5432

$docker run -p 5432:5432 -e POSTGRES_PASSWORD=password postgres

该连接现在正在工作,并且我们应该能够使用我们的JDBC数据源。

2.3 运行SQL脚本

现在,我们可以从外壳连接到我们的数据库,例如,运行初始化脚本。


首先,让我们找到正在运行的容器ID:

$docker ps

 CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES

 65d9163eece2 postgres "docker-entrypoint.s…" 27 minutes ago Up 27 minutes 0.0.0.0:5432->5432/tcp optimistic_hellman

然后,我们将运行带有交互式-it docker exec命令,以在容器内运行外壳程序

$docker exec -it 65d9163eece2 bash

最后,我们可以使用命令行客户端连接到数据库实例,并粘贴我们的SQL脚本:

[email protected]:/# psql -U postgres

 postgres=#CREATE DATABASE TEST;

 CREATE TABLE PERSON( ID INTEGER PRIMARY KEY,

 FIRST_NAME VARCHAR(1000),

 LAST_NAME VARCHAR(1000)

 );

 ...

例如,如果要加载较大的转储文件,则必须避免复制粘贴。我们可以直接从主机运行import命令,而不是使用docker exec命令

$docker exec 65d9163eece2 psql -U postgres < dump.sql

3.使用Docker卷持久化数据

3.1 为什么我们需要卷Volume?

只要我们使用相同的容器,我们的基本设置就可以使用,每次需要重启时docker container stop/start如果docker run ,则会创建一个新的空容器,并且我们将丢失数据。实际上,默认情况下,Docker将数据保留在临时目录中。

现在,我们将学习如何修改此体积映射。

3.2 Docker卷设置

一项任务是检查我们的容器,以查看数据库使用了哪个卷:

$docker inspect -f "{{ .Mounts }}" 65d9163eece2

 [{volume f1033d3 /var/lib/docker/volumes/f1033d3/_data /var/lib/postgresql/data local true }]

我们可以看到,卷f1033d3已将容器目录/var/lib/postgresql/data映射到在主机文件系统中创建的临时目录/var/lib/docker/volumes/f1033d3/_data


我们必须通过在第2.1章中使用的docker run命令中-v选项来修改此映射:

$docker run -v C:\docker-db-volume:/var/lib/postgresql/data -e POSTGRES_PASSWORD=password postgres

现在,我们可以看到在C:\docker-db-volume目录中创建的数据库文件。我们可以在这篇专门的文章中找到高级卷配置。


结果,每次我们使用docker run命令时,数据将与不同的容器执行一起保留。


另外,我们可能希望在团队成员之间或在不同环境中共享配置。我们可以使用Docker Compose文件,该文件每次都会创建新的容器。在这种情况下,必须使用卷。


下一章将介绍生产环境中Docker数据库的具体用法。

4.在生产中使用Docker

Docker Compose非常适合共享配置并将容器作为无状态服务进行管理。如果服务失败或无法处理工作量,我们可以将Docker Compose配置为自动创建新容器。这对于为REST后端构建生产集群非常有用,该集群在设计上是无状态的。

但是,数据库是有状态的,并且它们的管理更为复杂:让我们回顾一下不同的上下文。

4.1 单实例数据库

让我们假设我们正在构建一个非关键环境,用于测试或生产,该环境可以容忍停机时间(在部署,备份或故障期间)。


在这种情况下,我们不需要高可用性集群,我们可以简单地将Docker Compose用于单实例数据库

  • 們可以使用簡單的捲進行數據存儲,因為容器將在同一台機器上執行

  • 我们可以限制它使用全局模式一次运行一个容器

讓我們看一個簡單的工作示例

version: '3'

 services:

 database:

 image: 'postgres'

 deploy:

 mode: global

 environment:

 - POSTGRES_PASSWORD=password

 ports:

 - "5432:5432"

 volumes:

 - "C:/docker-db-volume:/var/lib/postgresql/data"

使用此配置,我们的产品将一次仅创建一个容器,并重新使用C:\docker-db-volume目录中的数据文件。


但是,在此配置中进行定期备份甚至更为重要。如果发生配置错误,该目录可能会被container擦除或破坏。

4.2 集群的数据库

现在让我们假设我们的生产环境至关重要。


在这种情况下,诸如Docker Swarm和Kubernetes之类的编排工具对于无状态容器是有好处的:它们提供垂直和水平群集,并具有负载平衡,故障转移和自动扩展功能。


不幸的是,由于我们的数据库容器是有状态的,因此这些解决方案没有提供卷复制机制。


另一方面,构建自制配置很危险,因为它可能导致严重的数据丢失。例如

  • 对卷使用NFS或NAS之类的共享存储不能保证在另一个实例中重新启动数据库时不会丢失数据

  • 在主从集群上,让Docker业务流程选择多个主节点是一个常见错误,这将导致数据损坏

到目前为止,我们的不同选择是:

  • 不要将Docker用于数据库,而应实现特定于数据库或硬件的复制机制

  • 请勿将Docker用于数据库,而订阅OpenShift,Amazon AWS或Azure等平台即服务解决方案

  • 使用特定于Docker的复制机制,例如KubeDB和Portworx

5.结论

在本文中,我们回顾了适用于开发,测试和非关键生产的基本配置。


最后,我们得出结论,当在高可用性环境中使用Docker时,存在缺点。因此,应避免使用它或与专门用于数据库群集的解决方案结合使用。


标签:

0 评论

发表评论

您的电子邮件地址不会被公开。 必填的字段已做标记 *