Files
devops-infra-helm-charts-gcp/helm-overrides/gke-toolshed-prd-usc1/harbor/custom-values.yaml
T
Mukul SharmaandClaude Opus 5 61bc4af1a0 Serve every tool on deployshed.com instead of nip.io
Harbor, Gitea, Argo CD, Jenkins, Vault, Grafana and vmui now answer on
their deployshed.com names alone. Each was already serving both while the
move was proved out; this removes the nip.io half.

The dual-hostname workarounds go with it. Jenkins' secondaryingress existed
only because its chart's primary ingress takes one hostName and a
certificate could not span both names — the real domain moves onto the
primary with jenkins-tls, which it already holds. Argo CD gets extraTls
rather than ingress.tls, because the boolean hardcodes secretName
argocd-server-tls and would request a second certificate for a name that
already has a valid one in argocd-deployshed-tls.

Harbor also changes in two ways beyond the hostname:

  - externalURL moves to https://harbor.infra.deployshed.com. Harbor hands
    this to docker clients in its own API responses and builds the push
    commands shown in its UI from it, so a stale value is what makes a
    correctly-configured registry still advertise the old address.

  - updateStrategy is now Recreate. Its jobservice and registry volumes are
    standard-rwo (ReadWriteOnce), and a RollingUpdate starts the new pod
    before the old one releases the disk, so the replacement hangs forever
    on Multi-Attach. The cluster was sitting in exactly that state, old pods
    serving while new ones stayed in ContainerCreating. The chart's own
    comment on this value recommends Recreate when RWM is unavailable. The
    cost is a brief outage during upgrades, which beats a rollout that
    cannot complete.

The private registry CA is not removed yet. Apps deployed before this move
recorded nip.io image references that only change when each is rebuilt, so
the old hostname stays served by a standalone Ingress until then.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
2026-09-17 09:31:26 +05:30

161 lines
5.4 KiB
YAML

harbor:
# GKE counterpart of helm-overrides/k8s-admin-prd-ase1/harbor, same chart
# (1.19.1), with one fundamental difference: this Harbor is served over
# real TLS, and it has to be.
#
# The homelab runs Harbor on plain HTTP and works around containerd's
# refusal to pull from an insecure registry by hand-editing
# /etc/containerd/certs.d/<host>/hosts.toml on the node. GKE nodes are
# managed and replaced, so that edit cannot survive.
#
# That used to mean a private CA: the registry was a nip.io name, Let's
# Encrypt cannot issue for one (not on the public suffix list, and every
# *.nip.io certificate shares a single rate limit), so Terraform generated
# a CA, the node pool was told at creation to trust it for exactly that
# hostname, and cert-manager signed Harbor from it. It worked for pulls,
# which is what mattered, but every browser warned on the Harbor UI and
# every docker client that was not a node needed the CA mounted by hand.
#
# Owning a domain removes all of it. harbor.infra.deployshed.com takes an
# ordinary Let's Encrypt certificate that everything already trusts — the
# nodes, dockerd in a build pod, a laptop, a browser. What retires with it:
# registry-ca-clusterissuer.yaml, registry-ca-configmap.yaml, the CA mount
# in every dind pod, and eventually the node pool's own
# private_registry_access_config block in Terraform.
#
# The nip.io name is still served, by a standalone Ingress alongside this
# one, and still signed by the private CA. It has to be: apps deployed
# before the move recorded their image as harbor.35.238.248.203.nip.io/...
# in toolshed's database, and that reference only changes when each app is
# rebuilt. Retiring the old name before then breaks their next image pull.
expose:
type: ingress
tls:
enabled: true
# secret, not the chart's "auto": auto generates its own self-signed
# certificate, which nothing has any reason to trust.
certSource: secret
secret:
secretName: harbor-deployshed-tls
ingress:
hosts:
core: "harbor.infra.deployshed.com"
className: contour
annotations:
# cert-manager's ingress-shim watches for this and creates the
# Certificate itself, writing the result into the secret named
# above. Nothing here ever touches a Certificate resource directly.
cert-manager.io/cluster-issuer: letsencrypt-prod
# The update strategy for the two deployments with persistent volumes,
# jobservice and registry. Recreate, not the chart's default RollingUpdate,
# because their volumes are standard-rwo — ReadWriteOnce — and a rolling
# update starts the replacement pod before the old one releases the disk.
# The new pod then waits on "Multi-Attach error for volume ... already used
# by pod" forever, and the rollout never converges: this cluster sat in
# exactly that state, old pods serving while new ones hung in
# ContainerCreating. The chart's own comment on this value says to set it
# this way when RWM volumes are unavailable.
#
# The cost is honest: Harbor is briefly down during an upgrade, because the
# old pod must stop before the new one starts. That beats an update that
# cannot complete at all.
updateStrategy:
type: Recreate
# https, matching the ingress above. Harbor hands this URL to docker
# clients in its own API responses, so a mismatch here breaks pushes in
# ways that look like registry errors rather than configuration — and it is
# what the "docker login / docker push" commands shown in Harbor's own UI
# are built from, which is where a stale value is noticed first.
externalURL: "https://harbor.infra.deployshed.com"
# From Vault through External Secrets — see
# secretstores/harbor-admin-credentials.yaml and Vault path
# secret/harbor/admin.
existingSecretAdminPassword: harbor-admin-credentials
existingSecretAdminPasswordKey: HARBOR_ADMIN_PASSWORD
# The one genuinely optional component. Harbor's database and redis are
# its own required internal state, not add-ons.
trivy:
enabled: false
persistence:
enabled: true
# Keeps the PVCs if the release is ever uninstalled: these hold the
# actual images.
resourcePolicy: "keep"
persistentVolumeClaim:
registry:
storageClass: standard-rwo
size: 5Gi
jobservice:
jobLog:
storageClass: standard-rwo
size: 1Gi
database:
storageClass: standard-rwo
size: 1Gi
redis:
storageClass: standard-rwo
size: 1Gi
portal:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
core:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
jobservice:
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
memory: 256Mi
registry:
registry:
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
memory: 256Mi
controller:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi
database:
internal:
resources:
requests:
cpu: 100m
memory: 256Mi
limits:
memory: 512Mi
redis:
internal:
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
memory: 128Mi