Відкрийте для себе можливості Dapr у системах, що працюють за подієвим принципом.

Dapr (Distributed Application Runtime) — це відкритий, подієвий, переносний виконуваний середовище, яке надає основні компоненти для створення стійких, масштабованих та розподілених додатків.

Необхідні умови

  • minikube
  • Системи Dapr: dapr init — kubernetes
  • Redis: minikube pod
  • MongoDB: minikube pod
  • Розгортання компонента dapr
  • Демонстраційний API статей (.net)

Огляд

pic

Структура знань

pic

Бізнесові переваги

pic

  • Зосередженість на бізнес-логіці та прискорений розвиток за меншу вартість.
  • Дозволяє поступову модернізацію додатків без перерв, використовуючи вже наявні інвестиції.
  • Забезпечує гнучкість і здатність швидко змінювати інфраструктурний дизайн та реалізацію.
  • Незалежність від хмар та платформ.
  • Відкритий код та підтримка спільноти.
  • Безкоштовне використання.

Інженерні переваги

pic

  • Попередньо побудовані компоненти для вирішення типових проблем.
  • Узгоджений досвід інтеграції.
  • Легке з'єднання мікросервісів для більш стійкої архітектури.
  • Можливість налаштування компонентів для надання розширюваності.
  • Забезпечує можливість мокування інфраструктури для тестування інтеграцій.

Ключові концепції

  • Sidecar
  • Компонент
  • Схема компонента
  • Основні блоки

Sidecar

pic

  • Sidecar є основним елементом системи Dapr.
  • Sidecar Dapr — це процес або контейнер, який працює поряд з основним додатком, щоб надати додаткову функціональність або сервіси.
  • Кожен екземпляр додатка має свій унікальний Dapr sidecar.
  • Dapr sidecar називається "daprd".
  • У K8S Dapr sidecar є контейнером, який працює разом із додатком у тому самому поді.
  • Dapr sidecar може комунікувати з різними нижчими цілями, включаючи компоненти Dapr, акторів Dapr або інші Dapr sidecar.
  • Різні будівельні блоки вимагають, щоб Dapr sidecar комунікував з різними цілями різними способами, наприклад, HTTP, gRPC або MQTT.
  • Dapr sidecar, як агент додатка, відповідає за обробку інтеграції з нижчими цілями.

pic

Компонент

pic

  • Dapr використовує модульний дизайн, де функціональність надається як компонент.
  • Компоненти Dapr надають конкретні функціональності, які можна використовувати.
  • Завдяки абстракції від деталей реалізації, компонент Dapr забезпечує узгоджений інтерфейс для взаємодії з різними сервісами, незалежно від використовуваної технології чи постачальника.
  • Для Dapr доступні підключувані компоненти. Інженерна команда може реалізувати свої власні компоненти з більш налаштованими функціями.

Схема компонента

  • Компоненти повинні бути зареєстровані перед використанням, що передбачає визначення їх у YAML-файлі за допомогою схеми компонента.
  • Розділ spec.type визначає тип компонента.
    Шаблон цього значення має вигляд [категорія].[реалізація]

приклад: state — схема компонента для mongo

pic

приклад: state — схема компонента для redis

pic

приклад: схема компонента pub-sub

pic

Основні блоки

pic

  • HTTP або gRPC API.
  • Спрощення завдань у мікросервісах.
  • Надання узгодженого API.
  • Абстрагування деталей реалізації.
  • Dapr надає різноманітні основні блоки.
  • Розширюваність.

Я продемонструю вам, що можна зробити з деякими популярними основними блоками.

Управління станом

pic

  • Абстракція сховища стану.
  • API для управління станом.
  • Конфігурація сховища стану.
  • Dapr підтримує широкий спектр сховищ стану: Redis, Cosmos DB, SQL Database, MongoDB, DynamoDB, Cassandra тощо.
    https://github.com/dapr/components-contrib/tree/master/state

Повідомлення Pub/Sub

pic

  • API для видавця.
  • API для підписника.
  • Підтримує кілька систем обміну повідомленнями, таких як Azure Service Bus, RabbitMQ, Kafka, NATS та інші.
    https://github.com/dapr/components-contrib/tree/master/pubsub
  • Повторні спроби та обробка помилок.

Виклик Сервісів

pic

  • Виклик Сервісів між Сервісами: Dapr дозволяє сервісам викликати методи або API інших сервісів за допомогою простого та узгодженого програмного моделі.
  • Підтримка різних протоколів комунікації: Dapr підтримує різноманітні протоколи комунікації, зокрема HTTP, gRPC.
  • Шаблони запиту-відповіді та "fire-and-forget": Dapr підтримує як шаблони запиту-відповіді, так і "fire-and-forget" для комунікації.
  • Розрив ланцюга та повторні спроби: Dapr включає вбудовані механізми розриву ланцюга та повторних спроб для обробки тимчасових збоїв під час викликів сервісів.

Життєвий Цикл Sidecar та Компонентів

Контрольна Плита Dapr

pic

  • Контрольна плита Dapr — це набір сервісів, що займаються керуванням та налаштуванням виконуваного середовища Dapr.
  • Чотири основні сервіси:
  • Сервіс інжектора Sidecar
  • Сервіс оператора
  • Сервіс розташування
  • Сервіс Sentry

Як це виглядає в Kubernetes

pic

Реєстрація Компонентів

pic

  • YAML файли компонентів можна застосовувати через kubectl або helm.
  • Сервіс оператора Dapr споживає YAML файл компонента та реєструє схеми компонентів як кастомні визначення ресурсів K8S.
  • Будь-які оновлення та видалення схем компонентів Dapr також обробляються сервісом оператора.

Інжекція Sidecar

pic

  • Увімкнення Dapr в розгортання додатка за допомогою анотацій Kubernetes для Dapr.
  • Інжектор Sidecar споживає файл розгортання додатка, щоб інжектувати контейнер Dapr sidecar до Kubernetes pod.
  • Dapr sidecar виконує перевірки готовності під час ініціалізації та встановлення з'єднання, щоб переконатися, що він готовий до роботи.
  • У специфічних випадках, таких як pub-sub, Dapr sidecar чекає на запуск додатка, щоб забезпечити встановлення зв'язку.

Подорож Повідомлень

pic

  • Dapr sidecar надає API через HTTP або gRPC, якими додатки можуть користуватися для взаємодії з ним.
  • Замість прямої інтеграції з ресурсами інфраструктури, Dapr спілкується з компонентами Dapr як проміжний елемент.
  • Компоненти відповідають за інтеграцію з основними інфраструктурними ресурсами.
  • Додаток може мати активну або пасивну комунікацію з sidecar залежно від типу компонента.
  • При активній комунікації додаток безпосередньо взаємодіє з Dapr sidecar, який пересилає запити до виконуваного середовища Dapr і повертає відповідь.
  • При пасивній комунікації додаток хостить API на клієнтській стороні за допомогою SDK Dapr. Sidecar перехоплює та обробляє повідомлення, що надходять до додатка через це API, виконує операції Dapr і доставляє оброблене повідомлення.

Стан Здоров'я Sidecar

pic

  • Sidecar успішно інжектовано, але виникли проблеми під час ініціалізації.
  • Sidecar надає перевірки на живучість (liveness) та готовність (readiness) для K8S.
  • Невдача перевірки живучості призведе до перезапуску контейнера, тоді як невдача перевірки готовності заборонить додатку обробляти трафік.
  • Однак, інжекція sidecar може також зазнати невдачі.
  • Sidecar може не бути інжектовано з таких причин:
    • Кластер K8S зламався, і pod додатка було запущено до того, як сервіс інжектора стартував.
    • Тимчасові збої у роботі сервісу інжектора.
  • Для вирішення цієї проблеми, сервіс оператора додав функцію watchdog інжектора, яка забезпечує наявність sidecar разом з додатком в pod.
  • Зверніть увагу, що функція watchdog інжектора вимкнена за замовчуванням.

Демонстрація

Я хочу створити API для взаємодії зі станом Dapr в середовищі Kubernetes. Ось що я намагаюся зробити:

1.
Створіть демонстраційний API з кінцевою точкою

app.MapGet("/articles/{articleId}", async (string articleId, IArticleRepository articleRepository) =>  
 await articleRepository.GetArticle(articleId))  
 .WithName("Отримати статтю за ID");
  1. В API вам знадобиться DaprClientBuilder для запитів до станів Dapr
using var client = new DaprClientBuilder().Build();  
 var queryBuilder = new DaprStateQueryBuilder()  
 .Filter(new EqFilterExpression("category", category));  
 var metadata = new Dictionary {  
 { "contentType", "application/json" },  
 { "queryIndexName", "articleCategoryIndex" }  
 };  
 var result = await client.QueryStateAsync(_stateStoreName, queryBuilder.Build(), metadata: metadata);  
 return result.Results.Select(q => q.Data).ToList();
  1. Для тестування Dapr локально на вашому комп'ютері, вам потрібно встановити minikube

  2. Створіть файл простору імен Kubernetes: kube-env-setup.yaml

apiVersion: v1  
kind: Namespace  
metadata:  
 name: apps

та застосуйте його за допомогою kubectl

kubectl apply -f ../kube-env-setup.yaml
  1. Ініціалізуйте Dapr для Kubernetes
dapr init --kubernetes --wait  

kubectl get service -n dapr-system
  1. Створіть файл розгортання для redis
apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: redis-db  
 namespace: apps  
 labels:  
 app: redis  
spec:  
 replicas: 1  
 selector:  
 matchLabels:  
 app: redis  
 template:  
 metadata:  
 labels:  
 app: redis  
 spec:  
 containers:  
 - name: redis  
 image: redis/redis-stack:latest  
 ports:  
 - containerPort: 6379  
 volumeMounts:  
 - name: redis-data  
 mountPath: /data  
 volumes:  
 - name: redis-data  
 persistentVolumeClaim:  
 claimName: redis-pvc  

---  
apiVersion: v1  
kind: Service  
metadata:  
 name: redis-db  
 namespace: apps  
spec:  
 selector:  
 app: redis  
 ports:  
 - name: redis  
 protocol: TCP  
 port: 6379  
 targetPort: 6379  
 type: NodePort  

---  
kind: PersistentVolumeClaim  
apiVersion: v1  
metadata:  
 name: redis-pvc  
 namespace: apps  
spec:  
 accessModes:  
 - ReadWriteOnce  
 storageClassName: standard  
 resources:  
 requests:  
 storage: 1Gi
  1. Створіть файл розгортання для mongo
apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: mongodb  
 namespace: apps  
 labels:  
 app: mongodb  
spec:  
 selector:  
 matchLabels:  
 app: mongodb  
 replicas: 1  
 template:  
 metadata:  
 labels:  
 app: mongodb  
 spec:  
 containers:  
 - name: mongodb  
 image: mongo:latest  
 env:  
 - name: MONGO_INITDB_ROOT_USERNAME  
 value: root  
 - name: MONGO_INITDB_ROOT_PASSWORD  
 value: password  
 ports:  
 - containerPort: 27017  
 volumeMounts:  
 - name: mongodb-data  
 mountPath: /data/db  
 volumes:  
 - name: mongodb-data  
 persistentVolumeClaim:  
 claimName: mongodb-pvc  

---  
apiVersion: v1  
kind: Service  
metadata:  
 name: mongodb  
 namespace: apps  
spec:  
 selector:  
 app: mongodb  
 ports:  
 - name: mongodb  
 protocol: TCP  
 port: 27017  
 targetPort: 27017  
 type: NodePort  

---  
kind: PersistentVolumeClaim  
apiVersion: v1  
metadata:  
 name: mongodb-pvc  
 namespace: apps  
spec:  
 accessModes:  
 - ReadWriteOnce  
 storageClassName: standard  
 resources:  
 requests:  
 storage: 1Gi
  1. Застосуйте ці файли до Kubernetes
kubectl apply -f ../redis-db.yaml  

kubectl apply -f ../mongo-db.yaml
  1. Тепер вкажіть стан компонента, використовуючи redis: dapr-component-state-redis.yaml
apiVersion: dapr.io/v1alpha1  
kind: Component  
metadata:  
 name: demostore  
 namespace: apps  
spec:  
 version: v1  
 type: state.redis  
 metadata:  
 - name: redisHost  
 value: redis-db:6379  
 - name: queryIndexes  
 value: |  
 [  
 {  
 "name": "articleCategoryIndex",  
 "indexes": [  
 {  
 "key": "category",  
 "type": "TEXT"  
 }  
 ]  
 }  
 ]

10.
Після того, як ви застосували цей ресурс до Kubernetes, Dapr використовуватиме Redis для маніпулювання станами.

kubectl apply -f ../dapr-component-state-redis.yaml
  1. Після виконання попередніх кроків, Dapr готовий до роботи. Тепер визначте файл розгортання для API та застосуйте його до Kubernetes: article-api.yaml
apiVersion: v1  
kind: Service  
metadata:  
 name: article-api  
 namespace: apps  
 labels:  
 app: article-api  
spec:  
 type: NodePort  
 ports:  
 - port: 8080  
 targetPort: 80  
 selector:  
 app: article-api  


---  
apiVersion: apps/v1  
kind: Deployment  
metadata:  
 name: article-api  
 namespace: apps  
 labels:  
 app: article-api  
spec:  
 replicas: 1  
 selector:  
 matchLabels:  
 app: article-api  
 template:  
 metadata:  
 labels:  
 app: article-api  
 annotations:  
 dapr.io/enabled: "true"  
 dapr.io/app-id: "article-api"  
 dapr.io/app-port: "80"  
 dapr.io/enable-api-logging: "true"  
 spec:  
 containers:  
 - name: article-api  
 image: automatefse/dapr-demo-single-state:latest  
 ports:  
 - containerPort: 80  
 imagePullPolicy: Always
  1. Застосуйте це до Kubernetes, зверніть увагу, що можливо вам доведеться зробити порт-форвардинг для роботи API.
kubectl apply -f ../article-api.yaml  

kubectl port-forward service/article-api 8080:8080 -n apps
  1. Спробуйте створити ще один компонент стану для використання MongoDB "під капотом", тобто dapr-component-state-mongo.yaml
apiVersion: dapr.io/v1alpha1  
kind: Component  
metadata:  
 name: demostore  
 namespace: apps  
spec:  
 version: v1  
 type: state.mongodb  
 metadata:  
 - name: host  
 value: "mongodb"  
 - name: port  
 value: "27017"   
 - name: username  
 value: "root"  
 - name: password  
 value: "password"  
 - name: databaseName  
 value: "testdb"  
 - name: collectionName  
 value: "articles"  
 - name: operationTimeout  
 value: "60s"  
 - name: params  
 value: "?authSource=admin"
  1. Тепер, якщо ви застосуєте цей ресурс до Kubernetes, Dapr замінить управління станом з Redis на MongoDB.
kubectl apply -f ../dapr-component-state-azure-cosmos.yaml

Сподіваюся, це дасть вам кілька ідей щодо Dapr і допоможе вам розпочати нові проекти з Dapr 🙂

Перекладено з: Discover Dapr’s ability for event driven systems

Leave a Reply

Your email address will not be published. Required fields are marked *