This is the multi-page printable view of this section. Click here to print.
部署和配置Dapr
- 1: 可观测性
- 1.1: 代码跟踪
- 1.1.1: 分布式追踪概述
- 1.1.2: W3C 跟踪上下文概述
- 1.1.3: 配置 Dapr 发送分布式追踪数据
- 1.1.4: Open Telemetry Collector
- 1.1.4.1: 使用 OpenTelemetry Collector 收集追踪
- 1.1.4.2: 使用 OpenTelemetry Collector 将跟踪信息发送到应用程序洞察
- 1.1.4.3: 使用 OpenTelemetry Collector 收集追踪信息并发送到 Jaeger
- 1.1.5: 操作指南:配置 New Relic 进行分布式追踪
- 1.1.6: 操作指南:设置 Zipkin 进行分布式追踪
- 1.1.7: 操作指南:为分布式追踪设置 Datadog
- 1.2: 监控指标
- 1.2.1: 操作指南:使用 Prometheus 监控指标
- 1.2.2: 配置指标
- 1.2.3: 如何使用Grafana监控指标
- 1.2.4: 操作指南:配置 New Relic 以收集和分析指标
- 1.2.5: 操作指南:配置 Azure Monitor 以搜索日志和收集指标
- 1.3: 日志记录
- 1.3.1: 日志
- 1.3.2: 操作指南:在 Kubernetes 中设置 Fluentd、Elastic search 和 Kibana
- 1.3.3: 操作指南:为 Dapr 日志配置 New Relic
- 2: Dapr 的部署方式
- 2.1: 在本地自托管模式下运行 Dapr
- 2.1.1: Dapr 自托管模式概述
- 2.1.2: 如何使用 Podman 在自托管模式下运行 Dapr
- 2.1.3: 如何使用 Docker 自托管 Dapr
- 2.1.4: 操作指南:在离线或隔离环境中运行Dapr
- 2.1.5: 如何在没有 Docker 的环境中以自托管模式运行 Dapr
- 2.1.6: 操作指南:持久化调度器作业
- 2.1.7: 在自托管环境中升级 Dapr 的步骤
- 2.1.8: 在自托管环境中卸载 Dapr
- 2.2: 在 Kubernetes 环境中部署和运行 Dapr
- 2.2.1: Dapr 在 Kubernetes 上的概述
- 2.2.2: Kubernetes 集群配置
- 2.2.2.1: 设置 Minikube 集群
- 2.2.2.2: 设置 KiND 集群
- 2.2.2.3: 配置 Azure Kubernetes 服务 (AKS) 集群
- 2.2.2.4: 设置 Google Kubernetes Engine (GKE) 集群
- 2.2.2.5: 配置弹性Kubernetes服务(EKS)集群
- 2.2.3: 在 Kubernetes 集群上部署 Dapr
- 2.2.4: 在 Kubernetes 集群上升级 Dapr
- 2.2.5: Kubernetes 生产指南
- 2.2.6: 使用 Dapr Shared 部署 Dapr 到每个节点或每个集群
- 2.2.7: 操作指南:持久化调度器任务
- 2.2.8: 部署到混合 Linux/Windows Kubernetes 集群
- 2.2.9: 在 Kubernetes Job 中运行 Dapr
- 2.2.10: 操作指南:将 Pod 卷挂载到 Dapr sidecar
- 2.3: 在无服务器服务中运行 Dapr
- 2.3.1: Azure 容器应用
- 3: Dapr 配置管理指南
- 3.1: Dapr 配置
- 3.2: 操作指南:控制并发和限制应用程序的速率
- 3.3: 操作指南:限制从 secret 存储中读取的 secret
- 3.4: 操作指南:为服务调用配置应用访问控制列表
- 3.5: 使用指南:选择性启用 Dapr Sidecar 的 API
- 3.6: 操作指南:配置 Dapr 使用 gRPC
- 3.7: 操作指南:如何处理大容量 HTTP 请求体
- 3.8: 操作指南:处理大型HTTP头部大小
- 3.9: 操作指南:在Dapr sidecar中安装证书
- 3.10: 操作指南:启用预览功能
- 3.11: 操作指南:为 Dapr sidecar 配置 Secret 环境变量
- 4: 管理 Dapr 中的组件
- 4.1: 认证流程
- 4.2: 更新组件
- 4.3: 操作指南:将组件限定于一个或多个应用程序
- 4.4: 操作指南:在组件中引用secret
- 4.5: 状态存储组件
- 4.6: 发布/订阅代理
- 4.7: Secret 存储组件
- 4.8: Bindings 组件
- 4.9: 如何:注册一个可插拔组件
- 4.10: 配置中间件组件
- 5: 保护 Dapr 部署
- 5.1: 设置和配置 mTLS 证书
- 5.2: 使用 OAuth 配置端点授权
- 5.3: 在 Dapr 中启用 API 令牌认证
- 5.4: 使用令牌认证对Dapr请求进行身份验证
- 6: 通过弹性策略实现错误恢复
- 7: 支持和版本控制
- 7.1: 版本控制政策
- 7.2: 支持的运行时和SDK版本
- 7.3: 重大变更和弃用
- 7.4: 报告安全问题
- 7.5: 预览功能
- 7.6: Alpha 和 Beta API
- 8: 调试与故障排除
- 8.1: 运行 Dapr 时的常见问题
- 8.2: 配置和查看 Dapr 日志
- 8.3: Dapr API 日志
- 8.4: 性能分析与调试
- 9: Dapr 的性能与扩展性概述
- 9.1: 服务调用性能
- 9.2: actor 性能激活
1.1 - 代码跟踪
1.1.1 - 分布式追踪概述
Dapr 通过 Open Telemetry (OTEL) 和 Zipkin 协议来实现分布式追踪。OTEL 是行业标准,并且是推荐使用的追踪协议。
大多数可观测性工具支持 OTEL,包括:
下图展示了 Dapr(使用 OTEL 和 Zipkin 协议)如何与多个可观测性工具集成。

场景
追踪用于服务调用和发布/订阅(pubsub)API。您可以在使用这些 API 的服务之间传递追踪上下文。追踪的使用有两种场景:
- Dapr 生成追踪上下文,您将追踪上下文传递到另一个服务。
- 您生成追踪上下文,Dapr 将追踪上下文传递到服务。
场景 1:Dapr 生成追踪上下文头
顺序服务调用的传递
Dapr 负责创建追踪头。然而,当有两个以上的服务时,您需要负责在它们之间传递追踪头。让我们通过示例来了解这些场景:
单一服务调用
例如,服务 A -> 服务 B
。
Dapr 在 服务 A
中生成追踪头,然后从 服务 A
传递到 服务 B
。不需要进一步的传递。
多个顺序服务调用
例如,服务 A -> 服务 B -> 传递追踪头到 -> 服务 C
,以及其他启用 Dapr 的服务。
Dapr 在请求开始时在 服务 A
中生成追踪头,然后传递到 服务 B
。您现在需要负责获取头并将其传递到 服务 C
,因为这与您的应用程序特定相关。
换句话说,如果应用程序调用 Dapr 并希望使用现有的追踪头(span)进行追踪,它必须始终传递到 Dapr(在此示例中,从 服务 B
到 服务 C
)。Dapr 始终将追踪 span 传递到应用程序。
注意
Dapr SDK 中没有公开的辅助方法来传递和检索追踪上下文。您需要使用 HTTP/gRPC 客户端通过 HTTP 头和 gRPC 元数据传递和检索追踪头。请求来自外部端点
例如,从网关服务到启用 Dapr 的服务 A
。
外部网关入口调用 Dapr,Dapr 生成追踪头并调用 服务 A
。服务 A
然后调用 服务 B
和其他启用 Dapr 的服务。
您必须从 服务 A
传递头到 服务 B
。例如:入口 -> 服务 A -> 传递追踪头 -> 服务 B
。这类似于案例 2。
发布/订阅消息
Dapr 在发布的消息主题中生成追踪头。对于 rawPayload
消息,可以指定 traceparent
头以传递追踪信息。这些追踪头会传递到任何监听该主题的服务。
多个不同服务调用的传递
在以下场景中,Dapr 为您完成了一些工作,您需要创建或传递追踪头。
从单个服务调用多个不同的服务
当您从单个服务调用多个服务时,您需要传递追踪头。例如:
服务 A -> 服务 B
[ .. 一些代码逻辑 ..]
服务 A -> 服务 C
[ .. 一些代码逻辑 ..]
服务 A -> 服务 D
[ .. 一些代码逻辑 ..]
在这种情况下:
- 当
服务 A
首次调用服务 B
时,Dapr 在服务 A
中生成追踪头。 服务 A
中的追踪头被传递到服务 B
。- 这些追踪头作为响应头的一部分在
服务 B
的响应中返回。 - 然后,您需要将返回的追踪上下文传递到下一个服务,如
服务 C
和服务 D
,因为 Dapr 不知道您想要重用相同的头。
场景 2:您从非 Dapr 化应用程序生成自己的追踪上下文头
生成您自己的追踪上下文头较为少见,并且在调用 Dapr 时通常不需要。
然而,在某些场景中,您可能会特别选择在服务调用中添加 W3C 追踪头。例如,您有一个不使用 Dapr 的现有应用程序。在这种情况下,Dapr 仍然为您传递追踪上下文头。
如果您决定自己生成追踪头,可以通过三种方式完成:
标准 OpenTelemetry SDK
您可以使用行业标准的 OpenTelemetry SDKs 生成追踪头,并将这些追踪头传递到启用 Dapr 的服务。这是首选方法。
供应商 SDK
您可以使用提供生成 W3C 追踪头的方法的供应商 SDK,并将其传递到启用 Dapr 的服务。
W3C 追踪上下文
您可以根据 W3C 追踪上下文规范 手工制作追踪上下文,并将其传递到启用 Dapr 的服务。
阅读 追踪上下文概述 以获取有关 W3C 追踪上下文和头的更多背景和示例。
相关链接
1.1.2 - W3C 跟踪上下文概述
Dapr 采用 Open Telemetry 协议,该协议利用 W3C 跟踪上下文 来实现服务调用和发布/订阅消息的分布式跟踪。Dapr 生成并传播跟踪上下文信息,可以将其发送到可观测性工具进行可视化和查询。
背景
分布式跟踪是一种由跟踪工具实现的方法,用于跟踪、分析和调试跨多个软件组件的事务。
通常,分布式跟踪会跨越多个服务,因此需要一个唯一的标识符来标识每个事务。跟踪上下文传播就是传递这种唯一标识符的过程。
过去,不同的跟踪供应商各自实现自己的跟踪上下文传播方式。在多供应商环境中,这会导致互操作性的问题,例如:
- 不同供应商收集的跟踪数据无法关联,因为没有共享的唯一标识符。
- 跨越不同供应商边界的跟踪无法传播,因为没有统一的标识符集。
- 中间商可能会丢弃供应商特定的元数据。
- 云平台供应商、中间商和服务提供商无法保证支持跟踪上下文传播,因为没有标准可循。
以前,大多数应用程序由单一的跟踪供应商监控,并保持在单一平台提供商的边界内,因此这些问题没有显著影响。
如今,越来越多的应用程序是分布式的,并利用多个中间件服务和云平台。这种现代应用程序的转变需要一个分布式跟踪上下文传播标准。
W3C 跟踪上下文规范 定义了一种通用格式,用于交换跟踪上下文数据(称为跟踪上下文)。通过提供以下内容,跟踪上下文解决了上述问题:
- 为单个跟踪和请求提供唯一标识符,允许将多个供应商的跟踪数据链接在一起。
- 提供一种机制来转发供应商特定的跟踪数据,避免在单个事务中多个跟踪工具参与时出现断裂的跟踪。
- 一个中间商、平台和硬件供应商可以支持的行业标准。
这种统一的跟踪数据传播方法提高了对分布式应用程序行为的可见性,促进了问题和性能分析。
W3C 跟踪上下文和头格式
W3C 跟踪上下文
Dapr 使用标准的 W3C 跟踪上下文头。
- 对于 HTTP 请求,Dapr 使用
traceparent
头。 - 对于 gRPC 请求,Dapr 使用
grpc-trace-bin
头。
当请求到达时没有跟踪 ID,Dapr 会创建一个新的。否则,它会沿调用链传递跟踪 ID。
W3C 跟踪头
这些是 Dapr 为 HTTP 和 gRPC 生成和传播的特定跟踪上下文头。
在从 HTTP 响应传播跟踪上下文头到 HTTP 请求时复制这些头:
Traceparent 头
Traceparent 头以所有供应商都能理解的通用格式表示跟踪系统中的传入请求:
traceparent: 00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
Tracestate 头
Tracestate 头以可能是供应商特定的格式包含父级:
tracestate: congo=t61rcWkgMzE
在 gRPC API 调用中,跟踪上下文通过 grpc-trace-bin
头传递。
相关链接
1.1.3 - 配置 Dapr 发送分布式追踪数据
注意
建议在任何生产环境中启用 Dapr 的追踪功能。您可以根据运行环境配置 Dapr,将追踪和遥测数据发送到多种可观测性工具,无论是在云端还是本地。配置
在 Configuration
规范中的 tracing
部分包含以下属性:
spec:
tracing:
samplingRate: "1"
otel:
endpointAddress: "myendpoint.cluster.local:4317"
zipkin:
endpointAddress: "https://..."
下表列出了追踪的属性:
属性 | 类型 | 描述 |
---|---|---|
samplingRate | string | 设置追踪的采样率来启用或禁用追踪。 |
stdout | bool | 如果为真,则会将更详细的信息写入追踪。 |
otel.endpointAddress | string | 设置 Open Telemetry (OTEL) 目标主机名和可选端口。如果使用此项,则无需指定 ‘zipkin’ 部分。 |
otel.isSecure | bool | 指定连接到端点地址的连接是否加密。 |
otel.protocol | string | 设置为 http 或 grpc 协议。 |
zipkin.endpointAddress | string | 设置 Zipkin 服务器 URL。如果使用此项,则无需指定 otel 部分。 |
要启用追踪,请使用配置文件(在 selfhost 模式下)或 Kubernetes 配置对象(在 Kubernetes 模式下)。例如,以下配置对象将采样率设置为 1(每个 span 都被采样),并使用 OTEL 协议将追踪发送到本地的 OTEL 服务器 localhost:4317。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: tracing
spec:
tracing:
samplingRate: "1"
otel:
endpointAddress: "localhost:4317"
isSecure: false
protocol: grpc
采样率
Dapr 使用概率采样。采样率定义了追踪 span 被采样的概率,值可以在 0 到 1 之间(包括 0 和 1)。默认采样率为 0.0001(即每 10,000 个 span 中采样 1 个)。
将 samplingRate
设置为 0 将完全禁用追踪。
环境变量
OpenTelemetry (otel) 端点也可以通过环境变量进行配置。设置 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量将为 sidecar 启用追踪。
环境变量 | 描述 |
---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | 设置 Open Telemetry (OTEL) 服务器主机名和可选端口,启用追踪 |
OTEL_EXPORTER_OTLP_INSECURE | 将连接设置为未加密(true/false) |
OTEL_EXPORTER_OTLP_PROTOCOL | 传输协议(grpc 、http/protobuf 、http/json ) |
下一步
了解如何使用以下工具之一设置追踪:
1.1.4 - Open Telemetry Collector
1.1.4.1 - 使用 OpenTelemetry Collector 收集追踪
Dapr 推荐使用 OpenTelemetry (OTLP) 协议来写入追踪数据。对于直接支持 OTLP 的可观测性工具,建议使用 OpenTelemetry Collector,因为它可以快速卸载数据,并提供重试、批处理和加密等功能。更多信息请参阅 Open Telemetry Collector 的文档。
Dapr 也支持使用 Zipkin 协议来写入追踪数据。在 OTLP 协议支持之前,Zipkin 协议与 OpenTelemetry Collector 一起使用,以将追踪数据发送到 AWS X-Ray、Google Cloud Operations Suite 和 Azure Monitor 等可观测性工具。虽然两种协议都有效,但推荐使用 OpenTelemetry 协议。
先决条件
- 在 Kubernetes 上安装 Dapr
- 确保您的追踪后端已准备好接收追踪数据
- 查看 OTEL Collector 导出器所需的参数:
配置 OTEL Collector 推送追踪数据到您的后端
将
<your-exporter-here>
替换为您的追踪导出器的实际配置。- 请参考先决条件部分中的 OTEL Collector 链接以获取正确的配置。
使用以下命令应用配置:
kubectl apply -f open-telemetry-collector-generic.yaml
配置 Dapr 发送追踪数据到 OTEL Collector
创建一个 Dapr 配置文件以启用追踪,并部署一个使用 OpenTelemetry Collector 的追踪导出器组件。
使用此
collector-config.yaml
文件创建您的配置。使用以下命令应用配置:
kubectl apply -f collector-config.yaml
部署应用程序并启用追踪
在需要参与分布式追踪的容器中添加 dapr.io/config
注解以应用 appconfig
配置,如下所示:
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
metadata:
...
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "MyApp"
dapr.io/app-port: "8080"
dapr.io/config: "appconfig"
您可以同时注册多个追踪导出器,追踪数据将被转发到所有注册的导出器。
就是这样!无需包含任何 SDK 或对您的应用程序代码进行修改。Dapr 会自动为您处理分布式追踪。
查看追踪
部署并运行一些应用程序。等待追踪数据传播到您的追踪后端并在那里查看它们。
相关链接
1.1.4.2 - 使用 OpenTelemetry Collector 将跟踪信息发送到应用程序洞察
Dapr 使用 Zipkin API 集成了 OpenTelemetry (OTEL) Collector。本指南演示了如何通过 Dapr 使用 OpenTelemetry Collector 将跟踪事件推送到 Azure 应用程序洞察。
前提条件
- 在 Kubernetes 上安装 Dapr
- 设置一个应用程序洞察资源并记录下你的应用程序洞察仪器密钥。
配置 OTEL Collector 以推送数据到应用程序洞察
要将事件推送到你的应用程序洞察实例,请在 Kubernetes 集群中安装 OTEL Collector。
用你的应用程序洞察仪器密钥替换
<INSTRUMENTATION-KEY>
占位符。使用以下命令应用配置:
kubectl apply -f open-telemetry-collector-appinsights.yaml
配置 Dapr 以发送跟踪数据到 OTEL Collector
创建一个 Dapr 配置文件以启用跟踪,并部署一个使用 OpenTelemetry Collector 的跟踪导出组件。
使用此
collector-config.yaml
文件创建你自己的配置。使用以下命令应用配置:
kubectl apply -f collector-config.yaml
部署应用程序并启用跟踪
在你希望参与分布式跟踪的容器中添加 dapr.io/config
注解以应用 appconfig
配置,如下例所示:
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
metadata:
...
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "MyApp"
dapr.io/app-port: "8080"
dapr.io/config: "appconfig"
你可以同时注册多个跟踪导出器,跟踪日志会被转发到所有注册的导出器。
就是这样!无需包含任何 SDK 或对你的应用程序代码进行额外的修改。Dapr 会自动为你处理分布式跟踪。
查看跟踪
部署并运行一些应用程序。几分钟后,你应该会在你的应用程序洞察资源中看到跟踪日志。你还可以使用 应用程序地图 来检查你的服务拓扑,如下所示:
注意
只有通过 Dapr sidecar 暴露的 Dapr API(例如,服务调用或事件发布)的操作会显示在应用程序地图拓扑中。相关链接
1.1.4.3 - 使用 OpenTelemetry Collector 收集追踪信息并发送到 Jaeger
Dapr 支持通过 OpenTelemetry (OTLP) 和 Zipkin 协议进行追踪信息的写入。然而,由于 Jaeger 对 Zipkin 的支持已被弃用,建议使用 OTLP。虽然 Jaeger 可以直接支持 OTLP,但在生产环境中,推荐使用 OpenTelemetry Collector 从 Dapr 收集追踪信息并发送到 Jaeger。这样可以让您的应用程序更高效地处理数据,并利用重试、批处理和加密等功能。更多信息请阅读 Open Telemetry Collector 文档。
在自托管模式下配置 Jaeger
本地设置
启动 Jaeger 的最简单方法是运行发布到 DockerHub 的预构建的 all-in-one Jaeger 镜像,并暴露 OTLP 端口:
docker run -d --name jaeger \
-p 4317:4317 \
-p 16686:16686 \
jaegertracing/all-in-one:1.49
接下来,在本地创建以下 config.yaml
文件:
注意: 因为您使用 Open Telemetry 协议与 Jaeger 通信,您需要填写追踪配置的
otel
部分,并将endpointAddress
设置为 Jaeger 容器的地址。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: tracing
namespace: default
spec:
tracing:
samplingRate: "1"
stdout: true
otel:
endpointAddress: "localhost:4317"
isSecure: false
protocol: grpc
要启动引用新 YAML 配置文件的应用程序,请使用 --config
选项。例如:
dapr run --app-id myapp --app-port 3000 node app.js --config config.yaml
查看追踪信息
要在浏览器中查看追踪信息,请访问 http://localhost:16686
查看 Jaeger UI。
在 Kubernetes 上使用 OpenTelemetry Collector 配置 Jaeger
以下步骤展示了如何配置 Dapr 以将分布式追踪数据发送到 OpenTelemetry Collector,然后将追踪信息发送到 Jaeger。
前提条件
- 在 Kubernetes 上安装 Dapr
- 使用 Jaeger Kubernetes Operator 设置 Jaeger
设置 OpenTelemetry Collector 推送到 Jaeger
要将追踪信息推送到您的 Jaeger 实例,请在您的 Kubernetes 集群上安装 OpenTelemetry Collector。
下载并检查
open-telemetry-collector-jaeger.yaml
文件。在
otel-collector-conf
ConfigMap 的数据部分,更新otlp/jaeger.endpoint
值以匹配您的 Jaeger collector Kubernetes 服务对象的端点。将 OpenTelemetry Collector 部署到运行 Dapr 应用程序的相同命名空间中:
kubectl apply -f open-telemetry-collector-jaeger.yaml
设置 Dapr 发送追踪信息到 OpenTelemetryCollector
创建一个 Dapr 配置文件以启用追踪,并将 sidecar 追踪信息导出到 OpenTelemetry Collector。
使用
collector-config-otel.yaml
文件创建您自己的 Dapr 配置。更新
namespace
和otel.endpointAddress
值以与部署 Dapr 应用程序和 OpenTelemetry Collector 的命名空间对齐。应用配置:
kubectl apply -f collector-config.yaml
部署启用追踪的应用程序
通过在您希望启用分布式追踪的应用程序部署中添加 dapr.io/config
注释来应用 tracing
Dapr 配置,如下例所示:
apiVersion: apps/v1
kind: Deployment
metadata:
...
spec:
...
template:
metadata:
...
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "MyApp"
dapr.io/app-port: "8080"
dapr.io/config: "tracing"
您可以同时注册多个追踪导出器,追踪日志将被转发到所有注册的导出器。
就是这样!无需包含 OpenTelemetry SDK 或对您的应用程序代码进行检测。Dapr 会自动为您处理分布式追踪。
查看追踪信息
要查看 Dapr sidecar 追踪信息,请端口转发 Jaeger 服务并打开 UI:
kubectl port-forward svc/jaeger-query 16686 -n observability
在您的浏览器中,访问 http://localhost:16686
,您将看到 Jaeger UI。
参考资料
1.1.5 - 操作指南:配置 New Relic 进行分布式追踪
前提条件
- 需要一个 New Relic 账户,该账户永久免费,每月可免费处理 100 GB 的数据,包含 1 个完全访问用户和无限数量的基本用户。
配置 Dapr 追踪
Dapr 可以直接将其捕获的指标和追踪数据发送到 New Relic。最简单的方式是通过配置 Dapr,将追踪数据以 Zipkin 格式发送到 New Relic 的 Trace API。
为了将数据集成到 New Relic 的 Telemetry Data Platform,您需要一个 New Relic Insights Insert API key。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
namespace: default
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "https://trace-api.newrelic.com/trace/v1?Api-Key=<NR-INSIGHTS-INSERT-API-KEY>&Data-Format=zipkin&Data-Format-Version=2"
查看追踪
New Relic 分布式追踪概览
New Relic 分布式追踪详情
(选择性)New Relic 仪器化
为了将数据集成到 New Relic Telemetry Data Platform,您需要一个 New Relic license key 或 New Relic Insights Insert API key。
OpenTelemetry 仪器化
您可以使用不同语言的 OpenTelemetry 实现,例如 New Relic Telemetry SDK 和 .NET 的 OpenTelemetry 支持。在这种情况下,使用 OpenTelemetry Trace Exporter。示例请参见此处。
New Relic 语言代理
类似于 OpenTelemetry 仪器化,您也可以使用 New Relic 语言代理。例如,.NET Core 的 New Relic 代理仪器化 是 Dockerfile 的一部分。示例请参见此处。
(选择性)启用 New Relic Kubernetes 集成
如果 Dapr 和您的应用程序在 Kubernetes 环境中运行,您可以启用额外的指标和日志。
安装 New Relic Kubernetes 集成的最简单方法是使用 自动安装程序 生成清单。它不仅包含集成 DaemonSets,还包括其他 New Relic Kubernetes 配置,如 Kubernetes 事件、Prometheus OpenMetrics 和 New Relic 日志监控。
New Relic Kubernetes 集群浏览器
New Relic Kubernetes 集群浏览器 提供了一个独特的可视化界面,展示了 Kubernetes 集成收集的所有数据和部署。
这是观察所有数据并深入了解应用程序或微服务内部发生的任何性能问题或事件的良好起点。
自动关联是 New Relic 可视化功能的一部分。
Pod 级别详情
上下文中的日志
New Relic 仪表板
Kubernetes 概览
Dapr 系统服务
Dapr 指标
New Relic Grafana 集成
New Relic 与 Grafana Labs 合作,您可以使用 Telemetry Data Platform 作为 Prometheus 指标的数据源,并在现有仪表板中查看它们,轻松利用 New Relic 提供的可靠性、规模和安全性。
用于监控 Dapr 系统服务和 sidecar 的 Grafana 仪表板模板 可以轻松使用,无需任何更改。New Relic 提供了一个 Prometheus 指标的本地端点 到 Grafana。可以轻松设置数据源:
并且可以导入来自 Dapr 的完全相同的仪表板模板,以可视化 Dapr 系统服务和 sidecar。
New Relic 警报
从 Dapr、Kubernetes 或任何在其上运行的服务收集的所有数据都可以用于设置警报和通知到您选择的首选渠道。请参见 Alerts and Applied Intelligence。
相关链接/参考
1.1.6 - 操作指南:设置 Zipkin 进行分布式追踪
配置自托管模式
在自托管模式下,运行 dapr init
时:
- 系统会默认创建一个 YAML 文件,路径为
$HOME/.dapr/config.yaml
(Linux/Mac)或%USERPROFILE%\.dapr\config.yaml
(Windows)。在执行dapr run
时,系统会默认引用该文件,除非您指定了其他配置:
- config.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprConfig
namespace: default
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://localhost:9411/api/v2/spans"
- 运行
dapr init
时,openzipkin/zipkin 的 Docker 容器会自动启动。您也可以手动启动:
使用 Docker 启动 Zipkin:
docker run -d -p 9411:9411 openzipkin/zipkin
- 使用
dapr run
启动应用程序时,默认会引用$HOME/.dapr/config.yaml
或%USERPROFILE%\.dapr\config.yaml
中的配置文件。您可以通过 Dapr CLI 的--config
参数来指定其他配置:
dapr run --app-id mynode --app-port 3000 node app.js
查看追踪
要查看追踪数据,请在浏览器中访问 http://localhost:9411,您将看到 Zipkin 的用户界面。
配置 Kubernetes
以下步骤将指导您如何配置 Dapr,将分布式追踪数据发送到 Kubernetes 集群中的 Zipkin 容器,并查看这些数据。
设置
首先,部署 Zipkin:
kubectl create deployment zipkin --image openzipkin/zipkin
为 Zipkin pod 创建一个 Kubernetes 服务:
kubectl expose deployment zipkin --type ClusterIP --port 9411
接下来,在本地创建以下 YAML 文件:
- tracing.yaml 配置
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: tracing
namespace: default
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
现在,部署 Dapr 配置文件:
kubectl apply -f tracing.yaml
要在 Dapr sidecar 中启用此配置,请在 pod 规范模板中添加以下注释:
annotations:
dapr.io/config: "tracing"
完成!您的 sidecar 现在已配置为将追踪数据发送到 Zipkin。
查看追踪数据
要查看追踪数据,请连接到 Zipkin 服务并打开用户界面:
kubectl port-forward svc/zipkin 9411:9411
在浏览器中,访问 http://localhost:9411
,您将看到 Zipkin 的用户界面。
参考资料
1.1.7 - 操作指南:为分布式追踪设置 Datadog
Dapr 捕获的指标和追踪信息可以通过 OpenTelemetry Collector 的 Datadog 导出器直接发送到 Datadog。
使用 OpenTelemetry Collector 和 Datadog 配置 Dapr 追踪
您可以使用 OpenTelemetry Collector 的 Datadog 导出器来配置 Dapr,为 Kubernetes 集群中的每个应用程序创建追踪,并将这些追踪信息收集到 Datadog 中。
在开始之前,请先设置 OpenTelemetry Collector。
在
datadog
导出器的配置部分,将您的 Datadog API 密钥添加到./deploy/opentelemetry-collector-generic-datadog.yaml
文件中:data: otel-collector-config: ... exporters: ... datadog: api: key: <YOUR_API_KEY>
运行以下命令以应用
opentelemetry-collector
的配置。kubectl apply -f ./deploy/open-telemetry-collector-generic-datadog.yaml
设置一个 Dapr 配置文件以启用追踪,并部署一个使用 OpenTelemetry Collector 的追踪导出器组件。
kubectl apply -f ./deploy/collector-config.yaml
在您希望参与分布式追踪的容器中添加
dapr.io/config
注解,以应用appconfig
配置。annotations: dapr.io/config: "appconfig"
创建并配置应用程序。应用程序运行后,遥测数据将被发送到 Datadog,并可以在 Datadog APM 中查看。

相关链接/参考
1.2 - 监控指标
1.2.1 - 操作指南:使用 Prometheus 监控指标
本地设置 Prometheus
在本地计算机上,您可以选择安装并作为进程运行 Prometheus,或者将其作为Docker 容器运行。
安装
注意
如果您计划将 Prometheus 作为 Docker 容器运行,则无需单独安装 Prometheus。请参阅容器部分的说明。请按照此处提供的步骤,根据您的操作系统安装 Prometheus。
配置
安装完成后,您需要创建一个配置文件。
以下是一个示例 Prometheus 配置,请将其保存为文件,例如 /tmp/prometheus.yml
或 C:\Temp\prometheus.yml
:
global:
scrape_interval: 15s # 默认情况下,每 15 秒收集一次指标。
# 包含一个收集端点的配置:
# 这里是 Prometheus 自身。
scrape_configs:
- job_name: 'dapr'
# 覆盖全局默认值,每 5 秒从此 job 收集指标。
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090'] # 如果不是默认值,请替换为 Dapr 指标端口
作为进程运行
使用您的配置文件运行 Prometheus,以开始从指定目标收集指标。
./prometheus --config.file=/tmp/prometheus.yml --web.listen-address=:8080
我们更改了端口以避免与 Dapr 自身的指标端点冲突。
如果您当前没有运行 Dapr 应用程序,目标将显示为离线。要开始收集指标,您必须启动 Dapr,并确保其指标端口与配置中指定的目标一致。
一旦 Prometheus 运行,您可以通过访问 http://localhost:8080
来查看其仪表板。
作为容器运行
要在本地计算机上将 Prometheus 作为 Docker 容器运行,首先确保已安装并运行 Docker。
然后可以使用以下命令将 Prometheus 作为 Docker 容器运行:
docker run \
--net=host \
-v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml \
prom/prometheus --config.file=/etc/prometheus/prometheus.yml --web.listen-address=:8080
--net=host
确保 Prometheus 实例能够连接到在主机上运行的任何 Dapr 实例。如果您计划也在容器中运行 Dapr 应用程序,则需要在共享的 Docker 网络上运行它们,并使用正确的目标地址更新配置。
一旦 Prometheus 运行,您可以通过访问 http://localhost:8080
来查看其仪表板。
在 Kubernetes 上设置 Prometheus
先决条件
安装 Prometheus
- 首先创建一个命名空间,用于部署 Grafana 和 Prometheus 监控工具
kubectl create namespace dapr-monitoring
- 安装 Prometheus
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install dapr-prom prometheus-community/prometheus -n dapr-monitoring
如果您是 Minikube 用户或想要禁用持久卷以进行开发,可以使用以下命令禁用它。
helm install dapr-prom prometheus-community/prometheus -n dapr-monitoring
--set alertmanager.persistence.enabled=false --set pushgateway.persistentVolume.enabled=false --set server.persistentVolume.enabled=false
要自动发现 Dapr 目标(服务发现),请使用:
helm install dapr-prom prometheus-community/prometheus -f values.yaml -n dapr-monitoring --create-namespace
values.yaml
文件
alertmanager:
persistence:
enabled: false
pushgateway:
persistentVolume:
enabled: false
server:
persistentVolume:
enabled: false
# 向 prometheus.yml 添加额外的收集配置
# 使用服务发现找到 Dapr 和 Dapr sidecar 目标
extraScrapeConfigs: |-
- job_name: dapr-sidecars
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: keep
regex: "true"
source_labels:
- __meta_kubernetes_pod_annotation_dapr_io_enabled
- action: keep
regex: "true"
source_labels:
- __meta_kubernetes_pod_annotation_dapr_io_enable_metrics
- action: replace
replacement: ${1}
source_labels:
- __meta_kubernetes_namespace
target_label: namespace
- action: replace
replacement: ${1}
source_labels:
- __meta_kubernetes_pod_name
target_label: pod
- action: replace
regex: (.*);daprd
replacement: ${1}-dapr
source_labels:
- __meta_kubernetes_pod_annotation_dapr_io_app_id
- __meta_kubernetes_pod_container_name
target_label: service
- action: replace
replacement: ${1}:9090
source_labels:
- __meta_kubernetes_pod_ip
target_label: __address__
- job_name: dapr
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: keep
regex: dapr
source_labels:
- __meta_kubernetes_pod_label_app_kubernetes_io_name
- action: keep
regex: dapr
source_labels:
- __meta_kubernetes_pod_label_app_kubernetes_io_part_of
- action: replace
replacement: ${1}
source_labels:
- __meta_kubernetes_pod_label_app
target_label: app
- action: replace
replacement: ${1}
source_labels:
- __meta_kubernetes_namespace
target_label: namespace
- action: replace
replacement: ${1}
source_labels:
- __meta_kubernetes_pod_name
target_label: pod
- action: replace
replacement: ${1}:9090
source_labels:
- __meta_kubernetes_pod_ip
target_label: __address__
- 验证
确保 Prometheus 在您的集群中运行。
kubectl get pods -n dapr-monitoring
预期输出:
NAME READY STATUS RESTARTS AGE
dapr-prom-kube-state-metrics-9849d6cc6-t94p8 1/1 Running 0 4m58s
dapr-prom-prometheus-alertmanager-749cc46f6-9b5t8 2/2 Running 0 4m58s
dapr-prom-prometheus-node-exporter-5jh8p 1/1 Running 0 4m58s
dapr-prom-prometheus-node-exporter-88gbg 1/1 Running 0 4m58s
dapr-prom-prometheus-node-exporter-bjp9f 1/1 Running 0 4m58s
dapr-prom-prometheus-pushgateway-688665d597-h4xx2 1/1 Running 0 4m58s
dapr-prom-prometheus-server-694fd8d7c-q5d59 2/2 Running 0 4m58s
访问 Prometheus 仪表板
要查看 Prometheus 仪表板并检查服务发现:
kubectl port-forward svc/dapr-prom-prometheus-server 9090:80 -n dapr-monitoring
打开浏览器并访问 http://localhost:9090
。导航到 Status > Service Discovery 以验证 Dapr 目标是否被正确发现。

您可以看到 job_name
及其发现的目标。

示例
参考资料
1.2.2 - 配置指标
默认情况下,每个Dapr系统进程都会发出Go运行时和进程指标,并拥有自己的Dapr指标。
Prometheus端点
Dapr sidecar提供了一个与Prometheus兼容的指标端点,您可以通过抓取该端点来更好地了解Dapr的运行状况。
使用CLI配置指标
指标应用程序端点默认是启用的。您可以通过传递命令行参数--enable-metrics=false
来禁用它。
默认的指标端口是9090
。您可以通过传递命令行参数--metrics-port
给daprd来更改此设置。
在Kubernetes中配置指标
您还可以通过在应用程序部署上设置dapr.io/enable-metrics: "false"
注解来启用或禁用特定应用程序的指标。禁用指标导出器后,daprd不会打开指标监听端口。
以下Kubernetes部署示例显示了如何显式启用指标,并将端口指定为"9090"。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
labels:
app: node
spec:
replicas: 1
selector:
matchLabels:
app: node
template:
metadata:
labels:
app: node
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/enable-metrics: "true"
dapr.io/metrics-port: "9090"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
使用应用程序配置启用指标
您还可以通过应用程序配置启用指标。要默认禁用Dapr sidecar中的指标收集,请将spec.metrics.enabled
设置为false
。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: tracing
namespace: default
spec:
metrics:
enabled: false
为错误代码配置指标
您可以通过设置spec.metrics.recordErrorCodes
为true
来为Dapr API错误代码启用额外的指标。Dapr API可能会返回标准化的错误代码。一个名为error_code_total
的新指标被记录,它允许监控由应用程序、代码和类别触发的错误代码。有关特定代码和类别,请参见errorcodes
包。
示例配置:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: tracing
namespace: default
spec:
metrics:
enabled: true
recordErrorCodes: true
示例指标:
{
"app_id": "publisher-app",
"category": "state",
"dapr_io_enabled": "true",
"error_code": "ERR_STATE_STORE_NOT_CONFIGURED",
"instance": "10.244.1.64:9090",
"job": "kubernetes-service-endpoints",
"namespace": "my-app",
"node": "my-node",
"service": "publisher-app-dapr"
}
使用路径匹配优化HTTP指标报告
在使用HTTP调用Dapr时,默认情况下会为每个请求的方法创建指标。这可能导致大量指标,称为高基数,这可能会影响内存使用和CPU。
路径匹配允许您管理和控制Dapr中HTTP指标的基数。通过聚合指标,您可以减少指标事件的数量并报告一个总体数量。了解更多关于如何在配置中设置基数。
此配置是选择加入的,并通过Dapr配置spec.metrics.http.pathMatching
启用。当定义时,它启用路径匹配,这将标准化指定路径的两个指标路径。这减少了唯一指标路径的数量,使指标更易于管理,并以受控方式减少资源消耗。
当spec.metrics.http.pathMatching
与increasedCardinality
标志设置为false
结合使用时,未匹配的路径会被转换为一个通用桶,以控制和限制基数,防止路径无限增长。相反,当increasedCardinality
为true
(默认值)时,未匹配的路径会像通常一样传递,允许潜在的更高基数,但保留原始路径数据。
HTTP指标中的路径匹配示例
以下示例演示了如何在Dapr中使用路径匹配API来管理HTTP指标。在每个示例中,指标是从5个HTTP请求到/orders
端点收集的,具有不同的订单ID。通过调整基数和利用路径匹配,您可以微调指标粒度以平衡细节和资源效率。
这些示例说明了指标的基数,强调高基数配置会导致许多条目,这对应于处理指标的更高内存使用。为简单起见,以下示例专注于单个指标:dapr_http_server_request_count
。
低基数与路径匹配(推荐)
配置:
http:
increasedCardinality: false
pathMatching:
- /orders/{orderID}
生成的指标:
# 匹配的路径
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/{orderID}",status="200"} 5
# 未匹配的路径
dapr_http_server_request_count{app_id="order-service",method="GET",path="",status="200"} 1
通过配置低基数和路径匹配,您可以在不影响基数的情况下对重要端点的指标进行分组。这种方法有助于避免高内存使用和潜在的安全问题。
无路径匹配的低基数
配置:
http:
increasedCardinality: false
生成的指标:
dapr_http_server_request_count{app_id="order-service",method="GET", path="",status="200"} 5
在低基数模式下,路径是无限基数的主要来源,被丢弃。这导致的指标主要指示给定HTTP方法的服务请求数量,但没有关于调用路径的信息。
高基数与路径匹配
配置:
http:
increasedCardinality: true
pathMatching:
- /orders/{orderID}
生成的指标:
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/{orderID}",status="200"} 5
此示例来自与上例相同的HTTP请求,但为路径/orders/{orderID}
配置了路径匹配。通过使用路径匹配,您可以通过基于匹配路径分组指标来实现减少基数。
无路径匹配的高基数
配置:
http:
increasedCardinality: true
生成的指标:
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/1",status="200"} 1
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/2",status="200"} 1
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/3",status="200"} 1
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/4",status="200"} 1
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders/5",status="200"} 1
对于每个请求,都会创建一个带有请求路径的新指标。此过程会继续为每个新订单ID的请求创建新指标,导致基数无限增长,因为ID是不断增长的。
HTTP指标排除动词
excludeVerbs
选项允许您从指标中排除特定的HTTP动词。这在内存节省至关重要的高性能应用程序中非常有用。
在指标中排除HTTP动词的示例
以下示例演示了如何在Dapr中排除HTTP动词以管理HTTP指标。
默认 - 包含HTTP动词
配置:
http:
excludeVerbs: false
生成的指标:
dapr_http_server_request_count{app_id="order-service",method="GET",path="/orders",status="200"} 1
dapr_http_server_request_count{app_id="order-service",method="POST",path="/orders",status="200"} 1
在此示例中,HTTP方法包含在指标中,导致每个请求到/orders
端点的单独指标。
排除HTTP动词
配置:
http:
excludeVerbs: true
生成的指标:
dapr_http_server_request_count{app_id="order-service",method="",path="/orders",status="200"} 2
在此示例中,HTTP方法从指标中排除,导致所有请求到/orders
端点的单个指标。
配置自定义延迟直方图桶
Dapr使用累积直方图指标将延迟值分组到桶中,其中每个桶包含:
- 具有该延迟的请求数量
- 所有具有较低延迟的请求
使用默认延迟桶配置
默认情况下,Dapr将请求延迟指标分组到以下桶中:
1, 2, 3, 4, 5, 6, 8, 10, 13, 16, 20, 25, 30, 40, 50, 65, 80, 100, 130, 160, 200, 250, 300, 400, 500, 650, 800, 1000, 2000, 5000, 10000, 20000, 50000, 100000
以累积方式分组延迟值允许根据需要使用或丢弃桶以增加或减少数据的粒度。 例如,如果一个请求需要3ms,它会被计入3ms桶、4ms桶、5ms桶,依此类推。 同样,如果一个请求需要10ms,它会被计入10ms桶、13ms桶、16ms桶,依此类推。 在这两个请求完成后,3ms桶的计数为1,而10ms桶的计数为2,因为这两个请求都包含在这里。
这显示如下:
1 | 2 | 3 | 4 | 5 | 6 | 8 | 10 | 13 | 16 | 20 | 25 | 30 | 40 | 50 | 65 | 80 | 100 | 130 | 160 | ….. | 100000 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 1 | 1 | 1 | 1 | 1 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | ….. | 2 |
默认的桶数量适用于大多数用例,但可以根据需要进行调整。每个请求创建34个不同的指标,这个值可能会随着大量应用程序而显著增长。 通过增加桶的数量可以获得更准确的延迟百分位数。然而,更多的桶会增加存储指标所需的内存量,可能会对您的监控系统产生负面影响。
建议将延迟桶的数量设置为默认值,除非您在监控系统中看到不必要的内存压力。配置桶的数量允许您选择应用程序:
- 您希望通过更多的桶看到更多细节
- 通过减少桶来获得更广泛的值
在配置桶的数量之前,请注意您的应用程序产生的默认延迟值。
根据您的场景自定义延迟桶
通过修改应用程序的Dapr配置规范中的spec.metrics.latencyDistributionBuckets
字段,定制延迟桶以满足您的需求。
例如,如果您对极低的延迟值(1-10ms)不感兴趣,可以将它们分组到一个10ms桶中。同样,您可以将高值分组到一个桶中(1000-5000ms),同时在您最感兴趣的中间范围内保持更多细节。
以下配置规范示例用11个桶替换了默认的34个桶,在中间范围内提供了更高的粒度:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: custom-metrics
spec:
metrics:
enabled: true
latencyDistributionBuckets: [10, 25, 40, 50, 70, 100, 150, 200, 500, 1000, 5000]
使用正则表达式转换指标
您可以为Dapr sidecar公开的每个指标设置正则表达式以“转换”其值。查看所有Dapr指标的列表。
规则的名称必须与被转换的指标名称匹配。以下示例显示了如何为指标dapr_runtime_service_invocation_req_sent_total
中的标签method
应用正则表达式:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprConfig
spec:
metrics:
enabled: true
http:
increasedCardinality: true
rules:
- name: dapr_runtime_service_invocation_req_sent_total
labels:
- name: method
regex:
"orders/": "orders/.+"
应用此配置后,记录的带有method
标签的指标orders/a746dhsk293972nz
将被替换为orders/
。
使用正则表达式减少指标基数被认为是遗留的。我们鼓励所有用户将spec.metrics.http.increasedCardinality
设置为false
,这更易于配置并提供更好的性能。
参考
1.2.3 - 如何使用Grafana监控指标
可用的仪表板
grafana-system-services-dashboard.json
模板展示了Dapr系统组件的状态,包括dapr-operator、dapr-sidecar-injector、dapr-sentry和dapr-placement:

grafana-sidecar-dashboard.json
模板展示了Dapr sidecar 的状态,包括sidecar 的健康状况/资源使用情况、HTTP和gRPC的吞吐量/延迟、actor、mTLS等:

grafana-actor-dashboard.json
模板展示了Dapr sidecar 的状态、actor 调用的吞吐量/延迟、timer/reminder触发器和基于回合的并发性:

前提条件
在Kubernetes上设置
安装Grafana
添加Grafana Helm仓库:
helm repo add grafana https://grafana.github.io/helm-charts helm repo update
安装图表:
helm install grafana grafana/grafana -n dapr-monitoring
注意
如果您使用Minikube或希望在开发中禁用持久卷,可以使用以下命令禁用:
helm install grafana grafana/grafana -n dapr-monitoring --set persistence.enabled=false
获取Grafana登录的管理员密码:
kubectl get secret --namespace dapr-monitoring grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
您将看到一个类似于
cj3m0OfBNx8SLzUlTx91dEECgzRlYJb60D2evof1%
的密码。请去掉密码中的%
字符,得到cj3m0OfBNx8SLzUlTx91dEECgzRlYJb60D2evof1
作为管理员密码。检查Grafana是否在您的集群中运行:
kubectl get pods -n dapr-monitoring NAME READY STATUS RESTARTS AGE dapr-prom-kube-state-metrics-9849d6cc6-t94p8 1/1 Running 0 4m58s dapr-prom-prometheus-alertmanager-749cc46f6-9b5t8 2/2 Running 0 4m58s dapr-prom-prometheus-node-exporter-5jh8p 1/1 Running 0 4m58s dapr-prom-prometheus-node-exporter-88gbg 1/1 Running 0 4m58s dapr-prom-prometheus-node-exporter-bjp9f 1/1 Running 0 4m58s dapr-prom-prometheus-pushgateway-688665d597-h4xx2 1/1 Running 0 4m58s dapr-prom-prometheus-server-694fd8d7c-q5d59 2/2 Running 0 4m58s grafana-c49889cff-x56vj 1/1 Running 0 5m10s
配置Prometheus作为数据源
首先,您需要将Prometheus连接为Grafana的数据源。
端口转发到svc/grafana:
kubectl port-forward svc/grafana 8080:80 -n dapr-monitoring Forwarding from 127.0.0.1:8080 -> 3000 Forwarding from [::1]:8080 -> 3000 Handling connection for 8080 Handling connection for 8080
打开浏览器访问
http://localhost:8080
登录Grafana
- 用户名 =
admin
- 密码 = 上述密码
- 用户名 =
选择
Configuration
和Data Sources
添加Prometheus作为数据源。
获取您的Prometheus HTTP URL
Prometheus HTTP URL的格式为
http://<prometheus服务端点>.<命名空间>
首先通过运行以下命令获取Prometheus服务器端点:
kubectl get svc -n dapr-monitoring NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE dapr-prom-kube-state-metrics ClusterIP 10.0.174.177 <none> 8080/TCP 7d9h dapr-prom-prometheus-alertmanager ClusterIP 10.0.255.199 <none> 80/TCP 7d9h dapr-prom-prometheus-node-exporter ClusterIP None <none> 9100/TCP 7d9h dapr-prom-prometheus-pushgateway ClusterIP 10.0.190.59 <none> 9091/TCP 7d9h dapr-prom-prometheus-server ClusterIP 10.0.172.191 <none> 80/TCP 7d9h elasticsearch-master ClusterIP 10.0.36.146 <none> 9200/TCP,9300/TCP 7d10h elasticsearch-master-headless ClusterIP None <none> 9200/TCP,9300/TCP 7d10h grafana ClusterIP 10.0.15.229 <none> 80/TCP 5d5h kibana-kibana ClusterIP 10.0.188.224 <none> 5601/TCP 7d10h
在本指南中,服务器名称为
dapr-prom-prometheus-server
,命名空间为dapr-monitoring
,因此HTTP URL将是http://dapr-prom-prometheus-server.dapr-monitoring
。填写以下设置:
- 名称:
Dapr
- HTTP URL:
http://dapr-prom-prometheus-server.dapr-monitoring
- 默认:开启
- 跳过TLS验证:开启
- 这是保存和测试配置所必需的
- 名称:
点击
Save & Test
按钮以验证连接是否成功。
在Grafana中导入仪表板
在Grafana主屏幕的左上角,点击“+”选项,然后选择“Import”。
现在,您可以从发布资产中为您的Dapr版本导入Grafana仪表板模板:
找到您导入的仪表板并享受
提示
将鼠标悬停在每个图表描述角落的
i
上:
参考资料
示例
1.2.4 - 操作指南:配置 New Relic 以收集和分析指标
前提条件
- New Relic 账户,永久免费,每月提供 100 GB 的免费数据摄取,1 个免费完全访问用户,无限制的免费基本用户
背景信息
New Relic 支持 Prometheus 的 OpenMetrics 集成。
本文档将介绍如何在集群中安装该集成,建议使用 Helm chart 进行安装。
安装步骤
根据官方说明安装 Helm。
按照这些说明添加 New Relic 官方 Helm chart 仓库。
运行以下命令通过 Helm 安装 New Relic Logging Kubernetes 插件,并将 YOUR_LICENSE_KEY 替换为您的 New Relic 许可证密钥:
helm install nri-prometheus newrelic/nri-prometheus --set licenseKey=YOUR_LICENSE_KEY
查看指标
相关链接/参考
1.2.5 - 操作指南:配置 Azure Monitor 以搜索日志和收集指标
前提条件
使用配置映射启用 Prometheus 指标抓取
确认 Azure Monitor Agents (AMA) 正在运行。
$ kubectl get pods -n kube-system NAME READY STATUS RESTARTS AGE ... ama-logs-48kpv 2/2 Running 0 2d13h ama-logs-mx24c 2/2 Running 0 2d13h ama-logs-rs-f9bbb9898-vbt6k 1/1 Running 0 30h ama-logs-sm2mz 2/2 Running 0 2d13h ama-logs-z7p4c 2/2 Running 0 2d13h ...
使用配置映射启用 Prometheus 指标端点抓取。
可以使用 azm-config-map.yaml 来启用 Prometheus 指标端点抓取。
如果 Dapr 安装在不同的命名空间,需要修改
monitor_kubernetes_pod_namespaces
数组的值。例如:... prometheus-data-collection-settings: |- [prometheus_data_collection_settings.cluster] interval = "1m" monitor_kubernetes_pods = true monitor_kubernetes_pods_namespaces = ["dapr-system", "default"] [prometheus_data_collection_settings.node] interval = "1m" ...
应用配置映射:
kubectl apply -f ./azm-config.map.yaml
安装带有 JSON 格式日志的 Dapr
安装 Dapr 并启用 JSON 格式日志。
helm install dapr dapr/dapr --namespace dapr-system --set global.logAsJson=true
在 Dapr sidecar 中启用 JSON 格式日志并添加 Prometheus 注解。
注意:只有设置了 Prometheus 注解,Azure Monitor Agents (AMA) 才会发送指标。
在部署的 YAML 文件中添加
dapr.io/log-as-json: "true"
注解。示例:
apiVersion: apps/v1 kind: Deployment metadata: name: pythonapp namespace: default labels: app: python spec: replicas: 1 selector: matchLabels: app: python template: metadata: labels: app: python annotations: dapr.io/enabled: "true" dapr.io/app-id: "pythonapp" dapr.io/log-as-json: "true" prometheus.io/scrape: "true" prometheus.io/port: "9090" prometheus.io/path: "/" ...
使用 Azure Monitor 搜索指标和日志
在 Azure 门户中进入 Azure Monitor。
搜索 Dapr 日志。
下面是一个示例查询,用于解析 JSON 格式日志并查询来自 Dapr 系统进程的日志。
ContainerLog | extend parsed=parse_json(LogEntry) | project Time=todatetime(parsed['time']), app_id=parsed['app_id'], scope=parsed['scope'],level=parsed['level'], msg=parsed['msg'], type=parsed['type'], ver=parsed['ver'], instance=parsed['instance'] | where level != "" | sort by Time
搜索 指标。
这个查询,查询
process_resident_memory_bytes
Prometheus 指标用于 Dapr 系统进程并渲染时间图表。InsightsMetrics | where Namespace == "prometheus" and Name == "process_resident_memory_bytes" | extend tags=parse_json(Tags) | project TimeGenerated, Name, Val, app=tostring(tags['app']) | summarize memInBytes=percentile(Val, 99) by bin(TimeGenerated, 1m), app | where app startswith "dapr-" | render timechart
参考资料
1.3 - 日志记录
在 Dapr 中,日志记录是一个关键功能,帮助开发者监控和调试应用程序。Dapr 提供了多种日志记录选项,您可以根据需求进行灵活配置。
配置 Dapr sidecar 日志
您可以通过设置环境变量来配置 Dapr sidecar 的日志记录。可以调整日志级别、输出格式等,以适应不同的需求。常见的日志级别包括 Debug
、Info
、Warning
和 Error
。
应用程序日志记录
除了 Dapr sidecar,您还可以为您的应用程序设置日志记录。通过使用 Dapr 的日志记录功能,您可以更有效地监控应用程序的行为和性能。
日志输出
Dapr 支持将日志输出到多种目标,包括控制台、文件和远程日志服务。您可以根据应用程序的部署环境选择最合适的日志输出方式。
通过合理配置日志记录,您可以更好地了解应用程序的运行状况,快速发现和解决问题。
1.3.1 - 日志
Dapr 生成的结构化日志会输出到 stdout,可以选择纯文本或 JSON 格式。默认情况下,所有 Dapr 进程(包括运行时或 sidecar,以及所有控制平面服务)都会以纯文本形式将日志写入控制台(stdout)。若要启用 JSON 格式的日志记录,您需要在运行 Dapr 进程时添加 --log-as-json
命令标志。
注意
如果您希望使用 Elastic Search 或 Azure Monitor 等搜索引擎来搜索日志,强烈建议使用 JSON 格式的日志,因为日志收集器和搜索引擎可以利用内置的 JSON 解析器更好地解析这些日志。日志模式
Dapr 生成的日志遵循以下模式:
字段 | 描述 | 示例 |
---|---|---|
time | ISO8601 时间戳 | 2011-10-05T14:48:00.000Z |
level | 日志级别 (info/warn/debug/error) | info |
type | 日志类型 | log |
msg | 日志消息 | hello dapr! |
scope | 日志范围 | dapr.runtime |
instance | 容器名称 | dapr-pod-xxxxx |
app_id | Dapr 应用 ID | dapr-app |
ver | Dapr 运行时版本 | 1.9.0 |
API 日志可能会添加其他结构化字段,具体请参阅 API 日志记录文档。
纯文本和 JSON 格式的日志
- 纯文本日志示例
time="2022-11-01T17:08:48.303776-07:00" level=info msg="starting Dapr Runtime -- version 1.9.0 -- commit v1.9.0-g5dfcf2e" instance=dapr-pod-xxxx scope=dapr.runtime type=log ver=1.9.0
time="2022-11-01T17:08:48.303913-07:00" level=info msg="log level set to: info" instance=dapr-pod-xxxx scope=dapr.runtime type=log ver=1.9.0
- JSON 格式日志示例
{"instance":"dapr-pod-xxxx","level":"info","msg":"starting Dapr Runtime -- version 1.9.0 -- commit v1.9.0-g5dfcf2e","scope":"dapr.runtime","time":"2022-11-01T17:09:45.788005Z","type":"log","ver":"1.9.0"}
{"instance":"dapr-pod-xxxx","level":"info","msg":"log level set to: info","scope":"dapr.runtime","time":"2022-11-01T17:09:45.788075Z","type":"log","ver":"1.9.0"}
日志格式
Dapr 支持输出纯文本(默认)或 JSON 格式的日志。
若要使用 JSON 格式的日志,您需要在安装 Dapr 和部署应用时添加额外的配置选项。建议使用 JSON 格式的日志,因为大多数日志收集器和搜索引擎可以更容易地解析 JSON。
使用 Dapr CLI 启用 JSON 日志
使用 Dapr CLI 运行应用程序时,传递 --log-as-json
选项以启用 JSON 格式的日志,例如:
dapr run \
--app-id orderprocessing \
--resources-path ./components/ \
--log-as-json \
-- python3 OrderProcessingService.py
在 Kubernetes 中启用 JSON 日志
以下步骤描述了如何为 Kubernetes 配置 JSON 格式的日志
Dapr 控制平面
Dapr 控制平面中的所有服务(如 operator
、sentry
等)支持 --log-as-json
选项以启用 JSON 格式的日志记录。
如果您使用 Helm chart 将 Dapr 部署到 Kubernetes,可以通过传递 --set global.logAsJson=true
选项为 Dapr 系统服务启用 JSON 格式的日志;例如:
helm upgrade --install dapr \
dapr/dapr \
--namespace dapr-system \
--set global.logAsJson=true
为 Dapr sidecar 启用 JSON 格式日志
您可以通过在部署中添加 dapr.io/log-as-json: "true"
注释来为 Dapr sidecar 启用 JSON 格式的日志,例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonapp
labels:
app: python
spec:
selector:
matchLabels:
app: python
template:
metadata:
labels:
app: python
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "pythonapp"
# 启用 JSON 格式的日志
dapr.io/log-as-json: "true"
...
API 日志
API 日志使您能够查看应用程序对 Dapr sidecar 的 API 调用,以调试问题或监控应用程序的行为。您可以将 Dapr API 日志与 Dapr 日志事件结合使用。
有关更多信息,请参阅 配置和查看 Dapr 日志 和 配置和查看 Dapr API 日志。
日志收集器
如果您在 Kubernetes 集群中运行 Dapr,Fluentd 是一个流行的容器日志收集器。您可以使用带有 JSON 解析器插件 的 Fluentd 来解析 Dapr JSON 格式的日志。这个 操作指南 显示了如何在集群中配置 Fluentd。
如果您使用 Azure Kubernetes Service,您可以使用内置代理通过 Azure Monitor 收集日志,而无需安装 Fluentd。
搜索引擎
如果您使用 Fluentd,我们建议使用 Elastic Search 和 Kibana。这个 操作指南 显示了如何在 Kubernetes 集群中设置 Elastic Search 和 Kibana。
如果您使用 Azure Kubernetes Service,您可以使用 Azure Monitor for containers 而无需安装任何额外的监控工具。另请阅读 如何启用 Azure Monitor for containers
参考资料
1.3.2 - 操作指南:在 Kubernetes 中设置 Fluentd、Elastic search 和 Kibana
前提条件
安装 Elastic search 和 Kibana
创建一个用于监控工具的 Kubernetes 命名空间
kubectl create namespace dapr-monitoring
添加 Elastic Search 的 Helm 仓库
helm repo add elastic https://helm.elastic.co helm repo update
使用 Helm 安装 Elastic Search
默认情况下,chart 会创建 3 个副本,要求它们位于不同的节点上。如果您的集群少于 3 个节点,请指定较少的副本数。例如,将副本数设置为 1:
helm install elasticsearch elastic/elasticsearch --version 7.17.3 -n dapr-monitoring --set replicas=1
否则:
helm install elasticsearch elastic/elasticsearch --version 7.17.3 -n dapr-monitoring
如果您使用 minikube 或仅在开发过程中想禁用持久卷,可以使用以下命令:
helm install elasticsearch elastic/elasticsearch --version 7.17.3 -n dapr-monitoring --set persistence.enabled=false,replicas=1
安装 Kibana
helm install kibana elastic/kibana --version 7.17.3 -n dapr-monitoring
确保 Elastic Search 和 Kibana 在您的 Kubernetes 集群中正常运行
$ kubectl get pods -n dapr-monitoring NAME READY STATUS RESTARTS AGE elasticsearch-master-0 1/1 Running 0 6m58s kibana-kibana-95bc54b89-zqdrk 1/1 Running 0 4m21s
安装 Fluentd
作为 daemonset 安装配置映射和 Fluentd
下载这些配置文件:
注意:如果您的集群中已经运行了 Fluentd,请启用嵌套的 JSON 解析器,以便它可以解析来自 Dapr 的 JSON 格式日志。
将配置应用到您的集群:
kubectl apply -f ./fluentd-config-map.yaml kubectl apply -f ./fluentd-dapr-with-rbac.yaml
确保 Fluentd 作为 daemonset 运行。FluentD 实例的数量应与集群节点的数量相同。以下示例中,集群中只有一个节点:
$ kubectl get pods -n kube-system -w NAME READY STATUS RESTARTS AGE coredns-6955765f44-cxjxk 1/1 Running 0 4m41s coredns-6955765f44-jlskv 1/1 Running 0 4m41s etcd-m01 1/1 Running 0 4m48s fluentd-sdrld 1/1 Running 0 14s
安装 Dapr 并启用 JSON 格式日志
安装 Dapr 并启用 JSON 格式日志
helm repo add dapr https://dapr.github.io/helm-charts/ helm repo update helm install dapr dapr/dapr --namespace dapr-system --set global.logAsJson=true
在 Dapr sidecar 中启用 JSON 格式日志
在您的部署 yaml 中添加
dapr.io/log-as-json: "true"
注解。例如:apiVersion: apps/v1 kind: Deployment metadata: name: pythonapp namespace: default labels: app: python spec: replicas: 1 selector: matchLabels: app: python template: metadata: labels: app: python annotations: dapr.io/enabled: "true" dapr.io/app-id: "pythonapp" dapr.io/log-as-json: "true" ...
搜索日志
注意:Elastic Search 需要一些时间来索引 Fluentd 发送的日志。
从本地主机端口转发到
svc/kibana-kibana
$ kubectl port-forward svc/kibana-kibana 5601 -n dapr-monitoring Forwarding from 127.0.0.1:5601 -> 5601 Forwarding from [::1]:5601 -> 5601 Handling connection for 5601 Handling connection for 5601
浏览到
http://localhost:5601
展开下拉菜单并点击 Management → Stack Management
在 Stack Management 页面上,选择 Data → Index Management 并等待
dapr-*
被索引。一旦
dapr-*
被索引,点击 Kibana → Index Patterns 然后点击 Create index pattern 按钮。通过在 Index Pattern name 字段中输入
dapr*
来定义一个新的索引模式,然后点击 Next step 按钮继续。通过从 Time field 下拉菜单中选择
@timestamp
选项来配置新索引模式的主要时间字段。点击 Create index pattern 按钮完成索引模式的创建。应显示新创建的索引模式。通过在 Fields 标签中的搜索框中使用搜索,确认感兴趣的字段如
scope
、type
、app_id
、level
等是否被索引。注意:如果找不到索引字段,请稍等。搜索所有索引字段所需的时间取决于数据量和 Elastic Search 运行的资源大小。
要探索索引的数据,展开下拉菜单并点击 Analytics → Discover。
在搜索框中输入查询字符串如
scope:*
并点击 Refresh 按钮查看结果。注意:这可能需要很长时间。返回所有结果所需的时间取决于数据量和 Elastic Search 运行的资源大小。
参考资料
1.3.3 - 操作指南:为 Dapr 日志配置 New Relic
前提条件
- 注册一个 New Relic 账户,享受每月 100 GB 的免费数据摄取、1 个免费完全访问用户和无限制的免费基本用户。
背景
New Relic 提供了一个 Fluent Bit 输出 插件,可以轻松地将日志转发到 New Relic Logs。该插件也可以作为独立的 Docker 镜像使用,并在 Kubernetes 集群中以 DaemonSet 的形式安装,我们称之为 Kubernetes 插件。
本文档将解释如何在集群中安装此插件,推荐使用 Helm chart,也可以通过应用 Kubernetes 清单手动安装。
安装
使用 Helm chart 安装(推荐)
按照官方说明安装 Helm。
添加 New Relic 官方 Helm chart 仓库。
运行以下命令通过 Helm 安装 New Relic Logging Kubernetes 插件,并将占位符 YOUR_LICENSE_KEY 替换为您的 New Relic 许可证密钥:
Helm 3
helm install newrelic-logging newrelic/newrelic-logging --set licenseKey=YOUR_LICENSE_KEY
Helm 2
helm install newrelic/newrelic-logging --name newrelic-logging --set licenseKey=YOUR_LICENSE_KEY
对于欧盟用户,请在上述命令中添加 --set endpoint=https://log-api.eu.newrelic.com/log/v1
。
默认情况下,日志跟踪路径设置为 /var/log/containers/*.log。要更改此设置,请在上述命令中添加 –set fluentBit.path=DESIRED_PATH,并提供您首选的路径。
安装 Kubernetes 清单
下载以下 3 个清单文件到当前工作目录:
curl https://raw.githubusercontent.com/newrelic/helm-charts/master/charts/newrelic-logging/k8s/fluent-conf.yml > fluent-conf.yml curl https://raw.githubusercontent.com/newrelic/helm-charts/master/charts/newrelic-logging/k8s/new-relic-fluent-plugin.yml > new-relic-fluent-plugin.yml curl https://raw.githubusercontent.com/newrelic/helm-charts/master/charts/newrelic-logging/k8s/rbac.yml > rbac.yml
在下载的 new-relic-fluent-plugin.yml 文件中,将占位符 LICENSE_KEY 替换为您的 New Relic 许可证密钥。
对于欧盟用户,将 ENDPOINT 环境变量替换为 https://log-api.eu.newrelic.com/log/v1。
添加许可证密钥后,在终端或命令行界面中运行以下命令:
kubectl apply -f .
[可选] 您可以通过编辑 fluent-conf.yml 文件中的 parsers.conf 部分来配置插件如何解析数据。有关更多信息,请参阅 Fluent Bit 的 Parsers 配置文档。
默认情况下,日志跟踪路径设置为 /var/log/containers/*.log。要更改此设置,请在 new-relic-fluent-plugin.yml 文件中将默认路径替换为您首选的路径。
查看日志
相关链接/参考
2 - Dapr 的部署方式
2.1 - 在本地自托管模式下运行 Dapr
2.1.1 - Dapr 自托管模式概述
概述
Dapr 可以配置为在本地开发者机器或生产环境的虚拟机上运行自托管模式。每个服务都会有一个 Dapr 运行时进程(或称为 sidecar),该进程配置为使用状态存储、发布/订阅、绑定组件和其他构建块。
初始化
Dapr 可以通过 Docker(默认)或 slim-init 模式进行初始化。它也可以在 离线或隔离环境中初始化和运行。
注意
您也可以使用 Podman 代替 Docker 作为容器运行时。请参阅 使用 Podman 初始化 Dapr 以获取更多详细信息。在由于各种网络限制无法安装 Docker 的情况下,这可能会很有用。默认的 Docker 设置提供了即用的功能,包含以下容器和配置:
- 一个 Redis 容器,配置为同时用于状态管理和发布/订阅的默认组件。
- 一个 Zipkin 容器,用于诊断和跟踪。
- 默认的 Dapr 配置和组件安装在
$HOME/.dapr/
(Mac/Linux) 或%USERPROFILE%\.dapr\
(Windows)。
dapr-placement
服务负责管理 actor 的分布方案和键范围设置。此服务不作为容器启动,仅在您使用 Dapr actor 时才需要。有关 actor Placement
服务的更多信息,请阅读 actor 概述。

使用 Dapr 启动应用程序
您可以使用 dapr run
CLI 命令 启动 Dapr sidecar 进程和您的应用程序。其他参数和标志可以在这里找到。
名称解析
Dapr 使用 名称解析组件 在 服务调用 构建块中进行服务发现。默认情况下,Dapr 在自托管模式下使用 mDNS。
如果您在虚拟机上运行 Dapr 或 mDNS 不可用的情况下,可以使用 HashiCorp Consul 组件进行名称解析。
2.1.2 - 如何使用 Podman 在自托管模式下运行 Dapr
本文介绍了如何在 Windows/Linux/macOS 机器或虚拟机上使用 Podman 运行 Dapr。
准备工作
设置 Dapr 环境
要设置 Dapr 控制平面容器并创建默认配置文件,请执行以下命令:
dapr init --container-runtime podman
以进程方式运行应用程序和 sidecar
可以使用 dapr run
CLI 命令 启动 Dapr sidecar 和您的应用程序:
dapr run --app-id myapp --app-port 5000 -- dotnet run
此命令会启动 daprd sidecar 和您的应用程序。
以进程方式运行应用程序,sidecar 作为 Docker 容器运行
如果您希望在 Docker 容器中运行 Dapr,而应用程序在主机上以进程方式运行,则需要配置 Podman 使用主机网络,以便 Dapr 和应用程序可以共享 localhost 网络接口。
在 Linux 主机上运行 Podman 时,可以使用以下命令启动 Dapr:
podman run --network="host" --mount type=bind,source="$(pwd)"/components,target=/components daprio/daprd:edge ./daprd -app-id <my-app-id> -app-port <my-app-port>
然后,您可以在主机上运行您的应用程序,它们可以通过 localhost 网络接口进行连接。
卸载 Dapr 环境
要卸载 Dapr,请运行:
dapr uninstall --container-runtime podman --all
2.1.3 - 如何使用 Docker 自托管 Dapr
本文介绍如何在 Windows/Linux/macOS 机器或虚拟机上使用 Docker 运行 Dapr。
前提条件
设置 Dapr 环境
运行以下命令以初始化 Dapr 控制平面并创建默认配置文件:
dapr init
以进程形式运行应用和 sidecar
使用 dapr run
CLI 命令 启动 Dapr sidecar 和您的应用程序:
dapr run --app-id myapp --app-port 5000 -- dotnet run
此命令将启动 daprd sidecar 并运行 dotnet run
,从而启动您的应用程序。
应用以进程形式运行,sidecar 以 Docker 容器形式运行
如果您希望在 Docker 容器中运行 Dapr,而应用程序在主机上以进程形式运行,则需要配置 Docker 使用主机网络,以便 Dapr 和应用程序可以共享 localhost 网络接口。
注意
Docker 的 host 网络模式仅支持 Linux 主机。在 Linux 主机上运行 Docker 守护进程时,可以使用以下命令启动 Dapr:
docker run --net="host" --mount type=bind,source="$(pwd)"/components,target=/components daprio/daprd:edge ./daprd -app-id <my-app-id> -app-port <my-app-port>
然后,您可以在主机上运行您的应用程序,它们应通过 localhost 网络接口进行连接。
在单个 Docker 容器中运行应用和 Dapr
仅用于开发目的
不建议在同一个容器中同时运行 Dapr 运行时和应用程序。然而,在本地开发场景中可以这样做。
为此,您需要编写一个 Dockerfile 来安装 Dapr 运行时、Dapr CLI 和您的应用程序代码。然后您可以使用 Dapr CLI 调用 Dapr 运行时和您的应用程序代码。
下面是一个实现此目的的 Dockerfile 示例:
FROM python:3.7.1
# 安装 dapr CLI
RUN wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
# 安装 daprd
ARG DAPR_BUILD_DIR
COPY $DAPR_BUILD_DIR /opt/dapr
ENV PATH="/opt/dapr/:${PATH}"
RUN dapr init --slim
# 安装您的应用
WORKDIR /app
COPY python .
RUN pip install requests
ENTRYPOINT ["dapr"]
CMD ["run", "--app-id", "nodeapp", "--app-port", "3000", "node", "app.js"]
请记住,如果 Dapr 需要与其他组件通信,例如 Redis,这些也需要对其可访问。
在 Docker 网络上运行
如果您有多个 Dapr 实例在 Docker 容器中运行,并希望它们能够相互通信(例如用于服务调用),那么您需要创建一个共享的 Docker 网络,并确保这些 Dapr 容器连接到该网络。
您可以使用以下命令创建一个简单的 Docker 网络:
docker network create my-dapr-network
在运行您的 Docker 容器时,您可以使用以下命令将它们连接到网络:
docker run --net=my-dapr-network ...
每个容器将在该网络上接收一个唯一的 IP,并能够与该网络上的其他容器通信。
使用 Docker-Compose 运行
Docker Compose 可用于定义多容器应用程序配置。如果您希望在本地运行多个带有 Dapr sidecar 的应用程序而不使用 Kubernetes,建议使用 Docker Compose 定义(docker-compose.yml
)。
Docker Compose 的语法和工具超出了本文的范围,建议您参考官方 Docker 文档以获取更多详细信息。
为了使用 Dapr 和 Docker Compose 运行您的应用程序,您需要在 docker-compose.yml
中定义 sidecar 模式。例如:
version: '3'
services:
nodeapp:
build: ./node
ports:
- "50001:50001" # Dapr 实例通过 gRPC 通信,因此我们需要暴露 gRPC 端口
depends_on:
- redis
- placement
networks:
- hello-dapr
nodeapp-dapr:
image: "daprio/daprd:edge"
command: [
"./daprd",
"--app-id", "nodeapp",
"--app-port", "3000",
"--placement-host-address", "placement:50006", # Dapr 的 placement 服务可以通过 docker DNS 条目访问
"--resources-path", "./components"
]
volumes:
- "./components/:/components" # 挂载我们的组件文件夹供运行时使用。挂载位置必须与 --resources-path 参数匹配。
depends_on:
- nodeapp
network_mode: "service:nodeapp" # 将 nodeapp-dapr 服务附加到 nodeapp 网络命名空间
... # 部署其他 daprized 服务和组件(例如 Redis)
placement:
image: "daprio/dapr"
command: ["./placement", "--port", "50006"]
ports:
- "50006:50006"
scheduler:
image: "daprio/dapr"
command: ["./scheduler", "--port", "50007"]
ports:
- "50007:50007"
# 警告 - 这是一个 tmpfs 卷,您的状态不会在重启后持久化
volumes:
- type: tmpfs
target: /data
tmpfs:
size: "10000"
networks:
hello-dapr: null
对于在 Linux 主机上运行 Docker 守护进程的用户,您还可以使用
network_mode: host
来利用主机网络(如果需要)。
要进一步了解如何使用 Docker Compose 运行 Dapr,请参阅 Docker-Compose 示例。
上述示例还包括一个使用非持久性数据存储进行测试和开发目的的调度器定义。
在 Kubernetes 上运行
如果您的部署目标是 Kubernetes,请使用 Dapr 的一流集成。请参阅 Dapr 在 Kubernetes 上的文档。
名称解析
Dapr 默认使用 mDNS 作为自托管模式下的名称解析组件进行服务调用。如果您在虚拟机上运行 Dapr 或 mDNS 不可用的地方运行 Dapr,则可以使用 HashiCorp Consul 组件进行名称解析。
Docker 镜像
Dapr 提供了多个不同组件的预构建 Docker 镜像,您应选择适合您所需二进制文件、架构和标签/版本的相关镜像。
镜像
在 Docker Hub 上提供了每个 Dapr 组件的已发布 Docker 镜像。
- daprio/dapr(包含所有 Dapr 二进制文件)
- daprio/daprd
- daprio/placement
- daprio/sentry
- daprio/dapr-dev
标签
Linux/amd64
latest
: 最新发布版本,仅用于开发目的。edge
: 最新的 edge 构建(master)。major.minor.patch
: 发布版本。major.minor.patch-rc.iteration
: 发布候选版本。
Linux/arm/v7
latest-arm
: ARM 的最新发布版本,仅用于开发目的。edge-arm
: ARM 的最新 edge 构建(master)。major.minor.patch-arm
: ARM 的发布版本。major.minor.patch-rc.iteration-arm
: ARM 的发布候选版本。
2.1.4 - 操作指南:在离线或隔离环境中运行Dapr
概述
通常情况下,Dapr初始化时会从网络下载二进制文件并拉取镜像来设置开发环境。然而,Dapr也支持使用预先下载的安装包进行离线或隔离安装,这可以通过Docker或精简模式来实现。每个Dapr版本的安装包都被构建成一个Dapr安装包,可以下载。通过使用这个安装包和Dapr CLI的init
命令,你可以在没有网络访问的环境中安装Dapr。
设置
在进行隔离初始化之前,需要预先下载一个Dapr安装包,其中包含CLI、运行时和仪表板的内容。这避免了在本地初始化Dapr时需要下载二进制文件和Docker镜像。
下载特定版本的Dapr安装包。例如,daprbundle_linux_amd64.tar.gz,daprbundle_windows_amd64.zip。
解压缩安装包。
要安装Dapr CLI,将
daprbundle/dapr (Windows为dapr.exe)
二进制文件复制到合适的位置:- 对于Linux/MacOS -
/usr/local/bin
- 对于Windows,创建一个目录并将其添加到系统PATH。例如,创建一个名为
c:\dapr
的目录,并通过编辑系统环境变量将此目录添加到路径中。
注意:如果Dapr CLI没有移动到合适的位置,你可以直接使用包中的本地
dapr
CLI二进制文件。上述步骤是为了将其移动到常用位置并添加到路径中。- 对于Linux/MacOS -
初始化Dapr环境
Dapr可以在有或没有Docker容器的隔离环境中初始化。
使用Docker初始化Dapr
(前提条件:环境中可用Docker)
进入安装包目录并运行以下命令:
dapr init --from-dir .
对于Linux用户,如果你使用sudo运行Docker命令,你需要使用“sudo dapr init”
如果你不是在安装包目录下运行上述命令,请提供安装包目录的完整路径。例如,假设安装包目录路径是$HOME/daprbundle,运行
dapr init --from-dir $HOME/daprbundle
以获得相同的效果。
输出应类似于以下内容:
正在进行超空间跳跃...
ℹ️ 正在安装最新的运行时版本
↘ 正在提取二进制文件并设置组件... 已加载镜像:daprio/dapr:$version
✅ 提取二进制文件并设置组件完成。
✅ 二进制文件提取和组件设置已完成。
ℹ️ daprd二进制文件已安装到$HOME/.dapr/bin。
ℹ️ dapr_placement容器正在运行。
ℹ️ 使用`docker ps`检查正在运行的容器。
✅ 成功!Dapr已启动并运行。要开始使用,请访问:https://aka.ms/dapr-getting-started
注意:要模拟在线 Dapr初始化,使用
dapr init
,你也可以运行Redis和Zipkin容器,如下所示:
1. docker run --name "dapr_zipkin" --restart always -d -p 9411:9411 openzipkin/zipkin
2. docker run --name "dapr_redis" --restart always -d -p 6379:6379 redislabs/rejson
不使用Docker初始化Dapr
或者,为了让CLI不安装任何默认配置文件或运行任何Docker容器,可以使用init
命令的--slim
标志。这样只会安装Dapr的二进制文件。
dapr init --slim --from-dir .
输出应类似于以下内容:
⌛ 正在进行超空间跳跃...
ℹ️ 正在安装最新的运行时版本
↙ 正在提取二进制文件并设置组件...
✅ 提取二进制文件并设置组件完成。
✅ 二进制文件提取和组件设置已完成。
ℹ️ daprd二进制文件已安装到$HOME/.dapr/bin。
ℹ️ placement二进制文件已安装到$HOME/.dapr/bin。
✅ 成功!Dapr已启动并运行。要开始使用,请访问:https://aka.ms/dapr-getting-started
2.1.5 - 如何在没有 Docker 的环境中以自托管模式运行 Dapr
前提条件
初始化无容器的 Dapr
Dapr CLI 提供了一个选项,可以使用 slim init 初始化 Dapr,而无需依赖 Docker 来创建默认的开发环境。安装 Dapr CLI 后,使用以下命令进行 slim init 初始化:
dapr init --slim
这将安装两个不同的二进制文件:
daprd
placement
placement
二进制文件用于在 Dapr 自托管安装中启用 actor。
在 slim init 模式下,不会安装用于状态管理或消息发布/订阅的默认组件(如 Redis)。这意味着,除了 服务调用 外,安装时没有其他内置功能可用。您可以根据需要设置自己的环境和自定义组件。
如果配置了状态存储,则可以进行基于 actor 的服务调用,具体说明请参见以下章节。
执行服务调用
请参阅 Hello Dapr slim 示例,了解如何在 slim init 模式下执行服务调用。
启用状态管理或消息发布/订阅
请参阅 在无 Docker 的自托管模式下配置 Redis 的文档,以启用本地状态存储或用于消息传递的发布/订阅代理。
启用 actor
要启用 actor placement:
- 在本地运行 placement 服务。
- 启用支持 ETags 的 事务性状态存储 以使用 actor。例如,在自托管模式下配置的 Redis。
默认情况下,placement
二进制文件安装在:
- 对于 Linux/MacOS:
/$HOME/.dapr/bin
- 对于 Windows:
%USERPROFILE%\.dapr\bin
$ $HOME/.dapr/bin/placement
INFO[0000] starting Dapr Placement Service -- version 1.0.0-rc.1 -- commit 13ae49d instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
INFO[0000] log level set to: info instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
INFO[0000] metrics server started on :9090/ instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.metrics type=log ver=1.0.0-rc.1
INFO[0000] Raft server is starting on 127.0.0.1:8201... instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement.raft type=log ver=1.0.0-rc.1
INFO[0000] placement service started on port 50005 instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
INFO[0000] Healthz server is listening on :8080 instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
INFO[0001] cluster leadership acquired instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
INFO[0001] leader is established. instance=Nicoletaz-L10.redmond.corp.microsoft.com scope=dapr.placement type=log ver=1.0.0-rc.1
在 Windows 上运行独立的 placement 时,指定端口 6050:
%USERPROFILE%/.dapr/bin/placement.exe -port 6050
time="2022-10-17T14:56:55.4055836-05:00" level=info msg="starting Dapr Placement Service -- version 1.9.0 -- commit fdce5f1f1b76012291c888113169aee845f25ef8" instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
time="2022-10-17T14:56:55.4066226-05:00" level=info msg="log level set to: info" instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
time="2022-10-17T14:56:55.4067306-05:00" level=info msg="metrics server started on :9090/" instance=LAPTOP-OMK50S19 scope=dapr.metrics type=log ver=1.9.0
time="2022-10-17T14:56:55.4077529-05:00" level=info msg="Raft server is starting on 127.0.0.1:8201..." instance=LAPTOP-OMK50S19 scope=dapr.placement.raft type=log ver=1.9.0
time="2022-10-17T14:56:55.4077529-05:00" level=info msg="placement service started on port 6050" instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
time="2022-10-17T14:56:55.4082772-05:00" level=info msg="Healthz server is listening on :8080" instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
time="2022-10-17T14:56:56.8232286-05:00" level=info msg="cluster leadership acquired" instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
time="2022-10-17T14:56:56.8232286-05:00" level=info msg="leader is established." instance=LAPTOP-OMK50S19 scope=dapr.placement type=log ver=1.9.0
现在,要运行启用了 actor 的应用程序,您可以参考以下示例:
更新状态存储配置文件以匹配您的 Redis 主机和密码设置。
通过将元数据部分设置为类似于 示例 Java Redis 组件 的定义,将其启用为 actor 状态存储。
- name: actorStateStore
value: "true"
清理
完成后,请按照 在自托管环境中卸载 Dapr 的步骤移除二进制文件。
下一步
- 使用默认的 Docker 或在 airgap 环境 中运行 Dapr
- 在自托管模式下升级 Dapr
2.1.6 - 操作指南:持久化调度器作业
调度器服务负责将作业写入嵌入式数据库并进行调度执行。
默认情况下,调度器服务会将数据写入本地卷dapr_scheduler
,这意味着数据在重启时会被持久化。
此本地卷的主机文件位置通常位于/var/lib/docker/volumes/dapr_scheduler/_data
或~/.local/share/containers/storage/volumes/dapr_scheduler/_data
,具体取决于您的容器运行时。
请注意,如果您使用的是Docker Desktop,此卷位于Docker Desktop虚拟机的文件系统中,可以通过以下命令访问:
docker run -it --privileged --pid=host debian nsenter -t 1 -m -u -n -i sh
调度器的持久卷可以通过使用预先存在的自定义卷进行修改,或者由Dapr自动创建。
dapr init --scheduler-volume my-scheduler-volume
2.1.7 - 在自托管环境中升级 Dapr 的步骤
卸载当前的 Dapr 部署:
注意
这将删除默认的$HOME/.dapr
目录、二进制文件和所有容器(dapr_redis、dapr_placement 和 dapr_zipkin)。如果在 Linux 上运行 docker 命令需要使用 sudo,请使用sudo
。dapr uninstall --all
访问本指南以下载并安装最新版本的 CLI。
初始化 Dapr 运行时:
dapr init
确认您正在使用最新版本的 Dapr (v1.15.5):
$ dapr --version CLI version: 1.15 Runtime version: 1.15
2.1.8 - 在自托管环境中卸载 Dapr
以下 CLI 命令用于移除 Dapr sidecar 二进制文件和 placement 容器:
dapr uninstall
上述命令不会移除在 dapr init
时默认安装的 Redis 或 Zipkin 容器,以防您将它们用于其他用途。要移除 Redis、Zipkin、actor placement 容器,以及位于 $HOME/.dapr
或 %USERPROFILE%\.dapr\
的默认 Dapr 目录,请运行以下命令:
dapr uninstall --all
注意
对于 Linux/MacOS 用户,如果您使用 sudo 运行 docker 命令,或者 Dapr 安装在/usr/local/bin
(默认安装路径),则需要使用 sudo dapr uninstall
来移除 Dapr 二进制文件和/或容器。2.2 - 在 Kubernetes 环境中部署和运行 Dapr
2.2.1 - Dapr 在 Kubernetes 上的概述
Dapr 可以在任何支持的 Kubernetes 版本上运行。为此,Dapr 部署了一些 Kubernetes 服务,这些服务提供了良好的集成,使得在 Kubernetes 上运行 Dapr 应用程序变得简单。
Kubernetes 服务 | 描述 |
---|---|
dapr-operator | 管理 Dapr 的组件更新和 Kubernetes 服务端点(如状态存储、发布/订阅等) |
dapr-sidecar-injector | 将 Dapr 注入到已标注的部署 pod 中,并添加环境变量 DAPR_HTTP_PORT 和 DAPR_GRPC_PORT ,以便用户应用程序可以轻松与 Dapr 通信,而无需硬编码 Dapr 端口。 |
dapr-placement | 专用于actor。创建映射表,将 actor 实例映射到 pod |
dapr-sentry | 管理服务之间的 mTLS 并充当证书颁发机构。更多信息请参阅安全概述 |

支持的版本
Dapr 对 Kubernetes 的支持遵循 Kubernetes 版本偏差政策。
将 Dapr 部署到 Kubernetes 集群
阅读在 Kubernetes 集群上部署 Dapr以了解如何将 Dapr 部署到您的 Kubernetes 集群。
将 Dapr 添加到 Kubernetes 部署
要在 Kubernetes 集群中部署和运行启用 Dapr 的应用程序,只需在 pod 中添加一些注释即可。例如,在以下示例中,您的 Kubernetes pod 被标注为:
- 为您的服务提供 Dapr 识别的
id
和port
- 配置追踪功能
- 启动 Dapr sidecar 容器
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "tracing"
有关更多信息,请查看 Dapr 注释。
从私有注册表拉取容器镜像
Dapr 可以与任何用户应用程序容器镜像无缝配合使用,无论其来源。只需初始化 Dapr并在 Kubernetes 定义中添加 Dapr 注释 以添加 Dapr sidecar。
Dapr 控制平面和 sidecar 镜像来自 daprio Docker Hub 容器注册表,这是一个公共注册表。
有关以下内容的信息:
- 从私有注册表拉取您的应用程序镜像,请参考官方 Kubernetes 文档。
- 使用 Azure 容器注册表与 Azure Kubernetes 服务,请参考 AKS 文档。
教程
通过Hello Kubernetes 教程了解如何在您的 Kubernetes 集群上开始使用 Dapr。
相关链接
2.2.2 - Kubernetes 集群配置
2.2.2.1 - 设置 Minikube 集群
前提条件
- 安装:
- 对于 Windows:
- 在 BIOS 中启用虚拟化
- 安装 Hyper-V
注意
查看 [Minikube 官方文档] 以了解有关驱动程序的详细信息和插件安装方法。启动 Minikube 集群
如果您的项目需要,设置默认的虚拟机。
minikube config set vm-driver [driver_name]
启动集群。如果需要,使用
--kubernetes-version
指定 Kubernetes 1.13.x 或更新版本。minikube start --cpus=4 --memory=4096
启用 Minikube 仪表板和 ingress 插件。
# 启用仪表板 minikube addons enable dashboard # 启用 ingress minikube addons enable ingress
安装 Helm v3(可选)
如果您使用 Helm,安装 Helm v3 客户端。
重要
最新的 Dapr Helm chart 不再支持 Helm v2。从 Helm v2 迁移到 Helm v3。故障排除
负载均衡器的外部 IP 地址在 kubectl get svc
中未显示。
在 Minikube 中,kubectl get svc
中的 EXTERNAL-IP
显示为 <pending>
状态。此时,您可以运行 minikube service [service_name]
来打开服务,即使没有外部 IP 地址。
$ kubectl get svc
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
...
calculator-front-end LoadBalancer 10.103.98.37 <pending> 80:30534/TCP 25h
calculator-front-end-dapr ClusterIP 10.107.128.226 <none> 80/TCP,50001/TCP 25h
...
$ minikube service calculator-front-end
|-----------|----------------------|-------------|---------------------------|
| NAMESPACE | NAME | TARGET PORT | URL |
|-----------|----------------------|-------------|---------------------------|
| default | calculator-front-end | | http://192.168.64.7:30534 |
|-----------|----------------------|-------------|---------------------------|
🎉 正在默认浏览器中打开 Kubernetes 服务 default/calculator-front-end...
相关链接
2.2.2.2 - 设置 KiND 集群
前提条件
- 安装:
- 对于 Windows:
- 在 BIOS 中启用虚拟化
- 安装 Hyper-V
安装和配置 KiND
使用 Docker Desktop 时,请确保您已进行推荐的设置。
配置并创建 KiND 集群
创建一个名为
kind-cluster-config.yaml
的文件,并粘贴以下内容:kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 nodes: - role: control-plane kubeadmConfigPatches: - | kind: InitConfiguration nodeRegistration: kubeletExtraArgs: node-labels: "ingress-ready=true" extraPortMappings: - containerPort: 80 hostPort: 8081 protocol: TCP - containerPort: 443 hostPort: 8443 protocol: TCP - role: worker - role: worker
此集群配置:
- 启动一个由控制平面和两个工作节点组成的 Kubernetes 集群。
- 方便将来设置 Ingress。
- 将容器端口映射到主机。
运行
kind create cluster
命令,提供集群配置文件:kind create cluster --config kind-cluster-config.yaml
预期输出
Creating cluster "kind" ... ✓ Ensuring node image (kindest/node:v1.21.1) 🖼 ✓ Preparing nodes 📦 📦 📦 ✓ Writing configuration 📜 ✓ Starting control-plane 🕹️ ✓ Installing CNI 🔌 ✓ Installing StorageClass 💾 ✓ Joining worker nodes 🚜 Set kubectl context to "kind-kind" You can now use your cluster with: kubectl cluster-info --context kind-kind Thanks for using kind! 😊
初始化并运行 Dapr
在 Kubernetes 中初始化 Dapr。
dapr init --kubernetes
Dapr 初始化完成后,您可以在集群上使用其核心组件。
验证 Dapr 组件的状态:
dapr status -k
预期输出
NAME NAMESPACE HEALTHY STATUS REPLICAS VERSION AGE CREATED dapr-sentry dapr-system True Running 1 1.5.1 53s 2021-12-10 09:27.17 dapr-operator dapr-system True Running 1 1.5.1 53s 2021-12-10 09:27.17 dapr-sidecar-injector dapr-system True Running 1 1.5.1 53s 2021-12-10 09:27.17 dapr-dashboard dapr-system True Running 1 0.9.0 53s 2021-12-10 09:27.17 dapr-placement-server dapr-system True Running 1 1.5.1 52s 2021-12-10 09:27.18
将端口转发到 Dapr 仪表板:
dapr dashboard -k -p 9999
访问
http://localhost:9999
检查设置是否成功。
在 Kind Kubernetes 集群上安装 metrics-server
获取 metrics-server 清单
wget https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
向 components.yaml 文件添加不安全的 TLS 参数
metadata: labels: k8s-app: metrics-server spec: containers: - args: - --cert-dir=/tmp - --secure-port=4443 - --kubelet-preferred-address-types=InternalIP,ExternalIP,Hostname - --kubelet-use-node-status-port - --kubelet-insecure-tls <==== 添加此项 - --metric-resolution=15s image: k8s.gcr.io/metrics-server/metrics-server:v0.6.2 imagePullPolicy: IfNotPresent livenessProbe: failureThreshold: 3 httpGet: path: /livez
应用修改后的清单
kubectl apply -f components.yaml
相关链接
2.2.2.3 - 配置 Azure Kubernetes 服务 (AKS) 集群
本指南将引导您安装 Azure Kubernetes 服务 (AKS) 集群。如果您需要更多信息,请参考 快速入门:使用 Azure CLI 部署 AKS 集群
先决条件
部署 AKS 集群
在终端中登录到 Azure。
az login
设置您的默认订阅:
az account set -s [your_subscription_id]
创建资源组。
az group create --name [your_resource_group] --location [region]
创建 AKS 集群。若需使用特定版本的 Kubernetes,请使用
--kubernetes-version
参数(需 1.13.x 或更高版本)。az aks create --resource-group [your_resource_group] --name [your_aks_cluster_name] --node-count 2 --enable-addons http_application_routing --generate-ssh-keys
获取 AKS 集群的访问凭据。
az aks get-credentials -n [your_aks_cluster_name] -g [your_resource_group]
AKS Edge Essentials
要使用 Azure Kubernetes 服务 (AKS) Edge Essentials 创建单机 K8s/K3s Linux-only 集群,您可以按照 AKS Edge Essentials 快速入门指南 进行操作。
注意
AKS Edge Essentials 不自带默认存储类,这可能会导致在部署 Dapr 时出现问题。为避免此问题,请确保在部署 Dapr 之前在集群上启用 local-path-provisioner 存储类。有关更多信息,请参考 AKS EE 上的 Local Path Provisioner。相关链接
2.2.2.4 - 设置 Google Kubernetes Engine (GKE) 集群
前提条件
创建新集群
运行以下命令以创建 GKE 集群:
$ gcloud services enable container.googleapis.com && \
gcloud container clusters create $CLUSTER_NAME \
--zone $ZONE \
--project $PROJECT_ID
更多选项请参阅:
- Google Cloud SDK 文档。
- 通过 Cloud Console 创建集群以获得更具互动性的体验。
私有 GKE 集群的 Sidecar 注入
私有集群的 Sidecar 注入需要额外步骤。
在私有 GKE 集群中,自动创建的主访问防火墙规则未开放 Dapr 所需的 4000 端口用于 Sidecar 注入。
查看相关的防火墙规则:
$ gcloud compute firewall-rules list --filter="name~gke-${CLUSTER_NAME}-[0-9a-z]*-master"
更新现有规则以允许 Kubernetes 主节点访问 4000 端口:
$ gcloud compute firewall-rules update <firewall-rule-name> --allow tcp:10250,tcp:443,tcp:4000
获取 kubectl
的凭据
运行以下命令以获取您的凭据:
$ gcloud container clusters get-credentials $CLUSTER_NAME \
--zone $ZONE \
--project $PROJECT_ID
安装 Helm v3(可选)
如果您使用 Helm,请安装 Helm v3 客户端。
重要
最新的 Dapr Helm chart 不再支持 Helm v2。请参考 从 Helm v2 迁移到 Helm v3。故障排除
Kubernetes 仪表板权限
如果您收到类似以下的错误消息:
configmaps is forbidden: User "system:serviceaccount:kube-system:kubernetes-dashboard" cannot list configmaps in the namespace "default"
请执行此命令:
kubectl create clusterrolebinding kubernetes-dashboard -n kube-system --clusterrole=cluster-admin --serviceaccount=kube-system:kubernetes-dashboard
相关链接
2.2.2.5 - 配置弹性Kubernetes服务(EKS)集群
本指南将引导您配置一个弹性Kubernetes服务(EKS)集群。如果您需要更多信息,请参考创建一个Amazon EKS集群
前提条件
部署一个EKS集群
在终端中配置AWS凭证。
aws configure
创建一个名为
cluster-config.yaml
的新文件,并将以下内容添加到其中,将[your_cluster_name]
、[your_cluster_region]
和[your_k8s_version]
替换为相应的值:apiVersion: eksctl.io/v1alpha5 kind: ClusterConfig metadata: name: [your_cluster_name] region: [your_cluster_region] version: [your_k8s_version] tags: karpenter.sh/discovery: [your_cluster_name] iam: withOIDC: true managedNodeGroups: - name: mng-od-4vcpu-8gb desiredCapacity: 2 minSize: 1 maxSize: 5 instanceType: c5.xlarge privateNetworking: true addons: - name: vpc-cni attachPolicyARNs: - arn:aws:iam::aws:policy/AmazonEKS_CNI_Policy - name: coredns version: latest - name: kube-proxy version: latest - name: aws-ebs-csi-driver wellKnownPolicies: ebsCSIController: true
通过运行以下命令创建集群:
eksctl create cluster -f cluster.yaml
验证kubectl上下文:
kubectl config current-context
为sidecar访问和默认存储类添加Dapr要求:
更新安全组规则,创建端口4000的入站规则,以允许EKS集群与Dapr sidecar通信。
aws ec2 authorize-security-group-ingress --region [your_aws_region] \ --group-id [your_security_group] \ --protocol tcp \ --port 4000 \ --source-group [your_security_group]
如果没有默认存储类,请添加一个:
kubectl patch storageclass gp2 -p '{"metadata": {"annotations":{"storageclass.kubernetes.io/is-default-class":"true"}}}'
安装Dapr
运行以下命令安装Dapr:
dapr init -k
您应该看到以下响应:
⌛ Making the jump to hyperspace...
ℹ️ Note: To install Dapr using Helm, see here: https://docs.dapr.io/getting-started/install-dapr-kubernetes/#install-with-helm-advanced
ℹ️ Container images will be pulled from Docker Hub
✅ Deploying the Dapr control plane with latest version to your cluster...
✅ Deploying the Dapr dashboard with latest version to your cluster...
✅ Success! Dapr has been installed to namespace dapr-system. To verify, run `dapr status -k' in your terminal. To get started, go here: https://docs.dapr.io/getting-started
故障排除
访问权限
如果您遇到访问权限问题,请确保您使用的是创建集群时使用的相同AWS配置文件。如有需要,使用正确的配置文件更新kubectl配置。更多信息请参考这里:
aws eks --region [your_aws_region] update-kubeconfig --name [your_eks_cluster_name] --profile [your_profile_name]
相关链接
2.2.3 - 在 Kubernetes 集群上部署 Dapr
在 Kubernetes 上设置 Dapr 时,你可以使用 Dapr CLI 或 Helm。
混合集群
Dapr CLI 和 Dapr Helm chart 默认会部署到带有标签kubernetes.io/os=linux
的节点上。如果你的应用程序需要,你也可以将 Dapr 部署到 Windows 节点。更多信息请参见部署到混合 Linux/Windows Kubernetes 集群。使用 Dapr CLI 安装
你可以使用 Dapr CLI 在 Kubernetes 集群中安装 Dapr。
先决条件
- 安装:
- 创建一个带有 Dapr 的 Kubernetes 集群。以下是一些有用的链接:
安装选项
你可以从官方 Helm chart 或私有 chart 安装 Dapr,并使用自定义命名空间等。
从官方 Dapr Helm chart 安装 Dapr
-k
标志用于在当前上下文的 Kubernetes 集群中初始化 Dapr。
通过检查
kubectl context (kubectl config get-contexts)
来验证是否设置了正确的 “目标” 集群。- 你可以使用
kubectl config use-context <CONTEXT>
设置不同的上下文。
- 你可以使用
使用以下命令在集群中初始化 Dapr:
dapr init -k
预期输出
⌛ 正在初始化... ✅ 正在将 Dapr 控制平面部署到集群中... ✅ 成功!Dapr 已安装到命名空间 dapr-system。要验证,请在终端中运行 "dapr status -k"。要开始,请访问此处:https://aka.ms/dapr-getting-started
运行仪表板:
dapr dashboard -k
如果你在非默认命名空间中安装了 Dapr,请运行:
dapr dashboard -k -n <your-namespace>
从官方 Dapr Helm chart 安装 Dapr(带开发标志)
添加 --dev
标志在当前上下文的 Kubernetes 集群中初始化 Dapr,并附加 Redis 和 Zipkin 部署。
步骤与从 Dapr Helm chart 安装类似,只是需要在 init
命令后附加 --dev
标志:
dapr init -k --dev
预期输出:
⌛ 正在初始化...
ℹ️ 注意:要使用 Helm 安装 Dapr,请参见此处:https://docs.dapr.io/getting-started/install-dapr-kubernetes/#install-with-helm-advanced
ℹ️ 容器镜像将从 Docker Hub 拉取
✅ 正在将最新版本的 Dapr 控制平面部署到集群中...
✅ 正在将最新版本的 Dapr 仪表板部署到集群中...
✅ 正在将最新版本的 Dapr Redis 部署到集群中...
✅ 正在将最新版本的 Dapr Zipkin 部署到集群中...
ℹ️ 正在将 "statestore" 组件应用到 Kubernetes "default" 命名空间。
ℹ️ 正在将 "pubsub" 组件应用到 Kubernetes "default" 命名空间。
ℹ️ 正在将 "appconfig" zipkin 配置应用到 Kubernetes "default" 命名空间。
✅ 成功!Dapr 已安装到命名空间 dapr-system。要验证,请在终端中运行 `dapr status -k`。要开始,请访问此处:https://aka.ms/dapr-getting-started
经过一段时间(或使用 --wait
标志并指定等待时间),你可以检查 Redis 和 Zipkin 组件是否已部署到集群中。
kubectl get pods --namespace default
预期输出:
NAME READY STATUS RESTARTS AGE
dapr-dev-zipkin-bfb4b45bb-sttz7 1/1 Running 0 159m
dapr-dev-redis-master-0 1/1 Running 0 159m
dapr-dev-redis-replicas-0 1/1 Running 0 159m
dapr-dev-redis-replicas-1 1/1 Running 0 159m
dapr-dev-redis-replicas-2 1/1 Running 0 158m
从私有 Dapr Helm chart 安装 Dapr
从私有 Helm chart 安装 Dapr在以下情况下可能有帮助:
- 需要对 Dapr Helm chart 进行更细粒度的控制
- 有自定义的 Dapr 部署
- 从由你的组织管理和维护的受信任注册表中拉取 Helm chart
设置以下参数以允许 dapr init -k
从配置的 Helm 仓库安装 Dapr 镜像。
export DAPR_HELM_REPO_URL="https://helm.custom-domain.com/dapr/dapr"
export DAPR_HELM_REPO_USERNAME="username_xxx"
export DAPR_HELM_REPO_PASSWORD="passwd_xxx"
在高可用模式下安装
你可以在 dapr-system
命名空间中运行每个控制平面 pod 的三个副本以用于生产场景。
dapr init -k --enable-ha=true
在自定义命名空间中安装
初始化 Dapr 时的默认命名空间是 dapr-system
。你可以使用 -n
标志覆盖此设置。
dapr init -k -n mynamespace
禁用 mTLS
Dapr 默认使用 mTLS 初始化。你可以通过以下方式禁用它:
dapr init -k --enable-mtls=false
等待安装完成
你可以使用 --wait
标志等待安装完成其部署。默认超时时间为 300 秒(5 分钟),但可以使用 --timeout
标志自定义。
dapr init -k --wait --timeout 600
使用 CLI 卸载 Kubernetes 上的 Dapr
在本地机器上运行以下命令以卸载集群上的 Dapr:
dapr uninstall -k
使用 Helm 安装
你可以使用 Helm v3 chart 在 Kubernetes 上安装 Dapr。
❗重要: 最新的 Dapr Helm chart 不再支持 Helm v2。从 Helm v2 迁移到 Helm v3。
先决条件
- 安装:
- 创建一个带有 Dapr 的 Kubernetes 集群。以下是一些有用的链接:
添加并安装 Dapr Helm chart
添加 Helm 仓库并更新:
// 添加官方 Dapr Helm chart。 helm repo add dapr https://dapr.github.io/helm-charts/ // 或者也可以添加私有 Dapr Helm chart。 helm repo add dapr http://helm.custom-domain.com/dapr/dapr/ \ --username=xxx --password=xxx helm repo update // 查看哪些 chart 版本可用 helm search repo dapr --devel --versions
在
dapr-system
命名空间中安装 Dapr chart 到你的集群。helm upgrade --install dapr dapr/dapr \ --version=1.15 \ --namespace dapr-system \ --create-namespace \ --wait
要在高可用模式下安装:
helm upgrade --install dapr dapr/dapr \ --version=1.15 \ --namespace dapr-system \ --create-namespace \ --set global.ha.enabled=true \ --wait
要在高可用模式下安装并独立于全局缩放选择服务:
helm upgrade --install dapr dapr/dapr \ --version=1.15 \ --namespace dapr-system \ --create-namespace \ --set global.ha.enabled=false \ --set dapr_scheduler.ha=true \ --set dapr_placement.ha=true \ --wait
有关使用 Helm 安装和升级 Dapr 的更多信息,请参见生产就绪部署的 Kubernetes 指南。
(可选)将 Dapr 仪表板作为控制平面的一部分安装
如果你想安装 Dapr 仪表板,请使用此 Helm chart 并选择附加设置:
helm install dapr dapr/dapr-dashboard --namespace dapr-system
例如:
helm repo add dapr https://dapr.github.io/helm-charts/
helm repo update
kubectl create namespace dapr-system
# 安装 Dapr 仪表板
helm install dapr-dashboard dapr/dapr-dashboard --namespace dapr-system
验证安装
安装完成后,验证 dapr-operator
、dapr-placement
、dapr-sidecar-injector
和 dapr-sentry
pod 是否在 dapr-system
命名空间中运行:
kubectl get pods --namespace dapr-system
NAME READY STATUS RESTARTS AGE
dapr-dashboard-7bd6cbf5bf-xglsr 1/1 Running 0 40s
dapr-operator-7bd6cbf5bf-xglsr 1/1 Running 0 40s
dapr-placement-7f8f76778f-6vhl2 1/1 Running 0 40s
dapr-sidecar-injector-8555576b6f-29cqm 1/1 Running 0 40s
dapr-sentry-9435776c7f-8f7yd 1/1 Running 0 40s
卸载 Kubernetes 上的 Dapr
helm uninstall dapr --namespace dapr-system
更多信息
- 阅读生产环境的 Kubernetes 指南以获取推荐的 Helm chart 值
- Dapr Helm chart 的更多细节
使用基于 Mariner 的镜像
在 Kubernetes 上默认拉取的容器镜像基于 distroless。
或者,你可以使用基于 Mariner 2(最小 distroless)的 Dapr 容器镜像。Mariner,官方称为 CBL-Mariner,是一个由微软维护的免费开源 Linux 发行版和容器基础镜像。对于一些 Dapr 用户,利用基于 Mariner 的容器镜像可以帮助你满足合规要求。
要使用基于 Mariner 的 Dapr 镜像,你需要在 Docker 标签中添加 -mariner
。例如,ghcr.io/dapr/dapr:latest
是基于 distroless 的 Docker 镜像,而 ghcr.io/dapr/dapr:latest-mariner
是基于 Mariner 的。也有固定到特定版本的标签可用,例如 1.15-mariner
。
在 Dapr CLI 中,你可以使用 --image-variant
标志切换到使用基于 Mariner 的镜像。
dapr init -k --image-variant mariner
在 Kubernetes 和 Helm 中,你可以通过设置 global.tag
选项并添加 -mariner
来使用基于 Mariner 的镜像。例如:
helm upgrade --install dapr dapr/dapr \
--version=1.15 \
--namespace dapr-system \
--create-namespace \
--set global.tag=1.15.5-mariner \
--wait
相关链接
2.2.4 - 在 Kubernetes 集群上升级 Dapr
您可以通过 Dapr CLI 或 Helm 来升级 Kubernetes 集群上的 Dapr 控制平面。
注意
请参阅 Dapr 版本政策 以获取 Dapr 升级路径的指导。使用 Dapr CLI 升级
您可以使用 Dapr CLI 来升级 Dapr。
前提条件
将现有集群升级到 1.15.5
dapr upgrade -k --runtime-version=1.15.5
您可以使用 Dapr CLI 提供所有可用的 Helm chart 配置。
通过 CLI 升级的故障排除
在集群上运行升级时,可能会遇到一个已知问题,即之前可能在集群上安装了 1.0.0-rc.2 之前的版本。
虽然这个问题不常见,但某些升级路径可能会在您的集群上留下不兼容的 CustomResourceDefinition
。如果遇到这种情况,您可能会看到如下错误信息:
❌ 升级 Dapr 失败:警告:kubectl apply 应用于由 kubectl create --save-config 或 kubectl apply 创建的资源
CustomResourceDefinition "configurations.dapr.io" 无效:spec.preserveUnknownFields: 无效值:true:必须为 false 以便在模式中使用默认值
解决方案
运行以下命令将
CustomResourceDefinition
升级到兼容版本:kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/release-1.15/charts/dapr/crds/configuration.yaml
继续执行
dapr upgrade --runtime-version 1.15.5 -k
命令。
使用 Helm 升级
您可以使用 Helm v3 chart 来升级 Dapr。
❗重要: 最新的 Dapr Helm chart 不再支持 Helm v2。从 Helm v2 迁移到 Helm v3。
前提条件
将现有集群升级到 1.15.5
从版本 1.0.0 开始,现有的证书值将在使用 Helm 升级 Dapr 时自动重用。
注意 Helm 不会自动处理资源的升级,因此您需要手动更新这些资源。资源是向后兼容的,只需向前安装即可。
将 Dapr 升级到版本 1.15.5:
kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.15.5/charts/dapr/crds/components.yaml kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.15.5/charts/dapr/crds/configuration.yaml kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.15.5/charts/dapr/crds/subscription.yaml kubectl apply -f https://raw.githubusercontent.com/dapr/dapr/v1.15.5/charts/dapr/crds/resiliency.yaml kubectl apply -f https://raw.githubusercontent.com/dapr/dapr/v1.15.5/charts/dapr/crds/httpendpoints.yaml
helm repo update
helm upgrade dapr dapr/dapr --version 1.15.5 --namespace dapr-system --wait
如果您使用的是 values 文件,请记得在运行升级命令时添加
--values
选项。*确保所有 pod 正在运行:
kubectl get pods -n dapr-system -w NAME READY STATUS RESTARTS AGE dapr-dashboard-69f5c5c867-mqhg4 1/1 Running 0 42s dapr-operator-5cdd6b7f9c-9sl7g 1/1 Running 0 41s dapr-placement-server-0 1/1 Running 0 41s dapr-sentry-84565c747b-7bh8h 1/1 Running 0 35s dapr-sidecar-injector-68f868668f-6xnbt 1/1 Running 0 41s
重启您的应用程序部署以更新 Dapr 运行时:
kubectl rollout restart deploy/<DEPLOYMENT-NAME>
升级现有 Dapr 部署以启用高可用模式
相关链接
2.2.5 - Kubernetes 生产指南
集群和容量要求
Dapr 对 Kubernetes 的支持遵循 Kubernetes 版本偏差政策。
以下资源配置可作为起始参考。具体要求会因集群规模、pod 数量及其他因素而有所不同。请根据您的环境进行测试以确定合适的配置值。在生产环境中,建议不要为 Dapr 控制平面组件设置内存限制,以避免出现 OOMKilled
pod 状态。
部署 | CPU | 内存 |
---|---|---|
Operator | 限制: 1, 请求: 100m | 请求: 100Mi |
Sidecar Injector | 限制: 1, 请求: 100m | 请求: 30Mi |
Sentry | 限制: 1, 请求: 100m | 请求: 30Mi |
Placement | 限制: 1, 请求: 250m | 请求: 75Mi |
注意
有关更多信息,请参阅 Kubernetes 文档中的 CPU 和内存资源单位及其含义。Helm
使用 Helm 安装 Dapr 时,默认未设置限制/请求值。每个组件都有一个 resources
选项(例如,dapr_dashboard.resources
),您可以根据需要调整 Dapr 控制平面的资源配置。
Helm chart 说明 提供了详细信息和示例。
对于本地/开发安装,您可以选择不配置 resources
选项。
可选组件
以下 Dapr 控制平面部署是可选的:
- Placement: 用于 Dapr actor
- Sentry: 用于服务到服务调用的 mTLS
- Dashboard: 用于集群的操作视图
Sidecar 资源设置
使用支持的注释设置 Dapr sidecar 的资源分配。与 资源约束 相关的特定注释是:
dapr.io/sidecar-cpu-limit
dapr.io/sidecar-memory-limit
dapr.io/sidecar-cpu-request
dapr.io/sidecar-memory-request
如果未设置,Dapr sidecar 将在没有资源设置的情况下运行,这可能会导致问题。对于生产就绪的设置,强烈建议配置这些设置。
生产就绪设置中 Dapr sidecar 的示例设置:
CPU | 内存 |
---|---|
限制: 300m, 请求: 100m | 限制: 1000Mi, 请求: 250Mi |
上述 CPU 和内存限制考虑了 Dapr 支持大量 I/O 绑定操作。使用 监控工具 获取 sidecar(和应用程序)容器的基线,并根据这些基线调整这些设置。
有关在 Kubernetes 中配置资源的更多详细信息,请参阅以下 Kubernetes 指南:
注意
由于 Dapr 旨在为您的应用程序完成大量 I/O 工作,分配给 Dapr 的资源会大大减少应用程序的资源分配。在 Dapr sidecar 上设置软内存限制
当您设置了内存限制时,建议在 Dapr sidecar 上设置软内存限制。使用软内存限制时,sidecar 垃圾收集器在超过限制时释放内存,而不是等待其达到运行时堆中最后一次存在的内存量的两倍。Go 的 垃圾收集器 默认会等待,这可能导致 OOM Kill 事件。
例如,对于一个内存限制设置为 1000Mi 的应用程序,其 app-id 为 nodeapp
,您可以在 pod 注释中使用以下内容:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
# 我们的 daprd 内存设置
dapr.io/sidecar-memory-limit: "1000Mi" # 您的内存限制
dapr.io/env: "GOMEMLIMIT=900MiB" # 您内存限制的 90%。还请注意后缀 "MiB" 而不是 "Mi"
在此示例中,软限制设置为 90%,以留出 5-10% 给其他服务,如推荐。
GOMEMLIMIT
环境变量 允许某些内存大小的后缀:B
、KiB
、MiB
、GiB
和 TiB
。
高可用模式
在生产就绪配置中部署 Dapr 时,最好以控制平面的高可用 (HA) 配置进行部署。这将在 dapr-system
命名空间中为每个控制平面 pod 创建三个副本,使 Dapr 控制平面能够保留三个运行实例并在单个节点故障和其他中断中幸存。
对于新的 Dapr 部署,可以通过以下两种方式设置 HA 模式:
对于现有的 Dapr 部署,您可以通过几个额外步骤启用 HA 模式。
单个服务 HA Helm 配置
您可以通过将 global.ha.enabled
标志设置为 true
来跨所有服务配置 HA 模式。默认情况下,--set global.ha.enabled=true
完全被尊重且无法覆盖,因此不可能同时将 placement 或调度服务作为单个实例。
注意: 调度和 placement 服务的 HA 不是默认设置。
要独立于 global.ha.enabled
标志将调度和 placement 扩展到三个实例,请将 global.ha.enabled
设置为 false
,并将 dapr_scheduler.ha
和 dapr_placement.ha
设置为 true
。例如:
helm upgrade --install dapr dapr/dapr \
--version=1.15 \
--namespace dapr-system \
--create-namespace \
--set global.ha.enabled=false \
--set dapr_scheduler.ha=true \
--set dapr_placement.ha=true \
--wait
为控制平面服务设置集群关键优先级类名称
在某些情况下,节点可能会有内存和/或 CPU 压力,Dapr 控制平面 pod 可能会被选中进行驱逐。为防止这种情况,您可以为 Dapr 控制平面 pod 设置一个关键优先级类名称。这确保了 Dapr 控制平面 pod 不会被驱逐,除非所有其他优先级较低的 pod 都被驱逐。
了解更多关于 保护关键任务 Pod 的信息。
Kubernetes 中有两个内置的关键优先级类:
system-cluster-critical
system-node-critical
(最高优先级)
建议将 priorityClassName
设置为 system-cluster-critical
用于 Dapr 控制平面 pod。
对于新的 Dapr 控制平面部署,可以通过 helm 值 global.priorityClassName
设置 system-cluster-critical
优先级类模式。
此优先级类可以通过 Dapr CLI 和 Helm charts 设置,
使用 helm --set global.priorityClassName=system-cluster-critical
参数。
Dapr 版本 < 1.14
对于低于 v1.14 的 Dapr 版本,建议您向 Dapr 控制平面命名空间添加 ResourceQuota
。这可以防止与调度 pod 相关的问题 集群可能被配置 限制哪些 pod 可以被分配高优先级类。对于 v1.14 及更高版本,Helm chart 会自动添加此项。
如果您在命名空间 dapr-system
中安装了 Dapr,您可以创建一个 ResourceQuota
,内容如下:
apiVersion: v1
kind: ResourceQuota
metadata:
name: dapr-system-critical-quota
namespace: dapr-system
spec:
scopeSelector:
matchExpressions:
- operator : In
scopeName: PriorityClass
values: [system-cluster-critical]
使用 Helm 部署 Dapr
参数文件
建议创建一个 values 文件,而不是在命令中指定参数。将 values 文件检入源代码控制,以便您可以跟踪其更改。
以下命令在 dapr-system
命名空间中运行每个控制平面服务的三个副本。
# 添加/更新官方 Dapr Helm 仓库。
helm repo add dapr https://dapr.github.io/helm-charts/
# 或添加/更新私有 Dapr Helm 仓库。
helm repo add dapr http://helm.custom-domain.com/dapr/dapr/ \
--username=xxx --password=xxx
helm repo update
# 查看哪些 chart 版本可用
helm search repo dapr --devel --versions
# 创建一个 values 文件来存储变量
touch values.yml
cat << EOF >> values.yml
global:
ha:
enabled: true
EOF
# 运行安装/升级
helm install dapr dapr/dapr \
--version=<Dapr chart version> \
--namespace dapr-system \
--create-namespace \
--values values.yml \
--wait
# 验证安装
kubectl get pods --namespace dapr-system
注意
上面的示例使用helm install
和 helm upgrade
。您还可以运行 helm upgrade --install
来动态确定是安装还是升级。Dapr Helm chart 自动部署具有 kubernetes.io/os=linux
标签的节点的亲和性。您可以将 Dapr 控制平面部署到 Windows 节点。有关更多信息,请参阅 部署到混合 Linux/Windows K8s 集群。
使用 Helm 升级 Dapr
Dapr 支持以下步骤的零停机时间升级。
升级 CLI(推荐)
升级 CLI 是可选的,但推荐。
- 下载最新版本 的 CLI。
- 验证 Dapr CLI 是否在您的路径中。
升级控制平面
更新数据平面(sidecars)
更新运行 Dapr 的 pod 以获取 Dapr 运行时的新版本。
对任何具有
dapr.io/enabled
注释的部署发出滚动重启命令:kubectl rollout restart deploy/<Application deployment name>
通过以下任一方式查看所有启用 Dapr 的部署列表:
使用 Dapr CLI 运行以下命令:
dapr list -k APP ID APP PORT AGE CREATED nodeapp 3000 16h 2020-07-29 17:16.22
在现有 Dapr 部署中启用高可用性
为现有 Dapr 部署启用 HA 模式需要两个步骤:
删除现有的 placement 有状态集。
kubectl delete statefulset.apps/dapr-placement-server -n dapr-system
您删除 placement 有状态集是因为在 HA 模式下,placement 服务添加了 Raft 用于领导者选举。然而,Kubernetes 仅允许有限的字段在有状态集中进行修补,随后会导致 placement 服务的升级失败。
删除现有的 placement 有状态集是安全的。代理会重新连接并重新注册到新创建的 placement 服务,该服务在 Raft 中持久化其表。
发出升级命令。
helm upgrade dapr ./charts/dapr -n dapr-system --set global.ha.enabled=true
推荐的安全配置
正确配置时,Dapr 确保安全通信,并可以通过许多内置功能使您的应用程序更安全。
验证您的生产就绪部署包括以下设置:
相互认证 (mTLS) 已启用。Dapr 默认启用 mTLS。了解更多关于如何使用您自己的证书。
应用程序到 Dapr API 认证 已启用。这是您的应用程序与 Dapr sidecar 之间的通信。为了保护 Dapr API 免受未经授权的应用程序访问,启用 Dapr 的基于令牌的认证。
Dapr 到应用程序 API 认证 已启用。这是 Dapr 与您的应用程序之间的通信。让 Dapr 知道它正在使用令牌认证与授权应用程序通信。
组件 secret 数据配置在 secret 存储中,而不是硬编码在组件 YAML 文件中。了解如何使用 Dapr 组件的 secret。
Dapr 控制平面安装在专用命名空间中,例如
dapr-system
。Dapr 支持并启用 为某些应用程序设置组件范围。这不是必需的实践。了解更多关于组件范围。
推荐的 Placement 服务配置
Placement 服务 是 Dapr 中的一个组件,负责通过 placement 表向所有 Dapr sidecar 传播 actor 地址信息(更多信息可以在 这里 找到)。
在生产环境中运行时,建议使用以下值配置 Placement 服务:
- 高可用性。确保 Placement 服务具有高可用性(三个副本)并能在单个节点故障中幸存。Helm chart 值:
dapr_placement.ha=true
- 内存日志。使用内存 Raft 日志存储以加快写入速度。权衡是更多的 placement 表传播(因此,在最终的 Placement 服务 pod 故障中,网络流量会增加)。Helm chart 值:
dapr_placement.cluster.forceInMemoryLog=true
- 无元数据端点。禁用未认证的
/placement/state
端点,该端点暴露了 Placement 服务的 placement 表信息。Helm chart 值:dapr_placement.metadataEnabled=false
- 超时 控制 Placement 服务与 sidecar 之间网络连接的敏感性,使用以下超时值。默认值已设置,但您可以根据网络条件调整这些值。
dapr_placement.keepAliveTime
设置 Placement 服务在 gRPC 流上向 Dapr sidecar 发送 keep alive ping 的间隔,以检查连接是否仍然存活。较低的值将在 pod 丢失/重启时导致较短的 actor 重新平衡时间,但在正常操作期间会增加网络流量。接受1s
到10s
之间的值。默认值为2s
。dapr_placement.keepAliveTimeout
设置 Dapr sidecar 响应 Placement 服务的 keep alive ping 的超时时间,然后 Placement 服务关闭连接。较低的值将在 pod 丢失/重启时导致较短的 actor 重新平衡时间,但在正常操作期间会增加网络流量。接受1s
到10s
之间的值。默认值为3s
。dapr_placement.disseminateTimeout
设置在 actor 成员更改(通常与 pod 重启相关)后传播延迟的超时时间,以避免在多个 pod 重启期间过度传播。较高的值将减少传播频率,但会延迟表传播。接受1s
到3s
之间的值。默认值为2s
。
服务账户令牌
默认情况下,Kubernetes 在每个容器中挂载一个包含 服务账户令牌 的卷。应用程序可以使用此令牌,其权限因集群和命名空间的配置等因素而异,以对 Kubernetes 控制平面执行 API 调用。
在创建新 Pod(或 Deployment、StatefulSet、Job 等)时,您可以通过在 pod 的 spec 中设置 automountServiceAccountToken: false
来禁用自动挂载服务账户令牌。
建议您考虑在不依赖服务账户令牌的情况下,将应用程序部署为 automountServiceAccountToken: false
,以提高 pod 的安全性。例如,您可能需要服务账户令牌,如果:
- 您的应用程序需要与 Kubernetes API 交互。
- 您正在使用与 Kubernetes API 交互的 Dapr 组件;例如,Kubernetes secret 存储 或 Kubernetes 事件绑定。
因此,Dapr 不会自动为您设置 automountServiceAccountToken: false
。然而,在您的解决方案不需要服务账户的所有情况下,建议您在 pod 的 spec 中设置此选项。
注意
使用存储为 Kubernetes secret 的 组件 secret 初始化 Dapr 组件不需要服务账户令牌,因此在这种情况下您仍然可以设置automountServiceAccountToken: false
。只有在运行时调用 Kubernetes secret 存储,使用 Secrets 管理 构建块时,才会受到影响。跟踪和指标配置
Dapr 默认启用跟踪和指标。建议您为您的应用程序和 Dapr 控制平面在生产中设置分布式跟踪和指标。
如果您已经有自己的可观察性设置,您可以禁用 Dapr 的跟踪和指标。
跟踪
指标
对于指标,Dapr 在端口 9090 上暴露了一个 Prometheus 端点,可以被 Prometheus 抓取。
设置 Prometheus、Grafana 和其他监控工具与 Dapr。
注入器看门狗
Dapr Operator 服务包括一个 注入器看门狗,可用于检测和修复您的应用程序的 pod 可能在没有 Dapr sidecar(daprd
容器)的情况下部署的情况。例如,它可以帮助在集群完全故障后恢复应用程序。
在 Kubernetes 模式下运行 Dapr 时,注入器看门狗默认禁用。然而,您应该考虑根据您的具体情况启用它并设置适当的值。
请参阅 Dapr operator 服务文档 以获取有关注入器看门狗及其启用方法的更多详细信息。
为 sidecar 容器配置 seccompProfile
默认情况下,Dapr sidecar 注入器注入一个没有任何 seccompProfile
的 sidecar。然而,为了使 Dapr sidecar 容器在具有 受限 配置文件的命名空间中成功运行,sidecar 容器需要 securityContext.seccompProfile.Type
不为 nil
。
请参阅 参数和注释概述 以在 sidecar 容器上设置适当的 seccompProfile
。
最佳实践
观看此视频,深入了解在 Kubernetes 上运行 Dapr 的最佳实践。
2.2.6 - 使用 Dapr Shared 部署 Dapr 到每个节点或每个集群
Dapr 会自动为您的应用程序注入一个 sidecar,以启用 Dapr API,从而实现最佳的可用性和可靠性。
Dapr Shared 提供了两种替代的部署策略:通过 Kubernetes 的 DaemonSet
实现每节点部署,或通过 Deployment
实现每集群部署。
DaemonSet
: 当以 Kubernetes 的DaemonSet
资源运行 Dapr Shared 时,daprd 容器会在集群中的每个 Kubernetes 节点上运行。这可以减少应用程序与 Dapr 之间的网络延迟。Deployment
: 当以 Kubernetes 的Deployment
运行 Dapr Shared 时,Kubernetes 调度器会决定 daprd 容器实例在集群中的哪个节点上运行。
Dapr Shared 部署
对于您部署的每个 Dapr 应用程序,您需要使用不同的shared.appId
来部署 Dapr Shared Helm chart。为什么选择 Dapr Shared?
默认情况下,当 Dapr 安装到 Kubernetes 集群中时,Dapr 控制平面会将 Dapr 作为 sidecar 注入到带有 Dapr 注释(dapr.io/enabled: "true"
)的应用程序中。sidecar 提供了许多优势,包括提高弹性,因为每个应用程序都有一个实例,并且应用程序与 sidecar 之间的所有通信都无需经过网络。

虽然 sidecar 是 Dapr 的默认部署方式,但某些用例需要其他方法。假设您希望将工作负载的生命周期与 Dapr API 解耦。一个典型的例子是函数或函数即服务(FaaS)运行时,它可能会自动缩减您的空闲工作负载以释放资源。在这种情况下,可能需要将 Dapr API 和所有 Dapr 异步功能(如订阅)分开。
Dapr Shared 是为这些场景而创建的,扩展了 Dapr sidecar 模型,提供了两种新的部署方法:DaemonSet
(每节点)和 Deployment
(每集群)。
重要
无论您选择哪种部署方法,重要的是要理解在大多数用例中,每个服务(app-id)都有一个 Dapr Shared 实例(Helm 发布)。这意味着如果您的应用程序由三个微服务组成,建议每个服务都有自己的 Dapr Shared 实例。您可以通过尝试 Hello Kubernetes with Dapr Shared 教程 来看到这一点。DeamonSet
(每节点)
使用 Kubernetes DaemonSet
,您可以定义需要在集群中每个节点上部署一次的应用程序。这使得在同一节点上运行的应用程序可以与本地 Dapr API 通信,无论 Kubernetes Scheduler
将您的工作负载调度到哪里。

注意
由于DaemonSet
在每个节点上安装一个实例,与每集群部署的 Deployment
相比,它在集群中消耗更多资源,但具有提高弹性的优势。Deployment
(每集群)
Kubernetes Deployments
每个集群安装一次。根据可用资源,Kubernetes Scheduler
决定工作负载在哪个节点上调度。对于 Dapr Shared,这意味着您的工作负载和 Dapr 实例可能位于不同的节点上,这可能会引入相当大的网络延迟,但资源使用减少。

开始使用 Dapr Shared
先决条件
在安装 Dapr Shared 之前,请确保您已在集群中安装 Dapr。如果您想开始使用 Dapr Shared,可以通过安装官方 Helm Chart 创建一个新的 Dapr Shared 实例:
helm install my-shared-instance oci://registry-1.docker.io/daprio/dapr-shared-chart --set shared.appId=<DAPR_APP_ID> --set shared.remoteURL=<REMOTE_URL> --set shared.remotePort=<REMOTE_PORT> --set shared.strategy=deployment
您的 Dapr 启用应用程序现在可以通过将 Dapr SDK 指向或发送请求到 Dapr Shared 实例暴露的 my-shared-instance-dapr
Kubernetes 服务来使用 Dapr Shared 实例。
上述
my-shared-instance
是 Helm Chart 发布名称。
如果您使用 Dapr SDK,可以为您的应用程序设置以下环境变量以连接到 Dapr Shared 实例(在此情况下,运行在 default
命名空间中):
env:
- name: DAPR_HTTP_ENDPOINT
value: http://my-shared-instance-dapr.default.svc.cluster.local:3500
- name: DAPR_GRPC_ENDPOINT
value: http://my-shared-instance-dapr.default.svc.cluster.local:50001
如果您不使用 SDK,可以向这些端点发送 HTTP 或 gRPC 请求。
下一步
- 尝试 Hello Kubernetes with Dapr Shared 教程。
- 在 Dapr Shared 仓库中阅读更多内容。
2.2.7 - 操作指南:持久化调度器任务
调度器服务负责将任务写入其嵌入的Etcd数据库并调度执行。
默认情况下,调度器服务数据库会将数据写入大小为1Gb
的持久卷声明(Persistent Volume Claim),使用集群的默认存储类。
这意味着在大多数Kubernetes部署中运行调度器服务不需要额外参数,但如果没有默认的StorageClass或在生产环境中运行时,您将需要进行额外的配置。
警告
调度器的默认存储大小为1Gi
,这对于大多数生产部署来说可能不够。
请注意,当启用SchedulerReminders预览功能时,调度器会用于actor提醒、工作流以及任务API。
您可能需要考虑重新安装Dapr,并将调度器存储增加到至少16Gi
或更多。
有关更多信息,请参见下面的ETCD存储磁盘大小部分。生产环境设置
ETCD存储磁盘大小
调度器的默认存储大小为1Gb
。
这个大小对于大多数生产部署来说可能不够。
当存储大小超出时,调度器将记录类似以下的错误:
error running scheduler: etcdserver: mvcc: database space exceeded
确定存储大小的安全上限并不是一门精确的科学,主要取决于应用程序任务的数量、持久性和数据负载大小。 任务API和actor提醒(启用SchedulerReminders预览功能时)会根据应用程序的使用情况进行映射。 工作流(启用SchedulerReminders预览功能时)会创建大量的任务作为actor提醒,但这些任务是短暂的,与每个工作流执行的生命周期相匹配。 工作流创建的任务的数据负载通常为空或很小。
调度器使用Etcd作为其存储后端数据库。 根据设计,Etcd以预写日志(WAL)和快照的形式持久化历史事务和数据。 这意味着调度器的实际磁盘使用量将高于当前可观察的数据库状态,通常是多个倍数。
在安装时设置存储大小
如果您需要增加现有调度器的存储大小,请参见下面的增加现有调度器存储大小部分。
要增加新Dapr安装的存储大小(在此示例中为16Gi
),您可以使用以下命令:
dapr init -k --set dapr_scheduler.cluster.storageSize=16Gi --set dapr_scheduler.etcdSpaceQuota=16Gi
helm upgrade --install dapr dapr/dapr \
--version=1.15 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.storageSize=16Gi \
--set dapr_scheduler.etcdSpaceQuota=16Gi \
--wait
增加现有调度器存储大小
警告
并非所有存储提供商都支持动态卷扩展。 请参阅您的存储提供商文档以确定是否支持此功能,以及如果不支持该怎么办。默认情况下,每个调度器会为每个副本创建一个大小为1Gi
的持久卷和持久卷声明,使用默认的standard
存储类。
这些将类似于以下内容,在此示例中我们以HA模式运行调度器。
NAMESPACE NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS VOLUMEATTRIBUTESCLASS AGE
dapr-system dapr-scheduler-data-dir-dapr-scheduler-server-0 Bound pvc-9f699d2e-f347-43b0-aa98-57dcf38229c5 1Gi RWO standard <unset> 3m25s
dapr-system dapr-scheduler-data-dir-dapr-scheduler-server-1 Bound pvc-f4c8be7b-ffbe-407b-954e-7688f2482caa 1Gi RWO standard <unset> 3m25s
dapr-system dapr-scheduler-data-dir-dapr-scheduler-server-2 Bound pvc-eaad5fb1-98e9-42a5-bcc8-d45dba1c4b9f 1Gi RWO standard <unset> 3m25s
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS VOLUMEATTRIBUTESCLASS REASON AGE
pvc-9f699d2e-f347-43b0-aa98-57dcf38229c5 1Gi RWO Delete Bound dapr-system/dapr-scheduler-data-dir-dapr-scheduler-server-0 standard <unset> 4m24s
pvc-eaad5fb1-98e9-42a5-bcc8-d45dba1c4b9f 1Gi RWO Delete Bound dapr-system/dapr-scheduler-data-dir-dapr-scheduler-server-2 standard <unset> 4m24s
pvc-f4c8be7b-ffbe-407b-954e-7688f2482caa 1Gi RWO Delete Bound dapr-system/dapr-scheduler-data-dir-dapr-scheduler-server-1 standard <unset> 4m24s
要扩展调度器的存储大小,请按照以下步骤操作:
- 首先,确保存储类支持卷扩展,并且
allowVolumeExpansion
字段设置为true
,如果尚未设置。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: my.driver
allowVolumeExpansion: true
...
- 删除调度器StatefulSet,同时保留绑定的持久卷声明。
kubectl delete sts -n dapr-system dapr-scheduler-server --cascade=orphan
- 通过编辑
spec.resources.requests.storage
字段,将持久卷声明的大小增加到所需大小。 在这种情况下,我们假设调度器以3个副本的HA模式运行。
kubectl edit pvc -n dapr-system dapr-scheduler-data-dir-dapr-scheduler-server-0 dapr-scheduler-data-dir-dapr-scheduler-server-1 dapr-scheduler-data-dir-dapr-scheduler-server-2
- 通过安装具有所需存储大小的Dapr重新创建调度器StatefulSet。
存储类
如果您的Kubernetes部署没有默认存储类或您正在配置生产集群,则需要定义存储类。
持久卷由托管的云提供商或Kubernetes基础设施平台提供的真实磁盘支持。 磁盘大小由预计一次持久化的任务数量决定;然而,64Gb对于大多数生产场景来说应该绰绰有余。 一些Kubernetes提供商建议使用CSI驱动来配置底层磁盘。 以下是为主要云提供商创建持久磁盘的相关文档的有用链接列表:
- Google Cloud Persistent Disk
- Amazon EBS Volumes
- Azure AKS Storage Options
- Digital Ocean Block Storage
- VMWare vSphere Storage
- OpenShift Persistent Storage
- Alibaba Cloud Disk Storage
一旦存储类可用,您可以使用以下命令安装Dapr,并将调度器配置为使用存储类(将my-storage-class
替换为存储类的名称):
dapr init -k --set dapr_scheduler.cluster.storageClassName=my-storage-class
helm upgrade --install dapr dapr/dapr \
--version=1.15 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.storageClassName=my-storage-class \
--wait
临时存储
在非HA模式下运行时,调度器可以选择使用临时存储,即内存存储,这种存储在重启时不具有弹性。例如,调度器重启后,所有任务数据都会丢失。 这在非生产部署或测试中很有用,在这些情况下存储不可用或不需要。
dapr init -k --set dapr_scheduler.cluster.inMemoryStorage=true
helm upgrade --install dapr dapr/dapr \
--version=1.15 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.inMemoryStorage=true \
--wait
2.2.8 - 部署到混合 Linux/Windows Kubernetes 集群
Dapr 支持在以下类型的 Kubernetes 集群上运行您的微服务:
- Windows
- Linux
- 两者的组合
这在分阶段将遗留应用程序迁移到 Dapr Kubernetes 集群时特别有用。
Kubernetes 使用 节点亲和性 的概念来指定您的应用程序应在 Linux 节点还是 Windows 节点上启动。当部署到同时具有 Windows 和 Linux 节点的集群时,您必须为应用程序设置亲和性规则,否则 Kubernetes 调度器可能会将您的应用程序启动在错误类型的节点上。
先决条件
在开始之前,设置一个具有 Windows 节点的 Kubernetes 集群。许多 Kubernetes 提供商支持自动配置启用 Windows 的 Kubernetes 集群。
按照您首选提供商的说明设置启用 Windows 的集群。
设置集群后,验证 Windows 和 Linux 节点是否可用。
kubectl get nodes -o wide NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME aks-nodepool1-11819434-vmss000000 Ready agent 6d v1.17.9 10.240.0.4 <none> Ubuntu 16.04.6 LTS 4.15.0-1092-azure docker://3.0.10+azure aks-nodepool1-11819434-vmss000001 Ready agent 6d v1.17.9 10.240.0.35 <none> Ubuntu 16.04.6 LTS 4.15.0-1092-azure docker://3.0.10+azure aks-nodepool1-11819434-vmss000002 Ready agent 5d10h v1.17.9 10.240.0.129 <none> Ubuntu 16.04.6 LTS 4.15.0-1092-azure docker://3.0.10+azure akswin000000 Ready agent 6d v1.17.9 10.240.0.66 <none> Windows Server 2019 Datacenter 10.0.17763.1339 docker://19.3.5 akswin000001 Ready agent 6d v1.17.9 10.240.0.97 <none> Windows Server 2019 Datacenter 10.0.17763.1339 docker://19.3.5
安装 Dapr 控制平面
如果您使用 Dapr CLI 或通过 Helm chart 安装,只需按照正常的部署程序进行:在 Kubernetes 集群上安装 Dapr
亲和性将自动设置为 kubernetes.io/os=linux
。这对于大多数用户来说是足够的,因为 Kubernetes 至少需要一个 Linux 节点池。
注意
Dapr 控制平面容器已为 Windows 和 Linux 构建和测试。然而,建议使用 Linux 控制平面容器,因为它们通常更小且拥有更大的用户基础。
如果您理解上述内容,但仍希望将 Dapr 控制平面部署到 Windows,可以通过设置以下命令实现:
helm install dapr dapr/dapr --set global.daprControlPlaneOs=windows
安装 Dapr 应用
Windows 应用
创建一个带有节点亲和性设置为
kubernetes.io/os: windows
的部署 YAML 文件。在下面的deploy_windows.yaml
部署文件示例中:apiVersion: apps/v1 kind: Deployment metadata: name: yourwinapp labels: app: applabel spec: replicas: 1 selector: matchLabels: app: applablel template: metadata: labels: app: applabel annotations: dapr.io/enabled: "true" dapr.io/id: "addapp" dapr.io/port: "6000" dapr.io/config: "appconfig" spec: containers: - name: add image: yourreponsitory/your-windows-dapr-container:your-tag ports: - containerPort: 6000 imagePullPolicy: Always affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - windows
将 YAML 文件部署到您的 Kubernetes 集群。
kubectl apply -f deploy_windows.yaml
Linux 应用
如果您已经有一个在 Linux 上运行的 Dapr 应用,您仍然需要添加亲和性规则。
创建一个带有节点亲和性设置为
kubernetes.io/os: linux
的部署 YAML 文件。在下面的deploy_linux.yaml
部署文件示例中:apiVersion: apps/v1 kind: Deployment metadata: name: yourlinuxapp labels: app: yourlabel spec: replicas: 1 selector: matchLabels: app: yourlabel template: metadata: labels: app: yourlabel annotations: dapr.io/enabled: "true" dapr.io/id: "addapp" dapr.io/port: "6000" dapr.io/config: "appconfig" spec: containers: - name: add image: yourreponsitory/your-application:your-tag ports: - containerPort: 6000 imagePullPolicy: Always affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/os operator: In values: - linux
将 YAML 部署到您的 Kubernetes 集群。
kubectl apply -f deploy_linux.yaml
就是这样!
清理
要从本指南中删除部署,请运行以下命令:
kubectl delete -f deploy_linux.yaml
kubectl delete -f deploy_windows.yaml
helm uninstall dapr
相关链接
2.2.9 - 在 Kubernetes Job 中运行 Dapr
Dapr sidecar 被设计为一个长期运行的进程。在 Kubernetes Job 的环境中,这种行为可能会阻碍作业的完成。
为了解决这个问题,Dapr sidecar 提供了一个 Shutdown
端点,用于关闭 sidecar。
在运行一个基本的 Kubernetes Job 时,你需要调用 sidecar 的 /shutdown
端点,以便优雅地停止 sidecar,并使作业被视为 Completed
。
如果作业在没有调用 Shutdown
的情况下完成,作业会处于 NotReady
状态,而 daprd
容器会一直运行下去。
停止 Dapr sidecar 会导致容器中的就绪性和存活性探测失败。
为了防止 Kubernetes 尝试重启你的作业,请将作业的 restartPolicy
设置为 Never
。
在调用 shutdown HTTP API 时,请确保使用 POST HTTP 动词。例如:
apiVersion: batch/v1
kind: Job
metadata:
name: job-with-shutdown
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "with-shutdown"
spec:
containers:
- name: job
image: alpine
command: ["/bin/sh", "-c", "apk --no-cache add curl && sleep 20 && curl -X POST localhost:3500/v1.0/shutdown"]
restartPolicy: Never
你也可以从任何 Dapr SDK 调用 Shutdown
。例如,对于 Go SDK:
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()
// Job
}
相关链接
2.2.10 - 操作指南:将 Pod 卷挂载到 Dapr sidecar
Dapr sidecar 可以配置为挂载应用程序 Pod 上的任何 Kubernetes 卷。这些卷可以通过 daprd
(sidecar) 容器以只读或读写模式访问。如果配置了一个卷进行挂载但在 Pod 中不存在,Dapr 会记录一个警告并忽略该卷。
有关不同类型卷的更多信息,请查看 Kubernetes 文档。
配置
您可以在部署的 YAML 文件中设置以下注解:
注解 | 描述 |
---|---|
dapr.io/volume-mounts | 用于只读卷挂载 |
dapr.io/volume-mounts-rw | 用于读写卷挂载 |
这些注解是以逗号分隔的 volume-name:path/in/container
对。请确保相应的卷在 Pod 规范中已定义。
在官方容器镜像中,Dapr 以用户 ID (UID) 65532
运行。请确保挂载卷内的文件夹和文件对用户 65532
可读写。
虽然您可以在 Dapr sidecar 容器内的任何文件夹中挂载卷,但为了避免冲突并确保未来的兼容性,建议将所有挂载点放置在以下位置之一或其子文件夹中:
位置 | 描述 |
---|---|
/mnt | 推荐用于存储 Dapr sidecar 进程可读写的持久数据的卷。 |
/tmp | 推荐用于存储临时数据的卷,例如临时磁盘。 |
示例
基本部署资源示例
在下面的 Deployment 资源示例中:
my-volume1
在 sidecar 容器内以只读模式挂载到/mnt/sample1
my-volume2
在 sidecar 容器内以只读模式挂载到/mnt/sample2
my-volume3
在 sidecar 容器内以读写模式挂载到/tmp/sample3
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/volume-mounts: "my-volume1:/mnt/sample1,my-volume2:/mnt/sample2"
dapr.io/volume-mounts-rw: "my-volume3:/tmp/sample3"
spec:
volumes:
- name: my-volume1
hostPath:
path: /sample
- name: my-volume2
persistentVolumeClaim:
claimName: pv-sample
- name: my-volume3
emptyDir: {}
...
使用本地文件 secret 存储自定义 secret 存储
由于任何类型的 Kubernetes 卷都可以附加到 sidecar,您可以使用本地文件 secret 存储从各种地方读取 secret。例如,如果您有一个运行在 10.201.202.203
的网络文件共享 (NFS) 服务器,secret 存储在 /secrets/stage/secrets.json
,您可以将其用作 secret 存储。
配置应用程序 pod 以挂载 NFS 并将其附加到 Dapr sidecar。
apiVersion: apps/v1 kind: Deployment metadata: name: myapp ... spec: ... template: ... annotations: dapr.io/enabled: "true" dapr.io/app-id: "myapp" dapr.io/app-port: "8000" dapr.io/volume-mounts: "nfs-secrets-vol:/mnt/secrets" spec: volumes: - name: nfs-secrets-vol nfs: server: 10.201.202.203 path: /secrets/stage ...
将本地文件 secret 存储组件指向附加的文件。
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: local-secret-store spec: type: secretstores.local.file version: v1 metadata: - name: secretsFile value: /mnt/secrets/secrets.json
使用 secret。
GET http://localhost:<daprPort>/v1.0/secrets/local-secret-store/my-secret
相关链接
2.3 - 在无服务器服务中运行 Dapr
如果您希望在无需管理底层基础设施(如虚拟机或 Kubernetes)的情况下运行 Dapr 应用程序,可以选择无服务器云服务。这些平台与 Dapr 集成,简化了应用程序的部署和管理。
服务提供
2.3.1 - Azure 容器应用
Azure 容器应用 是一种无服务器应用托管服务,用户无需管理底层的虚拟机、编排器或其他云基础设施。Azure 容器应用允许您运行打包在多个容器中的应用程序代码,并且对所使用的运行时或编程模型没有特定要求。
Dapr 已集成到容器应用中,您可以直接使用 Dapr API 的功能模块,而无需手动部署 Dapr 运行时。您只需将服务与其 Dapr 组件一起部署即可。
了解更多教程
访问 Azure 文档 以尝试微服务教程,您将在其中将两个启用 Dapr 的应用程序部署到 Azure 容器应用。

3 - Dapr 配置管理指南
3.1 - Dapr 配置
Dapr 配置通过一系列设置和策略,允许您调整单个 Dapr 应用程序的行为,或控制平面系统服务的整体行为。
应用程序配置
设置应用程序配置
您可以在自托管模式或 Kubernetes 模式下设置应用程序配置。
在自托管模式下,Dapr 配置是一个配置文件,例如 config.yaml
。默认情况下,Dapr sidecar 会在默认的 Dapr 文件夹中查找运行时配置:
- Linux/MacOs:
$HOME/.dapr/config.yaml
- Windows:
%USERPROFILE%\.dapr\config.yaml
您还可以在 dapr run
CLI 命令中使用 --config
标志指定文件路径来应用配置。
在 Kubernetes 模式下,Dapr 配置是一个应用于集群的配置资源。例如:
kubectl apply -f myappconfig.yaml
您可以使用 Dapr CLI 列出应用程序的配置资源。
dapr configurations -k
Dapr sidecar 可以通过 dapr.io/config
注解来应用特定配置。例如:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "myappconfig"
注意: 查看所有 Kubernetes 注解,以便在 sidecar 注入器系统服务激活时配置 Dapr sidecar。
应用程序配置选项
以下是您可以在 sidecar 上设置的所有配置选项。
跟踪
跟踪配置用于启用应用程序的跟踪功能。
Configuration
规范下的 tracing
部分包含以下属性:
tracing:
samplingRate: "1"
otel:
endpointAddress: "otelcollector.observability.svc.cluster.local:4317"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
下表列出了跟踪的属性:
属性 | 类型 | 描述 |
---|---|---|
samplingRate | string | 设置跟踪的采样率以启用或禁用。 |
stdout | bool | 为跟踪写入更详细的信息 |
otel.endpointAddress | string | 设置 Open Telemetry (OTEL) 服务器地址以发送跟踪。这可能需要或不需要 https:// 或 http://,具体取决于您的 OTEL 提供商。 |
otel.isSecure | bool | 连接到端点地址是否加密 |
otel.protocol | string | 设置为 http 或 grpc 协议 |
zipkin.endpointAddress | string | 设置 Zipkin 服务器地址以发送跟踪。这应该在端点上包含协议 (http:// 或 https://)。 |
samplingRate
samplingRate
用于启用或禁用跟踪。samplingRate
的有效范围是 0
到 1
(含)。采样率决定了是否根据值对跟踪跨度进行采样。
samplingRate : "1"
采样所有跟踪。默认情况下,采样率为 (0.0001),即 1 万分之一。
要禁用采样率,请在配置中设置 samplingRate : "0"
。
otel
OpenTelemetry (otel
) 端点也可以通过环境变量进行配置。OTEL_EXPORTER_OTLP_ENDPOINT
环境变量的存在会为 sidecar 启用跟踪。
环境变量 | 描述 |
---|---|
OTEL_EXPORTER_OTLP_ENDPOINT | 设置 Open Telemetry (OTEL) 服务器地址,启用跟踪 |
OTEL_EXPORTER_OTLP_INSECURE | 将连接到端点设置为未加密(true/false) |
OTEL_EXPORTER_OTLP_PROTOCOL | 传输协议 (grpc , http/protobuf , http/json ) |
有关更多信息,请参阅 可观察性分布式跟踪。
指标
Configuration
规范下的 metrics
部分可用于启用或禁用应用程序的指标。
metrics
部分包含以下属性:
metrics:
enabled: true
rules: []
latencyDistributionBuckets: []
http:
increasedCardinality: true
pathMatching:
- /items
- /orders/{orderID}
- /orders/{orderID}/items/{itemID}
- /payments/{paymentID}
- /payments/{paymentID}/status
- /payments/{paymentID}/refund
- /payments/{paymentID}/details
excludeVerbs: false
recordErrorCodes: true
在上面的示例中,路径过滤器 /orders/{orderID}/items/{itemID}
将返回 单个指标计数,匹配所有 orderID
和所有 itemID
,而不是为每个 itemID
返回多个指标。有关更多信息,请参阅 HTTP 指标路径匹配。
上面的示例还启用了 记录错误代码指标,默认情况下是禁用的。
下表列出了指标的属性:
属性 | 类型 | 描述 |
---|---|---|
enabled | boolean | 当设置为 true 时,默认情况下,启用指标收集和指标端点。 |
rules | array | 命名规则以过滤指标。每个规则包含一组 labels 以进行过滤和一个 regex 表达式以应用于指标路径。 |
latencyDistributionBuckets | array | 延迟指标直方图的延迟分布桶的毫秒数组。 |
http.increasedCardinality | boolean | 当设置为 true (默认)时,在 Dapr HTTP 服务器中,每个请求路径都会导致创建一个新的“桶”指标。这可能会导致问题,包括在请求的端点很多时(例如与 RESTful API 交互时)出现过多的内存消耗。为了缓解与 HTTP 服务器相关的高基数指标的高内存使用和出口成本,您应该将 metrics.http.increasedCardinality 属性设置为 false 。 |
http.pathMatching | array | 路径匹配的路径数组,允许用户定义匹配路径以管理基数。 |
http.excludeVerbs | boolean | 当设置为 true 时(默认值为 false),Dapr HTTP 服务器在构建方法指标标签时忽略每个请求的 HTTP 动词。 |
为了进一步帮助管理基数,路径匹配允许您根据定义的模式匹配指定的路径,减少唯一指标路径的数量,从而控制指标基数。此功能对于具有动态 URL 的应用程序特别有用,确保指标保持有意义且可管理,而不会消耗过多的内存。
使用规则,您可以为 Dapr sidecar 暴露的每个指标设置正则表达式。例如:
metrics:
enabled: true
rules:
- name: dapr_runtime_service_invocation_req_sent_total
labels:
- name: method
regex:
"orders/": "orders/.+"
有关更多信息,请参阅 指标文档。
日志
Configuration
规范下的 logging
部分用于配置 Dapr 运行时中的日志记录方式。
logging
部分包含以下属性:
logging:
apiLogging:
enabled: false
obfuscateURLs: false
omitHealthChecks: false
下表列出了日志记录的属性:
属性 | 类型 | 描述 |
---|---|---|
apiLogging.enabled | boolean | daprd 的 --enable-api-logging 标志的默认值(以及相应的 dapr.io/enable-api-logging 注解):除非为每个 Dapr 运行时传递 true 或 false 值,否则使用配置规范中设置的值作为默认值。默认值:false 。 |
apiLogging.obfuscateURLs | boolean | 启用时,会在 HTTP API 日志(如果启用)中模糊化 URL 的值,记录抽象路由名称而不是被调用的完整路径,该路径可能包含个人可识别信息(PII)。默认值:false 。 |
apiLogging.omitHealthChecks | boolean | 如果为 true ,则在启用 API 日志记录时,不会记录对健康检查端点(例如 /v1.0/healthz )的调用。这在这些调用在日志中添加了大量噪音时很有用。默认值:false |
有关更多信息,请参阅 日志记录文档。
中间件
中间件配置设置命名的 HTTP 管道中间件处理程序。Configuration
规范下的 httpPipeline
和 appHttpPipeline
部分包含以下属性:
httpPipeline: # 用于传入的 http 调用
handlers:
- name: oauth2
type: middleware.http.oauth2
- name: uppercase
type: middleware.http.uppercase
appHttpPipeline: # 用于传出的 http 调用
handlers:
- name: oauth2
type: middleware.http.oauth2
- name: uppercase
type: middleware.http.uppercase
下表列出了 HTTP 处理程序的属性:
属性 | 类型 | 描述 |
---|---|---|
name | string | 中间件组件的名称 |
type | string | 中间件组件的类型 |
有关更多信息,请参阅 中间件管道。
名称解析组件
您可以在配置文件中设置要使用的名称解析组件。例如,要将 spec.nameResolution.component
属性设置为 "sqlite"
,请在 spec.nameResolution.configuration
字典中传递配置选项,如下所示。
这是一个配置资源的基本示例:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
nameResolution:
component: "sqlite"
version: "v1"
configuration:
connectionString: "/home/user/.dapr/nr.db"
有关更多信息,请参阅:
限制 secret 存储访问
有关如何将 secret 范围限定到应用程序的信息和示例,请参阅 范围 secret 指南。
构建块 API 的访问控制白名单
有关如何在构建块 API 列表上设置访问控制白名单(ACL)的信息和示例,请参阅 在 Dapr sidecar 上选择性启用 Dapr API 指南。
服务调用 API 的访问控制白名单
有关如何使用 ACL 设置白名单的服务调用 API 的信息和示例,请参阅 服务调用的白名单 指南。
禁止使用某些组件类型
使用 Configuration
规范中的 components.deny
属性,您可以指定不能初始化的组件类型的拒绝列表。
例如,下面的配置禁止初始化类型为 bindings.smtp
和 secretstores.local.file
的组件:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
spec:
components:
deny:
- bindings.smtp
- secretstores.local.file
可选地,您可以通过在组件名称末尾添加版本来指定要禁止的版本。例如,state.in-memory/v1
禁止初始化类型为 state.in-memory
且版本为 v1
的组件,但不禁止组件的(假设的)v2
版本。
注意
当您将组件类型 secretstores.kubernetes
添加到拒绝列表时,Dapr 禁止创建 额外的 类型为 secretstores.kubernetes
的组件。
但是,它不会禁用内置的 Kubernetes secret 存储,该存储是:
- 由 Dapr 自动创建
- 用于存储组件规范中指定的 secret
如果您想禁用内置的 Kubernetes secret 存储,您需要使用 dapr.io/disable-builtin-k8s-secret-store
注解。
启用预览功能
有关如何选择加入发布版的预览功能的信息和示例,请参阅 预览功能 指南。
启用预览功能可以解锁新的功能,以便进行开发/测试,因为它们仍然需要更多时间才能在运行时中普遍可用(GA)。
示例 sidecar 配置
以下 YAML 显示了一个可以应用于应用程序的 Dapr sidecar 的示例配置文件。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
tracing:
samplingRate: "1"
stdout: true
otel:
endpointAddress: "localhost:4317"
isSecure: false
protocol: "grpc"
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
secrets:
scopes:
- storeName: localstore
defaultAccess: allow
deniedSecrets: ["redis-password"]
components:
deny:
- bindings.smtp
- secretstores.local.file
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['POST', 'GET']
action: deny
- name: /op2/*
httpVerb: ["*"]
action: allow
控制平面配置
一个名为 daprsystem
的单一配置文件与 Dapr 控制平面系统服务一起安装,应用全局设置。
仅在 Dapr 部署到 Kubernetes 时设置。
控制平面配置设置
Dapr 控制平面配置包含以下部分:
mtls
用于 mTLS(相互 TLS)
mTLS(相互 TLS)
mtls
部分包含 mTLS 的属性。
属性 | 类型 | 描述 |
---|---|---|
enabled | bool | 如果为 true,则启用集群中服务和应用程序之间通信的 mTLS。 |
allowedClockSkew | string | 检查 TLS 证书到期时允许的容差,以允许时钟偏差。遵循 Go 的 time.ParseDuration 使用的格式。默认值为 15m (15 分钟)。 |
workloadCertTTL | string | Dapr 签发的证书 TLS 的有效期。遵循 Go 的 time.ParseDuration 使用的格式。默认值为 24h (24 小时)。 |
sentryAddress | string | 连接到 Sentry 服务器的主机名端口地址。 |
controlPlaneTrustDomain | string | 控制平面的信任域。用于验证与控制平面服务的连接。 |
tokenValidators | array | 用于验证证书请求的其他 Sentry 令牌验证器。 |
示例控制平面配置
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
allowedClockSkew: 15m
workloadCertTTL: 24h
下一步
了解并发和速率限制3.2 - 操作指南:控制并发和限制应用程序的速率
在分布式计算中,通常您可能只希望允许一定数量的请求同时执行。通过使用 Dapr 的 app-max-concurrency
,您可以控制同时调用您应用程序的请求和事件数量。
默认情况下,app-max-concurrency
设置为 -1
,表示不限制并发数量。
不同的方法
本指南主要介绍 app-max-concurrency
,但您也可以使用 middleware.http.ratelimit
中间件来限制每秒的请求速率。理解这两种方法的区别非常重要:
middleware.http.ratelimit
:限制每秒的请求数量app-max-concurrency
:限制在任意时间点的最大并发请求(和事件)数量。
有关该方法的更多信息,请参见速率限制中间件。
演示
观看此视频以了解如何控制并发和速率限制。
配置 app-max-concurrency
如果不使用 Dapr,您需要在应用程序中创建某种信号量并负责获取和释放它。
使用 Dapr,您无需对应用程序进行任何代码更改。
选择您希望配置 app-max-concurrency
的方式。
要在本地开发环境中使用 Dapr CLI 设置并发限制,请添加 app-max-concurrency
标志:
dapr run --app-max-concurrency 1 --app-port 5000 python ./app.py
上述示例将您的应用程序变成一个顺序处理服务。
要在 Kubernetes 中配置并发限制,请将以下注释添加到您的 pod:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodesubscriber
namespace: default
labels:
app: nodesubscriber
spec:
replicas: 1
selector:
matchLabels:
app: nodesubscriber
template:
metadata:
labels:
app: nodesubscriber
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodesubscriber"
dapr.io/app-port: "3000"
dapr.io/app-max-concurrency: "1"
#...
限制
控制外部请求的并发
速率限制适用于来自 Dapr 的每个事件,包括 pub/sub 事件、来自其他服务的直接调用、bindings 事件等。然而,Dapr 无法对外部传入您应用程序的请求强制执行并发策略。
相关链接
下一步
限制 secret 存储访问3.3 - 操作指南:限制从 secret 存储中读取的 secret
除了定义哪些应用程序可以访问特定组件之外,您还可以将命名的 secret 存储组件限制为应用程序的一个或多个 secret。通过定义 allowedSecrets
和/或 deniedSecrets
列表,可以限制应用程序仅访问特定的 secret。
有关配置资源的更多信息:
配置 secret 访问
Configuration
规范下的 secrets
部分包含以下属性:
secrets:
scopes:
- storeName: kubernetes
defaultAccess: allow
allowedSecrets: ["redis-password"]
- storeName: localstore
defaultAccess: allow
deniedSecrets: ["redis-password"]
下表列出了 secret 范围的属性:
属性 | 类型 | 描述 |
---|---|---|
storeName | string | secret 存储组件的名称。storeName 在列表中必须是唯一的 |
defaultAccess | string | 访问修饰符。接受的值为 “allow”(默认)或 “deny” |
allowedSecrets | list | 可以访问的 secret 键列表 |
deniedSecrets | list | 不能访问的 secret 键列表 |
当 allowedSecrets
列表中存在至少一个元素时,应用程序只能访问列表中定义的那些 secret。
权限优先级
allowedSecrets
和 deniedSecrets
列表的优先级高于 defaultAccess
。请参阅以下示例场景了解其工作原理:
场景 | defaultAccess | allowedSecrets | deniedSecrets | permission | |
---|---|---|---|---|---|
1 | 仅默认访问 | deny /allow | 空 | 空 | deny /allow |
2 | 默认拒绝并允许列表 | deny | ["s1" ] | 空 | 仅 "s1" 可以访问 |
3 | 默认允许并拒绝列表 | allow | 空 | ["s1" ] | 仅 "s1" 不能访问 |
4 | 默认允许并允许列表 | allow | ["s1" ] | 空 | 仅 "s1" 可以访问 |
5 | 默认拒绝并拒绝列表 | deny | 空 | ["s1" ] | deny |
6 | 默认拒绝/允许并同时有列表 | deny /allow | ["s1" ] | ["s2" ] | 仅 "s1" 可以访问 |
示例
场景 1:拒绝对 secret 存储中所有 secret 的访问
在 Kubernetes 集群中,原生的 Kubernetes secret 存储默认会添加到您的 Dapr 应用程序中。在某些场景中,可能需要拒绝某个应用程序对 Dapr secret 的访问。要添加此配置:
定义以下
appconfig.yaml
。apiVersion: dapr.io/v1alpha1 kind: Configuration metadata: name: appconfig spec: secrets: scopes: - storeName: kubernetes defaultAccess: deny
使用以下命令将其应用到 Kubernetes 集群:
kubectl apply -f appconfig.yaml
对于需要拒绝访问 Kubernetes secret 存储的应用程序,请按照Kubernetes 指南,在应用程序 pod 中添加以下注释。
dapr.io/config: appconfig
定义此项后,应用程序将不再能访问 Kubernetes secret 存储。
场景 2:仅允许访问 secret 存储中的某些 secret
要允许 Dapr 应用程序仅访问某些 secret,请定义以下 config.yaml
:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
secrets:
scopes:
- storeName: vault
defaultAccess: deny
allowedSecrets: ["secret1", "secret2"]
此示例为名为 vault
的 secret 存储定义了配置。对 secret 存储的默认访问为 deny
。同时,应用程序可以根据 allowedSecrets
列表访问某些 secret。请按照sidecar 配置指南将配置应用到 sidecar。
场景 3:拒绝访问 secret 存储中的某些敏感 secret
定义以下 config.yaml
:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
secrets:
scopes:
- storeName: vault
defaultAccess: allow # 这是默认值,可以省略此行
deniedSecrets: ["secret1", "secret2"]
此配置明确拒绝访问名为 vault
的 secret 存储中的 secret1
和 secret2
,同时允许访问所有其他 secret。请按照sidecar 配置指南将配置应用到 sidecar。
下一步
服务调用访问控制3.4 - 操作指南:为服务调用配置应用访问控制列表
通过访问控制,您可以配置策略,限制调用应用程序在被调用应用程序上通过服务调用可以执行的操作。您可以在配置模式中定义访问控制策略规范,以限制访问:
- 从特定操作到被调用应用程序,以及
- 从调用应用程序到HTTP动词。
访问控制策略在配置中指定,并应用于被调用应用程序的Dapr sidecar。对被调用应用程序的访问基于匹配的策略操作。
您可以为所有调用应用程序提供一个默认的全局操作。如果未指定访问控制策略,默认行为是允许所有调用应用程序访问被调用应用程序。
术语
trustDomain
“信任域”是用于管理信任关系的逻辑分组。每个应用程序都被分配一个信任域,可以在访问控制列表策略规范中指定。如果未定义策略规范或指定了空的信任域,则使用默认值“public”。信任域用于在TLS证书中生成应用程序的身份。
应用程序身份
Dapr请求sentry服务为所有应用程序生成一个SPIFFE ID。此ID附加在TLS证书中。
SPIFFE ID的格式为:**spiffe://\<trustdomain>/ns/\<namespace\>/\<appid\>**
。
对于匹配策略,从调用应用程序的TLS证书中提取调用应用程序的信任域、命名空间和应用程序ID值。这些值与策略规范中指定的信任域、命名空间和应用程序ID值进行匹配。如果这三者都匹配,则进一步匹配更具体的策略。
配置属性
下表列出了访问控制、策略和操作的不同属性:
访问控制
属性 | 类型 | 描述 |
---|---|---|
defaultAction | string | 当没有其他策略匹配时的全局默认操作 |
trustDomain | string | 分配给应用程序的信任域。默认值为“public”。 |
policies | string | 确定调用应用程序可以在被调用应用程序上执行哪些操作的策略 |
策略
属性 | 类型 | 描述 |
---|---|---|
app | string | 允许/拒绝服务调用的调用应用程序的AppId |
namespace | string | 需要与调用应用程序的命名空间匹配的命名空间值 |
trustDomain | string | 需要与调用应用程序的信任域匹配的信任域。默认值为“public” |
defaultAction | string | 如果找到应用程序但没有匹配的特定操作,则应用程序级别的默认操作 |
operations | string | 允许从调用应用程序进行的操作 |
操作
属性 | 类型 | 描述 |
---|---|---|
name | string | 允许在被调用应用程序上进行的操作的路径名称。通配符“*”可以用于路径中进行匹配。通配符“**”可以用于匹配多个路径下的内容。 |
httpVerb | list | 调用应用程序可以使用的特定HTTP动词列表。通配符“*”可以用于匹配任何HTTP动词。未用于grpc调用。 |
action | string | 访问修饰符。接受的值为“allow”(默认)或“deny” |
策略规则
- 如果未指定访问策略,默认行为是允许所有应用程序访问被调用应用程序上的所有方法。
- 如果未指定全局默认操作且未定义特定应用程序策略,则空访问策略被视为未指定访问策略。默认行为是允许所有应用程序访问被调用应用程序上的所有方法。
- 如果未指定全局默认操作但已定义了一些特定应用程序策略,则我们采用更安全的选项,假设全局默认操作为拒绝访问被调用应用程序上的所有方法。
- 如果定义了访问策略且无法验证传入应用程序凭据,则全局默认操作生效。
- 如果传入应用程序的信任域或命名空间与应用程序策略中指定的值不匹配,则忽略应用程序策略,全局默认操作生效。
策略优先级
最具体的匹配策略对应的操作生效,按以下顺序排列:
- 在HTTP的情况下为特定HTTP动词,或在GRPC的情况下为操作级别操作。
- 应用程序级别的默认操作
- 全局级别的默认操作
示例场景
以下是使用访问控制列表进行服务调用的一些示例场景。请参阅配置指南以了解应用程序sidecar的可用配置设置。
场景1:
拒绝所有应用程序的访问,除非trustDomain
= public
,namespace
= default
,appId
= app1
通过此配置,所有调用方法的appId
= app1
被允许。来自其他应用程序的所有其他调用请求被拒绝。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
场景2:
拒绝所有应用程序的访问,除非trustDomain
= public
,namespace
= default
,appId
= app1
,operation
= op1
通过此配置,只有来自appId
= app1
的方法op1
被允许。来自所有其他应用程序的所有其他方法请求,包括app1
上的其他方法,均被拒绝。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['*']
action: allow
场景3:
拒绝所有应用程序的访问,除非匹配特定的HTTP动词和GRPC操作
通过此配置,只有以下场景被允许访问。来自所有其他应用程序的所有其他方法请求,包括app1
或app2
上的其他方法,均被拒绝。
trustDomain
=public
,namespace
=default
,appID
=app1
,operation
=op1
,httpVerb
=POST
/PUT
trustDomain
="myDomain"
,namespace
="ns1"
,appID
=app2
,operation
=op2
且应用程序协议为GRPC
只有来自appId
= app1
的方法op1
上的httpVerb
POST
/PUT
被允许。来自所有其他应用程序的所有其他方法请求,包括app1
上的其他方法,均被拒绝。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: deny
trustDomain: "public"
policies:
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1
httpVerb: ['POST', 'PUT']
action: allow
- appId: app2
defaultAction: deny
trustDomain: 'myDomain'
namespace: "ns1"
operations:
- name: /op2
action: allow
场景4:
允许访问所有方法,除非trustDomain
= public
,namespace
= default
,appId
= app1
,operation
= /op1/*
,所有httpVerb
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1/*
httpVerb: ['*']
action: deny
场景5:
允许访问所有方法,trustDomain
= public
,namespace
= ns1
,appId
= app1
,并拒绝访问所有方法,trustDomain
= public
,namespace
= ns2
,appId
= app1
此场景展示了如何指定具有相同应用程序ID但属于不同命名空间的应用程序。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "ns1"
- appId: app1
defaultAction: deny
trustDomain: 'public'
namespace: "ns2"
场景6:
允许访问所有方法,除非trustDomain
= public
,namespace
= default
,appId
= app1
,operation
= /op1/**/a
,所有httpVerb
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: appconfig
spec:
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: app1
defaultAction: allow
trustDomain: 'public'
namespace: "default"
operations:
- name: /op1/**/a
httpVerb: ['*']
action: deny
“hello world” 示例
在这些示例中,您将学习如何将访问控制应用于hello world教程。
访问控制列表依赖于Dapr Sentry服务生成带有SPIFFE ID的TLS证书进行身份验证。这意味着Sentry服务要么在本地运行,要么部署到您的托管环境中,例如Kubernetes集群。
下面的nodeappconfig
示例展示了如何拒绝来自pythonapp
的neworder
方法的访问,其中Python应用程序位于myDomain
信任域和default
命名空间中。Node.js应用程序位于public
信任域中。
nodeappconfig.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: nodeappconfig
spec:
tracing:
samplingRate: "1"
accessControl:
defaultAction: allow
trustDomain: "public"
policies:
- appId: pythonapp
defaultAction: allow
trustDomain: 'myDomain'
namespace: "default"
operations:
- name: /neworder
httpVerb: ['POST']
action: deny
pythonappconfig.yaml
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pythonappconfig
spec:
tracing:
samplingRate: "1"
accessControl:
defaultAction: allow
trustDomain: "myDomain"
自托管模式
在本教程中,您将:
- 在本地运行启用mTLS的Sentry服务
- 设置访问证书所需的环境变量
- 启动Node应用程序和Python应用程序,每个应用程序都引用Sentry服务以应用ACL
先决条件
- 熟悉在自托管模式下运行启用mTLS的Sentry服务
- 克隆hello world教程
运行Node.js应用程序
在命令提示符中,设置这些环境变量:
```bash export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt` export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt` export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key` export NAMESPACE=default ```
```powershell $env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt) $env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt) $env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key) $env:NAMESPACE="default" ```
运行daprd以启动Node.js应用程序的Dapr sidecar,启用mTLS,引用本地Sentry服务:
daprd --app-id nodeapp --dapr-grpc-port 50002 -dapr-http-port 3501 --log-level debug --app-port 3000 --enable-mtls --sentry-address localhost:50001 --config nodeappconfig.yaml
在另一个命令提示符中运行Node.js应用程序:
node app.js
运行Python应用程序
在另一个命令提示符中,设置这些环境变量:
```bash export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt` export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt` export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key` export NAMESPACE=default
$env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt) $env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt) $env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key) $env:NAMESPACE="default"
运行daprd以启动Python应用程序的Dapr sidecar,启用mTLS,引用本地Sentry服务:
daprd --app-id pythonapp --dapr-grpc-port 50003 --metrics-port 9092 --log-level debug --enable-mtls --sentry-address localhost:50001 --config pythonappconfig.yaml
在另一个命令提示符中运行Python应用程序:
python app.py
您应该在Python应用程序命令提示符中看到对Node.js应用程序的调用失败,这是由于nodeappconfig
文件中的拒绝操作。将此操作更改为允许并重新运行应用程序以查看此调用成功。
Kubernetes模式
先决条件
- 熟悉在自托管模式下运行启用mTLS的Sentry服务
- 克隆hello world教程
配置Node.js和Python应用程序
您可以创建并应用上述nodeappconfig.yaml
和pythonappconfig.yaml
配置文件,如配置中所述。
例如,下面的Kubernetes Deployment展示了Python应用程序如何在默认命名空间中使用此pythonappconfig
配置文件部署到Kubernetes。
对Node.js部署执行相同操作,并查看Python应用程序的日志以查看由于nodeappconfig
文件中设置的拒绝操作而导致的调用失败。
将此操作更改为允许并重新部署应用程序以查看此调用成功。
部署YAML示例
apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonapp
namespace: default
labels:
app: python
spec:
replicas: 1
selector:
matchLabels:
app: python
template:
metadata:
labels:
app: python
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "pythonapp"
dapr.io/config: "pythonappconfig"
spec:
containers:
- name: python
image: dapriosamples/hello-k8s-python:edge
演示
观看此视频了解如何为服务调用应用访问控制列表。
下一步
Dapr API允许列表3.5 - 使用指南:选择性启用 Dapr Sidecar 的 API
在零信任网络环境中,或通过前端将 Dapr Sidecar 暴露给外部流量时,建议仅启用应用程序实际使用的 Dapr Sidecar API。这样可以减少潜在的攻击风险,并确保 Dapr API 仅限于应用程序的实际需求。
Dapr 允许您通过使用 Dapr 配置 设置 API 白名单或黑名单来控制应用程序可以访问哪些 API。
默认设置
如果未指定 API 白名单或黑名单,默认情况下将允许访问所有 Dapr API。
- 如果只定义了黑名单,则除黑名单中定义的 API 外,所有 Dapr API 都被允许访问。
- 如果只定义了白名单,则仅允许白名单中列出的 Dapr API。
- 如果同时定义了白名单和黑名单,则黑名单中的 API 优先于白名单。
- 如果两者都未定义,则允许访问所有 API。
例如,以下配置为 HTTP 和 gRPC 启用所有 API:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
tracing:
samplingRate: "1"
使用白名单
启用特定的 HTTP API
以下示例启用 state v1.0
HTTP API,并禁用所有其他 HTTP API:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
allowed:
- name: state
version: v1.0
protocol: http
启用特定的 gRPC API
以下示例启用 state v1
gRPC API,并禁用所有其他 gRPC API:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
allowed:
- name: state
version: v1
protocol: grpc
使用黑名单
禁用特定的 HTTP API
以下示例禁用 state v1.0
HTTP API,允许所有其他 HTTP API:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
denied:
- name: state
version: v1.0
protocol: http
禁用特定的 gRPC API
以下示例禁用 state v1
gRPC API,允许所有其他 gRPC API:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: myappconfig
namespace: default
spec:
api:
denied:
- name: state
version: v1
protocol: grpc
Dapr API 列表
name
字段用于指定您想启用的 Dapr API 名称。
请参考以下列表获取不同 Dapr API 的名称:
API 组 | HTTP API | gRPC API |
---|---|---|
服务调用 | invoke (v1.0 ) | invoke (v1 ) |
状态 | state (v1.0 和 v1.0-alpha1 ) | state (v1 和 v1alpha1 ) |
发布/订阅 | publish (v1.0 和 v1.0-alpha1 ) | publish (v1 和 v1alpha1 ) |
输出绑定 | bindings (v1.0 ) | bindings (v1 ) |
订阅 | n/a | subscribe (v1alpha1 ) |
秘密 | secrets (v1.0 ) | secrets (v1 ) |
actor | actors (v1.0 ) | actors (v1 ) |
元数据 | metadata (v1.0 ) | metadata (v1 ) |
配置 | configuration (v1.0 和 v1.0-alpha1 ) | configuration (v1 和 v1alpha1 ) |
分布式锁 | lock (v1.0-alpha1 )unlock (v1.0-alpha1 ) | lock (v1alpha1 )unlock (v1alpha1 ) |
加密 | crypto (v1.0-alpha1 ) | crypto (v1alpha1 ) |
工作流 | workflows (v1.0 ) | workflows (v1 ) |
健康检查 | healthz (v1.0 ) | n/a |
关闭 | shutdown (v1.0 ) | shutdown (v1 ) |
后续步骤
配置 Dapr 使用 gRPC3.6 - 操作指南:配置 Dapr 使用 gRPC
Dapr 提供了用于本地调用的 HTTP 和 gRPC API。gRPC 适用于低延迟、高性能的场景,并支持通过 proto 客户端进行语言集成。您可以查看自动生成的客户端(Dapr SDKs)的完整列表。
Dapr 运行时提供了一个 proto 服务,应用程序可以通过 gRPC 与其进行通信。
Dapr 不仅可以通过 gRPC 被调用,还可以通过 gRPC 与应用程序通信。为此,应用程序需要托管一个 gRPC 服务器并实现 Dapr appcallback
服务。
配置 Dapr 通过 gRPC 与应用程序通信
在自托管模式下运行时,使用 --app-protocol
标志告诉 Dapr 使用 gRPC 与应用程序通信:
dapr run --app-protocol grpc --app-port 5005 node app.js
这告诉 Dapr 通过端口 5005
使用 gRPC 与您的应用程序通信。
在 Kubernetes 上,在您的部署 YAML 中设置以下注释:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-protocol: "grpc"
dapr.io/app-port: "5005"
#...
下一步
处理大型 HTTP 头部大小3.7 - 操作指南:如何处理大容量 HTTP 请求体
Dapr 默认限制请求体大小为 4MB。您可以通过以下方法更改此限制:
- 使用
dapr.io/http-max-request-size
注解,或 - 使用
--dapr-http-max-request-size
参数。
在自托管模式下运行时,使用 --dapr-http-max-request-size
参数来设置 Dapr 的请求体大小限制:
dapr run --dapr-http-max-request-size 16 node app.js
这将把 Dapr 的最大请求体大小设置为 16
MB。
在 Kubernetes 中,您可以在部署的 YAML 文件中添加以下注解:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/http-max-request-size: "16"
#...
相关链接
下一步
安装 Sidecar 证书3.8 - 操作指南:处理大型HTTP头部大小
Dapr的HTTP头部读取缓冲区大小默认限制为4KB。如果您发送的HTTP头部超过4KB,可能会遇到请求头部过大
的服务调用错误。
您可以通过以下方法增加HTTP头部大小:
- 使用
dapr.io/http-read-buffer-size
注解,或 - 在使用CLI时添加
--dapr-http-read-buffer-size
标志。
在自托管模式下运行时,使用--dapr-http-read-buffer-size
标志来配置Dapr,以便使用非默认的HTTP头部大小:
dapr run --dapr-http-read-buffer-size 16 node app.js
这会将Dapr的最大读取缓冲区大小设置为16
KB。
在Kubernetes上,您可以在部署的YAML文件中设置以下注解:
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/http-read-buffer-size: "16"
#...
相关链接
下一步
处理大型HTTP主体请求3.9 - 操作指南:在Dapr sidecar中安装证书
Dapr sidecar可以通过配置来信任与外部服务通信所需的证书。这在需要信任自签名证书的场景中非常有用,例如:
- 使用HTTP绑定
- 为sidecar配置出站代理
支持信任证书颁发机构(CA)证书和叶子证书。
当sidecar作为容器运行时,可以进行以下配置。
- 使用卷挂载将证书配置为可用于sidecar容器。
- 将sidecar容器中的环境变量
SSL_CERT_DIR
指向包含证书的目录。
注意: 对于Windows容器,请确保容器以管理员权限运行,以便可以安装证书。
以下示例展示了如何使用Docker Compose在sidecar容器中安装证书(证书位于本地的./certificates
目录中):
version: '3'
services:
dapr-sidecar:
image: "daprio/daprd:edge" # dapr版本必须至少为v1.8
command: [
"./daprd",
"-app-id", "myapp",
"-app-port", "3000",
]
volumes:
- "./components/:/components"
- "./certificates:/certificates" # (步骤1)将证书文件夹挂载到sidecar容器
environment:
- "SSL_CERT_DIR=/certificates" # (步骤2)将环境变量设置为证书文件夹的路径
# 对于Windows容器,取消注释下面的行
# user: ContainerAdministrator
注意: 当sidecar不在容器内运行时,证书必须直接安装在主机操作系统上。
在Kubernetes上:
- 使用卷挂载将证书配置为可用于sidecar容器。
- 将sidecar容器中的环境变量
SSL_CERT_DIR
指向包含证书的目录。
以下示例YAML展示了一个部署:
- 将pod卷附加到sidecar
- 设置
SSL_CERT_DIR
以安装证书
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
namespace: default
labels:
app: myapp
spec:
replicas: 1
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "myapp"
dapr.io/app-port: "8000"
dapr.io/volume-mounts: "certificates-vol:/tmp/certificates" # (步骤1)将证书文件夹挂载到sidecar容器
dapr.io/env: "SSL_CERT_DIR=/tmp/certificates" # (步骤2)将环境变量设置为证书文件夹的路径
spec:
volumes:
- name: certificates-vol
hostPath:
path: /certificates
#...
注意: 使用Windows容器时,sidecar容器以管理员权限启动,这是安装证书所需的。这不适用于Linux容器。
完成这些步骤后,SSL_CERT_DIR
指向的目录中的所有证书都将被安装。
- 在Linux容器上: 支持OpenSSL支持的所有证书扩展。了解更多。
- 在Windows容器上: 支持
certoc.exe
支持的所有证书扩展。查看Windows Server Core中的certoc.exe。
演示
观看在社区电话64中使用安装SSL证书和安全使用HTTP绑定的演示:
相关链接
下一步
启用预览功能3.10 - 操作指南:启用预览功能
在 Dapr 中,预览功能在首次发布时被视为实验功能。这些预览功能需要您明确选择启用才能使用。您需要在 Dapr 的配置文件中进行此选择。
预览功能是通过在运行应用程序实例时设置配置来启用的。
配置属性
Configuration
规范下的 features
部分包含以下属性:
属性 | 类型 | 描述 |
---|---|---|
name | 字符串 | 启用/禁用的预览功能的名称 |
enabled | 布尔值 | 指定功能是否启用或禁用的布尔值 |
启用预览功能
预览功能需要在配置中指定。以下是一个包含多个功能的完整配置示例:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: featureconfig
spec:
tracing:
samplingRate: "1"
zipkin:
endpointAddress: "http://zipkin.default.svc.cluster.local:9411/api/v2/spans"
features:
- name: Feature1
enabled: true
- name: Feature2
enabled: true
要在本地运行 Dapr 时启用预览功能,可以更新默认配置或使用 dapr run
指定单独的配置文件。
默认的 Dapr 配置是在您运行 dapr init
时创建的,位于:
- Windows:
%USERPROFILE%\.dapr\config.yaml
- Linux/macOS:
~/.dapr/config.yaml
或者,您可以通过在 dapr run
中指定 --config
标志并指向单独的 Dapr 配置文件来更新本地运行的所有应用程序的预览功能:
dapr run --app-id myApp --config ./previewConfig.yaml ./app
在 Kubernetes 模式下,必须通过配置组件来提供配置。使用与上面相同的配置,通过 kubectl
应用:
kubectl apply -f previewConfig.yaml
然后可以通过修改应用程序的配置,使用 dapr.io/config
元素来引用该特定配置组件。例如:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
labels:
app: node
spec:
replicas: 1
selector:
matchLabels:
app: node
template:
metadata:
labels:
app: node
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "featureconfig"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
下一步
配置模式3.11 - 操作指南:为 Dapr sidecar 配置 Secret 环境变量
在某些情况下,Dapr sidecar 需要注入环境变量。这可能是因为某个组件、第三方库或模块需要通过环境变量进行配置或自定义行为。这在生产和非生产环境中都很有用。
概述
在 Dapr 1.15 中,引入了新的 dapr.io/env-from-secret
注解,类似于 dapr.io/env
。通过这个注解,你可以将环境变量注入到 Dapr sidecar 中,其值来自于一个 secret。
注解格式
注解的格式如下:
- 单个键的 secret:
<ENV_VAR_NAME>=<SECRET_NAME>
- 多个键/值的 secret:
<ENV_VAR_NAME>=<SECRET_NAME>:<SECRET_KEY>
<ENV_VAR_NAME>
必须符合 C_IDENTIFIER
格式,遵循 [A-Za-z_][A-Za-z0-9_]*
的正则表达式:
- 必须以字母或下划线开头
- 其余部分可以包含字母、数字或下划线
由于 secretKeyRef
的限制,name
字段是必需的,因此 name
和 key
必须同时设置。从 Kubernetes 文档的 “env.valueFrom.secretKeyRef.name” 部分了解更多信息。 在这种情况下,Dapr 会将两者设置为相同的值。
配置单个键的 secret 环境变量
在以下示例中,dapr.io/env-from-secret
注解被添加到 Deployment 中。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/env-from-secret: "AUTH_TOKEN=auth-headers-secret"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
dapr.io/env-from-secret
注解的值为 "AUTH_TOKEN=auth-headers-secret"
被注入为:
env:
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: auth-headers-secret
key: auth-headers-secret
这要求 secret 的 name
和 key
字段具有相同的值,即 “auth-headers-secret”。
示例 secret
注意: 以下示例仅用于演示目的。不建议以明文存储 secret。
apiVersion: v1
kind: Secret
metadata:
name: auth-headers-secret
type: Opaque
stringData:
auth-headers-secret: "AUTH=mykey"
配置多个键的 secret 环境变量
在以下示例中,dapr.io/env-from-secret
注解被添加到 Deployment 中。
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
spec:
template:
metadata:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/env-from-secret: "AUTH_TOKEN=auth-headers-secret:auth-header-value"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node:latest
ports:
- containerPort: 3000
imagePullPolicy: Always
dapr.io/env-from-secret
注解的值为 "AUTH_TOKEN=auth-headers-secret:auth-header-value"
被注入为:
env:
- name: AUTH_TOKEN
valueFrom:
secretKeyRef:
name: auth-headers-secret
key: auth-header-value
示例 secret
注意: 以下示例仅用于演示目的。不建议以明文存储 secret。
apiVersion: v1
kind: Secret
metadata:
name: auth-headers-secret
type: Opaque
stringData:
auth-header-value: "AUTH=mykey"
4 - 管理 Dapr 中的组件
在 Dapr 中,组件是应用程序与外部资源交互的关键。它们可以是数据库、消息队列、秘密管理系统等。开发者可以通过配置这些组件,轻松地在应用程序中集成和使用这些外部资源。
Dapr 提供了一种声明式的方法来管理组件。每个组件都通过一个 YAML 文件定义,该文件描述了组件的类型、元数据和其他配置细节。以下是一个简单的组件定义示例:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: my-pubsub
namespace: default
spec:
type: pubsub.redis
version: v1
metadata:
- name: redisHost
value: "localhost:6379"
- name: redisPassword
secretKeyRef:
name: redis-secret
key: password
在这个示例中,我们定义了一个名为 my-pubsub
的发布订阅组件,它使用 Redis 作为底层实现。组件的元数据部分指定了 Redis 主机和密码,其中密码是通过 secret 管理的。
要在应用程序中使用这些组件,开发者只需在应用程序代码中引用组件名称即可。Dapr 的 sidecar 会自动处理与组件的交互,使得开发者无需关心底层实现细节。
通过这种方式,Dapr 提供了一种灵活且可扩展的方式来管理应用程序中的外部资源,使得开发者可以专注于业务逻辑,而不是基础设施管理。
4.1 - 认证流程
注意
认证流程仅适用于内置组件,不适用于可插拔组件。概述
Dapr 采用模块化设计,功能以组件形式提供。每个组件都有一个接口定义,所有组件都是可互换的,因此理想情况下,您可以用具有相同接口的另一个组件替换一个组件。每个用于生产的组件都需要满足一定的技术要求,以确保功能兼容性和稳健性。
一般来说,一个组件需要:
- 符合定义的 Dapr 接口
- 功能正确且稳健
- 有良好的文档和维护
为了确保组件符合 Dapr 设定的标准,会在 Dapr 维护者管理的环境中对组件进行一系列测试。一旦测试持续通过,就可以确定组件的成熟度级别。
认证级别
级别如下:
Alpha
- 组件实现了所需的接口,并按规范描述工作
- 组件有文档
- 组件可能存在漏洞,或在集成时暴露出漏洞
- 组件可能无法通过所有一致性测试
- 组件可能没有一致性测试
- 由于后续版本中可能出现不兼容的更改,仅推荐用于非关键业务用途
所有组件都从 Alpha 阶段开始。
Beta
- 组件必须通过所有定义的组件一致性测试以满足组件规范
- 组件一致性测试已在 Dapr 维护者管理的环境中运行
- 组件包含由 Dapr 维护者审核和批准的特定 components-contrib 版本的一致性测试结果记录
- 由于后续版本中可能出现不兼容的更改,仅推荐用于非关键业务用途
注意
如果满足以下条件,组件可以跳过 Beta 阶段和一致性测试要求,由维护者决定:
- 组件是一个绑定
- 认证测试是全面的
Stable
- 组件必须有组件认证测试以验证功能和弹性
- 组件由 Dapr 维护者维护并由社区支持
- 组件有良好的文档和测试
- 组件在之前至少一个 Dapr 运行时的小版本发布中以 Alpha 或 Beta 形式存在
- 维护者将根据 Dapr 支持政策解决组件安全性、核心功能和测试问题,并发布包含修补的稳定组件的补丁版本
注意
稳定的 Dapr 组件基于 Dapr 认证和一致性测试,并不保证由任何特定供应商支持,其中供应商的 SDK 作为组件的一部分使用。
Dapr 组件测试保证组件的稳定性,与第三方供应商为任何使用的 SDK 声明的稳定性状态无关。这是因为稳定的含义(例如 alpha、beta、stable)可能因供应商而异。
以前的正式发布 (GA) 组件
任何先前认证为 GA 的组件,即使不符合新要求,也允许进入 Stable。
一致性测试
components-contrib 仓库中的每个组件都需要遵循 Dapr 定义的一组接口。一致性测试是在这些组件定义及其相关支持服务上运行的测试,以确保组件符合 Dapr 接口规范和行为。
一致性测试为以下构建块定义:
- 状态存储
- secret 存储
- 绑定
- pubsub
要了解更多信息,请参阅此处的自述文件。
测试要求
- 测试应根据组件规范验证组件的功能行为和稳健性
- 作为组件一致性测试文档的一部分,添加所有重现测试所需的详细信息
认证测试
components-contrib 仓库中的每个稳定组件必须有一个认证测试计划和自动化认证测试,以验证组件通过 Dapr 支持的所有功能。
稳定组件的测试计划应包括以下场景:
- 客户端重新连接:如果客户端库暂时无法连接到服务,一旦服务重新上线,Dapr sidecar 不应需要重启。
- 认证选项:验证组件可以使用所有支持的选项进行认证。
- 验证资源配置:验证组件在初始化时是否自动配置资源(如果适用)。
- 所有与相应构建块和组件相关的场景。
测试计划必须由 Dapr 维护者批准,并与组件代码一起发布在 README.md
文件中。
测试要求
- 测试应根据组件规范验证组件的功能行为和稳健性,反映测试计划中的场景
- 测试必须作为 components-contrib 仓库的持续集成的一部分成功运行
组件认证过程
为了使组件获得认证,测试在由 Dapr 项目维护的环境中运行。
新组件认证:Alpha->Beta
对于需要从 Alpha 更改为 Beta 认证的新组件,组件认证请求遵循以下步骤:
- 请求者在 components-contrib 仓库中创建一个问题,以认证组件的当前和新认证级别
- 请求者提交一个 PR 以将组件与定义的一致性测试套件集成(如果尚未包含)
- 用户在创建的问题中详细说明环境设置,以便 Dapr 维护者可以在托管环境中设置服务
- 环境设置完成后,Dapr 维护者审核 PR,如果批准则合并该 PR
- 请求者在 docs 仓库中提交一个 PR,更新组件的认证级别
新组件认证:Beta->Stable
对于需要从 Beta 更改为 Stable 认证的新组件,组件认证请求遵循以下步骤:
- 请求者在 components-contrib 仓库中创建一个问题,以认证组件的当前和新认证级别
- 请求者在组件的源代码目录中提交一个 PR,将测试计划作为
README.md
文件- 请求者在创建的 PR 中详细说明测试环境要求,包括任何手动步骤或凭据
- Dapr 维护者审核测试计划,提供反馈或批准,并最终合并 PR
- 请求者提交一个 PR 用于自动化认证测试,包括在适用时配置资源的脚本
- 在测试环境设置完成和凭据配置后,Dapr 维护者审核 PR,如果批准则合并 PR
- 请求者在 docs 仓库中提交一个 PR,更新组件的认证级别
4.2 - 更新组件
在更新应用程序使用的现有已部署组件时,除非启用了 HotReload
功能门控,否则 Dapr 不会自动更新组件。需要重启 Dapr sidecar 才能获取组件的最新版本。具体操作方式取决于托管环境。
Kubernetes
在 Kubernetes 中运行时,更新组件的过程包括以下两个步骤:
- 将新的组件 YAML 应用到所需的命名空间。
- 除非启用了
HotReload
功能门控,否则需要对部署执行 滚动重启操作 以获取最新组件。
自托管
除非启用了 HotReload
功能门控,更新组件的过程包括停止和重启 daprd
进程以获取最新组件的单个步骤。
热重载(预览功能)
此功能目前处于预览状态。 热重载通过
HotReload
功能门控 启用。
Dapr 可以实现“热重载”组件,从而在不需要重启 Dapr sidecar 进程或 Kubernetes pod 的情况下自动获取组件更新。这意味着创建、更新或删除组件清单将在运行时反映在 Dapr sidecar 中。
更新组件
当组件更新时,它首先被关闭,然后使用新配置重新初始化。这会导致组件在此过程中短时间内不可用。初始化错误
如果通过热重载创建或更新组件时初始化过程出错,Dapr sidecar 会遵循组件字段 spec.ignoreErrors
的设置。也就是说,行为与 sidecar 在启动时加载组件时相同。
spec.ignoreErrors=false
(默认): sidecar 优雅地关闭。spec.ignoreErrors=true
: sidecar 继续运行,既没有注册旧的也没有注册新的组件配置。
除以下类型外,所有组件均支持热重载。这些组件类型的任何创建、更新或删除都将被 sidecar 忽略,需要重启以获取更改。
进一步阅读
4.3 - 操作指南:将组件限定于一个或多个应用程序
Dapr组件具有命名空间(这与Kubernetes的命名空间概念不同),这意味着一个Dapr运行时实例只能访问部署在相同命名空间中的组件。
Dapr运行时,会将其配置的命名空间与加载的组件的命名空间进行匹配,并仅初始化与其命名空间匹配的组件。其他命名空间中的组件将不会被加载。
命名空间
命名空间可以用来限制组件对特定Dapr实例的访问。
在自托管模式下,开发者可以通过设置NAMESPACE
环境变量来为Dapr实例指定命名空间。
如果设置了NAMESPACE
环境变量,Dapr将不会加载任何在其元数据中未指定相同命名空间的组件。
例如,假设在production
命名空间中有以下组件:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
namespace: production
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: redis-master:6379
要告诉Dapr它被部署到哪个命名空间,设置环境变量:
MacOS/Linux:
export NAMESPACE=production
# 像往常一样运行Dapr
Windows:
setx NAMESPACE "production"
# 像往常一样运行Dapr
让我们考虑以下在Kubernetes中的组件:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
namespace: production
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: redis-master:6379
在这个例子中,Redis组件仅对运行在production
命名空间内的Dapr实例可访问。
注意
应用于命名空间"A"的组件YAML可以引用命名空间"B"中的实现。例如,命名空间"production-A"中的Redis组件YAML可以将Redis主机地址指向部署在命名空间"production-B"中的Redis实例。
参见配置具有多个命名空间的Pub/Sub组件以获取示例。
应用程序对具有范围的组件的访问
开发者和操作员可能希望限制某个应用程序或一组特定应用程序对一个数据库的访问。
为实现这一点,Dapr允许您在组件YAML上指定scopes
。添加到组件的应用程序范围仅限制具有特定ID的应用程序使用该组件。
以下示例展示了如何为两个启用Dapr的应用程序提供访问权限,这两个应用程序的ID分别为app1
和app2
,访问名为statestore
的Redis组件,该组件本身位于production
命名空间中
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
namespace: production
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: redis-master:6379
scopes:
- app1
- app2
社区电话演示
使用命名空间进行服务调用
阅读跨命名空间的服务调用以获取有关在服务之间调用时使用命名空间的更多信息。
使用命名空间进行pub/sub
阅读配置具有多个命名空间的Pub/Sub组件以获取有关在pub/sub中使用命名空间的更多信息。
相关链接
4.4 - 操作指南:在组件中引用secret
概述
在组件定义的spec.metadata
部分中,可以引用secret。
要引用secret,你需要设置auth.secretStore
字段来指定保存secret的secret存储的名称。
在Kubernetes中运行时,如果auth.secretStore
为空,则默认使用Kubernetes secret存储。
支持的secret存储
访问此链接查看Dapr支持的所有secret存储,以及如何配置和使用它们的信息。
引用secret
虽然你可以选择使用纯文本secret(如MyPassword),如下面yaml中redisPassword
的value
所示,但这不建议用于生产环境:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
value: MyPassword
相反,建议在你的secret存储中创建secret并在组件定义中引用它。下面展示了两种情况——“secret包含嵌入的key”和“secret是一个字符串”。
“secret包含嵌入的key”适用于secret中嵌入了一个key的情况,即secret不是一个完整的连接字符串。这在以下组件定义yaml中展示。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.redis
version: v1
metadata:
- name: redisHost
value: localhost:6379
- name: redisPassword
secretKeyRef:
name: redis-secret
key: redis-password
auth:
secretStore: <SECRET_STORE_NAME>
SECRET_STORE_NAME
是配置的secret存储组件的名称。在Kubernetes中运行并使用Kubernetes secret存储时,字段auth.SecretStore
默认为kubernetes
,可以留空。
上述组件定义告诉Dapr从定义的secretStore
中提取名为redis-secret
的secret,并将secret中嵌入的redis-password
key关联的值分配给组件中的redisPassword
字段。此情况的一个用途是当你的代码正在构建一个连接字符串时,例如将URL、secret以及其他必要信息组合成一个字符串。
另一方面,下面的“secret是一个字符串”适用于secret中没有嵌入key的情况。相反,secret只是一个字符串。因此,在secretKeyRef
部分中,secret的name
和secret的key
将是相同的。这种情况是当secret本身是一个完整的连接字符串,没有需要提取值的嵌入key时。通常,连接字符串由连接信息、某种允许连接的secret以及可能的其他信息组成,不需要单独的“secret”。这种情况在下面的组件定义yaml中展示。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: servicec-inputq-azkvsecret-asbqueue
spec:
type: bindings.azure.servicebusqueues
version: v1
metadata:
- name: connectionString
secretKeyRef:
name: asbNsConnString
key: asbNsConnString
- name: queueName
value: servicec-inputq
auth:
secretStore: <SECRET_STORE_NAME>
上述“secret是一个字符串”情况的yaml告诉Dapr从定义的secretStore
中提取名为asbNsConnstring
的连接字符串,并将值分配给组件中的connectionString
字段,因为从secretStore
中提取的“secret”是一个纯字符串,没有嵌入的key。这要求secret的name
和secret的key
相同。
示例
引用Kubernetes secret
以下示例展示了如何创建一个Kubernetes secret来保存Event Hubs绑定的连接字符串。
首先,创建Kubernetes secret:
kubectl create secret generic eventhubs-secret --from-literal=connectionString=*********
接下来,在你的绑定中引用secret:
apiVersion: dapr.io/v1alpha1 kind: Component metadata: name: eventhubs spec: type: bindings.azure.eventhubs version: v1 metadata: - name: connectionString secretKeyRef: name: eventhubs-secret key: connectionString
最后,将组件应用到Kubernetes集群:
kubectl apply -f ./eventhubs.yaml
限制对secret的访问
Dapr可以使用其配置限制对secret存储中secret的访问。阅读如何使用secret范围和如何限制从secret存储中读取的secret以获取更多信息。这是使用Dapr限制对secret访问的推荐方法。
Kubernetes权限
默认命名空间
在Kubernetes中运行时,Dapr在安装期间为从Kubernetes secret存储访问secret定义了默认的Role和RoleBinding在default
命名空间中。对于从default
命名空间获取secret的Dapr启用的应用程序,可以如上例所示定义和引用secret。
非默认命名空间
如果你的Dapr启用的应用程序使用从非默认命名空间获取secret的组件,请将以下资源应用到该命名空间:
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: secret-reader
namespace: <NAMESPACE>
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "list"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: dapr-secret-reader
namespace: <NAMESPACE>
subjects:
- kind: ServiceAccount
name: default
roleRef:
kind: Role
name: secret-reader
apiGroup: rbac.authorization.k8s.io
这些资源授予Dapr从Role和RoleBinding中定义的命名空间的Kubernetes secret存储中获取secret的权限。
相关链接
4.5 - 状态存储组件
Dapr 集成现有数据库,为应用提供 CRUD 操作、事务等状态管理功能。它还支持为每个应用配置多个独立的状态存储组件。
状态存储具有可扩展性,可以在 components-contrib 仓库中找到。
在 Dapr 中,状态存储通过 Component
文件进行描述:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.<DATABASE>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...
数据库的类型由 type
字段决定,连接字符串和其他元数据信息放在 .metadata
部分。即使元数据值可以包含明文的密钥,仍建议使用 密钥存储。
请参考本指南了解如何配置状态存储组件。
支持的状态存储
请访问此参考查看 Dapr 中支持的所有状态存储。
相关主题
4.6 - 发布/订阅代理
Dapr 支持与发布/订阅消息总线的集成,为应用程序提供创建事件驱动、松耦合架构的能力,生产者通过主题向消费者发送事件。
Dapr 允许为每个应用程序配置多个具名的发布/订阅组件。每个组件都有一个名称,用于在发布消息主题时识别。阅读 API 参考 了解如何发布和订阅主题的详细信息。
发布/订阅组件是可扩展的。支持的组件列表在这里,实现可以在 components-contrib 仓库中找到。
组件文件
发布/订阅通过 Component
文件描述:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: pubsub
namespace: default
spec:
type: pubsub.<NAME>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...
发布/订阅的类型由 type
字段指定,连接字符串和其他元数据等属性放在 .metadata
部分。尽管元数据值可以包含明文的 secret,建议您通过 secretKeyRef
使用 secret 存储 来管理这些 secret。
主题创建
根据您使用的发布/订阅消息总线及其配置,主题可能会自动创建。即使消息总线支持自动主题创建,在生产环境中禁用它是一种常见的治理实践。您可能仍需要使用 CLI、管理控制台或请求表单手动创建应用程序所需的主题。虽然所有发布/订阅组件都支持 consumerID
元数据,但如果您未提供,运行时会自动生成一个消费者 ID。所有组件元数据字段值可以使用 模板化元数据值,这些值在 Dapr sidecar 启动时解析。例如,您可以选择使用 {namespace}
作为 consumerGroup
,以便在不同命名空间中使用相同的 appId
使用相同的主题,如本文所述。
访问本指南获取配置和使用发布/订阅组件的说明。
相关链接
- Dapr 发布/订阅构建块概述
- 尝试 发布/订阅快速入门示例
- 阅读发布和订阅指南
- 了解主题范围
- 了解消息生存时间
- 学习如何配置具有多个命名空间的发布/订阅组件
- 发布/订阅组件列表
- 阅读 API 参考
4.6.1 - HowTo: 配置具有多个命名空间的 Pub/Sub 组件
在某些情况下,应用程序可能会跨多个命名空间分布,并通过 PubSub 共享队列或主题。在这种情况下,需要在每个命名空间中配置 PubSub 组件。
注意
命名空间是 Dapr 用于限定应用程序和组件范围的概念。本示例使用 Kubernetes 命名空间,但 Dapr 组件命名空间范围可以在任何支持的平台上使用。阅读 How-To: 将组件限定到一个或多个应用程序 以获取有关限定组件的更多信息。本示例使用 PubSub 示例。Redis 安装和订阅者位于 namespace-a
,而发布者 UI 位于 namespace-b
。即使 Redis 安装在另一个命名空间,或者您使用托管云服务如 Azure ServiceBus、AWS SNS/SQS 或 GCP PubSub,该解决方案也同样适用。
以下是使用命名空间的示例图。

下表显示了哪些资源部署到哪些命名空间:
资源 | namespace-a | namespace-b |
---|---|---|
Redis 主节点 | ✅ | ❌ |
Redis 副本 | ✅ | ❌ |
Dapr 的 PubSub 组件 | ✅ | ✅ |
Node 订阅者 | ✅ | ❌ |
Python 订阅者 | ✅ | ❌ |
React UI 发布者 | ❌ | ✅ |
注意
所有 pub/sub 组件都支持通过 命名空间或组件范围 将 pub/sub 主题限制到特定应用程序。前提条件
- 在 Kubernetes 上安装 Dapr,因为 Dapr 在集群级别工作。
- 检出并进入 PubSub 快速入门 的目录。
设置 namespace-a
创建命名空间并切换 kubectl 使用它。
kubectl create namespace namespace-a
kubectl config set-context --current --namespace=namespace-a
在 namespace-a
上安装 Redis(主节点和从节点),按照这些说明。
现在,配置 deploy/redis.yaml
,确保主机名包含 namespace-a
。
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: pubsub
spec:
type: pubsub.redis
version: v1
metadata:
- name: "redisHost"
value: "redis-master.namespace-a.svc:6379"
- name: "redisPassword"
value: "YOUR_PASSWORD"
将资源部署到 namespace-a
:
kubectl apply -f deploy/redis.yaml
kubectl apply -f deploy/node-subscriber.yaml
kubectl apply -f deploy/python-subscriber.yaml
设置 namespace-b
创建命名空间并切换 kubectl 使用它。
kubectl create namespace namespace-b
kubectl config set-context --current --namespace=namespace-b
将资源部署到 namespace-b
,包括 Redis 组件:
kubectl apply -f deploy/redis.yaml
kubectl apply -f deploy/react-form.yaml
现在,找到 react-form 的 IP 地址,在浏览器中打开它并向每个主题(A、B 和 C)发布消息。
kubectl get service -A
确认订阅者接收到消息。
切换回 namespace-a
:
kubectl config set-context --current --namespace=namespace-a
找到 POD 名称:
kubectl get pod # 复制 POD 名称并在下一个命令中使用。
显示日志:
kubectl logs node-subscriber-XYZ node-subscriber
kubectl logs python-subscriber-XYZ python-subscriber
在浏览器上发布的消息应显示在相应订阅者的日志中。Node.js 订阅者接收类型为 “A” 和 “B” 的消息,而 Python 订阅者接收类型为 “A” 和 “C” 的消息。
清理
kubectl delete -f deploy/redis.yaml --namespace namespace-a
kubectl delete -f deploy/node-subscriber.yaml --namespace namespace-a
kubectl delete -f deploy/python-subscriber.yaml --namespace namespace-a
kubectl delete -f deploy/react-form.yaml --namespace namespace-b
kubectl delete -f deploy/redis.yaml --namespace namespace-b
kubectl config set-context --current --namespace=default
kubectl delete namespace namespace-a
kubectl delete namespace namespace-b
相关链接
4.7 - Secret 存储组件
Dapr 集成了 Secret 存储,为应用程序和其他组件提供安全的 Secret 存储和访问,例如访问密钥和密码。每个 Secret 存储组件都有一个名称,用于访问 Secret 时使用。
与其他构建块组件类似,Secret 存储组件是可扩展的,相关代码可以在 components-contrib 仓库中找到。
在 Dapr 中,Secret 存储通过一个 Component
文件进行描述,包含以下字段:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: secretstore
spec:
type: secretstores.<NAME>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...
Secret 存储的类型由 type
字段指定,连接字符串和其他元数据信息放在 .metadata
部分。
不同的支持的 Secret 存储会有不同的特定字段需要配置。例如,配置使用 AWS Secrets Manager 的 Secret 存储时,文件格式如下:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: awssecretmanager
spec:
type: secretstores.aws.secretmanager
version: v1
metadata:
- name: region
value: "[aws_region]"
- name: accessKey
value: "[aws_access_key]"
- name: secretKey
value: "[aws_secret_key]"
- name: sessionToken
value: "[aws_session_token]"
重要
在 EKS (AWS Kubernetes) 上运行 Dapr sidecar (daprd) 时,如果节点/Pod 已附加了允许访问 AWS 资源的 IAM 策略,则不应在组件配置中提供 AWS access-key、secret-key 和 tokens。应用配置
创建组件的 YAML 文件后,请根据您的托管环境按照以下说明应用它:
在本地运行时,创建一个包含 YAML 文件的 components
目录,并使用 --resources-path
标志提供给 dapr run
命令。
在 Kubernetes 中部署时,假设您的组件文件名为 secret-store.yaml
,运行:
kubectl apply -f secret-store.yaml
支持的 Secret 存储
访问 Secret 存储参考 以获取支持的 Secret 存储的完整列表。
相关链接
4.8 - Bindings 组件
Dapr 可以与外部资源集成,使应用程序既能被外部事件触发,也能与资源进行交互。每个 bindings 组件都有一个名称,用于与资源进行交互时使用。
与其他构建块组件一样,bindings 组件是可扩展的,相关代码可以在 components-contrib 仓库中找到。
在 Dapr 中,bindings 使用一个 Component
文件描述,包含以下字段:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: <NAME>
namespace: <NAMESPACE>
spec:
type: bindings.<NAME>
version: v1
metadata:
- name: <KEY>
value: <VALUE>
- name: <KEY>
value: <VALUE>
...
bindings 的类型由 type
字段指定,连接字符串和其他元数据则在 .metadata
部分定义。
不同的支持的 bindings会有不同的特定字段需要配置。例如,当为 Azure Blob Storage 配置 bindings 时,文件看起来像这样:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: <NAME>
spec:
type: bindings.azure.blobstorage
version: v1
metadata:
- name: storageAccount
value: myStorageAccountName
- name: storageAccessKey
value: ***********
- name: container
value: container1
- name: decodeBase64
value: <bool>
- name: getBlobRetryCount
value: <integer>
应用配置
一旦创建了组件的 YAML 文件,请根据您的托管环境按照以下步骤进行配置:
对于自托管环境,创建一个包含 YAML 文件的 components
目录,并使用 --resources-path
标志将路径提供给 dapr run
命令。
对于 Kubernetes 部署,假设您的组件文件名为 mybinding.yaml
,运行以下命令:
kubectl apply -f mybinding.yaml
支持的 bindings
访问 bindings 参考 以获取支持资源的完整列表。
相关链接
4.9 - 如何:注册一个可插拔组件
组件注册过程
使用 gRPC 的可插拔组件通常作为容器或进程运行,需要通过Unix 域套接字(简称 UDS)与 Dapr 运行时通信。它们会通过以下步骤自动被发现并注册到运行时中:
- 组件监听放置在共享卷上的Unix 域套接字。
- Dapr 运行时列出共享卷中的所有Unix 域套接字。
- Dapr 运行时连接每个套接字,并使用 gRPC 反射从组件实现的给定构建块 API 中发现所有 proto 服务。
一个组件可以同时实现多个组件接口。

虽然 Dapr 的内置组件已经集成在运行时中,但可插拔组件在与 Dapr 一起使用之前需要进行一些设置步骤。
- 可插拔组件需要在 Dapr 本身启动之前启动并准备好接收请求。
- 用于可插拔组件通信的Unix 域套接字文件需要对 Dapr 和可插拔组件都可访问。
在独立模式下,可插拔组件可以作为进程或容器运行。在 Kubernetes 上,可插拔组件作为容器运行,并由 Dapr 的 sidecar 注入器自动注入到应用程序的 pod 中,允许通过标准的Kubernetes 容器规范进行自定义。
这也改变了在 Dapr 和可插拔组件之间共享Unix 域套接字文件的方法。
注意
作为前提条件,操作系统必须支持 Unix 域套接字,任何 UNIX 或类 UNIX 系统(Mac、Linux 或用于本地开发的 WSL 对于 Windows 用户)都应该足够。选择您的环境以开始使您的组件可被发现。
运行组件
在 Dapr 启动之前,您的组件和 Unix 套接字必须正在运行。
默认情况下,Dapr sidecar 在 /tmp/dapr-components-sockets
中查找作为Unix 域套接字文件的组件。
此文件夹中的文件名对于组件注册很重要。它们必须通过附加组件的名称和您选择的文件扩展名(通常为 .sock
)来形成。例如,文件名 my-component.sock
是一个有效的 Unix 域套接字文件名,适用于名为 my-component
的组件。
由于您在与组件相同的主机上运行 Dapr,请验证此文件夹及其中的文件是否可被您的组件和 Dapr 访问和写入。如果您使用 Dapr 的 sidecar 注入器功能,则此卷会自动创建和挂载。
组件发现和多路复用
通过Unix 域套接字(UDS)可访问的可插拔组件可以托管多个不同的组件 API。在组件的初始发现过程中,Dapr 使用反射枚举 UDS 后面的所有组件 API。上例中的 my-component
可插拔组件可以包含状态存储(state
)和 pub/sub(pubsub
)组件 API。
通常,可插拔组件实现单个组件 API 以进行打包和部署。然而,以增加其依赖性和扩大其安全攻击面为代价,可插拔组件可以实现多个组件 API。这可以减轻部署和监控负担。隔离、容错和安全的最佳实践是为每个可插拔组件实现单个组件 API。
定义组件
使用组件规范定义您的组件。组件的 spec.type
值是通过以下两个部分与 .
连接而成的:
- 组件的 API(
state
、pubsub
、bindings
等) - 组件的名称,它是从Unix 域套接字文件名中派生的,不包括文件扩展名。
您需要为可插拔组件的Unix 域套接字公开的每个 API 定义一个组件规范。前面示例中的 Unix 域套接字 my-component.sock
公开了一个名为 my-component
的可插拔组件,具有 state
和 pubsub
API。需要两个组件规范,每个规范在其自己的 YAML 文件中,放置在 resources-path
中:一个用于 state.my-component
,另一个用于 pubsub.my-component
。
例如,state.my-component
的组件规范可以是:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: my-production-state-store
spec:
type: state.my-component
version: v1
metadata:
在上面的示例中,请注意以下几点:
- 字段
spec.type
的内容是state.my-component
,指的是作为名为my-component
的可插拔组件公开的状态存储。 - 字段
metadata.name
,即此处定义的状态存储的名称,与可插拔组件名称无关。
将此文件保存为 Dapr 的组件配置文件夹中的 component.yaml
。就像 metadata.name
字段的内容一样,此 YAML 文件的文件名没有影响,也不依赖于可插拔组件名称。
运行 Dapr
初始化 Dapr,并确保您的组件文件放置在正确的文件夹中。
注意
Dapr 1.9.0 是支持可插拔组件的最低版本。从 1.11.0 版本开始,支持可插拔组件的容器自动注入。
就是这样!现在您可以通过 Dapr API 调用状态存储 API。通过运行以下命令查看其运行情况。用 Dapr HTTP 端口替换 $PORT
:
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne", "metadata": {}}]' http://localhost:$PORT/v1.0/state/prod-mystore
检索值,用 Dapr HTTP 端口替换 $PORT
:
curl http://localhost:$PORT/v1.0/state/prod-mystore/name
为您的可插拔组件构建和发布容器
确保您的组件作为容器运行,首先发布并可被您的 Kubernetes 集群访问。
在 Kubernetes 集群上部署 Dapr
按照在 Kubernetes 集群上部署 Dapr文档中提供的步骤进行操作。
在您的部署中添加可插拔组件容器
可插拔组件作为容器在与您的应用程序相同的 pod 中部署。
由于可插拔组件由Unix 域套接字支持,请使您的可插拔组件创建的套接字可被 Dapr 运行时访问。配置部署规范以:
- 挂载卷
- 提示 Dapr 挂载的 Unix 套接字卷位置
- 将卷附加到您的可插拔组件容器
在以下示例中,您配置的可插拔组件作为容器部署在与您的应用程序容器相同的 pod 中。
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
annotations:
# 推荐自动注入可插拔组件。
dapr.io/inject-pluggable-components: "true"
dapr.io/app-id: "my-app"
dapr.io/enabled: "true"
spec:
containers:
# 您的应用程序的容器规范,照常。
- name: app
image: YOUR_APP_IMAGE:YOUR_APP_IMAGE_VERSION
建议将 dapr.io/inject-pluggable-components
注释设置为 “true”,指示 Dapr 的 sidecar 注入器该应用程序的 pod 将有额外的容器用于可插拔组件。
或者,您可以跳过 Dapr 的 sidecar 注入功能,手动添加可插拔组件的容器并注释您的 pod,告诉 Dapr 该 pod 中哪些容器是可插拔组件,如下例所示:
apiVersion: apps/v1
kind: Deployment
metadata:
name: app
labels:
app: app
spec:
replicas: 1
selector:
matchLabels:
app: app
template:
metadata:
labels:
app: app
annotations:
dapr.io/pluggable-components: "component" ## 可插拔组件容器的名称,用 `,` 分隔,例如 "componentA,componentB"。
dapr.io/app-id: "my-app"
dapr.io/enabled: "true"
spec:
containers:
### --------------------- 您的应用程序容器在此处 -----------
- name: app
image: YOUR_APP_IMAGE:YOUR_APP_IMAGE_VERSION
### --------------------- 您的可插拔组件容器在此处 -----------
- name: component
image: YOUR_IMAGE_GOES_HERE:YOUR_IMAGE_VERSION
在应用部署之前,让我们再添加一个配置:组件规范。
定义组件
可插拔组件使用组件规范定义。组件 type
是从套接字名称(不带文件扩展名)派生的。在以下示例 YAML 中,替换:
your_socket_goes_here
为您的组件套接字名称(无扩展名)your_component_type
为您的组件类型
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: prod-mystore
# 在 Kubernetes 上运行并自动容器注入时,添加以下注释:
annotations:
dapr.io/component-container: >
{
"name": "my-component",
"image": "<registry>/<image_name>:<image_tag>"
}
spec:
type: your_component_type.your_socket_goes_here
version: v1
metadata:
scopes:
- backend
当您希望 Dapr 的 sidecar 注入器处理可插拔组件的容器和卷注入时,dapr.io/component-container
注释在 Kubernetes 上是必需的。至少,您需要 name
和 image
属性,以便 Dapr 的 sidecar 注入器成功将容器添加到应用程序的 pod 中。Unix 域套接字的卷由 Dapr 的 sidecar 注入器自动创建和挂载。
范围您的组件,以确保只有目标应用程序可以连接到可插拔组件,因为它只会在其部署中运行。否则,运行时在初始化组件时会失败。
就是这样!将创建的清单应用到您的 Kubernetes 集群,并通过 Dapr API 调用状态存储 API。
使用Kubernetes pod 转发器访问 daprd
运行时。
通过运行以下命令查看其运行情况。用 Dapr HTTP 端口替换 $PORT
:
curl -X POST -H "Content-Type: application/json" -d '[{ "key": "name", "value": "Bruce Wayne", "metadata": {}}]' http://localhost:$PORT/v1.0/state/prod-mystore
检索值,用 Dapr HTTP 端口替换 $PORT
:
curl http://localhost:$PORT/v1.0/state/prod-mystore/name
下一步
使用此示例代码开始开发 .NET 可插拔组件
4.10 - 配置中间件组件
Dapr 允许通过串联一系列中间件组件来定义自定义处理管道。您可以在以下两种场景中使用中间件管道:
- 基础模块 API - 在调用任何 Dapr HTTP API 时执行 HTTP 中间件组件。
- 服务间调用 - HTTP 中间件组件应用于服务间调用。
配置 API 中间件管道
启动时,Dapr sidecar 会为传入的 HTTP 调用构建一个中间件处理管道。默认情况下,管道由追踪和 CORS 中间件组成。可以通过 Dapr configuration 配置的其他中间件按定义顺序添加到管道中。该管道适用于所有 Dapr API 端点,包括 state、pubsub、service-invocation、bindings、secret、configuration、分布式锁等。
请求在路由到用户代码之前会依次经过所有定义的中间件组件,然后在返回给客户端之前以相反的顺序再次经过这些中间件,如下图所示。

在使用 httpPipeline
配置调用 Dapr HTTP API 时,HTTP 中间件组件会被执行。
以下配置示例定义了一个自定义管道,使用了 OAuth 2.0 中间件 和 大写中间件组件。在这种情况下,所有请求在转发到用户代码之前都通过 OAuth 2.0 协议进行授权,并转换为大写文本。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
- name: uppercase
type: middleware.http.uppercase
与其他组件一样,中间件组件可以在支持的中间件参考和dapr/components-contrib
仓库中找到。
配置应用中间件管道
在进行服务间调用时,您也可以使用任何中间件组件。例如,在零信任环境中添加令牌验证,转换特定应用端点的请求,或应用 OAuth 策略。
服务间调用中间件组件适用于从 Dapr sidecar 到接收应用(服务)的所有传出调用,如下图所示。

任何可以用作 HTTP 中间件的中间件组件也可以通过 appHttpPipeline
配置应用于服务间调用。下面的示例为从 Dapr sidecar(服务调用的目标)到应用的所有传出调用添加了 uppercase
中间件组件。
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
appHttpPipeline:
handlers:
- name: uppercase
type: middleware.http.uppercase
相关链接
5 - 保护 Dapr 部署
在使用 Dapr 部署应用程序时,确保安全性至关重要。Dapr 提供了一系列功能和最佳实践,帮助开发者保护他们的应用程序。这些功能包括身份验证、授权、数据加密以及安全的通信协议。
首先,身份验证是确保只有授权用户和服务可以访问您的 Dapr 应用程序的关键步骤。Dapr 支持多种身份验证机制,包括 OAuth 和 API 密钥。通过配置这些机制,您可以有效地控制对应用程序的访问。
其次,授权是在用户或服务通过身份验证后,确定其可以执行哪些操作。Dapr 提供了详细的权限控制,允许您定义不同角色和权限,以确保用户只能访问他们被授权的资源。
数据加密是保护敏感信息的另一重要措施。Dapr 支持在传输和存储过程中对数据进行加密。即使数据被截获,未授权用户也无法读取。
最后,Dapr 使用安全的通信协议来保护数据在网络中的传输。通过采用 HTTPS 和其他加密协议,Dapr 确保数据在传输过程中不会被窃听或篡改。
通过遵循这些最佳实践,您可以显著提高 Dapr 应用程序的安全性,保护您的数据和服务免受潜在威胁。
5.1 - 设置和配置 mTLS 证书
Dapr 支持通过 Dapr 控制平面的 Sentry 服务对 Dapr 实例之间的通信进行传输加密。Sentry 服务是一个中央证书颁发机构 (CA)。
Dapr 允许操作员和开发人员使用自己的证书,或者让 Dapr 自动创建并保存自签名的根证书和颁发者证书。
有关 mTLS 的详细信息,请阅读安全概念部分。
如果没有提供自定义证书,Dapr 会自动创建并保存有效期为一年的自签名证书。 在 Kubernetes 中,证书会保存到 Dapr 系统 pod 所在命名空间的 secret 中,仅对它们可访问。 在自托管模式中,证书会保存到磁盘。
控制平面 Sentry 服务配置
mTLS 设置位于 Dapr 控制平面配置文件中。例如,当您将 Dapr 控制平面部署到 Kubernetes 时,此配置文件会自动创建,然后您可以编辑它。以下文件显示了在 daprsystem
命名空间中部署的配置资源中可用的 mTLS 设置:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "24h"
allowedClockSkew: "15m"
此文件显示了默认的 daprsystem
配置设置。下面的示例向您展示如何在 Kubernetes 和自托管模式下更改和应用此配置到控制平面 Sentry 服务。
Kubernetes
使用配置资源设置 mTLS
在 Kubernetes 中,Dapr 创建了一个启用 mTLS 的默认控制平面配置资源。
Sentry 服务,即证书颁发机构系统 pod,可以通过 Helm 和 Dapr CLI 使用 dapr init --kubernetes
安装。
您可以使用以下命令查看控制平面配置资源:
kubectl get configurations/daprsystem --namespace <DAPR_NAMESPACE> -o yaml
要对控制平面配置资源进行更改,请运行以下命令进行编辑:
kubectl edit configurations/daprsystem --namespace <DAPR_NAMESPACE>
保存更改后,对控制平面执行滚动更新:
kubectl rollout restart deploy/dapr-sentry -n <DAPR_NAMESPACE>
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
注意:控制平面 sidecar 注入器服务不需要重新部署
使用 Helm 禁用 mTLS
控制平面将继续使用 mTLS
kubectl create ns dapr-system
helm install \
--set global.mtls.enabled=false \
--namespace dapr-system \
dapr \
dapr/dapr
使用 CLI 禁用 mTLS
控制平面将继续使用 mTLS
dapr init --kubernetes --enable-mtls=false
查看日志
要查看 Sentry 服务日志,请运行以下命令:
kubectl logs --selector=app=dapr-sentry --namespace <DAPR_NAMESPACE>
使用您自己的证书
使用 Helm,您可以提供 PEM 编码的根证书、颁发者证书和私钥,这些将被填充到 Sentry 服务使用的 Kubernetes secret 中。
避免停机
为了避免在轮换过期证书时停机,请始终使用相同的私有根密钥签署您的证书。注意:此示例使用 OpenSSL 命令行工具,这是一个广泛分发的软件包,可以通过包管理器轻松安装在 Linux 上。在 Windows 上可以使用 chocolatey 安装 OpenSSL。在 MacOS 上可以使用 brew 安装 brew install openssl
创建用于生成证书的配置文件,这是生成带有 SAN(主题备用名称)扩展字段的 v3 证书所必需的。首先将以下内容保存到名为 root.conf
的文件中:
[req]
distinguished_name = req_distinguished_name
x509_extensions = v3_req
prompt = no
[req_distinguished_name]
C = US
ST = VA
L = Daprville
O = dapr.io/sentry
OU = dapr.io/sentry
CN = cluster.local
[v3_req]
basicConstraints = critical, CA:true
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
[alt_names]
DNS.1 = cluster.local
对 issuer.conf
重复此操作,将相同的内容粘贴到文件中,但在 basicConstraints 行的末尾添加 pathlen:0
,如下所示:
basicConstraints = critical, CA:true, pathlen:0
运行以下命令生成根证书和密钥
# 跳过以下行以重用现有的根密钥,这是轮换过期证书所需的
openssl ecparam -genkey -name prime256v1 | openssl ec -out root.key
openssl req -new -nodes -sha256 -key root.key -out root.csr -config root.conf -extensions v3_req
openssl x509 -req -sha256 -days 365 -in root.csr -signkey root.key -outform PEM -out root.pem -extfile root.conf -extensions v3_req
接下来运行以下命令生成颁发者证书和密钥:
# 跳过以下行以重用现有的颁发者密钥,这是轮换过期证书所需的
openssl ecparam -genkey -name prime256v1 | openssl ec -out issuer.key
openssl req -new -sha256 -key issuer.key -out issuer.csr -config issuer.conf -extensions v3_req
openssl x509 -req -in issuer.csr -CA root.pem -CAkey root.key -CAcreateserial -outform PEM -out issuer.pem -days 365 -sha256 -extfile issuer.conf -extensions v3_req
安装 Helm 并通过配置将根证书、颁发者证书和颁发者密钥传递给 Sentry:
kubectl create ns dapr-system
helm install \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
使用 CLI 升级根和颁发者证书(推荐)
以下 CLI 命令可用于更新 Kubernetes 集群中的根和颁发者证书。
生成全新的证书
- 下面的命令生成全新的根和颁发者证书,由新生成的私有根密钥签名。
注意:必须重启
Dapr sentry 服务
以及其余的控制平面服务,以便它们能够读取新证书。这可以通过向命令提供--restart
标志来完成。
dapr mtls renew-certificate -k --valid-until <days> --restart
- 下面的命令生成全新的根和颁发者证书,由提供的私有根密钥签名。
注意:如果您现有的已部署证书是由此相同的私有根密钥签名的,则
Dapr Sentry 服务
可以在不重启的情况下读取这些新证书。
dapr mtls renew-certificate -k --private-key <private_key_file_path> --valid-until <days>
使用提供的自定义证书更新证书
要更新 Kubernetes 集群中提供的证书,可以使用以下 CLI 命令。
注意 - 它不支持
valid-until
标志来指定新证书的有效期。
dapr mtls renew-certificate -k --ca-root-certificate <ca.crt> --issuer-private-key <issuer.key> --issuer-public-certificate <issuer.crt> --restart
重启 Dapr 启用的 pod
无论使用哪个命令更新证书,您都必须重启所有 Dapr 启用的 pod。 由于证书不匹配,您可能会在所有部署成功重启之前经历一些停机时间。推荐的方法是对您的部署执行滚动重启:
kubectl rollout restart deploy/myapp
使用 Kubectl 更新根或颁发者证书
如果根或颁发者证书即将过期,您可以更新它们并重启所需的系统服务。
在轮换证书时避免停机
为了避免在轮换过期证书时停机,您的新证书必须使用与先前证书相同的私有根密钥签名。这目前无法使用 Dapr 生成的自签名证书实现。Dapr 生成的自签名证书
- 清除现有的 Dapr 信任包 secret,将以下 YAML 保存到文件(例如
clear-trust-bundle.yaml
)并应用此 secret。
apiVersion: v1
kind: Secret
metadata:
name: dapr-trust-bundle
labels:
app: dapr-sentry
data:
kubectl apply -f `clear-trust-bundle.yaml` -n <DAPR_NAMESPACE>
- 重启 Dapr Sentry 服务。这将生成一个新的证书包并更新
dapr-trust-bundle
Kubernetes secret。
kubectl rollout restart -n <DAPR_NAMESPACE> deployment/dapr-sentry
- 一旦 Sentry 服务已重启,重启其余的 Dapr 控制平面以获取新的 Dapr 信任包。
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
- 重启您的 Dapr 应用程序以获取最新的信任包。
启用 mTLS 时可能导致应用程序停机。
使用 mTLS 进行服务调用的部署重启将失败,直到被调用的服务也已重启(从而加载新的 Dapr 信任包)。此外,placement 服务将无法分配新的 actor(而现有的 actor 不受影响),直到应用程序已重启以加载新的 Dapr 信任包。kubectl rollout restart deployment/mydaprservice1 kubectl deployment/myotherdaprservice2
自定义证书(自带)
首先,使用上面使用您自己的证书中的步骤颁发新证书。
现在您有了新证书,使用 Helm 升级证书:
helm upgrade \
--set-file dapr_sentry.tls.issuer.certPEM=issuer.pem \
--set-file dapr_sentry.tls.issuer.keyPEM=issuer.key \
--set-file dapr_sentry.tls.root.certPEM=root.pem \
--namespace dapr-system \
dapr \
dapr/dapr
或者,您可以更新保存它们的 Kubernetes secret:
kubectl edit secret dapr-trust-bundle -n <DAPR_NAMESPACE>
用新证书的相应值替换 Kubernetes secret 中的 ca.crt
、issuer.crt
和 issuer.key
键。
注意:这些值必须是 base64 编码的
如果您使用相同的私有密钥签署了新的证书根,Dapr Sentry 服务将自动获取新证书。您可以使用 kubectl rollout restart
重启您的应用程序部署而不会停机。无需一次性重启所有部署,只要在原始证书过期之前重启即可。
如果您使用不同的私有密钥签署了新的证书根,您必须重启 Dapr Sentry 服务,然后是其余的 Dapr 控制平面服务。
kubectl rollout restart deploy/dapr-sentry -n <DAPR_NAMESPACE>
一旦 Sentry 完全重启,运行:
kubectl rollout restart deploy/dapr-operator -n <DAPR_NAMESPACE>
kubectl rollout restart statefulsets/dapr-placement-server -n <DAPR_NAMESPACE>
接下来,您必须重启所有 Dapr 启用的 pod。 推荐的方法是对您的部署执行滚动重启:
kubectl rollout restart deploy/myapp
由于证书不匹配,您将经历潜在的停机,直到所有部署成功重启(从而加载新的 Dapr 证书)。
Kubernetes 视频演示
观看此视频以了解如何在 Kubernetes 上更新 mTLS 证书
设置 Dapr 控制平面 mTLS 证书过期的监控
从 mTLS 根证书过期前 30 天开始,Dapr sentry 服务将每小时发出警告级别日志,指示根证书即将过期。
作为在生产中运行 Dapr 的操作最佳实践,我们建议为这些特定的 sentry 服务日志配置监控,以便您了解即将到来的证书过期。
"Dapr root certificate expiration warning: certificate expires in 2 days and 15 hours"
一旦证书过期,您将看到以下消息:
"Dapr root certificate expiration warning: certificate has expired."
在 Kubernetes 中,您可以这样查看 sentry 服务日志:
kubectl logs deployment/dapr-sentry -n dapr-system
日志输出将如下所示:"
{"instance":"dapr-sentry-68cbf79bb9-gdqdv","level":"warning","msg":"Dapr root certificate expiration warning: certificate expires in 2 days and 15 hours","scope":"dapr.sentry","time":"2022-04-01T23:43:35.931825236Z","type":"log","ver":"1.6.0"}
作为提醒您即将到来的证书过期的额外工具,从 1.7.0 版本开始,CLI 现在在您与基于 Kubernetes 的部署交互时打印证书过期状态。
示例:
dapr status -k
NAME NAMESPACE HEALTHY STATUS REPLICAS VERSION AGE CREATED
dapr-sentry dapr-system True Running 1 1.7.0 17d 2022-03-15 09:29.45
dapr-dashboard dapr-system True Running 1 0.9.0 17d 2022-03-15 09:29.45
dapr-sidecar-injector dapr-system True Running 1 1.7.0 17d 2022-03-15 09:29.45
dapr-operator dapr-system True Running 1 1.7.0 17d 2022-03-15 09:29.45
dapr-placement-server dapr-system True Running 1 1.7.0 17d 2022-03-15 09:29.45
⚠ Dapr root certificate of your Kubernetes cluster expires in 2 days. Expiry date: Mon, 04 Apr 2022 15:01:03 UTC.
请参阅 docs.dapr.io 以获取证书更新说明,以避免服务中断。
自托管
运行控制平面 Sentry 服务
为了运行 Sentry 服务,您可以从这里下载源代码或发布的二进制文件。
在从源代码构建时,请参考此指南了解如何构建 Dapr。
其次,为 Sentry 服务创建一个目录以创建自签名的根证书:
mkdir -p $HOME/.dapr/certs
使用以下命令在本地运行 Sentry 服务:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
如果成功,Sentry 服务将运行并在给定目录中创建根证书。 此命令使用默认配置值,因为没有给定自定义配置文件。请参阅下文了解如何使用自定义配置启动 Sentry 服务。
使用配置资源设置 mTLS
Dapr 实例配置
在自托管模式下运行 Dapr 时,默认情况下禁用 mTLS。您可以通过创建以下配置文件来启用它:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
除了 Dapr 配置,您还需要为每个 Dapr sidecar 实例提供 TLS 证书。您可以在运行 Dapr 实例之前设置以下环境变量来实现:
export DAPR_TRUST_ANCHORS=`cat $HOME/.dapr/certs/ca.crt`
export DAPR_CERT_CHAIN=`cat $HOME/.dapr/certs/issuer.crt`
export DAPR_CERT_KEY=`cat $HOME/.dapr/certs/issuer.key`
export NAMESPACE=default
$env:DAPR_TRUST_ANCHORS=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\ca.crt)
$env:DAPR_CERT_CHAIN=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.crt)
$env:DAPR_CERT_KEY=$(Get-Content -raw $env:USERPROFILE\.dapr\certs\issuer.key)
$env:NAMESPACE="default"
如果使用 Dapr CLI,请将 Dapr 指向上面的配置文件以启用 mTLS 运行 Dapr 实例:
dapr run --app-id myapp --config ./config.yaml node myapp.js
如果直接使用 daprd
,请使用以下标志启用 mTLS:
daprd --app-id myapp --enable-mtls --sentry-address localhost:50001 --config=./config.yaml
Sentry 服务配置
以下是一个 Sentry 配置示例,将工作负载证书 TTL 更改为 25 秒:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: daprsystem
namespace: default
spec:
mtls:
enabled: true
workloadCertTTL: "25s"
为了使用自定义配置启动 Sentry 服务,请使用以下标志:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=./config.yaml
使用您自己的证书
为了提供您自己的凭据,请创建 ECDSA PEM 编码的根和颁发者证书并将它们放置在文件系统上。
使用 --issuer-credentials
标志告诉 Sentry 服务从哪里加载证书。
下一个示例创建根和颁发者证书并将它们加载到 Sentry 服务中。
注意:此示例使用 step 工具创建证书。您可以从这里安装 step 工具。Windows 二进制文件可从这里获得
创建根证书:
step certificate create cluster.local ca.crt ca.key --profile root-ca --no-password --insecure
创建颁发者证书:
step certificate create cluster.local issuer.crt issuer.key --ca ca.crt --ca-key ca.key --profile intermediate-ca --not-after 8760h --no-password --insecure
这将创建根和颁发者证书和密钥。
将 ca.crt
、issuer.crt
和 issuer.key
放在所需路径中(以下示例中为 $HOME/.dapr/certs
),并启动 Sentry:
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local
更新根或颁发者证书
如果根或颁发者证书即将过期,您可以更新它们并重启所需的系统服务。
要让 Dapr 生成新证书,请删除现有的 $HOME/.dapr/certs
证书并重启 sentry 服务以生成新证书。
./sentry --issuer-credentials $HOME/.dapr/certs --trust-domain cluster.local --config=./config.yaml
要替换为您自己的证书,请首先使用上面使用您自己的证书中的步骤生成新证书。
将 ca.crt
、issuer.crt
和 issuer.key
复制到每个配置的系统服务的文件系统路径,并重启进程或容器。
默认情况下,系统服务将在 /var/run/dapr/credentials
中查找凭据。上面的示例使用 $HOME/.dapr/certs
作为自定义位置。
注意:如果您使用不同的私有密钥签署了证书根,请重启 Dapr 实例。
社区通话视频关于证书轮换
观看此视频以了解如何在证书即将过期时执行证书轮换。
Sentry 令牌验证器
令牌通常用于身份验证和授权目的。 令牌验证器是负责验证这些令牌的有效性和真实性的组件。 例如,在 Kubernetes 环境中,一种常见的令牌验证方法是通过 Kubernetes 绑定服务帐户机制。 此验证器检查绑定服务帐户令牌以确保其合法性。
Sentry 服务可以配置为:
- 启用除 Kubernetes 绑定服务帐户验证器之外的额外令牌验证器
- 替换自托管模式下默认启用的
insecure
验证器
Sentry 令牌验证器用于将额外的非 Kubernetes 客户端加入到以 Kubernetes 模式运行的 Dapr 集群中,或替换自托管模式下的不安全“允许所有”验证器以启用适当的身份验证。 除非您使用的是特殊的部署场景,否则不需要配置令牌验证器。
当前唯一支持的令牌验证器是
jwks
验证器。
JWKS
jwks
验证器使 Sentry 服务能够使用 JWKS 端点验证 JWT 令牌。
令牌的内容_必须_包含与 Dapr 客户端的 SPIFFE 身份匹配的 sub
声明,格式为 spiffe://<trust-domain>/ns/<namespace>/<app-id>
。
令牌的受众必须是 Sentry 身份的 SPIFFE ID,例如 spiffe://cluster.local/ns/dapr-system/dapr-sentry
。
其他基本的 JWT 规则,如签名、过期等也适用。
jwks
验证器可以接受远程源以获取公钥列表或公钥的静态数组。
以下配置启用具有远程源的 jwks
令牌验证器。
此远程源使用 HTTPS,因此 caCertificate
字段包含远程源的信任根。
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: "https://localhost:1234/"
caCertificate: "<optional ca certificate bundle string>"
以下配置启用具有公钥静态数组的 jwks
令牌验证器。
kind: Configuration
apiVersion: dapr.io/v1alpha1
metadata:
name: sentryconfig
spec:
mtls:
enabled: true
tokenValidators:
- name: jwks
options:
minRefreshInterval: 2m
requestTimeout: 1m
source: |
{"keys":[ "12345.." ]}
5.2 - 使用 OAuth 配置端点授权
Dapr 的 OAuth 2.0 中间件允许您在 Dapr 端点上为 Web API 启用 OAuth 授权,支持 授权码模式。您还可以将授权令牌注入到端点 API 中,这些令牌可用于通过 客户端凭证模式对 API 调用的外部 API 进行授权。启用中间件后,所有通过 Dapr 的方法调用在传递给用户代码之前都需要进行授权。
这两种模式的主要区别在于,授权码模式
需要用户交互并授权用户,而客户端凭证模式
不需要用户交互,授权的是服务或应用程序。
在授权服务器上注册您的应用程序
不同的授权服务器提供不同的应用程序注册体验。以下是一些示例:
要配置 Dapr OAuth 中间件,您需要收集以下信息:
一些流行的授权服务器的授权/令牌 URL:
定义中间件组件
定义授权码模式组件
OAuth 中间件(授权码模式)由以下组件定义:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: oauth2
namespace: default
spec:
type: middleware.http.oauth2
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "<comma-separated scope names>"
- name: authURL
value: "<authorization URL>"
- name: tokenURL
value: "<token exchange URL>"
- name: redirectURL
value: "<redirect URL>"
- name: authHeaderName
value: "<header name under which the secret token is saved>"
- name: forceHTTPS
value: "<set to true if you invoke an API method through Dapr from https origin>"
为授权码模式定义自定义管道
要使用 OAuth 中间件(授权码模式),您需要使用 Dapr 配置 创建一个 自定义管道,如下所示:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
- name: oauth2
type: middleware.http.oauth2
定义客户端凭证模式组件
OAuth(客户端凭证模式)中间件由以下组件定义:
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: myComponent
spec:
type: middleware.http.oauth2clientcredentials
version: v1
metadata:
- name: clientId
value: "<your client ID>"
- name: clientSecret
value: "<your client secret>"
- name: scopes
value: "<comma-separated scope names>"
- name: tokenURL
value: "<token issuing URL>"
- name: headerName
value: "<header name under which the secret token is saved>"
- name: endpointParamsQuery
value: "<list of additional key=value settings separated by ampersands or semicolons forwarded to the token issuing service>"
- name: authStyle
value: "<see comment>"
为客户端凭证模式定义自定义管道
要使用 OAuth 中间件(客户端凭证模式),您需要使用 Dapr 配置 创建一个 自定义管道,如下所示:
apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
name: pipeline
namespace: default
spec:
httpPipeline:
handlers:
- name: myComponent
type: middleware.http.oauth2clientcredentials
应用配置
要将上述配置(无论授权类型)应用到您的 Dapr sidecar,请在您的 pod 规范中添加一个 dapr.io/config
注释:
apiVersion: apps/v1
kind: Deployment
...
spec:
...
template:
metadata:
...
annotations:
dapr.io/enabled: "true"
...
dapr.io/config: "pipeline"
...
访问访问令牌
授权码模式
配置完成后,每当客户端尝试通过 Dapr sidecar 调用 API 方法时(例如调用 v1.0/invoke/ 端点),如果未找到访问令牌,客户端将被重定向到授权同意页面。否则,访问令牌将写入 authHeaderName 头中,供应用程序代码使用。
客户端凭证模式
配置完成后,每当客户端尝试通过 Dapr sidecar 调用 API 方法时(例如调用 v1.0/invoke/ 端点),如果未找到现有的有效令牌,将检索一个新的访问令牌。访问令牌将写入 headerName 头中,供应用程序代码使用。这样,应用程序可以在调用请求该令牌的外部 API 时在授权头中转发令牌。
5.3 - 在 Dapr 中启用 API 令牌认证
默认情况下,Dapr 通过网络边界限制对其公共 API 的访问。如果您计划在该边界之外公开 Dapr API,或者您的部署需要额外的安全级别,请考虑为 Dapr API 启用令牌认证。这意味着 Dapr 将要求每个传入的 gRPC 和 HTTP 请求在通过之前包含认证令牌。
创建令牌
Dapr 通过共享令牌进行 API 认证。您可以自由定义要使用的 API 令牌。
虽然 Dapr 对共享令牌的格式没有具体要求,但一个好的做法是生成一个随机字节序列并将其编码为 Base64。例如,以下命令生成一个随机的 32 字节密钥并将其编码为 Base64:
openssl rand 16 | base64
在 Dapr 中配置 API 令牌认证
对于 Kubernetes 或自托管 Dapr 部署,令牌认证配置略有不同:
自托管
在自托管场景中,Dapr 会检查 DAPR_API_TOKEN
环境变量是否存在。如果在 daprd
进程启动时设置了该环境变量,Dapr 将对其公共 API 强制执行认证:
export DAPR_API_TOKEN=<token>
要更新配置的令牌,请将 DAPR_API_TOKEN
环境变量更新为新值并重新启动 daprd
进程。
Kubernetes
在 Kubernetes 部署中,Dapr 使用 Kubernetes secret 存储来保存共享令牌。要配置 Dapr API 认证,首先创建一个新的 secret:
kubectl create secret generic dapr-api-token --from-literal=token=<token>
注意,您需要在每个希望启用 Dapr 令牌认证的命名空间中创建上述 secret。
要指示 Dapr 使用该 secret 来保护其公共 API,请在您的 Deployment 模板规范中添加一个注释:
annotations:
dapr.io/enabled: "true"
dapr.io/api-token-secret: "dapr-api-token" # Kubernetes secret 的名称
部署时,Dapr sidecar 注入器将自动创建一个 secret 引用并将实际值注入 DAPR_API_TOKEN
环境变量。
更新令牌
自托管
要在自托管中更新配置的令牌,请将 DAPR_API_TOKEN
环境变量更新为新值并重新启动 daprd
进程。
Kubernetes
要在 Kubernetes 中更新配置的令牌,请在每个命名空间中使用新令牌更新先前创建的 secret。您可以使用 kubectl patch
命令执行此操作,但在每个命名空间中更新这些的更简单方法是使用清单:
apiVersion: v1
kind: Secret
metadata:
name: dapr-api-token
type: Opaque
data:
token: <your-new-token>
然后将其应用到每个命名空间:
kubectl apply --file token-secret.yaml --namespace <namespace-name>
要让 Dapr 开始使用新令牌,请触发对每个部署的滚动升级:
kubectl rollout restart deployment/<deployment-name> --namespace <namespace-name>
假设您的服务配置了多个副本,密钥更新过程不会导致任何停机时间。
向客户端 API 调用添加 API 令牌
一旦在 Dapr 中配置了令牌认证,所有调用 Dapr API 的客户端都需要在每个请求中附加 dapr-api-token
令牌。
注意: Dapr SDK 会读取 DAPR_API_TOKEN 环境变量并默认为您设置。

HTTP
在 HTTP 的情况下,Dapr 要求在 dapr-api-token
头中提供 API 令牌。例如:
GET http://<daprAddress>/v1.0/metadata
dapr-api-token: <token>
使用 curl,您可以使用 --header
(或 -H
)选项传递头。例如:
curl http://localhost:3500/v1.0/metadata \
--header "dapr-api-token: my-token"
gRPC
使用 gRPC 协议时,Dapr 将在 gRPC 元数据中检查传入调用的 API 令牌:
dapr-api-token[0].
从应用访问令牌
Kubernetes
在 Kubernetes 中,建议将 secret 挂载到您的 pod 作为环境变量,如下例所示,其中名为 dapr-api-token
的 Kubernetes secret 用于保存令牌。
containers:
- name: mycontainer
image: myregistry/myapp
envFrom:
- secretRef:
name: dapr-api-token
自托管
在自托管模式下,您可以将令牌设置为应用的环境变量:
export DAPR_API_TOKEN=<my-dapr-token>
相关链接
5.4 - 使用令牌认证对Dapr请求进行身份验证
对于一些构建块,例如pubsub、service-invocation和输入bindings,Dapr与应用程序通过HTTP或gRPC进行通信。 为了让应用程序能够验证来自Dapr sidecar的请求,您可以配置Dapr在HTTP请求的头部或gRPC请求的元数据中发送一个API令牌。
创建令牌
Dapr使用共享令牌进行API认证。您可以自由定义API令牌。
虽然Dapr对共享令牌没有强制格式,但一个好的做法是生成一个随机字节序列并将其编码为Base64。例如,这个命令生成一个随机的32字节密钥并将其编码为Base64:
openssl rand 16 | base64
在Dapr中配置应用API令牌认证
令牌认证配置在Kubernetes或selfhosted Dapr部署中略有不同:
Selfhosted
在selfhosted场景中,Dapr会检查APP_API_TOKEN
环境变量是否存在。如果在daprd
进程启动时设置了该环境变量,Dapr在调用应用程序时会包含该令牌:
export APP_API_TOKEN=<token>
要更新配置的令牌,修改APP_API_TOKEN
环境变量为新值并重启daprd
进程。
Kubernetes
在Kubernetes部署中,Dapr使用Kubernetes secrets存储来保存共享令牌。首先,创建一个新的secret:
kubectl create secret generic app-api-token --from-literal=token=<token>
注意,您需要在每个希望启用应用令牌认证的命名空间中创建上述secret
要指示Dapr在向应用程序发送请求时使用secret中的令牌,请在您的Deployment模板规范中添加一个注解:
annotations:
dapr.io/enabled: "true"
dapr.io/app-token-secret: "app-api-token" # Kubernetes secret的名称
部署时,Dapr Sidecar Injector会自动创建一个secret引用并将实际值注入到APP_API_TOKEN
环境变量中。
轮换令牌
Selfhosted
要在selfhosted中更新配置的令牌,修改APP_API_TOKEN
环境变量为新值并重启daprd
进程。
Kubernetes
要在Kubernetes中更新配置的令牌,修改之前创建的secret中的新令牌在每个命名空间中。您可以使用kubectl patch
命令来完成此操作,但更简单的方法是使用清单更新这些:
apiVersion: v1
kind: Secret
metadata:
name: app-api-token
type: Opaque
data:
token: <your-new-token>
然后将其应用到每个命名空间:
kubectl apply --file token-secret.yaml --namespace <namespace-name>
要让Dapr开始使用新令牌,请触发对每个部署的滚动升级:
kubectl rollout restart deployment/<deployment-name> --namespace <namespace-name>
假设您的服务配置了多个副本,密钥轮换过程不会导致任何停机。
验证来自Dapr的请求
一旦使用环境变量或Kubernetes secret app-api-token
配置了应用令牌认证,Dapr sidecar在调用应用程序时总是会在HTTP头部或gRPC元数据中包含dapr-api-token: <token>
。从应用程序端,确保您使用dapr-api-token
值进行认证,该值使用您设置的app-api-token
来验证来自Dapr的请求。

HTTP
在您的代码中,查找传入请求中的HTTP头部dapr-api-token
:
dapr-api-token: <token>
gRPC
使用gRPC协议时,检查传入调用中的gRPC元数据中的API令牌:
dapr-api-token[0].
从应用程序访问令牌
Kubernetes
在Kubernetes中,建议将secret挂载到您的pod作为环境变量。
假设我们创建了一个名为app-api-token
的secret来保存令牌:
containers:
- name: mycontainer
image: myregistry/myapp
envFrom:
- secretRef:
name: app-api-token
Selfhosted
在selfhosted模式中,您可以将令牌设置为应用程序的环境变量:
export APP_API_TOKEN=<my-app-token>
相关链接
6 - 通过弹性策略实现错误恢复
6.1 - 概述
Dapr 提供了一种通过弹性规范来定义和应用容错策略的功能。弹性规范与组件规范存放在同一位置,并在 Dapr sidecar 启动时生效。sidecar 决定如何将这些策略应用于您的 Dapr API 调用。在自托管模式下,弹性规范文件必须命名为 resiliency.yaml
。在 Kubernetes 中,Dapr 会找到您的应用程序使用的命名弹性规范。在弹性规范中,您可以定义常见的弹性模式策略,例如:
这些策略可以应用于目标,包括:
此外,弹性策略还可以限定到特定应用程序。
演示视频
了解更多关于如何使用 Dapr 编写弹性微服务。
弹性策略结构
以下是弹性策略的一般结构:
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: myresiliency
scopes:
# 可选地将策略限定到特定应用程序
spec:
policies:
timeouts:
# 超时策略定义
retries:
# 重试策略定义
circuitBreakers:
# 断路器策略定义
targets:
apps:
# 应用程序及其应用的策略
actors:
# actor 类型及其应用的策略
components:
# 组件及其应用的策略
完整示例策略
apiVersion: dapr.io/v1alpha1
kind: Resiliency
metadata:
name: myresiliency
# 类似于订阅和配置规范,scopes 列出了可以使用此弹性规范的 Dapr 应用程序 ID。
scopes:
- app1
- app2
spec:
# policies 是定义超时、重试和断路器策略的地方。
# 每个策略都有一个名称,以便可以在弹性规范的 targets 部分引用。
policies:
# 超时是简单的命名持续时间。
timeouts:
general: 5s
important: 60s
largeResponse: 10s
# 重试是重试配置的命名模板,并在操作的生命周期内实例化。
retries:
pubsubRetry:
policy: constant
duration: 5s
maxRetries: 10
retryForever:
policy: exponential
maxInterval: 15s
maxRetries: -1 # 无限重试
important:
policy: constant
duration: 5s
maxRetries: 30
someOperation:
policy: exponential
maxInterval: 15s
largeResponse:
policy: constant
duration: 5s
maxRetries: 3
# 断路器会自动为每个组件和应用实例创建。
# 断路器维护的计数器在 Dapr sidecar 运行期间存在。它们不会被持久化。
circuitBreakers:
simpleCB:
maxRequests: 1
timeout: 30s
trip: consecutiveFailures >= 5
pubsubCB:
maxRequests: 1
interval: 8s
timeout: 45s
trip: consecutiveFailures > 8
# targets 是应用命名策略的对象。Dapr 支持 3 种目标类型 - 应用程序、组件和 actor
targets:
apps:
appB:
timeout: general
retry: important
# 服务的断路器是按应用实例限定的。
# 当断路器被触发时,该路由将从负载均衡中移除,持续配置的 `timeout` 时间。
circuitBreaker: simpleCB
actors:
myActorType: # 自定义 actor 类型名称
timeout: general
retry: important
# actor 的断路器可以按类型、ID 或两者限定。
# 当断路器被触发时,该类型或 ID 将从配置表中移除,持续配置的 `timeout` 时间。
circuitBreaker: simpleCB
circuitBreakerScope: both ##
circuitBreakerCacheSize: 5000
components:
# 对于状态存储,策略适用于保存和检索状态。
statestore1: # 任何组件名称 -- 这里是一个状态存储
outbound:
timeout: general
retry: retryForever
# 组件的断路器是按组件配置/实例限定的。例如 myRediscomponent。
# 当此断路器被触发时,所有与该组件的交互将在配置的 `timeout` 时间内被阻止。
circuitBreaker: simpleCB
pubsub1: # 任何组件名称 -- 这里是一个 pubsub broker
outbound:
retry: pubsubRetry
circuitBreaker: pubsubCB
pubsub2: # 任何组件名称 -- 这里是另一个 pubsub broker
outbound:
retry: pubsubRetry
circuitBreaker: pubsubCB
inbound: # inbound 仅适用于从 sidecar 到应用程序的传递
timeout: general
retry: important
circuitBreaker: pubsubCB
相关链接
观看此视频以了解如何使用弹性:
下一步
了解更多关于弹性策略和目标:
6.2 - 弹性策略
在 policies
下定义超时、重试和断路器策略。每个策略都有一个名称,以便您可以在弹性规范的 targets
部分中引用它们。
注意:Dapr 为某些 API 提供默认的重试机制。请参阅此处了解如何使用用户定义的重试策略覆盖默认重试逻辑。
超时
超时是可选策略,用于提前终止长时间运行的操作。如果超过了超时时间:
- 正在进行的操作将被终止(如果可能)。
- 返回错误。
有效值是 Go 的 time.ParseDuration 接受的格式,例如:15s
、2m
、1h30m
。超时没有设置最大值。
示例:
spec:
policies:
# 超时是简单的命名持续时间。
timeouts:
general: 5s
important: 60s
largeResponse: 10s
如果未指定超时值,则策略不会强制执行时间限制,默认使用请求客户端设置的任何值。
重试
通过 retries
,您可以为失败的操作定义重试策略,包括由于触发定义的超时或断路器策略而失败的请求。
Pub/sub 组件重试与入站弹性
每个 pub/sub 组件 都有其内置的重试行为。显式应用 Dapr 弹性策略不会覆盖这些内置重试机制。相反,重试策略补充了内置重试机制,这可能导致消息的重复聚集。以下重试选项是可配置的:
重试选项 | 描述 |
---|---|
policy | 确定退避和重试间隔策略。有效值为 constant 和 exponential 。默认为 constant 。 |
duration | 确定重试之间的时间间隔。仅适用于 constant 策略。有效值为 200ms 、15s 、2m 等格式。默认为 5s 。 |
maxInterval | 确定 exponential 退避策略可以增长到的最大间隔。额外的重试总是在 maxInterval 的持续时间之后发生。默认为 60s 。有效值为 5s 、1m 、1m30s 等格式。 |
maxRetries | 尝试的最大重试次数。-1 表示无限次重试,而 0 表示请求不会被重试(本质上表现为未设置重试策略)。默认为 -1 。 |
matching.httpStatusCodes | 可选:要重试的 HTTP 状态代码或代码范围的逗号分隔字符串。未列出的状态代码不重试。 有效值:100-599,参考 格式: <code> 或范围 <start>-<end> 示例:“429,501-503” 默认:空字符串 "" 或字段未设置。重试所有 HTTP 错误。 |
matching.gRPCStatusCodes | 可选:要重试的 gRPC 状态代码或代码范围的逗号分隔字符串。未列出的状态代码不重试。 有效值:0-16,参考 格式: <code> 或范围 <start>-<end> 示例:“1,501-503” 默认:空字符串 "" 或字段未设置。重试所有 gRPC 错误。 |
httpStatusCodes 和 gRPCStatusCodes 格式
字段值应遵循字段描述中指定的格式或下面的“示例 2”中的格式。 格式不正确的值将产生错误日志(“无法读取弹性策略”),并且daprd
启动序列将继续。指数退避窗口使用以下公式:
BackOffDuration = PreviousBackOffDuration * (随机值从 0.5 到 1.5) * 1.5
if BackOffDuration > maxInterval {
BackoffDuration = maxInterval
}
示例:
spec:
policies:
# 重试是重试配置的命名模板,并在操作的生命周期内实例化。
retries:
pubsubRetry:
policy: constant
duration: 5s
maxRetries: 10
retryForever:
policy: exponential
maxInterval: 15s
maxRetries: -1 # 无限重试
示例 2:
spec:
policies:
retries:
retry5xxOnly:
policy: constant
duration: 5s
maxRetries: 3
matching:
httpStatusCodes: "429,500-599" # 重试此范围内的 HTTP 状态代码。所有其他不重试。
gRPCStatusCodes: "1-4,8-11,13,14" # 重试这些范围内的 gRPC 状态代码并分隔单个代码。
断路器
断路器(CB)策略用于当其他应用程序/服务/组件经历较高的失败率时。CB 监控请求,并在满足某个条件时关闭所有流向受影响服务的流量(“打开”状态)。通过这样做,CB 给服务时间从其故障中恢复,而不是用事件淹没它。CB 还可以允许部分流量通过,以查看系统是否已恢复(“半开”状态)。一旦请求恢复成功,CB 进入“关闭”状态并允许流量完全恢复。
重试选项 | 描述 |
---|---|
maxRequests | 在 CB 半开(从故障中恢复)时允许通过的最大请求数。默认为 1 。 |
interval | CB 用于清除其内部计数的周期性时间段。如果设置为 0 秒,则永不清除。默认为 0s 。 |
timeout | 开放状态(直接在故障后)到 CB 切换到半开的时间段。默认为 60s 。 |
trip | 由 CB 评估的 通用表达式语言(CEL) 语句。当语句评估为 true 时,CB 触发并变为打开。默认为 consecutiveFailures > 5 。其他可能的值是 requests 和 totalFailures ,其中 requests 表示电路打开之前的成功或失败调用次数,totalFailures 表示电路打开之前的总失败尝试次数(不一定是连续的)。示例:requests > 5 和 totalFailures >3 。 |
示例:
spec:
policies:
circuitBreakers:
pubsubCB:
maxRequests: 1
interval: 8s
timeout: 45s
trip: consecutiveFailures > 8
覆盖默认重试
Dapr 为任何不成功的请求(如失败和瞬态错误)提供默认重试。在弹性规范中,您可以通过定义具有保留名称关键字的策略来覆盖 Dapr 的默认重试逻辑。例如,定义名为 DaprBuiltInServiceRetries
的策略,覆盖通过服务到服务请求的 sidecar 之间的失败的默认重试。策略覆盖不适用于特定目标。
注意:尽管您可以使用更强大的重试覆盖默认值,但您不能使用比提供的默认值更低的值覆盖,或完全删除默认重试。这可以防止意外停机。
下面是描述 Dapr 默认重试和覆盖它们的策略关键字的表格:
功能 | 覆盖关键字 | 默认重试行为 | 描述 |
---|---|---|---|
服务调用 | DaprBuiltInServiceRetries | 每次调用重试以 1 秒的退避间隔执行,最多达到 3 次的阈值。 | sidecar 到 sidecar 请求(服务调用方法调用)失败并导致 gRPC 代码 Unavailable 或 Unauthenticated |
actor | DaprBuiltInActorRetries | 每次调用重试以 1 秒的退避间隔执行,最多达到 3 次的阈值。 | sidecar 到 sidecar 请求(actor 方法调用)失败并导致 gRPC 代码 Unavailable 或 Unauthenticated |
actor 提醒 | DaprBuiltInActorReminderRetries | 每次调用重试以指数退避执行,初始间隔为 500ms,最多 60s,持续 15 分钟 | 请求失败将 actor 提醒持久化到状态存储 |
初始化重试 | DaprBuiltInInitializationRetries | 每次调用重试 3 次,指数退避,初始间隔为 500ms,持续 10s | 向应用程序发出请求以检索给定规范时的失败。例如,无法检索订阅、组件或弹性规范 |
下面的弹性规范示例显示了使用保留名称关键字 ‘DaprBuiltInServiceRetries’ 覆盖 所有 服务调用请求的默认重试。
还定义了一个名为 ‘retryForever’ 的重试策略,仅适用于 appB 目标。appB 使用 ‘retryForever’ 重试策略,而所有其他应用程序服务调用重试失败使用覆盖的 ‘DaprBuiltInServiceRetries’ 默认策略。
spec:
policies:
retries:
DaprBuiltInServiceRetries: # 覆盖服务到服务调用的默认重试行为
policy: constant
duration: 5s
maxRetries: 10
retryForever: # 用户定义的重试策略替换默认重试。目标仅依赖于应用的策略。
policy: exponential
maxInterval: 15s
maxRetries: -1 # 无限重试
targets:
apps:
appB: # 目标服务的 app-id
retry: retryForever
设置默认策略
在弹性中,您可以设置默认策略,这些策略具有广泛的范围。这是通过保留关键字完成的,这些关键字让 Dapr 知道何时应用策略。有 3 种默认策略类型:
DefaultRetryPolicy
DefaultTimeoutPolicy
DefaultCircuitBreakerPolicy
如果定义了这些策略,它们将用于服务、应用程序或组件的每个操作。它们还可以通过附加其他关键字进行更具体的修改。特定策略遵循以下模式,Default%sRetryPolicy
、Default%sTimeoutPolicy
和 Default%sCircuitBreakerPolicy
。其中 %s
被策略的目标替换。
下面是所有可能的默认策略关键字及其如何转换为策略名称的表格。
关键字 | 目标操作 | 示例策略名称 |
---|---|---|
App | 服务调用。 | DefaultAppRetryPolicy |
Actor | actor 调用。 | DefaultActorTimeoutPolicy |
Component | 所有组件操作。 | DefaultComponentCircuitBreakerPolicy |
ComponentInbound | 所有入站组件操作。 | DefaultComponentInboundRetryPolicy |
ComponentOutbound | 所有出站组件操作。 | DefaultComponentOutboundTimeoutPolicy |
StatestoreComponentOutbound | 所有状态存储组件操作。 | DefaultStatestoreComponentOutboundCircuitBreakerPolicy |
PubsubComponentOutbound | 所有出站 pubsub(发布)组件操作。 | DefaultPubsubComponentOutboundRetryPolicy |
PubsubComponentInbound | 所有入站 pubsub(订阅)组件操作。 | DefaultPubsubComponentInboundTimeoutPolicy |
BindingComponentOutbound | 所有出站绑定(调用)组件操作。 | DefaultBindingComponentOutboundCircuitBreakerPolicy |
BindingComponentInbound | 所有入站绑定(读取)组件操作。 | DefaultBindingComponentInboundRetryPolicy |
SecretstoreComponentOutbound | 所有 secretstore 组件操作。 | DefaultSecretstoreComponentTimeoutPolicy |
ConfigurationComponentOutbound | 所有配置组件操作。 | DefaultConfigurationComponentOutboundCircuitBreakerPolicy |
LockComponentOutbound | 所有锁组件操作。 | DefaultLockComponentOutboundRetryPolicy |
策略层次结构解析
如果正在执行的操作与策略类型匹配,并且没有更具体的策略针对它,则应用默认策略。对于每个目标类型(应用程序、actor 和组件),优先级最高的策略是命名策略,即专门针对该构造的策略。
如果不存在,则策略从最具体到最广泛应用。
默认策略和内置重试如何协同工作
在 [内置重试](https://v1-16.docs.dapr.io/zh-hans/operations/resiliency/policies/#Override Default Retries) 的情况下,默认策略不会阻止内置重试策略运行。两者一起使用,但仅在特定情况下。
对于服务和 actor 调用,内置重试专门处理连接到远程 sidecar 的问题(如有必要)。由于这些对于 Dapr 运行时的稳定性至关重要,因此它们不会被禁用除非为操作专门引用了命名策略。在某些情况下,可能会有来自内置重试和默认重试策略的额外重试,但这可以防止过于弱的默认策略降低 sidecar 的可用性/成功率。
应用程序的策略解析层次结构,从最具体到最广泛:
- 应用程序目标中的命名策略
- 默认应用程序策略 / 内置服务重试
- 默认策略 / 内置服务重试
actor 的策略解析层次结构,从最具体到最广泛:
- actor 目标中的命名策略
- 默认 actor 策略 / 内置 actor 重试
- 默认策略 / 内置 actor 重试
组件的策略解析层次结构,从最具体到最广泛:
- 组件目标中的命名策略
- 默认组件类型 + 组件方向策略 / 内置 actor 提醒重试(如适用)
- 默认组件方向策略 / 内置 actor 提醒重试(如适用)
- 默认组件策略 / 内置 actor 提醒重试(如适用)
- 默认策略 / 内置 actor 提醒重试(如适用)
例如,以下解决方案由三个应用程序、三个组件和两个 actor 类型组成:
应用程序:
- AppA
- AppB
- AppC
组件:
- Redis Pubsub: pubsub
- Redis 状态存储: statestore
- CosmosDB 状态存储: actorstore
actor:
- EventActor
- SummaryActor
下面是使用默认和命名策略的策略,并将其应用于目标。
spec:
policies:
retries:
# 全局重试策略
DefaultRetryPolicy:
policy: constant
duration: 1s
maxRetries: 3
# 应用程序的全局重试策略
DefaultAppRetryPolicy:
policy: constant
duration: 100ms
maxRetries: 5
# actor 的全局重试策略
DefaultActorRetryPolicy:
policy: exponential
maxInterval: 15s
maxRetries: 10
# 入站组件操作的全局重试策略
DefaultComponentInboundRetryPolicy:
policy: constant
duration: 5s
maxRetries: 5
# 状态存储的全局重试策略
DefaultStatestoreComponentOutboundRetryPolicy:
policy: exponential
maxInterval: 60s
maxRetries: -1
# 命名策略
fastRetries:
policy: constant
duration: 10ms
maxRetries: 3
# 命名策略
retryForever:
policy: exponential
maxInterval: 10s
maxRetries: -1
targets:
apps:
appA:
retry: fastRetries
appB:
retry: retryForever
actors:
EventActor:
retry: retryForever
components:
actorstore:
retry: fastRetries
下表是尝试调用此解决方案中的各种目标时应用的策略的细分。
目标 | 使用的策略 |
---|---|
AppA | fastRetries |
AppB | retryForever |
AppC | DefaultAppRetryPolicy / DaprBuiltInActorRetries |
pubsub - 发布 | DefaultRetryPolicy |
pubsub - 订阅 | DefaultComponentInboundRetryPolicy |
statestore | DefaultStatestoreComponentOutboundRetryPolicy |
actorstore | fastRetries |
EventActor | retryForever |
SummaryActor | DefaultActorRetryPolicy |
下一步
尝试其中一个弹性快速入门:
6.3 - 目标
目标
命名的策略被应用于目标。Dapr支持三种目标类型,这些类型适用于所有Dapr构建块的API:
apps
components
actors
应用程序
使用apps
目标,您可以将retry
、timeout
和circuitBreaker
策略应用于Dapr应用程序之间的服务调用。在targets/apps
下,策略应用于每个目标服务的app-id
。当sidecar之间的通信出现故障时,这些策略将被调用,如下图所示。
Dapr提供了内置的服务调用重试,因此任何应用的
retry
策略都是额外的。

应用于目标应用程序app-id
为"appB"的策略示例:
specs:
targets:
apps:
appB: # 目标服务的app-id
timeout: general
retry: general
circuitBreaker: general
组件
使用components
目标,您可以将retry
、timeout
和circuitBreaker
策略应用于组件操作。
策略可以应用于outbound
操作(从Dapr sidecar到组件的调用)和/或inbound
(从sidecar到您的应用程序的调用)。
出站
outbound
操作是从sidecar到组件的调用,例如:
- 持久化或检索状态。
- 在pubsub组件上发布消息。
- 调用输出绑定。
某些组件可能具有内置的重试功能,并且可以在每个组件的基础上进行配置。

spec:
targets:
components:
myStateStore:
outbound:
retry: retryForever
circuitBreaker: simpleCB
入站
inbound
操作是从sidecar到您的应用程序的调用,例如:
- pubsub订阅在传递消息时。
- 输入绑定。
某些组件可能具有内置的重试功能,并且可以在每个组件的基础上进行配置。

spec:
targets:
components:
myInputBinding:
inbound:
timeout: general
retry: general
circuitBreaker: general
PubSub
在pubsub target/component
中,您可以同时指定inbound
和outbound
操作。

spec:
targets:
components:
myPubsub:
outbound:
retry: pubsubRetry
circuitBreaker: pubsubCB
inbound: # 入站仅适用于从sidecar到应用程序的传递
timeout: general
retry: general
circuitBreaker: general
Actor
使用actors
目标,您可以将retry
、timeout
和circuitBreaker
策略应用于actor操作。
当为actors
目标使用circuitBreaker
策略时,您可以通过circuitBreakerScope
指定电路断开的范围:
id
:单个actor IDtype
:给定actor类型的所有actorboth
:以上两者
您还可以使用circuitBreakerCacheSize
属性指定要在内存中保留的电路断路器数量的缓存大小,提供一个整数值,例如5000
。
示例
spec:
targets:
actors:
myActorType:
timeout: general
retry: general
circuitBreaker: general
circuitBreakerScope: both
circuitBreakerCacheSize: 5000
下一步
尝试其中一个弹性快速入门:
6.4 - 健康检查
6.4.1 - 应用健康检查
应用健康检查功能可以检测应用程序的健康状况,并对状态变化做出反应。
应用程序可能由于多种原因变得无响应。例如,您的应用程序:
- 可能太忙而无法接受新工作;
- 可能已崩溃;或
- 可能处于死锁状态。
有时这种情况可能是暂时的,例如:
- 如果应用程序只是忙碌,最终会恢复接受新工作
- 如果应用程序因某种原因正在重启并处于初始化阶段
应用健康检查默认情况下是禁用的。一旦启用,Dapr 运行时(sidecar)会通过 HTTP 或 gRPC 调用定期轮询您的应用程序。当检测到应用程序的健康状况出现问题时,Dapr 会通过以下方式暂停接受新工作:
- 取消所有 pub/sub 订阅
- 停止所有输入绑定
- 短路所有服务调用请求,这些请求在 Dapr 运行时终止,不会转发到应用程序
这些变化是暂时的,一旦 Dapr 检测到应用程序恢复响应,它将恢复正常操作。

应用健康检查与平台级健康检查
Dapr 的应用健康检查旨在补充而不是替代任何平台级健康检查,例如在 Kubernetes 上运行时的存活探针。
平台级健康检查(或存活探针)通常确保应用程序正在运行,并在出现故障时导致平台重启应用程序。
与平台级健康检查不同,Dapr 的应用健康检查专注于暂停当前无法接受工作的应用程序,但预计最终能够恢复接受工作。目标包括:
- 不给已经超载的应用程序带来更多负担。
- 当 Dapr 知道应用程序无法处理消息时,不从队列、绑定或 pub/sub 代理中获取消息。
在这方面,Dapr 的应用健康检查是“较软”的,等待应用程序能够处理工作,而不是以“硬”方式终止正在运行的进程。
注意
对于 Kubernetes,失败的应用健康检查不会将 pod 从服务发现中移除:这仍然是 Kubernetes 存活探针的责任,而不是 Dapr。配置应用健康检查
应用健康检查默认情况下是禁用的,但可以通过以下方式启用:
--enable-app-health-check
CLI 标志;或- 在 Kubernetes 上运行时使用
dapr.io/enable-app-health-check: true
注释。
添加此标志是启用应用健康检查的必要且充分条件,使用默认选项。
完整的选项列表如下表所示:
CLI 标志 | Kubernetes 部署注释 | 描述 | 默认值 |
---|---|---|---|
--enable-app-health-check | dapr.io/enable-app-health-check | 启用健康检查的布尔值 | 禁用 |
--app-health-check-path | dapr.io/app-health-check-path | 当应用通道为 HTTP 时,Dapr 用于健康探测的路径(如果应用通道使用 gRPC,则忽略此值) | /healthz |
--app-health-probe-interval | dapr.io/app-health-probe-interval | 每次健康探测之间的秒数 | 5 |
--app-health-probe-timeout | dapr.io/app-health-probe-timeout | 健康探测请求的超时时间(以毫秒为单位) | 500 |
--app-health-threshold | dapr.io/app-health-threshold | 在应用被视为不健康之前的最大连续失败次数 | 3 |
请参阅完整的 Dapr 参数和注释参考以获取所有选项及其启用方法。
此外,应用健康检查受应用通道使用的协议影响,该协议通过以下标志或注释进行配置:
CLI 标志 | Kubernetes 部署注释 | 描述 | 默认值 |
---|---|---|---|
--app-protocol | dapr.io/app-protocol | 应用通道使用的协议。支持的值有 http 、grpc 、https 、grpcs 和 h2c (HTTP/2 明文)。 | http |
注意
如果应用健康探测超时值过低,可能会在应用程序遇到突然高负载时将其分类为不健康,导致响应时间下降。如果发生这种情况,请增加dapr.io/app-health-probe-timeout
值。健康检查路径
HTTP
当使用 HTTP(包括 http
、https
和 h2c
)作为 app-protocol
时,Dapr 通过对 app-health-check-path
指定的路径进行 HTTP 调用来执行健康探测,默认路径为 /health
。
为了使您的应用被视为健康,响应必须具有 200-299 范围内的 HTTP 状态码。任何其他状态码都被视为失败。Dapr 只关心响应的状态码,忽略任何响应头或正文。
gRPC
当使用 gRPC 作为应用通道(app-protocol
设置为 grpc
或 grpcs
)时,Dapr 在您的应用程序中调用方法 /dapr.proto.runtime.v1.AppCallbackHealthCheck/HealthCheck
。您很可能会使用 Dapr SDK 来实现此方法的处理程序。
在响应健康探测请求时,您的应用可以决定执行额外的内部健康检查,以确定它是否准备好处理来自 Dapr 运行时的工作。然而,这不是必需的;这取决于您的应用程序的需求。
间隔、超时和阈值
间隔
默认情况下,当启用应用健康检查时,Dapr 每 5 秒探测一次您的应用程序。您可以使用 app-health-probe-interval
配置间隔(以秒为单位)。这些探测会定期发生,无论您的应用程序是否健康。
超时
当 Dapr 运行时(sidecar)最初启动时,Dapr 会等待成功的健康探测,然后才认为应用程序是健康的。这意味着在第一次健康检查完成并成功之前,pub/sub 订阅、输入绑定和服务调用请求不会为您的应用程序启用。
如果应用程序在 app-health-probe-timeout
中配置的超时内发送成功响应(如上所述),则健康探测请求被视为成功。默认值为 500,对应于 500 毫秒(半秒)。
阈值
在 Dapr 认为应用程序进入不健康状态之前,它将等待 app-health-threshold
次连续失败,默认值为 3。此默认值意味着您的应用程序必须连续失败健康探测 3 次才能被视为不健康。
如果您将阈值设置为 1,任何失败都会导致 Dapr 假设您的应用程序不健康,并停止向其传递工作。
大于 1 的阈值可以帮助排除由于外部情况导致的瞬态故障。适合您的应用程序的正确值取决于您的要求。
阈值仅适用于失败。单个成功响应足以让 Dapr 认为您的应用程序是健康的,并恢复正常操作。
示例
使用 dapr run
命令的 CLI 标志启用应用健康检查:
dapr run \
--app-id my-app \
--app-port 7001 \
--app-protocol http \
--enable-app-health-check \
--app-health-check-path=/healthz \
--app-health-probe-interval 3 \
--app-health-probe-timeout 200 \
--app-health-threshold 2 \
-- \
<command to execute>
要在 Kubernetes 中启用应用健康检查,请将相关注释添加到您的 Deployment:
apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
labels:
app: my-app
spec:
template:
metadata:
labels:
app: my-app
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"
dapr.io/app-health-probe-interval: "3"
dapr.io/app-health-probe-timeout: "200"
dapr.io/app-health-threshold: "2"
演示
观看此视频以获取使用应用健康检查的概述:
6.4.2 - Sidecar 健康检查
Dapr 提供了一种方法,通过 HTTP /healthz
端点 来确定其健康状态。通过这个端点,daprd 进程或 sidecar 可以:
- 检查整体健康状况
- 在初始化期间确认 Dapr sidecar 的就绪状态
- 在 Kubernetes 中确定就绪和存活状态
在本指南中,您将了解 Dapr /healthz
端点如何与应用托管平台(如 Kubernetes)以及 Dapr SDK 的健康检查功能集成。
注意
Dapr actor 也有一个健康 API 端点,Dapr 会探测应用程序以响应 Dapr 发出的信号,确认 actor 应用程序是健康且正在运行的。请参阅 actor 健康 API。下图展示了 Dapr sidecar 启动时,healthz 端点和应用通道初始化的步骤。

出站健康端点
如上图中的红色边界线所示,v1.0/healthz/
端点用于等待以下情况:
- 所有组件已初始化;
- Dapr HTTP 端口可用;并且,
- 应用通道已初始化。
这用于确认 Dapr sidecar 的完整初始化及其健康状况。
您可以通过设置 DAPR_HEALTH_TIMEOUT
环境变量来控制健康检查的超时时间,这在高延迟环境中可能很重要。
另一方面,如上图中的绿色边界线所示,当 v1.0/healthz/outbound
端点返回成功时:
- 所有组件已初始化;
- Dapr HTTP 端口可用;但,
- 应用通道尚未建立。
在 Dapr SDK 中,waitForSidecar
/wait_until_ready
方法(取决于您使用的 SDK)用于通过 v1.0/healthz/outbound
端点进行此特定检查。使用这种方法,您的应用程序可以在应用通道初始化之前调用 Dapr sidecar API,例如,通过 secret API 读取 secret。
如果您在 SDK 上使用 waitForSidecar
/wait_until_ready
方法,则会执行正确的初始化。否则,您可以在初始化期间调用 v1.0/healthz/outbound
端点,如果成功,您可以调用 Dapr sidecar API。
支持出站健康端点的 SDK
目前,v1.0/healthz/outbound
端点在以下 SDK 中得到支持:
健康端点:与 Kubernetes 的集成
当将 Dapr 部署到像 Kubernetes 这样的托管平台时,Dapr 健康端点会自动为您配置。
Kubernetes 使用 就绪 和 存活 探针来确定容器的健康状况。
存活性
kubelet 使用存活探针来判断何时需要重启容器。例如,存活探针可以捕获死锁(一个无法进展的运行应用程序)。在这种状态下重启容器可以帮助提高应用程序的可用性,即使存在错误。
如何在 Kubernetes 中配置存活探针
在 pod 配置文件中,存活探针被添加到容器规范部分,如下所示:
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
在上述示例中,periodSeconds
字段指定 kubelet 应每 3 秒执行一次存活探针。initialDelaySeconds
字段告诉 kubelet 应在执行第一次探针前等待 3 秒。为了执行探针,kubelet 向在容器中运行并监听端口 8080 的服务器发送 HTTP GET 请求。如果服务器的 /healthz
路径的处理程序返回成功代码,kubelet 认为容器是存活且健康的。如果处理程序返回失败代码,kubelet 会杀死容器并重启它。
任何介于 200 和 399 之间的 HTTP 状态代码表示成功;任何其他状态代码表示失败。
就绪性
kubelet 使用就绪探针来判断容器何时准备好开始接受流量。当所有容器都准备好时,pod 被认为是就绪的。就绪信号的一个用途是控制哪些 pod 被用作 Kubernetes 服务的后端。当 pod 未就绪时,它会从 Kubernetes 服务负载均衡器中移除。
注意
一旦应用程序在其配置的端口上可访问,Dapr sidecar 将处于就绪状态。在应用程序启动/初始化期间,应用程序无法访问 Dapr 组件。如何在 Kubernetes 中配置就绪探针
就绪探针的配置与存活探针类似。唯一的区别是使用 readinessProbe
字段而不是 livenessProbe
字段:
readinessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 3
periodSeconds: 3
Sidecar 注入器
在与 Kubernetes 集成时,Dapr sidecar 被注入了一个 Kubernetes 探针配置,告诉它使用 Dapr healthz
端点。这是由 “Sidecar 注入器” 系统服务完成的。与 kubelet 的集成如下面的图示所示。

Dapr sidecar 健康端点如何与 Kubernetes 配置
如上所述,此配置由 Sidecar 注入器服务自动完成。本节描述了在存活和就绪探针上设置的具体值。
Dapr 在端口 3500 上有其 HTTP 健康端点 /v1.0/healthz
。这可以与 Kubernetes 一起用于就绪和存活探针。当 Dapr sidecar 被注入时,存活和就绪探针在 pod 配置文件中配置为以下值:
livenessProbe:
httpGet:
path: v1.0/healthz
port: 3500
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds : 5
failureThreshold : 3
readinessProbe:
httpGet:
path: v1.0/healthz
port: 3500
initialDelaySeconds: 5
periodSeconds: 10
timeoutSeconds : 5
failureThreshold: 3
延迟优雅关闭
Dapr 提供了一个 dapr.io/block-shutdown-duration
注释或 --dapr-block-shutdown-duration
CLI 标志,它会延迟完整的关闭过程,直到指定的持续时间,或直到应用报告为不健康,以较早者为准。
在此期间,所有订阅和输入绑定都会关闭。这对于需要在其自身关闭过程中使用 Dapr API 的应用程序非常有用。
适用的注释或 CLI 标志包括:
--dapr-graceful-shutdown-seconds
/dapr.io/graceful-shutdown-seconds
--dapr-block-shutdown-duration
/dapr.io/block-shutdown-duration
在 注释和参数指南 中了解更多关于这些及其使用方法。
相关链接
7 - 支持和版本控制
7.1 - 版本控制政策
介绍
Dapr 通过版本控制方案为未来的运行时、API 和组件的变化做好了设计。本主题描述了 API、组件和 Github 仓库的版本控制方案和策略。
版本控制
版本控制是为计算机软件的每个独特状态分配唯一版本名称或版本号的过程。
- 版本控制提供兼容性、明确的变更控制,并处理变更,尤其是重大变更。
- Dapr 力求保持向后兼容性。如果需要重大变更,将会提前宣布。
- 废弃的功能将在多个版本中逐步淘汰,新旧功能将并行工作。
版本控制涉及以下 Dapr 仓库:dapr、CLI、稳定语言 SDK、dashboard、components-contrib、quickstarts、helm-charts 和文档。
Dapr 具有以下版本控制方案:
- Dapr
HTTP API
采用MAJOR.MINOR
版本控制 - Dapr
GRPC API
采用MAJOR
版本控制 - 发布版本(包括 GitHub 仓库中的 dapr、CLI、SDK 和 Helm Chart)采用
MAJOR.MINOR.PATCH
版本控制 - 文档和 Quickstarts 仓库与 Dapr 运行时仓库版本控制一致。
- Dapr
组件
在 components-contrib GitHub 仓库中采用MAJOR
版本控制。 - Dapr
清单
采用MAJOR.MINOR
版本控制。这些包括订阅和配置。
请注意,Dapr 的 API、二进制发布(运行时、CLI、SDK)和组件都是相互独立的。
Dapr HTTP API
Dapr HTTP API 根据这些REST API 指南进行版本控制。
根据这些指南;
- 当预期旧版本的弃用时,API 的
MAJOR
版本会递增。任何此类弃用将被通知,并提供升级路径。 MINOR
版本可能因其他更改而递增。例如,发送到 API 的消息的 JSON 模式的更改。 API 的重大变更定义可以在这里查看。- 实验性 API 包含一个“alpha”后缀以表示其 alpha 状态。例如 v1.0alpha、v2.0alpha 等。
Dapr 运行时
Dapr 发布使用 MAJOR.MINOR.PATCH
版本控制。例如 1.0.0。阅读支持的发布以了解更多关于发布版本控制的信息。
Helm Charts
helm-charts 仓库中的 Helm charts 与 Dapr 运行时版本一致。Helm charts 用于Kubernetes 部署
语言 SDK、CLI 和 dashboard
Dapr 语言 SDK、CLI 和 dashboard 独立于 Dapr 运行时进行版本控制,并可以在不同的时间表上发布。请参阅此表格以显示 SDK、CLI、dashboard 和运行时版本之间的兼容性。每个新的运行时发布都会列出相应支持的 SDK、CLI 和 Dashboard。
SDK、CLI 和 Dashboard 的版本控制遵循 MAJOR.MINOR.PATCH
格式。当 SDK 中存在非向后兼容的更改时(例如,更改客户端方法的参数),主版本会递增。次版本用于新功能和错误修复,补丁版本在出现错误或安全热修复时递增。
SDK 中的示例和例子与该仓库的版本一致。
组件
组件在 components-contrib 仓库中实现,并遵循 MAJOR
版本控制方案。组件的版本遵循主版本(vX),因为补丁和非破坏性更改会添加到最新的主版本中。当组件接口中存在非向后兼容的更改时,例如更改 State Store 接口中的现有方法,版本会递增。
components-contrib 仓库发布是所有内部组件的统一版本。也就是说,components-contrib 仓库发布的版本由其内部所有组件的模式组成。如果没有组件更改,Dapr 的新版本并不意味着 components-contrib 有新的发布。
注意:组件具有生产使用生命周期状态:Alpha、Beta 和 Stable。这些状态与其版本控制无关。支持的组件表显示了它们的版本和状态。
- state store 组件列表
- pub/sub 组件列表
- binding 组件列表
- secret store 组件列表
- configuration store 组件列表
- lock 组件列表
- cryptography 组件列表
- middleware 组件列表
有关组件版本控制的更多信息,请阅读组件的版本 2 及以后
组件模式
组件 YAML 的版本控制有两种形式:
- 组件清单的版本控制。
apiVersion
- 组件实现的版本。
.spec.version
组件清单在 .spec.metadata
字段中包含实现的模式,.type
字段表示实现
请参阅下面示例中的注释:
apiVersion: dapr.io/v1alpha1 # <-- 这是组件清单的版本
kind: Component
metadata:
name: pubsub
spec:
version: v1 # <-- 这是 pubsub.redis 模式实现的版本
type: pubsub.redis
metadata:
- name: redisHost
value: redis-master:6379
- name: redisPassword
value: general-kenobi
组件清单版本
组件 YAML 清单的版本为 dapr.io/v1alpha1
。
组件实现版本
组件实现的版本由示例中的 .spec.version
字段确定。.spec.version
字段在模式实例中是必需的,如果不存在,该组件将无法加载。在 Dapr 1.0.0 发布时,所有组件都标记为 v1
。组件实现版本仅在非向后兼容更改时递增。
组件弃用
组件的弃用将在两个(2)版本之前宣布。组件的弃用会导致组件版本的主版本更新。经过 2 个版本后,该组件将从 Dapr 运行时中注销,尝试加载它将抛出致命异常。
组件的弃用和移除将在发布说明中宣布。
Quickstarts 和示例
Quickstarts 仓库中的 Quickstarts 与运行时版本一致,其中相应版本的表格位于示例仓库的首页。用户应仅使用与正在运行的运行时版本相对应的 Quickstarts。
Samples 仓库中的示例根据示例维护者的情况逐个版本控制。与运行时发布(多个版本之前)非常不一致或超过 1 年未维护的示例将被移除。
相关链接
7.2 - 支持的运行时和SDK版本
介绍
本主题详细介绍了Dapr版本的支持策略、升级策略,以及在所有Dapr代码库(如运行时、CLI、SDK等)中如何传达弃用和重大更改的信息,适用于1.x及以上版本。
Dapr版本采用MAJOR.MINOR.PATCH
的版本号格式。例如,1.0.0。
版本号 | 描述 |
---|---|
MAJOR | 当运行时有不兼容的更改时更新,例如API的更改。MAJOR 版本也可能在有显著功能添加或更改时发布,以便与之前版本区分。 |
MINOR | 作为常规发布节奏的一部分更新,包括新功能、错误修复和安全修复。 |
PATCH | 针对关键问题(如P0问题)和安全修复进行更新。 |
支持的版本指的是:
- 如果版本存在关键问题,例如主线中断或安全问题,将发布修补程序。每个问题都根据具体情况进行评估。
- 对支持的版本进行问题调查。如果版本不再受支持,您需要升级到较新的版本以确定问题是否仍然存在。
从1.8.0版本开始,Dapr支持三个版本:当前版本和之前的两个版本。通常这些是MINOR
版本更新。这意味着支持版本的动态窗口会向前移动,您有责任保持这些支持版本的最新状态。如果您使用较旧版本的Dapr,可能需要进行中间升级以达到支持的版本。
在major.minor版本发布之间至少有13周(3个月)的时间,给用户至少9个月的时间从不支持的版本进行升级。有关发布过程的更多详细信息,请阅读发布周期和节奏。
补丁支持适用于当前和之前的支持版本。
构建变体
Dapr的sidecar镜像被发布到GitHub容器注册表和Docker注册表。默认镜像包含所有组件。从1.11版本开始,Dapr还提供了仅包含稳定组件的sidecar镜像变体。
- 默认sidecar镜像:
daprio/daprd:<version>
或ghcr.io/dapr/daprd:<version>
(例如ghcr.io/dapr/daprd:1.11.1
) - 稳定组件的sidecar镜像:
daprio/daprd:<version>-stablecomponents
或ghcr.io/dapr/daprd:<version>-stablecomponents
(例如ghcr.io/dapr/daprd:1.11.1-stablecomponents
)
在Kubernetes上,可以通过dapr.io/sidecar-image
注释覆盖应用程序部署资源的sidecar镜像。有关更多信息,请参阅Dapr的参数和注释。如果未指定,则使用默认的’daprio/daprd:latest’镜像。
了解更多关于Dapr组件的认证生命周期。
支持的版本
下表显示了已一起测试并形成“打包”发布的Dapr版本。任何其他版本组合都不受支持。
发布日期 | 运行时 | CLI | SDKs | 仪表板 | 状态 | 发布说明 |
---|---|---|---|---|---|---|
2024年9月16日 | 1.14.4 | 1.14.1 | Java 1.12.0Go 1.11.0PHP 1.2.0Python 1.14.0.NET 1.14.0JS 3.3.1 | 0.15.0 | 支持(当前) | v1.14.4发布说明 |
2024年9月13日 | 1.14.3 | 1.14.1 | Java 1.12.0Go 1.11.0PHP 1.2.0Python 1.14.0.NET 1.14.0JS 3.3.1 | 0.15.0 | ⚠️ 已召回 | v1.14.3发布说明 |
2024年9月6日 | 1.14.2 | 1.14.1 | Java 1.12.0Go 1.11.0PHP 1.2.0Python 1.14.0.NET 1.14.0JS 3.3.1 | 0.15.0 | 支持(当前) | v1.14.2发布说明 |
2024年8月14日 | 1.14.1 | 1.14.1 | Java 1.12.0Go 1.11.0PHP 1.2.0Python 1.14.0.NET 1.14.0JS 3.3.1 | 0.15.0 | 支持(当前) | v1.14.1发布说明 |
2024年8月14日 | 1.14.0 | 1.14.0 | Java 1.12.0Go 1.11.0PHP 1.2.0Python 1.14.0.NET 1.14.0JS 3.3.1 | 0.15.0 | 支持(当前) | v1.14.0发布说明 |
2024年5月29日 | 1.13.4 | 1.13.0 | Java 1.11.0Go 1.10.0PHP 1.2.0Python 1.13.0.NET 1.13.0JS 3.3.0 | 0.14.0 | 支持 | v1.13.4发布说明 |
2024年5月21日 | 1.13.3 | 1.13.0 | Java 1.11.0Go 1.10.0PHP 1.2.0Python 1.13.0.NET 1.13.0JS 3.3.0 | 0.14.0 | 支持 | v1.13.3发布说明 |
2024年4月3日 | 1.13.2 | 1.13.0 | Java 1.11.0Go 1.10.0PHP 1.2.0Python 1.13.0.NET 1.13.0JS 3.3.0 | 0.14.0 | 支持 | v1.13.2发布说明 |
2024年3月26日 | 1.13.1 | 1.13.0 | Java 1.11.0Go 1.10.0PHP 1.2.0Python 1.13.0.NET 1.13.0JS 3.3.0 | 0.14.0 | 支持 | v1.13.1发布说明 |
2024年3月6日 | 1.13.0 | 1.13.0 | Java 1.11.0Go 1.10.0PHP 1.2.0Python 1.13.0.NET 1.13.0JS 3.3.0 | 0.14.0 | 支持 | v1.13.0发布说明 |
2024年1月17日 | 1.12.4 | 1.12.0 | Java 1.10.0Go 1.9.1PHP 1.2.0Python 1.12.0.NET 1.12.0JS 3.2.0 | 0.14.0 | 支持 | v1.12.4发布说明 |
2024年1月2日 | 1.12.3 | 1.12.0 | Java 1.10.0Go 1.9.1PHP 1.2.0Python 1.12.0.NET 1.12.0JS 3.2.0 | 0.14.0 | 支持 | v1.12.3发布说明 |
2023年11月18日 | 1.12.2 | 1.12.0 | Java 1.10.0Go 1.9.1PHP 1.2.0Python 1.12.0.NET 1.12.0JS 3.2.0 | 0.14.0 | 支持 | v1.12.2发布说明 |
2023年11月16日 | 1.12.1 | 1.12.0 | Java 1.10.0Go 1.9.1PHP 1.2.0Python 1.12.0.NET 1.12.0JS 3.2.0 | 0.14.0 | 支持 | v1.12.1发布说明 |
2023年10月11日 | 1.12.0 | 1.12.0 | Java 1.10.0Go 1.9.0PHP 1.1.0Python 1.11.0.NET 1.12.0JS 3.1.2 | 0.14.0 | 支持 | v1.12.0发布说明 |
2023年11月18日 | 1.11.6 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.6发布说明 |
2023年11月3日 | 1.11.5 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.5发布说明 |
2023年10月5日 | 1.11.4 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.4发布说明 |
2023年8月31日 | 1.11.3 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.3发布说明 |
2023年7月20日 | 1.11.2 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.2发布说明 |
2023年6月22日 | 1.11.1 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.1发布说明 |
2023年6月12日 | 1.11.0 | 1.11.0 | Java 1.9.0Go 1.8.0PHP 1.1.0Python 1.10.0.NET 1.11.0JS 3.1.0 | 0.13.0 | 不支持 | v1.11.0发布说明 |
2023年11月18日 | 1.10.10 | 1.10.0 | Java 1.8.0Go 1.7.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年7月20日 | 1.10.9 | 1.10.0 | Java 1.8.0Go 1.7.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年6月22日 | 1.10.8 | 1.10.0 | Java 1.8.0Go 1.7.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年5月15日 | 1.10.7 | 1.10.0 | Java 1.8.0Go 1.7.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年5月12日 | 1.10.6 | 1.10.0 | Java 1.8.0Go 1.7.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年4月13日 | 1.10.5 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 3.0.0 | 0.11.0 | 不支持 | |
2023年3月16日 | 1.10.4 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 2.5.0 | 0.11.0 | 不支持 | |
2023年3月14日 | 1.10.3 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 2.5.0 | 0.11.0 | 不支持 | |
2023年2月24日 | 1.10.2 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 2.5.0 | 0.11.0 | 不支持 | |
2023年2月20日 | 1.10.1 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 2.5.0 | 0.11.0 | 不支持 | |
2023年2月14日 | 1.10.0 | 1.10.0 | Java 1.8.0Go 1.6.0PHP 1.1.0Python 1.9.0.NET 1.10.0JS 2.5.0 | 0.11.0 | 不支持 | |
2022年12月2日 | 1.9.5 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.3.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年11月17日 | 1.9.4 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.3.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年11月4日 | 1.9.3 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.3.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年11月1日 | 1.9.2 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.1.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年10月26日 | 1.9.1 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.1.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年10月13日 | 1.9.0 | 1.9.1 | Java 1.7.0Go 1.6.0PHP 1.1.0Python 1.8.3.NET 1.9.0JS 2.4.2 | 0.11.0 | 不支持 | |
2022年10月26日 | 1.8.6 | 1.8.1 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年10月13日 | 1.8.5 | 1.8.1 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年8月10日 | 1.8.4 | 1.8.1 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年7月29日 | 1.8.3 | 1.8.0 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年7月21日 | 1.8.2 | 1.8.0 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年7月20日 | 1.8.1 | 1.8.0 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年7月7日 | 1.8.0 | 1.8.0 | Java 1.6.0Go 1.5.0PHP 1.1.0Python 1.7.0.NET 1.8.0JS 2.3.0 | 0.11.0 | 不支持 | |
2022年10月26日 | 1.7.5 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.2.1 | 0.10.0 | 不支持 | |
2022年5月31日 | 1.7.4 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.2.1 | 0.10.0 | 不支持 | |
2022年5月17日 | 1.7.3 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.2.1 | 0.10.0 | 不支持 | |
2022年4月22日 | 1.7.2 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.1.0 | 0.10.0 | 不支持 | |
2022年4月20日 | 1.7.1 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.1.0 | 0.10.0 | 不支持 | |
2022年4月7日 | 1.7.0 | 1.7.0 | Java 1.5.0Go 1.4.0PHP 1.1.0Python 1.6.0.NET 1.7.0JS 2.1.0 | 0.10.0 | 不支持 | |
2022年4月20日 | 1.6.2 | 1.6.0 | Java 1.4.0Go 1.3.1PHP 1.1.0Python 1.5.0.NET 1.6.0JS 2.0.0 | 0.9.0 | 不支持 | |
2022年3月25日 | 1.6.1 | 1.6.0 | Java 1.4.0Go 1.3.1PHP 1.1.0Python 1.5.0.NET 1.6.0JS 2.0.0 | 0.9.0 | 不支持 | |
2022年1月25日 | 1.6.0 | 1.6.0 | Java 1.4.0Go 1.3.1PHP 1.1.0Python 1.5.0.NET 1.6.0JS 2.0.0 | 0.9.0 | 不支持 |
SDK兼容性
SDK和运行时承诺除了安全问题所需的更改外,不会有重大更改。如果需要,所有重大更改都会在发布说明中宣布。
SDK和运行时的前向兼容性
较新的Dapr SDK支持最新版本的Dapr运行时和之前的两个版本(N-2)。
SDK和运行时的后向兼容性
对于新的Dapr运行时,当前的SDK版本和之前的两个版本(N-2)都受到支持。
升级路径
在运行时1.0版本发布后,可能会出现需要通过额外版本显式升级以达到目标的情况。例如,从v1.0升级到v1.2可能需要经过v1.1。
注意
Dapr仅在单个次要版本中升级补丁版本或从一个次要版本升级到下一个次要版本时提供无缝保证。例如,从v1.6.0
升级到v1.6.4
或v1.6.4
升级到v1.7.0
是经过保证测试的。一次升级多个次要版本是未经测试的,并被视为尽力而为。下表显示了Dapr运行时的测试升级路径。任何其他升级组合都没有经过测试。
有关升级的一般指导可以在selfhost模式和Kubernetes部署中找到。最好查看目标版本的发布说明以获得具体指导。
当前运行时版本 | 必须通过的版本 | 目标运行时版本 |
---|---|---|
1.5.0 到 1.5.2 | N/A | 1.6.0 |
1.6.0 | 1.6.2 | |
1.6.2 | 1.7.5 | |
1.7.5 | 1.8.6 | |
1.8.6 | 1.9.6 | |
1.9.6 | 1.10.7 | |
1.6.0 到 1.6.2 | N/A | 1.7.5 |
1.7.5 | 1.8.6 | |
1.8.6 | 1.9.6 | |
1.9.6 | 1.10.7 | |
1.7.0 到 1.7.5 | N/A | 1.8.6 |
1.8.6 | 1.9.6 | |
1.9.6 | 1.10.7 | |
1.8.0 到 1.8.6 | N/A | 1.9.6 |
1.9.0 到 1.9.6 | N/A | 1.10.8 |
1.10.0 到 1.10.8 | N/A | 1.11.4 |
1.11.0 到 1.11.4 | N/A | 1.12.4 |
1.12.0 到 1.12.4 | N/A | 1.13.5 |
1.13.0 到 1.13.5 | N/A | 1.14.0 |
1.14.0 到 1.14.2 | N/A | 1.14.2 |
在托管平台上升级
Dapr可以支持多个生产托管平台。在1.0版本发布时,支持的两个平台是Kubernetes和物理机。有关Kubernetes升级,请参阅Kubernetes上的生产指南
依赖项的支持版本
以下是最新版本的Dapr(v1.15.5)已测试的软件列表。
依赖项 | 支持的版本 |
---|---|
Kubernetes | Dapr对Kubernetes的支持与Kubernetes版本偏差策略保持一致 |
Open Telemetry collector (OTEL) | v0.101.0 |
Prometheus | v2.28 |
相关链接
7.3 - 重大变更和弃用
重大变更
重大变更是指对以下内容的修改,这些修改可能导致现有的第三方应用程序或脚本在升级到下一个稳定的小版本的 Dapr 工件(如 SDK、CLI、runtime 等)后出现编译错误或运行时问题:
- 代码行为
- 架构
- 默认配置值
- 命令行参数
- 发布的指标
- Kubernetes 资源模板
- 公开访问的 API
- 公开可见的 SDK 接口、方法、类或属性
以下情况可以立即应用重大变更:
- 版本未达到 1.0.0 的项目
- 预览功能
- Alpha API
- SDK 中的预览或 Alpha 接口、类、方法或属性
- 处于 Alpha 或 Beta 阶段的 Dapr 组件
github.com/dapr/components-contrib
的接口- 文档和博客中的 URL
- 例外情况,需要修复关键错误或安全漏洞。
应用重大变更的流程
应用重大变更需要遵循以下流程:
- 弃用通知必须作为发布的一部分进行发布。
- 重大变更将在弃用公告发布后的两个版本后生效。
- 例如,功能 X 在 1.0.0 版本说明中宣布弃用,然后将在 1.2.0 中移除。
弃用
弃用可以应用于:
- API,包括 alpha API
- 预览功能
- 组件
- CLI
- 可能导致安全漏洞的功能
弃用信息会在发布说明中名为“弃用”的部分中列出,说明:
- 当前弃用的功能将在未来某个版本中不再受支持。例如,发布 x.y.z。这至少是在两个版本之前。
- 在发布说明中记录用户需要采取的任何步骤以修改其代码、操作等(如果适用)。
在宣布未来的重大变更后,该变更将在 2 个版本或 6 个月后生效,以较长者为准。弃用的功能应响应警告,但除此之外不执行任何操作。
已宣布的弃用
功能 | 弃用公告 | 移除 |
---|---|---|
GET /v1.0/shutdown API(用户应使用 POST API 代替) | 1.2.0 | 1.4.0 |
Java 域构建器类已弃用(用户应使用 setters 代替) | Java SDK 1.3.0 | Java SDK 1.5.0 |
当未指定内容类型时,服务调用将不再提供默认的 application/json 内容类型头。如果您的调用应用程序依赖于此头,则必须明确 设置内容类型头。 | 1.7.0 | 1.9.0 |
使用 invoke 方法的 gRPC 服务调用已弃用。请改用代理模式服务调用。请参阅 How-To: Invoke services using gRPC 以使用代理模式。 | 1.9.0 | 1.10.0 |
CLI 标志 --app-ssl (在 Dapr CLI 和 daprd 中)已弃用,建议使用 --app-protocol ,值为 https 或 grpcs 。daprd:6158 cli:1267 | 1.11.0 | 1.13.0 |
Hazelcast PubSub 组件 | 1.9.0 | 1.11.0 |
Twitter Binding 组件 | 1.10.0 | 1.11.0 |
NATS Streaming PubSub 组件 | 1.11.0 | 1.13.0 |
Workflows API Alpha1 /v1.0-alpha1/workflows 被弃用,建议使用 Workflow Client | 1.15.0 | 1.17.0 |
相关链接
7.4 - 报告安全问题
Dapr 项目和维护者将安全性视为操作和设计软件的核心关注点。从 Dapr 二进制文件到 GitHub 发布流程,我们采取了多种措施以确保用户应用程序和数据的安全。有关 Dapr 安全功能的更多信息,请访问安全页面。
涵盖的存储库和问题
提到“Dapr 中的安全漏洞”时,指的是dapr GitHub 组织下任何存储库中的安全问题。
此报告流程仅适用于 Dapr 项目本身的安全问题,不适用于使用 Dapr 的应用程序或不影响安全性的问题。
如果问题无法通过对上述涵盖的存储库之一的更改来解决,建议在适当的存储库中创建 GitHub 问题或在 Discord 中提出问题。
**如果您不确定,**请谨慎行事,在通过 GitHub、Discord 或其他渠道提出问题之前,使用报告流程进行联系。
明确不涵盖:漏洞扫描器报告
我们不接受仅仅是从漏洞扫描工具复制粘贴输出的报告,除非已经专门确认工具报告的漏洞确实存在于 Dapr 中,包括 CLI、Dapr SDKs、components-contrib 存储库或 Dapr 组织下的任何其他存储库。
我们也使用这些工具,并根据它们的输出采取行动。然而,当这些报告被发送到我们的安全邮件列表时,通常是误报,因为这些工具往往只检查库的存在,而不考虑库在上下文中的使用方式。
如果我们收到的报告似乎只是来自扫描器的漏洞列表,我们保留忽略它的权利。
这尤其适用于工具生成的漏洞标识符不是公开可见或以某种方式是专有的情况。我们可以查找 CVE 或其他公开可用的标识符以获取更多详细信息,但不能对专有标识符执行相同操作。
安全联系人
有权阅读您的安全报告的人列在maintainers.md
中。
报告流程
- 用英语描述问题,最好附上一些示例配置或代码,以便重现问题。解释为什么您认为这是 Dapr 中的安全问题。
- 将这些信息放入电子邮件中。使用描述性标题。
- 发送电子邮件至Security (security@dapr.io)
响应
响应时间可能会受到周末、假期、休息或时区差异的影响。尽管如此,维护者团队会尽快回复,理想情况下在 3 个工作日内。
如果团队得出结论认为报告的问题确实是 Dapr 项目中的安全漏洞,至少两名维护者团队成员会尽快讨论下一步,理想情况下在 24 小时内。
一旦团队决定报告是真实漏洞,团队中的一名成员会回复报告者,确认问题并建立披露时间表,应该尽快进行。
分类、响应、修补和公告应在 30 天内完成。
7.5 - 预览功能
Dapr 的预览功能在首次发布时被视为实验性功能。
要使用运行时的预览功能,必须在 Dapr 的应用程序配置中通过预览设置功能进行显式选择加入。有关更多信息,请参阅如何启用预览功能。
对于 CLI,不需要显式选择加入,只需使用首次提供该功能的版本即可。
当前预览功能
功能 | 描述 | 设置 | 文档 | 引入版本 |
---|---|---|---|---|
可插拔组件 | 允许创建基于 gRPC 的自托管组件,这些组件可以用任何支持 gRPC 的语言编写。支持以下组件 API:状态存储、pub/sub、bindings | N/A | 可插拔组件概念 | v1.9 |
Kubernetes 的多应用运行 | 从单个配置文件配置多个 Dapr 应用程序,并在 Kubernetes 上通过单个命令运行 | dapr run -k -f | 多应用运行 | v1.12 |
工作流 | 将工作流作为代码编写,以在应用程序中自动化和编排任务,如消息传递、状态管理和故障处理 | N/A | 工作流概念 | v1.10 |
加密 | 加密或解密数据而无需管理密钥 | N/A | 加密概念 | v1.11 |
actor 状态 TTL | 允许 actor 将记录保存到状态存储中,并设置生存时间 (TTL) 以自动清理旧数据。在当前实现中,带有 TTL 的 actor 状态可能无法被客户端正确反映。请阅读 actor 状态事务 以获取更多信息。 | ActorStateTTL | actor 状态事务 | v1.11 |
组件热重载 | 允许 Dapr 加载的组件进行“热重载”。当在 Kubernetes 中或在自托管模式下更新文件中的组件规范时,组件会被重新加载。对 actor 状态存储和工作流后端的更改将被忽略。 | HotReload | 热重载 | v1.13 |
订阅热重载 | 允许声明性订阅进行“热重载”。当在 Kubernetes 中更新订阅时,或在自托管模式下更新文件中的订阅时,订阅会被重新加载。重载时不会影响正在进行的消息。 | HotReload | 热重载 | v1.14 |
调度器 actor 提醒 | 调度器 actor 提醒是存储在调度器控制平面服务中的 actor 提醒,与存储在放置控制平面服务中的 actor 提醒系统不同。SchedulerReminders 预览功能默认设置为 true ,但您可以通过将其设置为 false 来禁用调度器 actor 提醒。 | SchedulerReminders | 调度器 actor 提醒 | v1.14 |
7.6 - Alpha 和 Beta API
Alpha API
模块/API | gRPC | HTTP | 描述 | 文档 | 引入版本 |
---|---|---|---|---|---|
查询状态 | 查询状态 proto | v1.0-alpha1/state/statestore/query | 状态查询 API 可以让您检索、过滤和排序存储在状态存储组件中的键值数据。 | 查询状态 API | v1.5 |
分布式锁 | 锁 proto | /v1.0-alpha1/lock | 分布式锁 API 可以让您对资源进行锁定。 | 分布式锁 API | v1.8 |
批量发布 | 批量发布 proto | v1.0-alpha1/publish/bulk | 批量发布 API 允许您在单个请求中向主题发布多条消息。 | 批量发布和订阅 API | v1.10 |
批量订阅 | 批量订阅 proto | N/A | 批量订阅应用程序回调可以在一次调用中接收来自主题的多条消息。 | 批量发布和订阅 API | v1.10 |
加密 | 加密 proto | v1.0-alpha1/crypto | 加密 API 可以执行复杂的加密操作来加密和解密消息。 | 加密 API | v1.11 |
任务 | 任务 proto | v1.0-alpha1/jobs | 任务 API 可以让您调度和编排任务。 | 任务 API | v1.14 |
对话 | 对话 proto | v1.0-alpha1/conversation | 使用对话 API 可以在不同的大型语言模型之间进行交流。 | 对话 API | v1.15 |
Beta API
当前没有 Beta API。
相关链接
8 - 调试与故障排除
8.1 - 运行 Dapr 时的常见问题
本指南涵盖了安装和运行 Dapr 时可能遇到的常见问题。
安装 Dapr CLI 时 Dapr 无法连接到 Docker
在安装和初始化 Dapr CLI 时,如果在运行 dapr init
后看到以下错误信息:
⌛ 正在进行初始化...
❌ 无法连接到 Docker。Docker 可能未安装或未运行
请通过以下步骤进行排查:
在 Docker Desktop 中,确认已选择 允许使用默认 Docker 套接字(需要密码) 选项。
我没有看到 Dapr sidecar 注入到我的 pod 中
sidecar 未注入到 pod 中可能有多种原因。首先,检查您的部署或 pod YAML 文件,确保在正确的位置有以下注释:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
示例部署:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nodeapp
namespace: default
labels:
app: node
spec:
replicas: 1
selector:
matchLabels:
app: node
template:
metadata:
labels:
app: node
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
spec:
containers:
- name: node
image: dapriosamples/hello-k8s-node
ports:
- containerPort: 3000
imagePullPolicy: Always
在某些情况下,这可能无法正常工作:
如果您的 pod 规范模板注释正确,但仍未看到 sidecar 注入,请确保在部署或 pod 部署之前,Dapr 已部署到集群中。
如果是这种情况,重启 pod 将解决问题。
如果您在私有 GKE 集群上部署 Dapr,sidecar 注入在没有额外步骤的情况下不起作用。请参阅 设置 Google Kubernetes Engine 集群。
为了进一步诊断任何问题,请检查 Dapr sidecar 注入器的日志:
kubectl logs -l app=dapr-sidecar-injector -n dapr-system
注意:如果您将 Dapr 安装到不同的命名空间,请将上面的 dapr-system 替换为所需的命名空间
如果您在 Amazon EKS 上部署 Dapr 并使用诸如 Calico 的覆盖网络,您需要将
hostNetwork
参数设置为 true,这是 EKS 在此类 CNI 上的限制。您可以使用 Helm
values.yaml
文件设置此参数:helm upgrade --install dapr dapr/dapr \ --namespace dapr-system \ --create-namespace \ --values values.yaml
values.yaml
dapr_sidecar_injector: hostNetwork: true
或使用命令行:
helm upgrade --install dapr dapr/dapr \ --namespace dapr-system \ --create-namespace \ --set dapr_sidecar_injector.hostNetwork=true
确保 kube api 服务器可以访问以下 webhook 服务:
- Sidecar Mutating Webhook Injector Service 在端口 4000,由 sidecar 注入器提供服务。
- Resource Conversion Webhook Service 在端口 19443,由 operator 提供服务。
请与您的集群管理员联系,以设置允许从 kube api 服务器到上述端口 4000 和 19443 的入口规则。
由于 daprd sidecar,我的 pod 处于 CrashLoopBackoff 或其他失败状态
如果 Dapr sidecar (daprd
) 初始化时间过长,可能会被 Kubernetes 视为健康检查失败。
如果您的 pod 处于失败状态,您应该检查以下内容:
kubectl describe pod <name-of-pod>
您可能会在命令输出的末尾看到如下表格:
Normal Created 7m41s (x2 over 8m2s) kubelet, aks-agentpool-12499885-vmss000000 Created container daprd
Normal Started 7m41s (x2 over 8m2s) kubelet, aks-agentpool-12499885-vmss000000 Started container daprd
Warning Unhealthy 7m28s (x5 over 7m58s) kubelet, aks-agentpool-12499885-vmss000000 Readiness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
Warning Unhealthy 7m25s (x6 over 7m55s) kubelet, aks-agentpool-12499885-vmss000000 Liveness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
Normal Killing 7m25s (x2 over 7m43s) kubelet, aks-agentpool-12499885-vmss000000 Container daprd failed liveness probe, will be restarted
Warning BackOff 3m2s (x18 over 6m48s) kubelet, aks-agentpool-12499885-vmss000000 Back-off restarting failed container
消息 Container daprd failed liveness probe, will be restarted
表示 Dapr sidecar 未通过健康检查并将被重启。消息 Readiness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
和 Liveness probe failed: Get http://10.244.1.10:3500/v1.0/healthz: dial tcp 10.244.1.10:3500: connect: connection refused
表明健康检查失败是因为无法连接到 sidecar。
此故障的最常见原因是某个组件(如状态存储)配置错误,导致初始化时间过长。当初始化时间过长时,健康检查可能会在 sidecar 记录任何有用信息之前终止它。
要诊断根本原因:
解决问题后,请记得将存活检查延迟和日志级别配置回您期望的值。
我无法保存状态或获取状态
您是否在集群中安装了 Dapr 状态存储?
要检查,请使用 kubectl 获取组件列表:
kubectl get components
如果没有状态存储组件,则意味着您需要设置一个。 访问 这里 了解更多详细信息。
如果一切设置正确,请确保您获得了正确的凭据。 搜索 Dapr 运行时日志并查找任何状态存储错误:
kubectl logs <name-of-pod> daprd
我无法发布和接收事件
您是否在集群中安装了 Dapr 消息总线?
要检查,请使用 kubectl 获取组件列表:
kubectl get components
如果没有 pub/sub 组件,则意味着您需要设置一个。 访问 这里 了解更多详细信息。
如果一切设置正确,请确保您获得了正确的凭据。 搜索 Dapr 运行时日志并查找任何 pub/sub 错误:
kubectl logs <name-of-pod> daprd
调用 Dapr 时收到 500 错误响应
这意味着 Dapr 运行时内部存在一些问题。 要诊断,请查看 sidecar 的日志:
kubectl logs <name-of-pod> daprd
调用 Dapr 时收到 404 未找到响应
这意味着您正在尝试调用一个不存在的 Dapr API 端点或 URL 格式错误。 查看 Dapr API 参考 这里 并确保您正在调用正确的端点。
我没有看到来自其他服务的任何传入事件或调用
您是否指定了应用程序正在监听的端口?
在 Kubernetes 中,确保指定了 dapr.io/app-port
注释:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
如果使用 Dapr Standalone 和 Dapr CLI,请确保将 --app-port
标志传递给 dapr run
命令。
我的 Dapr 启用的应用程序行为不正确
首先要做的是检查 Dapr API 返回的 HTTP 错误代码(如果有)。
如果仍然找不到问题,请尝试为 Dapr 运行时启用 debug
日志级别。请参阅 这里 了解如何操作。
您可能还需要查看您自己进程的错误日志。如果在 Kubernetes 上运行,找到包含您的应用程序的 pod,并执行以下操作:
kubectl logs <pod-name> <name-of-your-container>
如果在 Standalone 模式下运行,您应该在主控制台会话中看到应用程序的 stderr 和 stdout 输出。
本地运行 actor 时出现超时/连接错误
每个 Dapr 实例都会向放置服务报告其主机地址。放置服务然后将节点及其地址的表分发给所有 Dapr 实例。如果该主机地址无法访问,您可能会遇到套接字超时错误或其他请求失败错误。
除非通过设置名为 DAPR_HOST_IP
的环境变量为可访问的、可 ping 的地址来指定主机名,否则 Dapr 将遍历网络接口并选择第一个非回环地址。
如上所述,为了告诉 Dapr 应该使用哪个主机名,只需设置一个名为 DAPR_HOST_IP
的环境变量。
以下示例显示如何将主机 IP 环境变量设置为 127.0.0.1
:
注意:对于版本 <= 0.4.0 使用 HOST_IP
export DAPR_HOST_IP=127.0.0.1
我的应用程序启动时没有加载任何组件。我不断收到“错误组件 X 找不到”
这通常是由于以下问题之一
- 您可能在本地定义了
NAMESPACE
环境变量或将组件部署到 Kubernetes 中的不同命名空间。检查您的应用程序和组件部署到哪个命名空间。阅读 将组件限定到一个或多个应用程序 了解更多信息。 - 您可能没有在 Dapr
run
命令中提供--resources-path
或没有将组件放入操作系统的默认组件文件夹中。阅读 定义组件 了解更多信息。 - 您的组件 YAML 文件中可能存在语法问题。使用组件 YAML 示例 检查您的组件 YAML。
服务调用失败,我的 Dapr 服务缺少 appId(macOS)
一些组织会实施软件来过滤掉所有 UDP 流量,而 mDNS 正是基于此的。在 MacOS 上,Microsoft Content Filter
通常是罪魁祸首。
为了使 mDNS 正常工作,请确保 Microsoft Content Filter
处于非活动状态。
- 打开终端 shell。
- 输入
mdatp system-extension network-filter disable
并按回车。 - 输入您的帐户密码。
当输出为“Success”时,Microsoft Content Filter 被禁用。
一些组织会不时重新启用过滤器。如果您反复遇到 app-id 值丢失,首先检查过滤器是否已重新启用,然后再进行更广泛的故障排除。
准入 webhook 拒绝了请求
由于准入 webhook 对服务帐户创建或修改资源有一个允许列表,您可能会遇到类似于以下的错误。
root:[dapr]$ kubectl run -i --tty --rm debug --image=busybox --restart=Never -- sh
Error from server: admission webhook "sidecar-injector.dapr.io" denied the request: service account 'user-xdd5l' not on the list of allowed controller accounts
要解决此错误,您应该为当前用户创建一个 clusterrolebind
:
kubectl create clusterrolebinding dapr-<name-of-user> --clusterrole=dapr-operator-admin --user <name-of-user>
您可以运行以下命令以获取集群中的所有用户:
kubectl config get-users
您可以在 这里 了解有关 webhooks 的更多信息。
8.2 - 配置和查看 Dapr 日志
本节将帮助您了解 Dapr 中日志的工作原理,以及如何配置和查看日志。
概述
日志有不同的可配置级别。 以下列出的级别适用于系统组件和 Dapr sidecar 进程/容器:
- error
- warn
- info
- debug
error 级别输出最少,而 debug 级别输出最多。默认级别是 info,它在正常情况下为操作 Dapr 提供了足够的信息。
要设置输出级别,可以使用 --log-level
命令行选项。例如:
./daprd --log-level error
./placement --log-level debug
这将以 error
日志级别启动 Dapr 运行时二进制文件,并以 debug
日志级别启动 Dapr actor 放置服务。
独立模式下的日志
在使用 Dapr CLI 运行应用程序时,可以通过传递 log-level
参数来设置日志级别:
dapr run --log-level warn node myapp.js
如上所述,每个 Dapr 二进制文件都接受一个 --log-level
参数。例如,要以警告级别启动放置服务:
./placement --log-level warn
查看独立模式下的日志
当使用 Dapr CLI 运行 Dapr 时,您的应用程序日志输出和运行时输出将被重定向到同一会话,方便调试。 例如,这是运行 Dapr 时的输出:
dapr run node myapp.js
ℹ️ Starting Dapr with id Trackgreat-Lancer on port 56730
✅ You are up and running! Both Dapr and your app logs will appear here.
== APP == App listening on port 3000!
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="starting Dapr Runtime -- version 0.3.0-alpha -- commit b6f2810-dirty"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="log level set to: info"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="standalone mode configured"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="app id: Trackgreat-Lancer"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component statestore (state.redis)"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="loaded component messagebus (pubsub.redis)"
== DAPR == 2019/09/05 12:26:43 redis: connecting to localhost:6379
== DAPR == 2019/09/05 12:26:43 redis: connected to localhost:6379 (localAddr: [::1]:56734, remAddr: [::1]:6379)
== DAPR == time="2019-09-05T12:26:43-07:00" level=warn msg="failed to init input bindings: app channel not initialized"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: starting connection attempt to placement service at localhost:50005"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="http server is running on port 56730"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="gRPC server is running on port 56731"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="dapr initialized. Status: Running. Init Elapsed 8.772922000000001ms"
== DAPR == time="2019-09-05T12:26:43-07:00" level=info msg="actors: established connection to placement service at localhost:50005"
Kubernetes 模式下的日志
您可以通过在 pod 规范模板中提供以下注释,为每个 sidecar 单独设置日志级别:
annotations:
dapr.io/log-level: "debug"
设置系统 pod 的日志级别
使用 Helm 3.x 将 Dapr 部署到集群时,您可以为每个 Dapr 系统组件单独设置日志级别:
helm install dapr dapr/dapr --namespace dapr-system --set <COMPONENT>.logLevel=<LEVEL>
组件:
- dapr_operator
- dapr_placement
- dapr_sidecar_injector
示例:
helm install dapr dapr/dapr --namespace dapr-system --set dapr_operator.logLevel=error
在 Kubernetes 上查看日志
Dapr 日志写入到标准输出(stdout)和标准错误(stderr)。 本节将指导您如何查看 Dapr 系统组件以及 Dapr sidecar 的日志。
Sidecar 日志
在 Kubernetes 中部署时,Dapr sidecar 注入器会将一个名为 daprd
的 Dapr 容器注入到您的注释 pod 中。
要查看 sidecar 的日志,只需通过运行 kubectl get pods
找到相关的 pod:
NAME READY STATUS RESTARTS AGE
addapp-74b57fb78c-67zm6 2/2 Running 0 40h
接下来,获取 Dapr sidecar 容器的日志:
kubectl logs addapp-74b57fb78c-67zm6 -c daprd
time="2019-09-04T02:52:27Z" level=info msg="starting Dapr Runtime -- version 0.3.0-alpha -- commit b6f2810-dirty"
time="2019-09-04T02:52:27Z" level=info msg="log level set to: info"
time="2019-09-04T02:52:27Z" level=info msg="kubernetes mode configured"
time="2019-09-04T02:52:27Z" level=info msg="app id: addapp"
time="2019-09-04T02:52:27Z" level=info msg="application protocol: http. waiting on port 6000"
time="2019-09-04T02:52:27Z" level=info msg="application discovered on port 6000"
time="2019-09-04T02:52:27Z" level=info msg="actor runtime started. actor idle timeout: 1h0m0s. actor scan interval: 30s"
time="2019-09-04T02:52:27Z" level=info msg="actors: starting connection attempt to placement service at dapr-placement.dapr-system.svc.cluster.local:80"
time="2019-09-04T02:52:27Z" level=info msg="http server is running on port 3500"
time="2019-09-04T02:52:27Z" level=info msg="gRPC server is running on port 50001"
time="2019-09-04T02:52:27Z" level=info msg="dapr initialized. Status: Running. Init Elapsed 64.234049ms"
time="2019-09-04T02:52:27Z" level=info msg="actors: established connection to placement service at dapr-placement.dapr-system.svc.cluster.local:80"
系统日志
Dapr 运行以下系统 pod:
- Dapr operator
- Dapr sidecar 注入器
- Dapr 放置服务
Operator 日志
kubectl logs -l app=dapr-operator -n dapr-system
I1207 06:01:02.891031 1 leaderelection.go:243] attempting to acquire leader lease dapr-system/operator.dapr.io...
I1207 06:01:02.913696 1 leaderelection.go:253] successfully acquired lease dapr-system/operator.dapr.io
time="2021-12-07T06:01:03.092529085Z" level=info msg="getting tls certificates" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.092703283Z" level=info msg="tls certificates loaded successfully" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.093062379Z" level=info msg="starting gRPC server" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator.api type=log ver=unknown
time="2021-12-07T06:01:03.093123778Z" level=info msg="Healthz server is listening on :8080" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
time="2021-12-07T06:01:03.497889776Z" level=info msg="starting webhooks" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
I1207 06:01:03.497944 1 leaderelection.go:243] attempting to acquire leader lease dapr-system/webhooks.dapr.io...
I1207 06:01:03.516641 1 leaderelection.go:253] successfully acquired lease dapr-system/webhooks.dapr.io
time="2021-12-07T06:01:03.526202227Z" level=info msg="Successfully patched webhook in CRD "subscriptions.dapr.io"" instance=dapr-operator-84bb47f895-dvbsj scope=dapr.operator type=log ver=unknown
注意:如果 Dapr 安装在不同的命名空间而不是 dapr-system,只需在上述命令中将命名空间替换为所需的命名空间
Sidecar 注入器日志
kubectl logs -l app=dapr-sidecar-injector -n dapr-system
time="2021-12-07T06:01:01.554859058Z" level=info msg="log level set to: info" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.555114755Z" level=info msg="metrics server started on :9090/" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.metrics type=log ver=unknown
time="2021-12-07T06:01:01.555233253Z" level=info msg="starting Dapr Sidecar Injector -- version 1.5.1 -- commit c6daae8e9b11b3e241a9cb84c33e5aa740d74368" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.557646524Z" level=info msg="Healthz server is listening on :8080" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
time="2021-12-07T06:01:01.621291968Z" level=info msg="Sidecar injector is listening on :4000, patching Dapr-enabled pods" instance=dapr-sidecar-injector-5d88fcfcf5-2gmvv scope=dapr.injector type=log ver=unknown
注意:如果 Dapr 安装在不同的命名空间而不是 dapr-system,只需在上述命令中将命名空间替换为所需的命名空间
查看放置服务日志
kubectl logs -l app=dapr-placement-server -n dapr-system
time="2021-12-04T05:08:05.733416791Z" level=info msg="starting Dapr Placement Service -- version 1.5.0 -- commit 83fe579f5dc93bef1ce3b464d3167a225a3aff3a" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=unknown
time="2021-12-04T05:08:05.733469491Z" level=info msg="log level set to: info" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.733512692Z" level=info msg="metrics server started on :9090/" instance=dapr-placement-server-0 scope=dapr.metrics type=log ver=1.5.0
time="2021-12-04T05:08:05.735207095Z" level=info msg="Raft server is starting on 127.0.0.1:8201..." instance=dapr-placement-server-0 scope=dapr.placement.raft type=log ver=1.5.0
time="2021-12-04T05:08:05.735221195Z" level=info msg="mTLS enabled, getting tls certificates" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735265696Z" level=info msg="tls certificates loaded successfully" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735276396Z" level=info msg="placement service started on port 50005" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:05.735553696Z" level=info msg="Healthz server is listening on :8080" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:07.036850257Z" level=info msg="cluster leadership acquired" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
time="2021-12-04T05:08:07.036909357Z" level=info msg="leader is established." instance=dapr-placement-server-0 scope=dapr.placement type=log ver=1.5.0
注意:如果 Dapr 安装在不同的命名空间而不是 dapr-system,只需在上述命令中将命名空间替换为所需的命名空间
非 Kubernetes 环境
以上示例特定于 Kubernetes,但对于任何类型的基于容器的环境,原则是相同的:只需获取 Dapr sidecar 和/或系统组件(如果适用)的容器 ID 并查看其日志。
参考资料
8.3 - Dapr API 日志
API 日志记录可以让您查看应用程序对 Dapr sidecar 的 API 调用情况。这对于监控应用程序行为或进行调试非常有用。您还可以将 Dapr API 日志记录与 Dapr 日志事件结合使用(参见配置和查看 Dapr 日志),以便更好地利用日志记录功能。
概述
API 日志记录默认情况下是禁用的。
要启用 API 日志记录,可以在启动 daprd
进程时使用 --enable-api-logging
命令行选项。例如:
./daprd --enable-api-logging
在自托管模式下配置 API 日志记录
当使用 Dapr CLI 运行应用程序时,要启用 API 日志记录,请传递 --enable-api-logging
标志:
dapr run \
--enable-api-logging \
-- node myapp.js
在自托管模式下查看 API 日志
使用 Dapr CLI 运行 Dapr 时,您的应用程序日志输出和 Dapr 运行时日志输出会被重定向到同一会话中,便于调试。
下面的示例显示了一些 API 日志:
$ dapr run --enable-api-logging -- node myapp.js
ℹ️ Starting Dapr with id order-processor on port 56730
✅ You are up and running! Both Dapr and your app logs will appear here.
.....
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="POST /v1.0/state/mystate" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Saving Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="GET /v1.0/state/mystate/key123" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Getting Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="DELETE /v1.0/state/mystate" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
== APP == INFO:root:Deleted Order: {'orderId': '483'}
INFO[0000] HTTP API Called app_id=order-processor instance=mypc method="PUT /v1.0/metadata/cliPID" scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
在 Kubernetes 中配置 API 日志记录
您可以通过在 pod 规范模板中添加以下注释来为 sidecar 启用 API 日志:
annotations:
dapr.io/enable-api-logging: "true"
在 Kubernetes 上查看 API 日志
Dapr API 日志会被写入标准输出(stdout)和标准错误(stderr),您可以在 Kubernetes 上查看这些日志。
通过执行以下命令查看 Kubernetes API 日志。
kubectl logs <pod_name> daprd -n <name_space>
下面的示例显示了在 Kubernetes 中的 info
级别 API 日志记录(启用了URL 混淆)。
time="2022-03-16T18:32:02.487041454Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:02.698387866Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:02.917629403Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:03.137830112Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
time="2022-03-16T18:32:03.359097916Z" level=info msg="HTTP API Called" method="POST /v1.0/invoke/{id}/method/{method:*}" app_id=invoke-caller instance=invokecaller-f4f949886-cbnmt scope=dapr.runtime.http-info type=log useragent=Go-http-client/1.1 ver=edge
API 日志记录配置
使用 Dapr 配置规范,您可以配置 Dapr 运行时中 API 日志记录的默认行为。
默认启用 API 日志记录
使用 Dapr 配置规范,您可以为 --enable-api-logging
标志(以及在 Kubernetes 上运行时的相应注释)设置默认值,使用 logging.apiLogging.enabled
选项。此值适用于引用定义该配置文档或资源的所有 Dapr 运行时。
- 如果
logging.apiLogging.enabled
设置为false
,即默认值,则 Dapr 运行时的 API 日志记录是禁用的,除非--enable-api-logging
设置为true
(或添加dapr.io/enable-api-logging: true
注释)。 - 当
logging.apiLogging.enabled
为true
时,Dapr 运行时默认启用 API 日志记录,可以通过设置--enable-api-logging=false
或使用dapr.io/enable-api-logging: false
注释来禁用。
例如:
logging:
apiLogging:
enabled: true
在 HTTP API 日志记录中混淆 URL
默认情况下,HTTP 端点的 API 调用日志包括被调用的完整 URL(例如,POST /v1.0/invoke/directory/method/user-123
),这可能包含个人可识别信息(PII)。
为了减少在启用 API 日志记录时意外包含 PII 的风险,Dapr 可以记录被调用的抽象路由(例如,POST /v1.0/invoke/{id}/method/{method:*}
)。这有助于确保符合 GDPR 等隐私法规。
要在 Dapr 的 HTTP API 日志中启用 URL 混淆,请将 logging.apiLogging.obfuscateURLs
设置为 true
。例如:
logging:
apiLogging:
obfuscateURLs: true
Dapr gRPC API 发出的日志不受此配置选项的影响,因为它们仅包含被调用方法的名称而不包含参数。
从 API 日志记录中省略健康检查
当启用 API 日志记录时,所有对 Dapr API 服务器的调用都会被记录,包括对健康检查端点的调用(例如 /v1.0/healthz
)。根据您的环境,这可能会每分钟生成多行日志,并可能产生不必要的噪音。
您可以使用 Dapr 配置规范配置 Dapr 在启用 API 日志记录时不记录对健康检查端点的调用,通过设置 logging.apiLogging.omitHealthChecks: true
。默认值为 false
,这意味着健康检查调用会记录在 API 日志中。
例如:
logging:
apiLogging:
omitHealthChecks: true
8.4 - 性能分析与调试
在实际应用中,程序可能会出现资源使用高峰的问题。CPU和内存的使用高峰在很多情况下是常见的。
Dapr 允许用户通过其性能分析服务端点使用 pprof
启动按需性能分析会话,以检测并发、性能、CPU 和内存使用等问题。
启用性能分析
Dapr 支持在 Kubernetes 和独立模式下启用性能分析。
独立模式
在独立模式下启用性能分析时,可以通过 Dapr CLI 传递 --enable-profiling
和 --profile-port
标志:
注意,profile-port
是可选的,如果未指定,Dapr 会自动选择一个可用端口。
dapr run --enable-profiling --profile-port 7777 python myapp.py
Kubernetes
在 Kubernetes 中启用性能分析,只需在 Dapr 注解的 pod 中添加 dapr.io/enable-profiling
注解:
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "rust-app"
dapr.io/enable-profiling: "true"
调试性能分析会话
启用性能分析后,可以启动性能分析会话来调查 Dapr 运行时的情况。
独立模式
对于独立模式,首先找到需要分析的 Dapr 实例:
dapr list
APP ID DAPR PORT APP PORT COMMAND AGE CREATED PID
node-subscriber 3500 3000 node app.js 12s 2019-09-09 15:11.24 896
获取 DAPR PORT,如果已按上述步骤启用性能分析,现在可以使用 pprof
对 Dapr 进行分析。
查看上面的 Kubernetes 示例以获取一些有用的命令来分析 Dapr。
有关 pprof 的更多信息可以在这里找到。
Kubernetes
首先,找到包含 Dapr 运行时的 pod。如果不确定 pod 名称,可以输入 kubectl get pods
:
NAME READY STATUS RESTARTS AGE
divideapp-6dddf7dc74-6sq4l 2/2 Running 0 2d23h
如果性能分析已成功启用,运行时日志应显示以下内容:
time="2019-09-09T20:56:21Z" level=info msg="starting profiling server on port 7777"
在这种情况下,我们希望在 pod divideapp-6dddf7dc74-6sq4l
内启动 Dapr 运行时的会话。
可以通过端口转发连接到 pod 来实现:
kubectl port-forward divideapp-6dddf7dc74-6sq4 7777:7777
Forwarding from 127.0.0.1:7777 -> 7777
Forwarding from [::1]:7777 -> 7777
Handling connection for 7777
现在连接已建立,可以使用 pprof
对 Dapr 运行时进行分析。
以下示例将创建一个 cpu.pprof
文件,其中包含持续 120 秒的分析会话的样本:
curl "http://localhost:7777/debug/pprof/profile?seconds=120" > cpu.pprof
使用 pprof 分析文件:
pprof cpu.pprof
还可以将结果以可视化方式保存在 PDF 中:
go tool pprof --pdf your-binary-file http://localhost:7777/debug/pprof/profile?seconds=120 > profile.pdf
对于内存相关问题,可以分析堆:
go tool pprof --pdf your-binary-file http://localhost:7777/debug/pprof/heap > heap.pdf
分析已分配的对象:
go tool pprof http://localhost:7777/debug/pprof/heap
> exit
Saved profile in /Users/myusername/pprof/pprof.daprd.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz
要进行分析,获取上面的文件路径(这是一个动态文件路径,因此请注意不要粘贴此路径),然后执行:
go tool pprof -alloc_objects --pdf /Users/myusername/pprof/pprof.daprd.alloc_objects.alloc_space.inuse_objects.inuse_space.003.pb.gz > alloc-objects.pdf
9 - Dapr 的性能与扩展性概述
9.1 - 服务调用性能
本文提供了在不同托管环境中运行Dapr所需组件的服务调用API性能基准和资源利用率。
系统概述
Dapr由两个主要部分组成:数据平面和控制平面。数据平面是运行在应用程序旁边的sidecar,而控制平面负责配置sidecar并提供证书和身份管理等功能。
自托管组件
- sidecar(数据平面)
- Sentry(可选,控制平面)
- Placement(可选,控制平面)
更多信息请参见Dapr自托管模式概述。
Kubernetes组件
- sidecar(数据平面)
- Sentry(可选,控制平面)
- Placement(可选,控制平面)
- Operator(控制平面)
- sidecar注入器(控制平面)
更多信息请参见Dapr在Kubernetes上的概述。
Dapr v1.0的性能总结
服务调用API是一个反向代理,内置了服务发现功能,用于连接其他服务。这包括跟踪、指标、用于流量传输加密的mTLS,以及通过重试网络分区和连接错误来实现的弹性。
通过服务调用,您可以实现从HTTP到HTTP、HTTP到gRPC、gRPC到HTTP和gRPC到gRPC的调用。Dapr在sidecar之间的通信中始终使用gRPC,但保留了应用程序调用时使用的协议语义。服务调用是与Dapr actor通信的底层机制。
更多信息请参见服务调用概述。
Kubernetes性能测试设置
测试在一个3节点的Kubernetes集群上进行,使用普通硬件,每个节点配备4核CPU和8GB RAM,没有任何网络加速。 设置包括一个负载测试器(Fortio)pod,其中注入了一个Dapr sidecar,调用服务调用API以到达不同节点上的pod。
测试参数:
- 每秒1000个请求
- sidecar限制为0.5 vCPU
- 启用sidecar mTLS
- 启用sidecar遥测(采样率为0.1的跟踪)
- 1KB的负载
基准测试包括直接、未加密的流量,没有遥测,直接从负载测试器到目标应用程序。
控制平面性能
Dapr控制平面在非高可用模式下运行时使用总共0.009 vCPU和61.6 Mb,这意味着每个系统组件只有一个副本。 在高可用生产设置中运行时,Dapr控制平面消耗约0.02 vCPU和185 Mb。
组件 | vCPU | 内存 |
---|---|---|
Operator | 0.001 | 12.5 Mb |
Sentry | 0.005 | 13.6 Mb |
sidecar注入器 | 0.002 | 14.6 Mb |
Placement | 0.001 | 20.9 Mb |
有许多因素会影响每个系统组件的CPU和内存消耗。这些因素在下表中显示。
组件 | vCPU | 内存 |
---|---|---|
Operator | 请求组件、配置和订阅的pod数量 | |
Sentry | 证书请求数量 | |
sidecar注入器 | 准入请求数量 | |
Placement | actor重新平衡操作数量 | 连接的actor主机数量 |
数据平面性能
Dapr sidecar每秒处理1000个请求时使用0.48 vCPU和23Mb内存。 在端到端的调用中,Dapr sidecar(客户端和服务器)在第90百分位延迟中增加约1.40 ms,在第99百分位延迟中增加约2.10 ms。端到端是指从一个应用程序发出请求到另一个应用程序接收响应的全过程。这在此图的步骤1-7中显示。
这种性能与常用的服务网格相当或更好。
延迟
在测试设置中,请求通过Dapr sidecar在客户端(从负载测试工具服务请求)和服务器端(目标应用程序)进行。 在Dapr测试中启用了mTLS和遥测(采样率为0.1的跟踪)和指标,而在基准测试中禁用了这些功能。


9.2 - actor 性能激活
本文介绍了在 Kubernetes 上 Dapr 中 actor 的服务调用 API 的性能基准和资源使用情况。
系统概述
在 Dapr 中使用 actor 的应用程序需要考虑两个方面。首先,actor 调用的路由由 Dapr 的边车(sidecar)处理。其次,actor 的运行时在应用程序端实现和处理,这依赖于所使用的 SDK。目前,性能测试使用 Java SDK 在应用程序中提供 actor 运行时。
Kubernetes 组件
- 边车(数据平面)
- Placement(actor 所需,控制平面将 actor 类型映射到主机)
- Operator(控制平面)
- 边车注入器(控制平面)
- Sentry(可选,控制平面)
Dapr v1.0 的性能总结
Dapr 边车中的 actor API 负责识别注册了特定 actor 类型的主机,并将请求路由到拥有该 actor ID 的合适主机。主机运行应用程序的一个实例,并使用 Dapr SDK(.Net、Java、Python 或 PHP)通过 HTTP 处理 actor 请求。
本次测试通过 Dapr 的 HTTP API 直接调用 actor。
有关更多信息,请参见 actor 概述。
Kubernetes 性能测试设置
测试在一个由 3 个节点组成的 Kubernetes 集群上进行,使用普通硬件,每个节点配备 4 核 CPU 和 8GB RAM,没有网络加速。 设置包括一个负载测试器(Fortio)pod,其中注入了一个 Dapr 边车,调用服务 API 以访问不同节点上的 pod。
测试参数:
- 每秒 500 个请求
- 1 个副本
- 持续 1 分钟
- 边车限制为 0.5 vCPU
- 启用 mTLS
- 启用边车遥测(采样率为 0.1 的跟踪)
- 空 JSON 对象的负载:
{}
结果
- 实际吞吐量约为 500 qps。
- tp90 延迟约为 3ms。
- tp99 延迟约为 6.2ms。
- Dapr 应用程序消耗约 523m CPU 和约 304.7Mb 内存
- Dapr 边车消耗 2m CPU 和约 18.2Mb 内存
- 无应用程序重启
- 无边车重启
相关链接
- 有关更多信息,请参见 Kubernetes 上的 Dapr 概述