Skip to content
This repository has been archived by the owner on Jun 8, 2022. It is now read-only.

design: one pager component mutable and versioning mechanism for OAM #29

Merged
merged 1 commit into from
Jun 15, 2020

Conversation

wonderflow
Copy link
Member

@wonderflow wonderflow commented May 22, 2020

Signed-off-by: 天元 [email protected]

Coming from "OAM component versioning mechanism" and "The Component should mutable".

Since we discussed a lot and have a conclusion with OAM spec changes done. I write this proposal to make the implementation details more clear.

@hongchaodeng
Copy link
Member

Can you share an example how to do blue-green deployment?

@henrywangx
Copy link

henrywangx commented May 23, 2020

Can you share an example how to do blue-green deployment?

Actually, I think it's hard to handle Blue-Green. I'm considering to build a workload upon the deployment. Workload revision represents different deployment. That means Blue-Green will build two deployments.

In this way, do canary, blue-green upgrade will be much easier for deployment.

@henrywangx
Copy link

Meanwhile since for the whole application upgrade, we need to update the component and applicationConfiguration both. For those two config file's changes, it's an async process. So we may generate two revision and trigger 2 times upgrade. How to handle this case?

@resouer
Copy link
Contributor

resouer commented May 23, 2020

@henrywangx ParameterValues is nothing but a special case of Trait, it should not be considered as part of component revision.

You can think of a OAM application is composed by two parts:

  1. Data - Components
  2. A series of operations to the data - Anything defined in ApplicationConfiguration

Here is an essential difference between they two: modifying data will always trigger a new version of data, but modifying operations will trigger nothing unless the whole application is re-deployed. For example, imagine Deployment is data, and autoscaler is operation, modify autoscaler policy should not trigger a new version of Deployment, correct?

Revision is used to track history of data, because the system need to know what's the current version of data it is dealing with, and how to revert to a historical version if needed. In this context, blue-green deployment is very simple in OAM system, just apply a blue-green rollout trait, and modify your Component, a blue-green rollout will happen (rollout trait controller will control the instances of different revision).

For history of operations, the system doesn't care it too much, because even you want to rollback an operation, it's in practical nothing but a re-deploy with new operation policy (this policy is same with a previous operation policy, but the system doesn't care). That being said, you can record the history of operations for audit etc.

@henrywangx
Copy link

@resouer Yes I understand ParameterValue is a special trait like parameterTrait. But modify parameter trait or some other traits like env trait, volumeMount trait may change the workload's spec. That means a new workload revision will generate. Pods with new revision will then generate.

And autoscaler is just a special case, it only change the replica which won't generate a new ControllerRevision.

About the Blue-Green upgrade, I guess @hongchaodeng is talking about how a k8s's deployment do the Blue-Green upgrade. From my knowledge, it's really hard to achieve the Blue-Green upgrade for deployment. So I give a solution:

Actually, I think it's hard to handle Blue-Green. I'm considering to build a workload upon the deployment. Workload revision represents different deployment. That means Blue-Green will build two deployments.
In this way, do canary, blue-green upgrade will be much easier for deployment.

@resouer
Copy link
Contributor

resouer commented May 23, 2020

@henrywangx Note that OAM creates its own revision object, it doesn't care revisions generated by Deployment controller. So there's no difference between modifying replicas and patching env list in OAM - both of them will not generate new revision.

Though we will reuse ControllerRevision API in k8s to record the revision, just don't want to reinvent wheel.

I believe Hongchao is talking exactly same idea you are thinking. In OAM, you don't need to create a special workload for that:

component -> revision-1 --- deployment-1
component change -> revision-2 --- deployment-2

so your Blue-green trait controller can always use revision-1 and revision-2 to find different deployment object and do rollout.

@wonderflow , maybe code is better to illustrate the whole idea than Github comments 😄

@henrywangx
Copy link

henrywangx commented May 25, 2020

@resouer thanks for explanation, but I think the proposal by @ryanzhang-oss could convince me better.

There still are some confusion about the proposal, maybe I misunderstand about the idea by @wonderflow . And I will check the code to understand the design.

@henrywangx
Copy link

After offline discuss with @wonderflow, I understood about the component->revision->deployment idea.
It only treats the component's change as the version change. And the trait's change will be regarded as operations. But in my opinion, user may care more about the final deployment's change(component's change+trait's change) than the component's change.😄

@resouer
Copy link
Contributor

resouer commented May 26, 2020

But in my opinion, user may care more about the final deployment's change(component's change+trait's change) than the component's change.

The "final" deployment's state can be always checked by kubectl get deployment.

Though I'm not sure if you get the point of the difference between data and operation.

Let's say you have a Deployment (replicas=10), and a HPA (min=1;max=100). And at 10:00 am, May 25th, 2020, the HPA scaled the Deployment to replicas=20 because its CPU load is high.

Based your prevision suggestion, this scaling will trigger OAM system to create a "Component Revision (replicas=20)".

My argument is this "Component Revision (replicas=20)" is actually useless. Because replicas=20 is determined by the CPU load at 10:00 am, May 25th, 2020.

For example, what does it mean if we rollback to Component Revision (replicas=20)? Can we rollback the CPU load as well 🤔?

See? The essential difference here is trait's change is not determined by trait itself - it's co-determined by the system. That's why I said traits should never be part of revision - you can never rollback the trait's change unless you can rollback the whole system status.

There's another concept named snapshot. For example, you can snapshot all the objects of given ApplicationConfiguration every 5 mins. The purpose for snapshot is for auditing, not rollback (unless you can re-produce the whole system status).

Snapshot is not in the scope of OAM for now.

design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
@henrywangx
Copy link

@resouer I'm considering the change of trait and parameters may change the deployment's spec(replicas is not in the deployment's spec, yes it depends on the system load). For example, the actor uses parameters to replace deployment's image.

That's why I don't like the paremeters, we have two input paths(component and parameter) to influence the final deployment's spec.

@wonderflow
Copy link
Member Author

Can you share an example how to do blue-green deployment?

blue-green example was added

@wonderflow
Copy link
Member Author

After deep consideration for some of your comments and trying to implement this proposal, I have updated something, please take a second review. Thanks very much.

@henrywangx @resouer @ryanzhang-oss @hongchaodeng

@resouer
Copy link
Contributor

resouer commented May 28, 2020

I'm considering the change of trait and parameters may change the deployment's spec

@henrywangx the encouraged usage of parameterValues is for parameter passing, for example: #24. It's an anti-pattern to use parameters to rollout the app (update image etc), we will clarify this clearly in the doc after component revision is implemented.

@wonderflow
Copy link
Member Author

wonderflow commented May 29, 2020

@hasheddan @zzxwill Thanks so much for your review, I think we're all agree with ComponentRevision and the RevisionName was already merged in OAM spec so I hope we can follow that. All of the rest comments have been updated.

I'm going to implement this proposal if there are no other different ideas. Hope we can merge it? \cc @negz @resouer @hongchaodeng @ryanzhang-oss @henrywangx

Since component is becoming mutable, a very common question is how will the component versioning mechanism work.

One of the requirement is the versioning mechanism should allow users to specify a fixed version of component
in ApplicationConfiguration, so that the component can be upgraded as before.
Copy link
Contributor

Choose a reason for hiding this comment

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

Should this requirement be re-examined instead? Does using Helm solve this problem adequately? Or do we think that version/revision tracking is fundamentally necessary for some of the upgrade features we want to add?

It seems complex understand that ApplicationConfiguration both supports snapshotting (explicit versions everywhere) and automatic upgrade (no versions specified).

Copy link
Contributor

Choose a reason for hiding this comment

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

Should this requirement be re-examined instead? Does using Helm solve this problem adequately? Or do we think that version/revision tracking is fundamentally necessary for some of the upgrade features we want to add?

So the intention of having revision in OAM is to let Trait have a way to reference revisions when needed, for example, A/B testing trait and traffic splitting trait. AppConfig will not handle the upgrade story, it's only responsible for "emitting" correct revision of workload CR to k8s.

It seems complex understand that ApplicationConfiguration both supports snapshotting (explicit versions everywhere) and automatic upgrade (no versions specified).

Yes, though it should be implementable. This is a compromise that both scenarios are valid and widely used in the community.

@vturecek
Copy link

@hasheddan made an interesting suggestion to introduce versioned components, where each version is immutable. That makes sense to me, as immutability to me simply means that a component config is unique to a name-version pair. An Application Configuration should always be specific about the version of a component that's being run. I think it would be a huge mistake to allow the equivalent of the "latest" tag for container images with Component instances.

@resouer
Copy link
Contributor

resouer commented May 30, 2020

@vturecek This proposal is stick to have revisionName in ApplicationConfiguration which is based on the conclusion during previous discussion: oam-dev/spec#350 (comment). And as you suggested, the revisionName is the encouraged approach if rollout trait is not applied.

Copy link
Member

@zzxwill zzxwill left a comment

Choose a reason for hiding this comment

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

/lgtm

metadata:
name: frontend-v0.0.1 # you could name this anything you wanted, but just appending the semver would be good practice
spec:
version: v0.0.1
Copy link
Contributor

Choose a reason for hiding this comment

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

There's no need to explicitly claim a version IMO. Revision object should be generated by the system, so it doesn't make lots sense to force the system generate version number incrementally like this.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm fine but what's the difference between controllerRevision with ComponentRevision if we remove this version field ?

Copy link
Contributor

Choose a reason for hiding this comment

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

The main difference is ControllerRevision is not human readable as it uses a generic data field to carry the revisioned object.

So if the argument is user experience, ComponentRevision proposed in #29 (comment) is better - still, not a very big difference indeed.

While what I am not sure on Daniel is comment is:

but does not appear to be robust enough for a case like Component where an organization may want to "publish" multiple versions of a Component that will be consumed by multiple ApplicationConfigurations

I don't think it's the intention in this proposal. Revision is OAM is mostly for AppConfig/Trait controller to find workload CR by given revision number.

Copy link
Contributor

@resouer resouer left a comment

Choose a reason for hiding this comment

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

Generally looks good but with some missing parts. Comments left.

@wonderflow
Copy link
Member Author

@hasheddan Finally I decide to use controllerRevision instead of creating a new concept componentRevision, because they have almost the same experience for user.

@wonderflow
Copy link
Member Author

@resouer @artursouza I think I have fixed all comments and already have an implementation(#35). Can we approve this proposal and let's move forward quickly?

@wonderflow wonderflow requested a review from ryanzhang-oss June 10, 2020 08:18
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
Copy link
Contributor

@resouer resouer left a comment

Choose a reason for hiding this comment

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

Thanks all for reviewing, the current design doc generally LGTM.

We will continue discussion of implementation details in #35

design/one-pager-component-mutable-and-versioning.md Outdated Show resolved Hide resolved
- "bash top"
```

Now with `ControllerRevision` in place, let's talk about how to use it in Trait and ApplicationConfiguration.
Copy link
Member

Choose a reason for hiding this comment

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

How does Workload CR gets created in this case?

@hongchaodeng
Copy link
Member

lgtm

@hongchaodeng hongchaodeng merged commit 22028f0 into crossplane:master Jun 15, 2020
@wonderflow wonderflow deleted the design branch June 15, 2020 04:11
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

10 participants