第四部分 dapr on kubernetes

image-20220410164056425

Build connected distributed applications faster

The Distributed Application Runtime (Dapr) provides APIs that simplify microservice connectivity. Whether your communication pattern is service to service invocation or pub/sub messaging, Dapr helps you write resilient and secured microservices.

By letting Dapr’s sidecar take care of the complex challenges such as service discovery, message broker integration, encryption, observability, and secret management, you can focus on business logic and keep your code simple.

dapr(Distributed Application Runtime)中文翻译为:分布式应用运行时.dapr为我们在服务化架构中解决:

  1. 服务通讯(包括重试,限流)
  2. 状态存储
  3. 发布订阅
  4. 服务度量

1. 安装

​ 本安装教程以1.7版本为基础

1. 安装运行时

[root@master ~]# wget -q https://raw.githubusercontent.com/dapr/cli/master/install/install.sh -O - | /bin/bash
Getting the latest Dapr CLI...
Your system is linux_amd64
Installing Dapr CLI...

Installing v1.7.0 Dapr CLI...
Downloading https://github.com/dapr/cli/releases/download/v1.7.0/dapr_linux_amd64.tar.gz ...
dapr installed into /usr/local/bin successfully.
CLI version: 1.7.0
Runtime version: n/a
1
2
3
4
5
6
7
8
9
10

安装后

[root@master ~]# dapr
          __
     ____/ /___ _____  _____
    / __  / __ '/ __ \/ ___/
   / /_/ / /_/ / /_/ / /
   \__,_/\__,_/ .___/_/
             /_/
===============================
Distributed Application Runtime
Usage:
  dapr [command]
Available Commands:
  build-info     Print build info of Dapr CLI and runtime
  completion     Generates shell completion scripts
  components     List all Dapr components. Supported platforms: Kubernetes
  configurations List all Dapr configurations. Supported platforms: Kubernetes
  dashboard      Start Dapr dashboard. Supported platforms: Kubernetes and self-hosted
  help           Help about any command
  init           Install Dapr on supported hosting platforms. Supported platforms: Kubernetes and self-hosted
  invoke         Invoke a method on a given Dapr application. Supported platforms: Self-hosted
  list           List all Dapr instances. Supported platforms: Kubernetes and self-hosted
  logs           Get Dapr sidecar logs for an application. Supported platforms: Kubernetes
  mtls           Check if mTLS is enabled. Supported platforms: Kubernetes
  publish        Publish a pub-sub event. Supported platforms: Self-hosted
  run            Run Dapr and (optionally) your application side by side. Supported platforms: Self-hosted
  status         Show the health status of Dapr services. Supported platforms: Kubernetes
  stop           Stop Dapr instances and their associated apps. Supported platforms: Self-hosted
  uninstall      Uninstall Dapr runtime. Supported platforms: Kubernetes and self-hosted
  upgrade        Upgrades or downgrades a Dapr control plane installation in a cluster. Supported platforms: Kubernetes
Flags:
  -h, --help          help for dapr
      --log-as-json   Log output in JSON format
  -v, --version       version for dapr
Use "dapr [command] --help" for more information about a command.
[root@master ~]#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

2. 集群初始化

master节点使用以下命令,在集群中初始化dapr

 dapr init -k --set dapr_sidecar_injector.hostNetwork=true
1
[root@master ~]# dapr init -k --set dapr_sidecar_injector.hostNetwork=true
⌛  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

✅  Deploying the Dapr control plane 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://aka.ms/dapr-getting-started
[root@master ~]#
1
2
3
4
5
6
7

安装成功后,dapr的组件会部署在dapr-system的namespace下

[root@master ~]# kubectl get pod -n dapr-system
NAME                                     READY   STATUS    RESTARTS      AGE
dapr-dashboard-d8f5648f8-tdm4r           1/1     Running   1 (24d ago)   24d
dapr-operator-7b77f5d855-8659n           1/1     Running   3 (24d ago)   24d
dapr-placement-server-0                  1/1     Running   1 (24d ago)   24d
dapr-sentry-77969f8bcc-wt5hf             1/1     Running   1 (24d ago)   24d
dapr-sidecar-injector-69955f5db9-xzkvz   1/1     Running   1 (24d ago)   24d
1
2
3
4
5
6
7

​ 也可以使用dapr status -k来查看

[root@master ~]# dapr status -k
  NAME                   NAMESPACE    HEALTHY  STATUS   REPLICAS  VERSION  AGE  CREATED
  dapr-sidecar-injector  dapr-system  True     Running  1         1.7.0    24d  2022-04-10 04:57.43
  dapr-placement-server  dapr-system  True     Running  1         1.7.0    24d  2022-04-10 04:57.43
  dapr-operator          dapr-system  True     Running  1         1.7.0    24d  2022-04-10 04:57.42
  dapr-sentry            dapr-system  True     Running  1         1.7.0    24d  2022-04-10 04:57.42
  dapr-dashboard         dapr-system  True     Running  1         0.10.0   24d  2022-04-10 04:57.42
1
2
3
4
5
6
7

到此为止,daprkubernetes中就安装完毕.

2. 配置

​ 在配置前,我们首先规划dapr,dapr配置主要常用有以下三个配置

  1. component

​ 该配置主要是用来指定dapr使用发布定于中间件发布订阅

  1. state

​ 该配置主要是用来指定dapr使用的状态存储的中间件

  1. configuration

​ 该配置主要是用来指定dapr的行为,比如是否链路追踪,是否开启度量等

dapr的所有配置项也受限于Kubernetes的命名空间限制,所以创建这些配置时,都需要与业务pod在同一个命名空间

1. component

​ 我们使用RabbitMQ来作为发布订阅的中间件

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: rabbitmq-pubsub
  #namespace需要与业务namespace为同一个
  namespace: dotnet
spec:
  type: pubsub.rabbitmq
  version: v1
  metadata:
  - name: host
    value: "amqp://guest:guest@cd:5672"
  - name: durable
    value: "false"
  - name: deletedWhenUnused
    value: "false"
  - name: autoAck
    value: "true"
  - name: deliveryMode
    value: "0"
  - name: requeueInFailure
    value: "false"
  - name: prefetchCount
    value: "0"
  - name: reconnectWait
    value: "0"
  - name: concurrencyMode
    value: parallel
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

2. configuration

apiVersion: dapr.io/v1alpha1
kind: Configuration
metadata:
 name: dapr-config
 #namespace需要与业务namespace为同一个
 namespace: dotnet
spec:
 tracing:
  #开启链路追踪,值为0与1
  samplingRate: "1"
  zipkin:
   endpointAddress: "http://cd:9411/api/v2/spans"
 #开启度量  
 metric:
  enabled: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

3. state

​ 状态存储我们使用My SQL

apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
  name: statestore-mysql
  #namespace需要与业务namespace为同一个
  namespace: dotnet
spec:
  type: state.mysql
  version: v1
  metadata:
  - name: connectionString
    value: "root:123456@tcp(cd:3306)/?allowNativePasswords=true"
  - name: actorStateStore
    value: "true"
1
2
3
4
5
6
7
8
9
10
11
12
13
14

​ 在master节点上执行以上文件,可以看到相关配置已经部署成功

[root@master dapr]# kubectl get all -ndotnet
...
...
NAME                                 AGE
component.dapr.io/rabbitmq-pubsub    63s
component.dapr.io/statestore-mysql   11s

NAME                                AGE
configuration.dapr.io/dapr-config   30s
1
2
3
4
5
6
7
8
9

3. 服务调用

​ 在asp.netcore on kubernetes中,我们需要自行在应用程序中集成zipkinPolly来实现对于请求的重试,链路追踪等,在dapr中,dapr就已经自动的帮我们做了这些事情

​ 基于我们前面的演示环境hello.http调用fine.http,改用dapr后,请求链路如下

image-20220505155123487

1. 引用包

所有项目引用以下包

Dapr.AspNetCore

2. 更改调用

​ hello-http原有调用方式

services.AddRefitClient<IFineService>()
                .ConfigureHttpClient(options => options.BaseAddress = new Uri(Configuration["fine.service"]))
                .AddTransientHttpErrorPolicy(p => p.WaitAndRetryAsync(3, _ => TimeSpan.FromSeconds(2)))
                .AddHttpMessageHandler(_ => TracingHandler.WithoutInnerHandler(AppInfo.ServiceName));
1
2
3
4

更改成

if (this.WebHostEnvironment.IsDevelopment())
    #环境为本地调试环境,无法通过dapr,所以还是走网关
    services.AddRefitClient<IFineService>().ConfigureHttpClient(options => options.BaseAddress = new Uri("http://api.kong.com:32310"));
 else
     services.AddRefitClient<IFineService>().ConfigureHttpClient(options => options.BaseAddress = new Uri($"http://fine-http")).AddHttpMessageHandler(_ => new InvocationHandler());
1
2
3
4
5

InvocationHandlerdapr内部调用的Handler

​ 另外有一些教程,告诉我们使用dapr的方式是在Startup中,注入DaprClient这样的方式,使用该方式,则无法使用Refit这种强类型的服务绑定,需要我们手动处理HTTP请求.

3. 注入pod

​ 在Kubernetes中的部署yaml文件更改一下节点内容

​ 在Deployment->template->metadata->annotations下,增加dapr的注解

apiVersion: apps/v1
kind: Deployment
metadata:
 name: Deployment_Name
 namespace: dotnet
spec:
 replicas: 1
 selector:
    matchLabels:
      app: Deployment_Name
 template:
  metadata:
   annotations:
   		#注入dapr
        dapr.io/enabled: "true"
        #本服务在dapr中的app id,
        dapr.io/app-id: "app-id"
        #本服务的端口,也就是本pod的containerPort
        dapr.io/app-port: "80"
        #指定dapr的configuration
        dapr.io/config: "dapr-config"
        dapr.io/enable-metrics: "true"
        dapr.io/metrics-port: "9090"
...
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

可以看到dapr已经注入成功,在这个pod中,存在两个容器

[root@master dapr]# kubectl get pod -ndotnet
NAME                         READY   STATUS    RESTARTS   AGE
fine-http-ccbd77bb4-5vztz    2/2     Running   0          13m
hello-http-84b758b65-52tdg   2/2     Running   0          9m39s
1
2
3
4

dapr的容器名称是:daprd

image-20220505164632880

重新发布后,多访问几次hello-http服务

image-20220505204739446

然后在访问zipkin来查看数据,可以看到已经是通过dapr进行交互

image-20220505204704629

6. FAQ

  1. dapr的通讯端口

从DaprClient源码中可以看到以下定义,

HTTP默认端口为3500,Grpc端口默认为:50001

image-20220505163719405

Last Updated:
Contributors: 刘岩