运行 非 root 用户在 docker 容器中的进程

Run process with non-root user in docker container

我正在构建 run.sh 应该 运行 作为非 root 用户

的 redis 标志图像

run.sh

  while true; do
    master=$(redis-cli -h ${REDIS_SENTINEL_SERVICE_HOST} -p ${REDIS_SENTINEL_SERVICE_PORT} --csv SENTINEL get-master-addr-by-name mymaster | tr ',' ' ' | cut -d' ' -f1)
    if [[ -n ${master} ]]; then
      master="${master//\"}"
    else
      master=$(hostname -i)
    fi

    redis-cli -h ${master} INFO
    if [[ "$?" == "0" ]]; then
      break
    fi
    echo "Connecting to master failed.  Waiting..."
    sleep 10
  done

  sentinel_conf=/home/ubuntu/sentinel.conf

  echo "sentinel monitor mymaster ${master} 6379 2" > ${sentinel_conf}
  echo "sentinel down-after-milliseconds mymaster 60000" >> ${sentinel_conf}
  echo "sentinel failover-timeout mymaster 180000" >> ${sentinel_conf}
  echo "sentinel parallel-syncs mymaster 1" >> ${sentinel_conf}
  echo "bind 0.0.0.0" >> ${sentinel_conf}

  redis-sentinel ${sentinel_conf} --protected-mode no
}

function launchslave() {
  while true; do
    master=$(redis-cli -h ${REDIS_SENTINEL_SERVICE_HOST} -p ${REDIS_SENTINEL_SERVICE_PORT} --csv SENTINEL get-master-addr-by-name mymaster | tr ',' ' ' | cut -d' ' -f1)
    if [[ -n ${master} ]]; then
      master="${master//\"}"
    else
      echo "Failed to find master."
      sleep 60
      exit 1
    fi
    redis-cli -h ${master} INFO
    if [[ "$?" == "0" ]]; then
      break
    fi
    echo "Connecting to master failed.  Waiting..."
    sleep 10
  done
  sed -i "s/%master-ip%/${master}/" /redis-slave/redis.conf
  sed -i "s/%master-port%/6379/" /redis-slave/redis.conf
  redis-server /redis-slave/redis.conf --protected-mode no

Dockerfile

FROM alpine:3.4

RUN apk add --no-cache redis sed bash busybox-suid
#su: must be suid to work properly
COPY redis-master.conf /redis-master/redis.conf
COPY redis-slave.conf /redis-slave/redis.conf
RUN adduser -D ubuntu
USER ubuntu
COPY run.sh /home/ubuntu/run.sh
CMD [ "sh", "/home/ubuntu/run.sh" ]
ENTRYPOINT [ "bash", "-c" ]

我部署在 Openshift 中。容器不断重启,我也没有看到任何日志。我之前看过一些日志,当时 "run.sh" 是 root(默认),即 Dockerfile.

中没有提到任何 adduser

根据 docker documentation:

Both CMD and ENTRYPOINT instructions define what command gets executed when running a container.
There are few rules that describe their co-operation:
1. Dockerfile should specify at least one of CMD or ENTRYPOINT commands.
2. CMD will be overridden when running the container with alternative arguments.

CMDENTRYPOINT层在上面Dockerfile中完全不同,所以ENTRYPOINT覆盖了CMD层,这就是为什么CMD永远不会执行图层。

只需从Dockerfile中删除ENTRYPOINT层即可,此处不需要:

FROM alpine:3.4

RUN apk add --no-cache redis sed bash busybox-suid
#su: must be suid to work properly
COPY redis-master.conf /redis-master/redis.conf
COPY redis-slave.conf /redis-slave/redis.conf
RUN adduser -D ubuntu
USER ubuntu
COPY run.sh /home/ubuntu/run.sh
CMD [ "sh", "/home/ubuntu/run.sh" ]

更新:

我看到 [[ ]] 用于 run.sh 脚本。此构造适用于 bash,不适用于 sh。这就是 Dockerfile 应该是以下内容的原因:

FROM alpine:3.4

RUN apk add --no-cache redis sed bash busybox-suid
#su: must be suid to work properly
COPY redis-master.conf /redis-master/redis.conf
COPY redis-slave.conf /redis-slave/redis.conf
RUN adduser -D ubuntu
USER ubuntu
COPY run.sh /home/ubuntu/run.sh
CMD [ "bash", "/home/ubuntu/run.sh" ]