In-cluster
A common use case for any Kubernetes web UI is to deploy it in-cluster and set up an ingress server for having it available to users.
Using Helm
The easiest way to install headlamp in your existing cluster is to use helm with our helm chart.
# first add our custom repo to your local helm repositories
helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/
# now you should be able to install headlamp via helm
helm install my-headlamp headlamp/headlamp --namespace kube-system
As usual, it is possible to configure the helm release via the values file or setting your preferred values directly.
# install headlamp with your own values.yaml
helm install my-headlamp headlamp/headlamp --namespace kube-system -f values.yaml
# install headlamp by setting your values directly
helm install my-headlamp headlamp/headlamp --namespace kube-system --set replicaCount=2
Cluster Inventory
Headlamp can discover clusters from Cluster Inventory API ClusterProfile
resources when Cluster Inventory is enabled. The Helm chart configures the
backend flags from config.clusterInventory and mounts an access provider
config file.
Create cluster-inventory-values.yaml:
config:
clusterInventory:
enabled: true
accessProvidersConfig:
providers:
- name: secretreader
execConfig:
apiVersion: client.authentication.k8s.io/v1
command: /access-plugins/secretreader/bin/secretreader-plugin
interactiveMode: Never
provideClusterInfo: true
- name: kubeconfig-secretreader
execConfig:
apiVersion: client.authentication.k8s.io/v1
command: /access-plugins/kubeconfig-secretreader/bin/kubeconfig-secretreader-plugin
interactiveMode: Never
provideClusterInfo: true
plugins:
- name: secretreader
image: registry.k8s.io/cluster-inventory-api/secretreader:v0.1.3@sha256:ec3090dc166aa2b42fb35d714d161c417d8b27bbc463404c8f615f5f4c610a1d
mountPath: /access-plugins/secretreader
- name: kubeconfig-secretreader
image: registry.k8s.io/cluster-inventory-api/kubeconfig-secretreader:v0.1.3@sha256:b92966cc6e4ac78002a63862921022a71d54956826f6e4febcb7247495eb98c0
mountPath: /access-plugins/kubeconfig-secretreader
Then install Headlamp with the values file:
helm install my-headlamp headlamp/headlamp --namespace kube-system --values cluster-inventory-values.yaml
The accessProvidersConfig object is the provider config consumed by the
Cluster Inventory access provider. The plugins entries are Kubernetes image
volumes that mount provider binaries into the Headlamp container, not Headlamp
UI plugins. By default, Headlamp watches ClusterProfile resources that do not
have the headlamp.dev/ignore label because the chart sets
config.clusterInventory.labelSelector to !headlamp.dev/ignore. Discovery is
scoped to the Headlamp pod's namespace. This follows the namespaced consumer
model for ClusterProfile: each Headlamp instance reads the profiles published
for that consumer's namespace.
To watch specific namespaces, set:
config:
clusterInventory:
namespaces:
- inventory-team-a
- inventory-team-b
Each selected namespace requires permission to get, list, and watch
ClusterProfiles. Set namespaces to ["*"] to watch all namespaces. *
cannot be combined with named namespaces, and all-namespace discovery requires
equivalent cluster-wide access.
Using simple yaml
We also maintain a simple/vanilla file for setting up a Headlamp deployment and service. Be sure to review it and change anything you need.
If you're happy with the options in this deployment file, and assuming
you have a running Kubernetes cluster and your kubeconfig pointing to it,
you can run:
kubectl apply -f https://raw.githubusercontent.com/kubernetes-sigs/headlamp/main/kubernetes-headlamp.yaml
Optional TLS Backend Termination
Headlamp supports optional TLS termination at the backend server. The default is to terminate at the ingress (default) or optionally directly at the Headlamp container. This enables use cases such as NGINX TLS passthrough and transport server. See tls for details and usage.
Use a non-default kube config file
When Headlamp runs with the -in-cluster flag (the default for the Helm chart
and the sample deployment YAML), it automatically creates a cluster context
named main from the pod's service account. This context exists only in
memory: no kubeconfig file is written to the pod's filesystem. You do not need
to provide, generate, or mount any kubeconfig file for Headlamp to access the
cluster it is running in.
Mounting extra kubeconfig files is only needed if you want Headlamp to show additional clusters besides the one it is deployed to.
In in-cluster mode, the KUBECONFIG environment variable is ignored. To point
Headlamp at kubeconfig files, either mount them at the default location shown
below, pass the -kubeconfig argument, or set the HEADLAMP_CONFIG_KUBECONFIG
environment variable. Kubeconfig files are read when the server starts, so
restart the pod after changing them.
First, store the kubeconfig for the extra cluster(s) in a Secret. The examples
below assume Headlamp is installed in the kube-system namespace:
kubectl create secret generic headlamp-kubeconfig \
--from-file=config=./my-kubeconfig \
--namespace kube-system
Option 1: Mount the kubeconfig at the default location
Headlamp loads a kubeconfig file from
/home/headlamp/.config/Headlamp/kubeconfigs/config at startup. Mount the
Secret at that directory with these Helm values (the key inside the Secret
must be named config):
volumeMounts:
- name: kubeconfig
mountPath: /home/headlamp/.config/Headlamp/kubeconfigs
readOnly: true
volumes:
- name: kubeconfig
secret:
secretName: headlamp-kubeconfig
helm install my-headlamp headlamp/headlamp --namespace kube-system -f values.yaml
Option 2: Mount the kubeconfig anywhere and use the -kubeconfig argument
If you prefer an explicit path, mount the Secret wherever you like and pass
the path with the -kubeconfig argument through config.extraArgs:
config:
extraArgs:
- -kubeconfig=/headlamp/kubeconfig/config
volumeMounts:
- name: kubeconfig
mountPath: /headlamp/kubeconfig
readOnly: true
volumes:
- name: kubeconfig
secret:
secretName: headlamp-kubeconfig
Use several kubeconfig files
If you need to use more than one kubeconfig file at the same time, you can
list each file path with a ":" separator in the -kubeconfig argument:
config:
extraArgs:
- -kubeconfig=/headlamp/kubeconfig/cluster-a:/headlamp/kubeconfig/cluster-b
volumeMounts:
- name: kubeconfig
mountPath: /headlamp/kubeconfig
readOnly: true
volumes:
- name: kubeconfig
secret:
secretName: headlamp-kubeconfig
with a Secret that contains one key per kubeconfig file:
kubectl create secret generic headlamp-kubeconfig \
--from-file=cluster-a=./cluster-a-kubeconfig \
--from-file=cluster-b=./cluster-b-kubeconfig \
--namespace kube-system
Using plain YAML instead of Helm
If you deploy Headlamp with a plain manifest (like kubernetes-headlamp.yaml), apply the same idea directly on the Deployment:
spec:
template:
spec:
containers:
- name: headlamp
image: ghcr.io/headlamp-k8s/headlamp:latest
args:
- "-in-cluster"
- "-plugins-dir=/headlamp/plugins"
- "-kubeconfig=/headlamp/kubeconfig/config"
volumeMounts:
- name: kubeconfig
mountPath: /headlamp/kubeconfig
readOnly: true
volumes:
- name: kubeconfig
secret:
secretName: headlamp-kubeconfig
Exposing Headlamp with an ingress server
With the instructions in the previous section, the Headlamp service should be running, but you still need the ingress server as mentioned. We provide a sample ingress YAML file for this purpose, but you have to manually replace the URL placeholder with the desired URL. The ingress file also assumes that you have Contour and a cert-manager set up, but if you don't, then you'll just not have TLS.
Assuming your URL is headlamp.mydeployment.io, getting the sample ingress
file and changing the URL can quickly be done by:
curl -s https://raw.githubusercontent.com/kubernetes-sigs/headlamp/main/kubernetes-headlamp-ingress-sample.yaml | sed -e s/__URL__/headlamp.mydeployment.io/ > headlamp-ingress.yaml
and with that, you'll have a configured ingress file, so verify it and apply it:
kubectl apply -f ./headlamp-ingress.yaml
Exposing Headlamp with port-forwarding
If you want to quickly access Headlamp (after having its service running) and don't want to set up an ingress for it, you can run use port-forwarding as follows:
kubectl port-forward -n kube-system service/headlamp 8080:80
and then you can access localhost:8080 in your browser.
Accessing Headlamp
Once Headlamp is up and running, be sure to enable access to it either by creating a service account or by setting up OIDC.
Plugin Management
Headlamp supports managing plugins through a sidecar container when deployed in-cluster.
Using values.yaml
You can directly specify the plugin configuration in your values.yaml:
config:
watchPlugins: true
pluginsManager:
enabled: true
configContent: |
plugins:
- name: my-plugin
source: https://artifacthub.io/packages/headlamp/my-repo/my_plugin
version: 1.0.0
installOptions:
parallel: true
maxConcurrent: 2
baseImage: node:lts-alpine
version: latest
Using a Separate plugin.yml
Alternatively, you can maintain a separate plugin.yml file:
- Create a
plugin.ymlfile:
plugins:
- name: my-plugin
source: https://artifacthub.io/packages/headlamp/my-repo/my_plugin
version: 1.0.0
# Optional: specify dependencies if needed
dependencies:
- another-plugin
installOptions:
parallel: true
maxConcurrent: 2
- Install/upgrade Headlamp using the plugin configuration:
helm upgrade --install my-headlamp headlamp/headlamp --namespace kube-system -f values.yaml --set pluginsManager.configContent="$(cat plugin.yml)"
Plugin Configuration Format
The plugin configuration supports the following fields:
plugins: Array of plugins to installname: Plugin name (required)source: Plugin source URL from Artifact Hub (required)version: Plugin version (required)dependencies: Array of plugin names that this plugin depends on (optional)
installOptions:parallel: Whether to install plugins in parallel (default: false)maxConcurrent: Maximum number of concurrent installations when parallel is true
Auto-updating Plugins
Headlamp's plugin manager can automatically watch for changes in the plugin configuration. However, you need to enable watch for these changes in the main headlamp container. This can be enabled through the watchPlugins setting in values.yaml:
config:
watchPlugins: true # Set to true to enable automatic plugin updates in main headlamp container
When enabled, any plugins' changes (either through Helm upgrades or direct ConfigMap updates) wil update in the main headlamp container by enabling --watch-plugins-changes flag on headlamp server.