1 - Dapr 自托管模式概述

如何在 Windows/Linux/MacOS 机器上运行 Dapr 的概述

概述

Dapr 可以配置为在本地开发者机器或生产环境的虚拟机上运行自托管模式。每个服务都会有一个 Dapr 运行时进程(或称为 sidecar),该进程配置为使用状态存储、发布/订阅、绑定组件和其他构建块。

初始化

Dapr 可以通过 Docker(默认)或 slim-init 模式进行初始化。它也可以在 离线或隔离环境中初始化和运行。

默认的 Docker 设置提供了即用的功能,包含以下容器和配置:

  • 一个 Redis 容器,配置为同时用于状态管理和发布/订阅的默认组件。
  • 一个 Zipkin 容器,用于诊断和跟踪。
  • 默认的 Dapr 配置和组件安装在 $HOME/.dapr/ (Mac/Linux) 或 %USERPROFILE%\.dapr\ (Windows)。

dapr-placement 服务负责管理 actor 的分布方案和键范围设置。此服务不作为容器启动,仅在您使用 Dapr actor 时才需要。有关 actor Placement 服务的更多信息,请阅读 actor 概述

Dapr 自托管 Docker 模式的示意图

使用 Dapr 启动应用程序

您可以使用 dapr run CLI 命令 启动 Dapr sidecar 进程和您的应用程序。其他参数和标志可以在这里找到。

名称解析

Dapr 使用 名称解析组件服务调用 构建块中进行服务发现。默认情况下,Dapr 在自托管模式下使用 mDNS。

如果您在虚拟机上运行 Dapr 或 mDNS 不可用的情况下,可以使用 HashiCorp Consul 组件进行名称解析。

2 - 如何使用 Podman 在自托管模式下运行 Dapr

使用 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

3 - 如何使用 Docker 自托管 Dapr

在自托管模式下,如何通过 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 网络接口。

在 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 镜像。

标签

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 的发布候选版本。

4 - 操作指南:在离线或隔离环境中运行Dapr

如何在隔离环境中以自托管模式部署和运行Dapr

概述

通常情况下,Dapr初始化时会从网络下载二进制文件并拉取镜像来设置开发环境。然而,Dapr也支持使用预先下载的安装包进行离线或隔离安装,这可以通过Docker或精简模式来实现。每个Dapr版本的安装包都被构建成一个Dapr安装包,可以下载。通过使用这个安装包和Dapr CLI的init命令,你可以在没有网络访问的环境中安装Dapr。

设置

在进行隔离初始化之前,需要预先下载一个Dapr安装包,其中包含CLI、运行时和仪表板的内容。这避免了在本地初始化Dapr时需要下载二进制文件和Docker镜像。

  1. 下载特定版本的Dapr安装包。例如,daprbundle_linux_amd64.tar.gz,daprbundle_windows_amd64.zip。

  2. 解压缩安装包。

  3. 要安装Dapr CLI,将daprbundle/dapr (Windows为dapr.exe)二进制文件复制到合适的位置:

    • 对于Linux/MacOS - /usr/local/bin
    • 对于Windows,创建一个目录并将其添加到系统PATH。例如,创建一个名为c:\dapr的目录,并通过编辑系统环境变量将此目录添加到路径中。

    注意:如果Dapr CLI没有移动到合适的位置,你可以直接使用包中的本地dapr CLI二进制文件。上述步骤是为了将其移动到常用位置并添加到路径中。

初始化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

5 - 如何在没有 Docker 的环境中以自托管模式运行 Dapr

在本地机器上未安装 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 二进制文件安装在:

  • 对于 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 的步骤移除二进制文件。

下一步

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

7 - 在自托管环境中升级 Dapr 的步骤

按照这些步骤在自托管模式下升级 Dapr,确保升级过程顺利
  1. 卸载当前的 Dapr 部署:

    dapr uninstall --all
    
  2. 访问本指南以下载并安装最新版本的 CLI。

  3. 初始化 Dapr 运行时:

    dapr init
    
  4. 确认您正在使用最新版本的 Dapr (v1.15.5):

    $ dapr --version
    
    CLI version: 1.15
    Runtime version: 1.15
    

8 - 在自托管环境中卸载 Dapr

从本地机器中移除 Dapr 的步骤

以下 CLI 命令用于移除 Dapr sidecar 二进制文件和 placement 容器:

dapr uninstall

上述命令不会移除在 dapr init 时默认安装的 Redis 或 Zipkin 容器,以防您将它们用于其他用途。要移除 Redis、Zipkin、actor placement 容器,以及位于 $HOME/.dapr%USERPROFILE%\.dapr\ 的默认 Dapr 目录,请运行以下命令:

dapr uninstall --all