Postgres: config map vs secret to store credentials for Postgres deployment

Created on 26 Oct 2018  路  4Comments  路  Source: docker-library/postgres

What happened:
When I tried to reference credentials stored in a Kubernetes secret's values to Postgres - it didn't worked properly.

  1. create a secret
apiVersion: v1
kind: Secret
metadata:
  name: postgres-secret
type: Opaque
data:
  POSTGRES_DB: dGVzdAo= # test
  POSTGRES_USER: dGVzdAo= # test
  POSTGRES_PASSWORD: dGVzdAo= # test
  1. Reference those secrets as environment variables in Postgres deployment:
        - env:
            - name: POSTGRES_DB
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_DB
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_USER
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secret
                  key: POSTGRES_PASSWORD
  1. try to connect to DB from container:
root@postgres-84968677c9-c4z8q:/# env | grep POSTGRES
POSTGRES_DB=test
POSTGRES_PASSWORD=test
POSTGRES_USER=test
root@postgres-84968677c9-c4z8q:/# psql -U test
psql: FATAL:  role "test" does not exist
root@postgres-84968677c9-c4z8q:/# psql -U test -d test
psql: FATAL:  role "test" does not exist

As you can see - the user weren't created.

What you expected to happen:
Please take a look at the same flow, but for Config Map (it is working as expected):

  1. create a config map:
apiVersion: v1
kind: ConfigMap
metadata:
  name: postgres-config
data:
  POSTGRES_DB: test
  POSTGRES_USER: test
  POSTGRES_PASSWORD: test
  1. reference in deployment:
        - env:
            - name: POSTGRES_DB
              valueFrom:
                configMapKeyRef:
                  name: postgres-config
                  key: POSTGRES_DB
            - name: POSTGRES_USER
              valueFrom:
                configMapKeyRef:
                  name: postgres-config
                  key: POSTGRES_USER
            - name: POSTGRES_PASSWORD
              valueFrom:
                configMapKeyRef:
                  name: postgres-config
                  key: POSTGRES_PASSWORD
  1. try to connect:
root@postgres-5d95457659-gpwgz:/# env | grep POSTGRES
POSTGRES_DB=test
POSTGRES_PASSWORD=test
POSTGRES_USER=test
root@postgres-5d95457659-gpwgz:/# psql -U test -d test
psql (11.0 (Debian 11.0-1.pgdg90+2))
Type "help" for help.

test=#

Success!

How to reproduce it (as minimally and precisely as possible):

See above.

Anything else we need to know?:

Environment:

  • Kubernetes version (use kubectl version):
Client Version: version.Info{Major:"1", Minor:"11", GitVersion:"v1.11.2", GitCommit:"bb9ffb1654d4a729bb4cec18ff088eacc153c239", GitTreeState:"clean", BuildDate:"2018-08-08T16:31:10Z", GoVersion:"go1.10.3", Compiler:"gc", Platform:"darwin/amd64"}
Server Version: version.Info{Major:"1", Minor:"9+", GitVersion:"v1.9.7-gke.6", GitCommit:"9b635efce81582e1da13b35a7aa539c0ccb32987", GitTreeState:"clean", BuildDate:"2018-08-16T21:33:47Z", GoVersion:"go1.9.3b4", Compiler:"gc", Platform:"linux/amd64"}
  • Cloud provider or hardware configuration: GKE
  • OS (e.g. from /etc/os-release):
  • Kernel (e.g. uname -a):
  • Install tools:
  • Others:
Issue question

Most helpful comment

I have found where the issue was. It is actually my fault. When I have created secret, i have run

$ echo "test" | base64
dGVzdAo=

the problem is that this encoded value contains newline character.
To get same value without newline character, I should have run

$ echo -n "test" | base64
dGVzdA==

This way it works. I was able to start Postgres with secrets.

All 4 comments

The same error

I found. In my case trouble was in persistent volume that keeps old data

@Ivan-Feofanov could you post your specific yaml that you used successfully

I'm able to reproduce the same issue with kubernetes secrets in both Postgres and MySQL. I had also tried changing the API version to v1 and making it kind: Pod instead of a Deployment

secrets.yml

apiVersion: v1
kind: Secret
metadata:
  name: secret
type: Opaque
data:
  POSTGRES_DB: dGVzdAo= # test
  POSTGRES_USER: dGVzdAo= # test
  POSTGRES_PASSWORD: dGVzdAo= # test


postgres.yml

apiVersion: extensions/v1beta1                                                                                                                                
kind: Deployment                                                                                                                                              
metadata:                                                                                                                                                     
  name: dep                                                                                                                                                   
spec:                                                                                                                                                         
  selector:                                                                                                                                                   
    matchLabels:                                                                                                                                              
      name: kube-secrets                                                                                                                                      
      component: dep                                                                                                                                          
  rollbackTo:                                                                                                                                                 
    revision: 0                                                                                                                                               
  template:                                                                                                                                                   
    spec:                                                                                                                                                     
      imagePullSecrets: []                                                                                                                                    
      containers:                                                                                                                                             
      - name: postgres                                                                                                                                        
        image: postgres:11                                                                                                                                    
        env:                                                                                                                                                  
           - name: POSTGRES_DB                                                                                                                                
             valueFrom:                                                                                                                                       
               secretKeyRef:                                                                                                                                  
                 name: secret                                                                                                                                 
                 key: POSTGRES_DB                                                                                                                             
           - name: POSTGRES_USER                                                                                                                              
             valueFrom:                                                                                                                                       
               secretKeyRef:                                                                                                                                  
                 name: secret                                                                                                                                 
                 key: POSTGRES_USER                                                                                                                           
           - name: POSTGRES_PASSWORD                                                                                                                          
             valueFrom:                                                                                                                                       
               secretKeyRef:                                                                                                                                  
                 name: secret                                                                                                                                 
                 key: POSTGRES_PASSWORD                                                                                                                       
    metadata:                                                                                                                                                 
      labels:                                                                                                                                                 
        name: kube-secrets                                                                                                                                    
        component: dep                                                                                                                                        
  strategy:                                                                                                                                                   
    type: RollingUpdate                                                                                                                                       
    rollingUpdate: {}
  replicas: 1


docker logs

The files belonging to this database system will be owned by user "postgres".
This user must also own the server process.

The database cluster will be initialized with locale "en_US.utf8".
The default database encoding has accordingly been set to "UTF8".
The default text search configuration will be set to "english".

Data page checksums are disabled.

fixing permissions on existing directory /var/lib/postgresql/data ... ok
creating subdirectories ... ok
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting dynamic shared memory implementation ... posix
creating configuration files ... ok
running bootstrap script ... ok
performing post-bootstrap initialization ... ok

WARNING: enabling "trust" authentication for local connections
syncing data to disk ... ok

Success. You can now start the database server using:

    pg_ctl -D /var/lib/postgresql/data -l logfile start

You can change this by editing pg_hba.conf or using the option -A, or
--auth-local and --auth-host, the next time you run initdb.
waiting for server to start....2018-10-29 23:17:20.757 UTC [43] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2018-10-29 23:17:20.814 UTC [44] LOG:  database system was shut down at 2018-10-29 23:17:18 UTC
2018-10-29 23:17:20.832 UTC [43] LOG:  database system is ready to accept connections
 done
server started
CREATE DATABASE


/usr/local/bin/docker-entrypoint.sh: ignoring /docker-entrypoint-initdb.d/*

2018-10-29 23:17:21.950 UTC [43] LOG:  received fast shutdown request
waiting for server to shut down....2018-10-29 23:17:21.964 UTC [43] LOG:  aborting any active transactions
2018-10-29 23:17:21.973 UTC [43] LOG:  background worker "logical replication launcher" (PID 50) exited with exit code 1
2018-10-29 23:17:21.973 UTC [45] LOG:  shutting down
2018-10-29 23:17:22.013 UTC [43] LOG:  database system is shut down
 done
server stopped

PostgreSQL init process complete; ready for start up.

2018-10-29 23:17:22.085 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2018-10-29 23:17:22.086 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2018-10-29 23:17:22.092 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2018-10-29 23:17:22.118 UTC [61] LOG:  database system was shut down at 2018-10-29 23:17:21 UTC
2018-10-29 23:17:22.126 UTC [1] LOG:  database system is ready to accept connections
2018-10-29 23:18:00.648 UTC [98] FATAL:  role "test" does not exist

$ docker exec -it 6a5 bash
root@dep-6c47d54c54-6zpj8:/# env | grep POSTGRES
POSTGRES_DB=test                                                                                                                                              
POSTGRES_PASSWORD=test                                                                                                                                        
POSTGRES_USER=test                                                                                                                                            
root@dep-6c47d54c54-6zpj8:/# psql -Utest                                                                                                                      
psql: FATAL:  role "test" does not exist

I have found where the issue was. It is actually my fault. When I have created secret, i have run

$ echo "test" | base64
dGVzdAo=

the problem is that this encoded value contains newline character.
To get same value without newline character, I should have run

$ echo -n "test" | base64
dGVzdA==

This way it works. I was able to start Postgres with secrets.

Was this page helpful?
0 / 5 - 0 ratings