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

Document how to approach abstraction #3288

Open
bgrant0607 opened this issue Jun 4, 2022 · 1 comment
Open

Document how to approach abstraction #3288

bgrant0607 opened this issue Jun 4, 2022 · 1 comment
Labels
area/site documentation Improvements or additions to documentation enhancement New feature or request triaged Issue has been triaged by adding an `area/` label

Comments

@bgrant0607
Copy link
Contributor

Another reminder for myself, after discussing with @johnbelamaric.

Related to #3145, #3131, #2528

In kpt, packages are transparent bundles of resources that can be introspected and operated upon. They may CONTAIN resources (in-cluster or local) that represent abstractions, but they do not HAVE abstractions as a whole. Packages are not encapsulated. No parameter-based interfaces. WYSIWYG.

Some alternatives to abstraction are discussed in #3145. Thin abstractions get in the way, preventing standard resource-type-aware tools from interoperating on the configuration data. Just eliminating boilerplate and formatting YAML is not enough -- those could be done easily enough by GUIs, CLIs, and IDEs. Most parameterized attributes in off-the-shelf templates are just single attributes.

In order to carry its own weight, an abstraction needs to provide high leverage, such as a 10x or more expansion factor -- that is, the output is 10x larger than the inputs. Small percentages and even small factors rarely pay off. Some example platform interfaces have had expansion factors as high as 30x. This is a reasonable example, with 15x expansion:
https://medium.com/pinterest-engineering/building-a-kubernetes-platform-at-pinterest-fb3d9571c948

High-leverage, durable abstractions that are resistant to erosion are often hard to design. They require specializing on particular use cases, requirements, assumptions, and so on. Simplicity and flexibility are opposing requirements.

Consequently, one tactic to mitigate abstraction erosion is to be willing to create multiple targeted abstractions rather than attempt to make a single abstraction flexible enough to handle multiple use cases. The Kubernetes workload APIs (ignoring the PodTemplate part - issues.k8s.io/170) are an example: ReplicaSet, Deployment, StatefulSet, DaemonSet, Job, CronJob.

Where there are cases of high fan-out or fan-in of information sources and targets, optionality can be reduced by decoupling producers and consumers. Service discovery or DNS are an example: IP addresses can be allocated by a variety of producers and discovered and consumed by a variety of clients, interacting through the standardized naming layer.

Interfaces can also be partitioned to separate concerns. The "claim" model in Kubernetes uses this approach. PersistentVolumeClaims represent a subset of PersistentVolume information, referring indirectly to a set of desired attributes using StorageClass. gateway-api.sigs.k8s.io, oam.dev and Crossplane compositions use similar models to partition and amortize complexity. Even Service and Deployment are an example of separation of concerns.

Automation can enable higher-level abstractions, by filling in details of lower-level abstractions through reactive, predictive, or ML-based techniques. Autoscaling is the canonical example.

This list is not exhaustive.

Each input to a high-leverage abstraction ideally should be put to many uses. The highest-leverage piece of information is the identity of the abstraction itself, and it should enable many assumptions to be made about the desired state being requested.

@bgrant0607 bgrant0607 added documentation Improvements or additions to documentation enhancement New feature or request labels Jun 4, 2022
@bgrant0607 bgrant0607 self-assigned this Jun 4, 2022
@bgrant0607
Copy link
Contributor Author

I neglected to say that abstractions should be defined using custom resources, either actually defined server-side using CRDs, or local/client-side. We'll need a registry for client-side CRDs.

When to use one or the other? Package orchestration blurs the lines regarding what types of client surfaces and automation are possible with client-side abstractions, but there are some situations where one approach or the other is more suitable.

Client-side / local is:

  • Easier to customize and extend, and amenable to more customization strategies
  • More transparent -- the output can be pre-validated, reviewed, and approved

Use server-side when you want to:

  • Encapsulate the generation logic and restrict further customization
  • Support multiple runtime client surfaces
  • Support real-time automation on top of the abstraction that uses runtime state information
  • Control external resources as well

And when change control, versioning, and rollback of generated resources are not needed.

@mortent mortent added this to ToDo in kpt kanban board Jun 8, 2022
@mortent mortent added area/site triaged Issue has been triaged by adding an `area/` label labels Jan 26, 2023
@bgrant0607 bgrant0607 removed their assignment Mar 30, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/site documentation Improvements or additions to documentation enhancement New feature or request triaged Issue has been triaged by adding an `area/` label
Projects
Development

No branches or pull requests

2 participants