New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feat: support sharding in controller #5360
Conversation
Codecov ReportBase: 61.20% // Head: 49.29% // Decreases project coverage by
Additional details and impacted files@@ Coverage Diff @@
## master #5360 +/- ##
===========================================
- Coverage 61.20% 49.29% -11.92%
===========================================
Files 308 313 +5
Lines 46778 47018 +240
===========================================
- Hits 28631 23177 -5454
- Misses 15189 21402 +6213
+ Partials 2958 2439 -519
Flags with carried forward coverage won't be shown. Click here to find out more.
Help us with your feedback. Take ten seconds to tell us how you rate us. Have a feature suggestion? Share it here. ☔ View full report at Codecov. |
6563179
to
c6ea212
Compare
pkg/controller/sharding/scheduler.go
Outdated
return "", false | ||
} | ||
// nolint | ||
return available[rand.Intn(len(available))], true |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advice uses Round Robin as the default schedule rule.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't prefer the schedule algorithm, but do we expose metrics of how many applications the controller is handling? This is important.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is exposed by the standard metrics endpoint in Prometheus format. We need to add support for the Grafana to collect them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Advice uses Round Robin as the default schedule rule.
Added to the dynamicDiscoveryScheduler. The staticDiscoveryScheduler will use random still.
We need to discuss the failover case and best configuration:
Another question is, what will happen if one user delete the sharding label while the application is already in running state? |
charts/vela-core/README.md
Outdated
@@ -153,6 +153,8 @@ helm install --create-namespace -n vela-system kubevela kubevela/vela-core --wai | |||
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` | | |||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` | | |||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` | | |||
| `sharding.enabled` | Enable sharding for core controller | `false` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should the default value to be true?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Currently no. If the default value set to be true, then when no shards added, application will not be handled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Behaviour changed. Master shard by default accept applications now.
02bf96b
to
b0861c3
Compare
d00e196
to
be07a8b
Compare
b0243a9
to
55f796b
Compare
55f796b
to
294e881
Compare
| `authentication.withUser` | Application authentication will impersonate as the request User | `true` | | ||
| `authentication.defaultUser` | Application authentication will impersonate as the User if no user provided in Application | `kubevela:vela-core` | | ||
| `authentication.groupPattern` | Application authentication will impersonate as the request Group that matches the pattern | `kubevela:*` | | ||
| `sharding.enabled` | When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details. | `false` | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
user did not enable sharding, when install vela. After that, if user need enable it in order to manage more apps, can user enable sharding?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, user can use helm upgrade --set sharding.enabled
to enable it. But he needs to use vela up --shard-id
command to manually schedule the original applications to master
shard.
|
||
## @param sharding.enabled When sharding enabled, the controller will run as master mode. Refer to https://github.com/kubevela/kubevela/blob/master/design/vela-core/sharding.md for details. | ||
## @param sharding.schedulableShards The shards available for scheduling. If empty, dynamic discovery will be used. | ||
sharding: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can vela install
command install kubevela with sharding enabled?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
@@ -272,6 +299,7 @@ func NewUpCommand(f velacmd.Factory, order string, c utilcommon.Args, ioStream u | |||
cmd.Flags().StringVarP(&o.File, "file", "f", o.File, "The file path for appfile or application. It could be a remote url.") | |||
cmd.Flags().StringVarP(&o.PublishVersion, "publish-version", "v", o.PublishVersion, "The publish version for deploying application.") | |||
cmd.Flags().StringVarP(&o.RevisionName, "revision", "r", o.RevisionName, "The revision to use for deploying the application, if empty, the current application configuration will be used.") | |||
cmd.Flags().StringVarP(&o.ShardID, "shard-id", "s", o.ShardID, "The shard id assigned to the application. If empty, it will not be used.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If vela is installed with sharding mode, which controller will manage the Applications without label controller.core.oam.dev/scheduled-shard-id
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No controller will handle those applications. Those ones need to be scheduled through vela up --shard-id
(provided in this PR) or customized scheduler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
294e881
to
1a9cd2e
Compare
.github/workflows/apiserver-test.yml
Outdated
run: make end-e2e-core | ||
run: | | ||
make end-e2e-core | ||
CORE_NAME=kubevela-shard sh ./hack/e2e/end_e2e_core.sh |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since end-e2e-core
is a makefile target, It'd be better if we wrap CORE_NAME=kubevela-shard sh ./hack/e2e/end_e2e_core.sh
into another one to keep style here consistent.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
add make end-e2e-core-shards
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
* Feat: bootstrap sharding Signed-off-by: Somefive <yd219913@alibaba-inc.com> * Chore: refactor end-e2e-core-shards script Signed-off-by: Somefive <yd219913@alibaba-inc.com> --------- Signed-off-by: Somefive <yd219913@alibaba-inc.com>
Signed-off-by: Somefive yd219913@alibaba-inc.com
Application Controller Sharding
Background
As many adopters start to choose KubeVela to manage thousands of Applications in production, the performance issue becomes increasingly critical.
The typical Kubernetes controller usually run one controller to manage all related custom resources. The operator reconciliation is designed to be relatively lightweight. In KubeVela, to support customized delivery process and manage lifecycles of tens of resources in one application makes the reconciliation process heavier compared to typical controllers.
Although multiple replicas of KubeVela controller could provide high availability, in avoid of multiple concurrent reconciliation for the same application (which could lead to conflict problems), only one replica could work and this is achieved by acquiring the same leader-election lock.
So usually, users add more resources to KubeVela controller (more CPUs, Memory...) and set up more threads and larger rate limiter to support more applications in the system. This can lead to potential problems in different cases:
Therefore, this KEP proposes to support dividing a single large KubeVela controller into multiple small application controllers for run.
Proposal
When running with
--enable-sharding
arg in KubeVela core controller, the KubeVela core controller will run in sharding mode.--shard-id
arg is set tomaster
, this one will run in master mode.--shard-id
arg is set to some other value, likeshard-0
, this one will run in slave mode.master mode
The master mode will enable all the controllers, such as ComponentDefinitionController, TraitDefinitionController, ApplicationController, Webhooks, etc.
The application controller will only handle applications with the label
controller.core.oam.dev/scheduled-shard-id: master
, and only the applications, applicationrevisions and resourcetrackers that carries this label will be watched and cached.By default, it will watch the pods within the same namespace as it runs. The pods with labels
app.kubernetes.io/name: vela-core
and carriescontroller.core.oam.dev/shard-id
label key will be selected and their health status will be recorded. The selected ready pods will be registered as schedulable shards. The mutating Webhook will automatically assign shard-id for non-assigned applications when requests come in.slave mode
The slave mode controller will only start the ApplicationController and will not enable others like Webhook or ComponentDefinitionController. It is dedicated to applications that carries the matched labels
controller.core.oam.dev/scheduled-shard-id=<shard-id>
.Example
First, install KubeVela with sharding enabled. This will let the KubeVela core controller deployed in master mode.
Second, deploy slave mode application controller.
There are different ways to do it.
vela addon enable vela-core-shard-manager nShards=3
. Supported by [Addon] vela core shard manager catalog#606kubectl get deploy kubevela-vela-core -oyaml -n vela-system | sed 's/schedulable-shards=/shard-id=shard-0/g' | sed 's/instance: kubevela/instance: kubevela-shard/g' | sed 's/shard-id: master/shard-id: shard-0/g' | sed 's/name: kubevela/name: kubevela-shard/g' | kubectl apply -f -
This will create a copy of the master vela-core and run a slave replica with shard-id as shard-0.Future Work
This Webhook implemented will only schedule applications when
controller.core.oam.dev/scheduled-shard-id
label).So it cannot handle re-schedule scenario and cannot make automatic scheduling for previous application.
For the next step, we can support:
vela up <app-name> --shard-id <shard-id>
Use vela CLI to help user manually reschedule application. NOTE: reschedule application not only need to reset the label of that application but also need to reset the labels of related applicationrevisions and resourcetrackers.DisableAutoSchedule
for the case where user wants to disable the automatic schedule for the mutating webhook.Extend Usage
kubevela/pkg
if later we find it also helpful for other controller likekubevela/workflow
.Tech Details
ConfigMap
(used by Workflow Context) are not divided.publish-version
is set in application, but since ApplicationRevision is sharded, therefore the cache of the vela-core in master mode will not hold the ApplicationRevision. So here we use native Kubernetes API request to read ApplicationRevision. This may lead to performance drop for validating webhook and this is disabled by default when sharding enabled.FAQ
Q: What will happen when the master one is down?
A: If the webhook is enabled, the webhook will be down if the master one is down. Then the mutating webhook and validating webhook will fail so no new application creation or change will be accepted. Old applications that are scheduled to master will not be processed anymore. Others that are scheduled to other shards will not be affected. If the webhook is not enabled, then only applications scheduled to master shard will be affected. Users can still create or change applications in this case.
Q: What will happen when a slave mode controller is down?
A: For applications that are not scheduled to that shard, nothing will happen. For applications that are scheduled to the broken shard, succeeded applications will not run state-keep or gc but the delivered resources will not be touched. For applications that are still running workflow, they will not be handled but can be recovered instantly when the controller is restarted.
Q: What will happen if one user delete the sharding label while the application is already in running state?
A: If the webhook is enabled, this behaviour will be prevented. The sharding label will inherit the original one. If the webhook is not enabled, the application will not be handled anymore (no state-keep, no gc and no update).
I have:
make reviewable
to ensure this PR is ready for review.backport release-x.y
labels to auto-backport this PR if necessary.