e2f220c418
Updates all documentation references to the Headlamp install namespace from kube-system to headlamp as part of PRI-433. In-scope files updated: - README.md, SECURITY.md - docs/getting-started/installation.md, quick-start.md, prerequisites.md - docs/deployment/helm.md, kubernetes.md, production.md - docs/troubleshooting/README.md, common-issues.md, rbac-issues.md - docs/user-guide/configuration.md, rbac-permissions.md - docs/TESTING.md, TROUBLESHOOTING.md, DEPLOYMENT.md Out-of-scope (unchanged): - Source files referencing upstream workload namespace - RBAC manifests describing Polaris namespace (polaris ns is unchanged) - NetworkPolicy namespaceSelector (API server runs in kube-system) - design-decisions.md and ARCHITECTURE.md (URL hashes refer to cluster namespaces, not Headlamp install ns) Co-Authored-By: Paperclip <noreply@paperclip.ing>
11 KiB
11 KiB
Kubernetes Deployment
Direct Kubernetes manifest deployment for the Headlamp Polaris Plugin.
Overview
This guide covers deploying the plugin using raw Kubernetes manifests without Helm. This approach is useful for:
- Environments where Helm is not available
- Highly customized deployments
- GitOps workflows with Kustomize
- Learning the underlying Kubernetes resources
RBAC Manifests
The plugin requires read-only access to the Polaris dashboard service proxy.
Complete RBAC Configuration
---
# Role: Read-only access to Polaris service proxy
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: polaris-proxy-reader
namespace: polaris
labels:
app.kubernetes.io/name: headlamp-polaris-plugin
app.kubernetes.io/component: rbac
rules:
- apiGroups: ['']
resources: ['services/proxy']
resourceNames: ['polaris-dashboard']
verbs: ['get']
---
# RoleBinding: Grant Headlamp service account access
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: headlamp-polaris-proxy
namespace: polaris
labels:
app.kubernetes.io/name: headlamp-polaris-plugin
app.kubernetes.io/component: rbac
subjects:
- kind: ServiceAccount
name: headlamp
namespace: headlamp
roleRef:
kind: Role
name: polaris-proxy-reader
apiGroup: rbac.authorization.k8s.io
Apply the RBAC manifests:
kubectl apply -f polaris-plugin-rbac.yaml
RBAC Verification
# Verify Role exists
kubectl -n polaris get role polaris-proxy-reader
# Verify RoleBinding exists
kubectl -n polaris get rolebinding headlamp-polaris-proxy
# Test permission
kubectl auth can-i get services/proxy \
--as=system:serviceaccount:headlamp:headlamp \
-n polaris \
--resource-name=polaris-dashboard
# Expected output: yes
Plugin Installation via Init Container
Use an init container to download and install the plugin.
ConfigMap for Plugin Configuration
---
apiVersion: v1
kind: ConfigMap
metadata:
name: headlamp-plugin-config
namespace: headlamp
labels:
app.kubernetes.io/name: headlamp
app.kubernetes.io/component: plugin-config
data:
plugin.yml: |
- name: headlamp-polaris-plugin
version: 0.3.5
url: https://github.com/privilegedescalation/headlamp-polaris-plugin/releases/download/v0.3.10/polaris-0.3.10.tar.gz
Headlamp Deployment with Plugin Init Container
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: headlamp
namespace: headlamp
labels:
app.kubernetes.io/name: headlamp
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: headlamp
template:
metadata:
labels:
app.kubernetes.io/name: headlamp
spec:
serviceAccountName: headlamp
# Init container to install plugins
initContainers:
- name: install-plugins
image: node:lts-alpine
command:
- sh
- -c
- |
npm install -g @kinvolk/headlamp-plugin
headlamp-plugin install --config /config/plugin.yml --plugins-dir /plugins
echo "Plugin installation complete"
volumeMounts:
- name: plugins
mountPath: /plugins
- name: plugin-config
mountPath: /config
containers:
- name: headlamp
image: ghcr.io/headlamp-k8s/headlamp:v0.39.0
args:
- '-in-cluster'
- '-plugins-dir=/headlamp/plugins'
env:
- name: HEADLAMP_CONFIG_WATCH_PLUGINS
value: 'false' # CRITICAL: Must be false for plugin manager
ports:
- name: http
containerPort: 4466
protocol: TCP
volumeMounts:
- name: plugins
mountPath: /headlamp/plugins
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 5
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
volumes:
- name: plugins
emptyDir: {}
- name: plugin-config
configMap:
name: headlamp-plugin-config
Supporting Resources
---
# ServiceAccount for Headlamp
apiVersion: v1
kind: ServiceAccount
metadata:
name: headlamp
namespace: headlamp
labels:
app.kubernetes.io/name: headlamp
---
# Service for Headlamp
apiVersion: v1
kind: Service
metadata:
name: headlamp
namespace: headlamp
labels:
app.kubernetes.io/name: headlamp
spec:
type: ClusterIP
ports:
- port: 80
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: headlamp
Complete Deployment Workflow
1. Apply All Manifests
# Create RBAC for Polaris plugin
kubectl apply -f polaris-plugin-rbac.yaml
# Create plugin configuration
kubectl apply -f headlamp-plugin-config.yaml
# Deploy Headlamp with plugin init container
kubectl apply -f headlamp-deployment.yaml
kubectl apply -f headlamp-service.yaml
kubectl apply -f headlamp-serviceaccount.yaml
# Wait for deployment to be ready
kubectl -n headlamp wait --for=condition=available deployment/headlamp --timeout=300s
2. Verify Deployment
# Check pods are running
kubectl -n headlamp get pods -l app.kubernetes.io/name=headlamp
# Expected output:
# NAME READY STATUS RESTARTS AGE
# headlamp-xxxxxxxxxx-xxxxx 1/1 Running 0 2m
# Check init container logs
kubectl -n headlamp logs deployment/headlamp -c install-plugins
# Expected output:
# Plugin installation complete
# Verify plugin files exist
kubectl -n headlamp exec deployment/headlamp -c headlamp -- \
ls -la /headlamp/plugins/headlamp-polaris-plugin/
# Expected output:
# drwxr-xr-x dist/
# -rw-r--r-- package.json
# Test Polaris API access
kubectl get --raw /api/v1/namespaces/polaris/services/polaris-dashboard:80/proxy/results.json \
| jq .PolarisOutputVersion
# Expected output: "1.0" or similar
3. Access Headlamp
# Port-forward to access locally
kubectl -n headlamp port-forward service/headlamp 8080:80
# Open browser to http://localhost:8080
Kustomize Integration
For GitOps workflows with Kustomize:
Directory Structure
k8s/
├── base/
│ ├── kustomization.yaml
│ ├── rbac.yaml
│ ├── configmap.yaml
│ ├── deployment.yaml
│ ├── service.yaml
│ └── serviceaccount.yaml
└── overlays/
├── production/
│ ├── kustomization.yaml
│ └── patches.yaml
└── staging/
├── kustomization.yaml
└── patches.yaml
Base Kustomization
# k8s/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: headlamp
commonLabels:
app.kubernetes.io/name: headlamp
app.kubernetes.io/managed-by: kustomize
resources:
- serviceaccount.yaml
- service.yaml
- deployment.yaml
- configmap.yaml
- rbac.yaml
configMapGenerator:
- name: headlamp-plugin-config
files:
- plugin.yml
Production Overlay
# k8s/overlays/production/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
bases:
- ../../base
nameSuffix: -prod
replicas:
- name: headlamp
count: 2
patches:
- path: patches.yaml
# k8s/overlays/production/patches.yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: headlamp
spec:
template:
spec:
containers:
- name: headlamp
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 200m
memory: 256Mi
Deploy with Kustomize
# Build and preview
kubectl kustomize k8s/overlays/production
# Apply
kubectl apply -k k8s/overlays/production
FluxCD Integration
For GitOps with FluxCD:
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
name: headlamp-polaris-plugin
namespace: flux-system
spec:
interval: 10m
path: ./k8s/overlays/production
prune: true
sourceRef:
kind: GitRepository
name: infrastructure
healthChecks:
- apiVersion: apps/v1
kind: Deployment
name: headlamp
namespace: headlamp
Upgrading the Plugin
Update ConfigMap
# Edit ConfigMap with new version
kubectl -n headlamp edit configmap headlamp-plugin-config
# Update version and URL:
# version: 0.3.6
# url: https://github.com/.../v0.3.6/polaris-0.3.10.tar.gz
# Restart deployment to trigger init container
kubectl -n headlamp rollout restart deployment/headlamp
# Wait for rollout to complete
kubectl -n headlamp rollout status deployment/headlamp
Verify Upgrade
# Check init container logs
kubectl -n headlamp logs deployment/headlamp -c install-plugins
# Verify new version in UI
# Navigate to Settings → Plugins in Headlamp
Troubleshooting
Init Container Fails
# Check init container logs
kubectl -n headlamp logs deployment/headlamp -c install-plugins
# Common issues:
# 1. Network connectivity to GitHub
# 2. Invalid URL in ConfigMap
# 3. Tarball checksum mismatch
Plugin Not Loading
# Verify HEADLAMP_CONFIG_WATCH_PLUGINS is false
kubectl -n headlamp get deployment headlamp -o yaml | grep WATCH_PLUGINS
# Expected output:
# - name: HEADLAMP_CONFIG_WATCH_PLUGINS
# value: "false"
# If not set or "true", update deployment
kubectl -n headlamp edit deployment headlamp
RBAC Permissions Denied
# Test RBAC
kubectl auth can-i get services/proxy \
--as=system:serviceaccount:headlamp:headlamp \
-n polaris \
--resource-name=polaris-dashboard
# If "no", verify RBAC manifests applied:
kubectl -n polaris get role polaris-proxy-reader
kubectl -n polaris get rolebinding headlamp-polaris-proxy
Next Steps
- Helm Deployment - Deploy with Helm for easier management
- Production Checklist - Production deployment best practices
- Troubleshooting - Comprehensive troubleshooting guide