Skip to content

Commit d28bbec

Browse files
committed
feat: add s3 backup support
1 parent 8e140a3 commit d28bbec

File tree

6 files changed

+123
-1
lines changed

6 files changed

+123
-1
lines changed

Dockerfile

+18
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,26 @@ FROM docker.io/bitnami/etcd:${ETCD_VERSION}
55
# Switch to root user
66
USER root
77

8+
# Install required packages
9+
RUN apt-get update && apt-get install -y \
10+
wget \
11+
ca-certificates \
12+
cronie \
13+
&& rm -rf /var/lib/apt/lists/*
14+
15+
# Install minio client
16+
RUN wget https://dl.min.io/client/mc/release/linux-amd64/mc -O /usr/local/bin/mc && \
17+
chmod +x /usr/local/bin/mc
18+
19+
# Create backup directory
20+
RUN mkdir -p /backup
21+
822
VOLUME ["/bitnami/etcd"]
923

24+
# Copy backup scripts directly to /usr/local/bin
25+
COPY backup/*.sh /usr/local/bin/
26+
RUN chmod +x /usr/local/bin/*.sh
27+
1028
# Copy our custom entrypoint
1129
COPY docker-entrypoint.sh /usr/local/bin/
1230
RUN chmod +x /usr/local/bin/docker-entrypoint.sh

backup/backup-etcd.sh

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Configure mc client if not already configured
5+
if [ ! -f /root/.mc/config.json ]; then
6+
mc alias set s3 $S3_ENDPOINT $S3_ACCESS_KEY $S3_SECRET_KEY
7+
fi
8+
9+
# Create backup directory if it doesn't exist
10+
BACKUP_DIR="/backup"
11+
mkdir -p $BACKUP_DIR
12+
13+
# Create backup with timestamp
14+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
15+
BACKUP_NAME="etcd-backup-${TIMESTAMP}.db"
16+
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_NAME}"
17+
18+
# Create ETCD snapshot
19+
etcdctl snapshot save $BACKUP_PATH
20+
21+
# Compress backup
22+
gzip $BACKUP_PATH
23+
24+
# Upload to S3
25+
mc cp "${BACKUP_PATH}.gz" "s3/$S3_BUCKET/"
26+
27+
# Clean up local backup
28+
rm -f "${BACKUP_PATH}.gz"
29+
30+
# Clean up old backups in S3
31+
RETENTION_DAYS=${BACKUP_RETENTION_DAYS:-7} # Default to 7 days if not set
32+
mc rm --force --recursive --older-than "${RETENTION_DAYS}d" "s3/$S3_BUCKET/"
33+
34+
echo "Backup completed successfully at $(date)"

backup/crontab

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Run backup every 6 hours
2+
0 */6 * * * /usr/local/bin/backup-etcd.sh >> /var/log/etcd-backup.log 2>&1

backup/init-backup.sh

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Validate backup is enabled
5+
BACKUP_ENABLED=${BACKUP_ENABLED:-true}
6+
if [ "$BACKUP_ENABLED" != "true" ]; then
7+
echo "Backup system is disabled via BACKUP_ENABLED=false"
8+
exit 0
9+
fi
10+
11+
# Install crontab
12+
crontab /backup/crontab
13+
14+
# Start crond in background
15+
/usr/sbin/crond
16+
17+
# Configure mc client
18+
mc alias set s3 $S3_ENDPOINT $S3_ACCESS_KEY $S3_SECRET_KEY
19+
20+
echo "Backup system initialized successfully"

backup/restore-etcd.sh

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/bin/bash
2+
set -e
3+
4+
# Configure mc client if not already configured
5+
if [ ! -f /root/.mc/config.json ]; then
6+
mc alias set s3 $S3_ENDPOINT $S3_ACCESS_KEY $S3_SECRET_KEY
7+
fi
8+
9+
# Create temporary directory for restore
10+
RESTORE_DIR="/backup/restore"
11+
mkdir -p $RESTORE_DIR
12+
13+
# Get latest backup from S3
14+
LATEST_BACKUP=$(mc ls s3/$S3_BUCKET/ | sort -r | head -n1 | awk '{print $5}')
15+
if [ -z "$LATEST_BACKUP" ]; then
16+
echo "No backup found in S3"
17+
exit 1
18+
fi
19+
20+
# Download and extract backup
21+
mc cp "s3/$S3_BUCKET/$LATEST_BACKUP" "$RESTORE_DIR/"
22+
gunzip "$RESTORE_DIR/$LATEST_BACKUP"
23+
BACKUP_FILE="${RESTORE_DIR}/${LATEST_BACKUP%.*}"
24+
25+
# Stop ETCD service (if running)
26+
pkill etcd || true
27+
sleep 5
28+
29+
# Restore from snapshot
30+
etcdctl snapshot restore "$BACKUP_FILE" \
31+
--data-dir /bitnami/etcd/data
32+
33+
# Fix permissions
34+
chmod 700 -R /bitnami/etcd
35+
chown -R 1001:1001 /bitnami/etcd
36+
37+
# Clean up
38+
rm -rf $RESTORE_DIR
39+
40+
echo "Restore completed successfully at $(date)"

docker-entrypoint.sh

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ set -e
44
# Ensure the data directory exists with correct permissions
55
mkdir -p /bitnami/etcd/data
66
chmod 700 -R /bitnami/etcd
7-
chown -R 1000:1000 /bitnami/etcd
7+
chown -R 1001:1001 /bitnami/etcd
8+
9+
# Initialize backup system if enabled and environment variables are set
10+
BACKUP_ENABLED=${BACKUP_ENABLED:-true}
11+
if [ "$BACKUP_ENABLED" = "true" ] && [ ! -z "$S3_ENDPOINT" ] && [ ! -z "$S3_ACCESS_KEY" ] && [ ! -z "$S3_SECRET_KEY" ] && [ ! -z "$S3_BUCKET" ]; then
12+
/usr/local/bin/init-backup.sh
13+
else
14+
echo "Backup system not enabled or missing required S3 environment variables"
15+
fi
816

917
# Call the original entrypoint with all arguments
1018
exec /opt/bitnami/scripts/etcd/entrypoint.sh "$@"

0 commit comments

Comments
 (0)