-
Notifications
You must be signed in to change notification settings - Fork 861
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
[Feature] Support for explicit versioning of definitions #6435
Comments
I'll admit I've not a great understanding of the CRD alpha/beta/v1 versioning - by which I mean how does the consumer identify breaking/non-breaking changes, patches etc? Using it would obviously be "the kubernetes way". @linaking-guidewire, care to pitch in here with a description and case for using that over semver 🙂 ? |
I also like the idea of using CRD version like v1alpha, which probably gives us the space to add migration func from v1 to v2. |
So @FogDong / @linaking-guidewire I get how v1alpha/v1beta/v1 works when taking a new definition through concept to full "v1" implementation. But how does this work if we are adding a new feature to an already out there definition? For example say I want to add a new feature to the cpuscaler trait to support scaleDown/scaleUp policies. In semver world this would lead to a minor version bump e.g. to v1.1.0 - or if the implementation leads to a breaking change it might be v2.0.0. How would this scenario be handled under v1alpha/v1beta/v1 approach? (genuine question, this is where I don't understand this approach). |
I see components as being managed products by a platform engineering team with the promise that they can abstract away infrastructure details, encapsulate some policies, etc. Kubernetes standard interface allows to nicely decouple Platform Eng and users workflow. For example doing a rolling restart/upgrade of Kubernetes nodes should not impact user workload availability and does not require synchronisation between teams. With KubeVela we would like to retain this separation of concerns, and I feel components are kind in the way without this feature. IMHO it would be ideal if Platform Eng could progressively rollout new component versions, for example by doing a progressive patching of all Application using the component(s) to update, |
Thanks @fboismenu . I'm mostly in agreement on your points. One thing I'd like to note though is the proposal here to allow rollout of new definition versions (my emphasis). I think this is a good feature but would need to be optional, I wouldn't favour it being done automatically. I get it might be a good idea in dev, but would not want to do a bulk upgrade in prod, it would be akin to using If it is possible and if we choose semver, it should not allow bulk upgrade to a new major version number - the point of this in semver is that a major version number indicates a breaking (or at least very significant) change, and istm this should require review by teams. Whilst a minor or patch version update is intended to be non-breaking there's no guarantees so personally I wouldn't see even just a patch version increment as a green light to bulk auto-upgrade a definition, I'd want to choose to do that, but I don't see a problem with it being an optional approach for those that want it. Thoughts anyone? |
I agree that versioning is an optional setting for definitions. In semantic versioning, bumping the major version usually means there's a big change that could break things. Our current setup automatically increases the version with each update, and we're only tracking the major version at this point. To keep things smooth for KubeVela users, we're saying that a major version increase won't be a breaking change that requires manual intervention. In practice, updating definitions often just means adding a few new fields, which doesn't cause any disruption. This suggests that the typical approach should be to update the minor version—it's not as critical as changes to CRDs. Given this, I think semantic versioning could be a better fit for versioning our definitions. |
Semver is fine as long as we support specifying ranges, but I do think the Kubernetes API versioning would be a more standard approach for this case - "the Kubernetes way" as you mentioned @Kolossi. |
I like the proposal, but have some doubts on the options that are being proposed. In terms of calling component versions I think adding the version as proposed by @Kolossi will provide a user friendly approach for users deploying applications. To add an example of what I am understanding that would be: apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-with-comp-versioning
spec:
components:
- name: backend
type: my-component-type@1.0.2 However, from the component definition side of things, and linking with @FogDong comment, we should also define where the version will be specified. Should we add an optional annotation such as apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
name: <ComponentDefinition name>
annotations:
definition.oam.dev/description: <Function description>
# Option 1: using annotations
definition.oam.dev/version: <semver>
spec:
#Option 2: modifying the spec
version: <semver>
workload: # Workload Capability Indicator
definition:
apiVersion: <Kubernetes Workload resource group>
kind: <Kubernetes Workload types>
schematic: # Component description
cue: # Details of components defined by CUE language
template: <CUE format template> |
I have been giving this a second tough, and I have a doubt regarding the expected use case. Are we considering the possibility of having to versions of the same component available in the cluster? or is this just to enforce the fact that an application could only be deployed with a specific subset of component versions? @Kolossi which is the use you have in mind for this feature? The main problem I see if we need to store two component definitions in the cluster at the same time is the naming of the CRDs, as it may require having a name for the CRD entity (e.g., |
Thanks for reminding me about this @dhiguero, I've got sidetracked lately. Yes the scenario you have raised - of having multiple versions of the same definition (might be component, trait etc) - is what I'm after. When using custom traits there's the usual same SDLC scenarios of issuing patches, enhancements, breaking changes but whilst not wanting to break existing items. I'm still very curious as to how the alpha/beta/v1 proposal addresses this and no-one's posted how this could work? |
Thanks for this proposal!
I personally agree with @fboismenu most. And I don't really care in which way we name the version, whatever it's semantic versioning or CRD alpha/beta/v1 versioning, they're actually tags which shouldn't be aware by app developers, they should be handled by platform builders internally. The question here is how we can make it, a rolling upgrade for definition version. My proposal should be adding an annotation on App automatically and let the annotation to specify the real version. apiVersion: core.oam.dev/v1beta1
kind: Application
metadata:
name: app-with-comp-versioning
annotations:
oam.definition.versioning: "my-component-type@1.0.2, my-foo-def@v0.1.0"
spec:
components:
- name: backend
type: my-component-type
- name: frontend
type: my-foo-def Kubevela webhook can check extra rollout policy to add this kind of annotations automatically, other systems or users can also have the flexibility to specify it. I personally think we'd better avoid deign the versioning feature to be too complex, it should be the platform builders capability to maintain the compatibility, or they can invent a new definition name. That means we shouldn't support fancy feature like "type: >wb-service@v1.2". |
IMHO auto update should never be the default, particularly in live. If others want it then fine let them as an option but I wouldn't want to see auto update being the default behaviour - and definitely not the only behaviour! Aside from that I'd still like to see the worked-through scenario of how anyone thinks name, version number and update process will work in alternate proposed approaches in the case of
How will the numbering/naming work? My proposal is:
Using the above I don't personally see the need for the > syntax, the exact version should be specified otherwise it's just a version of the docker ":latest" tag problem. It seems to me that from what you've said @wonderflow your proposal would be the following, but please repost exactly what you mean not my words :-)
Thoughts @dhiguero @FogDong @wonderflow @linaking-guidewire ? |
Yes, thanks @Kolossi for explanation, you fully get what I mean, while the app developer still has a chance to define the version through annotation by their own if they prefer. |
Ah ok, so if I understand, your proposal to auto-update only applies if the developer has not specified a version number. In this case they would get patch and new feature changes automatically, but not breaking changes (because component name has to be changed in application definition)? If so, there's logic in that but that's essentially what we have at the moment, and having to have seperate component names with major versions in them was one thing this proposal was trying to address. However another key one was the ability of the definition author to determine the applicable version number as opposed to the auto-increment numbering provided at present. Whilst I'd prefer the semver approach (you got that, right? ;-) ) if we only added the ability for definition author to explicitly set the feature/patch version that would be of great benefit IMHO. |
@Kolossi , yes, you have fully got my point. Just go ahead with semver. |
Hey @Kolossi @wonderflow I would love to look into this issue. Can you tell me some prerequisites to tackles this.And where, we can discuss about it. Thanks ! |
Dear @FogDong I am looking forward to work on this issue during LFX mentorship program in your guidance and Support. Thank You. |
@Kolossi Thanks for the detail explanation, I like the idea of using semver to distinguish the minor patch and break change. For anyone who's interested in this issue for LFX, feel free to discuss with the community in Slack Kubevela channel and DM me in Slack, my id is FogDong. |
Good proposal and the fact we can specify the versions as annotations in the application is very much needed. In addition to this, I propose that we include a vela core configuration at the cluster level, which would specify the preferred versions for that specific cluster. And versions would be used in this order of precedence:
|
Thanks @oanasc, a good thing to raise. My only thought is what behaviour would we get if the cluster config version is changed? For user-changed version the update would only happen on redeploy, until then the previous Application, with the previous version number will be current. For "latest", as at present I would expect it wouldn't auto-update as soon as a latest version is available (how to poll etc?), so again only on redeploy. So that leaves the cluster config - if this is updated do we expect the cluster to redeploy everything? I would guess not, but then we end up with a situation where e.g. the workloads don't have a version configured, but when they were deployed it was v1.0.1, but since then the cluster config has been updated to v1.0.2 and then v1.0.3. So the only version specification in the cluster says v1.0.3 but the only deployed version is v1.0.1 which leads to confusion. But I can't really think of an easy way around that with cluster config that doesn't auto-update. And as I said I'm not keen on auto-update! 🤔 Anyone got any ideas? 🙂 |
Currently when you publish a new definition version it isn't automatically applied. A redeploy is needed in order to apply. |
Actually, I'm not proposing the auto-upgrade, but others have 🙂. I do see that others may want it, particularly in dev environments, so happy to go along provided it's configurable as you say. But in the particular case of an update to the cluster config which you have proposed, how would you see that working? |
To elaborate and make sure there's clarity, I share some of the views that users shouldn't have to worry about the definition versions. Additionally, I noticed we haven't considered how this approach will function in a multicluster setup; specifically, one in which a single definition is installed in the main cluster and subsequently used across all connected clusters. Under this scenario, if we upgrade a definition,it will instantaneously take effect across all clusters. The aim behind the definition upgrades is to initially test them in a separate environment; however, these annotation methods aren't topology sensitive. Therefore, I proposed setting up a hierarchy of configuration precedence as follows:
And have the behaviour of auto-upgrade the same between for 1 and 2, and treat 2 as a central another way to set versions and choose to configure it or not on a cluster basis. [Edit] I see your point @Kolossi now (realised as soon as I stepped away) auto upgrade from a cluster config could upgrade things that originally had a user version. Then what you suggested having no auto upgrade on cluster config could work. |
Following on yesterday's community meeting comments on this, one of the issues that needs to be designed is how the entities are going to be named in Kubernetes to avoid overwritting previous versions. One approach, as discussed, could be to assume that entities are going to be named in kubernetes with a version suffix, they will have versioning labels to facilitate retrieving them from the KubeVela operator, and the application will be abstracted from the versioning if not required. With this approach we will have the following scenario: Listing components: $ kubectl get componentdefinitions.core.oam.dev
NAME WORKLOAD-KIND DESCRIPTION
...
task Job Describes jobs that run code or a script to completion.
webservice Deployment Describes long-running, scalable, containerized services that have a stable network endpoint to receive external network traffic from customers.
worker Deployment Describes long-running, scalable, containerized services that running at backend. They do NOT have network endpoint to receive external network traffic.
my-comp-v1.0.0 Deployment My custom component (v1.0.0)
my-comp-v1.3.0 Deployment My custom component (v1.3.0)
my-comp-v2.1.0 Deployment My custom component (v2.1.0) Getting a component: $ kubectl get componentdefinitions.core.oam.dev my-comp-v2.1.0
apiVersion: core.oam.dev/v1beta1
kind: ComponentDefinition
metadata:
annotations:
definition.oam.dev/description: My custom component (v2.1)
labels:
custom.definition.oam.dev/ui-hidden: "true"
definition.oam.dev/name: my-comp
definition.oam.dev/major: 2
definition.oam.dev/minor: 1
definition.oam.dev/patch: 0
definition.oam.dev/version: 2.1.0
name: my-comp-v2.1.0
namespace: vela-system
spec:
schematic:
cue:
... To facilitate the adoption, we could modify also the $ vela def apply my-stateful.cue --version 1.2.3
ComponentDefinition my-stateful-v1.2.3 created in namespace vela-system with version 1.2.3. |
I like the component labels with semver 👍 Sorry I could not make for the community call, does the kubernetes naming convention changes the way it would be referenced from in the Application (meaning without version)? From a user perspective in the Application, we have following scenarios, I would say:
As a platform eng, I would to be able to redeploy the users application, satisfying users contrains, but doing it as a progressive rollout, not a blunt auto update all and pray strategy, so it means being able to manipulate the patch and or minor version in accordance to 2.
Absolutely 👍 |
Hey folks,I previously discussed the proposal on slack with @Kolossi and @FogDonga. After reading in more depth I have the following observations -
|
Description
This feature request is to add the facility for component/trait etc definitions to explicitly specify a version as part of the definition.
The Application will then have the ability to refer to the definition version when using a definition.
Exisiting situation
Definitions currently have a version field but this is automatically assigned:
The Version Control for Definitions docs have:
This is a simple version number, being an integer. Being auto-assigned causes problems in not being able to predict what version will need to be used in the Application file, and the version number may be different in different environments such as dev,staging,prod)
Possible Solutions
My preference as the originator would be to use semantic versioning for the definition version.
This could either be by repurposing the existing version field, or by adding a new version field.
Referencing the defintion within the Application could be allowed as follows:
Alternatives
vela def list
Additional considerations
References
This proposal originated from a slack thread created by Frederick Boismenu.
It was also discussed on the Kubevela Community call 4th-Jan-2024.
The text was updated successfully, but these errors were encountered: