How to restore a Postgres dump in kubernetes? - postgresql

have taken a Postgres dump using the below script and it was successful in k8.
kubectl -n [namespace] exec -it [pod name] -- bash -c "export PGPASSWORD='[db password]'; pg_dump -U [db user] [db name]" > [database].sql
what is the equivalent command to restore the same dump in kubernetes?

In order to restore the dump, you simply use psql:
kubectl -n [namespace] exec -it [pod name] -- bash -c "export PGPASSWORD='[db password]'; psql -U [db user] [new db name] -f [database].sql"

Related

Dockerized Postgresql : Delete PGDATA content

I am trying to configure replication between two Postgresql docker containers. All tutorials out there - which are based on regular VM, not containers - states that a backup from the Master has to be done in the Replica / StandBy, through a command like this:
pg_basebackup -h 192.168.0.108 -U replicator -p 5432 -D $PGDATA -Fp -Xs -P -R
Unfortunately, this throws an error:
pg_basebackup: error: directory "/var/lib/postgresql/data" exists but is not empty
I cannot delete the content of this folder because the Postgresql service will crash and I will be kicked out of the container.
So, how can I do this given that I cannot stop the Postgresql service because of the containerized application?
These instructions following the percona docs for configuration
postgres replication.
Create a network for the postgres servers:
docker network create pgnet
Start the primary database server:
docker run -d \
--network pgnet \
-v primary_data:/var/lib/postgresql/data \
--name pg_primary \
-e POSTGRES_PASSWORD=secret \
-e POSTGRES_DB=exampledb \
docker.io/postgres:14
Create a replication user and configure pg_hba.conf to allow
replication access:
docker exec pg_primary \
psql -U postgres -c \
"CREATE USER replicator WITH REPLICATION ENCRYPTED PASSWORD 'secret'"
docker exec pg_primary \
sh -c 'echo host replication replicator 0.0.0.0/0 md5 >> $PGDATA/pg_hba.conf'
docker exec pg_primary \
psql -U postgres -c 'select pg_reload_conf()'
Prepare the pgdata directory for the replica server. We do this by running the pg_basebackup command in an ephemeral container:
docker run -it --rm \
--network pgnet \
-v replica_data:/var/lib/postgresql/data \
--name pg_replica_init \
docker.io/postgres:14 \
sh -c 'pg_basebackup -h pg_primary -U replicator -p 5432 -D $PGDATA -Fp -Xs -P -R -W'
(The -W in the above command forces pg_basebackup to prompt for a
password. There are other ways you could provide the password; the
postgres docs have details.)
Start the replica:
docker run -d \
--network pgnet \
-v replica_data:/var/lib/postgresql/data \
--name pg_replica \
docker.io/postgres:14
Verify that replication is working. Create a table in the primary:
docker exec pg_primary \
psql -U postgres exampledb -c 'create table example_table (id int, name text)'
See that it shows up in the replica:
docker exec pg_replica \
psql -U postgres exampledb -c '\d'
You should see as output:
List of relations
Schema | Name | Type | Owner
--------+---------------+-------+----------
public | example_table | table | postgres
(1 row)

Better way to run multiple docker commands

I have a docker container for my database. lets call it my_pgdb. I am writing a script in which i am issuing multiple commands 1 by 1 i.e.,
docker exec -i my_pgdb pg_dump --schema-only -U my_user my_db > schema.sql
docker exec -i my_pgdb dropdb -U my_user "${db_name}_my_db" || true
docker exec -i my_pgdb createdb -U my_user "${db_name}_my_db"
cat schema.sql | docker exec -i my_pgdb psql -U my_user "${db_name}_my_db"
Is there a better way to merge these commands into 1? I mean i am doing docker exec multiple times, can i just issue all commands once or other better optimized way?
You can use heredoc in sh command like this:
docker exec -i my_pgdb sh <<-EOF
pg_dump --schema-only -U my_user my_db > schema.sql
dropdb -U my_user "${db_name}_my_db" || true
createdb -U my_user "${db_name}_my_db"
psql -U my_user "${db_name}_my_db" < schema.sql
EOF

Readiness probe failure for Postgres because of "root"

I am trying to execute the very standard SELECT 1 command as a readiness probe command.
I've been through numerous posts on Postgres, root user and Kubernetes but I still can't get it right although this might be trivial.
I defined ENV variables POSTGRES_USER=postgres and POSTGRES_DB=mydb in the config manifest of my Postgres StatefulSet manifest.
I understood I had to use bash to execute a command since ENV variables are not interpolated.
All following commands fail with FATAL, role "root
bash -c pg_isready -U $POSTGRES_USER -p 5432 -> FATAL
bash -c psql -w -U $POSTGRES_USER -d $POSTGRES_DB -c 'SELECT 1;' -> FATAL
# bash doesn't read ENV ?
bash -c psql -w -U $POSTGRES_USER -d mydb -c 'SELECT 1;' -> FATAL
# maybe current user from host? "me" from "whoami"
bash -c psql -w -U me -d postgres -c 'SELECT 1;' -> FATAL
Then I execute the commands to check if bash gets the ENV variables -> NO
kubectl exec -it pg-dep-0 -- bash -c psql -U $POSTGRES_USER -d $POSTGRES_DB -c 'SELECT 1;' -> FATAL
kubectl exec -it pg-dep-0 -- bash -c psql -U $POSTGRES_USER -d $POSTGRES_DB -c 'SELECT 1;' -> FATAL
kubectl exec -it pg-dep-0 -- psql -U $POSTGRES_USER -d $POSTGRES_DB -c 'SELECT 1;' -> FATAL
but:
kubectl exec -it pg-dep-0 -- psql -U postgres -c 'SELECT 1;' <-- correct
kubectl exec -it pg-dep-0 -- sh
/ # echo $POSTGRES_USER
postgres <-- correct
succeeds, without bash but no ENV variable.
Finally, setting directly the values and not using bash with psql -U postgres -c 'SELECT 1; (without bash) as the command for the readiness probe also fails: Postgres is up, but the test returns "Readiness probe failed".
I used directly:
spec.tempalte.spec.containers:
[...]
envFrom:
- configMapRef:
name: config
readinessProbe:
exec:
command:
- bash
- "-c"
- |
psql -U "postgres" -d "mydb" -c 'SELECT 1;'
apiVersion: v1
kind: ConfigMap
metadata:
name: config
data:
POSTGRES_HOST: "pg-svc"
POSTGRES_DB: "mysb"
POSTGRES_USER: "postgres"
A bit lost, any advice?

How to mount postgres backup into the postgres container running

docker run -d --rm --name dummy -v postgres_volume:/root alpine tail -f /dev/null
docker cp ./data dummy:/root
docker stop dummy
docker run -p 5432:5432 -v postgres_volume:/var/lib/postgresql -e POSTGRES_PASSWORD=password postgres
The above commands giving error: mkdir: cannot create directory ‘/var/lib/postgresql’: Permission denied.
./data in the docker cp command contains the Postgres backup.
What am I missing?
You (or rather postgres) are missing permissions for the files you have copied. This should fix it:
docker run --rm -v postgres_volume:/var/lib/postgresql postgres /bin/sh -c \
'chown --recursive $(id -u postgres):$(id -g postgres) /var/lib/postgresql'

how to connect to psql using password on kubernetes

I want to connect to psql using password on kubectl exec command on kubernetes like
kubectl exec -it postgres -- bash \`psql -h $IP -U admin --password password -p $PORT dbname\`
I tried to command
kubectl exec -it $podid -- bash \`psql -h $IP -U admin --password -p $PORT postgresdb\`
and
kubectl exec -it $podid -- bash -c "psql -- dbname=postgresql://postgres:password#$ip:$port/postgresdb -c 'INSERT INTO public."user" (user_id,user_pw,user_nm,email,phone,is_admin) VALUES ('admin','admin','admin','admin#admin.com',NULL,true);'"
but these command did not work.
How can I connect to psql using kubernetes commands and password?
try
kubectl exec -it <postgresspod-name> bash or sh
when you inside the container you can just do
PGPASSWORD=<password> psql -h <host or service name or localhost> -U <username> <dbname>
another option is
kubectl exec -it postgres -- bash \`PGPASSWORD=<password> psql -h <host or service name or localhost> -U <username> <dbname>\`
The accepted answer did not work for me (command PGPASSWORD=<...> not found).
This worked :
kubectl exec -ti postgres -- env PGPASSWORD=$PASSWD psql psql -h <host> -U <username> <dbname>
As you asking only for command I assume you have all Deployments, Services, etc.
Please execute command below:
$ kubectl exec -ti <postgresspod-name> -- psql -h <node/host IP> -U postgresadmin --password -p <port> postgresdb
Password for user postgresadmin:
After you will type password you will be connected to Postgres
For me only this works
kubectl exec postgres-postgresql-0 -n nte -- sh -c 'PGPASSWORD=postgres psql -U "postgres" -d "database_name" -c "select * from table_name"'
You can try this way :
kubectl exec -i <plsql podname> -- psql -h <host or service name or localhost> -u <username> -p<password>