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

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

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

问题

我想使用Kubernetes部署PostgreSQL

这是我的PostgreSQL Pod YAML文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      securityContext:
        runAsUser: 70
        runAsGroup: 70
        fsGroup: 70
        fsGroupChangePolicy: "Always"
      containers:
        - image: docker.io/postgres:14.8-alpine3.18
          name: postgres
          resources:
            limits:
              hugepages-2Mi: 512Mi
              memory: 2Gi
              cpu: "8"
            requests:
              memory: 128Mi
              cpu: "1"
          env:
            - name: POSTGRES_DB
              value: postgres_db_name
            - name: POSTGRES_USER
              value: postgres_db_user
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secrets
                  key: root_password_key
            - name: PGDATA
              value: /some/path/here
          ports:
            - containerPort: 5432
              name: postgres
          volumeMounts:
            - name: postgres-volume-name
              mountPath: /some/path/here
      volumes:
        - name: postgres-volume-name
          persistentVolumeClaim:
            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

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
  labels:
    app: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      securityContext:
        runAsUser: 70
        runAsGroup: 70
        fsGroup: 70
        fsGroupChangePolicy: "Always"
      containers:
        - image: docker.io/postgres:14.8-alpine3.18
          name: postgres
          resources: 
            limits:
              hugepages-2Mi: 512Mi
              memory: 2Gi
              cpu: "8"
            requests:
              memory: 128Mi
              cpu: "1"
          env:
            - name: POSTGRES_DB
              value: postgres_db_name
            - name: POSTGRES_USER
              value: postgres_db_user
            - name: POSTGRES_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-secrets
                  key: root_password_key
            - name: PGDATA
              value: /some/path/here
          ports:
            - containerPort: 5432
              name: postgres
          volumeMounts:
            - name: postgres-volume-name
              mountPath: /some/path/here
      volumes:
        - name: postgres-volume-name
          persistentVolumeClaim:
            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

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

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

    dnsPolicy: ClusterFirst
      initContainers:
      - command:
        - sh
        - -c
        - chown -R 1000:1000 /usr/share/XYZ/data
        - mkdir /usr/share/XYZ
        - sysctl -w vm.max_map_count=262144
        - chmod 777 /usr/share/XYZ
        image: busybox:1.29.2
        imagePullPolicy: IfNotPresent
        name: set-dir-owner
        resources: {}
        securityContext:
          privileged: true
        terminationMessagePath: /dev/termination-log
        terminationMessagePolicy: File
        volumeMounts:
        - mountPath: /usr/share/XYZ
          name: data
      restartPolicy: Always

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

    apiVersion: apps/v1  
    kind: StatefulSet
    metadata:
      name: postgres
    spec:
      serviceName: "postgres"
      replicas: 1
      selector:
        matchLabels:
          app: postgres
      template:
        metadata:
          labels:
            app: postgres
        spec:
          containers:
          - name: postgres
            image: postgres:9.5
            volumeMounts:
            - name: postgres-data
              mountPath: /var/lib/postgresql/data
              subPath: pgdata
            env:
            - name: POSTGRES_USER
              value: root
            - name: POSTGRES_PASSWORD
              value: password
            - name: POSTGRES_DB
              value: kong
            - name: PGDATA
              value: /var/lib/postgresql/data/pgdata
            ports:
            - containerPort: 5432
          terminationGracePeriodSeconds: 60
      volumeClaimTemplates:
      - metadata:
          name: postgres-data
        spec:
          accessModes:
          - "ReadWriteOnce"
          resources:
            requests:
              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.

dnsPolicy: ClusterFirst
  initContainers:
  - command:
    - sh
    - -c
    - chown -R 1000:1000 /usr/share/XYZ/data
    - mkdir /usr/share/XYZ
    - sysctl -w vm.max_map_count=262144
    - chmod 777 /usr/share/XYZ
    image: busybox:1.29.2
    imagePullPolicy: IfNotPresent
    name: set-dir-owner
    resources: {}
    securityContext:
      privileged: true
    terminationMessagePath: /dev/termination-log
    terminationMessagePolicy: File
    volumeMounts:
    - mountPath: /usr/share/XYZ
      name: data
  restartPolicy: Always

Try this stateful set if it's fine with you

apiVersion: apps/v1  
kind: StatefulSet
metadata:
  name: postgres
spec:
  serviceName: "postgres"
  replicas: 1
  selector:
    matchLabels:
      app: postgres
  template:
    metadata:
      labels:
        app: postgres
    spec:
      containers:
      - name: postgres
        image: postgres:9.5
        volumeMounts:
        - name: postgres-data
          mountPath: /var/lib/postgresql/data
          subPath: pgdata
        env:
        - name: POSTGRES_USER
          value: root
        - name: POSTGRES_PASSWORD
          value: password
        - name: POSTGRES_DB
          value: kong
        - name: PGDATA
          value: /var/lib/postgresql/data/pgdata
        ports:
        - containerPort: 5432
      terminationGracePeriodSeconds: 60
  volumeClaimTemplates:
  - metadata:
      name: postgres-data
    spec:
      accessModes:
      - "ReadWriteOnce"
      resources:
        requests:
          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:

  runAsUser: 1000
  runAsGroup: 3000
  fsGroup: 2000
  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:

确定