Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Doing Multi-Cloud the Easy Way... But should you?

Nico Krijnen
October 19, 2023

Doing Multi-Cloud the Easy Way... But should you?

In today's rapidly evolving technological landscape, organizations are increasingly adopting cloud computing as a means to enhance scalability and flexibility. However, multi-cloud makes this a complex decision process.

Tools like Kubernetes, Terraform, and Dapr simplify multi-cloud by providing a unified programming model that work seamlessly across different clouds.

That sounds great! Almost too good to be true? What are the trade-offs that they bring? Do they truly prevent vendor lock-in? And what are you loosing by not making full use of what your cloud vendor has to offer?

Nico Krijnen

October 19, 2023
Tweet

More Decks by Nico Krijnen

Other Decks in Business

Transcript

  1. Go Multi-Cloud? • You require extreme redundancy and reliability •

    You want to avoid vendor lock-in • It happened to you (acquisition) • Customers want to run on 'their' cloud • You want to minimize costs
  2. Multi-Cloud is not trivial • Manage diverse infrastructure • Complex

    in deployment and maintenance • Performance & data transfer concerns • Data gravity • Fragmented security solutions • Explosion of required knowledge
  3. Doing Multi-Cloud the Easy Way But should you? Nico Krijnen

    Doing Multi-Cloud the Easy Way @nicokrijnen nkrijnen nicokrijnen
  4. k-proxy kubelet sched sched sched Control Plane Node etcd Kubernetes

    cluster api api api c-c-m c-c-m c-c-m c-m c-m c-m Node Node k-proxy kubelet kubelet k-proxy Control plane Scheduler sched Cloud controller manager (optional) c-c-m Controller manager c-m kubelet kubelet kube-proxy k-proxy (persistence store) etcd etcd Node API server api
  5. AWS Azure GCP Kubernetes / EKS Database Pod Application Pod

    Database Pod Application Pod Application Pod Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Redis Pod Sidecar Sidecar Grafana Pod ArgoCD Pod Prometheus Pod Ingress Controller Cilium CNI External Secrets Operator
  6. AWS Azure GCP On premise Kubernetes / EKS Database Pod

    Application Pod Database Pod Application Pod Application Pod Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Sidecar Redis Pod Sidecar Sidecar Grafana Pod ArgoCD Pod Prometheus Pod Ingress Controller Cilium CNI External Secrets Operator
  7. !

  8. !

  9. Where does it break? "When we think about building cloud

    abstractions, finding suitable abstractions is difficult enough. But even that is only half the story. We also need to find a “stack trace”, a path back from any failure point to determining what to change at the abstraction layer to correct it." – Gregor Hohpe architectelevator.com/architecture/stacktrace-abstraction/
  10. Dapr - Queue pub/sub private val daprClient = DaprClientBuilder().build() fun

    publishEvent(event: CarEnteredEvent) { println("Publishing $event") val publishEventRequest = PublishEventRequest( pubsubName = "eventbus", topic = "cartelemetry", data = event ) daprClient.publishEvent(publishEventRequest).block() } !!" @Topic(name = "cartelemetry", pubsubName = "eventbus") @PostMapping("/cartelemetry") fun handleQueueMessage( @RequestBody(required = false) cloudEvent: CloudEvent<CarEnteredEvent> ) { handleCarTelemetry(cloudEvent.data) } private fun handleCarTelemetry(event: CarEnteredEvent) { println("Car ${event.licensePlate} at ${event.time}") } apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: cartelemetry spec: type: bindings.aws.sqs version: v1 metadata: - name: queueName value: "cartelemetry" - name: region value: "us-west-2" - name: accessKey value: "*****************" - name: secretKey value: "*****************" - name: sessionToken value: "*****************" - name: direction value: "input, output"
  11. Dapr vs AWS native private val daprClient = DaprClientBuilder().build() fun

    publishEvent(event: CarEnteredEvent) { println("Publishing $event") val publishEventRequest = PublishEventRequest( pubsubName = "eventbus", topic = "cartelemetry", data = event ) daprClient.publishEvent(publishEventRequest).block() } !!" @Topic(name = "cartelemetry", pubsubName = "eventbus") @PostMapping("/cartelemetry") fun handleQueueMessage( @RequestBody(required = false) cloudEvent: CloudEvent<CarEnteredEvent> ) { handleCarTelemetry(cloudEvent.data) } private fun handleCarTelemetry(event: CarEnteredEvent) { println("Car ${event.licensePlate} at ${event.time}") } private val sqs = AmazonSQSClientBuilder.defaultClient() fun publishEvent(event: CarEnteredEvent) { println("Publishing $event") val sendMessageRequest = SendMessageRequest() .withQueueUrl(queueUrl) .withMessageBody(event.toJson()) sqs.sendMessage(sendMessageRequest) } !!" @PostConstruct private fun handleQueueMessages() { while (true) { val result = sqs.receiveMessage(queueUrl) result.messages.forEach { msg !" handleCarTelemetry(msg.body.fromJson()) sqs.deleteMessage(queueUrl, msg.receiptHandle) } } } private fun handleCarTelemetry(event: CarEnteredEvent) { println("Car ${event.licensePlate} at ${event.time}") }
  12. Dapr vs AWS native private val daprClient = DaprClientBuilder().build() fun

    publishEvent(event: CarEnteredEvent) { println("Publishing $event") val publishEventRequest = PublishEventRequest( pubsubName = "eventbus", topic = "cartelemetry", data = event ) daprClient.publishEvent(publishEventRequest).block() } !!" @Topic(name = "cartelemetry", pubsubName = "eventbus") @PostMapping("/cartelemetry") fun handleQueueMessage( @RequestBody(required = false) cloudEvent: CloudEvent<CarEnteredEvent> ) { handleCarTelemetry(cloudEvent.data) } private fun handleCarTelemetry(event: CarEnteredEvent) { println("Car ${event.licensePlate} at ${event.time}") } private val sqs = AmazonSQSClientBuilder.defaultClient() fun publishEvent(event: CarEnteredEvent) { println("Publishing $event") val sendMessageRequest = SendMessageRequest() .withQueueUrl(queueUrl) .withMessageBody(event.toJson()) .withDelaySeconds(5) sqs.sendMessage(sendMessageRequest) } !!" @PostConstruct private fun handleQueueMessages() { while (true) { val request = ReceiveMessageRequest(queueUrl) .withVisibilityTimeout(10) val result = sqs.receiveMessage(request) result.messages.forEach { msg !" handleCarTelemetry(msg.body.fromJson()) sqs.deleteMessage(queueUrl, msg.receiptHandle) } } } private fun handleCarTelemetry(event: CarEnteredEvent) { println("Car ${event.licensePlate} at ${event.time}") }
  13. • Developer experience! " • Local simulation # $ •

    Auto-generate least privilege IAM policies %& • Built for the cloud from the start (it's still the start ')
  14. Spread your wings class Backend { api: cloud.Api; pub storage:

    cloud.Bucket; init() { this.api = new cloud.Api(); this.storage = new cloud.Bucket(); this.api.put("/car/entered", inflight (request) => { log("Received ${request.body}"); let body = Json.tryParse(request.body); let event: events.CarEnteredEvent = events.CarEnteredEvent.fromJson(body); let fileKey = "${event.licensePlate}.json"; let records: Json? = this.storage.tryGetJson(fileKey); let addRecord = (records: Json?, toAdd: Json): Json => { if records? { let newRecords = Json.deepCopyMut(records); let count: num = newRecords.get("length").asNum(); log("Adding to ${count} records"); newRecords.setAt(count, toAdd); return Json.deepCopy(newRecords); } else { log("Adding first record"); return Json [ event ]; } }; let fileBody = addRecord(records, Json event); this.storage.putJson(fileKey, fileBody); return cloud.ApiResponse { status: 200, headers: { "Content-Type" => "text/plain" }, body: "Ok" }; }); this.api.get("/license-plates/unique", inflight (request) => { let files = this.storage.list(); return cloud.ApiResponse { status: 200, headers: { "Content-Type" => "application/json" }, body: Json.stringify(Json { "uniquePlateCount": files.length }) }; }); } pub getApiUrl(): str { return this.api.url; } }
  15. Navigating lock-in Total investment budget Investment to add value Investment

    to allow switch ☁ ↻ Investment to make switch
  16. Navigating lock-in Investment to add value Investment to make switch

    ☁ ↻ Investment to add value Investment to allow switch ☁ ↻ Investment to make switch
  17. Navigating lock-in , - Investment to add value Investment to

    make switch ☁ ↻ Investment to add value Investment to allow switch ☁ ↻ Investment to make switch
  18. Go Multi-Cloud? • You require [extreme] redundancy and reliability .

    • You want to avoid vendor lock-in • It happened to you • You want to minimize costs you have lock-in anyway ! let each org unit stay on the cloud they're on ☁ ☁ operating multiple clouds is not free /
  19. But should you? Doing Multi-Cloud the Easy Way Maximize adding

    value now, while reducing the cost of being wrong.
  20. But should you? Have a plan & make well-considered choices,

    that work for your context. Doing Multi-Cloud the Easy Way