拨开荷叶行,寻梦已然成。仙女莲花里,翩翩白鹭情。
IMG-LOGO
主页 文章列表 Kubernetespostgres-用户的密码认证失败

Kubernetespostgres-用户的密码认证失败

白鹭 - 2022-02-10 2136 0 0

我想要达到的目标

我正在建立一个由 postgres 数据库和一个与数据库通信的 elixir 应用程序组成的 microk8s 集群。

我遇到的问题

尝试连接时,我总是从数据库 pod 中收到错误讯息:

2022-01-05 18:54:05.179 UTC [216] DETAIL:  Password does not match for user "phoenix_db_username
        ".
        Connection matched pg_hba.conf line 99: "host all all all md5"

由于数据库记录了错误,数据库和应用程序之间的连接显然正常作业。

我试过的

其他有问题的人建议洗掉 PV 和 PVC。请参阅此 github 问题:https : //github.com/helm/charts/issues/16251#issuecomment-577560984

  • 我试过洗掉 pvc 和 pv,我可以确认 pv 已被洗掉,因为我/var/snap/microk8s/common/default-storage在洗掉它之前和之后检查过它。
  • 我尝试通过运行microk8s.disable storage并再次启用存盘来永久洗掉存盘microk8s.enable storage

输出microk8s.disable storage

Disabling default storage
[...]
Storage removed
Remove PVC storage at /var/snap/microk8s/common/default-storage ? (Y/N): y
Storage space reclaimed
  • 我用 printenv 检查了数据库 pod 的环境,我看到了 POSTGRES_USER 和 POSTGRES_PASSWORD 的正确值(phoenix_db_username,phoenix_db_password)
  • 我用 printenv 检查了应用程序 pod 的环境,我看到了 DB_USERNAME 和 DB_PASSWORD 的正确值(phoenix_db_username,phoenix_db_password)
  • 我检查了 pq_hba.conf 档案,它不包含任何用户

根据 postgres docker 档案,这应该创建一个用户,但我不认为它正在创建一个用户。https://hub.docker.com/_/postgres

Elixir 应用 yml 资源

Elixir 应用的 configMap

apiVersion: v1
kind: ConfigMap
metadata:
  name: phoenix-app-config
  labels:
    app: phoenix-app
data:
  APP_NAME: "phoenix-app"
  APP_HOST: "0.0.0.0"
  APP_PORT: "4000"
  DB_NAME: "prod_db"
  DB_HOSTNAME: "phoenix-app-database"
  NAMESPACE: "production"

长生不老药应用程序的秘密

apiVersion: v1
kind: Secret
metadata:
  name: phoenix-app-secrets
  labels:
    app: phoenix-app
data:
  SECRET_KEY_BASE: KtpxCV3OY8KnRiC5yVo7Be GRVeND NxAsyk FASDFasdfadffhNS804MLk
  DB_PASSWORD: cGhvZW5peC1kYi1wYXNzd29yZAo= # phoenix_db_username
  DB_USERNAME: cGhvZW5peC1kYi11c2VybmFtZQo= # phoenix_db_password

Elixir 应用程序的部署

apiVersion: apps/v1
kind: Deployment
metadata:
  name: phoenix-app
  labels:
    app: phoenix-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: phoenix-app
  strategy:
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 1
    type: RollingUpdate
  template:
    metadata:
      labels:
        app: phoenix-app
    spec:
      containers:
      - name: phoenix-app
        image: REDACTED
        imagePullPolicy: Always
        command: ["./bin/hello", "start"]
        lifecycle:
          preStop:
            exec:
              command: ["./bin/hello", "stop"]
        ports:
        - containerPort: 4000
        env:
        - name: POD_IP
          valueFrom:
            fieldRef:
              fieldPath: status.podIP
        envFrom:
        - configMapRef:
            name: phoenix-app-config
        - secretRef:
            name: phoenix-app-secrets
      imagePullSecrets:
      - name: gitlab-pull-secret

数据库 yml 资源

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: phoenix-app-database
  labels:
    app: phoenix-app-database
spec:
  serviceName: phoenix-app-database
  replicas: 1
  selector:
    matchLabels:
      app: phoenix-app-database
  template:
    metadata:
      labels:
        app: phoenix-app-database
    spec:
      containers:
      - name: phoenix-app-database
        image: postgres:12-alpine
        envFrom:
        - configMapRef:
            name: phoenix-app-database-config
        - secretRef:
            name: phoenix-app-database-secrets
        ports:
        - containerPort: 5432
          name: postgresdb
        volumeMounts:
        - name: phoenix-app-database
          mountPath: /var/lib/postgresql/data
      volumes:
      - name: phoenix-app-database
        persistentVolumeClaim:
          claimName: phoenix-app-db-pvc
---
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: phoenix-app-db-pvc
spec:
  storageClassName: microk8s-hostpath
  capacity:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 250Mi
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: phoenix-app-database-config
  labels:
    app: phoenix-app-database
data:
  POSTGRES_DB: "prod_db"
---
apiVersion: v1
kind: Secret
metadata:
  name: phoenix-app-database-secrets
  labels:
    app: phoenix-app-database
data:
  POSTGRES_USER: cGhvZW5peF9kYl91c2VybmFtZQo= # phoenix_db_username
  POSTGRES_PASSWORD: cGhvZW5peF9kYl9wYXNzd29yZAo= # phoenix_db_password
---
apiVersion: v1
kind: Service
metadata:
  name: phoenix-app-database
  labels:
    app: phoenix-app-database
spec:
  ports:
  - port: 5432
    name: phoenix-app-database
  type: NodePort 
  selector:
    app: phoenix-app-database
---

来自数据库 pod 创建的日志

me@me:~/Documents/kubernetes-test$ kubectl logs phoenix-app-database-0 -n production
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 dynamic shared memory implementation ... posix
selecting default max_connections ... 100
selecting default shared_buffers ... 128MB
selecting default time zone ... UTC
creating configuration files ... ok
running bootstrap script ... ok
sh: locale: not found
2022-01-05 20:47:02.013 UTC [30] WARNING:  no usable system locales were found
performing post-bootstrap initialization ... ok
syncing data to disk ... ok


Success. You can now start the database server using:

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

initdb: warning: enabling "trust" authentication for local connections
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....2022-01-05 20:47:02.621 UTC [36] LOG:  starting PostgreSQL 12.9 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
2022-01-05 20:47:02.623 UTC [36] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2022-01-05 20:47:02.641 UTC [37] LOG:  database system was shut down at 2022-01-05 20:47:02 UTC
2022-01-05 20:47:02.645 UTC [36] LOG:  database system is ready to accept connections
 done
server started
CREATE DATABASE


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

waiting for server to shut down....2022-01-05 20:47:02.794 UTC [36] LOG:  received fast shutdown request
2022-01-05 20:47:02.795 UTC [36] LOG:  aborting any active transactions
2022-01-05 20:47:02.797 UTC [36] LOG:  background worker "logical replication launcher" (PID 43) exited with exit code 1
2022-01-05 20:47:02.797 UTC [38] LOG:  shutting down
2022-01-05 20:47:02.808 UTC [36] LOG:  database system is shut down
 done
server stopped

PostgreSQL init process complete; ready for start up.

2022-01-05 20:47:02.904 UTC [1] LOG:  starting PostgreSQL 12.9 on x86_64-pc-linux-musl, compiled by gcc (Alpine 10.3.1_git20211027) 10.3.1 20211027, 64-bit
2022-01-05 20:47:02.904 UTC [1] LOG:  listening on IPv4 address "0.0.0.0", port 5432
2022-01-05 20:47:02.905 UTC [1] LOG:  listening on IPv6 address "::", port 5432
2022-01-05 20:47:02.909 UTC [1] LOG:  listening on Unix socket "/var/run/postgresql/.s.PGSQL.5432"
2022-01-05 20:47:02.925 UTC [50] LOG:  database system was shut down at 2022-01-05 20:47:02 UTC
2022-01-05 20:47:02.929 UTC [1] LOG:  database system is ready to accept connections

uj5u.com热心网友回复:

好的,我已经解决了这个问题,修复起来相当简单,但很难注意到。

我正在通过模板创建 yml 档案,例如:

apiVersion: v1
kind: Secret
metadata:
  name: {{APP_NAME}}-database-secrets
  labels:
    app: {{APP_NAME}}-database
data:
  POSTGRES_USER: {{DB_USERNAME_B64}}
  POSTGRES_PASSWORD: {{DB_PASSWORD_B64}}

然后我将这些模板合并在一起,并将所有{{ }}包含的宣告替换为来自特定环境的值。以 _B64 结尾的我在插入之前将其编码为 base64 格式。

我这样做似乎作业正常:

if [[ "${variable_key}" == *_B64 ]]; then
    variable_value="$(echo "${variable_value}" | base64)"
fi

但是,这是不行的,因为当我echo在这里的变量时,我在变量中附加了一个换行符,这使得数据库名称和用户名对于 postgres 来说是非法的。我在检查 base64decode.org 上的译码值时意识到了这一点,发现有两行。

我通过将 bash 脚本更改为不打印换行符 ( -n)来修复它

if [[ "${variable_key}" == *_B64 ]]; then
    variable_value="$(echo -n "${variable_value}" | base64 -w 0 )"
fi

我希望这可以帮助将来有人除错这个问题!

标签:

0 评论

发表评论

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