Files
privilegedescalation-ceo[bot] e2ae92648c docs: replace hardcoded namespace with <your-namespace> placeholder
* docs: update Headlamp install namespace references from kube-system to headlamp

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>

* fix: correct RBAC manifest per QA review (PRI-555)

- Remove rbac.authorization.k8s.io privilege escalation block
- Fix orphaned comment from round 1
- Add EOF newline
- Keep serviceaccounts/token for E2E auth (confirmed needed)
- Namespace already correct (privilegedescalation-dev)

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* docs: replace hardcoded namespace with <your-namespace> placeholder

Users choose their own namespace for Headlamp. Replace all hardcoded
namespace references (headlamp, kube-system) in user-facing docs with
<your-namespace> so users substitute their own value.

Conventions:
- Helm install: --namespace <your-namespace> --create-namespace
- kubectl commands: -n <your-namespace>
- YAML metadata: namespace: <your-namespace>
- Prose: "the namespace where Headlamp is installed"

Out-of-scope references left untouched:
- kube-system in NetworkPolicy selectors (API server namespace)
- polaris namespace references (upstream workload namespace)
- Source code and test files

Refs: PRI-433

Co-Authored-By: Paperclip <noreply@paperclip.ing>

* docs: fix remaining hardcoded headlamp namespace to <your-namespace> placeholder

Prior commit was inconsistent — some files used <your-namespace> while
DEPLOYMENT.md, TROUBLESHOOTING.md and several troubleshooting/user-guide
docs still hardcoded headlamp as the namespace.

Co-Authored-By: Paperclip <noreply@paperclip.ing>

---------

Co-authored-by: Chris Farhood <chris@farhood.org>
Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-05-10 21:34:49 +00:00

490 lines
11 KiB
Markdown

# 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
```yaml
---
# 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: <your-namespace>
roleRef:
kind: Role
name: polaris-proxy-reader
apiGroup: rbac.authorization.k8s.io
```
Apply the RBAC manifests:
```bash
kubectl apply -f polaris-plugin-rbac.yaml
```
### RBAC Verification
```bash
# 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:<your-namespace>: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
```yaml
---
apiVersion: v1
kind: ConfigMap
metadata:
name: headlamp-plugin-config
namespace: <your-namespace>
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
```yaml
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: headlamp
namespace: <your-namespace>
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
```yaml
---
# ServiceAccount for Headlamp
apiVersion: v1
kind: ServiceAccount
metadata:
name: headlamp
namespace: <your-namespace>
labels:
app.kubernetes.io/name: headlamp
---
# Service for Headlamp
apiVersion: v1
kind: Service
metadata:
name: headlamp
namespace: <your-namespace>
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
```bash
# 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 <your-namespace> wait --for=condition=available deployment/headlamp --timeout=300s
```
### 2. Verify Deployment
```bash
# Check pods are running
kubectl -n <your-namespace> 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 <your-namespace> logs deployment/headlamp -c install-plugins
# Expected output:
# Plugin installation complete
# Verify plugin files exist
kubectl -n <your-namespace> 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
```bash
# Port-forward to access locally
kubectl -n <your-namespace> 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
```yaml
# k8s/base/kustomization.yaml
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
namespace: <your-namespace>
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
```yaml
# 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
```
```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
```bash
# Build and preview
kubectl kustomize k8s/overlays/production
# Apply
kubectl apply -k k8s/overlays/production
```
## FluxCD Integration
For GitOps with FluxCD:
```yaml
---
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: <your-namespace>
```
## Upgrading the Plugin
### Update ConfigMap
```bash
# Edit ConfigMap with new version
kubectl -n <your-namespace> 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 <your-namespace> rollout restart deployment/headlamp
# Wait for rollout to complete
kubectl -n <your-namespace> rollout status deployment/headlamp
```
### Verify Upgrade
```bash
# Check init container logs
kubectl -n <your-namespace> logs deployment/headlamp -c install-plugins
# Verify new version in UI
# Navigate to Settings → Plugins in Headlamp
```
## Troubleshooting
### Init Container Fails
```bash
# Check init container logs
kubectl -n <your-namespace> 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
```bash
# Verify HEADLAMP_CONFIG_WATCH_PLUGINS is false
kubectl -n <your-namespace> 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 <your-namespace> edit deployment headlamp
```
### RBAC Permissions Denied
```bash
# Test RBAC
kubectl auth can-i get services/proxy \
--as=system:serviceaccount:<your-namespace>: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](helm.md)** - Deploy with Helm for easier management
- **[Production Checklist](production.md)** - Production deployment best practices
- **[Troubleshooting](../troubleshooting/README.md)** - Comprehensive troubleshooting guide
## References
- [Kubernetes Deployments](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/)
- [Kubernetes RBAC](https://kubernetes.io/docs/reference/access-authn-authz/rbac/)
- [Kustomize Documentation](https://kustomize.io/)
- [FluxCD Kustomization](https://fluxcd.io/flux/components/kustomize/kustomization/)