Kubernetes Pod Deployment: Terminating, Logs show mkdir:权限被拒绝

huangapple go评论138阅读模式
英文:

Kubernetes Pod Deployment: Terminating, Logs show mkdir:permission denied

问题

我想使用Kubernetes部署PostgreSQL

这是我的PostgreSQL Pod YAML文件

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: postgres
  5. labels:
  6. app: postgres
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. app: postgres
  12. template:
  13. metadata:
  14. labels:
  15. app: postgres
  16. spec:
  17. securityContext:
  18. runAsUser: 70
  19. runAsGroup: 70
  20. fsGroup: 70
  21. fsGroupChangePolicy: "Always"
  22. containers:
  23. - image: docker.io/postgres:14.8-alpine3.18
  24. name: postgres
  25. resources:
  26. limits:
  27. hugepages-2Mi: 512Mi
  28. memory: 2Gi
  29. cpu: "8"
  30. requests:
  31. memory: 128Mi
  32. cpu: "1"
  33. env:
  34. - name: POSTGRES_DB
  35. value: postgres_db_name
  36. - name: POSTGRES_USER
  37. value: postgres_db_user
  38. - name: POSTGRES_PASSWORD
  39. valueFrom:
  40. secretKeyRef:
  41. name: postgres-secrets
  42. key: root_password_key
  43. - name: PGDATA
  44. value: /some/path/here
  45. ports:
  46. - containerPort: 5432
  47. name: postgres
  48. volumeMounts:
  49. - name: postgres-volume-name
  50. mountPath: /some/path/here
  51. volumes:
  52. - name: postgres-volume-name
  53. persistentVolumeClaim:
  54. claimName: postgres-pv-claim

运行后

kubectl get pods

我的Pod状态是terminating,所以我检查了日志,显示

mkdir: 无法创建目录 '/some/path/here':权限被拒绝

我该如何解决这个问题?
谢谢!

英文:

I want to deploy postgres using kubernetes

This is my postgres pod yaml file

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: postgres
  5. labels:
  6. app: postgres
  7. spec:
  8. replicas: 1
  9. selector:
  10. matchLabels:
  11. app: postgres
  12. template:
  13. metadata:
  14. labels:
  15. app: postgres
  16. spec:
  17. securityContext:
  18. runAsUser: 70
  19. runAsGroup: 70
  20. fsGroup: 70
  21. fsGroupChangePolicy: "Always"
  22. containers:
  23. - image: docker.io/postgres:14.8-alpine3.18
  24. name: postgres
  25. resources:
  26. limits:
  27. hugepages-2Mi: 512Mi
  28. memory: 2Gi
  29. cpu: "8"
  30. requests:
  31. memory: 128Mi
  32. cpu: "1"
  33. env:
  34. - name: POSTGRES_DB
  35. value: postgres_db_name
  36. - name: POSTGRES_USER
  37. value: postgres_db_user
  38. - name: POSTGRES_PASSWORD
  39. valueFrom:
  40. secretKeyRef:
  41. name: postgres-secrets
  42. key: root_password_key
  43. - name: PGDATA
  44. value: /some/path/here
  45. ports:
  46. - containerPort: 5432
  47. name: postgres
  48. volumeMounts:
  49. - name: postgres-volume-name
  50. mountPath: /some/path/here
  51. volumes:
  52. - name: postgres-volume-name
  53. persistentVolumeClaim:
  54. claimName: postgres-pv-claim

After running

> kubectl get pods

I POD status is terminating, so I have checked logs and
It shows

> mkdir: can't create directory '/some/path/here': Permission denied

How can I solve this?
Thanks!

答案1

得分: 1

你所看到的错误是由于文件权限问题导致的,你无法创建目录。

你可以首先更改安全上下文以覆盖权限,如果不行,可以使用初始化容器来更改文件权限或创建目录。

  1. dnsPolicy: ClusterFirst
  2. initContainers:
  3. - command:
  4. - sh
  5. - -c
  6. - chown -R 1000:1000 /usr/share/XYZ/data
  7. - mkdir /usr/share/XYZ
  8. - sysctl -w vm.max_map_count=262144
  9. - chmod 777 /usr/share/XYZ
  10. image: busybox:1.29.2
  11. imagePullPolicy: IfNotPresent
  12. name: set-dir-owner
  13. resources: {}
  14. securityContext:
  15. privileged: true
  16. terminationMessagePath: /dev/termination-log
  17. terminationMessagePolicy: File
  18. volumeMounts:
  19. - mountPath: /usr/share/XYZ
  20. name: data
  21. restartPolicy: Always

如果对你来说可以的话,请尝试这个有状态集(stateful set):

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: postgres
  5. spec:
  6. serviceName: "postgres"
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app: postgres
  11. template:
  12. metadata:
  13. labels:
  14. app: postgres
  15. spec:
  16. containers:
  17. - name: postgres
  18. image: postgres:9.5
  19. volumeMounts:
  20. - name: postgres-data
  21. mountPath: /var/lib/postgresql/data
  22. subPath: pgdata
  23. env:
  24. - name: POSTGRES_USER
  25. value: root
  26. - name: POSTGRES_PASSWORD
  27. value: password
  28. - name: POSTGRES_DB
  29. value: kong
  30. - name: PGDATA
  31. value: /var/lib/postgresql/data/pgdata
  32. ports:
  33. - containerPort: 5432
  34. terminationGracePeriodSeconds: 60
  35. volumeClaimTemplates:
  36. - metadata:
  37. name: postgres-data
  38. spec:
  39. accessModes:
  40. - "ReadWriteOnce"
  41. resources:
  42. requests:
  43. storage: 3Gi
英文:

The error you are seeing is due to the file permission and you are not able to create a directory.

You can change the security context first place to override the permission & if not you can use the init container to change the file permission or create a directory.

  1. dnsPolicy: ClusterFirst
  2. initContainers:
  3. - command:
  4. - sh
  5. - -c
  6. - chown -R 1000:1000 /usr/share/XYZ/data
  7. - mkdir /usr/share/XYZ
  8. - sysctl -w vm.max_map_count=262144
  9. - chmod 777 /usr/share/XYZ
  10. image: busybox:1.29.2
  11. imagePullPolicy: IfNotPresent
  12. name: set-dir-owner
  13. resources: {}
  14. securityContext:
  15. privileged: true
  16. terminationMessagePath: /dev/termination-log
  17. terminationMessagePolicy: File
  18. volumeMounts:
  19. - mountPath: /usr/share/XYZ
  20. name: data
  21. restartPolicy: Always

Try this stateful set if it's fine with you

  1. apiVersion: apps/v1
  2. kind: StatefulSet
  3. metadata:
  4. name: postgres
  5. spec:
  6. serviceName: "postgres"
  7. replicas: 1
  8. selector:
  9. matchLabels:
  10. app: postgres
  11. template:
  12. metadata:
  13. labels:
  14. app: postgres
  15. spec:
  16. containers:
  17. - name: postgres
  18. image: postgres:9.5
  19. volumeMounts:
  20. - name: postgres-data
  21. mountPath: /var/lib/postgresql/data
  22. subPath: pgdata
  23. env:
  24. - name: POSTGRES_USER
  25. value: root
  26. - name: POSTGRES_PASSWORD
  27. value: password
  28. - name: POSTGRES_DB
  29. value: kong
  30. - name: PGDATA
  31. value: /var/lib/postgresql/data/pgdata
  32. ports:
  33. - containerPort: 5432
  34. terminationGracePeriodSeconds: 60
  35. volumeClaimTemplates:
  36. - metadata:
  37. name: postgres-data
  38. spec:
  39. accessModes:
  40. - "ReadWriteOnce"
  41. resources:
  42. requests:
  43. storage: 3Gi

答案2

得分: 1

根据官方 Kubernetes 文档关于允许用户跳过挂载时的递归权限更改

在检查用于 StatefulSet 的 YAML 时,注意到在 pod 的 security context 中使用了 fsGroup,这确保了卷的内容可被每个新的 pod 读取和写入。设置 fsGroup 的一个副作用是,每次挂载卷时,Kubernetes 必须递归更改卷内所有文件和目录的所有者和权限。即使卷的组所有权已经与请求的 'fsGroup' 匹配,这也会发生,并且对于具有大量小文件的较大卷来说可能会非常昂贵,这会导致 pod 启动时间很长。

解决方案: 根据为 Pods 配置卷权限和所有权更改策略。建议将 fsGroupChangePolicy 设置为 "OnRootMismatch",这样如果卷的根目录已经具有正确的权限,则可以跳过递归权限更改。

fsGroupChangePolicy - fsGroupChangePolicy 定义卷在暴露给 Pod 之前更改所有权和权限的行为。此字段仅适用于支持 fsGroup 受控所有权和权限的卷类型。此字段有两个可能的值:

OnRootMismatch: 仅在根目录的权限和所有权与卷的期望权限不匹配时更改权限和所有权。这可以帮助缩短更改卷所有权和权限所需的时间。

Always: 每次挂载卷时都更改卷的权限和所有权。

例如:

securityContext:

  1. runAsUser: 1000
  2. runAsGroup: 3000
  3. fsGroup: 2000
  4. fsGroupChangePolicy: "OnRootMismatch"

*还参考System Admin 博客 by LiveStream 与错误相关的内容,可能有助于解决您的问题。

英文:

As per official Kubernetes doc on Allow users to skip recursive permission changes on mount:

While inspecting the YAML used for the StatefulSet, noticed there's the use of a fsGroup inside the pod’s security context, which makes sure that the volume's content can be readable and writable by each new pod. One side-effect of setting fsGroup is that, each time a volume is mounted, Kubernetes must recursively change the owner and permission of all the files and directories inside the volume. This happens even if group ownership of the volume already matches the requested 'fsGroup', and can be pretty expensive for larger volumes with lots of small files, which causes pod startup to take a long time.

Solution : As per Configure volume permission and ownership change policy for Pods. Suggest setting 'fsGroupChangePolicy' to "OnRootMismatch" so if the root of the volume already has the correct permissions, the recursive permission change can be skipped.

> fsGroupChangePolicy - fsGroupChangePolicy defines behavior for
> changing ownership and permission of the volume before being exposed
> inside a Pod. This field only applies to volume types that support
> fsGroup controlled ownership and permissions. This field has two
> possible values:
>
> OnRootMismatch: Only change permissions and ownership if the
> permission and the ownership of root directory does not match with
> expected permissions of the volume. This could help shorten the time
> it takes to change ownership and permission of a volume.
>
> Always: Always change permission and ownership of the volume when
> volume is mounted.
>
> For example:
>
> securityContext:
>
> runAsUser: 1000
> runAsGroup: 3000
> fsGroup: 2000
> fsGroupChangePolicy: "OnRootMismatch"

*Also refer to the System Admin blog by LiveStream related to the Error, which may help to resolve your issue.

huangapple
  • 本文由 发表于 2023年8月10日 15:27:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76873482.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定