Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

doc(applications): deploying add-ons #791

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

bacongobbler
Copy link
Member

This is the design document for deis addons and is currently a work-in-progress. This document is expected to change over time as work is being done.

closes #741 once the work has been laid out and implemented.

@deis-bot
Copy link

@slack, @mboersma and @krancour are potential reviewers of this pull request based on my analysis of git blame information. Thanks @bacongobbler!

the application's configuration and will contain the URL used to access the newly provisioned
service.

You can choose the alias that the add-on uses on the application using the `--as` flag. This will
Copy link
Member

Choose a reason for hiding this comment

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

How would this work with a broker that has multiple credential values, such as DB_USER and DB_PASS?

Copy link
Member Author

Choose a reason for hiding this comment

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

This is a very good question. This is a straight cut from Heroku's docs and I'm not sure if it's a resonable effort to do this for a first pass. I'm not sure how Heroku handles this either as I know they have add-ons like Papertrail with multiple envvars. I'll go play around with some of their add-ons and see what works and what doesn't.

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 was thinking we could do some crazy docker-like mapping in the form of --as DATABASE_URL=DB_URL,DATABASE_USER=DB_USER, but again I'm concerned about making the translation overly complex. I'm sure this will come into play as things start being implemented.

@bacongobbler
Copy link
Member Author

added deis addons:services to the docs to list the service catalog.

@bacongobbler
Copy link
Member Author

bacongobbler commented Apr 10, 2017

removed the --as support in the doc. Heroku's implementation is shoddy at best and I couldn't think of a perfect solution out the door, so for an initial implementation we'll just accept whatever envvars the service broker gives us.

@krancour
Copy link
Contributor

@bacongobbler, I think one needs to carefully read docs or interactive help to understand that addons:list is provisioned and bound services while addons:services are available services. Would the intent of each of those list operations be less ambiguous if we used addons:provisioned (or addons:installed) and addons:available, respectively?

@bacongobbler
Copy link
Member Author

bacongobbler commented Apr 11, 2017

I was trying to make it a 1:1 mapping with heroku CLI commands, but I agree it is a little confusing. I'd be amenable to deis addons:list being the catalog list and deis addons:installed being a list of addons provisioned under the user's account. How about that?

@krancour
Copy link
Contributor

Is parity with Heroku still a concrete objective? In either event, I'm happy with what you have just proposed.

@mboersma
Copy link
Member

Is parity with Heroku still a concrete objective?

Yes, because it's still a familiar toolset to many people, and that's still the general inspiration for Deis Workflow functionality. But it's not set in stone, if there's a good argument for doing things a different way--and it sounds like there might be here.

@bacongobbler
Copy link
Member Author

I think this is a very good opportunity to change the heroku CLI names for specific commands. I agree that addons:list and addons:services is too confusing. I'll update the docs with the commands I proposed.

@bacongobbler
Copy link
Member Author

bacongobbler commented Apr 12, 2017

So as it turns out, instances are namespaced. Makes sense, but we haven't had to provision user-namespaced resources before... Everything was either an annotation on the application's service or on the router.

What I think that means going forward is that we can introduce a myuser namespace creation at deis register (along with a data migration for existing users), then each instance that is provisioned from a broker is created in that user's namespace. Instance bindings just reference instances by name which is globally unique, so having the instance in one namespace and the binding in another shouldn't matter, right? This would also have the added benefit that all instances are removed when the user is deleted. This would also be a useful transition into deis teams, in that instances are deployed to a team's namespace and can be managed by the cluster operator accordingly.

Any opinions/thoughts on the matter, @krancour or @ultimateboy?

@bacongobbler
Copy link
Member Author

bacongobbler commented Apr 12, 2017

From what it looks like, my assumption was wrong. instances and instance bindings must exist in the same namespace, so instances must be bound to the application then. That kinda sucks, because I had expected instances to be able to bind to an account and the bindings would be what the application cares about. I'll file a ticket upstream and see if there's a way we can work around this.

As seen here, I have an instance in the bacongobbler namespace...

><> kubectl --context=service-catalog get instances --namespace bacongobbler
NAME           KIND
ups-instance   Instance.v1alpha1.servicecatalog.k8s.io

...And an instance binding in the test-ns namespace following the basic walkthrough.

><> kubectl --context=service-catalog get bindings -n test-ns ups-binding -o yaml
apiVersion: servicecatalog.k8s.io/v1alpha1
kind: Binding
metadata:
  creationTimestamp: 2017-04-12T22:44:01Z
  finalizers:
  - kubernetes
  name: ups-binding
  namespace: test-ns
  resourceVersion: "76"
  selfLink: /apis/servicecatalog.k8s.io/v1alpha1/namespaces/test-ns/bindings/ups-binding
  uid: 85e8d1d6-1fd1-11e7-b4a0-0242ac110006
spec:
  instanceRef:
    name: ups-instance
  osbGuid: 17633cb4-dff1-4221-909d-e3dadc2f3707
  secretName: my-secret
status:
  conditions:
  - message: The binding references an Instance that does not exist. Binding "test-ns/ups-binding"
      references a non-existent Instance "test-ns/ups-instance"
    reason: ReferencesNonexistentInstance
    status: "False"
    type: Ready

@bacongobbler
Copy link
Member Author

You know what, the idea of the instance and the instance binding living in the same namespace makes more sense anyways because in a team-centric world, all apps will be deployed in the same namespace as the team name so the instance should live in there.

I'll be white-boarding this more overnight and try to come up with a better solution tomorrow.

Copy link
Member

@arschles arschles left a comment

Choose a reason for hiding this comment

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

I added a bunch of my $0.02 here 😄

--------------- ----------------------
bonsai Bonsai Elasticsearch
deis-postgresql Deis Workflow Postgres
librato Librato
Copy link
Member

Choose a reason for hiding this comment

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

Does this list imply that the available services are provided as slugs? I have so many other questions, but I'll leave it at that for now 😄

Copy link
Member Author

Choose a reason for hiding this comment

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

Yep! The slug and name field relate directly with a service class' name and the description field. I'll change the name field to description and slug to name to hopefully make things clearer. This is just how Heroku calls things.

Copy link
Member Author

Choose a reason for hiding this comment

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

So given the ups broker is installed, deis addons:catalog would look like:

name                    description
---------------------   ---------------------
user-provided-service   User Provided Service

```
$ deis addons:detach deis-postgresql:standard --app wooden-rowboat
Detaching deis-postgresql:standard from wooden-rowboat... done, v6
```
Copy link
Member

Choose a reason for hiding this comment

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

what do you want to happen when a detach (unbind) happens before a deprovision?

Copy link
Member Author

Choose a reason for hiding this comment

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

So let's think about this in a team-oriented fashion:

  • I have a team (a namespace to store all apps deployed by a team)
  • I have many apps deployed in this namespace
  • I have a few instances running in this namespace

I would expect that, as a user, I can bind an app to the instance as well as unbind apps from the instance.

This is essentially useless for the "instance in the app's namespace" use case though. Again I'll give this some more thought. :)

```

If the application doesn’t yet have a database provisioned, a user can create a new database using
the CLI.
Copy link
Member

Choose a reason for hiding this comment

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

This is a little confusing. Does this phrase:

a user can create a new database using the CLI

Refer to a provision operation?

Copy link
Member Author

Choose a reason for hiding this comment

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

Correct. It relates to an instance resource being created on the service-catalog's side.

Basically there are three operations:

  • list the catalog
  • CRUD the instances
  • CRUD the instance bindings

is using.

```
$ deis addons:installed | grep -i postgresql
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 someone get a new addon into this list? In service-catalog land, they'd do that by creating a Broker resource. Is there an analog with the deis CLI?

Copy link
Member Author

Choose a reason for hiding this comment

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

There is not. The expectation is that we will be listing the service classes, but the brokers themselves is managed by service-catalog and we are not adding any administration to service catalog. Just communicating with it similar to how we consume the kubernetes API.

Copy link
Member Author

Choose a reason for hiding this comment

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

So basically if an admin creates a new broker resource, it will populate new service classes into the mix for users to query via deis addons:catalog

I haven't added addons:catalog into the docs yet but I am going to amend these once again so users can list instances, bindings and service classes.

# Deploying Add-ons

The goal of `deis addons` is to give users the power to provision consumable services such as
a postgres database, a minio bucket, or a logstash connection) to their applications. `deis addons`
Copy link
Member

Choose a reason for hiding this comment

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

The closing ) doesn't have an opening one to match.


As an example, most applications deployed by Workflow need a data store of some kind. `deis addons`
allows applications to consume services like databases that exist somewhere via common environment
variables like `DATABASE_URL`.
Copy link
Member

Choose a reason for hiding this comment

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

Is there a way for the app developer (the person who executes deis addons:attach for example) to tell what env vars are available, after they do the attach operation (note there's no way in service-catalog land to tell what's available before the attach)?

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 know that Heroku exposes them in config:list. I'm sure we can do the same somehow.

Copy link
Member Author

Choose a reason for hiding this comment

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

added more context lower down; should be available through deis config:list.

@krancour
Copy link
Contributor

@bacongobbler whether it should be possible to bind to instances in other namespaces was the subject of lots and lots of discussion very early on, but not so much as of late. I am of the opinion that in large enterprises and in microservice architectures, the notion of n applications all binding to a common instance that belongs to none of them (but is managed as its own thing) is probably not an uncommon use case. But that's not something that service catalog currently does because it would simply defy k8s existing permissions model and I don't think we were about to go re-inventing that.

The practical implication of that is exactly what you seem to have concluded already-- that service instances and bindings for those instances should all be provisioned within an app's own namespace (or within a team namespace that contains multiple apps? is that a thing now?)

Also, since Workflow is very app centric, would provision + bind be combined into a single step for Workflow users?

@bacongobbler
Copy link
Member Author

bacongobbler commented Apr 13, 2017

or within a team namespace that contains multiple apps? is that a thing now?

Nope! Just a twinkle in my eye.

Also, since Workflow is very app centric, would provision + bind be combined into a single step for Workflow users?

Yes. Honestly I've just revamped the documentation again to only have 5 commands:

  • addons:list (list instances provisioned for this app)
  • addons:create (create an instance + binding, using format serviceclassname:plan as argument)
  • addons:destroy (destroy an instance + binding using service class name as the argument)
  • addons:catalog (list available service classes)
  • addons:plans (list available plans for the given service class name)

addons:plans is still yet to be added to this PR, but will be up in a sec.

At the current time let's keep the instance + instance binding together with the app since all apps are in their own namespace. Had we deployed apps in a user's personal namespace (or implemented deis teams) then separating instance bindings from the app might've made more sense, but not with the current model.

Attaching deis-postgresql:standard to wooden-rowboat... done, v5
```

Once the instance has been attached to the application, a DATABASE_URL setting will be available in
Copy link
Contributor

@krancour krancour Apr 13, 2017

Choose a reason for hiding this comment

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

"setting" is a bit ambiguous. Change to "environment variable"?

Copy link
Member Author

Choose a reason for hiding this comment

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

changed.

@krancour
Copy link
Contributor

@bacongobbler I like where this is headed. It's clean and simple. There's a lot more complexity that could be exposed, but given Workflow's Heroku-esque focus on 12factor apps, this looks to be just right. 💯

@bacongobbler
Copy link
Member Author

k, deis addons:plans has now been added as well.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

deis addons command should work with k8s service brokers
6 participants