Maillage de services
Tous les autres écrans d'Avuru Obs masquent délibérément votre maillage. Un sidecar, un waypoint ou une passerelle transporte le trafic des autres : le dessiner sur un graphe de dépendances affirme donc des relations qui n'existent pas — d'où le classement de ces charges de travail comme « transport » par la carte des services, derrière une bascule.
C'est le bon choix pour un graphe de dépendances, et un mauvais dernier mot. Sur un cluster où le maillage est le réseau, un proxy qui a cessé de relayer, ou un plan de contrôle qui a cessé de pousser la configuration, constitue la panne. Cet écran est l'endroit où le tissu lui-même devient le sujet.
:::info Désactivé par défaut
Le module maillage naît désactivé (modules.mesh.enabled). La plupart des
installations n'ont pas de maillage, et un écran pour une infrastructure que vous
n'avez pas n'est que du bruit. Activez-le et la moitié « proxys » fonctionne
immédiatement — elle lit une télémétrie que vous envoyez déjà — et, avec le
module infra-metrics, la sonde se met aussi à lire
les proxys eux-mêmes.
:::
Les proxys
Chaque charge de travail que le hub classe comme transport, avec son propre débit, son taux de succès et sa latence — et, séparément, les appels qu'elle a transportés en entrée et ceux qu'elle a transportés en sortie.
Ces deux nombres ne sont volontairement pas additionnés en un « débit ». Un proxy dont le trafic arrive sans rien repartir a cessé de faire la seule chose pour laquelle il existe, et son propre taux d'erreur peut paraître parfaitement sain pendant ce temps : il répond aux requêtes, il ne les relaie simplement plus. Les voir côte à côte est ce qui rend cela visible.
Il n'y a aucune collecte supplémentaire derrière ce tableau. Les proxys
émettent des spans exactement comme les applications ; la seule raison de leur
absence ailleurs dans le produit est une décision d'affichage. Si une charge de
travail semble mal classée ici — une vraie application prise pour un proxy, ou un
proxy que les motifs intégrés manquent — la classification se corrige par
installation via la configuration topology du hub, sans attendre une version.
Voir
les sauts de maillage sur la carte.
Chaque proxy a un rôle
Un maillage n'est pas une flotte indifférenciée, et une liste qui le traite comme telle devient illisible dès qu'elle dépasse quelques lignes. Chaque proxy est classé selon ce qu'il est réellement :
| Rôle | De quoi il s'agit |
|---|---|
| Plan de contrôle | Le composant qui programme tout le reste |
| Passerelle d'entrée / de sortie | Le trafic qui entre dans le maillage ou en sort |
| Passerelle | Une passerelle dont le cluster n'indique pas le sens |
| Waypoint | Le proxy L7 qui sert un espace de noms ou une charge, dans un maillage sans sidecars |
| Ztunnel | Le proxy L4 présent sur chaque nœud |
| Sidecar | Un proxy à l'intérieur du pod de l'application |
Le rôle et l'espace de noms sont tous deux des facettes : « montre-moi tous les waypoints » ou « montre-moi les proxys de cet espace de noms » tient en un clic. Ni l'un ni l'autre n'est deviné : un proxy dont ni les labels ni le nom ne tranchent affiche un blanc plutôt qu'une valeur plausible par défaut.
Le rôle Passerelle existe pour une raison qui mérite d'être dite. Le label Gateway API établit qu'une charge est une passerelle, pas le sens dans lequel elle regarde — et dans un maillage sans sidecars, un waypoint est lui-même une ressource Gateway portant ce label. Les classer tous comme passerelles d'entrée serait une erreur pleine d'assurance : le nom décide donc du rôle, et les labels l'affinent.
Sur l'onglet Graphe, chaque rôle a aussi sa propre forme — une étoile pour le plan de contrôle, une étiquette pour une passerelle tournée vers l'intérieur et son miroir pour une tournée vers l'extérieur, un chevron pour ztunnel, un double anneau pour un waypoint — et une légende sous le graphe ne nomme que les formes réellement présentes. Un waypoint, un ztunnel et la passerelle d'entrée à côté sont trois métiers différents, et ils ne ressemblent plus à trois copies d'une même chose.
Ce qu'il a déplacé, et sur quoi
Les appels entrants et sortants sont des comptes. Avec le module infra-metrics actif, chaque proxy indique aussi les octets qu'il a réellement déplacés — mesurés sur les flux noyau, non déduits des spans — et la santé des liens empruntés : le temps d'aller-retour de son pire lien, ses connexions échouées et ses retransmissions.
Une installation qui ne mesure rien de tout cela n'obtient aucune colonne, et non une colonne de zéros. Un proxy annoncé comme ayant déplacé 0 octet et subi 0 connexion échouée, alors que personne ne regardait le fil, est exactement la fausse assurance que le reste de cet écran s'emploie à éviter.
Ouvrir un proxy
Un proxy s'ouvre sur son propre débit, ses erreurs et sa latence dans le temps — et sur ce que rien d'autre ici ne sait dire : ce qu'il transporte.
Non pas les appels qu'il a traités, qui sont un compte. Les vraies dépendances
app → app reconstituées à travers lui, chacune avec le nombre de proxys
traversés par la requête. C'est la
reconstitution de saut
que fait la carte, lue par l'autre bout : la carte demande qui dépend de qui, en
ignorant le maillage, et ceci demande de quoi ce proxy est responsable. Mêmes
arêtes, question inverse, aucune requête supplémentaire.
L'onglet Graphe dessine le maillage en conservant ces sauts — ztunnel vers waypoint vers ztunnel, tel que le trafic circule vraiment. C'est exactement ce que la carte des services existe pour retirer, d'où une vue distincte plutôt qu'une bascule sur la carte.
Ce que son proxy a compté
Un span enregistre un code de statut. Le proxy qui a produit le 503 sait pourquoi : un disjoncteur ouvert, un budget de relances épuisé, une route vers nulle part et une expiration côté amont sont quatre pannes différentes avec quatre correctifs différents. Avec la collecte du plan de données active, la page d'un proxy montre ses requêtes telles que son proxy les a comptées :
- Par indicateur de réponse, avec la raison du proxy en toutes lettres — un disjoncteur ouvert est dessiné en ambre. Un indicateur que ce produit ne connaît pas est transmis tel quel plutôt qu'écarté : le proxy l'a dit, et vous pouvez le chercher.
| Indicateur | Ce que dit le proxy |
|---|---|
UO | Débordement en amont — un disjoncteur est ouvert |
URX | Relances épuisées |
UF | L'amont n'a pas accepté la connexion |
UT | La requête vers l'amont a expiré |
NR | Aucune route configurée |
DC | La connexion en aval a été interrompue |
RL | Limité en débit |
- Par version de destination, pour qu'un canari en échec soit visiblement le canari.
- Par appelant, avec son nombre de 5xx, pour qu'une charge en échec le soit pour tout le monde ou pour un seul client.
Ses chiffres gagnent la part de TLS mutuel de la charge. Ceux d'un ztunnel gagnent ce que le proxy de nœud compte lui-même : les charges qu'il transporte, celles encore en attente de câblage, et le nombre de fois où son flux vers le plan de contrôle a été coupé. Le tableau des proxys n'obtient une colonne mTLS que là où la collecte en a rapporté une.
Les compteurs par amont qu'un lecteur cherche ensuite — débordement en attente,
éjections d'instances — sont annoncés comme non collectés. Un maillage par
défaut ne les expose pas, et la page nomme le réglage du proxy qui le fait
(meshConfig.defaultConfig.proxyStatsMatcher.inclusionPrefixes) plutôt que
d'afficher un zéro signifiant « on ne regarde pas ». Une charge qu'aucun proxy
n'a rapportée dans la fenêtre se lit non mesurée — autre chose que « le plan
de données n'est pas lu », ce que seul l'onglet Sécurité a
qualité pour dire.
Le plan de données, lu depuis les proxys eux-mêmes
Tout ce qui précède vient des spans et des flux noyau, qui répondent à « à quelle vitesse » et « combien de fois » — et ne savent pas répondre à ce que chaque proxy sait de lui-même : si une requête a circulé en TLS mutuel ou en clair, si un indicateur de réponse nomme un disjoncteur ou un budget de relances épuisé, si ztunnel transporte les charges qu'on lui a demandé de transporter. Rien de cela n'est dans un span.
La sonde collecte donc les proxys de son propre nœud — sidecars, waypoints,
passerelles et ztunnel — découverts grâce aux annotations prometheus.io/* que
le maillage écrit déjà sur eux. Il n'y a aucun point d'entrée à saisir. Chaque
nœud ne collecte que ses propres proxys, si bien qu'un cluster de n'importe
quelle taille atteint chaque proxy exactement une fois. C'est l'inverse de la
raison pour laquelle le plan de contrôle est collecté depuis la passerelle :
istiod est un seul Deployment, et les proxys sont un par pod.
Ce qu'elle conserve tient en huit séries : le compteur de requêtes — qui porte la politique de sécurité, l'indicateur de réponse, la version de destination et l'appelant — les quatre compteurs de connexions et d'octets TCP, qui portent aussi la politique de sécurité, et trois relevés de ztunnel : les charges transportées, les charges en attente, les flux vers le plan de contrôle coupés. Les séries de requêtes émises côté appelant dupliquent celles que rapporte le côté appelé : elles ne sont conservées que depuis les passerelles, qui n'ont pas de côté appelé pour les rapporter ; quand les deux bouts ont rapporté une arête, le compte de la destination l'emporte. Les espaces de noms exclus de la collecte le sont aux deux bouts d'une série, et pas seulement là où vit le proxy qui rapporte.
Le up de la collecte est conservé par proxy, pour que l'écran distingue
« personne ne collecte » de « les proxys ne répondent pas » — et nomme les pods
qui ne répondent pas.
Les compteurs sont lus en deltas par série, jamais re-sommés : une part calculée à partir de compteurs cumulatifs re-sommés est fausse d'une façon qui paraît plausible.
:::caution Activé par défaut sous le module de maillage Contrairement à la collecte du plan de contrôle, celle-ci n'a besoin d'aucune valeur : elle est donc active partout où le module de maillage, le module infra-metrics et l'agent de la sonde le sont — et elle démarre à la mise à jour. Le module est le consentement, et c'est à cela que le module sert.
Comptez environ 20 à 100 séries par proxy et par collecte de 30 secondes, stockées dans les tables d'infra-metrics sous votre rétention habituelle. Pour conserver l'écran Maillage sans elle :
mesh:
dataPlane:
enabled: false
Les installations sans module de maillage ne sont pas touchées. Le module de maillage actif avec infra-metrics désactivé se rend toujours, sans le récepteur, et le hub le dit. :::
Le plan de contrôle
Un maillage continue de servir sa dernière configuration acceptée longtemps après que le plan de contrôle a cessé de pousser. Tous les proxys restent debout, toutes les requêtes passent encore, et le déploiement suivant ne prend simplement jamais effet. Vu du seul plan de données, c'est indiscernable de la santé.
La carte du plan de contrôle y répond directement :
| Indicateur | Ce qu'il vous dit |
|---|---|
| Proxys connectés | La part de la flotte à laquelle le plan de contrôle parle réellement |
| Poussées | La distribution de configuration a-t-elle seulement lieu |
| Convergence p95 | Le temps qu'un changement met à atteindre les proxys |
| Configurations refusées | La configuration que vos proxys ont refusée |
| p95 de poussée | Le temps que prend la poussée elle-même, que la convergence seule confond avec le temps que les proxys mettent à l'appliquer |
| Expirations d'écriture | Les poussées qui ne sont jamais arrivées, parce qu'un proxy était trop lent pour les recevoir |
| Événements de configuration | La quantité de changements de configuration que le plan de contrôle absorbe |
| Conflits d'écouteurs | La configuration que le plan de contrôle n'a pas pu programmer parce que deux éléments revendiquent un même écouteur — résolue en en abandonnant un, et dite seulement ici |
| p95 de file d'attente | Le temps qu'une poussée a attendu dans la file du plan de contrôle avant même d'être envoyée — une contre-pression qui apparaît avant la convergence, pas dedans |
Les cinq derniers sont omis, et non mis à zéro, lorsque leurs séries ne sont pas dans la liste de conservation de votre collecte ou pas dans la fenêtre : une configuration de collecte plus ancienne rapporte moins d'indicateurs plutôt que des indicateurs rassurants.
Configurations refusées est l'indicateur que rien d'autre ne peut produire. Une poussée refusée signifie que le plan de contrôle et le plan de données divergent sur ce que le maillage devrait faire — pendant que la flotte continue de servir sa dernière configuration acceptée, en paraissant saine partout ailleurs.
Quand il se tait, la carte dit pourquoi
La carte n'affiche jamais zéro configuration refusée pour un plan de contrôle qu'elle ne lit pas. « 0 refusée » venant d'un plan de contrôle que personne ne surveille se lit comme une santé parfaite, et c'est la chose la plus dangereuse que cet écran pourrait afficher — la même discipline que le module énergie applique en rapportant « pas de RAPL » plutôt que 0 W.
Ce silence a trois causes, qui appellent trois corrections différentes : la carte dit donc de laquelle il s'agit.
| Carte | Ce qui s'est passé | Que faire |
|---|---|---|
| Plan de contrôle non observé | Rien ne le collecte | activez mesh.controlPlane.enabled=true |
| Plan de contrôle sans réponse | La collecte tourne et la cible ne répond pas | vérifiez mesh.controlPlane.endpoint — ou le plan de contrôle lui-même est tombé |
| Plan de contrôle non reconnu | La cible a répondu, et aucune des métriques que lit avuru obs n'est revenue | voir ci-dessous |
La vue du plan de contrôle a la forme d'Istio
Les quatre indicateurs ci-dessus sont ceux d'istiod — pilot_xds,
pilot_xds_pushes, pilot_total_xds_rejects, pilot_proxy_convergence_time.
Les autres plans de contrôle ne publient pas les mêmes quatre faits : le
contrôleur de destination de Linkerd, par exemple, n'a aucun équivalent de la
configuration que les proxys ont refusée, qui est l'indicateur le plus précieux
de la carte.
Plutôt que de plaquer d'autres chiffres sur les mêmes quatre libellés — ce qui laisserait les libellés justes et les réponses fausses — avuru obs dit franchement qu'il a atteint un plan de contrôle qu'il ne sait pas lire.
La moitié « proxys » de cet écran n'est pas affectée. La charge, la latence et le taux de succès des proxys viennent de vos propres traces et fonctionnent avec n'importe quel maillage dont les proxys sont classés comme transport. Seule la carte du plan de contrôle est spécifique à Istio, et elle vous le dit désormais.
Activer la santé du plan de contrôle
modules:
mesh:
enabled: true
mesh:
controlPlane:
enabled: true
# Le port Prometheus d'istiod sur le Service istiod. Changez l'hôte pour un
# plan de contrôle révisionné ou renommé.
endpoint: istiod.istio-system.svc.cluster.local:15014
Cela requiert aussi le module infra-metrics, puisque les séries collectées sont stockées dans ses tables — un garde-fou du chart refuse l'installation plutôt que de collecter dans le vide.
La collecte s'exécute dans la passerelle, pas dans la sonde. istiod est un unique Deployment et la sonde est un DaemonSet : collecter depuis celle-ci produirait une copie de chaque série du plan de contrôle par nœud, et tout total sur ces séries serait faux d'un facteur égal à la taille de votre cluster.
Sécurité, le déclaré et l'observé
La liste des espaces de noms dit STRICT. Un mode est une affirmation : une
politique STRICT qui ne s'applique pas à une charge — le pod jamais inscrit,
le sélecteur qui le manque, une DestinationRule qui désactive TLS pour son hôte
— ressemble, vue de la seule configuration comme des seules traces, exactement à
une politique appliquée. Seul le proxy qui a terminé la connexion le sait.
L'onglet Sécurité met les deux côte à côte, une ligne par charge de travail : le mode PeerAuthentication en vigueur avec la portée qui l'a décidé, la part du trafic accepté arrivée en TLS mutuel sous forme de barre et de nombre, et un verdict en badge. La jointure est une seule opération, exécutée une fois, et chaque écran la lit — l'onglet Charges de travail, les compteurs d'espace de noms — pour que deux écrans ne puissent pas se contredire sur une charge.
Le vocabulaire des postures
| Posture | Quand | Constat |
|---|---|---|
| Strict et tout en mTLS | Déclaré STRICT, aucun clair observé | — |
| Non appliqué | Déclaré STRICT, du clair observé | MESH_MTLS_NOT_ENFORCED — la politique ne s'applique pas à cette charge ; l'indice dit laquelle des trois causes vérifier d'abord |
| Peut être resserré | Aucune politique stricte, aucun clair observé | MESH_MTLS_READY_TO_TIGHTEN — STRICT ne refuserait rien de ce qui parle aujourd'hui |
| Appelants en clair | Aucune politique stricte, du clair observé | MESH_PLAINTEXT_CALLERS — les appelants à migrer avant de resserrer, nommés quand la ligne est ouverte |
| Non transportée | Un espace de noms ambiant, du trafic dans les traces, et aucun proxy n'a déclaré en transporter | MESH_TRAFFIC_UNCARRIED — le trafic traverse le cluster hors maillage pendant que l'espace de noms se lit comme couvert |
| Observé seulement / inactive / inconnue | Configuration non lue ; rien dans la fenêtre ; un proxy qui a refusé de classer | — |
Les deux absences gardent leur sens. Une configuration sans observation se lit rien observé dans cette fenêtre ; une observation sans configuration se lit introuvable dans ce cluster. Aucune n'est écartée, et un proxy qui a refusé de classer son trafic est compté comme inconnu, pas d'un côté ni de l'autre. Non transportée n'est dessiné que lorsque le plan de données a réellement été lu : personne qui regarde n'est pas la même chose que rien à voir.
Les constats derrière les verdicts se trouvent sous le tableau avec leur correctif, filtrables par espace de noms et par posture depuis l'URL.
Il commence par dire si quelque chose a été lu
Un plan de données que personne ne collecte ne rapporte aucun clair — ce qui se lirait comme un maillage entièrement chiffré, exactement le mensonge que cet onglet existe pour empêcher. L'onglet commence donc par dire si le plan de données a seulement été lu, avec les mots de la carte du plan de contrôle, et n'affiche aucun pourcentage tant qu'il ne l'a pas été :
| Onglet | Ce qui s'est passé | Que faire |
|---|---|---|
| Plan de données non observé | Rien ne le collecte | mesh.dataPlane.enabled=true, avec le module infra-metrics actif |
| Plan de données sans réponse | La collecte tourne et certains proxys ne répondent pas — les pods sont nommés | vérifiez les pods qu'il nomme |
| Plan de données non reconnu | Les proxys ont répondu, et aucune des séries que lit ce produit n'est revenue | voir Limites |
Quand le module mesh-config est désactivé, la colonne Déclaré est absente
plutôt que remplie de « default », et une légende le dit. Une part que personne
n'a mesurée est un tiret, jamais 0 %.
La carte marque chaque arête mesurée
Sur la carte des services et sur le graphe du maillage, chaque arête rapportée par le proxy de destination porte un marqueur côté appelant : un té quand tout a traversé en TLS mutuel, un cercle creux quand c'est mixte, un cercle plein quand rien ne l'a été — avec la part et le nombre d'appels en clair au survol. Le bout cible reste la flèche de direction, une arête en erreur reste rouge, et une arête que personne n'a mesurée ne porte aucun marqueur. La légende n'explique le marqueur que lorsqu'il y en a un sur la carte.
Vos espaces de noms, et ce que la configuration a de faux
Tout ce qui précède est dérivé du trafic et de ce que les proxys ont compté. C'est sa force et son plafond : une erreur de configuration du maillage qui arrête le trafic ne produit aucun trafic à observer. Un espace de noms inscrit au maillage sans rien derrière, une route pointant vers un service inexistant, une passerelle à laquelle rien ne se rattache — chacun est silencieux, et le silence est ce que tout écran dérivé de la télémétrie affiche comme une absence plutôt que comme un problème.
Un second module, mesh-config, lit les objets Istio et Gateway API de votre
cluster — et ses pods — et les juge.
:::caution Un module distinct, et une permission distincte
mesh-config est désactivé par défaut et séparé du module de maillage, ce
qui relève de la décision de conception et non du hasard d'empaquetage. Tout ce
qui précède ne demande aucune permission sur le cluster. Intégrer un
ClusterRole au même interrupteur aurait accordé une lecture à l'échelle du
cluster à toute installation utilisant déjà ces écrans, dès sa prochaine mise à
jour — l'autorisation est donc un choix explicite à part entière.
La permission se limite à get, list et watch, sur son propre compte de
service, sur les espaces de noms, les charges de travail, les pods et les
ressources de maillage. Il n'y a aucun verbe d'écriture, et le chart refuse de
se rendre si l'on en ajoute un.
:::
Les pods sont l'objet le plus gros et le plus nombreux d'un cluster : le hub n'en conserve donc qu'une douzaine de champs — nom, labels, les quatre annotations que le maillage écrit, propriétaire, compte de service, nœud, noms des conteneurs, phase — et écarte le reste avant stockage. Ils sont plafonnés à part, indépendamment de la configuration, pour qu'un grand cluster reste borné et que l'instantané dise quelle liste il a coupée. Chaque type rapporte aussi la date de son dernier réchauffement de cache et de son dernier changement, et un cache qui ne se réchauffe jamais est nommé comme manquant plutôt que servi à moitié.
Les espaces de noms que le trafic ne peut pas montrer
La liste des espaces de noms provient des labels du cluster, pas de la télémétrie : un espace de noms inscrit et totalement silencieux a donc enfin une ligne — et dans un maillage sans sidecars, « inscrit et silencieux » est la façon la plus courante de mal le configurer. Chaque ligne porte son mode de plan de données, le waypoint qui le sert, son mode mTLS dessiné comme un cadenas — marqué hérité quand une politique à l'échelle du maillage l'a décidé plutôt que la sienne — le nombre de ses charges que le maillage a réellement, les services et charges qui ont bel et bien émis de la télémétrie dans la fenêtre, et ses nombres de constats.
La télémétrie est jointe à cette liste par espace de noms, avec la même résolution que celle qu'emploie la carte des services : les deux écrans ne peuvent donc jamais se contredire sur l'endroit où vit une charge de travail.
Chaque charge de travail que le cluster exécute, dans le maillage ou non
L'inscription est un fait qui concerne un pod : le sidecar est un conteneur dedans, et la capture ambiante est une annotation que l'agent de nœud y écrit. Un label d'espace de noms dit ce qui a été demandé ; seul le pod dit ce qui s'est passé. L'onglet Charges de travail liste ce que le cluster exécute, qu'il ait ou non jamais émis un span — la ligne qui manquait à tout écran dérivé du trafic, parce qu'une charge invitée dans le maillage et jamais inscrite ne produit aucun trafic à elle.
| Colonne | Ce qu'elle dit |
|---|---|
| Inscription | Capturée par l'agent de nœud, sidecar injecté, déclarée, non inscrite — demandée par ses labels, en cours d'exécution, et ni l'un ni l'autre — ou hors maillage. Lu dans les pods, jamais dans les modèles : un modèle dit qu'un sidecar devrait être injecté ; seul le pod dit qu'il l'a été |
| Waypoint | Le waypoint qui la lie, et l'origine du lien — le label de la charge elle-même, son Service, ou son espace de noms |
| mTLS déclaré | Le mode qui s'applique, dessiné comme un cadenas, avec la PeerAuthentication qui l'a décidé et sa portée — sélecteur d'abord, puis espace de noms, puis maillage entier. Une ligne PERMISSIVE dans un espace de noms STRICT se lit comme une politique à sélecteur, pas comme un bug |
| mTLS observé | La part que le plan de données a mesurée pour son propre trafic — un tiret là où rien ne l'a fait |
| Posture | Le même verdict, issu de la même jointure, que l'onglet Sécurité |
| Trafic | Son débit et son taux d'erreur quand la télémétrie l'a vue dans la fenêtre ; aucun nombre sinon |
| Politiques | Les objets PeerAuthentication, AuthorizationPolicy et RequestAuthentication qui la couvrent, et à quelle portée chacun l'a atteinte |
| Problèmes | Ses nombres d'erreurs et d'avertissements |
Déclarée, non inscrite est un filtre à part entière — l'écart d'inscription à lui seul — et il voyage dans l'URL, comme l'espace de noms et le mode.
Une charge s'ouvre sur sa propre page : identité et lien, le déclaré à côté de l'observé, les politiques qui la couvrent avec leurs propres constats et un lien vers chacune, ses constats avec le correctif à côté du défaut, et ses pods — bornés à cinquante avec le total annoncé, pour qu'un DaemonSet sur mille nœuds soit une ligne et un nombre.
Les Deployments sont confirmés à partir du hash de modèle de pod sans surveiller les ReplicaSets — un fait que le hash encode déjà, sans autorisation supplémentaire. Un Deployment qui ne peut pas être confirmé est rapporté comme son ReplicaSet, ce qui est honnête.
La page d'une charge de travail
Une charge de travail s'ouvre sur la fiche que le cluster en tient lui-même. L'en-tête porte un verdict de santé dans le vocabulaire du tableau de santé — saine, dégradée, en panne, inactive — avec la raison qui l'a décidé au survol : aucun pod en marche, un pod manquant, une requête sur dix en échec, ou simplement rien qui appelle. En dessous :
- Aperçu — créée quand, et d'après quoi : la date du contrôleur lui-même,
ou celle du pod le plus ancien quand le contrôleur n'a pas été lu, et la page
précise lequel. Type,
version,app, mode. - Liés — chaque Service dont le sélecteur retient la charge, avec un lien vers son propre écran, et le waypoint L7 auquel elle est liée, avec un lien vers la page du proxy.
- Les étiquettes en puces, sans le hachage de modèle du ReplicaSet ; les annotations du contrôleur derrière un repli, dans des bornes explicites (64 clés, 2 Ko par valeur, et la page le dit quand le hub a coupé la liste).
- Pods — nom, révision (le déploiement auquel il appartient), phase, inscription, nœud, âge. Deux pods sur deux révisions pendant un mauvais déploiement, c'est la forme de la plupart des incidents, et « 2 sur 2 en marche » la cache.
- Configuration Istio — une section, deux listes : les politiques qui sélectionnent la charge par étiquette, avec la portée à laquelle elles l'atteignent, et les routes et règles qui l'atteignent par ses Services — HTTPRoute, GRPCRoute, VirtualService, DestinationRule — avec le Service et l'hôte par lesquels elles passent. Chaque référence renvoie au navigateur de configuration et porte ses propres constats, si bien que « cette route est cassée » se dit à côté de la route. Une page qui ne listait que les politiques disait qu'une charge routée était sans configuration.
Ses journaux, depuis trois sources
L'application journalise un côté de chaque requête. Le proxy de nœud journalise la connexion — source, destination, octets, durée, identité — et le waypoint l'échange HTTP, chacun sous son propre nom de service, si bien qu'aucun autre écran ne les rattache à la charge qu'ils concernent. L'onglet Journaux le fait : les lignes de la charge elle-même, les lignes de ztunnel nommant l'un de ses pods, et les lignes du waypoint nommant son Service, en un seul flux sous un seul curseur.
La composition est celle du hub — lui seul connaît les pods derrière une charge et le waypoint auquel elle est liée — et c'est une seule requête avec une branche par source, de sorte que la pagination ne répète ni ne saute aucune ligne. La barre d'outils appartient à l'onglet : une recherche, une sévérité minimale et une case à cocher par source, toutes conservées dans l'URL. La première case porte le nom de la charge et est la seule cochée par défaut — les lignes des proxys parlent de la charge sans être les siennes, celles de ztunnel et du waypoint sont donc à un clic, et une source reste toujours active. Une ligne sous la barre d'outils dit ce qui a réellement été demandé : quels noms de service, combien de pods ont été reconnus, quel waypoint.
| La ligne dit | Ce qui s'est passé | Que faire |
|---|---|---|
| N pods reconnus | Les pods viennent de l'instantané mesh-config ; les lignes des proxys sont reconnues par nom de pod et par nom.espace.svc | — |
| reconnus par nom, avec une raison | Les pods n'ont pas pu être connus — mesh-config éteint, cluster non lu, pods illisibles, liste de pods tronquée, ou charge absente de l'instantané — les lignes des proxys sont donc reconnues par nom et espace de noms ensemble, ce qui garde une charge distincte de son homonyme dans un autre espace | la raison nomme le remède ; la colonne n'est jamais vide en silence |
| waypoint : aucun lié | Aucun waypoint ne lie cette charge, il n'y a donc pas de lignes L7 à lire | — |
L'onglet n'existe que là où le module de journaux est actif. Il lit les tables que le module de journaux remplit déjà : aucune collecte nouvelle, aucune permission nouvelle.
Les trois mêmes sources figurent sur la page d'un service. Son onglet Journaux demande au hub de rattacher le service à une charge de travail, d'après les propres spans du service ou d'après le Service Kubernetes placé devant lui, puis lit ce que lit cet onglet-ci, en ajoutant le nom du service à celui de la charge : les lignes d'une application peuvent être rangées sous l'un ou l'autre. Quand aucune charge ne peut lui être rattachée, cet onglet affiche les propres lignes du service et dit pourquoi celles des proxys ne sont pas proposées.
Ce qu'un waypoint sert
Le trafic d'un waypoint ne sait pas dire à quoi il sert : un waypoint auquel rien n'est lié et un waypoint dont les clients sont inactifs se ressemblent sur le fil. La page d'un waypoint liste ce qu'il sert — les espaces de noms, les Services et les charges qui lui sont liés — et si un pod en cours d'exécution le sert, en disant clairement quand rien ne l'exécute, ou quand rien ne lui est lié.
Dix-sept contrôles, visant ce qui n'émet rien ou a l'air sûr
Les six contrôles de la v0.14 visaient les pannes qui n'émettent rien. Onze de plus couvrent désormais la configuration qui a l'air finie et ne l'est pas. Quinze codes, dont certains couvrent plus d'un contrôle :
Routes et hôtes
| Constat | Se déclenche quand |
|---|---|
MESH_ROUTE_BACKEND_MISSING | Une route envoie le trafic vers un Service, ou un port, qui n'existe pas — elle se rattache, correspond, et perd chaque requête |
MESH_ROUTE_PARENT_MISSING | Une route nomme une passerelle absente ; rien ne la sert |
MESH_HOST_UNRESOLVED | L'hôte d'une règle ne correspond à aucun service du cluster — le plus souvent une faute de frappe ou un service supprimé |
MESH_SUBSET_MISSING | Une route envoie le trafic vers un sous-ensemble qu'aucune DestinationRule de cet hôte ne définit — elle correspond et n'a pas d'amont |
MESH_HOST_CONFLICT | Deux VirtualServices liés au maillage pour un même hôte, ou deux DestinationRules revendiquant un même hôte — une seule est appliquée ; l'autre a l'air configurée et ne fait rien |
Passerelles et waypoints
| Constat | Se déclenche quand |
|---|---|
MESH_GATEWAY_NO_ROUTES | Un écouteur de passerelle auquel rien ne se rattache |
MESH_GATEWAY_NO_WORKLOAD | Une Gateway, waypoints compris, qu'aucun pod en cours d'exécution ne sert — ses écouteurs existent et rien n'y répond |
MESH_LISTENER_CONFLICT | Des écouteurs d'une même passerelle qui partagent un port et un nom d'hôte avec des protocoles différents, ou partagent un nom — la passerelle n'est pas programmée tant qu'ils sont en conflit |
MESH_WAYPOINT_MISSING | Un espace de noms, un Service ou une charge lié à un waypoint qui n'est pas déployé — chaque politique et chaque route qui lui étaient destinées sont ignorées en silence |
MESH_L7_WITHOUT_WAYPOINT | Une règle d'autorisation ou de routage de niveau HTTP, une authentification de requête, ou un pool de connexions HTTP dans un espace de noms ambiant sans waypoint pour l'évaluer — les règles d'autorisation échouent en fermant, les routes ne sont simplement pas appliquées |
Charges de travail et politiques
| Constat | Se déclenche quand |
|---|---|
MESH_AMBIENT_NOT_ENROLLED | Une charge étiquetée ambiante, en cours d'exécution, et ni capturée par l'agent de nœud ni injectée — l'erreur de configuration ambiante la plus courante, invisible au trafic seul |
MESH_DATAPLANE_CONFLICT | Une charge à qui l'on demande d'être deux choses à la fois : un sidecar dans un espace de noms ambiant, un pod étiqueté pour les deux modes, ou un lien de waypoint sur une charge qui n'est pas ambiante |
MESH_POLICY_NO_MATCH | Une politique dont le sélecteur ne correspond à aucun pod, ou dont le targetRef nomme un objet inexistant — une protection qui ne protège rien |
MESH_PRINCIPAL_UNKNOWN | Une règle d'autorisation nommant un compte de service qu'aucune charge en cours d'exécution n'utilise — un ALLOW pour lui n'autorise personne, un DENY ne refuse personne |
MESH_MTLS_CONFLICT | Une DestinationRule qui désactive TLS vers une charge dont la politique effective est STRICT, ou qui exige le TLS mutuel d'une charge qui le désactive — jugé par charge, politiques à sélecteur comprises, dans les deux sens |
Chaque constat dit ce qui casse en silence et quoi changer, et nomme l'objet concerné — avec son type, pour qu'un Service et une charge de travail au même nom s'ouvrent sur le bon onglet. Ils sont agrégés par espace de noms pour que la liste reste lisible d'un coup d'œil au lieu de devenir un mur de problèmes individuels.
Cinq d'entre eux ont besoin des pods — MESH_POLICY_NO_MATCH,
MESH_AMBIENT_NOT_ENROLLED, MESH_DATAPLANE_CONFLICT,
MESH_GATEWAY_NO_WORKLOAD et MESH_PRINCIPAL_UNKNOWN — et ne s'exécutent que
lorsque chaque pod a été lu. Quand les pods ont été refusés ou que la liste a été
coupée, ils deviennent silencieux plutôt que faux, et l'instantané le dit en
une phrase qui les nomme et dit pourquoi, sur chaque onglet qui affiche des
constats. Un contrôle qui ne voit pas tous les pods dirait qu'une politique ne
correspond à rien alors que ses pods sont simplement au-delà du plafond ; une
colonne de problèmes vide ne doit jamais se lire comme un quitus.
Volontairement pas un constat : « aucune politique ne couvre cette charge ». C'est la liste de politiques de la charge qui est vide — un fait sur la ligne — parce que sur la plupart des clusters, c'est l'état de la plupart des charges. Les contrôles restent prudents ailleurs aussi : un hôte qui est un joker, ou un domaine externe que le cluster ne saurait définir, est ignoré plutôt que signalé. Un écran qui crie au loup à propos d'une configuration qui marche finit ignoré, et ne vaut alors plus rien le jour où il a raison.
Quand il ne peut pas lire le cluster
Comme partout ailleurs ici, chaque échec se lit différemment et nomme son propre correctif :
| État | Ce qui s'est passé | Que faire |
|---|---|---|
| Non configuré | Le module est actif et le hub ne tourne pas dans un cluster | attendu hors de Kubernetes ; rien à corriger |
| Interdit | Le ClusterRole n'a pas été accordé | le motif nomme le rôle et la valeur du chart |
| Pas de CRD | Les ressources personnalisées de votre maillage ne sont pas installées | installez-les, ou désactivez le module |
| Tronqué | Le cluster dépasse le plafond de l'instantané | annoncé explicitement — jamais une liste discrètement tronquée |
| Pods illisibles, ou coupés | Le ClusterRole date d'avant la v0.15, ou le cluster a plus de pods que le plafond des pods | les cinq contrôles dépendant des pods sont ignorés et la réponse les nomme ; accordez get/list/watch sur pods en appliquant le chart mis à jour |
La configuration vit en mémoire, reconstruite depuis le cluster au démarrage. Il n'y a ni table, ni migration, ni interaction avec la rétention : elle est petite, elle change rarement, et la copie la plus fraîche est celle que détient le cluster lui-même.
L'activer
modules:
mesh:
enabled: true
meshConfig:
enabled: true
Il requiert le module maillage — le déploiement échoue bruyamment plutôt que de
rendre discrètement un écran sans rien au-dessus. En mise à jour depuis la
v0.14, le ClusterRole en lecture seule du chart gagne pods : appliquez le
chart mis à jour pour que les onglets Charges de travail et Sécurité se
remplissent.
Limites
- La configuration effective par proxy reste hors périmètre. Les routes qu'un proxy donné a effectivement chargées — son vidage de configuration — sont un travail de débogueur et exigent l'API d'administration du proxy. Ce qui est lu ici, c'est ce qu'on a demandé au cluster de faire, ce que ses proxys ont compté, et l'endroit où les deux ne concordent pas.
- Les compteurs par amont des proxys ne sont pas collectés. Le débordement
en attente et les éjections d'instances ne sont pas exposés par un maillage
par défaut ; les collecter revient à inscrire chaque proxy dans
proxyStatsMatcher.inclusionPrefixes: [cluster.outbound], ce qui multiplie les séries de chaque proxy par son nombre d'amonts. La page du proxy nomme le réglage plutôt que d'afficher leur absence comme un zéro. - Pas d'historique de posture, ni d'alerte sur la posture. Une posture est calculée sur la fenêtre que vous regardez. La suivre dans le temps et alerter dessus attendent que les verdicts aient été éprouvés sur de vrais clusters.
- Les deux collectes ont la forme d'Istio. La carte du plan de contrôle lit les métriques d'istiod par leur nom, et les séries du plan de données — le compteur de requêtes avec sa politique de sécurité, les compteurs TCP, les comptes de charges de ztunnel — sont celles d'Istio. Les proxys d'un autre maillage se lisent non reconnus plutôt que plaqués sur des libellés justes aux réponses fausses. La moitié RED par proxy et l'inventaire des charges sont agnostiques.
- Les constats portent sur la configuration et sur ce que les proxys ont compté, pas sur l'état vivant des proxys. Une posture dit que du clair a atteint une charge ; elle ne dit pas quel écouteur l'a accepté. Cela reste une question pour l'outillage de votre maillage.
Voir aussi
- Carte des services — où les sauts de maillage sont masqués, et la dépendance derrière eux reconstituée
- Santé réseau — le fil sous le maillage