From 720181c90041230dc2ca47a12feeafb22130b688 Mon Sep 17 00:00:00 2001 From: Story Crater Bot <19826264+Riotpiaole@users.noreply.github.com> Date: Wed, 19 Aug 2026 21:48:01 -0700 Subject: [PATCH] feat: let the runner build and the cluster pull from the Forgejo registry - Runner egress: allow 192.168.1.160/32:443. forgejo.riotpiao.com resolves to the ingress LB, inside the 192.168.1.0/24 block the NetworkPolicy denies, so docker push hung until timeout. - dind CA: also mount homelab-ca at /etc/docker/certs.d/forgejo.riotpiao.com/, the path dockerd actually reads for per-registry trust. - Pull secret: dockerconfigjson for the api namespace; /v2/ answers 401. - AppProject: allow the Forgejo repo as a source for api-gw. --- k8s/argocd/projects/homelab-project.yaml | 3 +++ .../secrets/forgejo-registry-pull.enc.yaml | 24 +++++++++++++++++++ k8s/argocd/secrets/secret-generator.yaml | 1 + .../forgejo-runner/templates/deployment.yaml | 7 ++++++ .../templates/networkpolicy.yaml | 10 ++++++++ k8s/infra/forgejo-runner/values.yaml | 7 ++++++ 6 files changed, 52 insertions(+) create mode 100644 k8s/argocd/secrets/forgejo-registry-pull.enc.yaml diff --git a/k8s/argocd/projects/homelab-project.yaml b/k8s/argocd/projects/homelab-project.yaml index bcee254..70d19b2 100644 --- a/k8s/argocd/projects/homelab-project.yaml +++ b/k8s/argocd/projects/homelab-project.yaml @@ -12,6 +12,9 @@ spec: description: Homelab GitOps — single-repo, in-cluster destinations only sourceRepos: - https://github.com/Riotpiaole/riotpiao.homelab.com.git + # In-cluster Forgejo — api-gw (k8s/argocd/apps/55-api-gateway.yaml) sources + # rock/homelab-frontend from here. + - https://forgejo.riotpiao.com/rock/homelab-frontend.git # Public Helm chart repos referenced by k8s/argocd/apps/* and bootstrap/* - https://cloudnative-pg.github.io/charts - https://dl.gitea.com/charts/ diff --git a/k8s/argocd/secrets/forgejo-registry-pull.enc.yaml b/k8s/argocd/secrets/forgejo-registry-pull.enc.yaml new file mode 100644 index 0000000..f625acb --- /dev/null +++ b/k8s/argocd/secrets/forgejo-registry-pull.enc.yaml @@ -0,0 +1,24 @@ +apiVersion: ENC[AES256_GCM,data:D9Y=,iv:EH+zD6bogxh/h/Oe+RxDCtfO96tkc56ou14V+68nK7k=,tag:xTeuhSzqZyrS/ltqvtHcgw==,type:str] +data: + .dockerconfigjson: ENC[AES256_GCM,data:P8x3bhPbJTFvFIKE8WQY1P7KqPwrxNTYTNR+4/Z7nZSr2YQab/Db0SRcvFO9lr4ImdO6waZ8EZ6CI1RzIYx1WcjGXs8FzX1jpBXSw9EG69vRTZCqRRJR8c2yg7qmNFfSvcPAUhK9tciYCzzFWRHZEDAmQ52cox/sMdxE/YR61dhYCy1E9kPwTnaDmDj5Hu72mbLJDxIYpN3T2hVWlw02lHYHgFnuKsPb0Tf1lxn174j/gMMxUT6ynVhWSEExzHvTqQ0RZzuP+VXAh3N9HasbtfcAabt3FtEjYNZqYJ+OE8oiX/A6YjgPDqUOR3AJFZE3,iv:6YsyIHQc8xp8T8XUWhN/pBeaYVI/VdIHOe/w/hb5e6U=,tag:nmGFdkv2hLgj8Dp8/0MOkw==,type:str] +kind: ENC[AES256_GCM,data:hOA36Sjr,iv:y0XHfUOUnut8z0yM2g7Beo3qiqxJhLLhffPpNlUhaec=,tag:45s3FjYCr83vYCSXDXu2/g==,type:str] +metadata: + creationTimestamp: null + name: ENC[AES256_GCM,data:yD8Fo/fncAA4qkaY7RjhRg==,iv:qwc4WId/kGwradgxFUwG5B5XIVYRlMY2HxsaGJAzrjw=,tag:O8GwNdDHMJreL609G/gykA==,type:str] + namespace: ENC[AES256_GCM,data:zg2o,iv:KDpM2L71/LDI4JLTQUtbcv5SV0IraAbKpNEBzSFn/rE=,tag:uFm+3EkgZN3NC2hUPXo9Pg==,type:str] +type: ENC[AES256_GCM,data:5/a+6lRp9Ea5rU/+gEMIgoDYs72xRWkfwefMcy+h,iv:jYirTXlb4rFwvb+nLcgB5X4x1Q/S+3LsVL+7ypS7mkQ=,tag:5Wc0DrMZxIpC0e39MzlAlw==,type:str] +sops: + age: + - enc: | + -----BEGIN AGE ENCRYPTED FILE----- + YWdlLWVuY3J5cHRpb24ub3JnL3YxCi0+IFgyNTUxOSB2ekxNWW9VQ09RTUlMUzVy + QlVrRm12Smt2akRaYmkvMHRPRmJvOTdBTzE0CmdhVFNyWDJnWDV3eTFFUm1majk0 + L01ZWTNZdmcwc1MwMHgzQmdVZy9KcjgKLS0tIHZLVGg5VmNRQ2ZNY1lIRHlzaUlo + TWVNelZRcHFveGRiNTVvNzJCNWtDSGMKyV3Puscgx3RqK65KSL6SYaTauxsBY3qd + CeFU928hcB86DwAG/Atq2Qtd7S9pzuzOVQmXRZxwpCDTTyRVhU7eVA== + -----END AGE ENCRYPTED FILE----- + recipient: age1e5fq3hwxy78psus2nfvmtmua36g0u3suk78ephw6246l974d2utsvn0hla + lastmodified: "2026-08-20T04:43:53Z" + mac: ENC[AES256_GCM,data:Leus5j38xJwJz3Ge9WggBjQSAh2ESlIMUnX9SylE4oIcAt71f8WadtSCOmnqT3ZK+uN8f+Huq6WetGHWUdLfZjZUngHQHWLoRP1xpTVvB5HwJK4F1ASvmL+u1rC88AG3JsZc3Kc2N1G+m6QruQK/9HSmkMi/HGXy658ijzErEzk=,iv:1ga2dKDqTalj9WnjVT6AubXsL7130CuJp3SbBkTb/64=,tag:YsD9metJdYiJmdVXpPuIsQ==,type:str] + unencrypted_suffix: _unencrypted + version: 3.13.2 diff --git a/k8s/argocd/secrets/secret-generator.yaml b/k8s/argocd/secrets/secret-generator.yaml index 96c131a..4cf19b6 100644 --- a/k8s/argocd/secrets/secret-generator.yaml +++ b/k8s/argocd/secrets/secret-generator.yaml @@ -11,6 +11,7 @@ files: - agent-pod-ssh-key.enc.yaml - authentik-secrets.enc.yaml - cloudflare-secrets.enc.yaml + - forgejo-registry-pull.enc.yaml - forgejo-runner-token.enc.yaml - forgejo-secrets.enc.yaml - grafana-oidc-secrets.enc.yaml diff --git a/k8s/infra/forgejo-runner/templates/deployment.yaml b/k8s/infra/forgejo-runner/templates/deployment.yaml index bd5ff27..67d88b4 100644 --- a/k8s/infra/forgejo-runner/templates/deployment.yaml +++ b/k8s/infra/forgejo-runner/templates/deployment.yaml @@ -91,6 +91,13 @@ spec: - name: homelab-ca mountPath: /etc/ssl/certs/homelab-ca.pem subPath: ca.crt + # dockerd resolves per-registry CAs from /etc/docker/certs.d// + # before falling back to the system pool. Mounting it here is what + # makes `docker push forgejo.riotpiao.com/...` trust the homelab CA + # rather than failing x509: signed by unknown authority. + - name: homelab-ca + mountPath: /etc/docker/certs.d/forgejo.riotpiao.com/ca.crt + subPath: ca.crt resources: {{- toYaml .Values.dind.resources | nindent 12 }} diff --git a/k8s/infra/forgejo-runner/templates/networkpolicy.yaml b/k8s/infra/forgejo-runner/templates/networkpolicy.yaml index 96a0414..baccba8 100644 --- a/k8s/infra/forgejo-runner/templates/networkpolicy.yaml +++ b/k8s/infra/forgejo-runner/templates/networkpolicy.yaml @@ -29,3 +29,13 @@ spec: except: - 192.168.1.0/24 - 10.244.0.0/16 + # Single LAN exception: the ingress-nginx LoadBalancer, which is how + # forgejo.riotpiao.com resolves. Image pushes go to that name so the tag + # matches what containerd pulls on the nodes; without this the whole /24 is + # denied above and `docker push` hangs until it times out. + - to: + - ipBlock: + cidr: {{ .Values.egress.ingressLoadBalancerIP }}/32 + ports: + - protocol: TCP + port: 443 diff --git a/k8s/infra/forgejo-runner/values.yaml b/k8s/infra/forgejo-runner/values.yaml index 4e4df63..3b6f9b1 100644 --- a/k8s/infra/forgejo-runner/values.yaml +++ b/k8s/infra/forgejo-runner/values.yaml @@ -47,3 +47,10 @@ tolerations: # attach there. nodeSelector: topology.kubernetes.io/zone: az-a + +# Egress exceptions. The NetworkPolicy denies the whole LAN /24 by default; +# this is the one address punched back through, because forgejo.riotpiao.com +# (the image registry) resolves to the ingress-nginx LoadBalancer. +# Must match the Cilium LB pool allocation — pool is 192.168.1.160/28. +egress: + ingressLoadBalancerIP: 192.168.1.160