如何以非root用户身份在docker中运行postgres?

问题描述 投票:0回答:2

我知道以 root 身份运行 docker 容器并不安全,所以我想改变它们的运行方式。我有一个运行 postgres 的容器,到目前为止它是以 root 身份运行的(默认)。但是,当我将这一行添加到我的

docker-compose
文件中时:

user: ${CURRENT_UID}

哪里

CURRENT_UID
是:

export CURRENT_UID=$(id -u):$(id -g)

我在容器日志中收到以下错误:

initdb: error: could not change permissions of directory "/var/lib/postgresql/data": Operation not permitted

fixing permissions on existing directory /var/lib/postgresql/data ... chmod: changing permissions of '/var/lib/postgresql/data': Operation not permitted

chmod: changing permissions of '/var/run/postgresql': Operation not permitted

运行

pg-admin
容器时情况相同,错误信息:

PermissionError: [Errno 13] Permission denied: '/var/log/pgadmin'

这些错误当然是有道理的,我不是 root,但 postgres 需要 root 访问权限。

这是否意味着非 root 无法运行?

postgresql docker
2个回答
9
投票

这是否意味着非 root 无法运行?

事实上,postgres 服务已经以非 root 用户身份运行。

postgres
容器的启动过程有效:

  1. 创建必要的目录并设置适当的所有权
  2. 切换到
    postgres
    用户
  3. 启动postgres

因此,如果您启动

postgres
图像,即使没有指定用户:

docker run -e POSTGRES_PASSWORD=secret postgres:14

您会发现它以

postgres
用户身份运行:

# ps -fe
UID          PID    PPID  C STIME TTY          TIME CMD
postgres       1       0  0 16:11 ?        00:00:00 postgres
postgres      56       1  0 16:11 ?        00:00:00 postgres: checkpointer
postgres      57       1  0 16:11 ?        00:00:00 postgres: background writer
postgres      58       1  0 16:11 ?        00:00:00 postgres: walwriter
postgres      59       1  0 16:11 ?        00:00:00 postgres: autovacuum launcher
postgres      60       1  0 16:11 ?        00:00:00 postgres: stats collector
postgres      61       1  0 16:11 ?        00:00:00 postgres: logical replication launcher

也完全可以以非根用户身份启动映像,但在这种情况下,您必须确保必要的目录存在并且具有适当的所有权。在像 Kubernetes/OpenShift 这样的环境中,容器编排系统会在安装卷时为您处理这个问题,但是当使用普通 Docker(或 docker-compose)时,您必须自己处理它。

这是一种方法:

  • 让“初始化容器”负责设置卷权限
  • 仅在初始化容器完成后启动 postgres
version: "3.9"

services:
  postgres-init:
    image: postgres:14
    volumes:
      - "postgres_data:/data"
    entrypoint:
      - sh
      - -c
      - |
        chown -R 2000:2000 /data

  postgres:
    depends_on:
      postgres-init:
        condition: service_completed_successfully

    image: postgres:14
    environment:
      POSTGRES_PASSWORD: "secret"
      PGDATA: /pgdata
    volumes:
      - "postgres_data:/pgdata"
    user: "2000"

volumes:
  postgres_data:

2
投票

我如何在 Kubernetes 中做到这一点:

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: db

spec:
  selector:
    matchLabels:
      app: db

  serviceName: "db"
  template:
    metadata:
      labels:
        app: db
    spec:

      initContainers:
        - name: db-init    # using root, change permissions to not use root in main container
          image: postgres
          command: 
            - 'sh'
            - '-c'
            - |
              chown -R 999:999 /var/lib/postgresql/data
              
          volumeMounts:
            - name:  db
              mountPath: /var/lib/postgresql/data


      containers:
      - name: db
        image: postgres
        securityContext:
          runAsUser: 999  # postgres user in container
          runAsGroup: 999

        envFrom:
          - secretRef:
             name: db-env

        ports:
        - containerPort: 5432
          name: db

        volumeMounts:
        - name: db
          mountPath: /var/lib/postgresql/data

        startupProbe:
          tcpSocket:
            port: db
          initialDelaySeconds: 5
          periodSeconds: 2
          failureThreshold: 15

        readinessProbe:
          exec:
            command:
              - bash 
              - '-c'
              - >
                psql -h localhost -U "${POSTGRES_USER}" -c 'select 1'

          initialDelaySeconds: 5
          periodSeconds: 5
          failureThreshold: 5

        livenessProbe:
          exec:
            command:
              - bash 
              - '-c'
              - >
                psql -h localhost -U "${POSTGRES_USER}" -c 'select 1'

          initialDelaySeconds: 5
          periodSeconds: 10

      volumes:
    
        - name: db
          persistentVolumeClaim:
            claimName: db 
© www.soinside.com 2019 - 2024. All rights reserved.