代码之家  ›  专栏  ›  技术社区  ›  Veerendra K

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

  •  0
  • Veerendra K  · 技术社区  · 8 年前

    我正在构建redis sentinal图像 run.sh 应以非root用户身份运行

    跑上海

      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(默认)时,即没有提到任何 adduser 在里面 Dockerfile文件 。

    1 回复  |  直到 8 年前
        1
  •  2
  •   nickgryg    8 年前

    根据 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.
    

    CMD 和 ENTRYPOINT 以上各层完全不同 Dockerfile 所以 入口点 覆盖 CMD命令 这就是为什么 CMD命令 永远不会执行层。

    只需删除 入口点 来自的图层 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" ]
    

    更新时间:

    我看到了 [[ ]] 用于 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" ]