Share
Comparing Kubernetes and Dapr: Overlaps and Differences
If Kubernetes has service discovery, why would you use Dapr service invocation? If Kubernetes can manage stateful applications, what makes Dapr's state store API necessary? What is the difference between Kubernetes CronJob and Dapr cron? How do the distributed lock implementations in Kubernetes and Dapr compare?
Such questions frequently puzzle developers familiar with Kubernetes when they are introduced to Dapr's features.
In this presentation we will look at these areas where Kubernetes and Dapr differ, showcasing how Dapr complements Kubernetes by addressing the specific needs of developers. If you know Kubernetes, this article will show what you might be missing and how Dapr can enhance the work of both operations teams and developers.
Bilgin Ibryam
Transcript
75 slides
-
Comparing Kubernetes and Dapr: Overlaps and Differences Bilgin Ibryam @bibryam
Product Manager, Diagrid -
Agenda • K8s App lifecycle vs Dapr Deployments • K8s
Services vs. Dapr Service Invocation API • K8s Health Probes vs. Dapr App Health Check • K8s vs. Dapr for creating EDA • K8s StatefulSet vs. Dapr Workflow • K8s PVCs vs. Dapr State API • K8s CronJob vs. Dapr Cron • K8s Lease vs. Dapr Distributed Lock API • K8s ConfigMap vs. Dapr Config API -
Why Should I talk about this topic? • Product Manager
at Diagrid • Former Architect/PM at Red Hat • Former Committer at Apache Camel • Blogger and Author ◦ Camel Design Patterns ◦ Kubernetes Patterns @bibryam https://k8spatterns.com -
Dapr APIs HTTP API gRPC API Microservices written in Application
code Any code or framework… Any cloud or edge infrastructure Microservices written in Virtual or physical machines State Management Distributed Lock Publish and Subscribe Service Invocation Secrets Bindings (In/Out) Workflows Configuration Actors Cryptography Observability Security Resiliency -
My App Over 115 Components (swappable YAML file) State Stores
Distributed Lock Pub/Sub Brokers Secret Stores Bindings & Triggers Workflow Configuration Cryptography Firebase Cassandra Redis Azure CosmosDB AWS DynamoDB Redis AWS SQS Azure Service Bus RabbitMQ GCP Pub/Sub GCP Storage AWS S3 Kafka Azure Storage Twilio AWS Secrets Manager Azure KeyVault GCP Secret Manager HashiCorp Vault Kubernetes Secret Redis Redis Dapr Workflow Azure KeyVault Kubernetes Secret Dapr Components Azure App Config PostgreSQL Redis PostgreSQL Azure CosmosDB MongoDB AWS DynamoDB Actors -
Dapr state API Save state POST /v1.0/state/orderstore Retrieve state GET
/v1.0/state/orderstore/myorder1 Delete state DELETE /v1.0/state/orderstore/myorder1 Get bulk state POST /v1.0/state/orderstore/bulk Submit multiple state transactions POST /v1.0/state/orderstore/transaction Redis Component apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderstore spec: type: state.redis version: v1 metadata: - name: redisHost value: redis.default.svc.cluster.local:6379 - name: redisPassword value: supersecret -
Dapr state API Save state POST /v1.0/state/orderstore Retrieve state GET
/v1.0/state/orderstore/myorder1 Delete state DELETE /v1.0/state/orderstore/myorder1 Get bulk state POST /v1.0/state/orderstore/bulk Submit multiple state transactions POST /v1.0/state/orderstore/transaction CosmosDB Component apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: orderstore spec: type: state.azure.cosmosdb version: v1 metadata: - name: url value: corpdb.documents.azure.com - name: masterKey secretKeyRef: name: master-key key: cosmos-key - name: database value: orders - name: collection value: processed -
Dapr Control Plane on Kubernetes Diagrid Conductor $ kubectl create
-f https://operatorhub.io/install/dapr-k ubernetes-operator.yaml Dapr Operator from OperatorHub.io Helm $ dapr init -k Dapr CLI $ helm upgrade --install dapr dapr/dapr \ --version=1.13 https://www.diagrid.io/conductor -
Dapr Data Plane Deployments My App Dapr API HTTP/gRPC Application
Code Dapr Runtime -
Sidecar Model kind: Deployment / StatefulSet … annotations: dapr.io/enabled: "true"
dapr.io/app-id: "my-app" dapr.io/app-port: "8080" (for long-lived workloads) -
Dapr-Shared Model Trade Offs Advantages • Faster startup times (Knative,
OpenFunctions) • Reduced resource usage • No App restart on Dapr upgrade Disadvantages • Shared downtime • Noisy neighbor • Manual scaling DaemonSet / Deployment https://github.com/dapr/dapr-shared (for serverless workloads) -
Job Model package main import ( "context" "log" "os" dapr
"github.com/dapr/go-sdk/client" ) func main() { client, err := dapr.NewClient() if err != nil { log.Panic(err) } defer client.Close() defer client.Shutdown() } apiVersion: batch/v1 kind: Job / CronJob metadata: name: my-job spec: template: metadata: annotations: dapr.io/enabled: "true" dapr.io/app-id: "with-shutdown" spec: containers: - name: job image: alpine command: ["/bin/sh"] restartPolicy: Never (for short-lived tasks) -
Application Lifecycle Kubernetes Kubernetes manages heterogeneous workloads regardless of the
language, including stateless, stateful, serverless (through Knative), and short-lived jobs. Dapr Dapr doesn't manage the application lifecycle, but it adapts to all of these: stateless, serverless, stateful, and short-lived jobs. -
Kubernetes Health Probes • Startup Probe ◦ Restarting containers if
startup probes fails • Readiness Probe ◦ Removing from service endpoint if readiness probe fails • Liveness Probe ◦ Restarting containers if liveness probes fails ▪ Probe methods ▪ HTTP endpoint ▪ gRPC endpoint ▪ TCP socket endpoint ▪ Unix command return value -
Dapr Sidecar Health readinessProbe: httpGet: path: v1.0/healthz port: 3500 initialDelaySeconds:
5 periodSeconds: 10 timeoutSeconds : 5 failureThreshold: 3 livenessProbe: httpGet: path: v1.0/healthz port: 3500 initialDelaySeconds: 5 periodSeconds: 10 timeoutSeconds : 5 failureThreshold : 3 My App kubelet HTTP /healthz HTTP /healthz HTTP /healthz/outbound -
Dapr App Health Checks kind: Deployment … annotations: dapr.io/enabled: "true"
dapr.io/app-id: "my-app" dapr.io/app-port: "7001" dapr.io/app-protocol: "http" dapr.io/enable-app-health-check: "true" dapr.io/app-health-check-path: "/healthz” My App App health check (failed) Dapr stops accepting new work • Short-circuiting all service-invocation requests • Unsubscribing from all pub/sub subscriptions • Stopping all input bindings requests ✓ X -
Health Checks Kubernetes Reboots applications to rectify issues Redirects incoming
traffic away from unhealthy app instances Dapr Stops outgoing connections on behalf of the app -
Kubernetes Service Discovery External Service Discovery Internal Service Discovery Advantages
• Simplifies access to pods through service discovery • Provides load balancing across pods to distribute traffic • Integrates with DNS for easy name resolution Limitations • Lacks built-in resiliency features like retries, circuit breakers, and timeouts • Does not offer tracing or network metrics • Does not support traffic encryption -
Dapr Service Invocation API POST http://localhost:3500/v1.0/invoke/checkout/method/order POST http://localhost:5100/order Shopping cart
Checkout DNS Service discovery Access Control Resiliency mTLS encryption Observability token authentication token authentication -
Dapr Service Invocation API Features • Service discovery (Kubernetes, HashiCorp
Consul, SQLite, mDNS) • Mitigating request timeouts or transient failures. • Built-in distributed tracing & metrics • Access control policies • End-to-end security and mTLS • Chain pluggable middleware components const order = {orderId: 1}; const url = `localhost:3500/order` const response = await fetch(url, { method: "POST", headers: { "dapr-app-id": "checkout", }, body: JSON.stringify(order), }); -
Kubernetes - Network Policy kind: NetworkPolicy apiVersion: networking.k8s.io/v1 metadata: name:
allow-database spec: podSelector: matchLabels: id: checkout ingress: - from: - podSelector: matchLabels: id: shopping-cart Features • Pod-level network isolation • Supports both IP address and namespace-based rules • Defines inbound and outbound traffic rules • Allows for TCP/UDP/SCTP and port-based filtering Notification services Pod Checkout Pod Shopping cart Pod -
Service Invocation: Access Control Features • Unique App Identity based
on SPIFFE ID • Granular access control (Layer 7) • HTTP verbs / Path or gRPC operation • Support for both HTTP and gRPC protocols apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: checkout-config spec: accessControl: defaultAction: deny trustDomain: "public" policies: - appId: shopping-cart defaultAction: deny trustDomain: 'public' namespace: "default" operations: - name: /order httpVerb: ['POST'] action: allow -
Synchronous Interactions Kubernetes • Service discovery and load balancing across
pods • L3/L4 network policies Dapr • Traffic encryption • Resiliency policies • Distributed tracing & metrics • L7 granular access control • Swappable service discovery • Pluggable middleware -
Dapr Pub/Sub API POST http://localhost:3500/v1.0/publish/mybroker/order-messages POST http://localhost:5100/orders Checkout Shipping Observability
backend Message broker Cloudevents Access Control Resiliency token authentication token authentication Encryption -
Dapr Pub/Sub API const client = new DaprClient({ daprHost, daprPort
}); const order = { orderId: 1 }; await client.pubsub.publish(“mypubsub”, “new-orders”, order); Publish Subscribe (Dapr pushes each message to the app) const server = new DaprServer({ serverHost, serverPort, clientOptions: { daprHost, daprPort } }); server.pubsub.subscribe(“mypubsub”, “new-orders”, data => console.log("Received:" + JSON.stringify(data)) ); await server.start(); stop, err := cl.SubscribeWithHandler(context.Background(), client.SubscriptionOptions{ PubsubName: "pubsub", Topic: "orders", }, eventHandler, ) Streaming Subscription (Bidirectional stream between app/sidecar ) Features • Integrates with many message brokers and queues • Push or Pull mode for subscriptions • Content-based message routing and filtering • Aggregator/Splitter through message batches • Dead-letter topics and resiliency policies • Access control per topic • Message expiration • Delayed delivery (coming soon) -
Event-driven Interactions Kubernetes • Platform for other projects: Knative Eventing,
Strimzi, KEDA, CloudEvents, Dapr.. Dapr • Message broker abstraction • Push or Pull mode for subscriptions • Content-based message routing and filtering • Aggregator/Splitter through message batches • Dead-letter topics and resiliency policies • Access control per topic • Message expiration • Delayed delivery (coming soon) -
Kubernetes Storage Abstraction (PVs) PVC accessModes • ReadWriteOnce a volume
that can be mounted to a single node at a time. • ReadOnlyMany The volume can be mounted to multiple nodes • ReadWriteMany - the volume can be mounted by many nodes • ReadWriteOncePod - guarantees that only a single Pod has access to a volume. -
Dapr StateStore API GET http://localhost:3500/v1.0/state/mystatestore/order1 POST http://localhost:3500/v1.0/state/mystat estore [{ “key”:
“order1”, “value”: “{orderId: 1}” }] Read Operation Write Operation Features • Integrates with many state stores • Concurrency: first-write / last-write; • Consistency behaviors: strong / eventual • Transactional operations • Resiliency policies • Bulk operations • Time-to-Live (TTL) • Data at rest encryption • Limit access per app (not operation) -
Transactional Outbox Pattern apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: mysql-outbox
spec: type: state.mysql version: v1 metadata: - name: connectionString value: "<CONNECTION STRING>" - name: outboxPublishPubsub # Required value: "mypubsub" - name: outboxPublishTopic # Required value: "newOrder" -
State Management Kubernetes • Provides durable storage abstraction over the
file system interface Dapr • Key/Value API with powerful features independent of the storage providers -
Stateful Workloads on Kubernetes Features • Unique instance identity •
Stable network address • Stable ordinality • Non-shared persistent storage • Minimal availability (quorum) -
Stateful Workloads with Dapr Workflows Features • Durable execution with
persisted state • Author workflows in C#, Java, Python or JavaScript • Apply patterns such as: chaining, Split/Synchronize, external trigger, durable timers, child workflows. -
Split/Syncrhonize with .NET SDK // Get a list of N
work items to process in parallel. object[] workBatch = await context.CallActivityAsync<object[]>("GetWorkBatch", null); // Schedule the parallel tasks, but don't wait for them to complete yet. var parallelTasks = new List<Task<int>>(workBatch.Length); for (int i = 0; i < workBatch.Length; i++) { Task<int> task = context.CallActivityAsync<int>("ProcessWorkItem", workBatch[i]); parallelTasks.Add(task); } // Everything is scheduled. Wait here until all parallel tasks have completed. await Task.WhenAll(parallelTasks); // Aggregate all N outputs and publish the result. int sum = parallelTasks.Sum(t => t.Result); await context.CallActivityAsync("PostResults", sum); -
End Activity A Activity B Activity C Start End Activity
A Activity B Activity C Start Activity CreateTimer Continue As New Start Wait with further execution Restart the workflow Wait for event Approval Event End Get Approval Not Approved Start Approved Sequence Split/Synchronize Timer External trigger -
Stateful Workloads Kubernetes • Coarse-grained, process-level orchestration • Start/stop processes
in sequence • Manage storage Dapr • Define stateful business processes in code • Durable execution guarantees • Flexible storage options -
Jobs in Kubernetes Job - is an isolated atomic unit
of work run until completion. apiVersion: batch/v1 kind: Job metadata: name: test-job spec: template: metadata: name: test-job spec: containers: - name: test image: alpine:latest command: - "bin/sh" - "-c" - "for i in 1 2 3 4 5 ; do echo $i ; done" restartPolicy: Never -
Actors in Dapr public class HelloWorldActorImpl extends AbstractActor implements HelloWorldActor
{ public HelloWorldActorImpl(ActorRuntimeContext runtimeContext, String id) { super(runtimeContext, id); } @Override public CompletableFuture<String> sayHello(String name) { return CompletableFuture.completedFuture("Hello " + name); } } Features • No concurrency or threading required • Built-in distribution and fail-over • State is persisted in a configurable state store -
Recurring Tasks in Kubernetes • CronJob - allows the execution
of a unit of work to be triggered by a temporal event. apiVersion: batch/v1 kind: CronJob metadata: name: hello-world-cronjob spec: schedule: "*/1 * * * *" # Runs every minute jobTemplate: spec: template: spec: containers: - name: hello image: busybox args: - /bin/sh - -c - echo "Hello, World!" restartPolicy: OnFailure -
Cron Binding in Dapr (Jobs API in v1.14) My App
HTTP POST Application Code Dapr runtime apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: my-job spec: type: bindings.cron version: v1 metadata: - name: schedule value: "@every 15m" -
Tasks Kubernetes • Job: Finite unit of computation ◦ Runs
a container • CronJob as temporal tasks Dapr • Actors as a “unit of computation” ◦ Runs a class/function • Actor timers/reminders • Cron Binding - stateless cron • (New Jobs API) - stateful cron -
Distributed Locks in Kubernetes • Runs a single replica with
StatefulSet • Hold a lock on Kubernetes ConfigMaps • Use Kubernetes Lease resource • Custom distributed lock e.g.: ◦ Zookeeper ◦ Consul ◦ Redis ◦ etcd -
Dapr Distributed Lock API ✖ Lock acquired Waiting for the
lock curl -X POST http://localhost:3500/v1.0-alpha1/lock/lockstore -H 'Content-Type: application/json' -d ' {"resourceId":"my_file_name", "lockOwner":"abc123", "expiryInSeconds": 60}' -
Distributed Locks Kubernetes • StatefulSet - process lock • Lease
resource - for Kubernetes itself and custom controllers Dapr • Simple HTTP based lock API -
Configurations and Secrets Kubernetes • Requires pod restarts or app
reloads for changes • Scoped at the namespace level Dapr • Supports dynamic updates without restarts • Scoped to specific services or applications • Supports multiple config and secret stores -
Bindings API for bi-directional connection to 3rd-party systems Resiliency: Retries/Back-offs,
Timeouts, Circuit Breakers Observability: Distributed Tracing, Network Metrics, Logs. Crypto API for encrypting and decrypting messages Other Dapr APIs -
Kubernetes or Dapr? Kubernetes enables Ops to operate heterogeneous applications
on any infrastructure, with consistent abstractions. Dapr eables Devs to implement polyglot applications, using any backing infrastructure and interaction style, with consistent APIs.