这些几乎是我按照顺序执行的步骤。基本上是文档概述的内容:
https://docs.microsoft.com/en-us/azure/aks/azure-files-dynamic-pv
azure-storage-claim.yaml
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: test-app-sc
provisioner: kubernetes.io/azure-file
mountOptions:
- dir_mode=0777
- file_mode=0777
- uid=1000
- gid=1000
- mfsymlinks
- nobrl
- cache=none
parameters:
skuName: Standard_LRS
location: westus
azure-storage.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: test-app-storage
spec:
accessModes:
- ReadWriteMany
storageClassName: test-app-sc
resources:
requests:
storage: 15Gi
PVC现在已设置。
根据Postgres图像文档更改了mountPath:
PGDATA
此可选变量可用于为数据库文件定义另一个位置,例如子目录。默认值为/ var / lib / postgresql / data,但是如果您使用的数据量是文件系统挂载点(例如GCE永久磁盘),则Postgres initdb建议使用一个子目录(例如/ var / lib / postgresql / data / pgdata)创建为包含数据。
这是非Docker特定的环境变量。由于该变量由postgres服务器二进制文件使用(请参见PostgreSQL文档),因此入口点脚本会将其考虑在内。
基于此,我的postgres.yaml
设置如下:
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment
spec:
replicas: 1
selector:
matchLabels:
component: postgres
template:
metadata:
labels:
component: postgres
spec:
containers:
- name: postgres
image: postgres:11-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: test-app-secrets
key: PGDATABASE
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: test-app-secrets
key: PGUSER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: test-app-secrets
key: PGPASSWORD
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
- name: PGDATA
value: /var/lib/postgresql-data
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql-data
subPath: postgres-storage
volumes:
- name: test-app-storage
persistentVolumeClaim:
claimName: test-app-storage
---
apiVersion: v1
kind: Service
metadata:
name: postgres-cluster-ip-service
spec:
type: ClusterIP
selector:
component: postgres
ports:
- port: 1423
targetPort: 5432
您收到错误:
chmod: changing permissions of '/var/lib/postgresql-data': Operation not permitted
因此将其中一个作为Dockerfile:
FROM postgres:11-alpine
EXPOSE 5432
RUN /bin/bash -c 'chmod 777 /var/lib/postgresql-data'
或
FROM postgres:11-alpine
EXPOSE 5432
这并不重要,通过执行以下任何操作,您仍然会收到相同类型的错误:
...
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql-data
subPath: postgres-storage
volumes:
- name: test-app-storage
persistentVolumeClaim:
claimName: test-app-storage
...
导致以下错误:
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.
initdb: error: directory "/var/lib/postgresql-data" exists but is not empty If you want to create a new database system, either remove or empty the directory "/var/lib/postgresql-data" or run initdb with an argument other than "/var/lib/postgresql-data".
尝试一下:
...
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql-data
subPath: postgres-storage
volumes:
- name: test-app-storage
persistentVolumeClaim:
claimName: test-app-storage
...
结果如下:
chmod: changing permissions of '/var/lib/postgresql-data': Operation not permitted
尝试一下:
...
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
value: "-D /var/lib/postgresql/data/pgdata"
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql/data/pgdata
subPath: postgres-storage
volumes:
- name: test-app-storage
persistentVolumeClaim:
claimName: test-app-storage
...
结果如下:
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.
initdb: error: could not change permissions of directory "/var/lib/postgresql/data/pgdata": Operation not permitted fixing permissions on existing directory /var/lib/postgresql/data/pgdata ...
So nothing seems to work that I've tried and following the documentation where I can.
有人建议像这样摆脱卷挂:
...
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
volumes:
- name: test-app-storage
persistentVolumeClaim:
claimName: test-app-storage
...
哪个,嘿,这确实有效!但是不会持久保留数据,因为它仅使用Pod存储,因此毫无意义:
当在Postgres中创建表,销毁Pod并重新部署它时,当然可以肯定,该表不再存在。
很有可能我做错了事,但是我一直在遵循文档,而且看起来应该可以。
哪里出了问题?
编辑:豆荚中的权限
显然,当PGDATA
与mountPath
是同一目录时,会发生权限问题。例如:
...
- name: PGDATA
value: /var/lib/postgresql-data
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql-data
subPath: postgres-storage
...
or
...
# if PGDATA is not specified it defaults to /var/lib/postgresql/data
# - name: PGDATA
# value: /var/lib/postgresql-data
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql/data
subPath: postgres-storage
...
类似这样的地方(它们不匹配)会创建Pod,但会使用我显然不想要的Pod存储:
# Thus /var/lib/postgresql/data
# - name: PGDATA
# value: /var/lib/postgresql-data
volumeMounts:
- name: test-app-storage
mountPath: /var/lib/postgresql-data
subPath: postgres-storage
权限ls -l
如下:
$ ls -l
drwxr-xr-x 1 root root 4096 Feb 2 06:06 apt
drwxr-xr-x 1 root root 4096 Feb 2 06:07 dpkg
drwxr-xr-x 2 root root 4096 Feb 2 06:06 exim4
drwxr-xr-x 2 root root 4096 Aug 28 2018 logrotate
drwxr-xr-x 2 root root 4096 Nov 10 12:17 misc
drwxr-xr-x 2 root root 4096 Jan 30 00:00 pam
drwxr-xr-x 1 postgres postgres 4096 Feb 2 06:07 postgresql
drwxrwxrwx 2 1000 1000 0 Jan 31 21:46 postgresql-data
drwxr-xr-x 1 root root 4096 Jan 30 00:00 systemd
drwxr-xr-x 3 root root 4096 Feb 2 06:07 ucf
$ ls -l postgresql && ls -l postgresql/data && ls -l postgresql-data
total 4
drwx------ 19 postgres postgres 4096 Feb 5 23:28 data
total 124
drwx------ 6 postgres postgres 4096 Feb 5 23:28 base
drwx------ 2 postgres postgres 4096 Feb 5 23:29 global
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_commit_ts
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_dynshmem
-rw------- 1 postgres postgres 4281 Feb 5 23:28 pg_hba.conf
-rw------- 1 postgres postgres 1636 Feb 5 23:28 pg_ident.conf
drwx------ 4 postgres postgres 4096 Feb 5 23:33 pg_logical
drwx------ 4 postgres postgres 4096 Feb 5 23:28 pg_multixact
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_notify
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_replslot
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_serial
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_snapshots
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_stat
drwx------ 2 postgres postgres 4096 Feb 5 23:51 pg_stat_tmp
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_subtrans
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_tblspc
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_twophase
-rw------- 1 postgres postgres 3 Feb 5 23:28 PG_VERSION
drwx------ 3 postgres postgres 4096 Feb 5 23:28 pg_wal
drwx------ 2 postgres postgres 4096 Feb 5 23:28 pg_xact
-rw------- 1 postgres postgres 88 Feb 5 23:28 postgresql.auto.conf
-rw------- 1 postgres postgres 26588 Feb 5 23:28 postgresql.conf
-rw------- 1 postgres postgres 36 Feb 5 23:28 postmaster.opts
-rw------- 1 postgres postgres 94 Feb 5 23:28 postmaster.pid
total 0
创建数据文件的权限为postgres
。但是,这样做不会将其映射到Azure文件和PVC。它只是留下而被豆荚摧毁。
我认为正在发生的事情是mountPath
使用root
,而PGDATA
使用postgres
,而mountPath
正试图使用postgres
? ??
真的,不确定,如何解决仍然迷路。
EDIT2
请回答以下答案:
https://stackoverflow.com/a/51203031/3123109
因此向我添加了以下内容:
- name: postgres
image: postgres
command:
- /bin/chown
- -R
- "1000"
- /var/lib/postgresql/data
但这会产生一个新错误:
The selected container has not logged any messages yet.
我猜是进步。
答案 0 :(得分:1)
我认为您的问题可能是由于您试图将子路径用作部署对象的一部分
请在没有此行的情况下重试您的第一个配置:
subPath:postgres-storage
应该导致这个 volumeMounts: -名称:postgres-storage mountPath:/ var / lib / postgresql / data / pgdata
让我知道是否有帮助。
更新:使用永久存储时,PostgreSQL的docker映像需要特别注意
https://hub.docker.com/_/postgres
要注意的主要警告是,postgres并不关心它运行的UID(只要/ var / lib / postgresql / data的所有者匹配),但是initdb确实在乎(并且需要用户存在于其中) / etc / passwd):
解决这个问题的三种最简单方法:
使用Debian变体(不是Alpine变体),从而允许映像使用nss_wrapper库为您“伪造” / etc / passwd内容(有关更多详细信息,请参阅docker-library / postgres#448)
从主机上以只读方式绑定安装/ etc / passwd(如果您想要的UID是主机上的有效用户):
$ docker run -it --rm --user“ $ {id -u):$(id -g)” -v / etc / passwd:/ etc / passwd:ro -e POSTGRES_PASSWORD = mysecretpassword postgres 属于该数据库系统的文件将由用户“ jsmith”拥有
$泊坞窗卷创建pgdata $ docker run -it --rm -v pgdata:/ var / lib / postgresql / data -e POSTGRES_PASSWORD = mysecretpassword postgres 属于该数据库系统的文件将由用户“ postgres”拥有。 (一旦成功完成初始化并等待连接,请停止它) $ docker run -it --rm -v pgdata:/ var / lib / postgresql / data bash chown -R 1000:1000 / var / lib / postgresql / data $ docker run -it --rm --user 1000:1000 -v pgdata:/ var / lib / postgresql / data postgres 日志:数据库系统于世界标准时间2017年1月20日00:03:23关闭 日志:现在启用了MultiXact成员环绕保护 日志:自动真空启动器已启动 日志:数据库系统已准备就绪,可以接受连接
一种解决方案是利用bitnami制作的helm图表,它们使用init容器制定了复杂的持久性存储配置的默认设置,并且还支持修复所需的/ dev / shm配置
还请注意,容器的默认/ dev / shm大小为64MB。如果共享内存已用完,您将遇到错误:无法调整共享内存段的大小。 。 。 : 设备上没有剩余空间。例如,您将要传递--shm-size = 256MB到docker run,或者通过docker-compose
这是图表使用的初始化容器的示例。
https://github.com/helm/charts/blob/master/stable/postgresql/templates/statefulset.yaml#L74-L115
建议使用头盔安装Postgres图表(使用statefuset),而不要尝试使用部署对象来部署数据库。 (通常,您希望将部署对象用于无状态应用程序。)
答案 1 :(得分:0)
最后,解决方案是改用 Azure 磁盘。也许这已得到修复,您可以从 2020 年初开始使用 Azure 文件,但自从使用 Azure 磁盘后我就没有尝试过。
我的 .yaml
配置如下所示:
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: file-storage
spec:
accessModes:
- ReadWriteMany
storageClassName: azurefile
resources:
requests:
storage: 25Gi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: postgres-storage
spec:
accessModes:
- ReadWriteOnce
storageClassName: default
resources:
requests:
storage: 25Gi
apiVersion: apps/v1
kind: Deployment
metadata:
name: postgres-deployment
spec:
replicas: 1
selector:
matchLabels:
component: postgres
template:
metadata:
labels:
component: postgres
spec:
containers:
- name: postgres
image: postgres:11-alpine
ports:
- containerPort: 5432
env:
- name: POSTGRES_DB
valueFrom:
secretKeyRef:
name: app-prod-secrets
key: PGDATABASE
- name: POSTGRES_USER
valueFrom:
secretKeyRef:
name: app-prod-secrets
key: PGUSER
- name: POSTGRES_PASSWORD
valueFrom:
secretKeyRef:
name: app-prod-secrets
key: PGPASSWORD
- name: POSTGRES_INITDB_ARGS
value: "-A md5"
- name: PGDATA
value: /var/postgresql/data
volumeMounts:
- name: postgres-storage
mountPath: /var/postgresql
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: postgres-storage
---
apiVersion: v1
kind: Service
metadata:
name: postgres-cluster-ip-service
spec:
type: ClusterIP
selector:
component: postgres
ports:
- port: 5432
targetPort: 5432
答案 2 :(得分:0)
之所以可以使用azure-disk,而不能使用azure-file,是因为azure-file是基于SMB协议的,而azure-disk不是[1]。
正如 GitHub.com 上的 andyzhangx 所述 [2]:
<块引用>SMB 挂载选项(包括 dir 权限)无法更改,这是由 SMB proto 设计的,而对于磁盘(ext4,xfs),可以在挂载后更改 dir 权限
也许 [3] 中使用的方法也是一个解决方案,但我现在也将坚持使用 azure-disk 来处理我的(Bitnami)Postgresql PVC。
答案 3 :(得分:0)
回答你所有的问题。我在 AKS 中使用 PVC 声明使 postgres pod 工作
从 https://github.com/docker-library/postgres/tree/5c0e796bb660f0ae42ae8bf084470f13417b8d63/12/buster 复制 docker 和 docker-entrypoint.sh 文件,我这么说的原因是我们需要修改 uid 和 gid 与 deployment.yaml 中定义的匹配,如下所示。我在这里使用 1025 。 安全上下文: runAsNonRoot: 假 以用户身份运行:1025 fsGroup:1025
更改docker文件中的2行
groupadd -r postgres --gid=1025;
useradd -r -g postgres --uid=1025--home-dir=/var/lib/postgresql --shell=/bin/bash postgres; \
然后在docker文件中添加一个额外的命令 -> COPY docker-entrypoint.sh /usr/local/bin/
运行 chmod +x /usr/local/bin/docker-entrypoint.sh
创建基础镜像并推送到 Azure 容器注册表
deployment.yaml 和 storage.yaml 如下
apiVersion:apps/v1
kind: Deployment
metadata:
name: kinetic-postgres-alpha
namespace: chatbot-dev
annotations:
buildNumber: 2020.04.15.1
contributors: "Rakesh Sekar"
azure-project: "Process"
azure-repository: "IT-Robotics-Chatbot_Common"
cmdb-app-name: "Robotics Chatbot" #
docs: https://wiki.prodapt.com/
description: |
Chatbot Postgres Deployment
labels:
svc: kinetic-postgres-alpha
spec:
replicas: 1
selector:
matchLabels:
svc: kinetic-postgres-alpha
template:
metadata:
labels:
svc: kinetic-postgres-alpha
annotations:
buildNumber: 2020.04.15.1
spec:
affinity:
podAntiAffinity:
preferredDuringSchedulingIgnoredDuringExecution:
- weight: 10
podAffinityTerm:
labelSelector:
matchExpressions:
- key: svc
operator: In
values:
- kinetic-postgres-alpha
topologyKey: "kubernetes.io/hostname"
containers:
- name: kinetic-postgres-alpha
image: winacr01.azurecr.io/robotics/chatbot_botpress_postgres_baseimage:12
imagePullPolicy: Always
ports:
- containerPort: 5432
protocol: TCP
resources:
limits:
cpu: 1000m
memory: 1024Mi
requests:
cpu: 750m
memory: 1024Mi
env:
- name: TZ
value: UTC
- name: POSTGRES_DB
value: botpress
- name: POSTGRES_USER
value: appadmin
- name: POSTGRES_PASSWORD
value: Admin4Chatbot
- name: spring_profiles_active
value: dev
- name: APP_NAME
value: kinetic-postgres-alpha
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SERVICE
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- mountPath: /var/lib/postgresql/data
subPath: pgdata
name: postgredb
volumes:
- name: postgredb
persistentVolumeClaim:
claimName: kinetic-postgres-pvc
securityContext:
runAsNonRoot: false
runAsUser: 1025
fsGroup: 1025
nodeSelector:
agentpool: robotics
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: kinetic-postgres-pvc
namespace: chatbot-dev
labels:
svc: kinetic-postgres-pvc
spec:
storageClassName: managed-premium-retain
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
这样可以避免错误,例如:
chmod:更改“var/lib/postgresql/data”的权限:权限被拒绝
chmod:更改“var/lib/postgresql/data/pgdata”的权限:权限被拒绝
如果您使用默认的 pgdata /var/lib/postgresql/data,为什么 Persistent 卷将无法工作,它会被挂载为 pod 存储,以使这项工作定义自定义 pgdata 并按如下方式挂载
- name: PGDATA
value: /var/lib/postgresql/data/pgdata
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: SERVICE
valueFrom:
fieldRef:
fieldPath: metadata.name
volumeMounts:
- mountPath: /var/lib/postgresql/data
subPath: pgdata
name: postgredb
我花了 2 周的时间才弄清楚这一点,希望它可以帮助像我一样尝试过的每个人。