Prerequisites
Verify your environment meets the following requirements before installing Conductor.
Deployment checklist
Before you can successfully deploy Conductor, ensure you have:
- Kubernetes cluster v1.21 or higher
- kubectl access with cluster-admin permissions
- Conductor account (free, no credit card required)
- Network connectivity - Outbound internet access to these addresses
- Kubernetes metrics server installed
Supported Kubernetes distributions
Conductor is officially tested on the following Kubernetes distributions.
| Platform | Version | What's Pre-Installed | Additional Requirements |
|---|---|---|---|
| Amazon EKS | 1.21+ | RBAC, CSI, Load balancer | Metrics Server must be installed separately |
| Google GKE | 1.21+ | Metrics Server, RBAC, CSI, Load balancer | - |
| Azure AKS | 1.21+ | Metrics Server, RBAC, CSI, Load balancer | - |
| RedHat OpenShift | 4.6+ | Metrics Server, RBAC | Cluster admin or SCC permissions; Network egress for outbound HTTPS |
| Local (Kind, Minikube, Docker Desktop) | 1.21+ | - | Docker running; Metrics Server with TLS workaround (see below) |
| On-Premises | 1.21+ | Varies | RBAC enabled; Metrics Server; Persistent volume support |
| ARM-based (M1/M2, Graviton, Ampere) | 1.21+ | Varies by provider | Node selectors for ARM64 - ARM guide |
Additional Kubernetes distributions haven't been officially tested with Conductor. You may try them at your own risk.
Metrics Server TLS workaround for local clusters:
After installing the Kubernetes Metrics Server on local Kubernetes clusters, you may need to account for this requirement: Kubelet certificate needs to be signed by cluster Certificate Authority (or disable certificate validation by passing --kubelet-insecure-tls to Metrics Server). To pass that flag, use this command on your cluster:
kubectl patch deployment metrics-server -n kube-system --type "json" \
-p '[{"op": "add", "path": "/spec/template/spec/containers/0/args/-", "value": "--kubelet-insecure-tls"}]'
Cluster resource requirements
Conductor agent
The Conductor agent consists of three components with the following default resource requests:
| Component | Type | Default Resources | Replicas | Deployed On |
|---|---|---|---|---|
| diagrid-agent | Deployment | 200m CPU, 400Mi memory | 2 | Selected nodes |
| diagrid-agent-logs-collector | DaemonSet | 200m CPU, 400Mi memory | 1 per node* | All nodes* |
| diagrid-agent-otel | StatefulSet | 200m CPU, 400Mi memory | 2 | Selected nodes |
*The Logs Collector and Otel Collector (metrics) use a modified version of the OpenTelemetry Collector. The Logs Collector runs on every node by default—use node selectors, affinity rules, or tolerations to restrict to nodes with Dapr applications for best results.
Dapr control plane resources
Conductor can install Dapr with recommended resource configurations automatically. Default Dev and Prod profiles set appropriate values based on Dapr production guidelines.
Read the Configuration Guide for more details.
Network requirements
Required outbound access
Your cluster must have outbound internet access to the following endpoints. No inbound access required, the Conductor agent uses outbound egress only.
| Endpoint | Purpose | Port |
|---|---|---|
conductor.diagrid.io, https://conductor.r1.diagrid.io | Console and control plane | 443 |
cloudgrid.diagrid.io, https://cloudgrid.r1.diagrid.io | Agent communication | 443 |
metrics.diagrid.io, https://metrics.r1.diagrid.io | Telemetry and metrics | 443 |
Optional endpoints for Dapr installation & upgrades
If Conductor will install or upgrade Dapr using the upstream Helm chart and container images, also allow:
https://dapr.github.io/helm-charts/https://hub.docker.comhttps://auth.docker.iohttps://registry.docker.iohttps://registry-1.docker.iohttps://production.cloudflare.docker.com
If using Dapr container images from a private registry, these addresses are not required. However, you become responsible for managing the Dapr Helm chart and container images, including upgrades. See Private Registry Guide.
Network policies
If using Kubernetes network policies, ensure the following is connectivity is allowed:
- Conductor agent → Dapr sidecars: Port
3501(Dapr metadata API, resources) - Conductor agent → Dapr control plane namespace (resources)
RBAC permissions
Installation permissions
- Required: Kubernetes cluster admin role (or equivalent) to install the Conductor agent.
- After installation: Only namespace-level permissions needed for the
diagrid-cloudand application namespaces.
Conductor agent permissions
The Conductor agent requires Kubernetes RBAC permissions to:
- Monitor Dapr control plane and workloads
- Install and upgrade Dapr components (if managing Dapr)
- Perform component initialization checks
- Roll out applications with updated Dapr sidecars
If you install with Helm managed mode, the agent operates in read-only mode with reduced permissions. A minimal set of write rules remain for agent operation (leases, configmaps for checkpoints).
Permission details
- Dapr Control Plane: RBAC rules use
resourceNameswhere possible for least-privilege access - Dapr Workloads: Dynamic names prevent
resourceNames, so follows Dapr RBAC chart - Workload Rollouts: To roll out applications and ensure they receive the latest version of the Dapr sidecar, the agent patches Kubernetes Deployment, DaemonSet, StatefulSet, and Job resources by modifying the
diagrid.io/restartedAtannotation to trigger a rollout - Component Init: Agent reads component secrets to validate initialization - Learn more →
Helm managed cluster connection (read-only mode)
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"persistentvolumeclaims",
"serviceaccounts",
]
verbs: ["get"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"persistentvolumeclaims",
"endpoints",
"replicasets",
]
verbs: ["list"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"leases",
"pods",
"nodes",
"nodes/metrics",
"nodes/proxy",
"jobs",
"cronjobs",
"endpoints",
]
verbs: ["watch"]
- apiGroups: ["metrics.k8s.io"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
# ⓘ by default, these are permitted cluster-wide. with the Helm managed agent, these are restricted to the agent and dapr namespaces.
# ⓘ however, with the Helm managed agent + component init disabled, these are restricted to the agent and dapr namespaces.
# ⓘ see more at https://docs.diagrid.io/conductor/observe/components#disabling-initialization
- apiGroups: ["*"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["get"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
verbs: ["get"]
- apiGroups: ["", "apps", "extensions"]
resources: ["deployments", "pods", "pods/log", "namespaces"]
verbs: ["get", "list"]
- apiGroups: ["*"]
resources:
[
"components",
"configurations",
"subscriptions",
"resiliencies",
"httpendpoints",
]
verbs: ["get", "list", "watch"]
- apiGroups: ["dapr.io"]
resources: ["*"]
verbs: ["get", "list", "watch", "patch", "update"]
- apiGroups: ["apps", "*"]
resources: ["statefulsets", "statefulsets/finalizers"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets"]
verbs: ["get", "list", "watch"]
- nonResourceURLs:
- /metrics
verbs: ["get"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "create", "update"]
# ⓘ `resourceName` limited:
# (some write verbs necessary)
- apiGroups: ["*"]
resources: ["configmaps"]
verbs: ["get", "list", "watch", "create", "patch"]
resourceNames:
- agent-checkpoint
- agent-dependencies-checkpoint
- dapr-checkpoint
- diagnostics-checkpoint
- rollouts-checkpoint
# ⓘ OPTIONAL: present only if the cluster was set as OpenShift:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
verbs: ["get"]
# ⓘ OPTIONAL: present only if the cluster has enabled Certificate Rotation:
# (some write verbs necessary)
- apiGroups:
[
"admissionregistration.k8s.io",
"dapr.io",
"policy",
"rbac.authorization.k8s.io",
]
resources:
[
"mutatingwebhookconfigurations",
"configurations",
"poddisruptionbudgets",
"clusterroles",
]
verbs: ["get", "update", "patch"]
- apiGroups: ["apps"]
resources: ["statefulsets", "deployments"]
verbs: ["get", "update", "patch"]
- apiGroups: ["*"]
resources: ["configmaps", "secrets"]
verbs: ["get", "list", "watch", "create", "patch", "update", "delete"]
Manifest backed cluster connection (Full management mode)
- apiGroups: ["*"]
resources:
[
"services",
"secrets",
"configmaps",
"leases",
"services/finalizers",
"deployments/finalizers",
"pods",
"nodes",
"endpoints",
]
verbs: ["update"]
- apiGroups: ["*"]
resources: ["services", "leases", "secrets", "persistentvolumeclaims"]
verbs: ["delete"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"configmaps",
"events",
"leases",
"secrets",
"namespaces",
"serviceaccounts",
]
verbs: ["create"]
- apiGroups: ["*"]
resources:
[
"deployments",
"services",
"configmaps",
"leases",
"secrets",
"namespaces",
"serviceaccounts",
]
verbs: ["patch", "update"]
- apiGroups: ["*"]
resources: ["pods"]
verbs: ["patch"]
- apiGroups: ["*"]
resources:
[
"components",
"configurations",
"subscriptions",
"resiliencies",
"httpendpoints",
]
verbs: ["create", "patch", "update"]
- apiGroups: ["dapr.io"]
resources: ["*"]
verbs: ["create", "patch", "update"]
- apiGroups: ["apps", "*"]
resources: ["statefulsets", "statefulsets/finalizers"]
verbs: ["create", "patch", "update", "delete"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets"]
verbs: ["create", "patch", "update"]
# OpenShift specific permissions, only present if OpenShift was selected as the distribution:
- apiGroups: ["security.openshift.io"]
resources: ["securitycontextconstraints"]
verbs: ["create", "patch"]
# `resourceName` specified:
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings", "roles", "rolebindings"]
resourceNames:
["dapr-dashboard", "dashboard-reader", "dashboard-reader-global"]
verbs: ["delete"]
- apiGroups: [""]
resources: ["serviceaccounts", "services"]
verbs: ["delete"]
resourceNames: ["dapr-dashboard", "dashboard-reader"]
- apiGroups: ["apps"]
resources: ["deployments", "deployments/finalizers"]
verbs: ["delete"]
resourceNames: ["dapr-dashboard"]
- apiGroups: ["apps"]
resources: ["deployments", "daemonsets", "statefulsets"]
verbs: ["create"] # create, list, watch cannot use resourceNames
- apiGroups: ["apps"]
resources: ["deployments"]
resourceNames: ["dapr-operator", "dapr-sentry", "dapr-sidecar-injector"]
verbs: ["get", "patch", "update"]
- apiGroups: [""] # needed for downgrading from 1.15 to 1.14
resources: ["persistentvolumeclaims"]
verbs: ["get", "list", "delete"]
resourceNames:
- dapr-scheduler-data-dir-dapr-scheduler-server-0
- dapr-scheduler-data-dir-dapr-scheduler-server-1
- dapr-scheduler-data-dir-dapr-scheduler-server-2
- apiGroups: ["apps"]
resources: ["daemonsets", "deployments", "statefulsets"]
resourceNames:
["diagrid-agent-logs-collector", "diagrid-agent", "diagrid-agent-otel"]
verbs: ["get", "patch", "update"]
- apiGroups: ["apps"]
resources: ["statefulsets"]
resourceNames: ["dapr-placement-server", "dapr-scheduler-server"]
verbs: ["get", "patch", "update", "delete"] # delete is required when going from non-HA to HA
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get", "update", "delete"]
resourceNames: ["dapr-trust-bundle"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "update"]
resourceNames: ["dapr-trust-bundle"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["create"]
- apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
verbs: ["get", "update"]
resourceNames: ["operator.dapr.io", "webhooks.dapr.io"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "update"]
resourceNames: ["operator.dapr.io", "webhooks.dapr.io"]
- apiGroups: ["apps"]
resources: ["deployments/finalizers"]
resourceNames: ["dapr-operator", "dapr-sentry", "dapr-sidecar-injector"]
verbs: ["update"]
- apiGroups: ["apps"]
resources: ["statefulsets/finalizers"]
resourceNames: ["dapr-placement-server", "dapr-scheduler-server"]
verbs: ["update"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs: ["create"]
- apiGroups: ["admissionregistration.k8s.io"]
resources: ["mutatingwebhookconfigurations"]
verbs: ["get", "patch", "update", "delete"]
resourceNames: ["dapr-sidecar-injector"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["create"]
- apiGroups: ["policy"]
resources: ["poddisruptionbudgets"]
verbs: ["patch", "update"]
resourceNames:
- dapr-operator-disruption-budget
- dapr-placement-server-disruption-budget
- dapr-scheduler-server-disruption-budget
- dapr-sentry-budget
- dapr-sidecar-injector-disruption-budget
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "update"]
resourceNames:
- dapr-placement-server
- dapr-scheduler-server
- dapr-sentry
- dapr-sidecar-injector
- dapr-api
- dapr-webhook
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["create"] # cannot use resourceNames for CRDs creation role
- apiGroups: ["*"]
resources: ["customresourcedefinitions"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"components.dapr.io",
"configurations.dapr.io",
"subscriptions.dapr.io",
"resiliencies.dapr.io",
"httpendpoints.dapr.io",
"pluggablecomponents.dapr.io",
]
- apiGroups: ["apiextensions.k8s.io"]
resources: ["customresourcedefinitions"]
verbs: ["get", "patch", "update"]
resourceNames: ["clusterconnections.conductor.diagrid.io"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles", "clusterrolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator-admin",
"dapr-injector",
"dapr-scheduler",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator",
"dapr-injector",
"dapr-scheduler",
"secret-reader",
"dapr-secret-reader",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-sentry",
"dapr-placement",
"dapr-operator",
"dapr-injector",
"dapr-scheduler",
]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles", "rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames: ["secret-reader", "dapr-secret-reader"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "patch", "update"]
resourceNames:
[
"dapr-operator",
"dapr-placement",
"dapr-scheduler",
"dapr-sentry",
"dapr-injector",
]
# Required by dapr 1.14
- apiGroups: [""]
resources: ["resourcequotas"]
verbs: ["create", "list", "watch"]
- apiGroups: [""]
resources: ["resourcequotas"]
verbs: ["get", "patch", "update", "delete"]
resourceNames: ["dapr-system-critical-quota", "system-critical-quota"]
# Required by dapr 1.15
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch"]
# Diagrid ClusterRole and ClusterRoleBinding
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["patch", "update"]
resourceNames:
- diagrid-agent-dashboard-reader
- diagrid-agent-dapr-operator-admin
- diagrid-operator-dashboard-reader
- diagrid-operator-dapr-operator-admin
- diagrid
- diagrid-operator-agent-role
- diagrid-operator-role
- dapr-dashboard
- dashboard-reader
- dashboard-reader-global
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
- diagrid-agent-dapr-operator
- diagrid-agent-dashboard-reader
- diagrid-agent-dapr-role-tokenreview-binding
- diagrid-agent-dashboard-reader-global
- diagrid-operator-dapr-operator
- diagrid-operator-dashboard-reader
- diagrid-operator-dapr-role-tokenreview-binding
- diagrid-operator-dashboard-reader-global
- diagrid
- diagrid-operator-agent-role
- diagrid-operator-operator-role
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["patch", "update"]
resourceNames:
- diagrid-operator-role-cm
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "patch", "update"]
resourceNames:
- diagrid-operator-operator-role
Next steps
Install Conductor
Choose your installation method and follow step-by-step instructions
Quickstart Guide
Get Conductor running in 10 minutes with a minimal local setup
Cluster Insights
Dive into Dapr insights from your apps in Conductor