如何使数据库(或其部分)对云数据处理器可访问?

我曾考虑使用像 Stitch DataSkyvia 这样的 ETL 服务来整合不同的数据源(包括我的 Discourse 数据库),但 Skyvia 的一位人员告诉我这是不可能的:

Skyvia 可以通过 SSH 连接 PostgreSQL,但如果 PostgreSQL 位于 Docker 容器内,而 SSH 服务器不在容器内而是在其前方,则无法连接。

这是他们连接 PostgreSQL 的 要求

是否有明显的解决方案?

您可以在 Discourse 容器(使用非标准端口)中启用 SSH,然后允许用户连接。我认为 Discourse_docker 的 samples 目录中可能有相关示例。

谢谢,Jay。我最终使用了 docker-ssh 配合公钥认证。:+1:

我似乎漏掉了一个关键概念,因为我能够通过自定义端口使用 SSH 连接,然后执行 su postgres -c 'psql discourse' 而没有任何问题。这种两步法一切正常,但我认为想要直接通过 pgAdmin(例如)连接,需要一些略微不同的配置。

这是我用来暴露自定义端口的命令:

docker run -d -p 2222:22 \
        -v /var/run/docker.sock:/var/run/docker.sock \
        -v ~/.ssh/authorized_keys:/authorized_keys \
        --name my-sshd \
        -e FILTERS={\"name\":[\"^/app$\"]} -e AUTH_MECHANISM=publicKey \
        -e AUTHORIZED_KEYS=/authorized_keys \
        jeroenpeeters/docker-ssh

这使得我之后可以直接执行以下操作(无需通过 launcher enter app 运行 Docker 容器):

ssh whatever@host -p 2222
su postgres -c 'psql discourse'

我尝试了多种方法,但均未成功。我觉得应该有一种方法可以执行 ssh whatever@host -p XXXX 并直接连接到数据库(这很可能就是 pgAdmin 所期望的)。

您无法连接,还是遇到了权限问题?

我可以通过命令行使用 ssh 连接,然后使用 psql 连接。但我无法通过 pgAdmin 连接。

您需要直接暴露 PostgreSQL 端口,才能通过 pgAdmin 进行连接。

app.yml 文件顶部附近,您会看到 80 和 443 端口已开放。您可以添加一行来开放 PostgreSQL 的端口 5432

不过,这极大概率是一个非常糟糕的做法。数据库从仅接受本地连接变为向整个互联网暴露。

如果您只是需要偶尔生成报告,从数据浏览器(Data Explorer)下载一些 CSV 文件并在您喜欢的工具中加载可能就足够了。您也可以下载 Discourse 备份(不包含上传文件),这些备份采用标准的 PostgreSQL 转储格式。有了这些文件,您就可以将其恢复到本地的 PostgreSQL 实例中进行分析。

谢谢,Rafael

我已经这样做了并重新构建了容器,但问题仍然存在(我使用的是真实 IP,而不是 XX.XX.XX.XX)

在 SSH 隧道选项卡中:

我遇到的错误如下:

关于这一点,我理解这减少了一层保护,但它仍然需要 SSH 私钥,对吧?

如果你在 app.yml 中添加 5432,该端口将直接暴露,无需通过 SSH 隧道。

我无法就 pgAdmin 的 SSH 隧道提供建议,因为我从未使用过它。我假设它期望端口监听本地连接,因此不需要暴露给互联网。

尝试以下配置:

expose:
  - "80:80"
  - "443:443"
  - "5432"

但是因为没有 PostgreSQL 密码,因为它需要超级用户权限:pg_hba.conf 文件将“local”连接权限设置为“peer”,所以它依赖于 UNIX 用户,这需要 SSH 登录,对吗?

这不起作用:psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse

您可以以超级用户身份连接到 psql

./launcher enter app
su postgres
psql

然后为您的报表创建具有必要权限的用户。

好的,从应用 Docker 容器内部连接没有问题。我的问题在于无法直接从本地机器(以便使用 pgAdmin)或从像 Stitch 这样的云端数据处理器直接连接到 PostgreSQL 数据库。这两者都期望提供主机 IP 地址和 SSH 凭据,但我一直无法让它们正常工作(我遇到了上面显示的错误)。

我目前唯一能做到的,是通过 docker-ssh 从本地计算机(无需执行 launcher enter app)使用公钥直接访问应用 Docker 容器。不过,我仍然需要执行 su postgres 'psql discourse' 才能访问数据库。我推测这就是 pgAdmin 和 Stitch 无法工作的原因——它们期望的是直接连接。

您是否尝试过创建一个带密码的新 PostgreSQL 实例,并将其密码提供给您的服务?

是的,他们有一套相当冗长的流程

不过,我在本地计算机上直接使用 pgAdmin 时也遇到了同样的问题。

我认为 如何从独立容器迁移到分离的 Web 和数据容器 这篇帖子中可能包含设置密码的说明。

此外,我认为你可以将 PostgreSQL 端口仅绑定到 127.0.0.1。

expose:
  - "80:80"
  - "443:443"
  - "127.0.0.1:5432:5432"

我决定退一步,看看是否能在不暴露任何端口的情况下连接到数据库。:grin:

如果进入容器,我会看到以下内容:

# netstat -lp | grep postgres
tcp        0      0 0.0.0.0:postgresql      0.0.0.0:*               LISTEN      -
tcp6       0      0 [::]:postgresql         [::]:*                  LISTEN      -
unix  2      [ ACC ]     STREAM     LISTENING     263612292 -                    /var/run/postgresql/.s.PGSQL.5432

如果退出容器并处于远程服务器上(尚未在本地计算机上),我是否应该能够使用以下命令进行连接?

/var/discourse# psql -h localhost -d discourse -U postgres

问题是我遇到了密码提示。由于 postgres 用户没有设置密码,我尝试创建另一个用户并为其分配密码:

CREATE USER whatever_user WITH ENCRYPTED PASSWORD '<whatever password>';
GRANT CONNECT ON DATABASE discourse TO whatever_user;
GRANT USAGE ON SCHEMA public TO whatever_user;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO whatever_user;
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO whatever_user;

我在 pg_hba.conf 中为该用户添加了一行 md5 配置,并使用 service postgresql restart 重启了 PostgreSQL:

# Database administrative login by Unix domain socket
local   all             postgres                                peer
local   all             whatever_user                      md5

然而,当我尝试从远程服务器连接时,却收到了身份验证失败的错误:

# psql -h localhost -d discourse -U whatever_user
Password for user whatever_user:
psql: FATAL:  password authentication failed for user "whatever_user"
FATAL:  password authentication failed for user "whatever_user"

我遗漏了什么?我至少希望能够在同一台服务器上连接到数据库。第二步是通过 SSH 隧道实现相同功能,但我想需要先解决第一步。任何帮助都将不胜感激。

好的,我终于搞定了 :tada:

我把这个:

改成了 - "127.0.0.1:5433:5432",因为我收到了端口已被占用的错误提示。

我重新构建了容器,并确认端口确实已开放:

$ sudo docker ps
CONTAINER ID        IMAGE                           COMMAND             CREATED             STATUS              PORTS                      NAMES
whatever_id        local_discourse/app             "/sbin/boot"        20 minutes ago      Up 20 minutes       127.0.0.1:5433->5432/tcp   app

现在我能够创建 SSH 隧道,并使用带密码的用户从远程服务器连接:

# 创建隧道(你也可以使用 ssh -f 在后台运行)
ssh -v -N -L 5433:localhost:5433 SERVER_IP_ADDRESS

# 在另一个标签页中连接并输入密码
psql -h localhost -d discourse -U whatever_user -p 5433

如果任何人尝试这样做时遇到任何问题,请告诉我。