ข้ามไปยังเนื้อหา

This is the Experimental version (Latest). It is under active development and may change. For the most reliable documentation, use the version selector in the top-right to switch to Stable, or click here to go to the Stable version's homepage.

SeaweedFS (Bootstrap) Installation

อัพเดทล่าสุด:

เนื้อหานี้ยังไม่มีในภาษาของคุณ

SeaweedFS (Bootstrap) is the minimal instance required to break the circular dependency between storage and the database. It provides the initial S3 endpoint for CloudnativePG.

  1. Connect to 🟢 Management Kubernetes Cluster ; _i.e w/ Kubeconfig File.

    Set Kubeconfig File

    Ensure you have defined and loaded your Global Shell Variables as described in Shell Variables.

    Terminal window
    source $BASE_WORKING_DIR/shell-values/kubernetes/management_cluster.vars.sh
  2. Prepare Required Shell Variables

    Ensure K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME and K8S_STORAGE_CLASS_NAME are defined as per the Shell Variables guide. Other credentials and domain names are loaded from your tools/*.vars.sh files.

  3. Create Namespace for SeaweedFS Bootstrap

    Terminal window
    kubectl create namespace seaweedfs-bootstrap
  4. Create SeaweedFS S3 Configuration

    Terminal window
    cat <<EOF > $BASE_WORKING_DIR/kubernetes-manifests/seaweedfs-bootstrap-s3.yaml
    ---
    # S3 Credentials for SeaweedFS (Minimal/Bootstrap)
    apiVersion: v1
    kind: Secret
    type: Opaque
    metadata:
    name: seaweedfs-s3-secret
    namespace: seaweedfs-bootstrap
    stringData:
    # ----------------------------------------------------------------------------
    # INPUT CONFIGURATION (YAML)
    # Run 'scripts/seaweedfs-utils.sh update <this_file>' to generate the JSON below.
    # ----------------------------------------------------------------------------
    s3_config_input: |
    users:
    - name: admin
    password: "${SEAWEEDFS_BOOTSTRAP_S3_ADMIN_PASSWORD}"
    actions:
    - Admin
    - Read
    - Write
    - List
    - Tagging
    - name: postgres-backup
    password: "${SEAWEEDFS_BOOTSTRAP_S3_POSTGRES_BACKUP_PASSWORD}"
    actions:
    - "Read:postgres-backups"
    - "Write:postgres-backups"
    - "List:postgres-backups"
    - "Tagging:postgres-backups"
    # ----------------------------------------------------------------------------
    # GENERATED CONFIGURATION (JSON) - DO NOT EDIT MANUALLY
    # ----------------------------------------------------------------------------
    seaweedfs_s3_config: ""
    EOF
    Terminal window
    # Generate proper JSON formatted config into the configuration file
    $BASE_WORKING_DIR/assets/scripts/seaweedfs-utils.sh update $BASE_WORKING_DIR/kubernetes-manifests/seaweedfs-bootstrap-s3.yaml

    Apply the configuration:

    Terminal window
    kubectl apply -f $BASE_WORKING_DIR/kubernetes-manifests/seaweedfs-bootstrap-s3.yaml
  5. Add SeaweedFS Helm Repository

    Terminal window
    helm repo add seaweedfs https://seaweedfs.github.io/seaweedfs/helm
    helm repo update
  6. Create SeaweedFS Bootstrap Helm Values

    Terminal window
    cat <<EOF > $BASE_WORKING_DIR/helm-values/seaweedfs-bootstrap-values.yaml
    global:
    imageName: chrislusf/seaweedfs
    loggingLevel: 1
    enableSecurity: false
    # Disable global replication (Relies on Longhorn)
    enableReplication: false
    # "000" = No replication at SeaweedFS level
    replicationPlacement: "000"
    master:
    enabled: true
    replicas: 1
    # Default volume size is 1GB (1000MB) in this chart, fitting ~10 volumes in 10Gi
    volumeSizeLimitMB: 1000
    # Security Context
    podSecurityContext:
    enabled: true
    fsGroup: 1000
    fsGroupChangePolicy: "OnRootMismatch"
    containerSecurityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    privileged: false
    allowPrivilegeEscalation: false
    seccompProfile:
    type: RuntimeDefault
    capabilities:
    drop: ["ALL"]
    # Persistence for Master (Metadata/Sequence)
    data:
    type: "persistentVolumeClaim"
    size: "1Gi"
    storageClass: "${K8S_STORAGECLASS_NAME}"
    logs:
    type: "stdout/stderr"
    volume:
    enabled: true
    replicas: 1
    ipBind: "0.0.0.0"
    minFreeSpacePercent: 5
    # Security Context
    podSecurityContext:
    enabled: true
    fsGroup: 1000
    fsGroupChangePolicy: "OnRootMismatch"
    containerSecurityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    privileged: false
    allowPrivilegeEscalation: false
    seccompProfile:
    type: RuntimeDefault
    capabilities:
    drop: ["ALL"]
    # Persistence for Volume (Data)
    dataDirs:
    - name: data
    type: "persistentVolumeClaim"
    size: "10Gi"
    storageClass: "${K8S_STORAGECLASS_NAME}"
    maxVolumes: 10
    extraArgs: []
    filer:
    enabled: true
    replicas: 1
    port: 9001 # MinIO Console compatibility
    # Security Context
    podSecurityContext:
    enabled: true
    fsGroup: 1000
    fsGroupChangePolicy: "OnRootMismatch"
    containerSecurityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    privileged: false
    allowPrivilegeEscalation: false
    seccompProfile:
    type: RuntimeDefault
    capabilities:
    drop: ["ALL"]
    # Persistence for Filer (Metadata)
    data:
    type: "persistentVolumeClaim"
    size: "1Gi"
    storageClass: "${K8S_STORAGECLASS_NAME}"
    logs:
    type: "stdout/stderr"
    # Ingress for Filer (SeaweedFS WebUI)
    ingress:
    enabled: false
    className: nginx
    host: "${SEAWEEDFS_BOOTSTRAP_FILER_DOMAIN}"
    path: "/"
    pathType: Prefix
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    ingress.kubernetes.io/proxy-body-size: "0"
    # Basic Auth Configuration
    # nginx.ingress.kubernetes.io/auth-type: basic
    # nginx.ingress.kubernetes.io/auth-secret: seaweedfs-filer-basic-auth
    # nginx.ingress.kubernetes.io/auth-realm: "Authentication Required"
    tls:
    - secretName: "${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}"
    hosts:
    - "${SEAWEEDFS_BOOTSTRAP_FILER_DOMAIN}"
    s3:
    enabled: true
    replicas: 1
    port: 9000 # MinIO API compatibility
    enableAuth: true
    existingConfigSecret: seaweedfs-s3-secret
    # Security Context
    podSecurityContext:
    enabled: true
    fsGroup: 1000
    fsGroupChangePolicy: "OnRootMismatch"
    containerSecurityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    privileged: false
    allowPrivilegeEscalation: false
    seccompProfile:
    type: RuntimeDefault
    capabilities:
    drop: ["ALL"]
    logs:
    type: "stdout/stderr"
    # Ingress for S3 API
    ingress:
    enabled: true
    className: nginx
    host: "${SEAWEEDFS_BOOTSTRAP_API_DOMAIN}"
    path: "/"
    pathType: Prefix
    annotations:
    nginx.ingress.kubernetes.io/proxy-body-size: "0"
    ingress.kubernetes.io/proxy-body-size: "0"
    tls:
    - secretName: "${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}"
    hosts:
    - "${SEAWEEDFS_BOOTSTRAP_API_DOMAIN}"
    admin:
    enabled: true
    secret:
    adminUser: "admin"
    adminPassword: "${SEAWEEDFS_BOOTSTRAP_ADMIN_PASSWORD}"
    ingress:
    enabled: true
    className: nginx
    host: "${SEAWEEDFS_BOOTSTRAP_ADMIN_DOMAIN}"
    path: "/"
    pathType: Prefix
    tls:
    - secretName: "${K8S_INGRESS_TLS_CERTIFICATE_SECRET_NAME}"
    hosts:
    - "${SEAWEEDFS_BOOTSTRAP_ADMIN_DOMAIN}"
    # Security Context
    podSecurityContext:
    enabled: true
    fsGroup: 1000
    fsGroupChangePolicy: "OnRootMismatch"
    containerSecurityContext:
    enabled: true
    runAsUser: 1000
    runAsGroup: 1000
    runAsNonRoot: true
    privileged: false
    allowPrivilegeEscalation: false
    seccompProfile:
    type: RuntimeDefault
    capabilities:
    drop: ["ALL"]
    EOF
  7. Install SeaweedFS Bootstrap Helm Release

    Terminal window
    helm upgrade --install seaweedfs-bootstrap seaweedfs/seaweedfs \
    --version 4.0.407 \
    --namespace seaweedfs-bootstrap \
    -f $BASE_WORKING_DIR/helm-values/seaweedfs-bootstrap-values.yaml
  8. Provision SeaweedFS Buckets

    Terminal window
    cat <<EOF > $BASE_WORKING_DIR/kubernetes-manifests/seaweedfs-bootstrap-job-provisioning.yaml
    apiVersion: batch/v1
    kind: Job
    metadata:
    name: seaweedfs-bootstrap-provisioning
    namespace: seaweedfs-bootstrap
    labels:
    app.kubernetes.io/name: seaweedfs-bootstrap
    app.kubernetes.io/component: provisioning
    spec:
    ttlSecondsAfterFinished: 300
    template:
    metadata:
    labels:
    app.kubernetes.io/name: seaweedfs-bootstrap
    app.kubernetes.io/component: provisioning
    spec:
    restartPolicy: OnFailure
    # Security Context
    securityContext:
    runAsNonRoot: true
    runAsUser: 10000
    fsGroup: 10000
    seccompProfile:
    type: RuntimeDefault
    containers:
    - name: provisioner
    image: chrislusf/seaweedfs:4.07
    # Security Context
    securityContext:
    allowPrivilegeEscalation: false
    readOnlyRootFilesystem: false
    runAsNonRoot: true
    runAsUser: 10000
    capabilities:
    drop: ["ALL"]
    # Resource Limits
    resources:
    requests:
    memory: "64Mi"
    cpu: "100m"
    limits:
    memory: "128Mi"
    cpu: "200m"
    env:
    # Target SeaweedFS Master (Minimal/Bootstrap instance)
    - name: WEED_MASTER
    value: "seaweedfs-master:9333"
    # Target SeaweedFS Filer (Minimal/Bootstrap instance)
    - name: WEED_FILER
    value: "seaweedfs-filer:9001"
    # Comma-separated list of buckets to create
    - name: SEAWEEDFS_BUCKETS
    value: "postgres-backups"
    command:
    - "/bin/sh"
    - "-c"
    - |
    set -e
    echo "[INFO] Starting SeaweedFS Bootstrap Provisioning..."
    echo "[INFO] Target Master: \$WEED_MASTER"
    echo "[INFO] Target Filer: \$WEED_FILER"
    echo "[INFO] Buckets: \$SEAWEEDFS_BUCKETS"
    # 1. Wait for Master Leader
    echo "[INFO] Waiting for SeaweedFS Master Leader..."
    START_TIME=\$(date +%s)
    TIMEOUT=300
    until echo cluster.ps | weed shell -master=\$WEED_MASTER > /dev/null 2>&1; do
    CURRENT_TIME=\$(date +%s)
    ELAPSED_TIME=\$((\$CURRENT_TIME - \$START_TIME))
    if [ \$ELAPSED_TIME -gt \$TIMEOUT ]; then
    echo "[ERROR] Timeout waiting for SeaweedFS Master at \$WEED_MASTER"
    exit 1
    fi
    echo "[WAIT] Connecting to master... (\${ELAPSED_TIME}s)"
    sleep 5
    done
    echo "[INFO] Connected to Master."
    # 2. Wait for Filer (required for bucket creation)
    echo "[INFO] Waiting for SeaweedFS Filer..."
    until echo fs.ls / | weed shell -master=\$WEED_MASTER -filer=\$WEED_FILER > /dev/null 2>&1; do
    CURRENT_TIME=\$(date +%s)
    ELAPSED_TIME=\$((\$CURRENT_TIME - \$START_TIME))
    if [ \$ELAPSED_TIME -gt \$TIMEOUT ]; then
    echo "[ERROR] Timeout waiting for SeaweedFS Filer at \$WEED_FILER"
    exit 1
    fi
    echo "[WAIT] Connecting to filer... (\${ELAPSED_TIME}s)"
    sleep 5
    done
    echo "[INFO] Connected to Filer."
    # 3. Create Buckets
    # Generate weed shell script
    SCRIPT_FILE="/tmp/provision.weed"
    echo "# Auto-generated provisioning script" > \$SCRIPT_FILE
    # POSIX compliant way to split comma-separated string
    echo "\$SEAWEEDFS_BUCKETS" | tr ',' '\n' | while read -r bucket; do
    # Trim whitespace
    bucket=\$(echo "\$bucket" | sed 's/^[[:space:]]*//;s/[[:space:]]*\$//')
    if [ -n "\$bucket" ]; then
    echo "s3.bucket.create -name \$bucket" >> \$SCRIPT_FILE
    echo "[INFO] Added bucket creation command for: \$bucket"
    fi
    done
    echo "s3.bucket.list" >> \$SCRIPT_FILE
    # Execute
    echo "[INFO] Executing provisioning commands:"
    cat \$SCRIPT_FILE
    echo "----------------------------------------"
    # Run weed shell with better error handling
    OUTPUT_FILE="/tmp/output.log"
    if ! cat \$SCRIPT_FILE | weed shell -master=\$WEED_MASTER -filer=\$WEED_FILER 2>&1 | tee \$OUTPUT_FILE; then
    # Check if error is just "bucket already exists"
    if grep -qi "already exist\|AlreadyExists" \$OUTPUT_FILE; then
    echo "[WARN] Some buckets already exist (expected, continuing...)"
    else
    echo "[ERROR] Bucket creation failed with unexpected error:"
    cat \$OUTPUT_FILE
    exit 1
    fi
    fi
    echo "[INFO] Bucket creation completed."
    # 4. Verify bucket creation
    echo "[INFO] Verifying bucket creation..."
    BUCKET_LIST=\$(echo s3.bucket.list | weed shell -master=\$WEED_MASTER -filer=\$WEED_FILER 2>&1)
    echo "\$SEAWEEDFS_BUCKETS" | tr ',' '\n' | while read -r bucket; do
    bucket=\$(echo "\$bucket" | sed 's/^[[:space:]]*//;s/[[:space:]]*\$//')
    if [ -n "\$bucket" ]; then
    if echo "\$BUCKET_LIST" | grep -q "\$bucket"; then
    echo "[SUCCESS] Bucket '\$bucket' exists"
    else
    echo "[ERROR] Bucket '\$bucket' NOT found!"
    echo "[DEBUG] Available buckets:"
    echo "\$BUCKET_LIST"
    exit 1
    fi
    fi
    done
    echo "[SUCCESS] All buckets verified successfully!"
    EOF

    Apply the provisioning job:

    Terminal window
    kubectl apply -f $BASE_WORKING_DIR/kubernetes-manifests/seaweedfs-bootstrap-job-provisioning.yaml
  1. Verify Pod Status

    Terminal window
    kubectl get pods -n seaweedfs-bootstrap

    💡 All components should be Running:

    NAME READY STATUS RESTARTS AGE
    seaweedfs-admin-0 1/1 Running 0 ...
    seaweedfs-filer-0 1/1 Running 0 ...
    seaweedfs-master-0 1/1 Running 0 ...
    seaweedfs-s3-XXXXXXXXXX-YYYYY 1/1 Running 0 ...
    seaweedfs-volume-0 1/1 Running 0 ...
    seaweedfs-bootstrap-provisioning 0/1 Completed 0 ...
  2. Verify Admin UI and Buckets

    • Access the SeaweedFS Bootstrap Admin UI at https://${SEAWEEDFS_BOOTSTRAP_ADMIN_DOMAIN}.
    • Login with the admin credentials defined in ${SEAWEEDFS_BOOTSTRAP_ADMIN_PASSWORD}.
    • Navigate to the Buckets tab and confirm that the postgres-backups bucket has been successfully created.

Finished?

Use the below navigation to proceed