Statut et Events
La condition Ready d'une ProxyKubeApi, ses codes de raison, ses Events et ses métriques de reconcile
Le controller publie l'état de chaque ProxyKubeApi sous une forme que les outils
Kubernetes savent lire : une condition Ready, des Events sur la ressource et des
métriques de reconcile (RFC 0011).
$ kubectl get proxykubeapis -n team-a
NAME READY REASON AGE
prod False TargetUnreachable 3d
$ kubectl wait --for=condition=Ready proxykubeapi/prod -n team-akubectl wait, le health check d'Argo CD et celui de Flux lisent status.conditions.
La condition Ready
Trueavec la raisonReconciled: la cible répond, le cluster est servi.Falseavec un code bloquant :status.erroren porte le message.observedGenerationn'avance que sur un succès : une CR en échec garde la génération de son dernier succès, ce qui dit « cette version de la spec n'a jamais été servie ».lastTransitionTimene bouge que quand le statut d'une condition change.
Chaque avis devient une condition True à côté de Ready, de type égal à son code.
Les codes
| Code | Sévérité | Quand |
|---|---|---|
Reconciled | succès | la cible répond, la CR est servie |
InvalidSpec | bloquant | la spec est refusée par la validation du controller |
OidcConfigUnresolved | bloquant | le Secret de oidc_provider.config_from ne se lit pas |
TargetUnreachable | bloquant | la sonde ne joint pas la cible |
ProbeFailed | bloquant | la sonde échoue elle-même |
CacheWriteFailed | bloquant | l'écriture (ou la suppression) dans Redis échoue |
StatusWriteFailed | bloquant | le patch du statut échoue |
FinalizerFailed | bloquant | l'ajout ou le retrait du finalizer échoue |
RulesRestricted | avis | des règles changent de sens sous une restriction de ports, de verbes ou d'exec (status.warnings) |
DeprecatedInsecureCert | avis | cert: Insecure, l'ancien nom de SystemRoots |
Deleted | avis | le finalizer a retiré le cluster de Redis |
AgentNoTunnel | bloquant | un cluster service: Agent dont aucun pod de la passerelle ne tient de tunnel (RFC 0012) ; le détail est dans status.agent |
AgentLimitCapped | avis | limits.streams_per_tunnel dépasse agentGateway.limits.maxStreamsPerTunnel et y est ramené |
AgentBootstrapNeeded | avis | OneShotToken : aucun agent connecté et le jeton est consommé ou expiré (annoter proxyauth.weebo.si.rs/regenerate-bootstrap), ou il n'a pas pu être écrit |
AgentVersionSkew | avis | un agent a plus d'une mineure de retard sur le proxy, est plus récent que lui, ou annonce une version qui n'est pas un SemVer ; ou la passerelle a refusé le protocole d'un agent alors que d'autres tunnels servent (RFC 0013) |
AgentProtocolUnsupported | bloquant | aucun tunnel, et la passerelle a refusé le protocole de l'agent dans les 5 dernières minutes : la cause de AgentNoTunnel ; le détail est dans status.agent.refused |
UpstreamModeNotAllowed | bloquant | upstream_auth.mode hors de upstreamAuth.allowedModes du chart (RFC 0014) ; le proxy répond 503 à ce cluster, jamais en Passthrough |
UpstreamModeUnsupported | bloquant | upstream_auth.mode que cette version ne sert pas encore (RFC 0014, décision 34) ; 503, jamais en Passthrough |
ClientCertMissing | bloquant | FrontProxy : le Secret proxyauth-frontproxy-<ns>.<nom> du namespace du proxy est absent, illisible, sans le label app.kubernetes.io/managed-by=proxyauthk8s, ou son certificat est expiré ou illisible ; status.upstreamAuth.clientCertSecret donne le nom |
ClientCertTargetMismatch | bloquant | FrontProxy : l'annotation proxyauth.weebo.si.rs/front-proxy-target du Secret ne vaut pas status.upstreamAuth.clientCertTarget (certificat posé pour une autre cible) |
ClientCertNameTooLong | bloquant | FrontProxy : proxyauth-frontproxy-<ns>.<nom> dépasse 253 caractères |
ClientCertSubjectReserved | bloquant | FrontProxy : le CN ou l'O du certificat commence par system: ; utiliser un certificat dédié |
AudienceValidationRequired | bloquant | un mode de confiance alors que OIDC_AUDIENCE_VALIDATION n'est pas enforce |
ClientCertExpiring | avis | le certificat FrontProxy expire dans moins de min(30 j, ⅓ de sa durée de vie) |
FrontProxyNotReady | avis | un cluster encore en Passthrough qui prépare FrontProxy (préfixes posés) ne serait pas servi une fois basculé ; le message dit pourquoi |
UpstreamIdentityNotHonoured | bloquant | la sonde de confiance (SelfSubjectReview par le leader, chaque minute) voit une autre identité que celle affirmée : certificat d'une CA --client-ca-file, ou en-tête de groupe ou d'extra non lu ; le message nomme l'identité vue |
FrontProxyNotTrusted | bloquant | la sonde de confiance reçoit 401 : la CA du certificat n'est pas dans --requestheader-client-ca-file, ou son CN pas dans --requestheader-allowed-names |
UpstreamTrustUnknown | avis | la sonde de confiance n'a pas conclu (transport, 5xx, agent absent) ; le cluster reste servi |
IssuerKeyUnavailable | bloquant | Issuer : le Secret proxyauth-issuer-<UID> du namespace du proxy est illisible, ne porte pas les labels du proxy (jamais adopté ni écrasé : le supprimer), ou ne peut pas être écrit ; le message le nomme |
IssuerUrlMismatch | bloquant | Issuer : le chemin de issuer_key.issuer_url n'est pas /issuer/<ns>/<nom>, la route que le proxy sert |
IssuerNotTrusted | bloquant | Issuer : la sonde reçoit 401 (issuer ou audience non déclarés dans l'AuthenticationConfiguration), ou l'apiserver accepte aussi une identité non préfixée (userValidationRules absentes) |
IssuerNotReady | avis | un cluster encore en Passthrough avec issuer_key ne serait pas servi une fois basculé en Issuer ; le message dit pourquoi |
IssuerKeyRotationOverdue | avis | la clé Issuer n'a pas tourné depuis plus de rotation_days + 1 jours |
IssuerBehindAgent | avis | Issuer derrière un agent : l'apiserver doit quand même joindre l'URL publique du proxy pour le JWKS |
TokenExchangeAtRisk | avis | TokenExchange : l'IdP du cluster n'est pas celui du proxy et connector_id est vide, ou oidc_provider n'a pas de secret client (l'échange échouera le plus souvent) ; le message dit lequel, et il est aussi dans status.warnings |
Le verdict de la sonde de confiance se suit aussi hors des conditions, succès compris :
status.upstreamAuth.trust (Trusted, Rejected, NotHonoured, Unknown, Unguarded) et
status.upstreamAuth.trustSince, colonne Trust en -o wide
(Apiserver en front-proxy, Le proxy comme émetteur).
Les Events
- Un
Warningà chaque reconcile qui finit surReady: False, et à chaque erreur avant le statut (CacheWriteFailed,StatusWriteFailed,FinalizerFailed). Kubernetes les agrège en série : un échec répété fait monter un compteur, pas une liste. - Un
NormalquandReadypasse àTrueou change de raison, et pour chaque avis qui apparaît ou disparaît. Kubernetes regroupe les Events de même type et de même raison : la disparition d'un avis fait monter le compteur de l'Event de son apparition, sans en changer le message. La condition, elle, disparaît. - Un
NormalDeletedquand le finalizer a nettoyé Redis.
$ kubectl describe proxykubeapi/prod -n team-a | sed -n '/Events/,$p'
Type Reason From Message
Warning TargetUnreachable proxy-kube-api-controller Target service is not reachableSeul le leader publie ; reportingInstance nomme son pod.
Une suppression attend Redis : si Redis ne répond pas, le finalizer reste et la
ressource reste Terminating, avec un Warning CacheWriteFailed. Sans cela, le
cluster supprimé resterait servi par le proxy, qui route depuis Redis.
Le rythme
| Après | Prochain reconcile |
|---|---|
un succès, ou un InvalidSpec | 5 min (±20 %) |
| un autre échec | 30 s, doublé à chaque nouvel échec, jusqu'à 5 min |
un cluster service: Agent | 1 min au plus, pour que status.agent suive les tunnels |
Une modification de la ressource déclenche un reconcile sans attendre. Le reconcile périodique rattrape ce que le watch ne voit pas : un Redis vidé, un Secret référencé modifié, une cible qui tombe ou revient. Un reconcile sans changement n'écrit rien sur la ressource.
Le watch du controller
Si le controller n'arrive plus à suivre les ProxyKubeApi (apiserver hôte injoignable,
RBAC retiré), chaque erreur est journalisée. Après 5 minutes d'échec continu,
/management/ready affiche "controller": "failing" dans son corps et la jauge
proxyauth_controller_watch_failing passe à 1. Les sondes n'en dépendent pas : le proxy
continue de servir les clusters déjà connus depuis Redis, et un redémarrage de toutes les
réplicas n'y changerait rien.
Les métriques
/management/metrics expose :
proxyauth_reconcile_total{kind, result, reason}:resultvautsuccessouerror,reasonest un code du tableau ;proxyauth_reconcile_duration_seconds{kind}.
Une alerte possible, par raison :
increase(proxyauth_reconcile_total{result="error"}[15m]) > 0