e2ae92648c
* 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>
490 lines
11 KiB
Markdown
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/)
|