运行 非 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
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
中完全不同,所以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" ]
我正在构建 run.sh
应该 运行 作为非 root 用户
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
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
中完全不同,所以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" ]