Skip to content
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 shared-resource policy #4213

Merged
merged 1 commit into from Jun 24, 2022

Conversation

Somefive
Copy link
Collaborator

@Somefive Somefive commented Jun 21, 2022

Signed-off-by: Somefive yd219913@alibaba-inc.com

Description of your changes

Background

In KubeVela, by default, application owns resources.
It means that resources create by the application should only be controlled by the application that creates it.

So there are basically two requirements for application creating resources:

  1. The resource must not exist before the application creating it. It exists, there will be a resource conflict error.
  2. The resource is expected to be only manageable through its creator. "Others" should not be able to modify it or edit it.

While dispatching resources, the application will

  1. Check if resource exists. If exists, check its labels.
    If "app.oam.dev/name" and "app.oam.dev/namespace" equals to the application's name and namespace, it means this resource is previously created by the same application and the dispatching operation now will become an update operation.
    The two labels identify the owner of the resource.
  2. If resource exists, but no label found, then this resource is created before this application. At this time, the application will report a resource conflict error.
  3. If resource exists, and the labels point to another application, then this resource is managed by other applications. At this time, the current application will also report a resource conflict error.

With these checks, different applications cannot manage the same resource.

Usage

However, there are scenarios that these two requirements are not met. One of the scenarios is sharing across different Applications.
For example, each application wants to create a ConfigMap, but their ConfigMaps are the same.

To achieve that, KubeVela application could utilize the shared-resource policy to make it possible.

create

When one resource is created as sharing resource, one special annotation app.oam.dev/shared-by will be added to the resource.
It will record the "sharer" of the resource in time order. The application that firstly creates the resource will set its owner labels to itself.
Then it will add itself to the sharer annotation.

share

When another application comes and wants to share the resource, it will check if the resource is sharable, aka there is at least one sharer in the sharer annotation.
If it is sharable, it will add itself to the sharer annotation, but not modify the content of the resource.

delete

With this mechanism, only the owner of the resource can modify the resource (including updating and state-keeping). Other sharer can only see that resource.
When the owner of the resource is gone (application is deleted or do not use this resource anymore), it will give the owner of the application to the next sharer. If no sharer exists, it will finally delete that resource.

See the following figures for details.

image
image

Example

apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: app1
spec:
  components:
    - name: ns1
      type: k8s-objects
      properties:
        objects:
          - apiVersion: v1
            kind: Namespace
            metadata:
              name: example
    - name: cm1
      type: k8s-objects
      properties:
        objects:
          - apiVersion: v1
            kind: ConfigMap
            metadata:
              name: cm1
              namespace: example
            data:
              key: value1
  policies:
    - name: shared-resource
      type: shared-resource
      properties:
        rules:
          - selector:
              resourceTypes: ["Namespace"]
apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
  name: app2
spec:
  components:
    - name: ns2
      type: k8s-objects
      properties:
        objects:
          - apiVersion: v1
            kind: Namespace
            metadata:
              name: example
    - name: cm2
      type: k8s-objects
      properties:
        objects:
          - apiVersion: v1
            kind: ConfigMap
            metadata:
              name: cm2
              namespace: example
            data:
              key: value2
  policies:
    - name: shared-resource
      type: shared-resource
      properties:
        rules:
          - selector:
              resourceTypes: ["Namespace"]

The above two applications will dispatch the same namespace "example".
They will create two different ConfigMap inside namespace "example" respectively.

Both application use the shared-resource policy and declared the namespace resource as shared.
In this way, there will be no conflict for creating the same namespace.
If the shared-resource policy is not used, the second application will report error after it finds that the namespace "example" is managed by the first application.

The namespace will only be recycled when both applications are removed.

I have:

  • Read and followed KubeVela's contribution process.
  • Related Docs updated properly. In a new feature or configuration option, an update to the documentation is necessary.
  • Run make reviewable to ensure this PR is ready for review.
  • Added backport release-x.y labels to auto-backport this PR if necessary.

How has this code been tested

Special notes for your reviewer

@Somefive Somefive marked this pull request as draft June 21, 2022 09:53
@codecov
Copy link

codecov bot commented Jun 21, 2022

Codecov Report

Merging #4213 (7da8752) into master (e10928d) will increase coverage by 2.18%.
The diff coverage is 89.92%.

@@            Coverage Diff             @@
##           master    #4213      +/-   ##
==========================================
+ Coverage   58.11%   60.30%   +2.18%     
==========================================
  Files         327      334       +7     
  Lines       32130    32366     +236     
==========================================
+ Hits        18672    19517     +845     
+ Misses      11003    10309     -694     
- Partials     2455     2540      +85     
Flag Coverage Δ
apiserver-unittests 34.88% <0.00%> (-0.02%) ⬇️
core-unittests 55.07% <86.82%> (+0.08%) ⬆️
e2e-multicluster-test 20.35% <79.84%> (?)
e2e-rollout-tests 22.10% <19.37%> (-0.04%) ⬇️
e2etests 29.18% <36.43%> (+0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
pkg/appfile/parser.go 58.72% <50.00%> (+7.47%) ⬆️
pkg/resourcekeeper/resourcekeeper.go 69.69% <50.00%> (-4.50%) ⬇️
pkg/resourcekeeper/gc.go 76.95% <68.42%> (-0.41%) ⬇️
pkg/utils/apply/apply.go 87.07% <89.74%> (+1.12%) ⬆️
apis/core.oam.dev/v1alpha1/garbagecollect_types.go 100.00% <100.00%> (ø)
apis/core.oam.dev/v1alpha1/policy_types.go 100.00% <100.00%> (ø)
pkg/policy/common.go 100.00% <100.00%> (ø)
pkg/resourcekeeper/cache.go 95.34% <100.00%> (+1.40%) ⬆️
pkg/resourcekeeper/dispatch.go 76.92% <100.00%> (+0.92%) ⬆️
pkg/resourcekeeper/statekeep.go 48.97% <100.00%> (+3.32%) ⬆️
... and 59 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e10928d...7da8752. Read the comment docs.

@Somefive Somefive force-pushed the feat/shared-resource branch 7 times, most recently from f69a534 to 6cfef72 Compare June 22, 2022 09:08
@Somefive Somefive marked this pull request as ready for review June 22, 2022 09:17
@Somefive Somefive force-pushed the feat/shared-resource branch 2 times, most recently from f641cfd to 50c835d Compare June 22, 2022 13:14
@Somefive Somefive force-pushed the feat/shared-resource branch 2 times, most recently from 1eee997 to 87f0631 Compare June 23, 2022 08:49
Signed-off-by: Somefive <yd219913@alibaba-inc.com>
@@ -53,3 +57,23 @@ type OverridePolicySpec struct {
Components []EnvComponentPatch `json:"components,omitempty"`
Selector []string `json:"selector,omitempty"`
}

// SharedResourcePolicySpec defines the spec of shared-resource policy
type SharedResourcePolicySpec struct {
Copy link
Collaborator

Choose a reason for hiding this comment

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

You should create the definition for this policy.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

shared-resource is an advanced feature. Let's reserve the creation of the policy definition in the future. (Another Issue will be launched for this.)

@Somefive Somefive deleted the feat/shared-resource branch June 20, 2023 13:31
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.

None yet

3 participants