feat: 纳管共享 etcd 与 k3s 外 PostgreSQL 高可用及备份
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
# Ansible 管理;与 k3s、数据库生命周期独立。
|
||||
name: {{ inventory_hostname | to_json }}
|
||||
data-dir: {{ etcd_data_dir | to_json }}
|
||||
listen-client-urls: https://{{ etcd_address }}:{{ etcd_client_port }}
|
||||
advertise-client-urls: https://{{ etcd_address }}:{{ etcd_client_port }}
|
||||
listen-peer-urls: https://{{ etcd_address }}:{{ etcd_peer_port }}
|
||||
initial-advertise-peer-urls: https://{{ etcd_address }}:{{ etcd_peer_port }}
|
||||
initial-cluster: "{% for member in groups['etcd'] %}{{ member }}=https://{{ hostvars[member].etcd_address }}:{{ etcd_peer_port }}{{ ',' if not loop.last else '' }}{% endfor %}"
|
||||
initial-cluster-token: {{ etcd_cluster_token | to_json }}
|
||||
initial-cluster-state: new
|
||||
# 已存在的数据目录优先;成员替换必须走单独 runbook,不删除数据重建。
|
||||
client-transport-security:
|
||||
cert-file: {{ etcd_config_dir }}/server.crt
|
||||
key-file: {{ etcd_config_dir }}/server.key
|
||||
client-cert-file: {{ etcd_config_dir }}/gateway.crt
|
||||
client-key-file: {{ etcd_config_dir }}/gateway.key
|
||||
trusted-ca-file: {{ etcd_config_dir }}/ca.crt
|
||||
client-cert-auth: true
|
||||
peer-transport-security:
|
||||
cert-file: {{ etcd_config_dir }}/peer.crt
|
||||
key-file: {{ etcd_config_dir }}/peer.key
|
||||
trusted-ca-file: {{ etcd_config_dir }}/ca.crt
|
||||
client-cert-auth: true
|
||||
allowed-cn: [homelab-etcd-peer]
|
||||
# 独立 metrics listener 仅提供指标/健康,不开放 KV API;只绑定受管内网地址。
|
||||
listen-metrics-urls: {{ etcd_metrics_urls | default("http://127.0.0.1:" ~ etcd_metrics_port) | to_json }}
|
||||
quota-backend-bytes: {{ etcd_quota_bytes }}
|
||||
auto-compaction-mode: periodic
|
||||
auto-compaction-retention: '1h'
|
||||
heartbeat-interval: 100
|
||||
election-timeout: 1000
|
||||
logger: zap
|
||||
log-level: info
|
||||
@@ -0,0 +1,23 @@
|
||||
[Unit]
|
||||
Description=Homelab shared etcd
|
||||
Wants=network-online.target
|
||||
After=network-online.target
|
||||
|
||||
[Service]
|
||||
User=homelab-etcd
|
||||
Group=homelab-etcd
|
||||
ExecStart={{ etcd_install_dir }}/etcd --config-file={{ etcd_config_dir }}/etcd.yml
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
TimeoutStopSec=60
|
||||
MemoryHigh={{ etcd_memory_high }}
|
||||
MemoryMax={{ etcd_memory_max }}
|
||||
UMask=0077
|
||||
NoNewPrivileges=true
|
||||
ProtectSystem=strict
|
||||
ProtectHome=true
|
||||
PrivateTmp=true
|
||||
ReadWritePaths={{ etcd_data_dir }}
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -0,0 +1,11 @@
|
||||
[Unit]
|
||||
Description=Snapshot homelab shared etcd
|
||||
After=homelab-etcd.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
ExecStart={{ etcd_install_dir }}/snapshot
|
||||
User=root
|
||||
UMask=0077
|
||||
TimeoutStartSec=300
|
||||
Nice=10
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
umask 077
|
||||
export ETCDCTL_ENDPOINTS="https://{{ etcd_address }}:{{ etcd_client_port }}"
|
||||
export ETCDCTL_CACERT="{{ etcd_config_dir }}/ca.crt"
|
||||
export ETCDCTL_CERT="{{ etcd_config_dir }}/admin.crt"
|
||||
export ETCDCTL_KEY="{{ etcd_config_dir }}/admin.key"
|
||||
repo="{{ etcd_snapshot_dir }}"
|
||||
exec 9>"$repo/.lock"
|
||||
flock -n 9 || exit 0
|
||||
output="$repo/$(date -u +%Y%m%dT%H%M%SZ).db"
|
||||
trap 'rm -f "$output.partial" "$output.partial.part"' EXIT
|
||||
{{ etcd_install_dir }}/etcdctl snapshot save "$output.partial"
|
||||
{{ etcd_install_dir }}/etcdutl snapshot status "$output.partial" >/dev/null
|
||||
mv "$output.partial" "$output"
|
||||
# 只有新快照成功且验证可读才清理旧备份。目录仅由此任务管理。
|
||||
mapfile -t snapshots < <(find "$repo" -maxdepth 1 -type f -name '????????T??????Z.db' -printf '%f\n' | sort -r)
|
||||
for old in "${snapshots[@]:{{ etcd_snapshot_keep }}}"; do
|
||||
rm -- "$repo/$old"
|
||||
done
|
||||
@@ -0,0 +1,10 @@
|
||||
[Unit]
|
||||
Description=Daily homelab etcd snapshot
|
||||
|
||||
[Timer]
|
||||
OnCalendar=*-*-* 03:20:00 UTC
|
||||
RandomizedDelaySec=300
|
||||
Persistent=true
|
||||
|
||||
[Install]
|
||||
WantedBy=timers.target
|
||||
Reference in New Issue
Block a user