apiVersion: v1 kind: Namespace metadata: name: backup-system --- apiVersion: batch/v1 kind: CronJob metadata: name: node-backup-job namespace: backup-system spec: # 每天凌晨2点运行 schedule: "0 2 * * *" concurrencyPolicy: Forbid jobTemplate: spec: ttlSecondsAfterFinished: 86400 # 1天后删除已完成的任务 template: spec: serviceAccountName: backup-service-account nodeSelector: kubernetes.io/hostname: "vkvm-us1" containers: - name: backup-trigger image: bitnami/kubectl:latest command: - /bin/sh - -c - | kubectl label daemonset/node-backup-daemon trigger-backup=true --overwrite -n backup-system && \ sleep 60 && \ kubectl label daemonset/node-backup-daemon trigger-backup- -n backup-system restartPolicy: OnFailure --- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-backup-daemon namespace: backup-system spec: selector: matchLabels: app: node-backup template: metadata: labels: app: node-backup spec: nodeSelector: kubernetes.io/hostname: "vkvm-us1" containers: - name: backup-container image: minio/mc:latest imagePullPolicy: IfNotPresent command: - /bin/sh - -c - | # 添加依赖的工具 apk add --no-cache jq bash findutils tar curl # 等待触发备份 while true; do if [ "$(curl -s -H "Authorization: Bearer $(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" \ https://kubernetes.default.svc/apis/apps/v1/namespaces/backup-system/daemonsets/node-backup-daemon \ --cacert /var/run/secrets/kubernetes.io/serviceaccount/ca.crt \ -X GET | jq -r '.metadata.labels["trigger-backup"]')" = "true" ]; then echo "备份触发,执行备份脚本..." bash /scripts/backup.sh echo "备份完成" fi # 每分钟检查一次 sleep 60 done env: - name: MINIO_ENDPOINT valueFrom: secretKeyRef: name: minio-credentials key: endpoint - name: MINIO_ACCESS_KEY valueFrom: secretKeyRef: name: minio-credentials key: access-key - name: MINIO_SECRET_KEY valueFrom: secretKeyRef: name: minio-credentials key: secret-key - name: MINIO_BUCKET valueFrom: secretKeyRef: name: minio-credentials key: bucket - name: MINIO_SUBPATH valueFrom: configMapKeyRef: name: backup-config key: subpath optional: true - name: BACKUPS_TO_KEEP valueFrom: configMapKeyRef: name: backup-config key: backups-to-keep optional: true volumeMounts: - name: host-data mountPath: /data - name: scripts mountPath: /scripts volumes: - name: host-data hostPath: path: /data - name: scripts configMap: name: backup-script defaultMode: 0755 --- apiVersion: v1 kind: Secret metadata: name: minio-credentials namespace: backup-system type: Opaque data: # 这些值需要使用base64编码替换 endpoint: aHR0cHM6Ly9hcGkubWluaW8uc2t5Ynl0ZS5tZQ== # https://api.minio.skybyte.me access-key: RVZuWFViR2xld2t0dFF0em9XUWs= # EVnXUbGlewkttQtzoWQk secret-key: THNxVFRmc0VEVzBFY3Buc09aOUxyTnhwc21zajdIMGxlR2R0WHBwRg== # LsqTTfsEDW0EcpnsOZ9LrNxpsmsj7H0leGdtXppF bucket: YmFja3Vwcw== # backups --- apiVersion: v1 kind: ConfigMap metadata: name: backup-config namespace: backup-system data: subpath: "backups" backups-to-keep: "3" --- apiVersion: v1 kind: ServiceAccount metadata: name: backup-service-account namespace: backup-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: backup-role namespace: backup-system rules: - apiGroups: ["apps"] resources: ["daemonsets"] verbs: ["get", "patch", "update"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: backup-role-binding namespace: backup-system subjects: - kind: ServiceAccount name: backup-service-account namespace: backup-system roleRef: kind: Role name: backup-role apiGroup: rbac.authorization.k8s.io