mirror of
https://github.com/kubevela/kubevela.git
synced 2026-08-18 03:56:36 +00:00
Feat: add pre-dispatch dryrun check (#5277)
Signed-off-by: Somefive <yd219913@alibaba-inc.com> Signed-off-by: Somefive <yd219913@alibaba-inc.com>
This commit is contained in:
@@ -99,6 +99,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `featureGates.multiStageComponentApply` | if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply. | `false` |
|
||||
| `featureGates.gzipApplicationRevision` | compress apprev using gzip (good) before being stored. This is reduces network throughput when dealing with huge apprevs. | `false` |
|
||||
| `featureGates.zstdApplicationRevision` | compress apprev using zstd (fast and good) before being stored. This is reduces network throughput when dealing with huge apprevs. Note that zstd will be prioritized if you enable other compression options. | `true` |
|
||||
| `featureGates.preDispatchDryRun` | enable dryrun before dispatching resources. Enable this flag can help prevent unsuccessful dispatch resources entering resourcetracker and improve the user experiences of gc but at the cost of increasing network requests. | `true` |
|
||||
|
||||
|
||||
### MultiCluster parameters
|
||||
@@ -110,7 +111,7 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai
|
||||
| `multicluster.clusterGateway.replicaCount` | ClusterGateway replica count | `1` |
|
||||
| `multicluster.clusterGateway.port` | ClusterGateway port | `9443` |
|
||||
| `multicluster.clusterGateway.image.repository` | ClusterGateway image repository | `oamdev/cluster-gateway` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.4.0` |
|
||||
| `multicluster.clusterGateway.image.tag` | ClusterGateway image tag | `v1.7.0-alpha.3` |
|
||||
| `multicluster.clusterGateway.image.pullPolicy` | ClusterGateway image pull policy | `IfNotPresent` |
|
||||
| `multicluster.clusterGateway.resources.limits.cpu` | ClusterGateway cpu limit | `100m` |
|
||||
| `multicluster.clusterGateway.resources.limits.memory` | ClusterGateway memory limit | `200Mi` |
|
||||
|
||||
@@ -274,6 +274,7 @@ spec:
|
||||
- "--feature-gates=MultiStageComponentApply= {{- .Values.featureGates.multiStageComponentApply | toString -}}"
|
||||
- "--feature-gates=GzipApplicationRevision={{- .Values.featureGates.gzipResourceTracker | toString -}}"
|
||||
- "--feature-gates=ZstdApplicationRevision={{- .Values.featureGates.zstdResourceTracker | toString -}}"
|
||||
- "--feature-gates=PreDispatchDryRun={{- .Values.featureGates.preDispatchDryRun | toString -}}"
|
||||
{{ if .Values.authentication.enabled }}
|
||||
{{ if .Values.authentication.withUser }}
|
||||
- "--authentication-with-user"
|
||||
|
||||
@@ -113,6 +113,7 @@ optimize:
|
||||
##@param featureGates.multiStageComponentApply if enabled, the multiStageComponentApply feature will be combined with the stage field in TraitDefinition to complete the multi-stage apply.
|
||||
##@param featureGates.gzipApplicationRevision compress apprev using gzip (good) before being stored. This is reduces network throughput when dealing with huge apprevs.
|
||||
##@param featureGates.zstdApplicationRevision compress apprev using zstd (fast and good) before being stored. This is reduces network throughput when dealing with huge apprevs. Note that zstd will be prioritized if you enable other compression options.
|
||||
##@param featureGates.preDispatchDryRun enable dryrun before dispatching resources. Enable this flag can help prevent unsuccessful dispatch resources entering resourcetracker and improve the user experiences of gc but at the cost of increasing network requests.
|
||||
##@param
|
||||
featureGates:
|
||||
enableLegacyComponentRevision: false
|
||||
@@ -122,6 +123,7 @@ featureGates:
|
||||
multiStageComponentApply: false
|
||||
gzipApplicationRevision: false
|
||||
zstdApplicationRevision: true
|
||||
preDispatchDryRun: true
|
||||
|
||||
## @section MultiCluster parameters
|
||||
|
||||
@@ -146,7 +148,7 @@ multicluster:
|
||||
port: 9443
|
||||
image:
|
||||
repository: oamdev/cluster-gateway
|
||||
tag: v1.4.0
|
||||
tag: v1.7.0-alpha.3
|
||||
pullPolicy: IfNotPresent
|
||||
resources:
|
||||
limits:
|
||||
|
||||
@@ -94,17 +94,9 @@ var _ = Describe("Test application controller finalizer logic", func() {
|
||||
By("Verify latest app revision is also recorded in status")
|
||||
Expect(checkApp.Status.LatestRevision).ShouldNot(BeNil())
|
||||
|
||||
By("Verify ResourceTracker is created")
|
||||
rt := &v1beta1.ResourceTracker{}
|
||||
Expect(k8sClient.Get(ctx, getTrackerKey(checkApp.Namespace, checkApp.Name, "v1"), rt)).Should(Succeed())
|
||||
|
||||
By("Delete Application")
|
||||
Expect(k8sClient.Delete(ctx, checkApp)).Should(BeNil())
|
||||
testutil.ReconcileOnceAfterFinalizer(reconciler, ctrl.Request{NamespacedName: appKey})
|
||||
|
||||
By("Verify ResourceTracker is deleted")
|
||||
rt = &v1beta1.ResourceTracker{}
|
||||
Expect(k8sClient.Get(ctx, getTrackerKey(checkApp.Namespace, checkApp.Name, "v1"), rt)).Should(util.NotFoundMatcher{})
|
||||
})
|
||||
|
||||
It("Test cross namespace workload, then delete the app", func() {
|
||||
|
||||
@@ -84,6 +84,11 @@ const (
|
||||
// MultiStageComponentApply enable multi-stage feature for component
|
||||
// If enabled, the dispatch of manifests is performed in batches according to the stage
|
||||
MultiStageComponentApply featuregate.Feature = "MultiStageComponentApply"
|
||||
|
||||
// PreDispatchDryRun enable dryrun before dispatching resources
|
||||
// Enable this flag can help prevent unsuccessful dispatch resources entering resourcetracker and improve the
|
||||
// user experiences of gc but at the cost of increasing network requests.
|
||||
PreDispatchDryRun featuregate.Feature = "PreDispatchDryRun"
|
||||
)
|
||||
|
||||
var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
@@ -102,6 +107,7 @@ var defaultFeatureGates = map[featuregate.Feature]featuregate.FeatureSpec{
|
||||
MultiStageComponentApply: {Default: false, PreRelease: featuregate.Alpha},
|
||||
GzipApplicationRevision: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ZstdApplicationRevision: {Default: false, PreRelease: featuregate.Alpha},
|
||||
PreDispatchDryRun: {Default: true, PreRelease: featuregate.Alpha},
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
||||
@@ -18,7 +18,9 @@ package resourcekeeper
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
velaslices "github.com/kubevela/pkg/util/slices"
|
||||
"github.com/pkg/errors"
|
||||
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
@@ -67,15 +69,23 @@ func (h *resourceKeeper) Dispatch(ctx context.Context, manifests []*unstructured
|
||||
if err = h.AdmissionCheck(ctx, manifests); err != nil {
|
||||
return err
|
||||
}
|
||||
// 1. record manifests in resourcetracker
|
||||
if err = h.record(ctx, manifests, options...); err != nil {
|
||||
return err
|
||||
}
|
||||
// 2. apply manifests
|
||||
// 1. pre-dispatch check
|
||||
opts := []apply.ApplyOption{apply.MustBeControlledByApp(h.app), apply.NotUpdateRenderHashEqual()}
|
||||
if len(applyOpts) > 0 {
|
||||
opts = append(opts, applyOpts...)
|
||||
}
|
||||
if utilfeature.DefaultMutableFeatureGate.Enabled(features.PreDispatchDryRun) {
|
||||
if err = h.dispatch(ctx,
|
||||
velaslices.Map(manifests, func(manifest *unstructured.Unstructured) *unstructured.Unstructured { return manifest.DeepCopy() }),
|
||||
append([]apply.ApplyOption{apply.DryRunAll()}, opts...)); err != nil {
|
||||
return fmt.Errorf("pre-dispatch dryrun failed: %w", err)
|
||||
}
|
||||
}
|
||||
// 2. record manifests in resourcetracker
|
||||
if err = h.record(ctx, manifests, options...); err != nil {
|
||||
return err
|
||||
}
|
||||
// 3. apply manifests
|
||||
if err = h.dispatch(ctx, manifests, opts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -528,6 +528,9 @@ var _ = Describe("Test multicluster scenario", func() {
|
||||
g.Expect(app.Status.Phase).Should(Equal(common.ApplicationRunningWorkflow))
|
||||
g.Expect(len(app.Status.Workflow.Steps) > 0).Should(BeTrue())
|
||||
g.Expect(app.Status.Workflow.Steps[0].Message).Should(ContainSubstring("is invalid"))
|
||||
rts := &v1beta1.ResourceTrackerList{}
|
||||
g.Expect(k8sClient.List(hubCtx, rts, client.MatchingLabels{oam.LabelAppName: app.Name, oam.LabelAppNamespace: app.Namespace})).Should(Succeed())
|
||||
g.Expect(len(rts.Items)).Should(Equal(0))
|
||||
}, 20*time.Second).Should(Succeed())
|
||||
Expect(k8sClient.Delete(ctx, app)).Should(Succeed())
|
||||
Eventually(func(g Gomega) {
|
||||
|
||||
Reference in New Issue
Block a user