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

Proposal: Add declaration of service instance dependencies #427

Open
fmui opened this issue Jan 23, 2018 · 26 comments
Open

Proposal: Add declaration of service instance dependencies #427

fmui opened this issue Jan 23, 2018 · 26 comments

Comments

@fmui
Copy link
Member

fmui commented Jan 23, 2018

OSB defines how applications are connected to service instances. We have scenarios where we have to bind service instances to other service instances. A service instance A needs a service instance B.

Today, we solve this problem with service keys. When service instance A is provisioned, the service key of service instance B has to be provided as a parameter. Because there is no standard, we see several variations of this pattern.

Is this a common problem? Do you think declaration of service instance dependencies should be part of OSB?

Please find the proposal document here: https://docs.google.com/document/d/1jBwoXRKtQqGzanhhvb-84YEGLYzqbiNbXkQ-XSeN-KA

@duglin
Copy link
Contributor

duglin commented Jan 23, 2018

@fmui while there's a syntactical difference between using "parameters" and "dependencies", is there really a semantic difference? I'm asking because it still feels like we're just passing along extra metadata just with a different tag name. And I'm wondering if it makes sense to start down the path of defining a new top-level field each time we may need to do add more data.

Also, have you considered just having the service call the platform (or broker) directly to ask for the dependent service to be created? Does it make sense to have the service manage its own dependencies via OSBAPI calls? Perhaps instead of passing in the creds to a service instance we should be passing in (and standardizing) the creds needed to invoke OSBAPI calls. Just pondering...

@krancour
Copy link

@fmui at MS, we've come to similar conclusions as you and we've begun experimenting with this in a feature branch of the Open Service Broker for Azure.

Our approach has been very similar to what you have outlined. In our catalog, we have modeled the parent/child nature of the relationship between certain services. (Right now, we're prototyping this with SQL Server and databases on the server.)

We've modified provisioning and deprovisioning in the following ways:

  • Provisioning a "parent" ("container") service instance requires an alias parameter that can be used to uniquely identify that service instance.
  • Provisioning a "child" service instance requires a parentAlias parameter as a reference to the service instance upon which it depends.
  • On provisioning, if a child's parent is still in a provisioning state or doesn't exist yet (this is possible if parent and child are provisioned simultaneously in a Helm chart, for instance), provisioning of the child is deferred until the parent is fully provisioned.
  • On deprovisioning, if a parent still has children, deprovisioning is deferred until it has no children remaining. (Deprovisioning does not cascade. It just waits until it can proceed.)

We have a lot of kinks to still work out.

I believe these sort of relationships between services will be common and I am in 100% agreement with you that, ideally, the OSB spec should model these relationships instead of leaving every broker to decide on an approach themselves.

I would further propose that this is something we should try to work through as a group sooner rather than later. If we're already both at a point where we're implementing this, others probably are too, and it would be best to work this out before we've all adopted our own, unique approaches and force breaking changes on ourselves in order to remain compliant with the spec if and when the spec finally defines this.

@krancour
Copy link

@fmui note that in our approach, we do not speak of "bindings" between instances. Conceptually, yes, that's what's going on, but we found it easier to socialize this idea internally by dropping the "instance-to-instance binding" language we'd been using.

@leonwanghui
Copy link
Contributor

leonwanghui commented Jan 24, 2018

Hi all, at Huawei we have experimented the instance dependencies for a while (over a year), here is some experience we want to share.

Imagine user's application wants to consume service A, but service A has a dependency with service B. So depending on the evaluation if it's valuable to expose B as a standalone service, these options are suggested:

  1. If B can't be published as a standalone service (ie. there is no scenario for application to use B only), it's prefered to package B into A to be exposed as a whole service,and actually users will get two service instances when provisioning.
  2. Usually Platform will initiate its service broker when a service be published, so it's also feasible to pass service credentials of B into A service broker by using environment variable. In Huawei product, we defined a field called "EXTEND_INFO" to let service publisher define some extra information, including service credentials from other services.
  3. If B can be published as a standalone service, then we suggest integrate B into A in the form of service dependencies (Talk about it later).

@duglin I think Option 1 and 2 match your opinion that doesn't need to add more top-level field. But as for the last option it's better to add new filed ("dependencies", "instance_dependencies" or whatever). Below is a sample PUT body definition when provisioning service instance A with dependencies of B:

{
  ..., # Ignore other fields
  "dependInfo": [{
    "service_id": "aaa-bbb-ccc",
    "service_tags": ["data_resource"],
    "instance_id": "xxx-yyy-zzz",
    "parameters": { ... },
    "credentials": { ... }
  }]
}

From the definition above, we could easily draw the workflow: user needs to provision service instance B and get its credential by binding this instance first, and then user provisions another service instance A and passes the credential of service instance B into "dependInfo" filed. @krancour It's a bit different from what MSFT has done (If I get it right, what you have done is let service broker bind the service instance B dynamically when user provision service instance A), but it should be ok in either way. But one thing SHOULD be noticed is that service instance A may depend on more than one service instance, so we need a JSON object list rather than a JSON object.

Those above are some thoughts from my side, sorry for my poor english and plz be free to ask : )

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

Really looking forward to the talk about this - its a really interesting set of usecases. Some aspects that come to mind:

  • instead of defining a new top-level property, I wonder if it would be better to have well-defined "parameters" instead. This has the benefit of not potentially changing any infrastructure/broker code that only know how to pass along existing OSBAPI fields + a blob of parameters. A new top-level thing means something like adding a new arg to a function call and that's a potentially breaking code change. Sticking it as a parameter shouldn't have that impact.
  • this would also align nicely with the idea we've talked about in the past of having well-defined cred properties on the binding response
  • if we find we need to add other "well defined" metadata to these calls, then we've established a pattern that can easily grow
  • @leonwanghui your third case feels a little like some kind of "bulk instance.create()" type of action where you want a single provision call to create multiple instances, do I have that right? The fact they might be dependencies of each other almost seems like a side issue that can even be ignored by Service A if they wanted.
  • this sounds like it only works when all of the services in question are supported by the same broker, right? Or are we expecting the list of possible dependent instances to be from the Platform's full list of possible services? And if so, this then raises the question of how the user knows which services are associated with each broker/service since in some platforms (e.g. CF, I think) that info is not visible to the user. And even in Kube's case, where the user can see which broker each service came from, that might not be accurate for this purpose because in some environments there's a "proxy broker" in-front of the real service brokers so it appears like all services come from the same broker. Hmmm, may need to add some metadata to each service to pass along extra info for the user to see.

@leonwanghui
Copy link
Contributor

@duglin Sorry I didn't get your point clearly, let me give an example to make it more clear:

User wants to consume a distributed MQ service (which is already published), but it turns out he needs to deploy ZooKeeper service (another service published) at first. In this case, he would provision a ZooKeeper instance and get its credentials first, and then pass these "dependInfo" to make sure the MQ service can connect to ZooKeeper when provision MQ service instance.

It's not about creating two service instances simultaneously with one provision call, but consuming them as a "whole" service. Does it make clear?

@mattmcneeney
Copy link
Contributor

Question: If the same service broker is providing all of the services in this dependency change, then why does the broker need to expose this to the developer? Can't they just provision however many databases/VMs/whatever they need ("instance" is a generic term) and then return the credentials the developer needs to access to main service?

Or, if we are talking about services being offered by different service brokers, then I can see how this needs to be handled by the platform/developers.

@leonwanghui
Copy link
Contributor

@mattmcneeney Good question!

At Huawei we only provide a unified PaaS platform and most of services are provided by ISVs. So it has to be offered by different service brokers. Any thoughts?

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

@leonwanghui yep - I understand that flow and that sounds like a good use of "parameters" to me - its all just config data to configure the service being provisioned. I don't draw much of a distinction between "size of the DB being provisioned" and "here's the creds to talk to a backend/dependent service" - all just parameters that the OSBAPI spec itself shouldn't really know about, or how they're used.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

@leonwanghui that sounds like you need a model where service brokers call back into the platform to create these dependent services. Or do you just need to be able to reference pre-existing service instances offered by multiple platforms? The latter may not need the "call back", but the former probably will.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

The "consistent binding" aspect is interesting. In cases where Service A provisions Service B then I would hope Service A would need to be responsible for deprovisioning B. But, in your case it (where A is just given the creds of B) it seems like its up to the user to not deprovision B too soon.

I think it might be good if we enumerated the exact usecases we want to support at the OSBAPI level vs at the Platform level. For example, some of this dependency stuff might be better managed at the Platform level and not at the OSB API level. For some usecases it might be better to keep the brokers as just "building blocks" because its really the Platform that knows about the inter-dependencies to block deprovisioning dependencies too soon. But I'm still not 100% sure I fully grok the requirements yet.

@krancour
Copy link

@mattmcneeney

Question: If the same service broker is providing all of the services in this dependency change, then why does the broker need to expose this to the developer?

I'll share the use cases we've been using for shaking out these details. I think it answers this question.

Consider PostgreSQL. There are (at least) two distinct kinds of (related) services a broker could offer. For the sake of example: an entire RDBMS (the server(s)) or a database.

In the case of a database, you often might not care where that DB is hosted. But there are also cases where, for the sake of cost-efficiency, for instance, one might want to provision a single RDBMS and then multiple databases upon that one RDBMS.

Also, it's entirely possible that the RDBMS is owned and provisioned by one party (cluster admin or DBA) and the databases hosted on it are owned and provisioned by another party (developers).

Based on interactions with customers, these are not outlying use case, but common concerns.

We've extrapolated three distinct service offerings from this. Coming back to your question:

why does the broker need to expose this to the developer?

There's a case where it doesn't, and there's a service for that:

  1. "All in one": Provisioning this gives you an RDBMS + database. No fuss. Could get expensive if you have lots of these.

But for the cases I highlighted, exposing these details seems necessary. These are the services that correspond to those use cases:

  1. "RDBMS only": Exactly what the name says. Probably owned by an operator, DBA, or some infra group. Deprovisioning is deferred until all DBs (from no. 3) on it are deprovisioned.
  2. "Database only": Exactly what the name says. Provisioned on an RDBMS (from no. 2). Probably owned by developers. Provisioning is deferred until RDBMS is fully provisioned.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

@krancour for case 2, are you looking for the broker managing the RDBMS to defer the deprovision or the Platform to do it?

@krancour
Copy link

krancour commented Jan 24, 2018

@duglin I'd rather not rely on all platforms implementing that because unless they all do, we couldn't guarantee that any of the above would work across platforms, so our broker handles that.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

if the services are managed by different brokers, how does the parent service get notified that the child is now gone?

@krancour
Copy link

if the services are managed by different brokers...

My examples involve services provided by a single broker that are explicitly designed to work together to enable the use cases I outlined.

I don't expect this sort of co-operation to work across brokers. (That would be cool, though.)

As I see it, everything discussed above is merely an implementation detail of the broker / services in question. Absent any action from this group, all of that is still doable. However, I do think it would be beneficial for these sort of parent/child relationships to be acknowledged by the spec and modeled in a uniform way.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

That sounds reasonable. I'm just trying to fully understand the scope of what's being asked for in the spec. The more we add the more we need to think about how this works in broader situations, like across brokers. But, if in the end, all we need to do is define some "standard parameter names" that might appear on the provision (and/or bind) calls then there's less to worry about - but we can still get the consistency/interop people are looking for.

@krancour
Copy link

@duglin I still think there needs to be a deep dive on this, but I think that you and I at least are converging on a common perspective on this.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

yep - definitely still want a deep dive

@krancour
Copy link

@duglin do we know when that's happening. I want to be sure to have that on my calendar.

@duglin
Copy link
Contributor

duglin commented Jan 24, 2018

As of now its the top topic for next week's call.

@mhrivnak
Copy link

Interesting discussion. At a basic level, it sounds like meeting all the use cases described might boil down to enabling the Platform to do some amount of service orchestration, by making sure the OSBAPI includes enough information for it to do so.

For example if there was a direct and explicit tie between a Binding and its use as input arguments to another service, could the Platform take responsibility for ensuring that services are provisioned and deprovisioned in the right order, and prevent a user from unbinding or deprovisioning where it would impact an in-use binding?

@xinzweb
Copy link

xinzweb commented Jan 10, 2019

@duglin where to find the week's call on the bind-service-to-service? I also have scenarios where want to bind multiple services together, in addition to bind app and service together.

I am NOT interested in the nested services, but only interested in cases where all the services are already provisioned, but they can use the same bind/unbind to find the credentials to other services through environment variables.

My scenario would be, I can have a replication service build between two postgresql instances. Instead of hardcode the replication at the two independent postgresql service instances, I can actually bind them together through another replicaiton service.

Beyond the OSBAPI, I am also looking at the cf command like cf bind-service-to-service in addition to the cf bind-service. Thanks.

@duglin
Copy link
Contributor

duglin commented Jan 15, 2019

@xinzweb you can find the recordings of previous calls here: https://github.com/openservicebrokerapi/servicebroker/wiki/Weekly-Call#previous-call-recordings

@xinzweb
Copy link

xinzweb commented Jan 18, 2019

Very cool. Thanks a lot @duglin. I will start from there.

@DrackThor
Copy link

Hi guys, I've recently started to dive into OSBAPI and currently I'm wondering what the status of this proposal is?
As far as I could see here #488 the service dependency spec is still in discussion?
Has there been any progress/decision in the weekly calls since 05/2018?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Inbox
Development

No branches or pull requests

9 participants