Kubernetes Dashboard 不想裸奔?Headlamp 本地管理集群,用 cpolar 临时给同事看只读面板
Kubernetes Dashboard 不想裸奔?Headlamp 本地管理集群,用 cpolar 临时给同事看只读面板
有些 K8s 问题,自己在终端里kubectl get pod -A看半天,同事一句“我能不能也看一下页面”就尴尬了。
给 kubeconfig?太危险。把 Kubernetes API Server 暴露出去?更别想。给一个 cluster-admin Token?这基本等于把测试集群钥匙递出去了。
这篇就按更稳的方式来:本地 k3s、minikube 或测试 Kubernetes 集群里跑 Headlamp,只用它看 Namespace、Pod、Service 和日志;需要协作验收时,用低权限 ServiceAccount 登录,再用 cpolar 短时开放 Headlamp 面板。
划重点:这里开放的是 Headlamp 的临时 Web 入口,不是 Kubernetes API Server,也不是 kubeconfig。
1 什么是 Headlamp?这篇里它负责看集群状态
Headlamp 是 Kubernetes SIG UI 下的一个 Kubernetes Web UI,官方定位很直接:既可以部署到集群里,也可以作为桌面应用本地使用。
这篇不把它当“生产集群运维平台”来写,只用它解决一个很常见的小场景:测试集群跑起来后,需要有人远程看一眼资源状态、Pod 日志和 Service 信息。
Headlamp 比较适合这个场景,是因为它会跟 Kubernetes RBAC 结合。你用什么权限的 Token 登录,它就按什么权限展示和操作。只读账号看不到或点不了的东西,就不会因为页面好看而突然变成管理员。
不过这也带来一个提醒:不要偷懒直接用cluster-admin。官方文档里为了演示会给 admin 示例,但我们做协作验收时,应该换成只读或低权限账号。
2 环境准备:先有一个本地测试集群
这篇默认你已经有一个本地或测试用 Kubernetes 集群,k3s、minikube、kind 都可以。不要拿生产集群直接做演示入口,尤其不要为了方便把公网访问、管理员 Token、真实业务 Namespace 混在一起。
先确认当前 kubectl 能连上集群:
kubectl cluster-info kubectl get nodes kubectl get ns能看到节点和 Namespace,就说明本机 kubeconfig 已经指向目标集群。
如果你用的是 minikube,可以先启动一个本地集群:
minikube start kubectl get nodes如果你用的是 k3s,通常 kubeconfig 在服务器上,需要确认本机kubectl已经能正常访问测试集群。这里别把生产 kubeconfig 拿来顺手演示,后面同事看的页面也会基于这套集群状态。
建议先创建一个专门演示用的 Namespace,后面页面里更清楚:
kubectl create namespace demo-headlamp kubectl -n demo-headlamp create deployment nginx-demo --image=nginx:1.27 kubectl -n demo-headlamp expose deployment nginx-demo --port=80 --target-port=80 kubectl -n demo-headlamp get pod,svc这一步不是为了凑命令,而是让 Headlamp 打开后有东西可看:Namespace、Deployment、Pod、Service 都能对上。
3 安装 Headlamp:部署到测试集群里
Headlamp 官方提供 Helm Chart,也提供简单 YAML。这里用 Helm,回滚和清理都更顺手。
helm repo add headlamp https://kubernetes-sigs.github.io/headlamp/ helm repo update helm upgrade --install my-headlamp headlamp/headlamp --namespace kube-system --create-namespace装完先看 Pod 和 Service:
kubectl -n kube-system get pods,svc | grep -i headlamp正常情况下能看到 Headlamp 的 Pod 处于 Running,Service 也已经创建出来。
如果 Pod 一直不是 Running,先看事件和日志,不要急着开公网入口:
kubectl -n kube-system describe pod -l app.kubernetes.io/name=headlamp kubectl -n kube-system logs -l app.kubernetes.io/name=headlamp --tail=100这一步做完,你已经有了集群内的 Headlamp 服务,但它还没有对外开放。我们先用kubectl port-forward在本机访问,确认页面和登录都正常。
HEADLAMP_SVC=$(kubectl -n kube-system get svc -l app.kubernetes.io/name=headlamp -o jsonpath='{.items[0].metadata.name}') echo "Headlamp service: ${HEADLAMP_SVC}" kubectl -n kube-system port-forward svc/${HEADLAMP_SVC} 8080:80终端保持不要关,浏览器打开:
http://127.0.0.1:8080看到 Headlamp 登录页就对了。如果打不开,优先检查三件事:Headlamp Pod 是否 Running、Service 名字是否取到、8080 端口有没有被本机其他程序占用。
4 创建只读 Token:只看资源,不给管理员钥匙
现在到了最容易犯错的一步。
很多人为了快,会直接创建cluster-admin账号,然后把 Token 发给同事。这在测试环境也不推荐,因为页面里一旦具备写权限,误删 Deployment、改 Service、查看敏感资源都挡不住。
这里我们创建一个专门给 Headlamp 验收用的 ServiceAccount,并绑定自定义只读 ClusterRole。它能看 Namespace、Pod、Service、Deployment、ReplicaSet、事件和 Pod 日志,但不授予创建、修改、删除权限,也不开放 Secret 读取。
新建文件headlamp-readonly-rbac.yaml:
apiVersion: v1 kind: ServiceAccount metadata: name: headlamp-readonly namespace: kube-system --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: headlamp-readonly rules: - apiGroups: [""] resources: ["namespaces", "pods", "services", "endpoints", "events", "nodes"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["pods/log"] verbs: ["get"] - apiGroups: ["apps"] resources: ["deployments", "replicasets", "statefulsets", "daemonsets"] verbs: ["get", "list", "watch"] - apiGroups: ["batch"] resources: ["jobs", "cronjobs"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: headlamp-readonly roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: headlamp-readonly subjects: - kind: ServiceAccount name: headlamp-readonly namespace: kube-system应用它:
kubectl apply -f headlamp-readonly-rbac.yaml生成登录 Headlamp 用的 Token:
kubectl -n kube-system create token headlamp-readonly --duration=2h把输出的 Token 复制到 Headlamp 登录页。这里建议设置一个短一点的有效期,比如 2 小时,刚好够同事看页面、验收问题、截图反馈。
如果登录后资源列表为空,先别怀疑 Headlamp。用下面的命令验证权限:
kubectl auth can-i list pods --all-namespaces --as=system:serviceaccount:kube-system:headlamp-readonly kubectl auth can-i get pods/log --namespace demo-headlamp --as=system:serviceaccount:kube-system:headlamp-readonly kubectl auth can-i delete pods --namespace demo-headlamp --as=system:serviceaccount:kube-system:headlamp-readonly前两条应该返回yes,最后一条应该返回no。这才是我们要的协作边界:能看,不能乱改。
5 在 Headlamp 里检查 Namespace、Pod、Service 和日志
登录后先看左侧资源菜单,不要急着把链接发出去。自己先走一遍验收路径,避免同事打开后只看到空页面。
建议按这个顺序看:
- Namespaces:确认能看到
demo-headlamp。 - Pods:确认
nginx-demo对应 Pod 是 Running。 - Services:确认
nginx-demoService 存在,端口是 80。 - Logs:进入 Pod 详情页,看日志入口是否能打开。
这一步的目的不是为了测试而测试,而是确认“页面展示、RBAC 权限、日志读取”这条链路已经打通。
如果 Namespace 能看到,但日志打不开,多半是pods/log权限没配对。回头检查 ClusterRole 里有没有这一段:
- apiGroups: [""] resources: ["pods/log"] verbs: ["get"]如果页面里出现删除、编辑等高风险按钮,也要停下来检查登录 Token。优先核对当前登录的是否是管理员 kubeconfig 或 cluster-admin Token。
6 用 cpolar 短时 HTTPS 给同事看 Headlamp
本机http://127.0.0.1:8080只能自己看。现在要给远程同事临时验收,就用 cpolar 建一个 HTTP 隧道指向本机 8080。
注意,这里映射的是 Headlamp 面板端口,不是 Kubernetes API Server 的6443,也不是任何 kubeconfig 文件。
如果还没安装 cpolar,可以从官网下载安装:
- 官网:https://www.cpolar.com/
- 下载页:https://www.cpolar.com/download
- 文档:https://www.cpolar.com/docs/
Linux 可以使用官方一键安装脚本:
curl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bashmacOS 可以用 Homebrew:
brew tap probezy/core && brew install cpolar sudo cpolar service install sudo cpolar service start安装后打开本地控制台http://127.0.0.1:9200登录账号;纯命令行环境也可以使用后台里的 Authtoken 手动绑定:
cpolar authtoken xxxxx确认 Headlamp 的 port-forward 还在运行后,新开一个终端:
cpolar http 8080cpolar 会生成一个公网 HTTPS 地址。把这个地址发给同事,再把前面生成的只读 Token 通过团队内部安全渠道单独发送,不要把链接和 Token 一起丢到公开群里。
免费随机地址适合临时演示,官方规则里随机公网地址会在 24 小时内变化。如果后续要固定地址,可以再看固定二级子域名方案;但这篇的建议很明确:K8s 面板验收按需开启,验收完就关,不要长期挂在公网。
7 安全边界:这几条别省
K8s 面板一旦能被远程打开,安全边界就要写在前面,而不是出事后补救。
这套方案里我建议坚持下面几条:
- 不暴露 Kubernetes API Server,不映射
6443。 - 不发送 kubeconfig,不把本机管理员凭据交给别人。
- 不给
cluster-admin,只用测试或低权限 ServiceAccount。 - 不长期公网开放 Headlamp,验收结束就关闭 cpolar 和 port-forward。
- 不在页面里展示生产 Secret、真实业务数据和敏感 Namespace。
关闭临时入口很简单,停掉两个前台进程就行:
# 关闭 cpolar http 8080 所在终端进程:Ctrl + C # 关闭 kubectl port-forward 所在终端进程:Ctrl + C验收结束后,也可以清理只读账号和演示应用:
kubectl delete -f headlamp-readonly-rbac.yaml kubectl delete namespace demo-headlamp helm uninstall my-headlamp --namespace kube-system如果只是下一轮还要继续演示,可以保留 Headlamp,但建议重新生成短时 Token。别把旧 Token 当长期密码用。
8 总结
现在这条链路已经比较清楚了:本地 k3s、minikube 或测试 Kubernetes 集群里部署 Headlamp,用只读 ServiceAccount 登录查看资源状态;需要同事远程协作时,只把 Headlamp 面板通过 cpolar 短时开放出去。
关键步骤就三件事:
- Headlamp 只负责看 Namespace、Pod、Service 和日志,不替代完整运维平台。
- 登录账号用低权限 ServiceAccount,验证
list pods是 yes、delete pods是 no。 - cpolar 只映射本机 Headlamp 页面端口,验收结束立刻关闭临时入口。
如果你只是自己在局域网里排查问题,cpolar 这一步可以先跳过;如果需要远程同事一起看页面,它就很适合做短时 HTTPS 入口。重点不是“把 K8s 面板放到公网”,而是在不暴露 API Server、不交出 kubeconfig、不授予管理员权限的前提下,把一次协作验收做完。