Skip to content

EAI-8229 Fix CLUSTER_SIZE small: keep global.domain, hooks, drop gitea - #815

Open
pre wants to merge 3 commits into
mainfrom
cf-small-domain-fix-main
Open

EAI-8229 Fix CLUSTER_SIZE small: keep global.domain, hooks, drop gitea#815
pre wants to merge 3 commits into
mainfrom
cf-small-domain-fix-main

Conversation

@pre

@pre pre commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Fixes EAI-8229.

CLUSTER_SIZE: small does not give a platform that works. Three faults stop
it, one after the other. This pull request corrects all three.

# Fault Correction
1 The root application loses global.domain, and CoreDNS then sends every name to the gateway Keep the value as a parameter
2 envoy-gateway never leaves PreSync, so the Gateway API CRDs are never installed Give the hooks a delete policy
3 gitea waits for a secret that nothing makes on this path Do not enable it on the small path

Only the small path is affected. With externalValues.enabled, the values of
fault 1 come from cluster-values/values.yaml in the in-cluster Gitea.


1. The root application loses global.domain

The root Application is rendered two times. bloom renders it with
helm template ... --set global.domain=... and applies the result. ArgoCD then
renders the same chart again to manage the app-of-apps, and that render reads
only the value files.

root/templates/cluster-forge.yaml copied clusterForge.targetRevision into
spec.source.helm.parameters, but not global.domain and not
global.clusterSize. The second render saw them empty, and the root
application overwrote its own specification without them.

An empty domain made envoy-gateway-config write

rewrite continue name regex .*\. https.envoy-gateway-system.svc.cluster.local answer auto

.*\. matches every name:

argocd-repo-server.argocd.svc.cluster.local   -> 10.243.148.243
argocd-redis.argocd.svc.cluster.local         -> 10.243.148.243
nope-does-not-exist.default.svc.cluster.local -> 10.243.148.243

10.243.148.243 is the envoy-gateway-system/https service. The ArgoCD
controller could not reach its repo-server, and all 39 applications stayed in
ComparisonError.

An empty global.clusterSize also removed values_small.yaml from the value
files, so the cluster got the wrong set of applications. The count decreased
from 39 to 26.

Correction. Copy both values into the parameters, in the same way as
clusterForge.targetRevision. The render now gives the same result each time:

helm template cluster-forge root --show-only templates/cluster-forge.yaml \
  --values root/values.yaml --values root/values_small.yaml \
  --set global.domain=1.2.3.4.nip.io | grep -A1 global.domain

2. envoy-gateway never leaves PreSync

waiting for completion of hook /ServiceAccount/envoy-gateway-gateway-helm-certgen and 5 more hooks

The hooks in sources/envoy-gateway/v1.8.1 carried helm.sh/hook but no
helm.sh/hook-delete-policy. ArgoCD reads a missing policy as
BeforeHookCreation, so it deletes each hook before it makes the hook again,
and it does that each time it resumes the operation. The operation resumes
about every four seconds, and the certgen job needs more time than that, so
the job never started.

Measured: the operation was Running for 30 minutes, and
envoy-gateway-system held no service account, no job and no pod. The Gateway
API CRDs were never installed, so each application that uses a Gateway, an
HTTPRoute or a TLSRoute failed with

failed to discover server resources for group version gateway.networking.k8s.io/v1

Ten applications stayed OutOfSync/Missing, among them envoy-gateway-config,
keycloak, gitea-config, openbao-config and seaweedfs-config.

Correction. hook-delete-policy: hook-succeeded on the seven hooks of that
chart. The hooks now stay until the job completes.

3. gitea cannot start on the small path

bloom does not bootstrap gitea when CLUSTER_SIZE is small.
clusterforge_setup.yaml holds when: (CLUSTER_SIZE | default('medium')) != 'small', and bootstrap_gitea.yaml is the only thing that makes the secret
gitea-admin-credentials. values_small.yaml enabled the gitea and
gitea-config applications all the same.

Measured: secret "gitea-admin-credentials" not found, 255 restarts in 59
minutes, and the application stayed Degraded.

Correction. Do not enable the two applications on the small path. That path
reads the repository from GitHub, because externalValues.enabled is false and
clusterForge.repoUrl names GitHub, so it has no use for the in-cluster Gitea.
Nothing else in values_small.yaml names it.


Test

One Kaytoo VM, Ubuntu 24.04, no GPU, CLUSTER_SIZE: small,
DOMAIN: <ip>.nip.io, CERT_OPTION: generate. Installed with bloom, then
cluster-forge from this branch.

Before After
root app parameters clusterForge.targetRevision only + global.domain, global.clusterSize
root app valueFiles values.yaml values.yaml, values_small.yaml
applications 26 53
ComparisonError 39 of 39 0
not Synced+Healthy 39 1

Name resolution now goes both ways, as intended:

regex .*\.129.213.21.55.nip.io

argocd-repo-server.argocd.svc.cluster.local  -> 10.243.9.71      (the service)
kc.129.213.21.55.nip.io                      -> 10.243.209.223   (the gateway)

envoy-gateway installs and both gateways are programmed:

phase: Succeeded, message: successfully synced (all tasks run)
pod/envoy-gateway-5f775fc774-tl7bs   1/1   Running

ai-gateway   envoy-gateway   10.243.109.13   True
https        envoy-gateway   10.0.255.153    True

What stays open

One application, envoy-gateway-config, is still OutOfSync, and it is not
corrected here. security-policy-ai-gateway-default-deny.yaml asks for port
8083 on ai-gateway-system/ai-gateway-discovery, and envoy-gateway refuses the
policy:

ExtAuth: TCP Port 8083 not found on service ai-gateway-system/ai-gateway-discovery

ai-gateway-discovery-chart:2.0.0 gives one port, health:8081, and the
container gives only health:8081, so there is no ext-auth port. This is a
mismatch of versions and not a wrong number, and port 8081 is the health probe,
so no correction is guessed here.
EAI-8231 records it.

The root Application is rendered two times. bloom renders it one time
with helm --set, and ArgoCD then renders the same chart again to manage
the app-of-apps. The second render reads only the value files, so each
value that was given with --set and is not repeated as a parameter is
lost, and the root app overwrites its own spec without it.

global.domain and global.clusterSize were lost this way. An empty
domain made envoy-gateway-config write the CoreDNS rewrite
`regex .*\.`, which matches every name, so each name in the cluster
resolved to the gateway service. The ArgoCD controller could not reach
its repo-server, all 39 applications stayed in ComparisonError, and no
secret was made. An empty clusterSize dropped values_<size>.yaml from
the value files, so the cluster got the wrong set of applications.

Only the small path is affected. With externalValues.enabled the two
values come from cluster-values/values.yaml in the in-cluster Gitea.

To see the difference:

  helm template cluster-forge root --show-only templates/cluster-forge.yaml \
    --values root/values.yaml --values root/values_small.yaml \
    --set global.domain=1.2.3.4.nip.io | grep -A1 global.domain
@pre
pre requested a review from a team as a code owner August 21, 2026 17:17
The certgen hooks carry "helm.sh/hook" but no delete policy. ArgoCD reads
a missing policy as BeforeHookCreation, so it deletes each hook before it
makes the hook again, and it does that each time it resumes the operation.

The operation resumes about every four seconds, and the certgen job needs
more time than that, so the job never started. envoy-gateway stayed at
PreSync with "waiting for completion of hook", the Gateway API CRDs were
never installed, and each application that uses a Gateway, an HTTPRoute or
a TLSRoute could not sync. Measured on a one-node cluster: the operation
was Running for 30 minutes and the namespace held no service account, no
job and no pod.

hook-succeeded keeps the hooks until the job completes, and removes them
after it.
@pre

pre commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

Test on a clean one-node cluster

Kaytoo VM, Ubuntu 24.04, no GPU, CLUSTER_SIZE: small,
DOMAIN: 129.213.21.55.nip.io, CERT_OPTION: generate. Installed with bloom
and then cluster-forge from this branch.

Correction 1, global.domain: confirmed

Before After
root app parameters clusterForge.targetRevision only + global.domain, global.clusterSize
root app valueFiles values.yaml values.yaml, values_small.yaml
envoy-gateway-config domain no values at all 129.213.21.55.nip.io
applications 26 53
ComparisonError 39 of 39 0

The CoreDNS rewrite is correct, and name resolution now goes both ways as
intended:

regex .*\.129.213.21.55.nip.io

argocd-repo-server.argocd.svc.cluster.local  -> 10.243.9.71      (the service)
kc.129.213.21.55.nip.io                      -> 10.243.209.223   (the gateway)

Before the correction both names gave the gateway address.

Correction 2, the PreSync hooks: confirmed

Before, envoy-gateway was Running for 30 minutes at
waiting for completion of hook, and envoy-gateway-system held no service
account, no job and no pod. After:

phase: Succeeded, message: successfully synced (all tasks run)
pod/envoy-gateway-5f775fc774-tl7bs   1/1   Running

The Gateway API CRDs are installed, and both gateways are programmed:

ai-gateway   envoy-gateway   10.243.109.13   True
https        envoy-gateway   10.0.255.153    True

Applications not Synced+Healthy went from 39 to 2.

This branch alone does not give a cluster that fully settles

The run still failed, and the two remaining faults are NOT corrected here.
They are recorded so that nobody reads this pull request as more than it is.

a. gitea cannot start on the small path. bloom skips bootstrap_gitea.yaml
when CLUSTER_SIZE is small (clusterforge_setup.yaml:81), and only that task
makes gitea-admin-credentials. values_small.yaml still enables gitea and
gitea-config, so the pod stays at
secret "gitea-admin-credentials" not found. Measured: 255 restarts in 59
minutes. A test that removed the two applications from values_small.yaml left
one application not settled, so this is the larger of the two. That change is
not in this pull request, because it decides what a small cluster contains.

b. the AI gateway ext-auth port does not exist.
security-policy-ai-gateway-default-deny.yaml:51 asks for port 8083 on
ai-gateway-system/ai-gateway-discovery, and envoy-gateway rejects the policy:

ExtAuth: TCP Port 8083 not found on service ai-gateway-system/ai-gateway-discovery

ai-gateway-discovery-chart:2.0.0 exposes one port, health:8081, and the
container exposes only health:8081. There is no ext-auth port at all, so
this is a version mismatch and not a wrong number. Changing 8083 to 8081 would
point ext-auth at the health probe, and failOpen: false would then refuse
traffic, so no correction is guessed here.

bloom does not bootstrap gitea when CLUSTER_SIZE is small. The task
clusterforge_setup.yaml holds `when: (CLUSTER_SIZE | default('medium'))
!= 'small'`, and bootstrap_gitea.yaml is the only thing that makes the
secret gitea-admin-credentials.

values_small.yaml enabled the gitea and gitea-config applications all the
same, so the pod waited for a secret that nothing makes. Measured on a
one-node cluster: `secret "gitea-admin-credentials" not found`, 255
restarts in 59 minutes, and the application stayed Degraded.

The small path reads the repository from GitHub, because
externalValues.enabled is false and clusterForge.repoUrl names GitHub.
It therefore has no use for the in-cluster Gitea, and nothing else in
values_small.yaml names it.
@pre pre changed the title EAI-8229 Keep global.domain when the root app renders itself EAI-8229 Fix CLUSTER_SIZE small: keep global.domain, hooks, drop gitea Aug 21, 2026
@pre

pre commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

Clean-room test of this branch

One more test, on a machine that never had bloom on it, against the branch as it now stands (a9615a47, all three commits).

Item Value
Machine fresh Kaytoo VM, Ubuntu 24.04.3, one node, no GPU
Start state no bloom binary, no rke2, no /etc/bloom
CLUSTER_SIZE small
Domain 150.136.144.151.nip.io
bloom EAI-8203-ubuntu-2604
cluster-forge cf-small-domain-fix-main

The three faults this PR corrects

1. The root application keeps global.domain. After ArgoCD rendered the chart again to manage the app-of-apps, the live application still holds both value files and all three parameters:

valueFiles: ["values.yaml","values_small.yaml"]
parameters: [clusterForge.targetRevision, global.domain, global.clusterSize]

CoreDNS got the name it must rewrite, not a wildcard:

rewrite continue name regex .*\.150.136.144.151.nip.io https.envoy-gateway-system.svc.cluster.local answer auto

Applications in ComparisonError: 0. Before the correction every application was in that state, because the empty domain made CoreDNS rewrite .*\. and each name in the cluster went to the gateway.

2. The envoy-gateway PreSync hooks complete. The certgen job ran and left its output:

envoy-gateway    kubernetes.io/tls   3
envoy            kubernetes.io/tls   3
envoy-rate-limit kubernetes.io/tls   3

The application is Synced and Healthy, and the 10 Gateway API CRDs are installed. Before the correction the job was never created at all: no service account, no job, no pod, for 30 minutes.

3. gitea is not enabled. 0 gitea applications and 0 gitea pods. Before, the pod asked for gitea-admin-credentials and restarted 255 times in 59 minutes, because bloom skips the task that makes that secret when the size is small.

Applications

49 of 51 are Synced and Healthy. The two others are named below and neither belongs to this PR.

What this test does NOT show

The cluster does not serve traffic yet. Two faults hold it, and this PR does not claim to correct either one.

  • EAI-8231. envoy-gateway-config stays OutOfSync. Its one differing resource is SecurityPolicy/ai-gateway-default-deny, which asks for port 8083 while the chart gives only health:8081.

  • A webhook certificate that does not match its own CA. Both Gateways stay Programmed=False with NoResources: Envoy replicas unavailable, because every Envoy proxy pod is refused:

    failed calling webhook "ai-gateway-controller.envoy-ai-gateway-system.svc.cluster.local":
    x509: certificate signed by unknown authority ... "ai-gateway-controller-ca"
    

    The caBundle in envoy-ai-gateway-gateway-pod-mutator and the ca.crt in self-signed-cert-for-mutating-webhook are different certificates. The webhook selects app.kubernetes.io/managed-by=envoy-gateway on pod CREATE and its failurePolicy is Fail, so the two proxy Deployments stay at 0/1. The controller restarted 3 times, which points to a race in how it makes its own certificate.

    This comes from sources/envoy-ai-gateway/v0.6.0/, which this PR does not change. The hook commit here touches only sources/envoy-gateway/v1.8.1/, and that chart has no Helm hooks at all in the ai-gateway source, so it is not the same fault as number 2 above. It needs its own ticket.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant