ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Kubeapps 项目全景指南:Kubernetes 集群内应用部署与管理的 Web UI

Kubeapps 项目全景指南:Kubernetes 集群内应用部署与管理的 Web UI
  • 云原生
  • 后端
  • 前端

【免费下载链接】kubeapps

A web-based UI for deploying and managing applications in Kubernetes clusters

项目地址:https://gitcode.com/gh_mirrors/ku/kubeapps
点击查看免费下载

导读

Kubeapps 是一个运行在 Kubernetes 集群内部的 Web 应用,通过一次安装即可为团队提供浏览、部署、升级与删除应用的能力,同时内置基于 Kubernetes RBAC 的授权与基于 OAuth2/OIDC 的认证方案。本篇指南以仓库site/content/docs/latest/project/readme.md为骨架,结合源码、Helm Chart 配置与官方文档,系统讲解 Kubeapps 的核心能力、快速安装、生产配置、排障路径与多集群部署要点,帮助你从零搭建一套可用的集群应用管理入口。

一、Kubeapps 是什么:核心能力与架构概览

Kubeapps 官方定位是 "in-cluster web-based application",即部署在集群内部、面向集群用户的 Web 应用。它的价值在于把"在集群里装软件"这件事标准化:无论是 Helm Chart、Flux 还是 Carvel 包,用户都可以通过统一的 Web 界面完成从浏览、选型、定制参数到部署、升级、删除的全生命周期管理。

官方能力清单(见 site/content/docs/latest/project/readme.md)包括:

  • 从公有或私有仓库浏览并部署各类包:Helm Chart、Flux 包、Carvel 包(含 VMware Marketplace 与 Bitnami Application Catalog);
  • 通过直观的表单式 UI 定制部署参数;
  • 浏览、升级、删除集群中已安装的应用;
  • 浏览并部署 Kubernetes Operator;
  • 使用独立 OAuth2/OIDC 提供方或 Pinniped 完成安全认证;
  • 基于 Kubernetes RBAC 实现细粒度授权。

从源码结构看,Kubeapps 由一组职责分离的组件组成(仓库中对应的实现位于cmd/与dashboard/目录):

组件仓库位置职责
Kubeapps Dashboarddashboard/srcReact + TypeScript 前端,提供 Catalog、部署表单、应用详情等界面
Kubeapps-APIscmd/kubeapps-apis/server/server.gogRPC + HTTP 网关聚合层,通过插件协议注册 Helm、Flux、Carvel 等后端
AppRepository Controllercmd/apprepository-controller/server/controller.go监听apprepositories.kubeapps.comCRD,周期性触发资产同步
Asset Syncercmd/asset-syncer/server/sync.go拉取仓库索引并写入 PostgreSQL(资产数据库)
OCI Catalogcmd/oci-catalogRust 实现的可选 OCI 目录 gRPC 服务
Pinniped Proxycmd/pinniped-proxy将 Kubeapps 的 Kubernetes API 请求代理到 Pinniped 认证的集群
前端反向代理chart/kubeapps/templates/frontendNGINX,负责把 Dashboard 流量路由到各后端并代理 Kubernetes API

其中 Kubeapps-APIs 是 2.x 的架构核心:Serve()会先创建 gRPC 网关,再通过pluginsv1alpha1.NewPluginsServer扫描插件目录中的.so插件(cmd/kubeapps-apis/core/plugins/v1alpha1/plugins.go),然后调用GetPluginsSatisfyingInterface把实现了 core.packages / core.repositories 接口的插件注册到统一服务上(server.go)。每个插件通过RegisterWithGRPCServer描述自身(如 Helm 插件在 main.go 中声明Name: "helm.packages"、Version: "v1alpha1"),从而实现"一个网关、多套打包后端"的插件化架构。

注意:Kubeapps 2.0 及以后仅支持 Helm 3 API;大部分为 Helm 2 编写的 Chart 仍可正常工作,但官方不再保证兼容。

二、快速开始:两条命令完成安装

官方在项目 README 中给出的最小安装命令如下(原文即完整安装方式,仅两条命令):

kubectl create namespace kubeapps helm install kubeapps --namespace kubeapps oci://registry-1.docker.io/bitnamicharts/kubeapps

对应的更完整形式(Chart README 的 TL;DR)为:

helm install my-release oci://registry-1.docker.io/bitnamicharts/kubeapps --namespace kubeapps --create-namespace

说明与前提:

  • 命令中的REGISTRY_NAME/REPOSITORY_NAME占位符以 Bitnami 为例应替换为registry-1.docker.io与bitnamicharts;
  • Chart 官方要求:Kubernetes 1.23+、Helm 3.8.0+、具备创建 CRD 的集群管理员权限、底层基础设施支持 PV(PostgreSQL 需要持久化)——这些要求记录在 chart/kubeapps/README.md;
  • Kubeapps 生产部署使用的是独立的 Bitnami Kubeapps Chart 主要用于开发目的;
  • 注意:每个 namespace 只支持一个 Kubeapps 安装实例;
  • 一个 namespace 内只能安装一个 Kubeapps;该 Chart 同时打包了 Bitnami PostgreSQL 子 Chart(数据库)与 Redis 子 Chart(Flux 插件所需)。

安装完成后可参照 getting-started 教程 继续使用。

三、安装后的第一步:创建演示凭据并访问 Dashboard

官方快速入门(getting-started.md)建议:任何面向真实用户的安装都应配置 OAuth2/OIDC,但为了快速体验,可以用 Kubernetes ServiceAccount 令牌登录。

创建 ServiceAccount 与绑定(Linux/macOS):

kubectl create --namespace default serviceaccount kubeapps-operator kubectl create clusterrolebinding kubeapps-operator --clusterrole=cluster-admin --serviceaccount=default:kubeapps-operator cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Secret metadata: name: kubeapps-operator-token namespace: default annotations: kubernetes.io/service-account.name: kubeapps-operator type: kubernetes.io/service-account-token EOF

注意:给用户分配cluster-admin仅用于演示,生产环境请参考 访问控制文档 配置细粒度 RBAC。

提取令牌:

kubectl get --namespace default secret kubeapps-operator-token -o go-template='{{.data.token | base64decode}}'

启动 Dashboard:

kubectl port-forward -n kubeapps svc/kubeapps 8080:80

随后在浏览器打开http://127.0.0.1:8080/,粘贴令牌即可进入 Kubeapps 主界面。部署 WordPress 等应用的完整交互流程(搜索包 → 填参数 → 查看状态与访问地址)同样在 getting-started.md 中有逐步说明,本文不再重复截图细节。

四、生产环境配置:Ingress、TLS 与外部暴露

前端本身带有一个到 Kubernetes API 的反向代理,因此把 Kubeapps 暴露到集群外网络时,Kubernetes API 也会随之暴露给该网络的已认证请求。官方强烈建议配置 OAuth2/OIDC 提供方,让认证代理(而非裸的 Kubeapps 前端)暴露在外,从而保证只有 IdP 信任的用户能触达前端进而触达 API;Service Token 认证只应用于演示环境。

4.1 LoadBalancer 方式

最简单的暴露方式是把前端 Service 改为 LoadBalancer:

helm install kubeapps oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps \ --namespace kubeapps \ --set frontend.service.type=LoadBalancer

然后观察 LoadBalancer 分配情况:

kubectl get services --namespace kubeapps --watch

4.2 Ingress 方式

Chart 原生支持 Ingress,参数集中在ingress.*(默认值见 values.yaml):

参数默认值说明
ingress.enabledfalse是否生成 Ingress 记录
ingress.hostnamekubeapps.localIngress 默认主机名
ingress.path/默认路径(ALB 控制器可能需要/*)
ingress.pathTypeImplementationSpecific路径匹配类型
ingress.annotations{"nginx.ingress.kubernetes.io/proxy-read-timeout":"600"}额外注解,可放 cert-manager 自动签发注解
ingress.tlsfalse是否为ingress.hostname启用 TLS
ingress.selfSignedfalse由 Helm 生成自签名证书并创建 TLS Secret
ingress.certManagerfalse使用 cert-manager 管理证书
ingress.extraHosts[]附加主机名数组
ingress.secrets[]自定义 TLS 证书 Secret

把http://example.com映射到 Dashboard:

helm install kubeapps oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps \ --namespace kubeapps \ --set ingress.enabled=true \ --set ingress.hostname=example.com \ --set ingress.annotations."kubernetes\.io/ingress\.class"=nginx

TLS 的四种常见管理方式(来自 chart/kubeapps/README.md):

  1. 由 Helm 依据参数生成/管理证书:把证书与私钥写入ingress.secrets[].certificate/ingress.secrets[].key;
  2. 用户自行管理证书:需提供名为_INGRESS_HOSTNAME_-tls的 TLS Secret(INGRESS_HOSTNAME替换为ingress.hostname的值);
  3. 同时设置ingress.tls=true与ingress.selfSigned=true,由 Helm 生成自签名证书;
  4. 集群已安装 cert-manager 时设置ingress.certManager=true,通过注解自动签发。

在子路径下提供服务:例如把 Kubeapps 挂到http://example.com/subpath:

helm install kubeapps oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps \ --namespace kubeapps \ --set ingress.enabled=true \ --set ingress.hostname=example.com \ --set ingress.path=/subpath \ --set ingress.annotations."kubernetes\.io/ingress\.class"=nginx

若同时启用 OIDC 登录,还需同步调整认证代理的路径参数:

--set authProxy.oauthLoginURI="/subpath/oauth2/login" \ --set authProxy.oauthLogoutURI="/subpath/oauth2/logout" \ --set authProxy.extraFlags="{<other flags>,--proxy-prefix=/subpath/oauth2}"

Cookie 过大报错:使用 LDAP via Dex 与 OIDC 时可能遇到upstream sent too big header while reading response header from upstream,可在 NGINX Ingress 上追加注解解决:

--set ingress.annotations."nginx\.ingress\.kubernetes\.io/proxy-read-timeout"=600 --set ingress.annotations."nginx\.ingress\.kubernetes\.io/proxy-buffer-size"=8k --set ingress.annotations."nginx\.ingress\.kubernetes\.io/proxy-buffers"=4

五、认证与授权:OIDC 与 RBAC

  • 认证:官方提供了两条路径——独立 OAuth2/OIDC 提供方教程 与 Pinniped 集成教程。Chart 层面由authProxy.*参数驱动(默认关闭,authProxy.enabled=false),关键参数包括:
参数默认值说明
authProxy.enabledfalse是否启用 OAuth 登录/登出
authProxy.oauthLoginURI/oauth2/start前端重定向的 OAuth 登录 URI
authProxy.oauthLogoutURI/oauth2/sign_out前端重定向的 OAuth 登出 URI
authProxy.provider""OAuth 提供方
authProxy.clientID/clientSecret""OAuth 客户端凭据
authProxy.cookieSecret""oauth2-proxy 加密凭据用密钥
authProxy.existingOauth2Secret""复用现有 Secret(需含clientID、clientSecret、cookieSecret键)
authProxy.scopeopenid email groupsOAuth 作用域
authProxy.emailDomain*允许的邮箱域名
authProxy.skipKubeappsLoginPagefalse跳过 Kubeapps 登录页直接跳转 IdP
  • 授权:Kubeapps 本身不额外实现权限模型,而是把 Kubernetes RBAC 当作授权依据(见 访问控制文档)。用户令牌被透传给 Kubernetes API,因此用户能做什么完全取决于其 ServiceAccount / User 在集群中的 RBAC 绑定。例如"列表 namespaces 过慢"这类问题就与 RBAC 枚举逻辑相关(见下文排障)。

六、应用仓库:AppRepository CRD 与初始仓库配置

Kubeapps 通过自定义资源apprepositories.kubeapps.com管理应用仓库(CRD 定义见 chart/kubeapps/crds/apprepository-crd.yaml,Go 类型见 cmd/apprepository-controller/pkg/apis/apprepository/v1alpha1/types.go)。其 Spec 包含type、url、auth、interval、filterRule、ociRepositories等字段。

默认情况下 Kubeapps 会跟踪 Bitnami Application Catalog;如需修改默认仓库,通过 Chart 的apprepository.initialRepos覆盖。仓库同步由 AppRepository Controller 驱动的 CronJob/Job 完成——从 controller.go 的syncHandler可以看到典型的 controller-runtime 工作队列模式:informer 监听 CRD 变更、写入 workqueue、syncHandler对比期望状态与实际状态并更新 Status。相关 Chart 参数:

参数默认值说明
apprepository.initialRepos[]初始仓库列表
apprepository.crontab""仓库同步默认调度(默认每 10 分钟)
apprepository.watchAllNamespacestrue是否监听所有 namespace(支持按 namespace 隔离仓库)
apprepository.globalReposNamespaceSuffix""全局仓库 namespace 后缀(Helm 插件)

私有仓库:Kubeapps 支持私有仓库,配置方法见 private-app-repository 文档。注意官方不允许为集群级全局仓库配置imagePullSecrets(因为那要求 Kubeapps 在用户部署时把 Secret 拷贝到目标 namespace,存在安全扩散风险);最佳实践是把所需imagePullSecrets配置到 Kubernetes 节点上,或让 Secret 在目标 namespace 中可用。

全局仓库的认证:imagePullSecrets只能手动配置(原因同上),可通过节点级凭据配置解决。

七、Operator 支持与功能开关

Kubeapps 自 v1.9.0 起支持在 Dashboard 中部署与管理 Operator(v2.0 起默认启用),详见 operators 教程。Chart 中的功能开关汇总:

参数默认值说明
featureFlags.operatorsfalse启用 Operator 支持
featureFlags.apiOnly.enabledfalse仅暴露 API 的 Ingress(此时 Dashboard 不可用)
featureFlags.schemaEditor.enabledfalse启用包 Schema 可视化编辑器

打包后端同样可开关:

参数默认值说明
packaging.helm.enabledtrue启用标准 Helm 打包
packaging.carvel.enabledfalse启用 Carvel(kapp-controller)打包
packaging.flux.enabledfalse启用 Flux v2 打包(需要 Redis)

八、多集群与离线部署

  • 多集群:Kubeapps 2.0+ 支持多集群环境,将 Kubeapps 所在集群称为 "Kubeapps cluster",其余为 "additional clusters",详细配置见 deploying-to-multiple-clusters 文档。clustersChart 参数用于声明可部署目标集群列表,Kubeapps-APIs 侧为多集群场景预留了/etc/additional-clusters-cafiles目录存放各集群 CA 证书(见 plugins.go)。
  • 离线(air-gapped)安装:官方提供 offline-installation 文档,适合无外网环境。

九、API 说明与文档导航

Kubeapps-APIs 基于 gRPC(bufbuild/connect + grpc-gateway)同时提供 gRPC 与 RESTful 风格接口,端口默认50051(kubeappsapis.containerPorts.http)。Serve()还挂载了/openapi.json与/docs路径(见 server.go)。官方 API 文档(OpenAPI)可从仓库 dashboard/public/openapi.yaml 获取,Swagger 定义见 cmd/kubeapps-apis/docs/kubeapps-apis.swagger.json;注意官方声明 API 仍在演进,非最终版本。

更多资料按类型组织在 site/content/docs/latest/README.md:

章节说明
Tutorials面向新用户的手把手入门
How-to guides解决具体问题与用例(访问控制、多集群、离线安装、私有仓库等)
Background架构与实现细节
Reference开发者指南、设计提案、翻译等

十、排障手册:常见错误与解决步骤

以下内容来自 chart/kubeapps/README.md 的官方 FAQ,可直接用于实战:

10.1 卸载与清理

helm uninstall -n kubeapps kubeapps # 可选:仅当集群中再无其他 Kubeapps 实例时 kubectl delete crd apprepositories.kubeapps.com

警告:删除apprepositories.kubeapps.comCRD 会删除所有已安装 Kubeapps 实例的仓库配置,会破坏仍在运行的安装。

若为 Kubeapps 单独开辟了 namespace,可彻底清理残留资源:

kubectl delete namespace kubeapps

10.2 升级失败:重置式升级

当 Chart 升级报错(新版本破坏性变更或安装状态不一致)时,按官方步骤处理:

  1. (可选)备份个人仓库:
    kubectl get apprepository -A -o yaml > <repo name>.yaml
  2. 删除 Kubeapps:
    helm del --purge kubeapps
  3. (可选,仅单实例时)删除 CRD:
    kubectl delete crd apprepositories.kubeapps.com
  4. (可选,仅 namespace 中无其他负载时)清理 namespace:
    kubectl delete namespace kubeapps
  5. 安装最新版本(携带需要的自定义参数):
    helm install --name kubeapps --namespace kubeapps oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps
  6. (可选)恢复仓库:
    kubectl apply -f <repo name>.yaml

升级前请特别留意 Chart 升级说明中的破坏性变更,例如:

  • 到 17.1.0:引入镜像验证,如需关闭设置global.security.allowInsecureImages=true;
  • 到 17.0.0:PostgreSQL 子 Chart 升级到 16.0.0(PostgreSQL 17.x),需按官方指引升级数据库;
  • 到 16.0.0:Redis 子 Chart 升级到 20.0.0;
  • 到 15.0.0:安全默认值变更——runAsGroup从0改为1001、readOnlyRootFilesystem=true、resourcesPreset由none改为最小可用值、global.compatibility.openshift.adaptSecurityContext由disabled改为auto、networkPolicy归一化且默认enabled=true;
  • 到 8.0.0:大量参数重命名(如frontend.service.port→frontend.service.ports.http、postgresql.postgresqlPassword→postgresql.auth.password等),现有 PostgreSQL Secret 的键需从postgresql-password改为postgres-password;
  • 到 6.0.0:Kubeapps 不再自动创建数据库 Secret;升级时需用旧 Secret 密码显式传入--set postgresql.postgresqlPassword=$POSTGRESQL_PASSWORD,并先删除旧的bitnami初始仓库(否则出现rendered manifests contain a resource that already exists错误)。

10.3 RBAC 未启用时报错

安装时出现如下错误,说明集群可能未启用 RBAC:

Error: release kubeapps failed: clusterroles.rbac.authorization.k8s.io "kubeapps-apprepository-controller" is forbidden: attempt to grant extra privileges: ... Error: namespaces "kubeapps" is forbidden: User "system:serviceaccount:kube-system:default" cannot get namespaces in the namespace "kubeapps"

检查方法:

kubectl api-versions

若输出不含rbac.authorization.k8s.io,则关闭 RBAC 创建后安装:

helm install --name kubeapps --namespace kubeapps oci://REGISTRY_NAME/REPOSITORY_NAME/kubeapps --set rbac.create=false

10.4 列表 namespaces 响应缓慢

Kubeapps 使用当前登录用户的凭据列出 namespaces;若无权限,后端会退回到自己的 ServiceAccount 列举全部 namespaces,再逐个检查用户权限,namespace 数量大时响应变慢。可提升并行度:

--set kubeappsapis.burst=<desired_number> --set kubeappsapis.QPS=<desired_number>

对应 Chart 默认值为kubeappsapis.qps=50.0、kubeappsapis.burst=100,并会在 Kubeapps-APIs 的 Kubernetes 客户端中生效(插件注册时透传给各插件,见 plugins.go 中ClientQPS/ClientBurst)。

10.5 IPv6 错误

启用--set enableIPv6=true后 NGINX 报:

nginx: [emerg] socket() [::]:8080 failed (97: Address family not supported by protocol)

说明集群不支持 IPv6,改用--set enableIPv6=false即可。

十一、版本历史与演进线索

Kubeapps Chart 版本与上游能力演进记录在 chart/kubeapps/CHANGELOG.md 与 Chart.yaml:

  • Chart 当前版本 17.1.1,appVersion: DEVEL(开发版),apiVersion: v2(仅 Helm 3 可安装),kubeVersion: '>=1.21.0-0';
  • 2.0 起仅支持 Helm 3;MongoDB 支持被移除,数据库只保留 PostgreSQL;
  • 5.0.0 起 Chart 从apiVersion: v1迁移到v2,正式与 Helm 2 告别。

注:本仓库中 chart/kubeapps 为开发用 Chart;面向生产安装请使用官方 Bitnami 发布的 Kubeapps Chart(oci://registry-1.docker.io/bitnamicharts/kubeapps)。

十二、为项目做贡献

项目鼓励开发者直接参与:阅读 CONTRIBUTING.md 了解开发环境搭建与提交流程,参考 ROADMAP.md 了解演进方向。需要提醒的是,上游官方仓库已于 2025 年 8 月宣布归档停更,并由 SAP SE 团队 fork 继续维护;如果你正规划新部署,建议优先评估该 fork 的后续版本。

结语

从项目 README 出发可以看到,Kubeapps 的设计哲学是"一次安装、聚合多种打包生态、把 Kubernetes 自身的认证与授权机制作为安全边界"。无论是单集群快速体验、OIDC + RBAC 的生产加固,还是多集群、离线场景的扩展,官方文档 与 Chart README 都提供了可直接落地的操作步骤;而仓库源码(尤其是 kubeapps-apis 插件机制 与 AppRepository Controller)则是理解其内部工作原理的最佳材料。

  • 云原生
  • 后端
  • 前端

【免费下载链接】kubeapps

A web-based UI for deploying and managing applications in Kubernetes clusters

项目地址:https://gitcode.com/gh_mirrors/ku/kubeapps
点击查看免费下载

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进