-
Notifications
You must be signed in to change notification settings - Fork 250
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
[Proposal] Change Component to be an instance, not schema #281
Comments
Hi folks, I'm the tech lead for Crossplane core. I'm currently thinking about how Crossplane might function as an OAM runtime, and what changes to the OAM spec (if any) might help enable that. I'm wondering whether this proposal would change how runtimes render and process OAM configuration. My Rust is terrible, but my understanding is that in Rudr we build the Kubernetes configuration necessary to deploy an application by:
Or put otherwise, nothing happens if I only create a Do I understand correctly that the problem this proposal describes is that because no controller is watching for Is the idea that by reframing |
Hi @negz . Great to hear from you!
In fact, we don't edit ComponentSchematic, but create a new ComponentSchematic.
No. But Component as an instance of Workload.
Yes.
No. Component is a subsidiary resource of ApplicationConfig. The runtime controller needs to watch ApplicationConfig to understand the whole picture and plan for the work (e.g. canary rollout, traffic split). |
Glad to hear from you @negz! This PR is needed because currently OAM "Hey, I already have a KubernetesApplication, can I leverage OAM Component to define a similar but more generic CrossplaneApplication without big change in my current logic?" This may not be so explicit, so I've already tried to draft an illustrated version of proposal and will share it to you tomorrow. |
Thanks for the fast reply @hongchaodeng!
Ah, that's useful thank you.
This seems sensible to me, but it also raises more questions about this proposal. :) It seems that a Component alone is insufficient to build the information needed to deploy an application - we need the ApplicationConfig and any Traits it references as well. Given this, it seems like we don't really want a controller watching for Component and reconciling purely the information stored in each Component that changes, but instead a controller that watches for Component and queues a reconcile of the ApplicationConfig to which that Component belongs. So not "reconcile this Component if it changes", but "reconcile this ApplicationConfig if it or any of its referenced Components change". Would this require a reference back from each Component to the ApplicationConfig to which it belongs? One thing I like about the current I wonder if there is a solution that retains the ability for the application developer to publish a sane set of defaults, and allows the application owner to override them (including the image version) in a fashion that is more CRD-compatible. Perhaps something like this: apiVersion: core.oam.dev/v1alpha1
kind: ComponentSchematic
metadata:
name: frontend
annotations:
description: >
Sample schematic that describes the administrative interface for our Twitter bot.
spec:
workloadType: core.oam.dev/v1alpha1.Server
osType: linux
containers:
- name: my-twitter-bot-frontend
image:
name: example/my-twitter-bot-frontend:latest
resources:
cpu:
required: 1.0
memory:
required: 100MB
ports:
- name: http
value: 8080
env:
- name: USERNAME
- name: PASSWORD
- name: BACKEND_ADDRESS
livenessProbe:
httpGet:
port: 8080
path: /healthz
readinessProbe:
httpGet:
port: 8080
path: /healthz apiVersion: core.oam.dev/v1alpha1
kind: Component
metadata:
name: cool-frontend
annotations:
version: v1.0.0
spec:
schematicRef:
name: frontend
containers:
- name: my-twitter-bot-frontend
image:
name: example/my-twitter-bot-frontend:v1.0.0
env:
- name: USERNAME
value: cooladmin
- name: PASSWORD
value: verysecret
- name: BACKEND_ADDRESS
value: https://example.org kind: ApplicationConfiguration
metadata:
name: coolest-app
spec:
components:
- componentRef:
name: cool-frontend
traits:
- name: ingress
- name: monitoring In this scenario:
Under this model all schema definition is left to CRDs - CRs only specify values - but the application developer still gets to specify a set of default values for their component, and the application operator still gets to override those default values. |
Hi @negz . That's a very thoughtful discussion.
I think this could be an implementation detail (e.g. reverse index). Regarding the
This is the problem of managing and passing parameters. And we can resolve it with tools like Helm template, Kustomize, etc. By asking developers to write Component instance, we defer such responsibility to external tools. For example, dev writes a Component: apiVersion: core.oam.dev/v1alpha1
kind: Component
metadata:
name: cool-frontend
annotations:
version: v1.0.0
spec:
containers:
- name: my-twitter-bot-frontend
image:
name: example/my-twitter-bot-frontend:v1.0.0
env:
- name: USERNAME
value: {{ .Values.Username | default "a" }}
- name: PASSWORD
value: {{ .Values.Password | default "b" }} Under this model CRD -> Workload, CR -> Component. Application developers and operators convey parameters and default values via external tools like Helm or Kustomize. What you described above looks right to me, but at this stage we could reduce schema layers (combine ComponentSchematic into Workload) and give users a minimal spec to setup. |
Are you saying that in a Kubernetes based implementation |
This one |
I think this issue could be closed now |
Yeah. This is already done in alpha2. |
Problem description
Problem 1: Upgrading Application requires writing another Component
Currently the container image is hard-coded in ComponentSchematic. Each time a new version of the application needs to rollout, we need to write a new ComponentSchematic and update ApplicationConfiguration simultaneously. This combination of work is complex. We heard complains from our users often, and has raised issue #265. We want to let developers define only one component and update image in one place.
Problem 2: Mapping existing Application definition to OAM is not intuitive
Many existing projects (both open source and internally) have defined Application schema and done deployment with instances of Application. For examples:
The current model having Component as another schema on top of Workload as a schema doesn't fit well for these real world cases.
Proposal
There are two issues in OAM that we want to improve:
Walkthrough
Let me give a concrete example. Let's say I have defined a WorkloadType AlibabaService:
Then deploy a Component:
While it might look the same up until now, the key change happens when we write ApplicationConfiguration:
As described above, Component becomes an instance itself, and ApplicationConfiguration references instances of Components.
What's changed here is that previously we asked developers how to describe the app, but now we ask them what to deploy. This brings us the following benefits:
This better resembles the use cases we have been encountering and solves those problems that users asked.
How it solves above problems?
Problem 1: Since component is an instance now, updating image would trigger correlated deployments to be updated as well.
Problem 2: Application CRD could be modeled as WorkloadType and Application CR could be modeled as Component. This would intuitively map existing use cases to OAM.
The text was updated successfully, but these errors were encountered: