11.6.18

Kube is so easy, that you don't even need it for everything.

Once you adopt a cloud native platform

You can ironically not only use containers more easily.

But... you can also *NOT* use them more easily.

That is - kubernetes prevents vendor lockin just as much as it creates platform lockin.

How's that? 

When you containerize your application its more portable, but it still requires one thing: STATE.

State is hard to maintain, and even harder to maintain in a container. 

So, when you need to deal with state in a cloud native environment you can either:

- use a persistent volume
- make replciation work in your cluster by using a distributed database.
- rely on an external service.

However, since your in a cloud native environment, you can rely on the fact that you have access to the cloud's own machinery, and therefore, you can provision a database, or disk, or any such object using APIs that are known to always  be present, and possibly globally secured in your kubernetes cluster.

What does that mean ? It means you can make an operator or controller which does something like this.

What it really means to be Cloud Native.

Being Cloud Native means that you actually know your in a cloud, you know how to talk to the cloud, and your not ashamed to take advantage of platform specific luxuries that come from a cloud-aware API offering.

Once your inside of the cloud, you often give up on that fantasy entirely, and just embrace the fact that you have a scheduler, a hypervisor, and a resource API that can provide you a commoditized version of any resource you might ever need.

And no thats not a bad thing ~ here's an example of why.

Example: Using database clones as the storage creation mechanism in a SAAS

An example of something you can easily do in a cloud native environment for state is the use of a service account, along with a service catalog resource, to mass produce hosted database instances in something like google cloud (GCloud SQL) or AWS (EC2 RDS)

Database cloning is something you don't think alot about until you start 'mass producing' apps for end users in a SAAS style environment, because it simply isn't an obviously transparent thing to do.  when your outside of a cloud, you typically want your app to be as decoupled from the infrastructure as possible so that its platform independent.
 
Clones instead of database backup files:

- Avoid risks associating with database dumps that have a missing character, don't migrate cleanly.
- Give you on-demand performance testing without requiring bootstrapping.  For example, to reproduce a complex issue for your QA team, you can have a namespace with stopped containers that is configured to point to a database that you turn 'off' for a long time when they arent on the case.
- Give you a way to ensure that any database 'backup' you have actually works, at some point.
- Cost you far less in the long run then you might think ~ you may be deploying 100s of SAAS instances, and only need 1 clone for their base schema, and maybe just a few other clones for canonical data sets, etc.
- Give you a ridiculously simple way to backup your databases: Don't delete them in the first place.

In any case, here's how i do it in GCloud.  Just create a single static 'object.prototype' version of your database, and clone from it when you have a new 'customer'...

Example: How to provision a CloudSQL database based on a templated database.

package main

import (
"fmt"
"time"

"golang.org/x/net/context"
"golang.org/x/oauth2/google"

sql "google.golang.org/api/sqladmin/v1beta4"
sqladmin "google.golang.org/api/sqladmin/v1beta4"
)

func main() {
// Use oauth2.NoContext if there isn't a good context to pass in.
ctx := context.Background()
client, err := google.DefaultClient(ctx, sqladmin.SqlserviceAdminScope)
if err != nil {
fmt.Print("error")
}
sqlAdmin, _ := sql.New(client)
cr := &sql.InstancesCloneRequest{
CloneContext: &sql.CloneContext{
DestinationInstanceName: "cloned-big",
},
}
fmt.Print("2 \n")
op, err := sqlAdmin.Instances.Clone("gke-verification", "opssight-4-7-2018-06-06-19-23-34", cr).Do()
for {
inst, err := sqlAdmin.Instances.Get("my-project", "cloned-db").Do()
fmt.Print(fmt.Sprintf("%v %v", op, err))
fmt.Print(fmt.Sprintf("instance: %v , disk: %v", inst.State, inst.CurrentDiskSize))
time.Sleep(10 * time.Second)
}
}

No comments:

Post a Comment