Argo CD and Harbor each had a standalone Ingress serving the real domain while their charts still served nip.io. Both charts now own their real hostname directly, so the standalone objects are removed — extra-manifests syncs the directory with prune, so deleting the files deletes the objects. harbor-ingress-legacy-nipio.yaml is the inverse of the file it replaces. Harbor's chart now serves harbor.infra.deployshed.com with a Let's Encrypt certificate, and this object serves the old nip.io name with the private CA the chart used to use. It has to exist: apps deployed before the move recorded harbor.35.238.248.203.nip.io image references in toolshed's database and in already-rendered pod specs, and nothing in git can rewrite those — they change only when each app is rebuilt. Until then a pod that restarts, reschedules or scales up pulls the old reference, and if the name stops resolving that pull fails looking like a broken registry rather than a retired hostname. It retires together with the registry-ca manifests and Terraform's node-pool trust. harbor-robot-dockerconfig lists both hostnames. Docker matches stored credentials by exact host and nothing else, so a single-value swap breaks whichever side lands second: change the credential first and the pipeline pushes unauthenticated, change the pipeline first and the same happens in reverse. Two entries make the order irrelevant — it is one robot account on one Harbor reached by two names. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01LEsTefWWifp4ikvhHF5s6N
61 lines
3.0 KiB
YAML
61 lines
3.0 KiB
YAML
# Docker registry credentials for Jenkins to push to Harbor, as a proper
|
|
# kubernetes.io/dockerconfigjson secret (not a plain Opaque one) so it can
|
|
# be mounted straight at ~/.docker/config.json in the build container —
|
|
# docker push/pull read that format natively, no explicit `docker login`
|
|
# step needed in the pipeline itself.
|
|
#
|
|
# Vault-backed, same pattern as everything else. Put the robot account's
|
|
# credentials in first (create it in the Harbor UI: your CI project ->
|
|
# Robot Accounts -> New Robot Account, scoped to push+pull on that one
|
|
# project — Harbor shows the secret once, copy it immediately):
|
|
# kubectl -n vault exec -i vault-0 -- vault kv put secret/harbor/jenkins-robot \
|
|
# username='robot$<project>+<robot-name>' \
|
|
# password='<the generated secret>'
|
|
apiVersion: external-secrets.io/v1
|
|
kind: ExternalSecret
|
|
metadata:
|
|
name: harbor-robot-dockerconfig
|
|
namespace: jenkins
|
|
spec:
|
|
refreshInterval: 1h
|
|
secretStoreRef:
|
|
name: vault-backend
|
|
kind: ClusterSecretStore
|
|
target:
|
|
name: harbor-robot-dockerconfig
|
|
creationPolicy: Owner
|
|
template:
|
|
type: kubernetes.io/dockerconfigjson
|
|
data:
|
|
# Keyed by exact registry hostname — docker matches credentials
|
|
# against the host portion of the image reference, so this must be
|
|
# the same hostname the pipeline pushes to and Harbor's own
|
|
# externalURL uses. On GKE that is the Contour ingress host, never
|
|
# harbor-core.harbor.svc.cluster.local: cluster DNS resolves from a
|
|
# pod but not from the node's containerd doing the actual image pull.
|
|
#
|
|
# BOTH hostnames are listed, deliberately, while the deployment moves
|
|
# off nip.io. Because the match is by exact host and nothing else, a
|
|
# single-value swap breaks whichever side lands second: change this
|
|
# first and the pipeline (still pushing to nip.io) pushes
|
|
# unauthenticated, which Harbor rejects as "unauthorized"; change the
|
|
# pipeline first and the same happens in reverse. Two entries make
|
|
# the order irrelevant — the credential is identical either way,
|
|
# since it is one robot account on one Harbor reached by two names.
|
|
#
|
|
# The nip.io entry comes out once no image reference anywhere names
|
|
# it: the pipeline's push target, the fallback Dockerfiles, the
|
|
# mirrored base images, and every app already deployed from an image
|
|
# tagged under the old name.
|
|
.dockerconfigjson: |
|
|
{"auths":{"harbor.infra.deployshed.com":{"username":"{{ .username }}","password":"{{ .password }}","auth":"{{ printf "%s:%s" .username .password | b64enc }}"},"harbor.35.238.248.203.nip.io":{"username":"{{ .username }}","password":"{{ .password }}","auth":"{{ printf "%s:%s" .username .password | b64enc }}"}}}
|
|
data:
|
|
- secretKey: username
|
|
remoteRef:
|
|
key: harbor/jenkins-robot
|
|
property: username
|
|
- secretKey: password
|
|
remoteRef:
|
|
key: harbor/jenkins-robot
|
|
property: password
|