有没有办法使用 Docker 秘密从 /run/secrets/redis-pass 读取并设置 redis --requirepass 标志?
Is there a way to use Docker secrets to read from /run/secrets/redis-pass and set the redis --requirepass flag?
有没有办法使用 Docker 秘密从 /run/secrets/redis-pass 读取并设置 redis --requirepass 标志?
例如:
在 swarm 管理器上设置 redis-pass
,然后使用 docker stack deploy -c docker-compose-prod.yml appname
这是我的 docker-compose.yml 文件中的工作 redis 服务。
redis:
build: ./redis
image: redis:3.2.9
volumes:
- ./redis/db/:/data/
# Without persistance
command: sh -c "redis-server --requirepass XXXXXXXXXX"
# With persistance (saves to /data), ref: https://redis.io/topics/persistence
# command: sh -c "redis-server --requirepass XXXXXXXXXX --appendonly yes"
expose:
- "6379"
这里是建议的 docker-compose.yml 片段,使用 Docker 群堆栈。
version: '3.1'
secrets:
redis-pass:
external: true
redis:
build: ./redis
image: redis:3.2.9
networks:
- frontend
ports:
- "6379"
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
secrets:
- redis-pass
environment:
REDIS_PASS_FILE: /run/secrets/redis-pass
通过遵循 Docker docs 并使用入口点脚本解决了这个问题。
这是一个方法。
为 redis 密码定义 Docker 秘密
在您的本地开发机器上。
创建一个机密文件,确保添加一个 .gitignore 条目以不向您的存储库提交机密。
./secrets/redis-pass.txt
g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9
在你的 swarm leader 节点上。
echo "g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9" | docker secret create redis-pass -
创建一个 redis 配置文件
./redis/redis.conf
定义 requirepass 属性.
requirepass XXXXXXXXXX
更新redis Docker文件
在构建时将配置复制到容器中。
./redis/Dockerfile
FROM alpine:3.6
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN addgroup -S redis && adduser -S -G redis redis
# grab su-exec for easy step-down from root
RUN apk add --no-cache 'su-exec>=0.2'
ENV REDIS_VERSION 3.2.9
ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-3.2.9.tar.gz
ENV REDIS_DOWNLOAD_SHA 6eaacfa983b287e440d0839ead20c2231749d5d6b78bbe0e0ffa3a890c59ff26
# for redis-sentinel see: http://redis.io/topics/sentinel
RUN set -ex; \
\
apk add --no-cache --virtual .build-deps \
coreutils \
gcc \
linux-headers \
make \
musl-dev \
; \
\
wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; \
echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; \
mkdir -p /usr/src/redis; \
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; \
rm redis.tar.gz; \
\
# Disable Redis protected mode [1] as it is unnecessary in context
# of Docker. Ports are not automatically exposed when running inside
# Docker, but rather explicitely by specifying -p / -P.
# [1] https://github.com/antirez/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da
grep -q '^#define CONFIG_DEFAULT_PROTECTED_MODE 1$' /usr/src/redis/src/server.h; \
sed -ri 's!^(#define CONFIG_DEFAULT_PROTECTED_MODE) 1$! 0!' /usr/src/redis/src/server.h; \
grep -q '^#define CONFIG_DEFAULT_PROTECTED_MODE 0$' /usr/src/redis/src/server.h; \
# for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
# see also https://github.com/docker-library/redis/issues/4#issuecomment-50780840
# (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
\
make -C /usr/src/redis -j "$(nproc)"; \
make -C /usr/src/redis install; \
\
rm -r /usr/src/redis; \
\
apk del .build-deps
RUN mkdir /data && chown redis:redis /data
VOLUME /data
WORKDIR /data
COPY redis.conf /home/redis/
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
# EXPOSE 6379
# CMD ["redis-server"]
使用 sed 命令更新 docker-entrypoint.sh。
./redis/docker-entrypoint.sh
sed 命令将用来自 /[=92= 的 redis-pass 密码的密码替换 redis.conf 文件中 requirepass 属性 的值]/secrets/redis-pass.
#!/bin/sh
set -e
# Updated password using sed
sed -i "s/requirepass XXXXXXXXXX/requirepass `cat /run/secrets/redis_password`/" /home/redis/redis.conf
# first arg is `-f` or `--some-option`
# or first arg is `something.conf`
if [ "${1#-}" != "" ] || [ "${1%.conf}" != "" ]; then
set -- redis-server "$@"
fi
# allow the container to be started with `--user`
if [ "" = 'redis-server' -a "$(id -u)" = '0' ]; then
chown -R redis .
exec su-exec redis "[=11=]" "$@"
fi
exec "$@"
更新您的 docker-compose.yml 文件
./docker-compose.yml
定义3.1的compose版本
version: "3.1"
定义机密
secrets:
redis-pass:
# local dev machine
#file: ./secrets/redis-pass.txt
# production environment
external: true
定义redis服务。
redis:
build: ./redis
image: redis:3.2.9
command: sh -c 'redis-server /home/redis/redis.conf'
expose:
- "6379"
# networks:
# - frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
secrets:
- redis-pass
tty: true
验证 requirepass 已更新
➜ blah git:(master) ✗ docker-compose exec redis sh
/data # ps -ef
PID USER TIME COMMAND
1 root 0:00 sh -c redis-server /home/redis/redis.conf
10 root 0:03 redis-server /home/redis/redis.conf
28 root 0:00 sh
34 root 0:00 ps -ef
/data # cat /home/redis/redis.conf
requirepass g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9
/data #
尽情享受吧!
你可以这样做
services: redis:
image: redis
secrets:
- redis_pass
environment:
REDIS_PASS_FILE: /run/secrets/redis_pass
command: [
"bash", "-c",
'
docker-entrypoint.sh
--requirepass "$$(cat $$REDIS_PASS_FILE)"
'
]
喜欢这里的建议:
有没有办法使用 Docker 秘密从 /run/secrets/redis-pass 读取并设置 redis --requirepass 标志?
例如:
在 swarm 管理器上设置 redis-pass
,然后使用 docker stack deploy -c docker-compose-prod.yml appname
这是我的 docker-compose.yml 文件中的工作 redis 服务。
redis:
build: ./redis
image: redis:3.2.9
volumes:
- ./redis/db/:/data/
# Without persistance
command: sh -c "redis-server --requirepass XXXXXXXXXX"
# With persistance (saves to /data), ref: https://redis.io/topics/persistence
# command: sh -c "redis-server --requirepass XXXXXXXXXX --appendonly yes"
expose:
- "6379"
这里是建议的 docker-compose.yml 片段,使用 Docker 群堆栈。
version: '3.1'
secrets:
redis-pass:
external: true
redis:
build: ./redis
image: redis:3.2.9
networks:
- frontend
ports:
- "6379"
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
secrets:
- redis-pass
environment:
REDIS_PASS_FILE: /run/secrets/redis-pass
通过遵循 Docker docs 并使用入口点脚本解决了这个问题。
这是一个方法。
为 redis 密码定义 Docker 秘密
在您的本地开发机器上。
创建一个机密文件,确保添加一个 .gitignore 条目以不向您的存储库提交机密。
./secrets/redis-pass.txt
g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9
在你的 swarm leader 节点上。
echo "g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9" | docker secret create redis-pass -
创建一个 redis 配置文件
./redis/redis.conf
定义 requirepass 属性.
requirepass XXXXXXXXXX
更新redis Docker文件
在构建时将配置复制到容器中。
./redis/Dockerfile
FROM alpine:3.6
# add our user and group first to make sure their IDs get assigned consistently, regardless of whatever dependencies get added
RUN addgroup -S redis && adduser -S -G redis redis
# grab su-exec for easy step-down from root
RUN apk add --no-cache 'su-exec>=0.2'
ENV REDIS_VERSION 3.2.9
ENV REDIS_DOWNLOAD_URL http://download.redis.io/releases/redis-3.2.9.tar.gz
ENV REDIS_DOWNLOAD_SHA 6eaacfa983b287e440d0839ead20c2231749d5d6b78bbe0e0ffa3a890c59ff26
# for redis-sentinel see: http://redis.io/topics/sentinel
RUN set -ex; \
\
apk add --no-cache --virtual .build-deps \
coreutils \
gcc \
linux-headers \
make \
musl-dev \
; \
\
wget -O redis.tar.gz "$REDIS_DOWNLOAD_URL"; \
echo "$REDIS_DOWNLOAD_SHA *redis.tar.gz" | sha256sum -c -; \
mkdir -p /usr/src/redis; \
tar -xzf redis.tar.gz -C /usr/src/redis --strip-components=1; \
rm redis.tar.gz; \
\
# Disable Redis protected mode [1] as it is unnecessary in context
# of Docker. Ports are not automatically exposed when running inside
# Docker, but rather explicitely by specifying -p / -P.
# [1] https://github.com/antirez/redis/commit/edd4d555df57dc84265fdfb4ef59a4678832f6da
grep -q '^#define CONFIG_DEFAULT_PROTECTED_MODE 1$' /usr/src/redis/src/server.h; \
sed -ri 's!^(#define CONFIG_DEFAULT_PROTECTED_MODE) 1$! 0!' /usr/src/redis/src/server.h; \
grep -q '^#define CONFIG_DEFAULT_PROTECTED_MODE 0$' /usr/src/redis/src/server.h; \
# for future reference, we modify this directly in the source instead of just supplying a default configuration flag because apparently "if you specify any argument to redis-server, [it assumes] you are going to specify everything"
# see also https://github.com/docker-library/redis/issues/4#issuecomment-50780840
# (more exactly, this makes sure the default behavior of "save on SIGTERM" stays functional by default)
\
make -C /usr/src/redis -j "$(nproc)"; \
make -C /usr/src/redis install; \
\
rm -r /usr/src/redis; \
\
apk del .build-deps
RUN mkdir /data && chown redis:redis /data
VOLUME /data
WORKDIR /data
COPY redis.conf /home/redis/
COPY docker-entrypoint.sh /usr/local/bin/
ENTRYPOINT ["docker-entrypoint.sh"]
# EXPOSE 6379
# CMD ["redis-server"]
使用 sed 命令更新 docker-entrypoint.sh。
./redis/docker-entrypoint.sh
sed 命令将用来自 /[=92= 的 redis-pass 密码的密码替换 redis.conf 文件中 requirepass 属性 的值]/secrets/redis-pass.
#!/bin/sh
set -e
# Updated password using sed
sed -i "s/requirepass XXXXXXXXXX/requirepass `cat /run/secrets/redis_password`/" /home/redis/redis.conf
# first arg is `-f` or `--some-option`
# or first arg is `something.conf`
if [ "${1#-}" != "" ] || [ "${1%.conf}" != "" ]; then
set -- redis-server "$@"
fi
# allow the container to be started with `--user`
if [ "" = 'redis-server' -a "$(id -u)" = '0' ]; then
chown -R redis .
exec su-exec redis "[=11=]" "$@"
fi
exec "$@"
更新您的 docker-compose.yml 文件
./docker-compose.yml
定义3.1的compose版本
version: "3.1"
定义机密
secrets:
redis-pass:
# local dev machine
#file: ./secrets/redis-pass.txt
# production environment
external: true
定义redis服务。
redis:
build: ./redis
image: redis:3.2.9
command: sh -c 'redis-server /home/redis/redis.conf'
expose:
- "6379"
# networks:
# - frontend
deploy:
replicas: 2
update_config:
parallelism: 2
delay: 10s
restart_policy:
condition: on-failure
secrets:
- redis-pass
tty: true
验证 requirepass 已更新
➜ blah git:(master) ✗ docker-compose exec redis sh
/data # ps -ef
PID USER TIME COMMAND
1 root 0:00 sh -c redis-server /home/redis/redis.conf
10 root 0:03 redis-server /home/redis/redis.conf
28 root 0:00 sh
34 root 0:00 ps -ef
/data # cat /home/redis/redis.conf
requirepass g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9
/data #
尽情享受吧!
你可以这样做
services: redis:
image: redis
secrets:
- redis_pass
environment:
REDIS_PASS_FILE: /run/secrets/redis_pass
command: [
"bash", "-c",
'
docker-entrypoint.sh
--requirepass "$$(cat $$REDIS_PASS_FILE)"
'
]
喜欢这里的建议: