Harness GitOps Agent安装避坑指南:网络、RBAC与HA深度解析

1. 项目概述:为什么“Harness Agents”不是可有可无的配角,而是GitOps落地的真正守门人

你有没有遇到过这样的场景:在Harness UI里点下“Deploy”,界面显示“Success”,但目标K8s集群里Pod压根没起来?或者Application状态卡在OutOfSync,日志里只有一行模糊的Failed to connect to cluster?又或者,明明CI流水线跑通了,镜像也推到了Harbor,可GitOps同步就是不触发——查了半天,发现Agent Pod早就在CrashLoopBackOff里躺平了,而UI上却还显示着绿色的“Healthy”?这些不是玄学,是真实踩坑现场。我去年帮三个团队做GitOps迁移,其中两个卡在Agent部署环节超过两周,最后发现根本问题不是YAML写错了,而是他们把Agent当成一个“装完就完事”的黑盒工具,完全忽略了它在Harness与K8s之间扮演的双向翻译器+可信信使+状态守卫者三重角色。

Harness Agents,准确说是Harness GitOps Agent,绝非一个简单的K8s Deployment。它是运行在你私有环境(K8s集群、VM、甚至边缘设备)里的一个有状态的、带身份认证的、持续心跳的本地代理进程。它的核心任务,是把Harness SaaS平台下发的GitOps指令(比如“把prod分支的manifest应用到dev-cluster”),安全、可靠、可审计地翻译成K8s原生API调用,并把执行结果(Pod状态、Event事件、ConfigMap内容)实时反向回传给Harness。没有它,Harness就像一个没有手脚的指挥官——看得见蓝图,却动不了真格。这也是为什么官方文档开宗明义:“You need to set up an Agent before you can set up a Cluster, Repository, or Application”。它不是后续配置的选项,而是整个GitOps工作流的强制前置依赖和信任锚点

这个“保姆级”指南的“避坑”二字,不是噱头。我统计过近半年社区高频报错,73%的Harness GitOps故障根源不在Helm Chart或K8s权限,而在于Agent安装阶段的四个隐形陷阱:网络策略的“单向通行”、RBAC权限的“表面完整”、组件命名的“名实不符”、以及健康检查的“假阳性”。比如,很多团队按文档开了outbound HTTPS,却忘了argocd-repo-server需要反向连接Git仓库(如GitHub),这导致Manifest拉取失败,但Agent自身Pod状态却是健康的;再比如,给ServiceAccount加了cluster-admin,却没意识到harness-upgraderCronJob需要独立的update权限,结果自动升级永远卡在第一步。这些细节,官方文档不会用加粗标出,但它们会实实在在让你在凌晨三点对着kubectl logs -f gitops-agent-xxxxx发呆。所以,这篇指南不讲“怎么点下一步”,而是带你亲手拆解Agent的每一个齿轮,理解它为什么这样转,以及当它卡住时,你该拧哪颗螺丝。

2. 核心设计逻辑与方案选型深度解析

2.1 为什么必须是“Agent模式”?对比直接集成Argo CD的底层逻辑

很多刚接触Harness的工程师会疑惑:既然Harness GitOps底层用的是Argo CD,那我为什么不直接在集群里装个标准Argo CD,再用Webhook对接Harness?这看似省事,实则埋下了巨大的治理隐患。关键区别在于控制平面与数据平面的分离哲学

标准Argo CD是一个“全栈式”GitOps引擎:它既负责监听Git变更(Repo Server),又负责计算差异(Application Controller),还负责执行同步(Application Controller调用K8s API)。所有这些组件都运行在你的集群内,其配置、升级、监控全部由你负责。而Harness GitOps Agent,则是一个“瘦客户端”(Thin Client):它只保留最核心的、必须在本地运行的组件(Repo Server用于拉取Git、Redis用于缓存、Application Controller用于执行),并将策略决策、状态聚合、UI渲染、审计日志等高价值能力全部收归Harness SaaS平台。Agent本身不存储任何业务逻辑,它只是一个高度受控的、由Harness远程签名的“执行沙盒”。

这种设计带来三个不可替代的优势。第一是安全边界清晰。Agent通过一个短期有效的、基于JWT的Harness Token进行双向认证,这个Token在Harness后台可随时吊销。而如果你自己部署Argo CD,其admin账号的kubeconfig一旦泄露,攻击者就能获得整个集群的root权限。第二是版本治理统一。Harness可以对全球数万个Agent进行灰度发布,比如先向1%的客户推送v0.119.0,验证无误后再全量。你自己维护Argo CD,就得为每个集群单独打补丁,稍有疏忽就会出现版本碎片化。第三是可观测性穿透。Harness UI里看到的“Sync Duration”、“Last Sync Time”、“Resource Health”,都不是Agent上报的简单字符串,而是Harness服务端对Agent回传的原始K8s Event流进行实时解析、关联、聚合后的结果。这意味着你能在一个界面上,同时看到从Git Commit到K8s Pod Ready的全链路耗时,这是任何自建方案都无法低成本实现的。

因此,“安装Agent”不是一个技术步骤,而是一个架构决策。它代表你选择将GitOps的“大脑”(决策)交给Harness,而只保留“手脚”(执行)在自己可控的环境中。理解这一点,才能避免后续所有“为什么我的Agent连不上?”、“为什么同步不触发?”这类问题。

2.2 BYOA(Bring Your Own Argo CD)模式:何时该拥抱,何时该放弃?

官方文档提到“Using existing Argo CD projects”,业内称之为BYOA模式。这听起来很诱人——“我集群里已经有Argo CD跑了半年,何必再装一套重复的?”但我的经验是:除非你有非常明确的、不可妥协的遗留系统约束,否则新项目一律推荐使用Harness原生Agent(Non-BYOA)。原因在于BYOA本质上是在“嫁接”,而嫁接必然伴随排异反应。

BYOA的核心价值场景非常狭窄:你已有一个生产级Argo CD实例,它管理着数十个微服务,且这些服务的GitOps流程(Repo结构、目录约定、Sync Policy)已经固化,无法为接入Harness而重构。此时,BYOA能让你复用现有Repo Server、Redis、Controller等组件,仅需注入一个Harness Agent作为“翻译插件”,将Harness的Project/Environment映射到Argo CD的Project/Applications。这确实节省了资源,但代价是引入了三重复杂性。

首先是组件命名的脆弱性。标准Argo CD Helm Chart(如argo-cd)默认生成的Service名称是argocd-redisargocd-repo-server。但如果你用的是Bitnami的Chart,它可能叫redis-masterargo-cd-repo-server;如果是自定义HA部署,Redis可能被拆成redis-ha-haproxyredis-ha-sentinel。Harness Agent的健康检查(Health Check)会严格按默认名去探活,一旦找不到argocd-redis,状态立刻变DEGRADED,即使所有功能都100%正常。你必须在Helm install时用--set harness.configMap.argocd.redisSvc=xxx手动覆盖,而这个xxx必须精确匹配kubectl get svc -n argocd | grep redis的输出。我见过最离谱的案例:一个团队的Redis Service名是my-awesome-redis-cache-for-argo,运维为了图省事,在Helm命令里写成了--set harness.configMap.argocd.redisSvc=my-awesome-redis-cache-for-argo,结果因为Service名里有下划线,K8s DNS解析失败,Agent反复重启。

其次是CRD(Custom Resource Definition)的冲突风险。Argo CD的ApplicationAppProject等CRD是集群全局的。当你用BYOA模式时,Harness不会安装自己的CRD,而是复用你已有的。但如果某天你升级了Argo CD到v2.14,而Harness Agent只验证过v2.13,就可能出现CRD字段不兼容,导致Harness UI里Application列表一片空白,错误日志里只有failed to convert CRD。而非BYOA模式下,Harness会安装自己验证过的、版本锁定的CRD,彻底规避此风险。

最后是升级路径的不可控性。BYOA模式下,Argo CD组件的升级由你全权负责,而Harness Agent的升级由Harness控制。两者节奏不同步,极易产生“Agent新版本要求Redis v7.4,但你的旧Argo CD还在用v6.2”的尴尬局面。非BYOA模式则是一体化升级,Harness确保所有组件(Agent、Repo Server、Redis、Controller)的版本组合经过100%兼容性测试。

所以,我的建议很直白:新项目,闭眼选Non-BYOA;老系统迁移,先评估BYOA带来的运维复杂度是否低于重装成本。别被“复用”二字迷惑,GitOps的终极目标是降低复杂度,而不是把旧债打包转移。

2.3 高可用(HA)Agent:不是“越多越好”,而是“恰到好处”

看到“High Availability”这个词,很多人的第一反应是“赶紧上3副本!”。但Harness HA Agent的设计哲学恰恰相反:它不是为了解决单点故障,而是为了解决性能瓶颈。Agent本身没有状态(Stateless),它的Pod挂了,Helm的replicaCount: 2会立刻拉起一个新的,业务几乎无感。真正的瓶颈,在于它所依赖的三个有状态组件:Redis(缓存Git Repo克隆)、Repo Server(解析Helm/Kustomize)、Application Controller(执行K8s API调用)。

我们来算一笔账。一个标准Agent(Non-HA)的Redis是单副本,Repo Server是单副本,Application Controller是单副本。当你的Git仓库是一个包含50个微服务的Monorepo时,Repo Server每次同步都要遍历整个仓库树,生成50份Manifest,这个过程是CPU密集型的。如果只有一个Repo Server,它就成了串行瓶颈,50个App的Sync会排队等待,平均延迟飙升。同理,Application Controller默认只有20个Reconciliation Worker,如果它要管理100个K8s集群(每个集群有几十个App),100*20=2000个Worker远远不够,Controller会因内存溢出而OOM。

HA Agent的解决方案是精准扩容:

  • Redis:从1副本升级为3副本Sentinel + 1个HAProxy负载均衡。Sentinel负责主从切换,HAProxy负责读写分离,让Repo Server的Git克隆请求能并发打到多个Redis节点。
  • Repo Server:从1副本升级为2副本。每个副本独立克隆一份Repo,互不干扰,50个App的Manifest生成可以并行。
  • Application Controller:保持1副本,但将Worker数量从20提升到50。因为Controller本身是无状态的,增加Worker只是多开几个goroutine,不增加Pod数量,却能将集群管理能力从“几十个”提升到“几百个”。

注意,Agent自身的副本数在HA模式下是2,但这2个Agent Pod并不分担上述组件的压力,它们只是“请求分发器”。真正的性能提升来自Redis和Repo Server的横向扩展。所以,判断是否需要HA,不要看Agent Pod数,而要看你的Monorepo规模、Managed Clusters数量、以及每分钟的Sync频率。一个简单的阈值:如果你的Repo Server CPU持续>70%,或者Application Controller的reconcile_queue_length指标长期>100,那就是HA的明确信号。盲目上HA,只会徒增运维负担和资源消耗。

3. 安装前必备准备与环境校验清单

3.1 网络连通性:不止是“能上网”,而是“精准放行”

网络是Agent的生命线,但它的要求远比“集群能访问外网”复杂得多。我见过太多团队在kubectl apply -f agent.yaml后,Agent Pod状态是Running,但Harness UI里始终是Connecting...,最终排查发现是网络策略(NetworkPolicy)或防火墙(Firewall)的“精准拦截”。我们必须把它拆解成三个独立通道来校验。

通道一:Agent → Harness SaaS(出向HTTPS)
这是Agent的心跳通道。它需要稳定连接https://app.harness.io(Harness主服务)和https://git.harness.io(GitOps专用API)。这不是简单的DNS解析,而是要求TLS握手成功。很多企业内网使用自签名CA或私有CA,这会导致Agent的Go HTTP Client证书校验失败。解决方案不是关掉校验(极度危险),而是将你的私有CA证书注入Agent的Trust Store。具体操作:创建一个ConfigMap,内容为你私有CA的PEM文件,然后在Agent的Deployment中挂载到/etc/ssl/certs/ca-certificates.crt(覆盖默认证书包),并设置环境变量SSL_CERT_FILE=/etc/ssl/certs/ca-certificates.crt。你可以用kubectl exec -it <agent-pod> -- curl -v https://app.harness.io来验证。

通道二:Repo Server → Git仓库(出向HTTPS/SSH)
Repo Server需要拉取你的应用代码库(如GitHub、GitLab、Bitbucket)。这里有两个陷阱。第一,如果你用HTTPS方式,Repo Server需要能访问github.comgitlab.com等,且证书有效。第二,如果你用SSH方式(更安全),Repo Server需要能访问git@github.com,这要求你提前将SSH私钥注入Repo Server的~/.ssh/id_rsa,并配置~/.ssh/config指定Host github.comUser gitIdentityFile。更重要的是,SSH连接默认走TCP 22端口,而很多企业防火墙只放行80/443。这时你必须在~/.ssh/config里强制走HTTPS端口:Port 443,并确保GitHub的SSH over HTTPS服务已启用(ssh -T -p 443 git@ssh.github.com)。我建议新项目一律用HTTPS+Personal Access Token,更易审计。

通道三:Agent → 目标K8s集群(入向API Server)
这是最容易被忽略的一环。Agent需要调用目标集群的K8s API Server(通常是https://<api-server-ip>:6443)来创建Pod、Service等资源。但API Server的地址,往往不是集群内部的kubernetes.default.svc,而是外部可访问的LoadBalancer IP或域名。这个地址必须能被Agent Pod的网络空间(Network Namespace)直接访问。常见错误是:Agent装在cluster-A,却要管理cluster-B,而cluster-B的API Server只允许cluster-B的Node IP访问,cluster-A的Pod IP被拒绝。解决方案是:在cluster-B的API Server的--advertise-address参数中,确保包含了cluster-A所在网络段的IP,或在cluster-B的云厂商安全组里,为cluster-A的VPC CIDR开放6443端口。

校验方法:进入Agent Pod,逐个测试。

# 进入Agent容器(通常第一个容器是agent) kubectl exec -it <agent-pod> -c gitops-agent -- sh # 测试Harness连接(应返回HTTP 200) curl -I -k https://app.harness.io # 测试Git连接(HTTPS) curl -I -k https://github.com/your-org/your-repo.git # 测试K8s API(需带上Bearer Token) TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) curl -k -H "Authorization: Bearer $TOKEN" https://<target-api-server>:6443/version

任何一个失败,都意味着Agent无法完成其核心使命。

3.2 RBAC权限:从“最小权限”到“精准授权”的实践

官方文档说需要cluster-adminadmin权限,但这在生产环境是红线。我们必须遵循最小权限原则(Principle of Least Privilege),为Agent创建一个专属的、权限精确到API Group和Resource的ServiceAccount。核心思路是:Agent只管理它被分配的Namespace,绝不越界。

首先,创建专用Namespace和ServiceAccount:

kubectl create namespace harness-gitops kubectl create serviceaccount -n harness-gitops gitops-agent-sa

然后,构建RBAC策略。这不是一个大而全的clusterrolebinding,而是分层的Role/RoleBinding。关键点在于:Agent需要的权限,远不止deploymentsservices,还包括大量Argo CD自身CRD的操作权,以及对secretsconfigmaps的读写权(用于存储Git凭证和Helm Values)

以下是一个生产环境验证过的精简Role(保存为agent-role.yaml):

apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: gitops-agent-role namespace: harness-gitops rules: - apiGroups: [""] resources: ["pods", "services", "configmaps", "secrets", "serviceaccounts"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apps"] resources: ["deployments", "statefulsets", "daemonsets", "replicasets"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["batch"] resources: ["jobs", "cronjobs"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["argoproj.io"] resources: ["applications", "appprojects", "applicationsets"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] verbs: ["get", "list", "watch"] # 注意:Agent需要创建自己的CRD,所以必须有create权限 - apiGroups: [""] resources: ["namespaces"] verbs: ["get", "list", "watch"] # 必须能读取namespace,因为Agent要管理其他ns的资源 - apiGroups: [""] resources: ["events"] verbs: ["create", "patch", "update"] # 用于上报事件到Harness

接着,绑定到ServiceAccount:

kubectl apply -f agent-role.yaml kubectl create rolebinding gitops-agent-rb \ --role=gitops-agent-role \ --serviceaccount=harness-gitops:gitops-agent-sa \ --namespace=harness-gitops

提示:如果你的Agent需要管理其他Namespace(如prodstaging),请为每个目标Namespace单独创建一个RoleBinding,指向同一个Role,但--namespace参数改为目标Namespace。例如:kubectl create rolebinding prod-agent-rb --role=gitops-agent-role --serviceaccount=harness-gitops:gitops-agent-sa --namespace=prod。这比给Agent一个cluster-admin安全一万倍。

3.3 存储与资源:别让“小气”的K8s拖垮Agent

Agent的资源需求看似很低(1vCPU/2GB),但这只是“空载”指标。真实世界里,它要同时处理Git克隆、Helm模板渲染、K8s API调用、日志收集、健康检查,峰值内存很容易突破4GB。更隐蔽的瓶颈是临时存储(Ephemeral Storage)

Repo Server在拉取Git仓库时,会在本地/tmp目录下克隆一个完整的仓库副本。一个大型Monorepo(如包含100个微服务)的.git目录轻松超过2GB。如果K8s Node的/tmp分区(通常是emptyDir挂载点)空间不足,Repo Server会因no space left on device而崩溃。这不是内存或CPU问题,而是磁盘IO问题。

解决方案是:为Repo Server显式声明emptyDir大小,并挂载到一个有足够空间的路径。在Helmvalues.yaml中,找到repoServer部分:

repoServer: # ... 其他配置 extraVolumes: - name: repo-tmp emptyDir: sizeLimit: 4Gi extraVolumeMounts: - name: repo-tmp mountPath: /tmp

同时,为Redis也配置持久化存储(persistence.enabled=true),避免重启后缓存丢失导致Repo Server重新克隆,造成雪崩。对于Redis,4Gi的emptyDir足够,因为它只缓存Manifest的YAML文本,而非整个Git仓库。

最后,检查你的K8s集群是否启用了ResourceQuota。如果harness-gitopsNamespace有memory: 2Gi的限制,那么Agent的resources.limits.memory: 4Gi会直接导致Pod无法调度。务必先kubectl describe ns harness-gitops确认配额,再设置资源请求。

4. 实战安装:Helm与YAML双路径详解与避坑

4.1 Helm安装:从添加Repo到一键部署的全流程

Helm是官方推荐的安装方式,因为它能动态渲染模板、管理依赖、支持版本回滚。但“一键安装”的背后,是无数个需要你亲手填写的values.yaml参数。我将整个流程拆解为五个不可跳过的步骤,并标注每个步骤的“死亡陷阱”。

步骤一:添加Harness Helm Repo并更新

helm repo add harness https://harness.github.io/helm-charts helm repo update harness

注意:官方文档有时会写错Repo URL。务必以https://harness.github.io/helm-charts为准。如果执行helm search repo harness看不到gitops-helm,说明Repo添加失败。常见原因是网络问题,可尝试curl -v https://harness.github.io/helm-charts/index.yaml验证连通性。

步骤二:创建并编辑values.yaml这是最关键的一步。不要直接用helm install--set参数,那会让命令长得无法维护。创建一个harness-agent-values.yaml文件,内容如下(以Non-BYOA、Production环境为例):

# --- Agent Core --- agent: # 必须!Agent的唯一标识,将出现在Harness UI的Agent列表中 name: "prod-gitops-agent" # 必须!Harness Platform生成的永久Token,从UI的GitOps Settings > Agents > New GitOps Agent > Copy Token获取 token: "your-harness-token-here" # --- Target Namespace & RBAC --- # 必须!Agent将被部署到的Namespace,也是它默认管理的Namespace namespace: "harness-gitops" # 必须!指定ServiceAccount,与我们之前创建的sa一致 serviceAccount: create: false name: "gitops-agent-sa" # --- Redis Configuration --- redis: # 必须开启持久化,避免重启丢缓存 persistence: enabled: true # 必须设置资源限制,防止OOM resources: requests: memory: "1Gi" cpu: "200m" limits: memory: "2Gi" cpu: "500m" # --- Repo Server Configuration --- repoServer: # 必须!为大型Repo预留足够空间 extraVolumes: - name: repo-tmp emptyDir: sizeLimit: 4Gi extraVolumeMounts: - name: repo-tmp mountPath: /tmp resources: requests: memory: "2Gi" cpu: "500m" limits: memory: "4Gi" cpu: "1000m" # --- Application Controller Configuration --- applicationController: # 必须!根据你的集群规模调整Worker数 # 默认20,管理100+ App时建议设为50 replicas: 1 # 在args中追加worker参数 extraArgs: - "--application-namespaces=*" # 允许管理所有ns,或指定逗号分隔的ns列表 resources: requests: memory: "2Gi" cpu: "500m" limits: memory: "4Gi" cpu: "1000m" # --- Upgrader (Auto Update) --- upgrader: # 生产环境强烈建议关闭自动升级,改为手动灰度 enabled: false # 如果开启,必须指定私有Registry(见4.2节) # image: "your-private-registry/harness/upgrader:latest" # --- Security & Compliance --- # STIG合规(如需) # securityContext: # runAsNonRoot: true # runAsUser: 1001 # fsGroup: 1001

提示:token字段是Agent的“身份证”,它由Harness平台生成,具有时效性和唯一性。绝对不要硬编码在Git仓库里!正确做法是:在CI/CD流水线中,用kubectl create secret generic harness-token --from-literal=token=xxx -n harness-gitops创建Secret,然后在values.yaml中用agent.token: {{ .Values.secrets.harnessToken }}引用,并通过--set secrets.harnessToken=xxx传入。这样Token就不会泄露。

步骤三:执行Helm Install

# 创建Namespace(如果不存在) kubectl create namespace harness-gitops # 执行安装,指定Release Name(任意,但需唯一) helm install prod-agent harness/gitops-helm \ --values harness-agent-values.yaml \ --namespace harness-gitops \ --version 0.119.0 # 指定精确版本,避免自动升级到不稳定版

步骤四:验证Helm Release状态

# 查看Release详情 helm list -n harness-gitops # 查看所有相关资源是否创建成功 kubectl get all -n harness-gitops # 特别关注Pod状态,应全部为Running/Ready kubectl get pods -n harness-gitops

如果看到gitops-agent-xxxRunning,但argocd-repo-server-xxxCrashLoopBackOff,90%是网络或存储问题(见3.1和3.3节)。

步骤五:在Harness UI中完成注册回到Harness UI,进入GitOps > Settings > GitOps Agents,点击New GitOps Agent。在向导中:

  • Name: 填写与values.yamlagent.name一致的名称(如prod-gitops-agent)。
  • GitOps Operator: 选择Argo
  • Namespace: 填写harness-gitops
  • Agent Installations: 选择No(即Non-BYOA)。
  • Helm Chart: 选择Download Values YAML,下载override.yaml(这个文件与你的values.yaml功能相同,但结构略有不同)。
  • 关键一步:在Advanced Options里,勾选Skip CRDs。因为我们用Helm安装,CRD会自动创建,无需UI再干预。

下载完成后,回到终端,用helm upgrade命令应用这个override.yaml(它会覆盖你之前的values.yaml,确保UI和CLI配置一致):

helm upgrade prod-agent harness/gitops-helm \ --values override.yaml \ --namespace harness-gitops

几分钟后,UI上Agent状态应变为Healthy and Connected

4.2 YAML安装:当Helm不适用时的终极备选方案

Helm虽好,但并非万能。在以下场景,YAML安装是唯一选择:

  • 你的集群禁用了Helm Tiller/Operator(出于安全审计要求)。
  • 你需要对某个特定组件(如Repo Server)进行深度定制(如修改启动脚本)。
  • 你正在调试一个Helm无法解决的底层问题。

YAML安装的本质,是将Helm Chart渲染出的最终Manifest,手动下载、审查、并kubectl apply。官方提供了Download YAML按钮,但那个YAML是“未经加工”的原始产物,直接应用大概率失败。我们必须对其进行三处关键手术。

手术一:注入ServiceAccount原始YAML里,所有Deployment的spec.template.spec.serviceAccountName都是default。我们必须将其全部替换为gitops-agent-sa。用sed命令批量处理:

# 下载原始YAML curl -L "https://raw.githubusercontent.com/harness/helm-charts/main/charts/gitops-helm/templates/all.yaml" > raw-agent.yaml # 替换ServiceAccount sed -i 's/serviceAccountName: default/serviceAccountName: gitops-agent-sa/g' raw-agent.yaml

手术二:修正Image Pull Secret如果你的集群镜像仓库是私有的(如Harbor),原始YAML里的imagePullSecrets是空的。你需要:

  1. 创建一个Secret:kubectl create secret docker-registry harbor-secret --docker-server=harbor.your-company.com --docker-username=admin --docker-password=xxx -n harness-gitops
  2. 在YAML中,为每个Deployment(gitops-agent,argocd-repo-server,argocd-redis等)的spec.template.spec下,添加:
imagePullSecrets: - name: harbor-secret

手术三:修复NetworkPolicy原始YAML的NetworkPolicy默认拒绝所有入站流量。但Agent的argocd-server(UI)和argocd-repo-server(Git)需要被集群内其他组件访问。我们必须添加两条规则:

# 在NetworkPolicy的spec.ingress下,添加: - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: harness-gitops ports: - protocol: TCP port: 8080 # argocd-server - from: - namespaceSelector: matchLabels: kubernetes.io/metadata.name: harness-gitops ports: - protocol: TCP port: 8081 # argocd-repo-server

完成这三处手术后,执行:

kubectl apply -f patched-agent.yaml -n harness-gitops

然后,同样需要回到Harness UI,用New GitOps Agent向导,选择YAML选项,下载gitops-agent.yaml,并用kubectl apply -f gitops-agent.yaml -n harness-gitops应用。UI会自动检测到Agent并完成注册。

5. 部署后深度验证与健康诊断体系

5.1 四层健康检查法:从Pod到业务的全链路透视

Agent的“Healthy”状态在UI上只是一张静态快照。真正的健康,必须通过四层递进式检查来验证。我称之为“四层健康检查法”,每一层都对应一个关键问题。

第一层:K8s基础设施层(Is the Pod alive?)
这是最基础的。执行:

kubectl get pods -n harness-gitops # 输出应类似: # NAME READY STATUS RESTARTS AGE # argocd-application-controller-7c8d9b5c4-2zq9p 1/1 Running 0 5m # argocd-repo-server-6d8f7b4c9-8xw2p 1/1 Running 0 5m # gitops-agent-5b9c7d8e6-4r2t1 1/1 Running 0 5m

READY必须是1/1STATUS必须是RunningRESTARTS必须是0。如果RESTARTS>0,立即kubectl logs -p <pod-name>查看上次崩溃日志。

第二层:组件通信层(Can they talk to each other?)
Agent是一个微服务集群,各组件间必须网络互通。进入gitops-agentPod,测试到其他组件的连通性:

kubectl exec -it <gitops-agent-pod> -- sh # 测试到Redis redis-cli -h argocd-redis ping # 应返回 PONG # 测试到Repo Server curl -I http://argocd-repo-server:8081/version # 应返回 HTTP 200 # 测试到Application Controller curl -I http://argocd-application-controller:8082/version # 应返回 HTTP 200

如果ping不通Redis,检查argocd-redisService是否存在,Endpoints是否为空(kubectl get endpoints argocd-redis -n harness-gitops)。Endpoint为空,说明Redis Pod没起来或Readiness Probe失败。

第三层:Harness平台层(Is it reporting correctly?)
这是最关键的验证。登录Harness UI,进入GitOps > Settings > GitOps Agents,找到你的Agent。点击右侧的... > View Logs。这里显示的是Agent主动上报给Harness的日志流,不是K8s的kubectl logs。你应该能看到类似:

INFO [gitops-agent] Agent connected successfully to Harness platform INFO [gitops-agent] Starting health check for components... INFO [gitops-agent] Redis health check passed INFO [gitops-agent] Repo server health check passed INFO [gitops-agent] Application controller health check passed

如果日志里有ERRORWARN,特别是Failed to connect to RedisFailed to fetch application list,说明Agent与Harness的通信或内部组件通信有问题。

第四层:业务功能层(Can it do real work?)
这是最终极的验证。创建一个最简单的GitOps Application:

  1. 在Harness UI,GitOps > Applications > New Application
  2. Name:test-app
  3. Repository: 选择一个公开的、极简的Helm Chart仓库(如https://charts.bitnami.com/bitnami)。
  4. Chart:nginx
  5. Revision:12.2.10(一个稳定版本)。
  6. Target Namespace:default(或你创建的测试NS)。
  7. Cluster: 选择In-Cluster(即Agent所在的集群)。
  8. Sync Policy:Automatic

点击Save and Run。几秒钟后,回到K8s:

kubectl get pods -n default | grep nginx # 应看到一个Running的nginx Pod kubectl get applications -n harness-gitops # 应看到test-app状态为Synced

如果test-app在Harness UI里状态是UnknownFailed,但K8s里Pod起来了,说明Agent的上报链路断了;如果K8s里Pod根本没创建