有没有办法使用Docker机密来读取/ run / secrets / redis-pass并设置redis --requirepass标志?

时间:2017-06-20 00:48:53

标签: redis docker-compose docker-swarm

有没有办法使用Docker机密来读取/ run / secrets / redis-pass并设置redis --requirepass标志?

例如:

在群体管理器上设置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 swarm堆栈的建议的docker-compose.yml片段。

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

2 个答案:

答案 0 :(得分:1)

通过遵循Docker docs并使用入口点脚本解决了这个问题。

这是一种方法。

为redis密码

定义Docker机密

在您当地的开发机器上。

创建一个秘密文件,确保添加一个.gitignore条目,以便不向您的回购提交秘密。

./秘密/ redis的-pass.txt

g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9

在您的群组领导节点上。

echo "g7VacrULudmwcLnxy23JWyUNZRit7cazG2JekTCc6vccxX2LxLWoHFP8XYLbD4U9" | docker secret create redis-pass -

创建redis配置文件

./ redis的/ redis.conf

定义requirepass属性。

requirepass XXXXXXXXXX

更新redis Dockerfile

在构建时将配置复制到容器中。

./ 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$!\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命令将使用来自/ run / secrets / redis-pass的redis-pass secret中的密码替换redis.conf文件中的requirepass属性值。

#!/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" ] || [ "${1%.conf}" != "$1" ]; then
    set -- redis-server "$@"
fi

# allow the container to be started with `--user`
if [ "$1" = 'redis-server' -a "$(id -u)" = '0' ]; then
    chown -R redis .
    exec su-exec redis "$0" "$@"
fi

exec "$@"

更新docker-compose.yml文件

./搬运工-compose.yml

定义3.1的撰写版本

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 #

享受!

答案 1 :(得分:1)

您可以这样做

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)"
      '
    ]

像这里建议的那样:

相关问题