溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

關(guān)于redis在docker-compose中免密配置的討論

發(fā)布時(shí)間:2020-06-04 14:22:56 來(lái)源:網(wǎng)絡(luò) 閱讀:10177 作者:yerikyu 欄目:系統(tǒng)運(yùn)維

遇到個(gè)很有趣的討論,先看一下這個(gè)docker-compose配置腳本:

version: '2'

services:
  redis:
    image: 'redis:5.0.3-stretch'
    restart: always
    command: redis-server --requirepass redis
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
    ports:
      - '6379:6379'
    volumes:
      - 'redis_data:/bitnami/redis/data'

volumes:
  redis_data:
    driver: local

這里先交代一下出現(xiàn)這樣腳本的背景,因?yàn)橐恢遍_(kāi)始的時(shí)候使用的是bitnami版本,因?yàn)槠渲С置饷芘渲茫谂渲瞄_(kāi)發(fā)環(huán)境具有很棒的優(yōu)勢(shì),后來(lái)為了安全起見(jiàn),使用了官方提供的鏡像文件redis:5.0.3-stretch,之后就有了這么奇怪的配置腳本,既有requirepass,也寫(xiě)了ALLOW_EMPTY_PASSWORD=yes

在這個(gè)配置中,在commend中配置passwd:redis,然而又在enviroment中配置了allow_empty_password=yes,那么這樣的配置,到底是需要密碼還是不需要呢?理由又是怎樣呢?

關(guān)于redis在docker-compose中免密配置的討論

解決這個(gè)問(wèn)題,先知道,問(wèn)題肯定不是在docker-compose上,這玩意充其量就是個(gè)腳本解析器,通常情況下,運(yùn)行指定的參數(shù)優(yōu)先級(jí)大于環(huán)境變量,環(huán)境變量大于配置文件,可事實(shí)上真的是這樣嗎?那么我們就需要去閱讀redis源碼了。有興趣的可以自己讀讀看redis源碼

src/config.c中寫(xiě)到,如果是用了requirepass這個(gè)命令,則會(huì)把password的內(nèi)容寫(xiě)進(jìn)sds中,不過(guò)好像還是沒(méi)有說(shuō)明到environment對(duì)于redis配置文件的影響,甚至是說(shuō)在整份config文件中沒(méi)有介紹到對(duì)于environment這個(gè)變量的調(diào)用,因此可以推斷到開(kāi)發(fā)者應(yīng)該是沒(méi)有考慮使用environment

關(guān)于redis在docker-compose中免密配置的討論

為了求證這個(gè)猜測(cè),因?yàn)椴⒉幌氪蠛漆樔グl(fā)掘源碼,所以去看下官方對(duì)于config的介紹

Passing arguments via the command line
Since Redis 2.6 it is possible to also pass Redis configuration parameters using the command line directly. This is very useful for testing purposes. The following is an example that starts a new Redis instance using port 6380 as a slave of the instance running at 127.0.0.1 port 6379.

./redis-server --port 6380 --slaveof 127.0.0.1 6379

The format of the arguments passed via the command line is exactly the same as the one used in the redis.conf file, with the exception that the keyword is prefixed with --.

Note that internally this generates an in-memory temporary config file (possibly concatenating the config file passed by the user if any) where arguments are translated into the format of redis.conf.

Changing Redis configuration while the server is running
It is possible to reconfigure Redis on the fly without stopping and restarting the service, or querying the current configuration programmatically using the special commands CONFIG SET and CONFIG GET

Not all the configuration directives are supported in this way, but most are supported as expected. Please refer to the CONFIG SET and CONFIG GET pages for more information.

Note that modifying the configuration on the fly has no effects on the redis.conf file so at the next restart of Redis the old configuration will be used instead.

Make sure to also modify the redis.conf file accordingly to the configuration you set using CONFIG SET. You can do it manually, or starting with Redis 2.8, you can just use CONFIG REWRITE, which will automatically scan your redis.conf file and update the fields which don't match the current configuration value. Fields non existing but set to the default value are not added. Comments inside your configuration file are retained.

通過(guò)介紹,我們中可以,知道對(duì)于redis的配置有兩種方式:

  • 通過(guò)命令行,這個(gè)方式就是在通過(guò)commend指令進(jìn)行配置的,屬于初始化配置,會(huì)被寫(xiě)入到redis.conf文件中
  • 在運(yùn)行過(guò)程中,這個(gè)方式是在redis運(yùn)行的過(guò)程中進(jìn)行配置的,屬于暫時(shí)配置,也不會(huì)寫(xiě)入到redis.conf,當(dāng)服務(wù)重啟的時(shí)候,原來(lái)的配置就失效,需要重新輸入指令config set xxx

至此,我們知道environment對(duì)于正版redis是無(wú)效的,那么為什么bitnami版本有這個(gè)效果呢?這個(gè)時(shí)候我們就需要看下這哥們是怎么設(shè)計(jì)的了。
先看下人家的docker-compose.yml,確實(shí)是允許免密進(jìn)入,這個(gè)好是好,自己一個(gè)人小打小鬧可還行,遇到團(tuán)隊(duì)協(xié)助或者在生產(chǎn)環(huán)境中分分鐘被噴

version: '2'

services:
  redis:
    image: 'bitnami/redis:5.0-centos-7'
    environment:
      # ALLOW_EMPTY_PASSWORD is recommended only for development.
      - ALLOW_EMPTY_PASSWORD=yes
      - REDIS_DISABLE_COMMANDS=FLUSHDB,FLUSHALL
    ports:
      - '6379:6379'
    volumes:
      - 'redis_data:/bitnami/redis/data'

volumes:
  redis_data:
    driver: local

之后是分析他的dockerfile,前面的打包內(nèi)容確實(shí)沒(méi)啥好看的,主要是看最后兩步ENTRYPOINT [ "/entrypoint.sh" ] && CMD [ "/run.sh" ],這個(gè)是其允許免密配置的關(guān)鍵,我們繼續(xù)探究源碼

FROM bitnami/centos-extras-base:7-r269
LABEL maintainer "Bitnami <containers@bitnami.com>"

ENV BITNAMI_PKG_CHMOD="-R g+rwX" \
    HOME="/" \
    OS_ARCH="x86_64" \
    OS_FLAVOUR="centos-7" \
    OS_NAME="linux"

# Install required system packages and dependencies
RUN install_packages glibc
RUN . ./libcomponent.sh && component_unpack "redis" "5.0.7-0" --checksum 0046ebee1870e41fe422f646d504a8ec84efb85152189ee434d8f4c9ad2917c7

COPY rootfs /
RUN /postunpack.sh
ENV BITNAMI_APP_NAME="redis" \
    BITNAMI_IMAGE_VERSION="5.0.7-centos-7-r59" \
    NAMI_PREFIX="/.nami" \
    PATH="/opt/bitnami/redis/bin:$PATH"

EXPOSE 6379

USER 1001
ENTRYPOINT [ "/entrypoint.sh" ]
CMD [ "/run.sh" ]

事實(shí)上,比較重要的就是entrypoint.sh這個(gè)文件,因?yàn)?code>run.sh其實(shí)是用來(lái)進(jìn)行啟動(dòng)初始化用的,有興趣的讀者可以進(jìn)去讀一下源碼,這里就不再贅述,我們不妨看下entrypoint.sh的源碼

#!/bin/bash

set -o errexit
set -o nounset
set -o pipefail
#set -o xtrace
# shellcheck disable=SC1091

# Load libraries
. /libbitnami.sh
. /libredis.sh

# Load Redis environment variables
eval "$(redis_env)"

print_welcome_page

if [[ "$*" = *"/run.sh"* ]]; then
    info "** Starting Redis setup **"
    /setup.sh
    info "** Redis setup finished! **"
fi

echo ""
exec "$@"

從代碼中知道,程序會(huì)先執(zhí)行libbitnami.sh,libredis.sh完成配置依賴庫(kù)的工作,然后使用eval函數(shù)將數(shù)據(jù)進(jìn)行提取,之后通過(guò)run.sh這個(gè)腳本啟動(dòng)redis,那問(wèn)題的答案越來(lái)越近了:),先發(fā)現(xiàn)libredis.sh就先讀這份代碼

關(guān)于redis在docker-compose中免密配置的討論

在這份代碼中,可以通過(guò)搜索關(guān)鍵字ALLOW_EMPTY_PASSWORD確定是不是有,我們要配置腳本,事實(shí)上也被我們找到了

關(guān)于redis在docker-compose中免密配置的討論

就是這個(gè)函數(shù)實(shí)現(xiàn)了免密注冊(cè)redis的效果

redis_validate() {
    debug "Validating settings in REDIS_* env vars.."
    local error_code=0

    # Auxiliary functions
    print_validation_error() {
        error "$1"
        error_code=1
    }

    empty_password_enabled_warn() {
        warn "You set the environment variable ALLOW_EMPTY_PASSWORD=${ALLOW_EMPTY_PASSWORD}. For safety reasons, do not use this flag in a production environment."
    }
    empty_password_error() {
        print_validation_error "The $1 environment variable is empty or not set. Set the environment variable ALLOW_EMPTY_PASSWORD=yes to allow the container to be started with blank passwords. This is recommended only for development."
    }

    if is_boolean_yes "$ALLOW_EMPTY_PASSWORD"; then
        empty_password_enabled_warn
    else
        [[ -z "$REDIS_PASSWORD" ]] && empty_password_error REDIS_PASSWORD
    fi
    if [[ -n "$REDIS_REPLICATION_MODE" ]]; then
        if [[ "$REDIS_REPLICATION_MODE" =~ ^(slave|replica)$ ]]; then
            if [[ -n "$REDIS_MASTER_PORT_NUMBER" ]]; then
                if ! err=$(validate_port "$REDIS_MASTER_PORT_NUMBER"); then
                    print_validation_error "An invalid port was specified in the environment variable REDIS_MASTER_PORT_NUMBER: $err"
                fi
            fi
            if ! is_boolean_yes "$ALLOW_EMPTY_PASSWORD" && [[ -z "$REDIS_MASTER_PASSWORD" ]]; then
                empty_password_error REDIS_MASTER_PASSWORD
            fi
        elif [[ "$REDIS_REPLICATION_MODE" != "master" ]]; then
            print_validation_error "Invalid replication mode. Available options are 'master/replica'"
        fi
    fi

    [[ "$error_code" -eq 0 ]] || exit "$error_code"
}

探究源碼真的挺有趣的,讓我們剖根究底,直面本源,知道之前拿來(lái)主義時(shí)沒(méi)有經(jīng)過(guò)思考就隨便抄的不良后果,原來(lái)的docker-compose配置中,用了5.0.3-stretch這個(gè)版本之后,environment這段文字實(shí)際上就是無(wú)效的。至此擱筆,問(wèn)題解決

參考資料:

  1. redis官方對(duì)于config的介紹,https://redis.io/topics/config
  2. redis源碼,https://github.com/antirez/redis/
  3. docker-compose redis:bitnami,https://github.com/bitnami/bitnami-docker-redis
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI