共享资源

    在 KubeVela 中,默认情况下,应用拥有资源。 这意味着应用创建的资源只能由创建它的应用控制。

    所以应用创建资源基本上有两个要求:

    1. 资源在应用创建它之前不能存在。如果存在,会出现资源冲突错误。
    2. 资源期望只能通过其创建者进行管理。 其他人 不应该修改或编辑它。

    调度资源时,应用将

    1. 检查资源是否存在。 如果存在,检查它的标签。 如果 和 app.oam.dev/namespace 等于应用的 name 和 namespace,则表示该资源之前是由同一个应用创建,现在调度操作将变为更新操作。 这两个标签标识资源的所有者。
    2. 如果资源存在,但未找到标签,则该资源是在应用之前创建。 这时候应用会报资源冲突错误。
    3. 如果资源存在,并且标签指向另一个应用,则该资源由其他应用管理。 这时候当前应用也会报资源冲突错误。

    通过这些检查,不同的应用不能管理相同的资源。

    但是,也有不满足这两个要求的场景。 其中一种场景是在不同的应用程序之间共享。

    例如,每个应用都想创建一个 ConfigMap,但它们的 ConfigMap 是相同的。

    当一个资源被创建为共享资源时,一个特殊的注解 app.oam.dev/shared-by 将被添加到资源中。 它将按时间顺序记录资源的 sharer。 首先创建资源的应用会将资源的所有者标签设置为应用自己。

    然后它将自己添加到 sharer 注解中。

    当另一个应用想要共享资源时,它会检查资源是否可共享,即 sharer 注解中至少有一个共享者。

    如果它是可共享的,它会将自己添加到 sharer 注解中,但不会修改资源的内容。

    通过这种机制,只有资源的所有者才能修改资源(包括更新和状态保持)。其他共享者只能看到该资源。

    当资源的所有者不在时(应用被删除或不再使用此资源),会把所有者交给下一个共享者。 如果没有其他共享者,它将最终删除该资源。

    shared-resource-2

    1. apiVersion: core.oam.dev/v1beta1
    2. kind: Application
    3. metadata:
    4. name: app2
    5. spec:
    6. components:
    7. - name: ns2
    8. objects:
    9. - apiVersion: v1
    10. kind: Namespace
    11. metadata:
    12. name: example
    13. - name: cm2
    14. type: k8s-objects
    15. properties:
    16. objects:
    17. - apiVersion: v1
    18. kind: ConfigMap
    19. name: cm2
    20. namespace: example
    21. data:
    22. key: value2
    23. policies:
    24. - name: shared-resource
    25. type: shared-resource
    26. properties:
    27. rules:
    28. - selector:
    29. resourceTypes: ["Namespace"]

    上述两个应用将分派相同的命名空间“example”。 他们将分别在命名空间“example”内创建两个不同的 ConfigMap。

    两个应用使用共享资源策略并将命名空间资源声明为共享。 这样创建同一个命名空间就不会有冲突了。 如果不使用共享资源策略,则第二个应用在发现命名空间“example”由第一个应用管理后会报错。

    只有当两个应用都删除时,命名空间才会被回收。

    1. 当多个应用共享同一个资源时,创建它的第一个应用程序可以更新其内容。 其他应用无法修改。 一旦第一个应用不再使用它(例如,第一个应用被删除),那么第二个应用将成为所有者,这意味着它现在可以修改资源的内容。 这不会立即生效。 但是发生 StateKeep 或者应用重新运行其工作流(例如,它被更新)时,它会将资源内容设置为其所需的状态。