Skip to content

Conversation

dengliu
Copy link
Collaborator

@dengliu dengliu commented Jun 17, 2025

Description

This PR implements comprehensive PVC (Persistent Volume Claim) expansion support for the StarRocks Kubernetes operator, enabling users to expand storage volumes for FE, BE, and CN components without data loss.

✨ Key Features

🔧 Core Functionality

  • Automatic PVC Expansion: Detects storage size increases and expands PVCs automatically
  • Storage Class Validation: Validates that storage classes support volume expansion (allowVolumeExpansion: true)
  • Conservative Safety: Defaults to offline expansion for unknown storage classes to prevent data corruption
  • Smart StatefulSet Management: Minimizes disruption by intelligently handling StatefulSet updates

🛡️ Safety Features

  • Size Reduction Prevention: Validates against storage size decreases
  • Data Preservation: All data is preserved during expansion (PVCs are never deleted)
  • Detachment Detection: Automatically detects when storage classes require PVC detachment
  • Comprehensive Validation: Multiple validation layers prevent dangerous operations

Performance Optimizations

  • Zero-Downtime Expansion: For size-only changes with online-capable storage classes
  • Minimal Disruption: Only recreates StatefulSets when absolutely necessary
  • Intelligent Decision Making: Chooses optimal expansion strategy based on change scope and storage capabilities

🔄 Expansion Strategies

The operator implements three intelligent expansion strategies:

Scenario Strategy Downtime Description
Size-only + Online Storage Direct PVC expansion None Expands PVCs without touching StatefulSet
Size-only + Offline Storage Offline expansion Minimal Deletes StatefulSet → Expands PVCs → Recreates StatefulSet
Mixed Changes Safe recreation Necessary Deletes StatefulSet → Expands PVCs → Recreates with all changes

🧪 Testing

Comprehensive Test Coverage

  • Unit Tests: 15+ test cases covering all expansion scenarios
  • Integration Tests: Automated test script for real cluster validation
  • E2E Tests: End-to-end testing with actual Kubernetes resources
  • Edge Case Testing: Storage class validation, size reduction prevention, detachment scenarios

Test Results

$ go test ./pkg/k8sutils/... -v
=== RUN   TestDetectPVCExpansion
=== RUN   TestExpandPVCs  
=== RUN   TestValidateStorageClassExpansion
=== RUN   TestCheckStorageClassRequiresDetachment
--- PASS: All tests (0.366s)

🔍 Technical Implementation

Key Components

PVC Expansion Detection

type PVCExpansionResult struct {
    NeedsExpansion             bool
    NeedsStatefulSetRecreation bool
    RequiresDetachment         bool
    OnlyPVCSizeChanged         bool
    PVCsToExpand               []PVCExpansionInfo
    ValidationErrors           []string
}

Storage Class Validation

  • Validates allowVolumeExpansion: true before attempting expansion
  • Maintains whitelist of known-safe online expansion provisioners
  • Conservative default: unknown storage classes use offline expansion

Smart StatefulSet Management

  • Detects scope of changes (size-only vs. mixed)
  • Avoids VolumeClaimTemplate immutability errors
  • Reuses existing StatefulSet recreation logic for consistency

🛡️ Safety Guarantees

Data Protection

  • PVCs are never deleted - only expanded
  • Size reduction prevention - validates against dangerous operations
  • Storage class validation - ensures expansion is supported
  • Conservative defaults - prefers safety over convenience

Operational Safety

  • Graceful StatefulSet recreation - proper pod termination and PVC detachment
  • Comprehensive error handling - clear error messages and recovery guidance
  • Rollback safety - failed expansions don't corrupt existing data

📖 Documentation

Please list any related issues and link them here.

#121

Checklist

For operator, please complete the following checklist:

  • run make generate to generate the code.
  • run golangci-lint run to check the code style.
  • run make test to run UT.
  • run make manifests to update the yaml files of CRD.

For helm chart, please complete the following checklist:

  • make sure you have updated the values.yaml
    file of starrocks chart.
  • In scripts directory, run bash create-parent-chart-values.sh to update the values.yaml file of the parent
    chart( kube-starrocks chart).

@dengliu dengliu changed the title [Feature] PVC expansion [Feature] PVC Expansion Support for StarRocks Kubernetes Operator Jun 17, 2025
Deng Liu added 2 commits June 16, 2025 23:30
Signed-off-by: Deng Liu <[email protected]>
Signed-off-by: Deng Liu <[email protected]>
@dengliu dengliu force-pushed the dliu/pvcexpansion branch from 2543e60 to 888632e Compare June 17, 2025 06:30
@kevincai kevincai self-requested a review June 17, 2025 09:21
@yandongxiao
Copy link
Collaborator

Thank you very much for submitting such an important Feature again. If this feature can be used as a switch option, I think it would be better for existing users.


1. **Storage Class Support**: Your storage class must support volume expansion
2. **Kubernetes Version**: Kubernetes 1.11+ (for PVC expansion support)
3. **Operator Version**: StarRocks operator v1.9.9+ (with PVC expansion feature)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now the newest version is v1.10.2.

return nil
} else {
// PVC sizes + other changes - delete StatefulSet first, then expand PVCs, then recreate
logger.Info("PVC expansion with other StatefulSet changes, will delete StatefulSet first for safe expansion", "count", len(expansionResult.PVCsToExpand))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


// ApplyStatefulSetWithPVCExpansion applies a StatefulSet with support for PVC expansion.
// It detects when PVC sizes need to be expanded and handles the expansion process.
func ApplyStatefulSetWithPVCExpansion(ctx context.Context, k8sClient client.Client, expect *appv1.StatefulSet,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we provide a command - line argument for the operator as an optional feature? That is, by default, the operator still directly calls ApplyStatefulSet. When the operator is launched with a certain parameter, for example, --with- pvc-expansion, then the operator calls ApplyStatefulSetWithPVCExpansion.

}

// waitForStatefulSetDeletion waits for a StatefulSet to be fully deleted
func waitForStatefulSetDeletion(ctx context.Context, k8sClient client.Client, namespace, name string) error {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to my tests, deleting a StatefulSet is a very quick action and does not require loop waiting. If you need to wait for the POD to be deleted, the logic of waiting for five minutes is a bit imprecise. If it returns due to timeout, the operator will fail before Step 3: Wait for PVCs to be fully detached

}

// Step 3: Wait for PVCs to be fully detached
err = waitForPVCsDetached(ctx, k8sClient, expansionInfos)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If waitForPVCsDetached fails, it will cause the expansion of PVC to fail and the creation of the Statefulset object to fail. Then, the Operator will rebuild the Statefulset object in the subsequent reconciliation. However, there will be the following error: The storage size set in StarRocksCluster is equal to the storage size set in the Statefulset. But the value set in the PVC has not changed at all.

err := k8sClient.Get(ctx, types.NamespacedName{
Namespace: namespace,
Name: statefulSetName,
}, &sts)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There will be an situation: The storage size set in StarRocksCluster is equal to the storage size set in the Statefulset. But the value set in the PVC has not changed at all.
So I think check the existing Statefulset is not enough.

}

// Step 5: Wait for PVC expansion to complete
err = waitForPVCExpansionComplete(ctx, k8sClient, expansionInfos)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the PVC Expansion has not been completed and a timeout occurs, what problems will occur if the newly created POD is attached to the PVC?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In addition, there is a situation where although the Operator has executed the ExpandPVCs operation, Kubernetes has not started the Expansion, and the Operator may mistakenly think that the Expand has been successful.

{{- fail (printf "Log storage size cannot be zero for %s component: %s" $component $logStorageSize) -}}
{{- end -}}
{{- if and $spillStorageSize (regexMatch "^0" $spillStorageSize) -}}
{{- fail (printf "Spill storage size cannot be zero for %s component: %s" $component $spillStorageSize) -}}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting the storage size to 0 is no longer allowed here. This conflicts with the behavior of the Operator. Please refer to

# If you set it to 0Gi, the related PVC will not be created, and the log will not be persisted.

// Delete the StatefulSet immediately since VolumeClaimTemplates are immutable
// This is more efficient than scaling to 0 first
logger.Info("deleting StatefulSet to update VolumeClaimTemplates")
err = k8sClient.Delete(ctx, &current)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need to adjust the RBAC configuration of Operator?

@CLAassistant
Copy link

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.


Deng Liu seems not to be a GitHub user. You need a GitHub account to be able to sign the CLA. If you have already a GitHub account, please add the email address used for this commit to your account.
You have signed the CLA already but the status is still pending? Let us recheck it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants