This is the multi-page printable view of this section. Click here to print.
在 Kubernetes 模式下部署和运行 Dapr
- 1: Kubernetes 上运行 Dapr 概述
- 2: Kubernetes 集群设置
- 2.1: 设置 Minikube 集群
- 2.2: 设置 KiND 集群
- 2.3: 设置 Azure Kubernetes Service (AKS) 集群
- 2.4: 设置 Google Kubernetes Engine (GKE) 集群
- 2.5: 设置 Elastic Kubernetes Service (EKS) 集群
- 3: 在 Kubernetes 集群上部署 Dapr
- 4: 在 Kubernetes 集群上升级 Dapr
- 5: Kubernetes 生产环境指南
- 6: 使用 Dapr Shared 每节点或每集群部署 Dapr
- 7: 操作指南:持久化 Scheduler 作业
- 8: 部署到混合 Linux/Windows Kubernetes 集群
- 9: 在 Kubernetes Job 中运行 Dapr
- 10: 操作指南:将 Pod 卷挂载到 Dapr 边车
1 - Kubernetes 上运行 Dapr 概述
Dapr 可以配置为在任何受支持的 Kubernetes 版本上运行。为此,Dapr 首先部署以下 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-scheduler | 提供由 Jobs API、Workflow API 和 Actor Reminders 使用的分布式作业调度功能 |

支持的版本
Dapr 对 Kubernetes 的支持与 Kubernetes 版本偏差策略保持一致。
将 Dapr 部署到 Kubernetes 集群
阅读在 Kubernetes 集群上部署 Dapr以了解如何将 Dapr 部署到您的 Kubernetes 集群。
将 Dapr 添加到 Kubernetes 部署
在 Kubernetes 集群中部署和运行启用 Dapr 的应用程序非常简单,只需在 Pod 架构中添加几个注解即可。例如,在以下示例中,您的 Kubernetes Pod 被注解为:
- 为您的服务提供一个 Dapr 已知的
id和port - 通过配置启用追踪
- 启动 Dapr 边车容器
annotations:
dapr.io/enabled: "true"
dapr.io/app-id: "nodeapp"
dapr.io/app-port: "3000"
dapr.io/config: "tracing"
有关更多信息,请查看 Dapr 注解。
从私有注册表拉取容器镜像
无论用户应用程序容器镜像来自何处,Dapr 都可以与其无缝协作。只需初始化 Dapr并将 Dapr 注解添加到您的 Kubernetes 定义中,即可添加 Dapr 边车。
Dapr 控制平面和边车镜像来自 daprio Docker Hub 容器注册表,这是一个公共注册表。
有关以下方面的信息:
- 从私有注册表拉取应用程序镜像,请参考 官方 Kubernetes 文档。
- 将 Azure Container Registry 与 Azure Kubernetes Service 结合使用,请参考 AKS 文档。
教程
通过Hello Kubernetes 教程了解有关在 Kubernetes 集群上开始使用 Dapr 的更多信息。
相关链接
2 - Kubernetes 集群设置
2.1 - 设置 Minikube 集群
前置条件
- 安装:
- 对于 Windows:
- 在 BIOS 中启用虚拟化
- 安装 Hyper-V
Note
有关支持的驱动程序以及如何安装插件的详细信息,请参阅 官方 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 客户端。
Important
最新的 Dapr Helm chart 不再支持 Helm v2。从 Helm v2 迁移到 Helm v3。故障排除
通过 kubectl get svc 无法显示负载均衡器的外部 IP 地址。
在 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 |
|-----------|----------------------|-------------|---------------------------|
🎉 Opening kubernetes service default/calculator-front-end in default browser...
相关链接
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此集群配置:
- 请求 KiND 启动一个由控制平面和两个工作节点组成的 Kubernetes 集群。
- 允许后续设置入口。
- 将容器端口暴露到主机。
运行
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 --kubernetesDapr 完成初始化后,您可以在集群上使用其核心组件。
验证 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.3 - 设置 Azure Kubernetes Service (AKS) 集群
本指南将引导您完成安装 Azure Kubernetes Service (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] --location [region] --node-count 2 --enable-app-routing --generate-ssh-keys获取 AKS 集群的访问凭据。
az aks get-credentials -n [your_aks_cluster_name] -g [your_resource_group]
AKS Edge Essentials
若要使用 Azure Kubernetes Service (AKS) Edge Essentials 创建单机 K8s/K3s 仅 Linux 集群,您可以参阅AKS Edge Essentials 快速入门指南。
注意
AKS Edge Essentials 默认不提供存储类,这可能会导致部署 Dapr 时出现问题。为避免此问题,请确保在部署 Dapr 之前在集群上启用 local-path-provisioner 存储类。如需更多信息,请参阅AKS EE 上的 Local Path Provisioner。相关链接
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 集群的边车注入
私有集群的边车注入需要额外步骤。
在私有 GKE 集群中,为 master 访问自动创建的防火墙规则不会打开端口 4000,而 Dapr 需要该端口进行边车注入。
查看相关的防火墙规则:
$ gcloud compute firewall-rules list --filter="name~gke-${CLUSTER_NAME}-[0-9a-z]*-master"
替换现有规则并允许 Kubernetes master 访问端口 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 dashboard 权限
假设您收到类似以下的错误消息:
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.5 - 设置 Elastic Kubernetes Service (EKS) 集群
本指南将引导您完成安装 Elastic Kubernetes Service (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-config.yaml验证 kubectl 上下文:
kubectl config current-context
添加 Dapr 的边车访问和默认存储类要求
更新安全组规则以允许 EKS 集群与 Dapr 边车通信,为端口 4000 创建入站规则。
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
服务账户的 IAM 角色 (IRSA)
您可以为 dapr_rbac Helm 子图表创建的 ServiceAccounts 附加自定义注解——这对于在 AWS EKS 上启用服务账户的 IAM 角色 (IRSA) 非常有用。
这可以通过 EKS 的 IRSA 机制为 Dapr 组件启用细粒度的安全访问控制。
更新您的 Dapr Helm 值文件以包含以下 ServiceAccounts 所需的注解。
有关 AWS 身份验证的更多信息,请参阅此处。
serviceAccount:
operator:
annotations:
eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/operator-role
injector:
annotations: {}
placement:
annotations: {}
scheduler:
annotations: {}
sentry:
annotations: {}
故障排除
访问权限
如果遇到任何访问权限问题,请确保您使用的是创建集群时所用的同一 AWS 配置文件。如需要,请使用正确的配置文件更新 kubectl 配置。更多信息请参见此处:
aws eks --region [your_aws_region] update-kubeconfig --name [your_eks_cluster_name] --profile [your_profile_name]
相关链接
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预期输出
⌛ Making the jump to hyperspace... ✅ 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运行仪表板:
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
预期输出:
⌛ 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...
✅ Deploying the Dapr Redis with latest version to your cluster...
✅ Deploying the Dapr Zipkin with latest version to your cluster...
ℹ️ Applying "statestore" component to Kubernetes "default" namespace.
ℹ️ Applying "pubsub" component to Kubernetes "default" namespace.
ℹ️ Applying "appconfig" zipkin configuration to Kubernetes "default" namespace.
✅ 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
等待一小段时间(或使用 --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.18 \ --namespace dapr-system \ --create-namespace \ --wait要以高可用模式安装:
helm upgrade --install dapr dapr/dapr \ --version=1.18 \ --namespace dapr-system \ --create-namespace \ --set global.ha.enabled=true \ --wait要以高可用模式安装并独立于全局扩展选定的服务:
helm upgrade --install dapr dapr/dapr \ --version=1.18 \ --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,是由 Microsoft 维护的免费开源 Linux 发行版和容器基础镜像。对于某些 Dapr 用户,利用基于 Mariner 的容器镜像可以帮助您满足合规性要求。
要为 Dapr 使用基于 Mariner 的镜像,您需要在 Docker 标签中添加 -mariner。例如,虽然 ghcr.io/dapr/dapr:latest 是基于 distroless 的 Docker 镜像,但 ghcr.io/dapr/dapr:latest-mariner 基于 Mariner。也可以使用特定版本的标签,例如 1.18-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.18 \
--namespace dapr-system \
--create-namespace \
--set global.tag=1.18.0-mariner \
--wait
相关链接
4 - 在 Kubernetes 集群上升级 Dapr
您可以使用 Dapr CLI 或 Helm 在 Kubernetes 集群上升级 Dapr 控制平面。
注意
请参阅 Dapr 版本策略 以获取有关 Dapr 升级路径的指导。使用 Dapr CLI 升级
您可以使用 Dapr CLI 来升级 Dapr。
前置条件
升级现有集群至 1.18.0
dapr upgrade -k --runtime-version=1.18.0
您可以使用 Dapr CLI 提供所有可用的 Helm chart 配置。
通过 CLI 进行升级的故障排查
在可能曾经安装过早于 1.0.0-rc.2 版本的集群上运行升级时,存在一个已知问题。
虽然这种情况很少见,但一些升级路径的边缘情况可能会在集群上留下不兼容的 CustomResourceDefinition。如果您遇到这种情况,您可能会看到类似如下的错误消息:
❌ Failed to upgrade Dapr: Warning: kubectl apply should be used on resource created by either kubectl create --save-config or kubectl apply
The CustomResourceDefinition "configurations.dapr.io" is invalid: spec.preserveUnknownFields: Invalid value: true: must be false in order to use defaults in the schema
解决方案
运行以下命令将
CustomResourceDefinition升级到兼容版本:kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/release-1.18/charts/dapr/crds/configuration.yaml继续执行
dapr upgrade --runtime-version 1.18.0 -k命令。
使用 Helm 升级
您可以使用 Helm v3 chart 升级 Dapr。
❗重要提示: 最新的 Dapr Helm chart 不再支持 Helm v2。从 Helm v2 迁移到 Helm v3。
前置条件
升级现有集群至 1.18.0
从 1.0.0 版本开始,使用 Helm 升级 Dapr 时,现有的证书值将自动被复用。
注意 Helm 不处理资源的升级,因此您需要手动执行该操作。资源具有向后兼容性,应仅向前安装。
将 Dapr 升级到版本 1.18.0:
kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.18.0/charts/dapr/crds/components.yaml kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.18.0/charts/dapr/crds/configuration.yaml kubectl replace -f https://raw.githubusercontent.com/dapr/dapr/v1.18.0/charts/dapr/crds/subscription.yaml kubectl apply -f https://raw.githubusercontent.com/dapr/dapr/v1.18.0/charts/dapr/crds/resiliency.yaml kubectl apply -f https://raw.githubusercontent.com/dapr/dapr/v1.18.0/charts/dapr/crds/httpendpoints.yamlhelm repo updatehelm upgrade dapr dapr/dapr --version 1.18.0 --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 部署以启用高可用模式
相关链接
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 readme 包含详细信息和示例。
对于本地/开发安装,您可能希望跳过配置 resources 选项。
可选组件
以下 Dapr 控制平面部署是可选的:
- Placement:用于使用 Dapr Actors
- Sentry:用于服务间调用的 mTLS
- Dashboard:用于集群的操作视图
边车资源设置
使用支持的注解为 Dapr 边车设置资源分配。与资源限制相关的具体注解为:
dapr.io/sidecar-cpu-limitdapr.io/sidecar-memory-limitdapr.io/sidecar-cpu-requestdapr.io/sidecar-memory-request
如果未设置,Dapr 边车将在没有资源设置的情况下运行,这可能导致问题。对于生产就绪的设置,强烈建议配置这些设置。
生产就绪设置中 Dapr 边车的示例设置:
| CPU | 内存 |
|---|---|
| 限制:300m,请求:100m | 限制:1000Mi,请求:250Mi |
上述 CPU 和内存限制考虑到了 Dapr 支持大量 I/O 密集型操作。使用监控工具 获取边车(和应用)容器的基线,并根据这些基线调整这些设置。
有关在 Kubernetes 中配置资源的更多详细信息,请参阅以下 Kubernetes 指南:
注意
由于 Dapr 旨在为您的应用程序处理大部分 I/O 密集型工作,因此分配给 Dapr 的资源会大幅减少应用程序的资源分配。为 Dapr 边车设置软内存限制
当您已设置内存限制时,为 Dapr 边车设置软内存限制。使用软内存限制时,边车垃圾回收器会在超过限制时释放内存,而不是等待内存达到运行时堆中上次内存量的两倍。等待是 Go 中使用的垃圾回收器的默认行为,可能导致 OOM 终止事件。
例如,对于 app-id 为 nodeapp 且内存限制设置为 1000Mi 的应用程序,您可以在 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。
用于企业策略的边车服务注解
在企业环境中,集群策略可能会强制所有 Service 资源使用强制性注解,用于安全、计费或网络策略目的。Dapr Operator 为边车创建一个 Service,该服务可能需要这些自定义注解以符合您组织的策略。
您可以使用 dapr.io/sidecar-svc-annotations 注解将这些必需的注解添加到 Dapr 边车服务。
高可用模式
在生产就绪配置中部署 Dapr 时,最好以控制平面的高可用(HA)配置进行部署。这会在 dapr-system 命名空间中为每个控制平面 Pod 创建三个副本,使 Dapr 控制平面能够保持三个运行实例,并在单个节点故障和其他中断中存活。
对于新的 Dapr 部署,可以通过以下方式设置 HA 模式:
对于现有的 Dapr 部署,您可以通过一些额外步骤启用 HA 模式。
单个服务 HA Helm 配置
您可以通过将 global.ha.enabled 标志设置为 true 来通过 Helm 在所有服务中配置 HA 模式。默认情况下,--set global.ha.enabled=true 被完全遵守且不能被覆盖,这使得 placement 或 scheduler 服务无法同时作为单个实例运行。
注意: scheduler 和 placement 服务的 HA 不是默认设置。
要独立于 global.ha.enabled 标志将 scheduler 和 placement 扩展到三个实例,请将 global.ha.enabled 设置为 false,并将 dapr_scheduler.ha 和 dapr_placement.ha 设置为 true。例如:
helm upgrade --install dapr dapr/dapr \
--version=1.18 \
--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 都被驱逐。
保护 Dapr 控制平面组件免于驱逐尤为重要,尤其是 Scheduler 服务。当 Scheduler 被重新调度或重启时,可能会对正在进行的作业造成严重破坏,可能导致它们重复触发。为了防止这种破坏,您应该确保 Dapr 控制平面组件比您的工作负载具有更高的优先级类。
了解有关保护任务关键型 Pod 的更多信息。
Kubernetes 中有两个内置的关键优先级类:
system-cluster-criticalsystem-node-critical(最高优先级)
建议为 Dapr 控制平面 Pod 将 priorityClassName 设置为 system-cluster-critical。如果您有自己的应用程序自定义优先级类,请确保它们的优先级值低于分配给 Dapr 控制平面的优先级值,以维持系统稳定性并防止核心 Dapr 服务中断。
对于新的 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 在您的路径中。
升级控制平面
更新数据平面(边车)
更新运行 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 stateful set。
kubectl delete statefulset.apps/dapr-placement-server -n dapr-system您删除 placement stateful set 是因为在 HA 模式下,placement 服务会添加 Raft 用于领导者选举。但是,Kubernetes 只允许对 stateful set 的有限字段进行修补,从而导致 placement 服务升级失败。
删除现有的 placement stateful set 是安全的。代理会重新连接并重新注册到新创建的 placement 服务,该服务将其表持久化在 Raft 中。
发出升级命令。
helm upgrade dapr ./charts/dapr -n dapr-system --set global.ha.enabled=true
推荐的安全配置
正确配置后,Dapr 可确保安全通信,并可以通过许多内置功能使您的应用程序更安全。
验证您的生产就绪部署包括以下设置:
双向身份验证(mTLS) 已启用。Dapr 默认启用 mTLS。了解有关如何使用自己的证书的更多信息。
应用程序到 Dapr API 身份验证 已启用。这是您的应用程序与 Dapr 边车之间的通信。为了保护 Dapr API 免受未经授权的应用程序访问,请启用 Dapr 的基于令牌的身份验证。
Dapr 到应用程序 API 身份验证 已启用。这是 Dapr 与您的应用程序之间的通信。让 Dapr 知道它正在使用令牌身份验证与授权应用程序通信。
组件密钥数据在密钥存储中配置,而不是硬编码在组件 YAML 文件中。了解如何将密钥与 Dapr 组件一起使用。
Dapr 控制平面安装在专用命名空间上,例如
dapr-system。Dapr 支持并启用为某些应用程序限定组件范围。这不是必需的做法。了解有关组件范围的更多信息。
推荐的 Placement 服务配置
Placement 服务 是 Dapr 中的一个组件,负责通过 placement 表向所有 Dapr 边车传播有关 actor 地址的信息(有关更多信息可以在这里找到)。
在生产环境中运行时,建议使用以下值配置 Placement 服务:
- 高可用性。确保 Placement 服务高度可用(三个副本)并且可以在单个节点故障中存活。Helm chart 值:
dapr_placement.ha=true - 内存日志。使用内存 Raft 日志存储以实现更快的写入。权衡是在最终的 Placement 服务 Pod 故障期间更多的 placement 表传播(因此,网络流量)。Helm chart 值:
dapr_placement.cluster.forceInMemoryLog=true - 无元数据端点。禁用未经身份验证的
/placement/state端点,该端点暴露 Placement 服务的 placement 表信息。Helm chart 值:dapr_placement.metadataEnabled=false - 超时使用以下超时值控制 Placement 服务与边车之间网络连接的敏感性。默认值已设置,但您可以根据您的网络条件调整这些值。
dapr_placement.keepAliveTime设置 Placement 服务在 gRPC 流上向 Dapr 边车发送保活 ping 以检查连接是否仍处于活动状态的间隔。较低的值将导致在 Pod 丢失/重启情况下更短的 actor 重新平衡时间,但在正常运行期间网络流量更高。接受1s到10s之间的值。默认为2s。dapr_placement.keepAliveTimeout设置 Dapr 边车响应 Placement 服务的保活 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 密钥存储 或 Kubernetes Events 绑定。
因此,Dapr 不会自动为您设置 automountServiceAccountToken: false。但是,在您的解决方案不需要服务账户的所有情况下,建议您在 Pod spec 中设置此选项。
注意
使用作为 Kubernetes secrets 存储的组件密钥初始化 Dapr 组件不需要您的 Pod 拥有服务账户令牌;Dapr Operator 在注入时解析secretKeyRef。要使用 automountServiceAccountToken: false 运行,请使用注解 dapr.io/disable-builtin-k8s-secret-store: "true" 禁用边车的内置 Kubernetes 密钥存储。仅当您的应用程序使用运行时密钥管理构建块时才保持密钥存储启用(并挂载令牌)。追踪和指标配置
追踪和指标在 Dapr 中默认启用。建议您为应用程序和 Dapr 控制平面设置分布式追踪和指标。
如果您已经有自己的可观测性设置,可以禁用 Dapr 的追踪和指标。
追踪
指标
对于指标,Dapr 会暴露一个在端口 9090 上监听的 Prometheus 端点,Prometheus 可以对其进行抓取。
使用 Dapr 设置 Prometheus、Grafana 和其他监控工具。
注入器看门狗
Dapr Operator 服务包含一个注入器看门狗,可用于检测和修复应用程序 Pod 可能没有 Dapr 边车(daprd 容器)部署的情况。例如,它可以帮助在集群完全故障后恢复应用程序。
在 Kubernetes 模式下运行 Dapr 时,注入器看门狗默认处于禁用状态。但是,您应该考虑针对您的具体情况使用适当的值启用它。
有关注入器看门狗以及如何启用它的更多详细信息,请参阅 Dapr operator 服务文档。
为边车容器配置 seccompProfile
默认情况下,Dapr 边车注入器会注入一个没有任何 seccompProfile 的边车。但是,为了使 Dapr 边车容器在带有受限配置文件的命名空间中成功运行,边车容器需要 securityContext.seccompProfile.Type 不为 nil。
请参阅参数和注解概述以在边车容器上设置适当的 seccompProfile。
以非 root 用户运行
在 Kubernetes 中运行时,Dapr 服务确保每个进程都以非 root 用户运行。
这是通过检查进程的 UID 和 GID 是否为 65532 来完成的,如果不是预期的值则会致命错误。
如果您必须在 Kubernetes 中运行非默认的 UID 和 GID,请设置以下环境变量以跳过此检查。
DAPR_UNSAFE_SKIP_CONTAINER_UID_GID_CHECK="true"
最佳实践
观看此视频,深入了解使用 Kubernetes 在生产环境中运行 Dapr 的最佳实践。
相关链接
6 - 使用 Dapr Shared 每节点或每集群部署 Dapr
Dapr 会自动注入一个边车,为您的应用程序启用 Dapr API,以获得最佳的可用性和可靠性。
Dapr Shared 支持两种替代部署策略,可以使用 Kubernetes Daemonset 进行每节点部署,或使用 Deployment 进行每集群部署,从而创建 Dapr 应用程序。
DaemonSet:当以 KubernetesDaemonSet资源运行 Dapr Shared 时,daprd 容器会在集群中的每个 Kubernetes 节点上运行。这可以减少应用程序与 Dapr 之间的网络跳数。Deployment:当以 KubernetesDeployment运行 Dapr Shared 时,Kubernetes 调度器会决定 daprd 容器实例在集群中的哪个单个节点上运行。
Dapr Shared 部署
对于您部署的每个 Dapr 应用程序,您需要使用不同的shared.appId 部署 Dapr Shared Helm chart。为什么选择 Dapr Shared?
默认情况下,当 Dapr 安装到 Kubernetes 集群时,Dapr 控制平面会将 Dapr 作为边车注入到使用 Dapr 注解(dapr.io/enabled: "true")的应用程序中。边车提供了许多优势,包括提高的弹性,因为每个应用程序都有一个实例,并且应用程序与边车之间的所有通信都在不涉及网络的情况下进行。

虽然边车是 Dapr 的默认部署方式,但某些用例需要其他方法。假设您想要将工作负载的生命周期与 Dapr API 解耦。一个典型的例子是函数或函数即服务运行时,它们可能会自动缩减空闲工作负载以释放资源。对于这种情况,可能需要将 Dapr API 和所有 Dapr 异步功能(如订阅)分开保存。
Dapr Shared 正是为这些场景而创建的,它扩展了 Dapr 边车模型,增加了两种新的部署方法:DaemonSet(每节点)和 Deployment(每集群)。
重要
无论您选择哪种部署方法,重要的是要理解,在大多数用例中,每个服务(app-id)都有一个 Dapr Shared 实例(Helm release)。这意味着如果您有一个由三个微服务组成的应用程序,建议每个服务都有自己的 Dapr Shared 实例。您可以通过尝试 Hello Kubernetes with Dapr Shared 教程来查看实际操作。DaemonSet(每节点)
使用 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 的 release 名称。
如果您使用的是 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 仓库 中阅读更多信息
7 - 操作指南:持久化 Scheduler 作业
Scheduler 服务负责将作业写入其 Etcd 数据库并调度它们执行。
默认情况下,Scheduler 服务数据库内嵌 Etcd,并将数据写入大小为 1Gb 的持久卷声明卷,使用集群的默认存储类。
这意味着在大多数 Kubernetes 部署上可靠运行调度器服务不需要额外的参数,但如果默认的 StorageClass 不可用或在生产环境中运行,则需要额外的配置。
警告
Scheduler 的默认存储大小为1Gi,这很可能不足以满足大多数生产部署的需求。
请记住,Scheduler 用于 Actor Reminders 和 工作流,以及 Jobs API。
您可能需要考虑重新安装 Dapr,并使用更大的 Scheduler 存储,至少 16Gi 或更多。
有关更多信息,请参阅下面的 ETCD 存储磁盘大小 部分。生产环境设置
ETCD 存储磁盘大小
Scheduler 的默认存储大小为 1Gb。
这个大小很可能不足以满足大多数生产部署的需求。
当超过存储大小时,Scheduler 将记录类似于以下的错误:
error running scheduler: etcdserver: mvcc: database space exceeded
了解存储大小的安全上限不是一门精确的科学,并且很大程度上取决于应用程序作业的数量、持久性和数据有效负载大小。 Job API 和 Actor Reminders 透明地一对一映射到您的应用程序使用情况。 工作流作为 Actor Reminders 创建大量作业,但这些作业是短暂的——与每个工作流执行的生命周期相匹配。 由工作流创建的作业的数据有效负载通常为空或很小。
Scheduler 使用 Etcd 作为其后端存储数据库。 根据设计,Etcd 以 预写日志(WAL)和快照 的形式持久化历史事务和数据。 这意味着 Scheduler 的实际磁盘使用量将高于当前可观察的数据库状态,通常是多倍。
在安装时设置存储大小
如果需要增加现有 Scheduler 存储大小,请参阅下面的增加 Scheduler 存储大小 部分。
要为全新 Dapr 安装增加存储大小(在此示例中为 16Gi),可以使用以下命令:
dapr init -k --set dapr_scheduler.cluster.storageSize=16Gi --set dapr_scheduler.etcdSpaceQuota=16Gi
helm upgrade --install dapr dapr/dapr \
--version=1.18 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.storageSize=16Gi \
--set dapr_scheduler.etcdSpaceQuota=16Gi \
--wait
注意
对于不支持动态卷扩展的存储提供商:如果集群上曾经安装过 Dapr,则必须手动卸载 Scheduler 的持久卷声明,以便创建具有增加存储大小的新卷声明。
kubectl delete 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
持久卷声明不会在卸载 时自动删除。这是一项旨在防止意外数据丢失的故意安全措施。
增加现有 Scheduler 存储大小
警告
并非所有存储提供商都支持动态卷扩展。 请参阅您的存储提供商文档,以确定是否支持此功能,以及如果不支持该怎么做。默认情况下,每个 Scheduler 将为每个 Scheduler 副本针对默认 standard 存储类创建大小为 1Gi 的持久卷和持久卷声明。
这些将类似于以下内容,在此示例中,我们在 HA 模式下运行 Scheduler。
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
要扩展 Scheduler 的存储大小,请按照以下步骤操作:
- 首先,确保存储类支持卷扩展,并且如果
allowVolumeExpansion字段尚未设置为true,请将其设置为true。
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: standard
provisioner: my.driver
allowVolumeExpansion: true
...
- 在保留绑定的持久卷声明的同时,删除 Scheduler StatefulSet。
kubectl delete sts -n dapr-system dapr-scheduler-server --cascade=orphan
- 通过编辑
spec.resources.requests.storage字段,将持久卷声明的大小增加到所需的大小。 同样在这种情况下,我们假设 Scheduler 在 HA 模式下运行,有 3 个副本。
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 来重新创建 Scheduler StatefulSet。
存储类
如果您的 Kubernetes 部署没有默认存储类,或者您正在配置生产集群,则需要定义存储类。
持久卷由托管的云提供商或 Kubernetes 基础设施平台提供的真实磁盘支持。 磁盘大小取决于预期要一次持久化的作业数量;但是,对于大多数生产场景,64Gb 应该绰绰有余。 一些 Kubernetes 提供商建议使用 CSI 驱动程序来提供底层磁盘。 以下是有关为主要云提供商创建持久磁盘的相关文档的有用链接列表:
一旦存储类可用,您可以使用以下命令安装 Dapr,其中 Scheduler 配置为使用存储类(将 my-storage-class 替换为存储类的名称):
dapr init -k --set dapr_scheduler.cluster.storageClassName=my-storage-class
helm upgrade --install dapr dapr/dapr \
--version=1.18 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.storageClassName=my-storage-class \
--wait
临时存储
在非 HA 模式下运行时,可以选择让 Scheduler 使用临时存储,这是一种不能够抵御重启的内存存储。例如,所有作业数据在 Scheduler 重启后都会丢失。 这对于非生产部署或测试非常有用,在这些情况下存储不可用或不需要。
dapr init -k --set dapr_scheduler.cluster.inMemoryStorage=true
helm upgrade --install dapr dapr/dapr \
--version=1.18 \
--namespace dapr-system \
--create-namespace \
--set dapr_scheduler.cluster.inMemoryStorage=true \
--wait
8 - 部署到混合 Linux/Windows Kubernetes 集群
Dapr 支持在以下 Kubernetes 集群上运行微服务:
- Windows
- Linux
- 两者组合
这在将传统应用程序逐步迁移到 Dapr Kubernetes 集群时特别有用。
Kubernetes 使用一个称为**节点亲和性(node affinity)**的概念来表示你希望应用程序在 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 应用
创建包含应用的 Docker 容器后,创建一个部署 YAML 文件,将节点亲和性设置为
kubernetes.io/os: windows。在下面的示例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 应用,仍然需要添加亲和性规则。
创建一个部署 YAML 文件,将节点亲和性设置为
kubernetes.io/os: linux。在下面的示例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
相关链接
9 - 在 Kubernetes Job 中运行 Dapr
Dapr 边车被设计为一个长期运行的进程。在 Kubernetes Job 的上下文中,这种行为可能会阻止您的 Job 完成。
在运行基本的 Kubernetes Job时,您需要调用 /shutdown 端点以使边车优雅停止,并将 Job 视为 Completed。
当 Job 在未调用 Shutdown 的情况下结束时,您的 Job 将处于 NotReady 状态,只有 daprd 容器无休止地运行。
停止 Dapr 边车会导致其就绪探针和存活探针在您的容器中失败。
为了防止 Kubernetes 尝试重启您的 Job,请将 Job 的 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
}
相关链接
10 - 操作指南:将 Pod 卷挂载到 Dapr 边车
Dapr 边车可以被配置来挂载任何附加到应用 Pod 的 Kubernetes 卷。这些卷可以被 daprd(边车)容器以 只读 或 读写 模式访问。如果一个卷被配置为挂载但在 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 边车容器内的任何文件夹中挂载卷,但为了避免冲突并确保未来的平稳运行,请将所有挂载点放在以下位置之一,或其子文件夹内:
| 位置 | 描述 |
|---|---|
/mnt | 推荐用于包含持久化数据的卷,Dapr 边车进程可以读取和/或写入这些数据。 |
/tmp | 推荐用于包含临时数据的卷,例如临时磁盘。 |
示例
基本部署资源示例
在下面的部署资源示例中:
my-volume1以只读模式在边车容器内的/mnt/sample1处可用my-volume2以只读模式在边车容器内的/mnt/sample2处可用my-volume3以读写模式在边车容器内的/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: {}
...
使用本地文件密钥存储的自定义密钥存储
由于任何类型的 Kubernetes 卷都可以附加到边车,你可以使用本地文件密钥存储从各种地方读取密钥。例如,如果你有一个运行在 10.201.202.203 的网络文件共享(NFS)服务器,密钥存储在 /secrets/stage/secrets.json,你可以将其用作密钥存储。
配置应用 Pod 以挂载 NFS 并将其附加到 Dapr 边车。
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 ...将本地文件密钥存储组件指向附加的文件。
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使用密钥。
GET http://localhost:<daprPort>/v1.0/secrets/local-secret-store/my-secret