Come rendere il database (o una parte di esso) accessibile a un processore di dati cloud?

Ero interessato a utilizzare servizi ETL come Stitch Data o Skyvia per integrare diverse fonti di dati (incluso il mio database Discourse), ma qualcuno di Skyvia mi ha detto che ciò non è possibile:

Skyvia può connettersi a PostgreSQL tramite SSH, tuttavia non è possibile connettersi quando si trova all’interno di un container Docker e il server SSH non si trova nel container ma davanti ad esso.

Questi sono i loro requisiti per la connessione a Postgres.

Esiste una soluzione ovvia?

Potresti abilitare SSH nel container di Discourse (su una porta non standard) e quindi permettere loro di connettersi lì. Credo che ci possa essere un esempio nella directory samples di Discourse_docker.

Grazie, Jay. Alla fine ho usato docker-ssh con autenticazione tramite chiave pubblica. :+1:

Sembra che mi stia sfuggendo un concetto chiave, dato che riesco a connettermi via SSH con la porta personalizzata e poi eseguire su postgres -c 'psql discourse' senza problemi. Tutto funziona con questo approccio in due passaggi, ma credo che per connettermi direttamente tramite pgAdmin (ad esempio) mi serva qualcosa di leggermente diverso.

Questo è il comando che sto usando per esporre una porta personalizzata:

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

Ciò mi permette in seguito di fare direttamente questo (senza dover avviare il container Docker tramite launcher enter app):

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

Ho provato diverse cose, ma senza successo. Sento che dovrebbe esserci un modo per eseguire ssh whatever@host -p XXXX e connettermi direttamente al database (che è probabilmente ciò che pgAdmin si aspetta).

Non riesci a connetterti o hai un problema di autorizzazioni?

Posso connettermi tramite riga di comando usando ssh e poi psql. Non riesco a connettermi tramite pgAdmin.

È necessario esporre direttamente la porta PostgreSQL per poter connettersi tramite pgAdmin.

Nel file app.yml, nella parte superiore, vedete le porte 80 e 443 aperte. Potete aggiungere un’altra riga per la porta 5432 di PostgreSQL.

Detto questo, è quasi certamente una pessima idea. Il database è passato dall’accettare solo connessioni locali all’essere esposto a tutto Internet.

Se avete solo bisogno di qualche report occasionale, scaricare alcuni file CSV da Data Explorer e caricarli nel vostro strumento preferito potrebbe essere sufficiente. Potete anche scaricare i backup di Discourse (senza gli allegati), che sono nel formato standard di dump PostgreSQL. Con questi a disposizione, potete ripristinarli su un’istanza PostgreSQL locale per l’analisi.

Grazie, Rafael

Ho fatto questo e ricompilato il container. Ma questo non funziona ancora (ho l’IP reale invece di XX.XX.XX.XX)

E nella scheda Tunnel SSH:

Questo è l’errore che ottengo

Riguardo a questo, capisco che sia un livello di protezione in meno, ma richiede comunque di possedere la chiave privata SSH, vero?

Se aggiungi 5432 a app.yml, è esposto direttamente, senza bisogno del tunnel SSH.

Non posso dare consigli sul tunnel SSH di pgAdmin, poiché non l’ho mai utilizzato. Immagino che si aspetti che la porta ascolti le connessioni locali, quindi non deve essere esposta a Internet.

Prova:

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

Ma non c’è una password per PostgreSQL perché richiede privilegi di superutente: il file pg_hba.conf ha le autorizzazioni di connessione “local” impostate su “peer”, quindi dipende dall’utente UNIX, il che richiede l’accesso via SSH, no?

Questo non funziona: psql -h XX.XX.XX.XX -p 5432 -U postgres -d discourse

Puoi connetterti a psql come superutente

./launcher enter app
su postgres
psql

e creare l’utente necessario con le autorizzazioni necessarie per i tuoi report.

Giusto, non ho problemi a connettermi dal contenitore Docker dell’app. Il mio problema è connettermi direttamente al database PostgreSQL dalla mia macchina locale (in modo da poter usare pgAdmin) o da un processore di dati cloud come Stitch. Entrambi si aspettano un indirizzo IP dell’host e le credenziali SSH, ma non sono riuscito a farli funzionare (ottengo l’errore che ho mostrato sopra).

L’unica cosa che sono riuscito a fare è usare docker-ssh per accedere direttamente al contenitore Docker dell’app (tramite chiave pubblica) dal mio computer locale (senza eseguire launcher enter app), ma devo comunque eseguire su postgres 'psql discourse' per accedere al database. Immagino che questo sia il problema con pgAdmin/Stitch: si aspettano una connessione diretta.

Hai provato a creare un nuovo database PostgreSQL con una password e a fornirlo al tuo servizio?

Sì, hanno una procedura piuttosto lunga.

Ma ho lo stesso problema semplicemente usando pgAdmin dal mio computer locale.

Credo che la guida Come passare da un contenitore autonomo a contenitori web e dati separati possa contenere istruzioni per impostare una password.

Inoltre, penso che potresti limitare l’ascolto della porta di PostgreSQL solo all’indirizzo 127.0.0.1.

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

Ho deciso di fare un passo indietro per vedere se riesco a connettermi al DB senza esporre nessuna porta. :grin:

Se entro nel container, vedo questo:

# 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

Se esco dal container e sono sul mio server remoto (non ancora sul mio computer locale), non dovrei essere in grado di connettermi usando questo?

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

Il problema è che mi viene chiesto una password. Dato che l’utente postgres non ne ha una, ho provato a creare un utente diverso e assegnargli una password:

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;

Ho aggiunto una riga per quell’utente con md5 in pg_hba.conf e ho riavviato PG con service postgresql restart

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

Tuttavia, quando provo a connettermi dal server remoto, ottengo un errore di autenticazione:

# 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"

Cosa mi sto perdendo? Sto cercando almeno di riuscire a connettermi al DB dallo stesso server. Il passo 2 sarebbe fare lo stesso usando un tunnel SSH, ma immagino che prima debba risolvere il passo 1. Qualsiasi aiuto è apprezzato.

Ok. Finalmente l’ho capito :tada:

Ho modificato questo:

in questo - "127.0.0.1:5433:5432" perché ho ricevuto un errore che indicava che la porta era già in uso.

Ho ricompilato il contenitore e verificato che la porta fosse effettivamente aperta:

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

Ora sono in grado di creare un tunnel SSH e connettermi dal mio server remoto utilizzando un utente con password:

# crea il tunnel (potresti anche usare ssh -f per eseguirlo in background)
ssh -v -N -L 5433:localhost:5433 INDIRIZZO_IP_SERVER

# connettiti in un'altra scheda e inserisci la password
psql -h localhost -d discourse -U whatever_user -p 5433

Se qualcuno sta cercando di fare questo e incontra problemi, fatemelo sapere.