ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Teleport Kubernetes Agent Updater 深度解析:大规模集群下的 Teleport Agent 自动升级控制器

Teleport Kubernetes Agent Updater 深度解析:大规模集群下的 Teleport Agent 自动升级控制器 Teleport Kubernetes Agent Updater 深度解析大规模集群下的 Teleport Agent 自动升级控制器【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleportteleport-kube-agent-updater是 Teleport 仓库中用于自动更新 Kubernetes 集群内 Teleport Agent 的控制器controller组件。它通过持续监听 Deployment 与 StatefulSet在维护窗口内校验版本、验证镜像签名并自动滚动升级 Agent从而大幅降低大规模部署场景下的人工运维成本。读完本文你将掌握该 Updater 的设计动机、三阶段更新逻辑、全部命令行参数与部署方式并能结合仓库源码理解其故障自愈机制。一、它是什么为大规模集群卸下 Agent 升级负担在 Teleport 的架构里所谓 Teleport Kubernetes Agent 并不局限于 Kubernetes Access 一种场景。它泛指运行在 Kubernetes 集群中、且不运行 Proxy 与 Auth Service 的每一个 Teleport 实例通常由teleport-kube-agentHelm Chart 部署。当集群规模很大、Agent 数量很多时逐个升级 Agent 的成本会急剧上升。teleport-kube-agent-updater正是为解决这个问题而生的控制器它以自动化方式承担 Agent 升级职责让运维人员无需再逐个更新集群中的 Agent。其完整代码位于仓库的 integrations/kube-agent-updater 目录入口程序为 cmd/teleport-kube-agent-updater/main.go。从代码组织看该组件按职责划分为清晰的包pkg/controller核心控制器逻辑包含 Deployment 与 StatefulSet 两个 Reconcile 实现pkg/img镜像签名验证与摘要解析基于 cosignpkg/maintenance维护窗口与工作负载健康度检查触发器pkg/podutilsPod 过滤工具函数hack/cosign-fixtures.go测试用 cosign 夹具。二、设计原则允许短暂故障绝不允许卡死从设计文档README.md与源码注释可以总结出两个核心原则短暂停机可接受如果一次更新失败出现临时性的服务不可用是可以容忍的这一风险通常通过多副本部署multi-replica来对冲卡死状态绝对不允许更新失败后如果部署卡在一个需要人工介入才能恢复的状态这是必须避免的失败模式。这直接决定了控制器的实现方向一方面维护窗口maintenance window机制让升级集中在计划内的时间段进行另一方面pkg/controller中针对 StatefulSet 专门实现了 解除卡死滚动unblock rollout逻辑会在升级失败时自动清理旧版本的不健康 Pod让 StatefulSet 控制器重新拉起新 Pod而不是把集群留在半死不活的状态。此外Updater 会校验镜像来源image provenance防止镜像仓库被攻破后拉取到被篡改的镜像——这正是pkg/img包内 cosign 签名验证的职责。三、核心更新逻辑三步走Updater 的更新判定逻辑高度收敛在 pkg/controller/updater.go 的VersionUpdater.GetVersion方法中严格遵循以下三步// Can we do a maintenance? if !r.maintenanceTriggers.CanStart(ctx, obj) { return nil, MaintenanceNotTriggeredError{} } // Get the next version nextVersion, err : r.versionGetter.GetVersion(ctx) ... if !version.ValidVersionChange(ctx, currentVersion, nextVersion) { return nil, version.NoNewVersionError{...} } // We validate the signatures digested, err : r.imageValidators.Validate(ctx, image)步骤 1检查是否允许维护maintenance只有维护触发器maintenance trigger被触发时才允许开始升级。触发器是 OR 关系任一触发即可。实际由 main.go 中的maintenance.Triggers组合而成maintenanceTriggers : maintenance.Triggers{ // 关键更新critical update maintenance.FailoverTrigger(criticalUpdateTriggers), // Agent 工作负载不健康 podmaintenance.NewUnhealthyWorkloadTrigger(unhealthy pods, mgr.GetClient()), // 处于计划维护窗口内 maintenance.FailoverTrigger(plannedMaintenanceTriggers), }关键更新触发器版本服务器或 Proxy 宣告存在关键更新如紧急安全修复时立即触发不健康工作负载触发器pkg/maintenance/unhealthy.go当工作负载管理的 Pod 中至少有一个不健康时触发。这一设计的目的是如果新版本破坏了 Agent可以立刻回滚恢复而不必等到下一个维护窗口当工作负载没有任何 Pod 时也视为不健康。其Default()返回false即无法评估时默认不触发保证安全维护窗口触发器pkg/maintenance/window.goAgent 会将维护计划写入名为workload-shared-state的 Kubernetes Secret 的agent-maintenance-schedule键中JSON 格式{windows:[{start:...,stop:...}]}Updater 判断当前时间是否落在某个窗口内。关键细节如果 Secret 缺失或过期触发器反而默认允许维护Default()返回true因为缺少有效维护计划意味着 Agent 可能工作不正常应当尽快升级修复。步骤 2检查是否有可用且合法的新版本Updater 通过版本获取器version.Getter向外部询问目标版本然后调用version.ValidVersionChange校验版本变化是否合法例如不允许降级或跨不兼容的大版本。从 main.go 可以看到版本获取器有两种来源且可以同时启用取第一个成功的来源对应协议说明--proxy-addressRFD-184 更新协议从 Proxy 的/find端点获取版本与关键更新信息对应仓库 rfd/0184-agent-auto-updates.md同时承担常规维护与关键更新两类触发器--version-serverRFD-109 更新协议从版本服务器 URL 拼接版本通道versionServer / versionChannel获取版本关键更新由该通道宣告计划维护窗口则从 Pod 导出对应仓库 rfd/0109-cloud-agent-upgrades.md当两者都未配置时程序会直接报错退出the updater has no upstream configured, it cannot retrieve the version and check when to update。步骤 3验证新镜像可被信任拿到新版本后Updater 以基础镜像名 新版本 tag 构造候选镜像如public.ecr.aws/gravitational/teleport:16.0.0随后交给img.Validators进行 cosign 签名验证。验证器列表是OR 关系只要有一个验证器通过即视为可信pkg/img/validator.go。验证通过后返回的镜像引用同时携带tag携带版本信息与 digest保证运行时拉取的是被验证过的确切镜像即NamedTaggedDigested接口pkg/img/validator.go。这一点非常关键即便镜像 tag 之后被重打Kubernetes 节点也只会运行通过验证的那个 digest 对应的镜像。四、安全机制cosign 签名验证与多级信任Updater 默认强制要求镜像签名可验证防止镜像仓库被攻破后分发被篡改的镜像。验证密钥硬编码在 cmd/teleport-kube-agent-updater/constants.goteleportProdOCIPubKey用于签署 Teleport 生产环境 distroless 镜像的公钥密钥存放在 Teleport 生产 AWS KMS 中teleportStageOCIPubKey用于签署开发构建镜像的公钥存放在 staging AWS KMS仅当 Updater 自身是预发布pre-release版本时才被信任。main.go 中的选择逻辑如下场景采用的验证策略--insecure-no-resolve-image完全禁用验证与摘要解析可更新到不存在的镜像极度不安全--insecure-no-verify-image禁用签名验证但仍解析 tag 且要求镜像必须存在不安全Updater 为预发布版本同时信任 staging 与 production 两把公钥fallthrough默认生产发布版仅信任 production 公钥五、部署形态与工作方式一个 Updater 管理一个工作负载从 main.go 可以看到Updater 基于controller-runtime构建每个 Updater 进程只针对一个 Deployment 或 StatefulSet缓存被限定在agentNamespace且按metadata.name agentName字段选择器过滤Leader Election ID 也复用 agentName。因此生产环境中通常是一个 Agent 工作负载配一个 Updater的部署模式。控制器通过两个 Reconcile 实现完成升级pkg/controller/deployment.go处理 Deployment。读取当前版本 → 调用GetVersion判定是否需要升级 → 修改名为teleport的容器镜像 → 更新 Deployment。若镜像 tag 无法解析出版本会继续尝试升级其他错误则记录状态并延后重试。pkg/controller/statefulset.go处理 StatefulSet。除了相同的升级流程外还包含unblockStatefulSetRolloutIfStuck逻辑StatefulSet 的滚动升级可能被旧版本的不健康 Pod卡住Updater 会删除那些属于旧 controller revision 且不健康的 Pod让 StatefulSet 控制器按最新 spec 重新创建从而解除卡死状态。此外还有一个关键细节teleport.dev/skipreconcile注解可以按资源禁用自动更新pkg/controller/constants.go方便运维对特定 Agent 暂停自动升级。状态报告机制StatusWriter会把更新状态与进度写回工作负载对象通过 controller-runtime 的 status 子资源Pod 侧据此决定挂载配置、执行更新等行为。Updater 自身会创建一个名为agentName-updater的 ConfigMap 持久化一个 UUIDupdate ID用于在代理更新协议RFD-184中标识自身main.go。六、命令行参数速查以下是 main.go 中定义的全部启动参数参数默认值说明--agent-name空必填要更新的 Agent 工作负载名称Deployment/StatefulSet 名必填--agent-namespace空必填Agent 工作负载所在命名空间必填--metrics-addr:8080metrics 端点监听地址--healthz-addr:8081健康探针端点监听地址--sync-period10h控制器缓存同步周期Gotime.ParseDuration格式--insecure-no-verify-imagefalse禁用镜像签名验证仍解析 tag、要求镜像存在--insecure-no-resolve-imagefalse禁用签名验证与解析可更新到不存在的镜像--disable-leader-electionfalse禁用 leader election用于在 Kubernetes 外运行 Updater--proxy-address空Teleport 集群 Proxy 地址设置后通过/find端点获取更新RFD-184--update-group空Agent 更新组对应autoupdate_config资源未设置或未知时使用默认组--version-serverhttps://updates.releases.teleport.dev/v1/宣告目标版本与关键维护的 HTTP 服务器尾斜杠可选RFD-109--version-channelstable/cloud获取更新的版本通道--base-imagepublic.ecr.aws/gravitational/teleport基础镜像引用registry repository--pull-credentialsnone镜像仓库拉取凭据来源可选docker、google、amazon、none--log-levelINFO日志级别DEBUG、INFO、WARN、ERROR日志格式为 JSON其中--agent-name与--agent-namespace为必填项--proxy-address与--version-server至少提供一个否则启动即失败。七、本地调试连接远程集群仓库附带的 DEBUG.md 提供了完整的本地调试流程——在本地运行 Updater 并连接远程 Kubernetes 集群便于挂载调试器复现复杂问题确认当前 kube context 可用kubectl cluster-info打开一个到 API Server 的代理保持该 shell 持续运行kubectl proxy在新终端中创建临时目录与指向本地代理的 kubeconfigexport KUBECONFIG$(mktemp) kubectl config set-credentials myself --usernamefoo kubectl config set-cluster local-server --serverhttp://localhost:8001 kubectl config set-context default-context --clusterlocal-server --usermyself kubectl config use-context default-context echo $KUBECONFIG设置KUBECONFIG环境变量后运行控制器例如go run或调试器启动cmd/teleport-kube-agent-updater主程序并带上--agent-name、--agent-namespace、--disable-leader-election等参数。仓库还提供了 Dockerfile 与 Makefile可用于构建发布镜像组件版本号定义在 version.go。针对控制器逻辑、维护触发器与镜像验证均有对应的单元测试如 pkg/controller/updater_test.go、pkg/controller/statefulset_test.go、pkg/maintenance/window_test.go、pkg/img/cosign_test.go可作为理解各模块行为的参考。八、总结teleport-kube-agent-updater以维护窗口内自动升级 cosign 镜像签名验证 健康自愈三要素为核心维护窗口机制让升级可控、可计划镜像验证保证从源头杜绝被篡改的镜像进入集群健康检查与 StatefulSet 卡死解除机制则确保即使升级失败集群也能自动恢复而非停在需要人工介入的状态。对于大规模 Kubernetes 集群中批量管理 Teleport Agent 的场景它是一套开箱即用、安全可控的自动化升级方案。【免费下载链接】teleportThe easiest, and most secure way to access and protect all of your infrastructure.项目地址: https://gitcode.com/gh_mirrors/tel/teleport创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表