[openstack-dev] [Heat] rough draft of Heat autoscaling API
Zane Bitter
zbitter at redhat.com
Mon Nov 25 19:31:05 UTC 2013
Top-posting *and* replying to myself today :D
I realised that I could have implemented this in less time than I've
spent arguing about it already, so I did:
https://review.openstack.org/#/c/58357/
https://review.openstack.org/#/c/58358/
cheers,
Zane.
On 19/11/13 23:27, Zane Bitter wrote:
> On 19/11/13 19:14, Christopher Armstrong wrote:
>> On Mon, Nov 18, 2013 at 5:57 AM, Zane Bitter <zbitter at redhat.com
>> <mailto:zbitter at redhat.com>> wrote:
>>
>> On 16/11/13 11:15, Angus Salkeld wrote:
>>
>> On 15/11/13 08:46 -0600, Christopher Armstrong wrote:
>>
>> On Fri, Nov 15, 2013 at 3:57 AM, Zane Bitter
>> <zbitter at redhat.com <mailto:zbitter at redhat.com>> wrote:
>>
>> On 15/11/13 02:48, Christopher Armstrong wrote:
>>
>> On Thu, Nov 14, 2013 at 5:40 PM, Angus Salkeld
>> <asalkeld at redhat.com <mailto:asalkeld at redhat.com>
>> <mailto:asalkeld at redhat.com
>> <mailto:asalkeld at redhat.com>>> wrote:
>>
>> On 14/11/13 10:19 -0600, Christopher Armstrong
>> wrote:
>>
>> http://docs.heatautoscale.__ap__iary.io/
>> <http://apiary.io/>
>>
>> <http://docs.heatautoscale.__apiary.io/
>> <http://docs.heatautoscale.apiary.io/>>
>>
>> I've thrown together a rough sketch of the
>> proposed API for
>> autoscaling.
>> It's written in API-Blueprint format (which
>> is a simple subset
>> of Markdown)
>> and provides schemas for inputs and outputs
>> using JSON-Schema.
>> The source
>> document is currently at
>> https://github.com/radix/heat/____raw/as-api-spike/
>> <https://github.com/radix/heat/__raw/as-api-spike/>
>> autoscaling.__apibp
>>
>>
>>
>> <https://github.com/radix/__heat/raw/as-api-spike/__autoscaling.apibp
>>
>> <https://github.com/radix/heat/raw/as-api-spike/autoscaling.apibp>
>> >
>>
>>
>> Things we still need to figure out:
>>
>> - how to scope projects/domains. put them
>> in the URL? get them
>> from the
>> token?
>> - how webhooks are done (though this
>> shouldn't affect the API
>> too much;
>> they're basically just opaque)
>>
>> Please read and comment :)
>>
>>
>> Hi Chistopher
>>
>> In the group create object you have 'resources'.
>> Can you explain what you expect in there? I
>> thought we talked at
>> summit about have a unit of scaling as a nested
>> stack.
>>
>> The thinking here was:
>> - this makes the new config stuff easier to
>> scale (config get
>> applied
>> Â per scaling stack)
>>
>> - you can potentially place notification
>> resources in the scaling
>> Â stack (think marconi message resource -
>> on-create it sends a
>> Â message)
>>
>> - no need for a launchconfig
>> - you can place a LoadbalancerMember resource
>> in the scaling stack
>> Â that triggers the loadbalancer to add/remove
>> it from the lb.
>>
>>
>> I guess what I am saying is I'd expect an api
>> to a nested stack.
>>
>>
>> Well, what I'm thinking now is that instead of
>> "resources" (a
>> mapping of
>> resources), just have "resource", which can be the
>> template definition
>> for a single resource. This would then allow the
>> user to specify a
>> Stack
>> resource if they want to provide multiple resources.
>> How does that
>> sound?
>>
>>
>> My thought was this (digging into the implementation
>> here a bit):
>>
>> - Basically, the autoscaling code works as it does now:
>> creates a
>> template
>> containing OS::Nova::Server resources (changed from
>> AWS::EC2::Instance),
>> with the properties obtained from the LaunchConfig, and
>> creates a
>> stack in
>> Heat.
>> - LaunchConfig can now contain any properties you like
>> (I'm not 100%
>> sure
>> about this one*).
>> - The user optionally supplies a template. If the
>> template is
>> supplied, it
>> is passed to Heat and set in the environment as the
>> provider for the
>> OS::Nova::Server resource.
>>
>>
>> I don't like the idea of binding to OS::Nova::Server
>> specifically for
>> autoscaling. I'd rather have the ability to scale *any*
>> resource,
>> including
>> nested stacks or custom resources. It seems like jumping
>> through hoops to
>>
>>
>> big +1 here, autoscaling should not even know what it is
>> scaling, just
>> some resource. solum might want to scale all sorts of non-server
>> resources (and other users).
>>
>>
>> I'm surprised by the negative reaction to what I suggested, which is
>> a completely standard use of provider templates. Allowing a
>> user-defined stack of resources to stand in for an unrelated
>> resource type is the entire point of providers. Everyone says that
>> it's a great feature, but if you try to use it for something they
>> call it a "hack". Strange.
>>
>>
>> To clarify this position (which I already did in IRC), replacing one
>> concrete resource with another that means something in a completely
>> different domain is a hack -- say, replacing "server" with "group of
>> related resources". However, replacing OS::Nova::Server with something
>> which still does something very much like creating a server is
>> reasonable -- e.g., using a different API like one for creating
>> containers or using a different cloud provider's API.
>
> Sure, but at the end of the day it's just a name that is used internally
> and which a user would struggle to even find referenced anywhere (I
> think if they look at the resources created by the autoscaling template
> it *might* show up). The name is completely immaterial to the idea, as
> demonstrated below where I did a straight string substitution (1 line in
> the environment) for a better name and nothing changed.
>
>> So, allow me to make a slight modification to my proposal:
>>
>> - The autoscaling service manages a template containing
>> OS::Heat::ScaledResource resources. This is an imaginary resource
>> type that is not backed by a plugin in Heat.
>> - If no template is supplied by the user, the environment declares
>> another resource plugin as the provider for OS::Heat::ScaledResource
>> (by default it would be OS::Nova::Server, but this should probably
>> be configurable by the deployer... so if you had a region full of
>> Docker containers and no Nova servers, you could set it to
>> OS::Docker::Container or something).
>> - If a provider template is supplied by the user, it would be
>> specified as the provider in the environment file.
>>
>> This, I hope, demonstrates that autoscaling needs no knowledge
>> whatsoever about what it is scaling to use this approach.
>>
>>
>> It'd be interesting to see some examples, I think. I'll provide some
>> examples of my proposals, with the following caveats:
>
> Excellent idea, thanks :)
>
>> - I'm assuming a separation of launch configuration from scaling group,
>> as you proposed -- I don't really have a problem with this.
>> - I'm also writing these examples with the plural "resources" parameter,
>> which there has been some bikeshedding around - I believe the structure
>> can be the same whether we go with singular, plural, or even
>> whole-template-as-a-string.
>>
>> # trivial example: scaling a single server
>>
>> POST /launch_configs
>>
>> {
>> "name": "my-launch-config",
>> "resources": {
>> "my-server": {
>> "type": "OS::Nova::Server",
>> "properties": {
>> "image": "my-image",
>> "flavor": "my-flavor", # etc...
>> }
>> }
>> }
>> }
>
> This case would be simpler with my proposal, assuming we allow a default:
>
> POST /launch_configs
>
> {
> "name": "my-launch-config",
> "parameters": {
> "image": "my-image",
> "flavor": "my-flavor", # etc...
> }
> }
>
> If we don't allow a default it might be something more like:
>
>
> POST /launch_configs
>
> {
> "name": "my-launch-config",
> "parameters": {
> "image": "my-image",
> "flavor": "my-flavor", # etc...
> },
> "provider_template_uri":
> "http://heat.example.com/<tenant_id>/resources_types/OS::Nova::Server/template"
>
> }
>
>
>> POST /groups
>>
>> {
>> "name": "group-name",
>> "launch_config": "my-launch-config",
>> "min_size": 0,
>> "max_size": 0,
>> }
>
> This would be the same.
>
>>
>> (and then, the user would continue on to create a policy that scales the
>> group, etc)
>>
>> # complex example: scaling a server with an attached volume
>>
>> POST /launch_configs
>>
>> {
>> "name": "my-launch-config",
>> "resources": {
>> "my-volume": {
>> "type": "OS::Cinder::Volume",
>> "properties": {
>> # volume properties...
>> }
>> },
>> "my-server": {
>> "type": "OS::Nova::Server",
>> "properties": {
>> "image": "my-image",
>> "flavor": "my-flavor", # etc...
>> }
>> },
>> "my-volume-attachment": {
>> "type": "OS::Cinder::VolumeAttachment",
>> "properties": {
>> "volume_id": {"get_resource": "my-volume"},
>> "instance_uuid": {"get_resource": "my-server"},
>> "mountpoint": "/mnt/volume"
>> }
>> }
>> }
>> }
>
> This appears slightly more complex on the surface; I'll explain why in a
> second.
>
> POST /launch_configs
>
> {
> "name": "my-launch-config",
> "parameters": {
> "image": "my-image",
> "flavor": "my-flavor", # etc...
> }
> "provider_template": {
> "hot_format_version": "some random date",
> "parameters" {
> "image_name": {
> "type": "string"
> },
> "flavor": {
> "type": "string"
> } # &c. ...
> },
> "resources" {
> "my-volume": {
> "type": "OS::Cinder::Volume",
> "properties": {
> # volume properties...
> }
> },
> "my-server": {
> "type": "OS::Nova::Server",
> "properties": {
> "image": {"get_param": "image_name"},
> "flavor": {"get_param": "flavor"}, # etc...
> }
> },
> "my-volume-attachment": {
> "type": "OS::Cinder::VolumeAttachment",
> "properties": {
> "volume_id": {"get_resource": "my-volume"},
> "instance_uuid": {"get_resource": "my-server"},
> "mountpoint": "/mnt/volume"
> }
> }
> },
> "outputs" {
> "public_ip_address": {
> "Value": {"get_attr": ["my-server",
> "public_ip_address"]} # &c. ...
> }
> }
> }
>
> (BTW the template could just as easily be included in the group rather
> than the launch config. If we put it here we can validate the parameters
> though.)
>
> There are a number of advantages to including the whole template, rather
> than a resource snippet:
> - Templates are versioned!
> - Templates accept parameters
> - Templates can provide outputs - we'll need these when we go to do
> notifications (e.g. to load balancers).
>
> The obvious downside is there's a lot of fiddly stuff to include in the
> template (hooking up the parameters and outputs), but this is almost
> entirely mitigated by the fact that the user can get a template, ready
> built with the server hooked up, from the API by hitting
> /resource_types/OS::Nova::Server/template and just edit in the Volume
> and VolumeAttachment. (For a different example, they could of course
> begin with a different resource type - the launch config accepts any
> keys for parameters.) To the extent that this encourages people to write
> templates where the outputs are actually supplied, it will help reduce
> the number of people complaining their load balancers aren't forwarding
> any traffic because they didn't surface the IP addresses.
>
>>
>> (and so on, creating the group and policies in the same way).
>
> ditto.
>
>> Can you please provide an example of your proposal for the same use
>> cases? Please indicate how you'd specify the custom properties for each
>> resource and how you specify the provider template in the API.
>
> As you can see, it's not really different, just an implementation
> strategy where all the edge cases have already been worked out, and all
> the parts already exist.
>
> cheers,
> Zane.
>
> _______________________________________________
> OpenStack-dev mailing list
> OpenStack-dev at lists.openstack.org
> http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev
More information about the OpenStack-dev
mailing list