这是本节的多页打印视图。 点击此处打印.

返回本页常规视图.

构建原生开发环境

构建在本机编码并在本机测试的原生开发环境

1 - Linux amd64

在 Linux amd64操作系统上构建本地开发环境,以ubuntu为例

1.1 - 开发

在linux平台上进行dapr开发的编码、单元测试、打包等工作

编码

通过 replace 引用修改的代码

以 dapr 仓库 和 components-contrib 仓库为例,如果我们在本地修改了 components-contrib 仓库的代码,然后希望在 dapr 仓库中使用这些修改后的代码,则可以修改 dapr 仓库中的 go.mod 文件,将对 components-contrib 仓库的依赖进行 replace 。

如果目标代码还没有提交到 github,则 replace 为 components-contrib 仓库的本地目录,如:

replace github.com/dapr/components-contrib => /home/sky/work/code/dapr-fork/components-contrib

如果代码已经提交到 github 仓库,则可以指定要 replace 的仓库、分支和commit:

replace github.com/dapr/components-contrib => github.com/skyao/components-contrib v1.7.1-0.20220418003919-48d8dbd6dfc8

后面这个方案适合在提交跨多个仓库的pr时使用。

测试

本地跑单元测试:

make test

e2e 测试和性能测试等运行比较麻烦,单独在测试篇中讲。

打包

构建二进制包

在 dapr/dapr 仓库下执行 make build 命令:

$ make build

CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -ldflags="-X github.com/dapr/dapr/pkg/version.gitcommit=b298e16f6bd641545c1b76b074b622578989f171 -X github.com/dapr/dapr/pkg/version.gitversion=v1.7.0-rc.4-34-gb298e16-dirty -X github.com/dapr/dapr/pkg/version.version=edge -X github.com/dapr/kit/logger.DaprVersion=edge -s -w" -o ./dist/linux_amd64/release/daprd ./cmd/daprd/;
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -ldflags="-X github.com/dapr/dapr/pkg/version.gitcommit=b298e16f6bd641545c1b76b074b622578989f171 -X github.com/dapr/dapr/pkg/version.gitversion=v1.7.0-rc.4-34-gb298e16-dirty -X github.com/dapr/dapr/pkg/version.version=edge -X github.com/dapr/kit/logger.DaprVersion=edge -s -w" -o ./dist/linux_amd64/release/placement ./cmd/placement/;
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -ldflags="-X github.com/dapr/dapr/pkg/version.gitcommit=b298e16f6bd641545c1b76b074b622578989f171 -X github.com/dapr/dapr/pkg/version.gitversion=v1.7.0-rc.4-34-gb298e16-dirty -X github.com/dapr/dapr/pkg/version.version=edge -X github.com/dapr/kit/logger.DaprVersion=edge -s -w" -o ./dist/linux_amd64/release/operator ./cmd/operator/;
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -ldflags="-X github.com/dapr/dapr/pkg/version.gitcommit=b298e16f6bd641545c1b76b074b622578989f171 -X github.com/dapr/dapr/pkg/version.gitversion=v1.7.0-rc.4-34-gb298e16-dirty -X github.com/dapr/dapr/pkg/version.version=edge -X github.com/dapr/kit/logger.DaprVersion=edge -s -w" -o ./dist/linux_amd64/release/injector ./cmd/injector/;
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build  -ldflags="-X github.com/dapr/dapr/pkg/version.gitcommit=b298e16f6bd641545c1b76b074b622578989f171 -X github.com/dapr/dapr/pkg/version.gitversion=v1.7.0-rc.4-34-gb298e16-dirty -X github.com/dapr/dapr/pkg/version.version=edge -X github.com/dapr/kit/logger.DaprVersion=edge -s -w" -o ./dist/linux_amd64/release/sentry ./cmd/sentry/;

生成的二进制文件存放在 dist/linux_amd64 目录下:

dapr-build-files

构建dapr容器

先设置 dapr 相关的环境变量:

export DAPR_TAG=dev
export DAPR_REGISTRY=docker.io/skyao

在 dapr/dapr 仓库下执行 make docker-build 命令:

$ make docker-build

Building docker.io/skyao/dapr:dev docker image ...
docker build --build-arg PKG_FILES=* -f ./docker/Dockerfile ./dist/linux_amd64/release -t docker.io/skyao/dapr:dev-linux-amd64
Sending build context to Docker daemon  236.4MB
Step 1/4 : FROM gcr.io/distroless/static:nonroot
 ---> bbd57f9cdb20
Step 2/4 : ARG PKG_FILES
 ---> Using cache
 ---> 0072a00d6320
Step 3/4 : WORKDIR /
 ---> Using cache
 ---> 01a8cf2e1345
Step 4/4 : COPY /$PKG_FILES /
 ---> Using cache
 ---> 42555e58ba97
Successfully built 42555e58ba97
Successfully tagged skyao/dapr:dev-linux-amd64
docker build --build-arg PKG_FILES=daprd -f ./docker/Dockerfile ./dist/linux_amd64/release -t docker.io/skyao/daprd:dev-linux-amd64
Sending build context to Docker daemon  236.4MB
Step 1/4 : FROM gcr.io/distroless/static:nonroot
 ---> bbd57f9cdb20
Step 2/4 : ARG PKG_FILES
 ---> Using cache
 ---> 0072a00d6320
Step 3/4 : WORKDIR /
 ---> Using cache
 ---> 01a8cf2e1345
Step 4/4 : COPY /$PKG_FILES /
 ---> Using cache
 ---> 3d189af067d0
Successfully built 3d189af067d0
Successfully tagged skyao/daprd:dev-linux-amd64
docker build --build-arg PKG_FILES=placement -f ./docker/Dockerfile ./dist/linux_amd64/release -t docker.io/skyao/placement:dev-linux-amd64
Sending build context to Docker daemon  236.4MB
Step 1/4 : FROM gcr.io/distroless/static:nonroot
 ---> bbd57f9cdb20
Step 2/4 : ARG PKG_FILES
 ---> Using cache
 ---> 0072a00d6320
Step 3/4 : WORKDIR /
 ---> Using cache
 ---> 01a8cf2e1345
Step 4/4 : COPY /$PKG_FILES /
 ---> Using cache
 ---> 18f7e2261d82
Successfully built 18f7e2261d82
Successfully tagged skyao/placement:dev-linux-amd64
docker build --build-arg PKG_FILES=sentry -f ./docker/Dockerfile ./dist/linux_amd64/release -t docker.io/skyao/sentry:dev-linux-amd64
Sending build context to Docker daemon  236.4MB
Step 1/4 : FROM gcr.io/distroless/static:nonroot
 ---> bbd57f9cdb20
Step 2/4 : ARG PKG_FILES
 ---> Using cache
 ---> 0072a00d6320
Step 3/4 : WORKDIR /
 ---> Using cache
 ---> 01a8cf2e1345
Step 4/4 : COPY /$PKG_FILES /
 ---> Using cache
 ---> 10523d0ff4a5
Successfully built 10523d0ff4a5
Successfully tagged skyao/sentry:dev-linux-amd64

生成的镜像文件可以通过 docker images 命令查看:

$ docker images
REPOSITORY                                 TAG               IMAGE ID       CREATED        SIZE
skyao/sentry                               dev-linux-amd64   10523d0ff4a5   2 days ago     39.4MB
skyao/placement                            dev-linux-amd64   18f7e2261d82   2 days ago     17MB
skyao/daprd                                dev-linux-amd64   3d189af067d0   2 days ago     113MB
skyao/dapr                                 dev-linux-amd64   42555e58ba97   2 days ago     239MB

1.2 - 原生运行daprd

在linux平台上原生运行daprd

运行二进制文件

daprd的二进制文件可以来自从源码编译的 dist/release 目录下,也可以来自通过 dapr cli 安装的 daprd。大多数情况下我们在开发时是运行刚编译出来的daprd 二进制文件。

Daprd 在运行时,通常需要和业务应用一起启动,需要和配置的外部组件相互连接,有些功能还需要 dapr 控制面的配合。

最小依赖运行

这是启动 daprd 最简单的方式,只需要指定 app-idcomponents-path (里面为空,不配置component):

$ ./dist/linux_amd64/release/daprd --components-path=./dist/components --app-id=app1

INFO[0000] starting Dapr Runtime -- version edge -- commit b298e16f6bd641545c1b76b074b622578989f171  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] log level set to: info                        app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] metrics server started on :9090/              app_id=app1 instance=skywork scope=dapr.metrics type=log ver=edge
INFO[0000] loading default configuration                 app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] standalone mode configured                    app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] app id: app1                                  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] mTLS is disabled. Skipping certificate request and tls validation  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] local service entry announced: app1 -> 192.168.100.10:35921  app_id=app1 instance=skywork scope=dapr.contrib type=log ver=edge
INFO[0000] Initialized name resolution to mdns           app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] loading components                            app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] waiting for all outstanding components to be processed  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] all outstanding components processed          app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] gRPC proxy enabled                            app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] enabled gRPC tracing middleware               app_id=app1 instance=skywork scope=dapr.runtime.grpc.api type=log ver=edge
INFO[0000] enabled gRPC metrics middleware               app_id=app1 instance=skywork scope=dapr.runtime.grpc.api type=log ver=edge
INFO[0000] API gRPC server is running on port 50001      app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] enabled metrics http middleware               app_id=app1 instance=skywork scope=dapr.runtime.http type=log ver=edge
INFO[0000] enabled tracing http middleware               app_id=app1 instance=skywork scope=dapr.runtime.http type=log ver=edge
INFO[0000] http server is running on port 3500           app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] The request body size parameter is: 4         app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] enabled gRPC tracing middleware               app_id=app1 instance=skywork scope=dapr.runtime.grpc.internal type=log ver=edge
INFO[0000] enabled gRPC metrics middleware               app_id=app1 instance=skywork scope=dapr.runtime.grpc.internal type=log ver=edge
INFO[0000] internal gRPC server is running on port 35921  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
WARN[0000] app channel is not initialized. did you make sure to configure an app-port?  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
WARN[0000] failed to init actors: no actor state store defined  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
WARN[0000] failed to read from bindings: app channel not initialized   app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge
INFO[0000] dapr initialized. Status: Running. Init Elapsed 2.781127ms  app_id=app1 instance=skywork scope=dapr.runtime type=log ver=edge

如果需要启动指定的 component ,则需要在通过 --components-path 指定的目录下(如./dist/components )放置对应的 yaml 文件。

依赖外部组件

当测试某些构建块的功能时,如 state / pubsub 等,流程比较简单,本机开发时只需要在本机将对应的组件的外部依赖启动起来,然后在 daprd 将配置好 component 的 yaml 文件放置在 --components-path 指定的目录下(如./dist/components ) 即可。

需要和业务App互动

TBD

需要dapr控制平面

TBD

在IDE中运行

最小依赖运行

在 IDE (如 goland) 中启动 daprd 的方式是打开 cmd/daprd/main.go 文件,然后运行,注意也要配置最基本的参数如 app-idcomponents-path

以 goland 为例:

goland-run-darpd

运行日志如下:

GOROOT=/usr/local/go #gosetup
GOPATH=/home/sky/work/soft/gopath #gosetup
/usr/local/go/bin/go build -o /tmp/GoLand/___daprd github.com/dapr/dapr/cmd/daprd #gosetup
/tmp/GoLand/___daprd --app-id=app1 --components-path=./dist/components
INFO[0000] starting Dapr Runtime -- version edge -- commit   app_id=app1 instance=skywork scope=dapr.runtime type=log ver=unknown
......

在 IDE 中用这种方式运行 daprd,最大的优势在于可以 debug!

1.3 - 在容器中运行daprd

在linux平台上通过容器运行daprd

1.4 - 在容器中运行外部组件

在linux平台上通过容器运行daprd需要访问的外部组件

本地开发时,各个组件只需要使用最简单的部署方案即可。

redis

执行下面命令,指定端口映射和访问密码:

docker run -d -p 6379:6379 redis --requirepass "abc123"

可以看到后台启动的 redis 进行:

ps -ef | grep redis
999         3348    3327  0 14:18 ?        00:00:12 redis-server *:6379

然后就可以配置基于 redis 的 component,如 state:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore
spec:
  type: state.redis
  version: v1
  initTimeout: 1m
  metadata:
  - name: redisHost
    value: localhost:6379
  - name: redisPassword
    value: abc123
  - name: actorStateStore
    value: true

kafka

kafka 相对 redis 要麻烦一些,因为 kafka 需要 zookeeper。因此需要使用 docker-compose 工具来启动多个 container。

https://github.com/conduktor/kafka-stack-docker-compose

这里有配置好的多种 kafka 方案,我们可以选择最简单的一种,zk-single-kafka-single

$ wget https://github.com/conduktor/kafka-stack-docker-compose/blob/master/zk-single-kafka-single.yml
$ docker-compose -f zk-single-kafka-single.yml up -d

# 可以看到 kafka 和 zeekeeper 在运行
$ ps -ef | grep kafka 
sky         3172    2436  0 18:05 pts/0    00:00:00 /usr/bin/python3 /usr/bin/docker-compose -f zk-single-kafka-single.yml up

sky         3930    3908  1 18:06 ?        00:00:04 java -Xmx512M -Xms512M -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.awt.headless=true -Xlog:gc*:file=/var/log/kafka/zookeeper-gc.log:time,tags:filecount=10,filesize=100M -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dkafka.logs.dir=/var/log/kafka -Dlog4j.configuration=file:/etc/kafka/log4j.properties -cp /usr/bin/../share/java/kafka/*:/usr/bin/../share/java/confluent-telemetry/* org.apache.zookeeper.server.quorum.QuorumPeerMain /etc/kafka/zookeeper.properties

sky         4114    4090  3 18:06 ?        00:00:10 java -Xmx1G -Xms1G -server -XX:+UseG1GC -XX:MaxGCPauseMillis=20 -XX:InitiatingHeapOccupancyPercent=35 -XX:+ExplicitGCInvokesConcurrent -XX:MaxInlineLevel=15 -Djava.awt.headless=true -Xlog:gc*:file=/var/log/kafka/kafkaServer-gc.log:time,tags:filecount=10,filesize=100M -Dcom.sun.management.jmxremote=true -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1 -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.rmi.port=9999 -Dcom.sun.management.jmxremote.port=9999 -Dcom.sun.management.jmxremote.port=9999 -Dkafka.logs.dir=/var/log/kafka -Dlog4j.configuration=file:/etc/kafka/log4j.properties -cp /usr/bin/../share/java/kafka/*:/usr/bin/../share/java/confluent-telemetry/* kafka.Kafka /etc/kafka/kafka.properties

kafka 和 zookeeper 运行的端口信息可以通过下面的命令看到:

$ docker-compose -f zk-single-kafka-single.yml ps
 Name             Command            State                                         Ports                                       
-------------------------------------------------------------------------------------------------------------------------------
kafka1   /etc/confluent/docker/run   Up      0.0.0.0:9092->9092/tcp,:::9092->9092/tcp, 0.0.0.0:9999->9999/tcp,:::9999->9999/tcp
zoo1     /etc/confluent/docker/run   Up      0.0.0.0:2181->2181/tcp,:::2181->2181/tcp, 2888/tcp, 3888/tcp 

kafka 运行在 localhost:9092

然后就可以配置基于 kafka 的 component,如 pubsub:

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: pubsub
spec:
  type: pubsub.kafka
  version: v1
  metadata:
  - name: brokers
    value: localhost:9092
  - name: consumerGroup
    value: pubsubgroup1
  - name: authRequired
    value: "false"
  - name: initialOffset
    value: oldest
  - name: disableTls
    value: true

参考: https://www.conduktor.io/kafka/how-to-start-kafka-using-docker

1.5 - 在k8s上debug控制平面

本地打包可debug的二进制文件和镜像,部署后再以debug的方式启动

参考官方文档:

https://docs.dapr.io/developing-applications/debugging/debug-k8s/debug-dapr-services/

准备工作

打包和推送可debug的镜像

cd dapr
make release GOOS=linux GOARCH=amd64 DEBUG=1

export DAPR_TAG=dev
export DAPR_REGISTRY=docker.io/skyao
docker login
make docker-push DEBUG=1

但 docker-push 速度会很慢,非常拖累速度,本地开发和debug完全没有不要用 docker 的正式 register,完全可以本地启动一个私有的 registery 。

docker private register

运行一下命令来启动一个容器承担 docker private register 的角色,以加速镜像文件推送到 docker register 的速度,避免浪费太多时间在镜像的上传上:

 docker run -d -p 5000:5000 --name registry registry:2 

为了可以使用 http,而不是默认使用 https 来执行镜像推送,需要修改 docker 配置:

sudo vi /etc/docker/daemon.json

增加内容:

{
		......,
        "insecure-registries": [
          "127.0.0.1:5000"
        ]
}

修改之后要重启 docker daemon,否则不生效:

sudo systemctl daemon-reload
sudo systemctl restart docker

然后再重启 registry 容器,否则无法访问:

docker restart registry

这时可以访问 http://127.0.0.1:5000/v2/ 查看是否正常工作。

此时再执行 make docker-push DEBUG=1 就非常快了:

export DAPR_TAG=dev
export DAPR_REGISTRY=127.0.0.1:5000
make docker-push DEBUG=1

参考资料:

准备 debug values 配置文件

准备一个 values-debug-templates.yaml 文件放在 dapr 仓库的 charts/dapr/ 目录下,内容为:

global:
   registry: "docker.io/skyao"
   tag: "dev-linux-amd64"
dapr_operator:
  debug:
    enabled: true
  runAsNonRoot: false
dapr_placement:
  debug:
    enabled: true
  runAsNonRoot: false
dapr_sentry:
  debug:
    enabled: true
  runAsNonRoot: false
dapr_sidecar_injector:
  debug:
    enabled: true
  runAsNonRoot: false
  sidecarRunAsNonRoot: false

一般每次我们只debug 一个控制面组件,因此上面的四段内容我们只需要用对应的其中一段即可。

如果有本地启动 docker private registry, 注意修改这里的 registry 地址:

global:
   registry: "127.0.0.1:5000"
   tag: "dev-linux-amd64"
......

开始 debug

debug sentry

复制 values-debug-templates.yaml 文件,改名 values-debug.yaml ,内容只保留 dapr_sentry 这一段:

global:
   registry: "127.0.0.1:5000"
   tag: "dev-linux-amd64"
dapr_sentry:
  debug:
    enabled: true
  runAsNonRoot: false

安装控制面:

cd dapr
helm install dapr charts/dapr --namespace dapr-system --values charts/dapr/values-debug.yaml --wait

其中 sentry 会以 debug 模式启动,然后等待连接:

k logs -n dapr-system dapr-sentry-7d9898fdb9-rt4kj  
2023-03-29T07:09:47Z warning layer=rpc Listening for remote connections (connections are not authenticated nor encrypted)
2023-03-29T07:09:47Z info layer=debugger launching process with args: [/sentry --log-level info --enable-metrics --metrics-port 9090 --trust-domain cluster.local]
API server listening at: [::]:40000

下面是 debug 模式启动的 sentry pod 的部分内容,可以看到容器的启动命令(/dlv)和参数(exec /sentry):

  dapr-sentry:
    Container ID:  docker://6b1c380486b9d06c639b63f152ea5ca61a30bd740cf3cbdf4a80d899a3abb973
    Image:         127.0.0.1:5000/sentry:dev-linux-amd64
    Image ID:      docker-pullable://127.0.0.1:5000/sentry@sha256:6625c43de22c794ca4b5e828fe18ba9ccf8d7f62a77ed143129b1a78d6e35a4c
    Ports:         50001/TCP, 9090/TCP, 40000/TCP
    Host Ports:    0/TCP, 0/TCP, 0/TCP
    Command:
      /dlv
    Args:
      --listen=:40000
      --accept-multiclient
      --headless=true
      --log
      --api-version=2
      exec
      /sentry
      --
      --log-level
      info
      --enable-metrics
      --metrics-port
      9090
      --trust-domain
      cluster.local
    State:          Running
      Started:      Wed, 29 Mar 2023 16:11:08 +0800
    Ready:          False
    Restart Count:  0
    Liveness:       http-get http://:8080/healthz delay=30000s timeout=1s period=3s #success=1 #failure=5
    Readiness:      http-get http://:8080/healthz delay=30000s timeout=1s period=3s #success=1 #failure=5
    Environment:
      NAMESPACE:  dapr-system (v1:metadata.namespace)
    Mounts:
      /var/run/dapr/credentials from credentials (ro)
      /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-xwc55 (ro)

此时的 dapr 控制平面状态为:

$ kubectl get pods -n dapr-system -o wide
NAME                                    READY   STATUS             RESTARTS      AGE    IP             NODE      NOMINATED NODE   READINESS GATES
dapr-dashboard-7c5c6bf5cf-rs757         1/1     Running            0             6m1s   10.244.0.104   skywork   <none>           <none>
dapr-operator-cbcb6c4fb-vz625           0/1     Running            6 (90s ago)   6m1s   10.244.0.102   skywork   <none>           <none>
dapr-placement-server-0                 0/1     CrashLoopBackOff   6 (13s ago)   6m1s   10.244.0.103   skywork   <none>           <none>
dapr-sentry-7d9898fdb9-rt4kj            0/1     Running            0             6m1s   10.244.0.101   skywork   <none>           <none>
dapr-sidecar-injector-dcbd7fcbd-cj52p   1/1     Running            0             6m1s   10.244.0.105   skywork   <none>           <none>

做一下 dapr-sentry pod 的 debug 端口的端口映射:

$ kubectl port-forward -n dapr-system dapr-sentry-7d9898fdb9-rt4kj 40000:40000 
Forwarding from 127.0.0.1:40000 -> 40000
Forwarding from [::1]:40000 -> 40000

打开 IDE,以 vs code 为例,我打开 dapr/dapr 仓库,然后设置断点为 cmd/sentry/main.go 中 main 行数的第一行,这样就可以从 sentry 启动开始 debug。

修改 lanch.json 文件,加入以下内容:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "debug sentry",
            "type": "go",
            "request": "attach",
            "mode": "remote",
            "remotePath": "${workspaceFolder}",
            "port": 40000,
            "host": "127.0.0.1"
        }
    ]
}

然后在 “Run and Debug” 中选择 “debug sentry”,点击三角形启动:

debug

图上可以看到 debug 启动成功,代码执行停留在 main() 函数的第一行位置,后面就可以按照自己的需要进行断点设置和代码debug了。

如果要重新开始 debug (比如再次debg sentry 启动的过程),最快捷的方式是重新启动 sentry 的pod:

# 删除 dapr-sentry 的现有 pod
k delete pod -n dapr-system dapr-sentry-7d9898fdb9-rt4kj
# 稍后 k8s 会重新启动一个新的 pod,然后依然是以 debug 的方式启动
# 需要再做一次端口映射
kubectl port-forward -n dapr-system dapr-sentry-7d9898fdb9-xxxx 40000:40000

常见错误

runAsNonRoot 错误导致容器启动失败

cd dapr
helm install dapr charts/dapr --namespace dapr-system --values charts/dapr/values-debug.yaml --wait

发现 dapr 的控制面启动不起来:

$ k get pods -n dapr-system                                            
NAME                                     READY   STATUS                       RESTARTS      AGE
dapr-dashboard-7c5c6bf5cf-qkq9j          1/1     Running                      0             7m14s
dapr-operator-684d455b4f-9gwk5           0/1     CreateContainerConfigError   0             7m14s
dapr-placement-server-0                  0/1     CrashLoopBackOff             6 (78s ago)   7m14s
dapr-sentry-6b47f647bb-nr8ld             0/1     CreateContainerConfigError   0             7m14s
dapr-sidecar-injector-699dfb595f-xvgjc   0/1     CreateContainerConfigError   0             7m14s

injector 报错:

  Normal   Scheduled  6m25s                   default-scheduler  Successfully assigned dapr-system/dapr-sidecar-injector-699dfb595f-xvgjc to skywork
  Warning  Failed     4m18s (x12 over 6m25s)  kubelet            Error: container has runAsNonRoot and image will run as root (pod: "dapr-sidecar-injector-699dfb595f-xvgjc_dapr-system(1643bcd9-3453-430a-b135-a48361311639)", container: dapr-sidecar-injector)
  Normal   Pulled     75s (x25 over 6m25s)    kubelet            Container image "192.168.0.90:5000/injector:dev-linux-amd64" already present on machine

这是因为容器要求 runAsNonRoot,但是 debug 打包出来的镜像要求 root。

解决方式: 在 values 文件中将 runAsNonRoot 设置为 false 来暂时避开这个问题。

sentry 调试时其他组件启动失败

k get pods -n dapr-system
NAME                                     READY   STATUS             RESTARTS      AGE
dapr-dashboard-7c5c6bf5cf-r5nsz          1/1     Running            0             37s
dapr-operator-6487d8f4fb-vqdnc           0/1     Running            0             37s
dapr-placement-server-0                  0/1     CrashLoopBackOff   2 (19s ago)   37s
dapr-sentry-b74b47fc-sfq6f               0/1     Running            0             37s
dapr-sidecar-injector-7699f486c6-lqxs8   1/1     Running            0             37s

placement 失败的原因是:

k logs -n dapr-system dapr-placement-server-0 
time="2023-03-28T15:55:27.175204696Z" level=info msg="Starting Dapr Placement Service -- version edge -- commit ccec8b8dc58f4b5e892f7806f895f6d5a85d7eeb" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=edge
time="2023-03-28T15:55:27.175289436Z" level=info msg="Log level set to: info" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=edge
time="2023-03-28T15:55:27.175357952Z" level=info msg="metrics server started on :9090/" instance=dapr-placement-server-0 scope=dapr.metrics type=log ver=edge
time="2023-03-28T15:55:27.175394106Z" level=fatal msg="open /var/run/dapr/credentials/ca.crt: no such file or directory" instance=dapr-placement-server-0 scope=dapr.placement type=log ver=edge

operator 失败的原因:

I0329 07:04:11.751075       1 leaderelection.go:248] attempting to acquire leader lease dapr-system/operator.dapr.io...
time="2023-03-29T07:04:11.852009943Z" level=info msg="Getting TLS certificates" instance=dapr-operator-6487d8f4fb-vqdnc scope=dapr.operator type=log ver=edge
time="2023-03-29T07:04:11.852046755Z" level=info msg="TLS certificate not found; waiting for disk changes. err=open /var/run/dapr/credentials/ca.crt: no such file or directory" instance=dapr-operator-6487d8f4fb-vqdnc scope=dapr.operator type=log ver=edge
time="2023-03-29T07:04:11.852065157Z" level=info msg="Starting watch for certs on filesystem: /var/run/dapr/credentials" instance=dapr-operator-6487d8f4fb-vqdnc scope=dapr.operator type=log ver=edge

2 - 使用M1芯片的Macos

在使用M1芯片的 Macos 上构建本地开发环境