Botkube Installation Guide
Overview
This guide covers the installation of Botkube on a K3s Raspberry Pi 5 cluster with Slack integration, using HashiCorp Vault for secret management and FluxCD for GitOps deployment.
Architecture
- Cluster: K3s on Raspberry Pi 5
- GitOps: FluxCD
- Secret Management: HashiCorp Vault + External Secrets Operator
- Communication: Slack (Socket Mode)
- Storage: Persistent volume for plugin caching
Prerequisites
- K3s cluster running
- FluxCD installed and configured
- HashiCorp Vault deployed with KV secrets engine
- External Secrets Operator installed with ClusterSecretStore configured
- Slack workspace with admin access
Directory Structure
infrastructure/
├── controllers/base/botkube/
│ ├── kustomization.yaml
│ ├── kustomizeconfig.yaml
│ ├── namespace.yaml
│ ├── pvc.yaml
│ ├── release.yaml
│ ├── repository.yaml
│ └── values.yaml
└── configs/base/botkube/
├── botkube-slack-secrets.yaml
└── kustomization.yaml
Step 1: Create Slack App
1.1 Create the App
- Go to https://api.slack.com/apps
- Click “Create New App” → “From scratch”
- Name it “Botkube” (or your preferred name)
- Select your workspace
1.2 Configure OAuth Scopes
Navigate to OAuth & Permissions and add these Bot Token Scopes:
app_mentions:read- View messages that directly mention the botchannels:history- View messages in public channelschannels:read- View basic channel informationchat:write- Send messagescommands- Add shortcuts and/or slash commandsfiles:write- Upload filesusers:read- View people in the workspaceusers:read.email- View email addresses (optional)
1.3 Enable Socket Mode
- Go to Socket Mode in the sidebar
- Enable Socket Mode
- Generate an App-Level Token with
connections:writescope - Save the token (starts with
xapp-)
1.4 Get Bot Token
- Go to OAuth & Permissions
- Click “Install to Workspace”
- Copy the Bot User OAuth Token (starts with
xoxb-)
1.5 Configure App Display
- Go to Basic Information
- Under Display Information:
- Upload Kubernetes icon (download from: https://raw.githubusercontent.com/cncf/artwork/master/projects/kubernetes/icon/color/kubernetes-icon-color.png)
- Add app description
- Set background color
1.6 Create Slack Channel
- Create a channel in Slack (e.g.,
k3s-pi5cluster)- Note: Channel name must be lowercase, no special characters
- Invite your Botkube app to the channel:
/invite @Botkube
Step 2: Store Secrets in Vault
Store your Slack tokens in Vault:
# Store both tokens in Vault
vault kv put secret/botkube-slack-secrets \
botToken="xoxb-your-bot-token-here" \
appToken="xapp-your-app-token-here"
# Verify the secrets
vault kv get secret/botkube-slack-secrets
Note: Adjust the path (secret/botkube-slack-secrets) based on your Vault mount point.
Step 3: Deploy Botkube with FluxCD
3.1 Create Namespace
File: infrastructure/controllers/base/botkube/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
name: botkube
3.2 Add Helm Repository
File: infrastructure/controllers/base/botkube/repository.yaml
apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
name: botkube
namespace: botkube
spec:
interval: 1h
url: https://charts.botkube.io/
3.3 Create PersistentVolumeClaim for Plugin Cache
File: infrastructure/controllers/base/botkube/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: botkube-plugins-cache
namespace: botkube
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: synology-iscsi-storage # Adjust to your storage class
Why PVC? Plugin downloads on Raspberry Pi can take 2-3 minutes. Caching plugins in a PVC reduces restart time from minutes to seconds.
3.4 Configure Helm Values
File: infrastructure/controllers/base/botkube/values.yaml
## Format: communications.{alias}
communications:
"default-group":
socketSlack:
enabled: true
channels:
"default":
name: "k3s-pi5cluster" # Your Slack channel name (lowercase)
bindings:
executors:
- k8s-default-tools
sources:
- k8s-err-events
- k8s-recommendation-events
botToken: "" # Will be overridden by existingCommunicationsSecretName
appToken: ""
## Global Botkube configuration
settings:
clusterName: k3s-pi5cluster # Customize your cluster name
# Use existing secret for communications config
existingCommunicationsSecretName: "botkube-slack-secrets"
# Mount PVC for plugin caching
extraVolumes:
- name: plugins-cache
persistentVolumeClaim:
claimName: botkube-plugins-cache
extraVolumeMounts:
- name: plugins-cache
mountPath: /tmp
# Increase health check timeouts for slower Pi hardware
deployment:
livenessProbe:
initialDelaySeconds: 180 # 3 minutes
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 12
readinessProbe:
initialDelaySeconds: 180
periodSeconds: 10
timeoutSeconds: 5
failureThreshold: 12
3.5 Create HelmRelease
File: infrastructure/controllers/base/botkube/release.yaml
apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
name: botkube
namespace: botkube
spec:
releaseName: botkube
interval: 15m
chart:
spec:
chart: botkube
version: 1.*
sourceRef:
kind: HelmRepository
name: botkube
namespace: botkube
valuesFrom:
- kind: ConfigMap
name: botkube-values
3.6 Create Kustomize Configuration
File: infrastructure/controllers/base/botkube/kustomizeconfig.yaml
nameReference:
- kind: ConfigMap
version: v1
fieldSpecs:
- path: spec/valuesFrom/name
kind: HelmRelease
File: infrastructure/controllers/base/botkube/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: botkube
resources:
- namespace.yaml
- release.yaml
- repository.yaml
- pvc.yaml
configMapGenerator:
- name: botkube-values
files:
- values.yaml=values.yaml
configurations:
- kustomizeconfig.yaml
Step 4: Configure External Secrets
4.1 Create ExternalSecret
File: infrastructure/configs/base/botkube/botkube-slack-secrets.yaml
apiVersion: external-secrets.io/v1
kind: ExternalSecret
metadata:
name: botkube-slack-secrets
namespace: botkube
spec:
refreshInterval: "15s"
secretStoreRef:
name: vault-backend-global # Your ClusterSecretStore name
kind: ClusterSecretStore
target:
name: botkube-slack-secrets
creationPolicy: Owner
template:
engineVersion: v2
data:
comm_config.yaml: |
communications:
'default-group':
socketSlack:
enabled: true
channels:
'default':
name: 'k3s-pi5cluster'
bindings:
executors:
- k8s-default-tools
sources:
- k8s-err-events
- k8s-recommendation-events
botToken: "{{ .botToken }}"
appToken: "{{ .appToken }}"
data:
- secretKey: botToken
remoteRef:
key: botkube-slack-secrets # Vault path
property: botToken
- secretKey: appToken
remoteRef:
key: botkube-slack-secrets # Vault path
property: appToken
Key Points:
- The ExternalSecret creates a Kubernetes Secret with a
comm_config.yamlfile - Botkube automatically loads this config via
existingCommunicationsSecretName - Tokens are templated from Vault into the YAML config
- Secret refreshes every 15 seconds
4.2 Create Kustomization
File: infrastructure/configs/base/botkube/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: botkube
resources:
- botkube-slack-secrets.yaml
Step 5: Deploy
5.1 Commit and Push
# Add all files to git
git add infrastructure/controllers/base/botkube/
git add infrastructure/configs/base/botkube/
# Commit
git commit -m "Add Botkube with Vault secrets integration"
# Push
git push
5.2 Trigger FluxCD Reconciliation
# Reconcile the configuration
flux reconcile kustomization infra-configs
# Reconcile the controllers
flux reconcile kustomization infra-controllers
# Watch the deployment
kubectl get pods -n botkube -w
5.3 Monitor Startup
# Check pod status
kubectl get pods -n botkube
# View logs
kubectl logs -f -n botkube -l app=botkube
# Check if secrets are synced
kubectl get externalsecret -n botkube
kubectl get secret botkube-slack-secrets -n botkube
Expected startup time: 3-5 minutes on first deployment (downloading plugins), then 10-30 seconds on subsequent restarts (using cached plugins).
Step 6: Verify Installation
6.1 Check Logs
Look for these successful initialization messages:
{"component":"Plugin Manager","msg":"Executor plugin registered successfully","plugin":"botkube/kubectl"}
{"component":"Plugin Manager","msg":"Executor plugin registered successfully","plugin":"botkubeExtra/helm"}
{"component":"Plugin Manager","msg":"Source plugin registered successfully","plugin":"botkube/kubernetes"}
{"bot":"SocketSlack","msg":"Botkube connected to Slack!"}
6.2 Test in Slack
Go to your Slack channel and try these commands:
@Botkube ping
@Botkube kubectl get nodes
@Botkube kubectl get pods -n botkube
@Botkube helm list -A
6.3 Check Notifications
Deploy a test pod to trigger Kubernetes event notifications:
kubectl run test-nginx --image=nginx -n default
kubectl delete pod test-nginx -n default
You should see notifications in your Slack channel.
Troubleshooting
Pod Stuck in CrashLoopBackOff
Symptoms: Pod restarts repeatedly, never becomes Ready.
Common causes:
- Health checks too aggressive for slow plugin downloads
- Invalid Slack tokens
- Secret not mounted correctly
Solutions:
# Check logs for errors
kubectl logs -n botkube -l app=botkube --tail=100
# Verify secret exists and has correct data
kubectl get secret botkube-slack-secrets -n botkube -o yaml
# Check if comm_config.yaml has actual tokens (not templates)
kubectl get secret botkube-slack-secrets -n botkube -o jsonpath='{.data.comm_config\.yaml}' | base64 -d
# Verify ExternalSecret is syncing
kubectl describe externalsecret botkube-slack-secrets -n botkube
Slack Connection Issues
Symptoms: “missing_scope” or connection errors in logs.
Solution: Verify all required OAuth scopes are added (see Step 1.2), then reinstall the app to your workspace and update the Bot Token in Vault.
Slow Startup Times
Symptoms: Pod takes 3+ minutes to become Ready.
Solution: This is normal on first start. The PVC caches plugins for faster subsequent starts. To verify caching is working:
# Check PVC is bound
kubectl get pvc -n botkube
# Verify plugins are cached
kubectl exec -n botkube -l app=botkube -- ls -lh /tmp/botkube/ /tmp/botkubeExtra/
ExternalSecret Not Syncing
Symptoms: ExternalSecret shows “SecretSyncedError” status.
Solutions:
# Check ExternalSecret status
kubectl describe externalsecret botkube-slack-secrets -n botkube
# Verify ClusterSecretStore is configured
kubectl get clustersecretstore vault-backend-global -o yaml
# Check Vault path and permissions
vault kv get secret/botkube-slack-secrets
# Verify the Vault path in ExternalSecret matches your Vault mount point
Channel Name Issues
Symptoms: Warning about invalid channel name.
Solution: Slack channel names must be lowercase with no special characters. Update both:
- The actual Slack channel name
- The channel name in
botkube-slack-secrets.yaml
Configuration Options
Customize Notifications
Edit the values.yaml to change which events trigger notifications:
sources:
"k8s-err-events":
botkube/kubernetes:
config:
event:
types:
- error
- warning # Add this for warnings
Add Multiple Channels
In botkube-slack-secrets.yaml, add more channels:
channels:
'default':
name: 'k3s-pi5cluster'
bindings:
sources:
- k8s-err-events
'alerts':
name: 'k3s-alerts'
bindings:
sources:
- k8s-err-events
- k8s-recommendation-events
Change Cluster Name
Update in values.yaml:
settings:
clusterName: my-prod-cluster
Maintenance
Update Botkube
FluxCD automatically updates Botkube when new versions matching 1.* are released. To force an update:
flux reconcile helmrelease botkube -n botkube
Rotate Slack Tokens
- Generate new tokens in Slack App settings
- Update Vault:
vault kv patch secret/botkube-slack-secrets \ botToken="xoxb-new-token" \ appToken="xapp-new-token" - Wait 15 seconds for ExternalSecret to sync
- Botkube automatically reloads (Config Watcher detects changes)
View Cached Plugins
kubectl exec -n botkube -l app=botkube -- ls -lh /tmp/
Clear Plugin Cache
# Delete PVC (will be recreated)
kubectl delete pvc botkube-plugins-cache -n botkube
# Restart pod to download fresh plugins
kubectl rollout restart deployment botkube -n botkube
Security Considerations
- Vault Access: Ensure only the External Secrets Operator service account can read the Botkube secrets path
- Slack Tokens: Never commit tokens to Git - always use Vault
- RBAC: Review Botkube’s RBAC permissions in the Helm chart
- Network Policies: Consider adding NetworkPolicy to restrict Botkube’s network access
Resources
Summary
You now have:
- ✅ Botkube deployed via GitOps
- ✅ Secrets managed securely in Vault
- ✅ Automatic secret synchronization
- ✅ Plugin caching for fast restarts
- ✅ Slack integration with custom icon
- ✅ Kubernetes event notifications
Enjoy your automated Kubernetes monitoring! 🚀