Dapr (Distributed Application Runtime) — це відкритий, подієвий, переносний виконуваний середовище, яке надає основні компоненти для створення стійких, масштабованих та розподілених додатків.
Необхідні умови
- minikube
- Системи Dapr: dapr init — kubernetes
- Redis: minikube pod
- MongoDB: minikube pod
- Розгортання компонента dapr
- Демонстраційний API статей (.net)
Огляд
Структура знань
Бізнесові переваги
- Зосередженість на бізнес-логіці та прискорений розвиток за меншу вартість.
- Дозволяє поступову модернізацію додатків без перерв, використовуючи вже наявні інвестиції.
- Забезпечує гнучкість і здатність швидко змінювати інфраструктурний дизайн та реалізацію.
- Незалежність від хмар та платформ.
- Відкритий код та підтримка спільноти.
- Безкоштовне використання.
Інженерні переваги
- Попередньо побудовані компоненти для вирішення типових проблем.
- Узгоджений досвід інтеграції.
- Легке з'єднання мікросервісів для більш стійкої архітектури.
- Можливість налаштування компонентів для надання розширюваності.
- Забезпечує можливість мокування інфраструктури для тестування інтеграцій.
Ключові концепції
- Sidecar
- Компонент
- Схема компонента
- Основні блоки
Sidecar
- 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, як агент додатка, відповідає за обробку інтеграції з нижчими цілями.
Компонент
- Dapr використовує модульний дизайн, де функціональність надається як компонент.
- Компоненти Dapr надають конкретні функціональності, які можна використовувати.
- Завдяки абстракції від деталей реалізації, компонент Dapr забезпечує узгоджений інтерфейс для взаємодії з різними сервісами, незалежно від використовуваної технології чи постачальника.
- Для Dapr доступні підключувані компоненти. Інженерна команда може реалізувати свої власні компоненти з більш налаштованими функціями.
Схема компонента
- Компоненти повинні бути зареєстровані перед використанням, що передбачає визначення їх у YAML-файлі за допомогою схеми компонента.
- Розділ spec.type визначає тип компонента.
Шаблон цього значення має вигляд [категорія].[реалізація]
приклад: state — схема компонента для mongo
приклад: state — схема компонента для redis
приклад: схема компонента pub-sub
Основні блоки
- HTTP або gRPC API.
- Спрощення завдань у мікросервісах.
- Надання узгодженого API.
- Абстрагування деталей реалізації.
- Dapr надає різноманітні основні блоки.
- Розширюваність.
Я продемонструю вам, що можна зробити з деякими популярними основними блоками.
Управління станом
- Абстракція сховища стану.
- API для управління станом.
- Конфігурація сховища стану.
- Dapr підтримує широкий спектр сховищ стану: Redis, Cosmos DB, SQL Database, MongoDB, DynamoDB, Cassandra тощо.
https://github.com/dapr/components-contrib/tree/master/state
Повідомлення Pub/Sub
- API для видавця.
- API для підписника.
- Підтримує кілька систем обміну повідомленнями, таких як Azure Service Bus, RabbitMQ, Kafka, NATS та інші.
https://github.com/dapr/components-contrib/tree/master/pubsub - Повторні спроби та обробка помилок.
Виклик Сервісів
- Виклик Сервісів між Сервісами: Dapr дозволяє сервісам викликати методи або API інших сервісів за допомогою простого та узгодженого програмного моделі.
- Підтримка різних протоколів комунікації: Dapr підтримує різноманітні протоколи комунікації, зокрема HTTP, gRPC.
- Шаблони запиту-відповіді та "fire-and-forget": Dapr підтримує як шаблони запиту-відповіді, так і "fire-and-forget" для комунікації.
- Розрив ланцюга та повторні спроби: Dapr включає вбудовані механізми розриву ланцюга та повторних спроб для обробки тимчасових збоїв під час викликів сервісів.
Життєвий Цикл Sidecar та Компонентів
Контрольна Плита Dapr
- Контрольна плита Dapr — це набір сервісів, що займаються керуванням та налаштуванням виконуваного середовища Dapr.
- Чотири основні сервіси:
- Сервіс інжектора Sidecar
- Сервіс оператора
- Сервіс розташування
- Сервіс Sentry
Як це виглядає в Kubernetes
Реєстрація Компонентів
- YAML файли компонентів можна застосовувати через kubectl або helm.
- Сервіс оператора Dapr споживає YAML файл компонента та реєструє схеми компонентів як кастомні визначення ресурсів K8S.
- Будь-які оновлення та видалення схем компонентів Dapr також обробляються сервісом оператора.
Інжекція Sidecar
- Увімкнення Dapr в розгортання додатка за допомогою анотацій Kubernetes для Dapr.
- Інжектор Sidecar споживає файл розгортання додатка, щоб інжектувати контейнер Dapr sidecar до Kubernetes pod.
- Dapr sidecar виконує перевірки готовності під час ініціалізації та встановлення з'єднання, щоб переконатися, що він готовий до роботи.
- У специфічних випадках, таких як pub-sub, Dapr sidecar чекає на запуск додатка, щоб забезпечити встановлення зв'язку.
Подорож Повідомлень
- Dapr sidecar надає API через HTTP або gRPC, якими додатки можуть користуватися для взаємодії з ним.
- Замість прямої інтеграції з ресурсами інфраструктури, Dapr спілкується з компонентами Dapr як проміжний елемент.
- Компоненти відповідають за інтеграцію з основними інфраструктурними ресурсами.
- Додаток може мати активну або пасивну комунікацію з sidecar залежно від типу компонента.
- При активній комунікації додаток безпосередньо взаємодіє з Dapr sidecar, який пересилає запити до виконуваного середовища Dapr і повертає відповідь.
- При пасивній комунікації додаток хостить API на клієнтській стороні за допомогою SDK Dapr. Sidecar перехоплює та обробляє повідомлення, що надходять до додатка через це API, виконує операції Dapr і доставляє оброблене повідомлення.
Стан Здоров'я Sidecar
- 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");
- В 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();
-
Для тестування Dapr локально на вашому комп'ютері, вам потрібно встановити minikube
-
Створіть файл простору імен Kubernetes: kube-env-setup.yaml
apiVersion: v1
kind: Namespace
metadata:
name: apps
та застосуйте його за допомогою kubectl
kubectl apply -f ../kube-env-setup.yaml
- Ініціалізуйте Dapr для Kubernetes
dapr init --kubernetes --wait
kubectl get service -n dapr-system
- Створіть файл розгортання для 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
- Створіть файл розгортання для 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
- Застосуйте ці файли до Kubernetes
kubectl apply -f ../redis-db.yaml
kubectl apply -f ../mongo-db.yaml
- Тепер вкажіть стан компонента, використовуючи 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
- Після виконання попередніх кроків, 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
- Застосуйте це до Kubernetes, зверніть увагу, що можливо вам доведеться зробити порт-форвардинг для роботи API.
kubectl apply -f ../article-api.yaml
kubectl port-forward service/article-api 8080:8080 -n apps
- Спробуйте створити ще один компонент стану для використання 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"
- Тепер, якщо ви застосуєте цей ресурс до Kubernetes, Dapr замінить управління станом з Redis на MongoDB.
kubectl apply -f ../dapr-component-state-azure-cosmos.yaml
Сподіваюся, це дасть вам кілька ідей щодо Dapr і допоможе вам розпочати нові проекти з Dapr 🙂
Перекладено з: Discover Dapr’s ability for event driven systems