sealed-secrets 开发者指南:从开发环境搭建到 Controller/Kubeseal 构建测试与 git-hooks 规范
【免费下载链接】sealed-secretsA Kubernetes controller and tool for one-way encrypted Secrets项目地址: https://gitcode.com/GitHub_Trending/se/sealed-secrets
本文以仓库 docs/developer/README.md 为主干,结合 controller.md、kubeseal.md、Makefile 及核心源码,系统梳理 Sealed Secrets 项目的本地开发流程:环境依赖、两大可执行组件的源码布局、完整测试链路(单元测试 → 构建镜像 → 部署清单 → 集成测试),以及通过 git-hooks 自动化维护文档目录(TOC)的工程规范。读完本文,你将能够在一台装有 Go 与 Docker 的机器上独立完成 controller 与 kubeseal 的编译、在 minikube/kind 上跑通端到端集成测试,并掌握仓库文档维护的提交前校验流程。
Sealed Secrets 的三大组成部分
Sealed Secrets 由三个部分协同工作(见 docs/developer/README.md):
- 自定义资源(CRD):名为
SealedSecret的 Kubernetes Custom Resource,其 API 定义位于 pkg/apis/sealedsecrets/v1alpha1/types.go,对应的 CRD 清单为 helm/sealed-secrets/crds/bitnami.com_sealedsecrets.yaml。 - 集群侧 controller / operator:负责让
SealedSecret对象的当前状态持续与声明式期望状态保持同步。 - 客户端工具 kubeseal:使用非对称加密(asymmetric crypto)对 Secret 加密,且只有集群内的 controller 能解密。
开发者通常围绕 controller 与 kubeseal 两条主线展开工作,两条线都遵循"下载源码 → 编译 → 测试"的循环。
开发前置条件(Prerequisites)
要在本地开发本项目,需要预先安装以下工具(均来自 docs/developer/README.md 的 Prerequisites 清单):
- Git:版本管理。
- Make:项目构建入口,仓库根目录的 Makefile 定义了
controller、kubeseal、test、integrationtest等全部目标。 - Go 编程语言:项目主体语言,
go.mod位于仓库根目录。 - Docker CE:用于构建 controller 容器镜像。
- Kubernetes 集群(v1.16+):运行集成测试所需;文档推荐使用 Minikube,也可使用 kind。
- Kubecfg:用于将仓库根目录的
.jsonnet控制器清单(controller.jsonnet、controller-norbac.jsonnet 等)渲染为 YAML。 - Ginkgo:集成测试框架,对应 Makefile 中的
GINKGO = ginkgo -p。 - git-hooks:第三方 Git hooks 管理工具,用于安装仓库内预置的提交钩子。
- doctoc:为 Markdown 文档自动生成/更新 Table of Contents 的工具。
其中 Go、Docker 和集群环境是构建与集成测试的硬性前提;Kubecfg、Ginkgo 仅在执行 manifest 渲染与集成测试时使用;git-hooks 与 doctoc 服务于文档工程规范。
组件一:Controller 开发指南
controller 的职责是保持SealedSecret对象当前状态与期望状态同步(详见 controller.md)。controller 对外暴露一个基于 Swagger/OpenAPI v3 规范定义的 API,定义文件为 swagger.yml。
获取源码与目录布局
git clone https://github.com/bitnami/sealed-secrets.git $SEALED_SECRETS_DIRcontroller 源码位于cmd/controller/(入口为 cmd/controller/main.go),并复用pkg目录下的包。其中关键的实现包括:
- 参数绑定:
cmd/controller/main.go中bindControllerFlags绑定了--key-size、--key-renew-period、--key-ttl、--update-status等核心参数,且所有参数支持通过SEALED_SECRETS_*环境变量注入(pkg/flagenv与pkg/pflagenv)。 - 控制器主体:
pkg/controller/main.go中的Main()完成密钥注册、密钥轮换调度、informer 启动与 HTTP 服务启动的完整装配。 - 密钥管理:
pkg/controller/keyregistry.go的KeyRegistry以 RSA 密钥对 + X.509 证书为核心数据结构,按指纹索引并维护mostRecentKey。 - 密钥持久化:
pkg/controller/keys.go通过带sealedsecrets.bitnami.com/sealed-secrets-key: active标签的 TLS 类型 Secret 存储私钥与证书。 - HTTP API:
pkg/controller/server.go暴露/healthz、/v1/verify、/v1/rotate、/v1/cert.pem以及:8081上的/metrics。
搭建用于测试的 Kubernetes 集群
集成测试需要一个 Kubernetes 集群。两种推荐方式:
方式一:minikube(复用本地 Docker daemon)
minikube start eval $(minikube docker-env)方式二:kind(搭配本地镜像仓库)
先在本地启动一个 registry:
export LOCAL_REGISTRY_PORT='5000' export LOCAL_REGISTRY_NAME='kind-registry' docker run --rm -d -p "127.0.0.1:${LOCAL_REGISTRY_PORT}:5000" --name "${LOCAL_REGISTRY_NAME}" registry:2再创建允许访问该 registry 的 kind 集群:
cat <<EOF | kind create cluster --name "${CLUSTER_NAME}" --config=- kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 containerdConfigPatches: - |- [plugins."io.containerd.grpc.v1.cri".registry.mirrors."localhost:${LOCAL_REGISTRY_PORT}"] endpoint = ["http://${LOCAL_REGISTRY_NAME}:5000"] EOF docker network connect "kind" "${LOCAL_REGISTRY_NAME}"一条命令跑完所有 controller 测试
Makefile 中的controller-tests目标由test push-controller apply-controller-manifests clean integrationtest串联而成,一条命令即可完成"单元测试 → 构建并推送镜像 → 应用清单 → 集成测试"的完整链路:
make K8S_CONTEXT=mytestk8s-context OS=linux ARCH=amd64 controller-tests需要注意:
K8S_CONTEXT必须设置为指向目标测试集群的kubectlcontext 名称。OS与ARCH必须与测试集群所在节点的操作系统与架构一致(例如linux/amd64)。
对于 kind + 本地 registry 的组合,需要额外指定REGISTRY:
make K8S_CONTEXT=kind REGISTRY=localhost:5000 OS=linux ARCH=amd64 controller-tests对于 minikube 则无需REGISTRY(本地 Docker daemon 直接可达):
make K8S_CONTEXT=minikube OS=linux ARCH=amd64 controller-tests分步执行测试流程
1. 构建 controller 二进制
make controller该命令对应 Makefile 中的目标:
controller: $(GO_FILES) $(GO) build -o $@ $(GO_FLAGS) -ldflags "$(GO_LD_FLAGS)" ./cmd/controller产物controller二进制会生成在当前工作目录;GO_LD_FLAGS会把main.VERSION注入为当前 commit 或 tag(工作区有未提交改动时追加+dirty后缀),可通过controller -version查看。
2. 运行单元测试
make test对应目标使用gotestsum生成 JUnit 报告与覆盖率文件:
test: $(GOTESTSUM) $(GO_FLAGS) --junitfile report.xml --format testname -- "-coverprofile=coverage.out" $(GO_PACKAGES)GO_PACKAGES = ./...,即覆盖仓库全部 Go 包,包括 pkg/controller、pkg/crypto、pkg/kubeseal 等目录下的测试。
3. 构建并推送 controller 镜像
minikube 场景(实际不会 push,minikube 直接访问本地镜像):
make K8S_CONTEXT=minikube OS=linux ARCH=amd64 push-controller使用自定义 registry(如 kind 本地仓库)时:
make K8S_CONTEXT=kind REGISTRY=localhost:5000 OS=linux ARCH=amd64 push-controllerMakefile 中push-controller会先clean并执行scripts/check-k8s校验集群可达性,然后构建controller.image.$(OS)-$(ARCH)。镜像基于 docker/controller.Dockerfile 构建,默认镜像名规则为$(REGISTRY)/bitnami/sealed-secrets-controller:latest。当REGISTRY=docker.io(minikube 默认场景)时跳过实际 push,否则执行docker push。
4. 构建并应用 controller manifests
make K8S_CONTEXT=minikube apply-controller-manifests或 kind 场景:
make K8S_CONTEXT=kind REGISTRY=localhost:5000 apply-controller-manifests该目标先用kubecfg将仓库根目录的 controller.jsonnet(依赖 kube-fixes.libsonnet 与 schema-v1alpha1.yaml)渲染为controller.yaml,随后kubectl apply -f controller.yaml部署到集群,并通过kubectl rollout status deployment sealed-secrets-controller -n kube-system等待控制器就绪。
5. 运行集成测试
make integrationtest对应 Makefile 目标:
integrationtest: kubeseal controller $(GINKGO) -tags 'integration' integration -- -kubeconfig $(KUBECONFIG) -kubeseal-bin $(abspath $<) -controller-bin $(abspath $(word 2,$^))集成测试位于 integration/ 目录(如 integration/controller_test.go、integration/kubeseal_test.go),通过integrationbuild tag 隔离。测试会真实调用kubeseal与controller二进制,在integration_suite_test.go中通过-kubeconfig、-kubeseal-bin、-controller-bin等 flag 指定被测产物路径。因此在运行集成测试前,测试集群中必须已经安装好 controller。
组件二:Kubeseal 开发指南
kubeseal 是客户端 CLI,使用非对称加密对 Secret 加密,只有 controller 能解密(详见 kubeseal.md)。
获取源码与目录布局
git clone https://github.com/bitnami/sealed-secrets.git $SEALED_SECRETS_DIRkubeseal 源码位于cmd/kubeseal/(入口为 cmd/kubeseal/main.go),同样复用pkg目录。其核心加密逻辑集中在 pkg/kubeseal/kubeseal.go,主要函数包括:
Seal:将输入 Secret 密封为 SealedSecret。EncryptSecretItem:配合--raw对单个值加密。ValidateSealedSecret:调用 controller 的/v1/verify端点校验可解密性。ReEncryptSealedSecret:调用/v1/rotate用最新密钥重新加密。UnsealSealedSecret:--recovery-unseal灾难恢复模式的离线解密。
构建 kubeseal 二进制
make kubeseal对应 Makefile 目标,同样支持静态交叉编译(如kubeseal-static-linux-amd64),产物生成在当前工作目录。
运行 kubeseal 测试
make test与 controller 共用make test,覆盖 cmd/kubeseal/main_test.go 与 pkg/kubeseal/kubeseal_test.go 等测试文件。
关联源码:controller 与 kubeseal 的核心参数速览
为便于开发调试,这里结合 cmd/controller/main.go 与 cmd/kubeseal/main.go 汇总两组关键启动参数(所有参数均可用SEALED_SECRETS_前缀的环境变量覆盖):
Controller 常用参数(controller -h可查看全部):
| 参数 | 默认值 | 说明 |
|---|---|---|
--key-size | 4096 | 加密密钥 RSA 位数 |
--key-ttl | 10 年 | 证书有效期 |
--key-renew-period | 30 天 | 新密钥生成周期,设为 0 关闭自动轮换(SIGUSR1 手动轮换仍生效) |
--key-order-priority | CertNotBefore | 密钥排序依据,可选SecretCreationTimestamp |
--key-cutoff-time | 空 | RFC1123 格式截止时间,最新密钥更早时生成新密钥 |
--all-namespaces | true | 是否扫描全部命名空间 |
--additional-namespaces | 空 | 逗号分隔的额外扫描命名空间 |
--label-selector | 空 | 过滤 SealedSecret 的标签选择器 |
--rate-limit/--rate-limit-burst | 2 / 2 | /v1/verify与/v1/rotate的每秒请求数与突发上限 |
--update-status | true | beta:处理时是否更新 status 子资源 |
--watch-for-secrets | false | beta:是否监听外部创建的密钥 Secret |
--skip-recreate | false | 跳过监听托管 Secret 变更以重建它们(适用于权限受限环境) |
--old-gc-behavior | false | 回退到旧的 GC 行为(controller 自行删除 Secret 而非交给 k8s) |
--listen-addr/--listen-metrics-addr | :8080/:8081 | HTTP 服务与指标服务地址(定义于 pkg/controller/server.go) |
Kubeseal 常用参数(kubeseal --help可查看全部):
| 参数 | 默认值 | 说明 |
|---|---|---|
--cert | 空 | 指定证书/公钥文件或 URL,覆盖--controller-* |
--controller-namespace | kube-system | controller 所在命名空间 |
--controller-name | sealed-secrets-controller | controller 名称 |
-o, --format | json | 输出格式 json/yaml |
-f, --secret-file | 空 | 输入 Secret 文件,缺省从 stdin 读取 |
-w, --sealed-secret-file | 空 | 输出文件(.yaml/.yml自动切换 yaml 格式) |
--fetch-cert | false | 从 controller 抓取证书到 stdout |
--scope | strict | 密封范围:strict / namespace-wide / cluster-wide |
--raw | false | 直接加密原始值(配合--from-file或 stdin) |
--name | 空 | --raw且 strict scope 时必填 |
--validate | false | 通过/v1/verify校验 SealedSecret 可解密 |
--re-encrypt | false | 用最新集群密钥重新加密 |
--recovery-unseal | false | 灾难恢复模式离线解密 |
--recovery-private-key | 空 | --recovery-unseal所需私钥文件(可重复指定) |
Controller 的 HTTP 端点由 pkg/controller/server.go 实现,其中/v1/cert.pem以 PEM 格式暴露当前公钥证书,这正是 kubeseal--fetch-cert的数据来源;/v1/verify与/v1/rotate均受基于throttled库的速率限制保护,并支持X-Forwarded-For头区分客户端。
git-hooks:提交前的文档目录校验
为避免显而易见的问题流入 main 分支,仓库通过 Git hooks 实现了若干校验。Git 原生 hooks 存放在.git目录(不随仓库分发),因此需要先安装第三方工具git-hooks(见前置条件),才能将 hooks 纳入版本管理。
目前仓库只在pre-commit级别挂载了一个 hook:doc-toc。它使用doctoc为所有使用了该工具的.md与.txt文件自动更新 Table of Contents。hook 脚本位于 githooks/pre-commit/doc-toc,其逻辑为:以main分支为基准计算待提交文件,凡是以.md/.txt结尾的文件都执行doctoc "$f"重新生成 TOC;若工作区因此产生改动,则git add --all并打印变更清单,从而保证"文档目录永远与正文同步"。
为本仓库配置 git-hooks:
git hooks install验证是否配置成功:
$ git hooks list Git hooks ARE installed in this repository. project hooks pre-commit - doc-toc Contrib hooks如果git hooks list输出中能看到pre-commit -> doc-toc,说明每次提交都会自动触发文档 TOC 校验与更新。
小结
Sealed Secrets 的开发者工作流可概括为三条主线:编译(make controller/make kubeseal)、测试(make test单元测试 +make integrationtest集成测试)、部署(make push-controller+make apply-controller-manifests),并可由make controller-tests一键串联。调试与理解系统时,建议沿着 cmd/controller/main.go → pkg/controller/main.go → pkg/controller/keyregistry.go 的调用链阅读,配合 cmd/kubeseal/main.go → pkg/kubeseal/kubeseal.go 理解客户端密封逻辑。最后,通过 git-hooks + doctoc 的配合,文档 TOC 的维护成本被压到零——这正是该项目工程化细节的一个缩影。
【免费下载链接】sealed-secretsA Kubernetes controller and tool for one-way encrypted Secrets项目地址: https://gitcode.com/GitHub_Trending/se/sealed-secrets
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考