From fec9ec386f7028a17e72b54ebe41ae57375918f4 Mon Sep 17 00:00:00 2001 From: keyhan Date: Sat, 11 Jul 2026 11:43:05 +0330 Subject: [PATCH] Push Kaniko artifacts via harbor-core for Harbor UI visibility. Add REGISTRY_PUSH_URL config, route CI Kaniko to harbor-core, and document dual-host kaniko auth for core push plus registry base-image pull. Co-authored-by: Cursor --- .gitea/workflows/build-deploy.yaml | 4 +-- backend/src/config/configuration.ts | 8 +++++- backend/src/kubernetes/registry.service.ts | 9 +++++- gitops/jobs/kaniko-harbor-auth.example.yaml | 32 ++++++++++++--------- gitops/platform/values-abrban.example.yaml | 2 ++ 5 files changed, 37 insertions(+), 18 deletions(-) diff --git a/.gitea/workflows/build-deploy.yaml b/.gitea/workflows/build-deploy.yaml index 088efdc..42b4138 100644 --- a/.gitea/workflows/build-deploy.yaml +++ b/.gitea/workflows/build-deploy.yaml @@ -14,8 +14,8 @@ concurrency: env: # PULL_REGISTRY: kubelet pulls via k3s mirror → harbor-core (matches registry-pull-secret) PULL_REGISTRY: registry.abrban.com - # PUSH_REGISTRY: kaniko pushes directly to harbor-registry (internal, no TLS) - PUSH_REGISTRY: harbor-registry.cloudhost.svc.cluster.local:5000 + # PUSH_REGISTRY: kaniko pushes via harbor-core (Harbor UI metadata + blob storage) + PUSH_REGISTRY: harbor-core.cloudhost.svc.cluster.local PROJECT: abrban BUILD_NS: cloudhost-builds GITEA_HOST: gitea-http.gitea.svc.cluster.local:3000 diff --git a/backend/src/config/configuration.ts b/backend/src/config/configuration.ts index 18e3f67..1da46d9 100644 --- a/backend/src/config/configuration.ts +++ b/backend/src/config/configuration.ts @@ -124,11 +124,17 @@ export default () => ({ }, registry: { - /** In-cluster registry — Kaniko push and app image pull (same host). */ + /** Kaniko push target — harbor-core when set (Harbor UI metadata); else in-cluster registry. */ url: process.env.REGISTRY_URL || 'registry.cloudhost-builds.svc.cluster.local:5000', + pushUrl: + process.env.REGISTRY_PUSH_URL || + process.env.REGISTRY_URL || + 'registry.cloudhost-builds.svc.cluster.local:5000', + /** Kubelet / workload pull (external hostname on Harbor setups). */ pullUrl: process.env.REGISTRY_PULL_URL || process.env.REGISTRY_URL || 'registry.cloudhost-builds.svc.cluster.local:5000', username: process.env.REGISTRY_USERNAME || 'admin', password: process.env.REGISTRY_PASSWORD || '', + harborCoreService: process.env.HARBOR_CORE_SERVICE || 'harbor-core', }, build: { diff --git a/backend/src/kubernetes/registry.service.ts b/backend/src/kubernetes/registry.service.ts index cdc9cc9..2fa87a4 100644 --- a/backend/src/kubernetes/registry.service.ts +++ b/backend/src/kubernetes/registry.service.ts @@ -35,10 +35,11 @@ export class RegistryService { return slash === -1 ? url : url.slice(0, slash); } - /** Push target host[:port][/project] — Kaniko destination (may differ from pull URL on Harbor). */ + /** Push target host[:port][/project] — Kaniko via harbor-core when configured (Harbor UI metadata). */ getRegistryPushUrl(): string { const buildNs = this.getBuildNamespace(); const url = + this.configService.get('registry.pushUrl') || this.configService.get('registry.url') || `registry.${buildNs}.svc.cluster.local:5000`; return url.replace(/^https?:\/\//, ''); @@ -112,6 +113,12 @@ export class RegistryService { if (pushHost !== pullHost) { auths[pushHost] = { auth }; } + // Legacy direct-registry push host (base image pulls during Kaniko build). + const directPushHost = this.configService.get('registry.url')?.replace(/^https?:\/\//, ''); + const directHostOnly = directPushHost?.includes('/') ? directPushHost.slice(0, directPushHost.indexOf('/')) : directPushHost; + if (directHostOnly && directHostOnly !== pushHost && directHostOnly !== pullHost) { + auths[directHostOnly] = { auth }; + } return JSON.stringify({ auths }); } diff --git a/gitops/jobs/kaniko-harbor-auth.example.yaml b/gitops/jobs/kaniko-harbor-auth.example.yaml index 3c5cfac..0b8b4bd 100644 --- a/gitops/jobs/kaniko-harbor-auth.example.yaml +++ b/gitops/jobs/kaniko-harbor-auth.example.yaml @@ -2,21 +2,15 @@ # The real secret is managed as a SealedSecret in the cloud-host-gitops repo # (sealed-secrets/kaniko-harbor-auth.yaml). # -# Kaniko pushes directly to the internal registry endpoint -# (harbor-registry.cloudhost.svc.cluster.local:5000), which bypasses harbor-core. -# That endpoint only accepts the internal registry credential — Harbor robot -# accounts do NOT work there (their tokens are issued by harbor-core's token -# service). Use the harbor_registry_user credential from the harbor-core secret: +# Kaniko pushes via harbor-core (Harbor UI metadata). Pull base images may still +# use harbor-registry:5000 — include auth for both hosts in one dockerconfigjson. # -# REG_PASS="$(kubectl -n cloudhost get secret harbor-core \ -# -o jsonpath='{.data.REGISTRY_CREDENTIAL_PASSWORD}' | base64 -d)" -# kubectl -n cloudhost-builds create secret docker-registry kaniko-harbor-auth \ -# --docker-server=harbor-registry.cloudhost.svc.cluster.local:5000 \ -# --docker-username=harbor_registry_user \ -# --docker-password="${REG_PASS}" +# ADMIN="$(kubectl -n cloudhost get secret harbor-core -o jsonpath='{.data.HARBOR_ADMIN_PASSWORD}' | base64 -d)" +# REG_PASS="$(kubectl -n cloudhost get secret harbor-core -o jsonpath='{.data.REGISTRY_CREDENTIAL_PASSWORD}' | base64 -d)" +# kubectl -n cloudhost-builds create secret generic kaniko-harbor-auth \ +# --from-literal=admin="${ADMIN}" --from-literal=reg_pass="${REG_PASS}" --dry-run=client -o yaml | ... # -# The build-deploy workflow mounts this secret at /kaniko/.docker/config.json -# inside every Kaniko Job. See RUNBOOK-CICD.fa.md for the full procedure. +# See RUNBOOK-CICD.fa.md for the full procedure. apiVersion: v1 kind: Secret metadata: @@ -27,10 +21,20 @@ stringData: .dockerconfigjson: | { "auths": { + "harbor-core.cloudhost.svc.cluster.local": { + "username": "admin", + "password": "", + "auth": "" + }, "harbor-registry.cloudhost.svc.cluster.local:5000": { "username": "harbor_registry_user", "password": "", - "auth": "" + "auth": "" + }, + "registry.abrban.com": { + "username": "harbor_registry_user", + "password": "", + "auth": "" } } } diff --git a/gitops/platform/values-abrban.example.yaml b/gitops/platform/values-abrban.example.yaml index 39a4868..d6ffd10 100644 --- a/gitops/platform/values-abrban.example.yaml +++ b/gitops/platform/values-abrban.example.yaml @@ -103,6 +103,8 @@ backend: PLATFORM_DOMAIN: apps.abrban.com PREVIEW_BASE_DOMAIN: apps.abrban.com FRONTEND_URL: https://panel.abrban.com,https://abrban.com + # Push via harbor-core so artifacts appear in Harbor UI; pull stays on registry.abrban.com. + REGISTRY_PUSH_URL: harbor-core.cloudhost.svc.cluster.local/abrban REGISTRY_URL: harbor-registry.cloudhost.svc.cluster.local:5000/abrban REGISTRY_PULL_URL: registry.abrban.com/abrban BUILD_NAMESPACE: cloudhost-builds