3.5.1-debian-10-r56 release

This commit is contained in:
Bitnami Bot
2021-12-16 14:00:51 +00:00
parent 9537d1a691
commit 7c04f0ffd8
6 changed files with 225 additions and 55 deletions

View File

@@ -4,21 +4,22 @@ LABEL maintainer "Bitnami <containers@bitnami.com>"
ENV HOME="/" \
OS_ARCH="amd64" \
OS_FLAVOUR="debian-10" \
OS_NAME="linux" \
PATH="/opt/bitnami/common/bin:/opt/bitnami/etcd/bin:$PATH"
OS_NAME="linux"
COPY prebuildfs /
# Install required system packages and dependencies
RUN install_packages acl ca-certificates curl gzip jq procps tar
RUN install_packages acl ca-certificates curl gzip procps tar
RUN . /opt/bitnami/scripts/libcomponent.sh && component_unpack "yq" "4.16.1-0" --checksum e7a14c06b08e5a773ac5e640a58adce2c0196b5e82e331df19f11861bceb2c9d
RUN . /opt/bitnami/scripts/libcomponent.sh && component_unpack "gosu" "1.14.0-0" --checksum 3e6fc37ca073b10a73a804d39c2f0c028947a1a596382a4f8ebe43dfbaa3a25e
RUN . /opt/bitnami/scripts/libcomponent.sh && component_unpack "etcd" "3.5.1-0" --checksum 912653e5c0879fd27c8bb0327bea171d7ae504611ec0a9c8fcc2ec6184766a63
RUN . /opt/bitnami/scripts/libcomponent.sh && component_unpack "etcd" "3.5.1-1" --checksum 424ad409fddf0b8bbb44fae42c1696bfe85ae147acbbbd0489fc75367feaf309
RUN chmod g+rwX /opt/bitnami
COPY rootfs /
RUN /opt/bitnami/scripts/etcd/postunpack.sh
ENV BITNAMI_APP_NAME="etcd" \
BITNAMI_IMAGE_VERSION="3.5.1-debian-10-r54" \
ETCDCTL_API="3"
BITNAMI_IMAGE_VERSION="3.5.1-debian-10-r56" \
ETCDCTL_API="3" \
PATH="/opt/bitnami/common/bin:/opt/bitnami/etcd/bin:$PATH"
EXPOSE 2379 2380

View File

@@ -1,10 +1,10 @@
{
"etcd": {
"arch": "amd64",
"digest": "912653e5c0879fd27c8bb0327bea171d7ae504611ec0a9c8fcc2ec6184766a63",
"digest": "424ad409fddf0b8bbb44fae42c1696bfe85ae147acbbbd0489fc75367feaf309",
"distro": "debian-10",
"type": "NAMI",
"version": "3.5.1-0"
"version": "3.5.1-1"
},
"gosu": {
"arch": "amd64",
@@ -12,5 +12,12 @@
"distro": "debian-10",
"type": "NAMI",
"version": "1.14.0-0"
},
"yq": {
"arch": "amd64",
"digest": "e7a14c06b08e5a773ac5e640a58adce2c0196b5e82e331df19f11861bceb2c9d",
"distro": "debian-10",
"type": "NAMI",
"version": "4.16.1-0"
}
}

View File

@@ -62,8 +62,11 @@ unset etcd_env_vars
# Paths
export ETCD_BASE_DIR="/opt/bitnami/etcd"
export ETCD_VOLUME_DIR="/bitnami/etcd"
export ETCD_BIN_DIR="${ETCD_BASE_DIR}/sbin"
export ETCD_BIN_DIR="${ETCD_BASE_DIR}/bin"
export ETCD_DATA_DIR="${ETCD_VOLUME_DIR}/data"
export ETCD_CONF_DIR="${ETCD_BASE_DIR}/conf"
export ETCD_TMP_DIR="${ETCD_BASE_DIR}/tmp"
export ETCD_CONF_FILE="${ETCD_CONF_DIR}/etcd.yaml"
export ETCD_SNAPSHOTS_DIR="/snapshots"
export ETCD_INIT_SNAPSHOTS_DIR="${ETCD_INIT_SNAPSHOTS_DIR:-/init-snapshot}"
export ETCD_NEW_MEMBERS_ENV_FILE="${ETCD_DATA_DIR}/new_member_envs"
@@ -81,9 +84,9 @@ export ETCD_START_FROM_SNAPSHOT="${ETCD_START_FROM_SNAPSHOT:-no}"
export ETCD_DISASTER_RECOVERY="${ETCD_DISASTER_RECOVERY:-no}"
export ETCD_ON_K8S="${ETCD_ON_K8S:-no}"
export ETCD_INIT_SNAPSHOT_FILENAME="${ETCD_INIT_SNAPSHOT_FILENAME:-}"
export ETCDCTL_API="${ETCDCTL_API:-3}"
# etcd native environment variables (see https://etcd.io/docs/current/op-guide/configuration)
export ETCDCTL_API="${ETCDCTL_API:-3}"
export ETCD_NAME="${ETCD_NAME:-}"
export ETCD_LOG_LEVEL="${ETCD_LOG_LEVEL:-info}"
export ETCD_LISTEN_CLIENT_URLS="${ETCD_LISTEN_CLIENT_URLS:-http://0.0.0.0:2379}"

View File

@@ -16,9 +16,6 @@ set -o pipefail
# Load etcd environment variables
. /opt/bitnami/scripts/etcd-env.sh
# Constants
EXEC="$(command -v etcd)"
! 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"
@@ -31,9 +28,15 @@ else
export ETCD_INITIAL_CLUSTER
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 gosu "$ETCD_DAEMON_USER" "${EXEC}" "$@"
exec gosu "$ETCD_DAEMON_USER" "${cmd[@]}"
else
exec "${EXEC}" "$@"
exec "${cmd[@]}"
fi

View File

@@ -2,7 +2,7 @@
#
# Bitnami etcd library
# shellcheck disable=SC1090,SC1091
# shellcheck disable=SC1090,SC1091,SC2119
# Load Generic Libraries
. /opt/bitnami/scripts/libfile.sh
@@ -14,6 +14,95 @@
# Functions
########################
# Write a configuration setting value
# Globals:
# ETCD_CONF_FILE
# Arguments:
# $1 - key
# $2 - value
# $3 - YAML type (string, int or bool)
# Returns:
# None
#########################
etcd_conf_write() {
local -r key="${1:?Missing key}"
local -r value="${2:-}"
local -r type="${3:-string}"
local -r tempfile=$(mktemp)
[[ -z "$value" ]] && return
[[ ! -f "$ETCD_CONF_FILE" ]] && touch "$ETCD_CONF_FILE"
case "$type" in
string)
yq eval "(.${key}) |= \"${value}\"" "$ETCD_CONF_FILE" > "$tempfile"
;;
bool)
yq eval "(.${key}) |= (\"${value}\" | test(\"true\"))" "$ETCD_CONF_FILE" > "$tempfile"
;;
raw)
yq eval "(.${key}) |= ${value}" "$ETCD_CONF_FILE" > "$tempfile"
;;
*)
error "Type unknown: ${type}"
return 1
;;
esac
cp "$tempfile" "$ETCD_CONF_FILE"
}
########################
# Creates etcd configuration file from environment variables
# Globals:
# ETCD_CFG_*
# Arguments:
# None
# Returns:
# None
#########################
etcd_setup_from_environment_variables() {
## Except for Client and Peer TLS configuration,
## all etcd settings consists of ETCD_FLAG_NAME
## transformed into flag-name and configured under the yaml config root.
local -a client_tls_values=(
"ETCD_CFG_CERT_FILE"
"ETCD_CFG_KEY_FILE"
"ETCD_CFG_CLIENT_CERT_AUTH"
"ETCD_CFG_TRUSTED_CA_FILE"
"ETCD_CFG_AUTO_TLS"
"ETCD_CFG_CA_FILE"
)
info "Generating etcd config file using env variables"
# Map environment variables to config properties for cassandra-env.sh
for var in "${!ETCD_CFG_@}"; do
value="${!var:-}"
if [[ -n "$value" ]]; then
type="string"
# Detect if value is digit or bool
if [[ "$value" =~ ^[+-]?[0-9]+([.][0-9]+)?$ || "$value" =~ ^(true|false)$ ]]; then
type="raw"
fi
if [[ ${client_tls_values[*]} =~ ${var} ]]; then
key="$(echo "$var" | sed -e 's/^ETCD_CFG_//g' -e 's/_/-/g' | tr '[:upper:]' '[:lower:]')"
etcd_conf_write "client-transport-security.${key}" "$value" "$type"
elif [[ "$var" =~ "ETCD_CFG_CLIENT_" ]]; then
key="$(echo "$var" | sed -e 's/^ETCD_CFG_CLIENT_//g' -e 's/_/-/g' | tr '[:upper:]' '[:lower:]')"
etcd_conf_write "client-transport-security.${key}" "$value" "$type"
elif [[ "$var" =~ "ETCD_CFG_PEER_" ]]; then
key="$(echo "$var" | sed -e 's/^ETCD_CFG_PEER_//g' -e 's/_/-/g' | tr '[:upper:]' '[:lower:]')"
etcd_conf_write "peer-transport-security.${key}" "$value" "$type"
else
# shellcheck disable=SC2001
key="$(echo "$var" | sed -e 's/^ETCD_CFG_//g' -e 's/_/-/g' | tr '[:upper:]' '[:lower:]')"
etcd_conf_write "$key" "$value" "$type"
fi
fi
done
if am_i_root; then
chown "$ETCD_DAEMON_USER" "$ETCD_CONF_FILE"
fi
}
########################
# Validate settings in ETCD_* environment variables
# Globals:
@@ -53,7 +142,14 @@ etcd_validate() {
# Boolean
#########################
is_etcd_running() {
local -r pid="$(pgrep -f "^etcd")"
local pid
pid="$(pgrep -f "^etcd" || true)"
# etcd does not create any PID file
# We regenerate the PID file for each time we query it to avoid getting outdated
if [[ -n "${ETCD_PID_FILE:-}" ]]; then
echo "$pid" > "$ETCD_PID_FILE"
fi
if [[ -n "$pid" ]]; then
is_service_running "$pid"
@@ -62,6 +158,19 @@ is_etcd_running() {
fi
}
########################
# Check if etcd is running
# Globals:
# ETCD_PID_FILE
# Arguments:
# None
# Returns:
# Whether etcd is not running
########################
is_etcd_not_running() {
! is_etcd_running
}
########################
# Stop etcd
# Arguments:
@@ -74,6 +183,7 @@ etcd_stop() {
! is_etcd_running && return
info "Stopping etcd"
# Ensure process matches etcd binary with or without options
pid="$(pgrep -f "^etcd")"
local counter=10
kill "$pid"
@@ -94,7 +204,10 @@ etcd_start_bg() {
is_etcd_running && return
info "Starting etcd in background"
debug_execute "etcd" &
local start_command=("etcd")
am_i_root && start_command=("gosu" "$ETCD_DAEMON_USER" "${start_command[@]}")
[[ -f "$ETCD_CONF_FILE" ]] && start_command+=("--config-file" "$ETCD_CONF_FILE")
debug_execute "${start_command[@]}" &
sleep 3
}
@@ -130,38 +243,34 @@ etcdctl_get_endpoints() {
return 1
}
if is_boolean_yes "$ETCD_ON_K8S"; then
# This piece of code assumes this container is used on a K8s environment
# where etcd members are part of a statefulset that uses a headless service
# to create a unique FQDN per member. Under these circumstances, the
# ETCD_ADVERTISE_CLIENT_URLS env. variable is created as follows:
# SCHEME://POD_NAME.HEADLESS_SVC_DOMAIN:CLIENT_PORT,SCHEME://SVC_DOMAIN:SVC_CLIENT_PORT
#
# Assuming this, we can extract the HEADLESS_SVC_DOMAIN and obtain
# every available endpoint
read -r -a advertised_array <<< "$(tr ',;' ' ' <<< "$ETCD_ADVERTISE_CLIENT_URLS")"
host="$(parse_uri "${advertised_array[0]}" "host")"
port="$(parse_uri "${advertised_array[0]}" "port")"
domain="${host#"${ETCD_NAME}."}"
# When ETCD_CLUSTER_DOMAIN is set, we use that value instead of extracting
# it from ETCD_ADVERTISE_CLIENT_URLS
! is_empty_value "$ETCD_CLUSTER_DOMAIN" && domain="$ETCD_CLUSTER_DOMAIN"
# Depending on the K8s distro & the DNS plugin, it might need
# a few seconds to associate the POD(s) IP(s) to the headless svc domain
if retry_while "hostname_has_ips $domain"; then
for ip in $(getent ahosts "$domain" | awk '{print $1}' | uniq); do
if retry_while "ip_has_valid_hostname $ip $domain"; then
h="$(getent hosts "$ip" | awk '{print $2}')"
if ! { [[ $only_others = true ]] && [[ "$h" = "$host" ]]; }; then
endpoints+=("${h}:${port}")
fi
# This piece of code assumes this code is executed on a K8s environment
# where etcd members are part of a statefulset that uses a headless service
# to create a unique FQDN per member. Under these circumstances, the
# ETCD_ADVERTISE_CLIENT_URLS env. variable is created as follows:
# SCHEME://POD_NAME.HEADLESS_SVC_DOMAIN:CLIENT_PORT,SCHEME://SVC_DOMAIN:SVC_CLIENT_PORT
#
# Assuming this, we can extract the HEADLESS_SVC_DOMAIN and obtain
# every available endpoint
read -r -a advertised_array <<< "$(tr ',;' ' ' <<< "$ETCD_ADVERTISE_CLIENT_URLS")"
host="$(parse_uri "${advertised_array[0]}" "host")"
port="$(parse_uri "${advertised_array[0]}" "port")"
domain="${host#"${ETCD_NAME}."}"
# When ETCD_CLUSTER_DOMAIN is set, we use that value instead of extracting
# it from ETCD_ADVERTISE_CLIENT_URLS
! is_empty_value "$ETCD_CLUSTER_DOMAIN" && domain="$ETCD_CLUSTER_DOMAIN"
# Depending on the K8s distro & the DNS plugin, it might need
# a few seconds to associate the POD(s) IP(s) to the headless svc domain
if retry_while "hostname_has_ips $domain"; then
for ip in $(getent ahosts "$domain" | awk '{print $1}' | uniq); do
if retry_while "ip_has_valid_hostname $ip $domain"; then
h="$(getent hosts "$ip" | awk '{print $2}')"
if ! { [[ $only_others = true ]] && [[ "$h" = "$host" ]]; }; then
endpoints+=("${h}:${port}")
fi
done
fi
echo "${endpoints[*]}" | tr ' ' ','
else
echo ""
fi
done
fi
echo "${endpoints[*]}" | tr ' ' ','
}
########################
@@ -199,7 +308,7 @@ etcd_store_member_id() {
local -a extra_flags
read -r -a extra_flags <<< "$(etcdctl_auth_flags)"
extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
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
while [[ ! -s "${ETCD_DATA_DIR}/member_id" ]]; do
# We use 'stdbuf' to ensure memory buffers are flushed to disk
@@ -226,7 +335,8 @@ etcd_configure_rbac() {
! is_etcd_running && etcd_start_bg
read -r -a extra_flags <<< "$(etcdctl_auth_flags)"
extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
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
debug_execute etcdctl "${extra_flags[@]}" user add root --interactive=false <<< "$ETCD_ROOT_PASSWORD"
debug_execute etcdctl "${extra_flags[@]}" user grant-role root root
@@ -286,9 +396,10 @@ is_healthy_etcd_cluster() {
local return_value=0
local active_endpoints=0
local -a extra_flags
local -a endpoints_array=()
local host port
read -r -a endpoints_array <<< "$(tr ',;' ' ' <<< "$(etcdctl_get_endpoints)")"
is_boolean_yes "$ETCD_ON_K8S" && read -r -a endpoints_array <<< "$(tr ',;' ' ' <<< "$(etcdctl_get_endpoints)")"
local -r cluster_size=${#endpoints_array[@]}
read -r -a advertised_array <<< "$(tr ',;' ' ' <<< "$ETCD_ADVERTISE_CLIENT_URLS")"
host="$(parse_uri "${advertised_array[0]}" "host")"
@@ -339,6 +450,36 @@ is_healthy_etcd_cluster() {
return $return_value
}
########################
# Prints initial cluster nodes
# Globals:
# ETCD_*
# Arguments:
# None
# Returns:
# String
########################
get_initial_cluster() {
local -a endpoints_array=()
local scheme port initial_members
read -r -a endpoints_array <<< "$(tr ',;' ' ' <<< "$ETCD_INITIAL_CLUSTER")"
if [[ ${#endpoints_array[@]} -gt 0 ]] && ! grep -sqE "://" <<< "$ETCD_INITIAL_CLUSTER"; then
# This piece of code assumes this container is used on a VM environment
# where ETCD_INITIAL_CLUSTER contains a comma-separated list of hostnames,
# and recreates it as follows:
# SCHEME://NOTE_NAME:PEER_PORT
scheme="$(parse_uri "$ETCD_INITIAL_ADVERTISE_PEER_URLS" "scheme")"
port="$(parse_uri "$ETCD_INITIAL_ADVERTISE_PEER_URLS" "port")"
for nodePeer in "${endpoints_array[@]}"; do
initial_members+=("${nodePeer}=${scheme}://${nodePeer}:$port")
done
echo "${initial_members[*]}" | tr ' ' ','
else
# Nothing to do
echo "$ETCD_INITIAL_CLUSTER"
fi
}
########################
# Recalculate initial cluster
# Globals:
@@ -395,6 +536,14 @@ etcd_initialize() {
local domain
info "Initializing etcd"
# Generate user configuration if ETCD_CFG_* variables are provided
etcd_setup_from_environment_variables
ETCD_INITIAL_CLUSTER="$(get_initial_cluster)"
export ETCD_INITIAL_CLUSTER
[[ -f "$ETCD_CONF_FILE" ]] && etcd_conf_write "initial-cluster" "$ETCD_INITIAL_CLUSTER"
read -r -a initial_members <<< "$(tr ',;' ' ' <<< "$ETCD_INITIAL_CLUSTER")"
if is_mounted_dir_empty "$ETCD_DATA_DIR"; then
info "There is no data from previous deployments"
@@ -433,7 +582,8 @@ etcd_initialize() {
info "Adding new member to existing cluster"
ensure_dir_exists "$ETCD_DATA_DIR"
read -r -a extra_flags <<< "$(etcdctl_auth_flags)"
extra_flags+=("--endpoints=$(etcdctl_get_endpoints)" "--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
is_boolean_yes "$ETCD_ON_K8S" && extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
extra_flags+=("--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
etcdctl member add "$ETCD_NAME" "${extra_flags[@]}" | grep "^ETCD_" > "$ETCD_NEW_MEMBERS_ENV_FILE"
replace_in_file "$ETCD_NEW_MEMBERS_ENV_FILE" "^" "export "
fi
@@ -445,6 +595,7 @@ etcd_initialize() {
if [[ ${#initial_members[@]} -gt 1 ]]; then
ETCD_INITIAL_CLUSTER="$(recalculate_initial_cluster)"
export ETCD_INITIAL_CLUSTER
[[ -f "$ETCD_CONF_FILE" ]] && etcd_conf_write "initial-cluster" "$ETCD_INITIAL_CLUSTER"
restore_args+=(
"--name" "$ETCD_NAME"
"--initial-cluster" "$ETCD_INITIAL_CLUSTER"
@@ -487,6 +638,7 @@ etcd_initialize() {
rm -rf "$ETCD_DATA_DIR"
ETCD_INITIAL_CLUSTER="$(recalculate_initial_cluster)"
export ETCD_INITIAL_CLUSTER
[[ -f "$ETCD_CONF_FILE" ]] && etcd_conf_write "initial-cluster" "$ETCD_INITIAL_CLUSTER"
debug_execute etcdctl snapshot restore "${latest_snapshot_file}" \
--name "$ETCD_NAME" \
--data-dir "$ETCD_DATA_DIR" \
@@ -504,19 +656,23 @@ etcd_initialize() {
elif was_etcd_member_removed; then
info "Adding new member to existing cluster"
read -r -a extra_flags <<< "$(etcdctl_auth_flags)"
extra_flags+=("--endpoints=$(etcdctl_get_endpoints)" "--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
is_boolean_yes "$ETCD_ON_K8S" && extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
extra_flags+=("--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
etcdctl member add "$ETCD_NAME" "${extra_flags[@]}" | grep "^ETCD_" > "$ETCD_NEW_MEMBERS_ENV_FILE"
replace_in_file "$ETCD_NEW_MEMBERS_ENV_FILE" "^" "export "
debug_execute etcd_store_member_id &
elif [[ -f "${ETCD_DATA_DIR}/member_id" ]]; then
info "Updating member in existing cluster"
export ETCD_INITIAL_CLUSTER_STATE=existing
[[ -f "$ETCD_CONF_FILE" ]] && etcd_conf_write "initial-cluster-state" "$ETCD_INITIAL_CLUSTER_STATE"
read -r -a extra_flags <<< "$(etcdctl_auth_flags)"
extra_flags+=("--endpoints=$(etcdctl_get_endpoints true)" "--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
is_boolean_yes "$ETCD_ON_K8S" && extra_flags+=("--endpoints=$(etcdctl_get_endpoints)")
extra_flags+=("--peer-urls=$ETCD_INITIAL_ADVERTISE_PEER_URLS")
etcdctl member update "$(cat "${ETCD_DATA_DIR}/member_id")" "${extra_flags[@]}"
else
info "Member ID wasn't properly stored, the member will try to join the cluster by it's own"
export ETCD_INITIAL_CLUSTER_STATE=existing
[[ -f "$ETCD_CONF_FILE" ]] && etcd_conf_write "initial-cluster-state" "$ETCD_INITIAL_CLUSTER_STATE"
fi
fi
fi

View File

@@ -48,7 +48,7 @@ Non-root container images add an extra layer of security and are generally recom
Learn more about the Bitnami tagging policy and the difference between rolling tags and immutable tags [in our documentation page](https://docs.bitnami.com/tutorials/understand-rolling-tags-containers/).
* [`3`, `3-debian-10`, `3.5.1`, `3.5.1-debian-10-r54`, `latest` (3/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-etcd/blob/3.5.1-debian-10-r54/3/debian-10/Dockerfile)
* [`3`, `3-debian-10`, `3.5.1`, `3.5.1-debian-10-r56`, `latest` (3/debian-10/Dockerfile)](https://github.com/bitnami/bitnami-docker-etcd/blob/3.5.1-debian-10-r56/3/debian-10/Dockerfile)
Subscribe to project updates by watching the [bitnami/etcd GitHub repo](https://github.com/bitnami/bitnami-docker-etcd).