entrypoint
默认是/opt/bitnami/scripts/etcd/entrypoint.sh
,当第一cmd
参数是/opt/bitnami/scripts/etcd/run.sh
时,会启动setup
流程
#!/bin/bash
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0
# shellcheck disable=SC1091
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace # Uncomment this line for debugging purposes
# Load libraries
. /opt/bitnami/scripts/libbitnami.sh
. /opt/bitnami/scripts/liblog.sh
# Load etcd environment variables
. /opt/bitnami/scripts/etcd-env.sh
print_welcome_page
if [[ "$1" = "/opt/bitnami/scripts/etcd/run.sh" ]]; then
info "** Starting etcd setup **"
/opt/bitnami/scripts/etcd/setup.sh
info "** etcd setup finished! **"
fi
echo ""
exec "$@"
顺序是先setup.sh
(如果指定了的话) ,后run.sh
setup
文件是/opt/bitnami/scripts/etcd/setup.sh
#!/bin/bash
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0
# shellcheck disable=SC1091
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace # Uncomment this line for debugging purposes
# Load libraries
. /opt/bitnami/scripts/libos.sh
. /opt/bitnami/scripts/libetcd.sh
# Load etcd environment settings
. /opt/bitnami/scripts/etcd-env.sh
# Ensure etcd environment settings are valid
etcd_validate
# Ensure etcd is stopped when this script ends.
trap "etcd_stop" EXIT
# Ensure 'daemon' user exists when running as 'root'
am_i_root && ensure_user_exists "$ETCD_DAEMON_USER" --group "$ETCD_DAEMON_GROUP"
# Ensure etcd is initialized
etcd_initialize
这里最关键的地方是etcd_initialize
函数,要确定etcd
已经初始化,这个函数是在/opt/bitnami/scripts/libetcd.sh
中定义的
run
文件是/opt/bitnami/scripts/etcd/run.sh
,最后执行的是etcd
命令(${cmd[@]}
)
#!/bin/bash
# Copyright VMware, Inc.
# SPDX-License-Identifier: APACHE-2.0
# shellcheck disable=SC1090,SC1091
set -o errexit
set -o nounset
set -o pipefail
# set -o xtrace # Uncomment this line for debugging purposes
# Load libraries
. /opt/bitnami/scripts/liblog.sh
. /opt/bitnami/scripts/libos.sh
. /opt/bitnami/scripts/libvalidations.sh
. /opt/bitnami/scripts/libetcd.sh
# Load etcd environment variables
. /opt/bitnami/scripts/etcd-env.sh
is_empty_value "$ETCD_ROOT_PASSWORD" && unset ETCD_ROOT_PASSWORD
if [[ -f "$ETCD_NEW_MEMBERS_ENV_FILE" ]]; then
debug "Loading env vars of existing cluster"
. "$ETCD_NEW_MEMBERS_ENV_FILE"
# We rely on the original value of ETCD_INITIAL_CLUSTER
# when bootstrapping a new cluster since
# we need all initial members to calcualte a same cluster_id
fi
declare -a cmd=("etcd")
# If provided, run using configuration file
# Using a configuration file will cause etcd to ignore other flags and environment variables
[[ -f "$ETCD_CONF_FILE" ]] && cmd+=("--config-file" "$ETCD_CONF_FILE")
cmd+=("$@")
info "** Starting etcd **"
if am_i_root; then
exec_as_user "$ETCD_DAEMON_USER" "${cmd[@]}"
else
exec "${cmd[@]}"
fi
自定义
如果启动过程中需要自定义一些内容,比如:
#!/bin/sh
./etcdctl user add root
./etcdctl --user=root --password="123456" user grant-role root root
./etcdctl --user=root --password="123456" auth enable
./etcdctl --user=root --password="123456" role add client
./etcdctl --user=root --password="123456" role add worker
./etcdctl --user=root --password="123456" user add worker
./etcdctl --user=root --password="123456" user grant-role worker worker
./etcdctl --user=root --password="123456" role grant-permission client read /hotcaffeine --prefix=true
./etcdctl --user=root --password="123456" role grant-permission worker readwrite /hotcaffeine --prefix=true
这些内容单独做个脚本放在entrypoint.sh
的最后面执行是有点难度的,经常会出现:
{"level":"warn","ts":"2023-12-29T06:17:55.512582Z","logger":"etcd-client","caller":"v3@v3.5.11/retry_interceptor.go:62","msg":"retrying of unary invoker failed","target":"etcd-endpoints://0xc0001508c0/127.0.0.1:2379","attempt":0,"error":"rpc error: code = DeadlineExceeded desc = latest balancer error: last connection error: connection error: desc = \"transport: Error while dialing: dial tcp 127.0.0.1:2379: connect: connection refused\""}
因为初始化了之后会终止掉服务再重启。要么在初始化的时候自定义,要么再等服务完成重启完成
所以我目前的做法是直接把/opt/bitnami/scripts/libetcd.sh
文件中的函数etcd_initialize
改掉,然后映射覆盖掉。
覆盖etcd_initialize
把/opt/bitnami/scripts/libetcd.sh
复制出来,然后修改要自定义的地方,像这样:
etcd_configure_rbac() {
! is_etcd_running && etcd_start_bg
read -r -a extra_flags <<<"$(etcdctl_auth_flags)"
is_boolean_yes "$ETCD_ON_K8S" && extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
if retry_while "etcdctl ${extra_flags[*]} member list" >/dev/null 2>&1; then
if retry_while "etcdctl ${extra_flags[*]} auth status" >/dev/null 2>&1; then
if etcdctl "${extra_flags[@]}" auth status | grep -q "Authentication Status: true"; then
info "Authentication already enabled"
else
info "Enabling etcd authentication"
is_boolean_yes "$ETCD_ON_K8S" && extra_flags=("--endpoints=$(etcdctl_get_endpoints)")
etcdctl "${extra_flags[@]}" user add root --interactive=false <<<"$ETCD_ROOT_PASSWORD"
etcdctl "${extra_flags[@]}" user grant-role root root
etcdctl "${extra_flags[@]}" auth enable
# 这里是自定义的内容
etcdctl "${extra_flags[@]}" role add client
etcdctl "${extra_flags[@]}" role add worker
etcdctl "${extra_flags[@]}" user add worker --interactive=false <<<"$ETCD_WORKER_PASSWORD"
etcdctl "${extra_flags[@]}" user grant-role worker worker
etcdctl "${extra_flags[@]}" role grant-permission client read /hotcaffeine --prefix=true
etcdctl "${extra_flags[@]}" role grant-permission worker readwrite /hotcaffeine --prefix=true
fi
fi
fi
etcd_stop
}
然后在volumes
中将原来的文件覆盖掉
使用docker-compose
version: '3'
services:
etcd:
image: bitnami/etcd:latest
restart: always
container_name: etcd
ports:
- 2379:2379
- 2380:2380
volumes:
# 覆盖掉原始的文件
- ./libetcd.sh:/opt/bitnami/scripts/libetcd.sh
environment:
- ETCD_ROOT_PASSWORD=H&O%T=C9AFF]
- ETCD_WORKER_PASSWORD==+WK%&#*