1 - Dapr 配置

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 设置为 httpgrpc 协议
zipkin.endpointAddress string 设置 Zipkin 服务器地址以发送跟踪。这应该在端点上包含协议 (http:// 或 https://)。
samplingRate

samplingRate 用于启用或禁用跟踪。samplingRate 的有效范围是 01(含)。采样率决定了是否根据值对跟踪跨度进行采样。

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 运行时传递 truefalse 值,否则使用配置规范中设置的值作为默认值。默认值:false
apiLogging.obfuscateURLs boolean 启用时,会在 HTTP API 日志(如果启用)中模糊化 URL 的值,记录抽象路由名称而不是被调用的完整路径,该路径可能包含个人可识别信息(PII)。默认值:false
apiLogging.omitHealthChecks boolean 如果为 true,则在启用 API 日志记录时,不会记录对健康检查端点(例如 /v1.0/healthz)的调用。这在这些调用在日志中添加了大量噪音时很有用。默认值:false

有关更多信息,请参阅 日志记录文档

中间件

中间件配置设置命名的 HTTP 管道中间件处理程序。Configuration 规范下的 httpPipelineappHttpPipeline 部分包含以下属性:

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.smtpsecretstores.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 版本。

启用预览功能

有关如何选择加入发布版的预览功能的信息和示例,请参阅 预览功能 指南。

启用预览功能可以解锁新的功能,以便进行开发/测试,因为它们仍然需要更多时间才能在运行时中普遍可用(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 令牌验证器。

有关更多信息,请参阅 mTLS 操作指南安全概念

示例控制平面配置

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
  name: daprsystem
  namespace: default
spec:
  mtls:
    enabled: true
    allowedClockSkew: 15m
    workloadCertTTL: 24h

下一步

了解并发和速率限制

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 - 操作指南:限制从 secret 存储中读取的 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。

权限优先级

allowedSecretsdeniedSecrets 列表的优先级高于 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 的访问。要添加此配置:

  1. 定义以下 appconfig.yaml

    apiVersion: dapr.io/v1alpha1
    kind: Configuration
    metadata:
      name: appconfig
    spec:
      secrets:
        scopes:
          - storeName: kubernetes
            defaultAccess: deny
    
  2. 使用以下命令将其应用到 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 存储中的 secret1secret2,同时允许访问所有其他 secret。请按照sidecar 配置指南将配置应用到 sidecar。

下一步

服务调用访问控制

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”

策略规则

  1. 如果未指定访问策略,默认行为是允许所有应用程序访问被调用应用程序上的所有方法。
  2. 如果未指定全局默认操作且未定义特定应用程序策略,则空访问策略被视为未指定访问策略。默认行为是允许所有应用程序访问被调用应用程序上的所有方法。
  3. 如果未指定全局默认操作但已定义了一些特定应用程序策略,则我们采用更安全的选项,假设全局默认操作为拒绝访问被调用应用程序上的所有方法。
  4. 如果定义了访问策略且无法验证传入应用程序凭据,则全局默认操作生效。
  5. 如果传入应用程序的信任域或命名空间与应用程序策略中指定的值不匹配,则忽略应用程序策略,全局默认操作生效。

策略优先级

最具体的匹配策略对应的操作生效,按以下顺序排列:

  1. 在HTTP的情况下为特定HTTP动词,或在GRPC的情况下为操作级别操作。
  2. 应用程序级别的默认操作
  3. 全局级别的默认操作

示例场景

以下是使用访问控制列表进行服务调用的一些示例场景。请参阅配置指南以了解应用程序sidecar的可用配置设置。

场景1:

拒绝所有应用程序的访问,除非trustDomain = publicnamespace = defaultappId = 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 = publicnamespace = defaultappId = app1operation = 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操作

通过此配置,只有以下场景被允许访问。来自所有其他应用程序的所有其他方法请求,包括app1app2上的其他方法,均被拒绝。

  • trustDomain = publicnamespace = defaultappID = app1operation = op1httpVerb = POST/PUT
  • trustDomain = "myDomain"namespace = "ns1"appID = app2operation = 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 = publicnamespace = defaultappId = app1operation = /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 = publicnamespace = ns1appId = app1,并拒绝访问所有方法,trustDomain = publicnamespace = ns2appId = 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 = publicnamespace = defaultappId = app1operation = /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示例展示了如何拒绝来自pythonappneworder方法的访问,其中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

先决条件

运行Node.js应用程序

  1. 在命令提示符中,设置这些环境变量:

      ```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"
      ```
    
  2. 运行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
    
  3. 在另一个命令提示符中运行Node.js应用程序:

    node app.js
    

运行Python应用程序

  1. 在另一个命令提示符中,设置这些环境变量:

    ```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"
    
  2. 运行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
    
  3. 在另一个命令提示符中运行Python应用程序:

    python app.py
    

您应该在Python应用程序命令提示符中看到对Node.js应用程序的调用失败,这是由于nodeappconfig文件中的拒绝操作。将此操作更改为允许并重新运行应用程序以查看此调用成功。

Kubernetes模式

先决条件

配置Node.js和Python应用程序

您可以创建并应用上述nodeappconfig.yamlpythonappconfig.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允许列表

5 - 使用指南:选择性启用 Dapr Sidecar 的 API

选择应用程序可以使用的 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.0v1.0-alpha1) state (v1v1alpha1)
发布/订阅 publish (v1.0v1.0-alpha1) publish (v1v1alpha1)
输出绑定 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.0v1.0-alpha1) configuration (v1v1alpha1)
分布式锁 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 使用 gRPC

6 - 操作指南:配置 Dapr 使用 gRPC

配置 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 头部大小

7 - 操作指南:如何处理大容量 HTTP 请求体

如何配置超过 4 MB 的 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"
#...

相关链接

Dapr Kubernetes pod 注解规范

下一步

安装 Sidecar 证书

8 - 操作指南:处理大型HTTP头部大小

配置更大的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"
#...

相关链接

Dapr Kubernetes pod注解规范

下一步

处理大型HTTP主体请求

9 - 操作指南:在Dapr sidecar中安装证书

配置Dapr sidecar容器以信任证书

Dapr sidecar可以通过配置来信任与外部服务通信所需的证书。这在需要信任自签名证书的场景中非常有用,例如:

  • 使用HTTP绑定
  • 为sidecar配置出站代理

支持信任证书颁发机构(CA)证书和叶子证书。

当sidecar作为容器运行时,可以进行以下配置。

  1. 使用卷挂载将证书配置为可用于sidecar容器。
  2. 将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上:

  1. 使用卷挂载将证书配置为可用于sidecar容器。
  2. 将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指向的目录中的所有证书都将被安装。

演示

观看在社区电话64中使用安装SSL证书和安全使用HTTP绑定的演示:

相关链接

下一步

启用预览功能

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

下一步

配置模式

11 - 操作指南:为 Dapr sidecar 配置 Secret 环境变量

将 Kubernetes Secret 中的环境变量注入到 Dapr sidecar

在某些情况下,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 字段是必需的,因此 namekey 必须同时设置。从 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 的 namekey 字段具有相同的值,即 “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"