Cet article enregistre / partage la structure de déploiement K8 du projet actuel et demande le plan de transformation du suivi
Ce diagramme peut être considéré comme une structure de déploiement k8s générale avec séparation front-end et back-end:
Nginx Ingress est responsable de l'exposition des services (service de ressources statiques front-end nginx). Selon le principe de l'application à douze éléments
, le back -end -end api est utilisé comme une ressource dynamique supplémentaire pour les services nginx.
Ingress vs Ingress-nginx
Site Web du coupon https://www.fenfaw.net/Ingress est un procédé d'exposition de services à des clients en dehors du cluster K8S. Ingress fonctionne à la couche d'application de la pile de protocoles de réseau ,
et détermine le service auquel la demande est transmise basée sur l'hôte de nom d'hôte demandé et le chemin de trajectoire.
Avant d'appliquer les fonctions fournies par l'objet Ingress, il faut souligner que le contrôleur Ingress existe dans le cluster afin que la ressource Ingress puisse fonctionner normalement.
Mon projet Web utilise ici le commun Ingress-nginx (le Ingress officiel à d'autres fins). Ingress-nginx est un contrôleur K8s Ingress qui utilise nginx comme proxy inverse et équilibreur de charge. Il fonctionne comme un pod dans l' kube-system
espace de noms.
Comprendre le principe de fonctionnement d'Ingress est propice à la façon dont nous traitons le personnel d'exploitation et de maintenance.
Ce qui suit expose le service Kibana via Ingress-nginx:
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: kibana
labels:
app: kibana
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-body-size: "8m"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
tls:
- hosts:
- 'https://logging.internal.gridsum.com/'
secretName: tls-cert
rules:
- host: 'https://logging.internal.gridsum.com'
http:
paths:
- path: /
backend:
serviceName: kibana
servicePort: 5601
Ingress-nginx m'a le plus dérouté, c'est que ce sont Paths分流
les rewrite-target
notes.
- Le shunt de chemins est
généralement utilisé pour transférer les demandes vers un pod de service back-end spécifique en fonction d'un chemin spécifique, et le pod de service back-end peut recevoir les informations de chemin.
En règle générale, le service back-end est utilisé comme une API. - Rewrite-target
redirige la requête vers le service back-end. À quoi cela sert-il?
Réponse: Prenons l'exemple du kibana exposé ci-dessus. Nous pouvons déjà https://logging.internal.gridsum.com/
accéder au Kibana complet. Que faire si je veux utiliser ce nom de domaine pour exposer le site ElasticSearch?
Vous pouvez l'utiliser rewrite-target
à ce moment ,
---
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
name: elasticsearch
labels:
app: kibana
annotations:
kubernetes.io/ingress.class: "nginx"
nginx.ingress.kubernetes.io/proxy-connect-timeout: "30"
nginx.ingress.kubernetes.io/proxy-read-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-send-timeout: "1800"
nginx.ingress.kubernetes.io/proxy-body-size: "8m"
nginx.ingress.kubernetes.io/ssl-redirect: "true"
nginx.ingress.kubernetes.io/rewrite-target: "/$2"
spec:
tls:
- hosts:
- 'logging.internal.gridsum.com'
secretName: tls-cert
rules:
- host: 'logging.internal.gridsum.com'
http:
paths:
- path: /es(/|$)(.*)
backend:
serviceName: elasticsearch
servicePort: 9200
Dans cette définition Ingress, (.*)
tous les caractères capturés seront affectés à l'espace réservé $ 2, qui sera ensuite utilisé comme paramètre dans l'annotation cible de réécriture. Dans ce cas: il https://logging.internal.gridsum.com/es
sera redirigé vers le site backend elasticsearch, et le chemin de es sera ignoré
Suivi des journaux Ingress-nginx vers l'application Web
Des amis qui me connaissent savent que j'ai écrit «Un programme standard de collecte et d'analyse des journaux d'applications conteneurisés ASP.NET Core», qui contient principalement les journaux des applications BackEnd. À partir du diagramme de structure ci-dessus,
Ingress-nginx ----> Nginx FrontEnd App ---> BackEnd App nécessite un identifiant de suivi en série, ce qui est pratique pour observer le réseau d'exploitation et de maintenance et les applications métier.
Heureusement, Ingress-nginx, les puissantes capacités de configuration de Nginx nous ont aidés à faire beaucoup de choses:
-
La demande du client arrive au contrôleur Ingress-Nginx, le contrôleur Ingress-Nginx ajoutera automatiquement un en-
X-Request-ID
tête de demande, une valeur aléatoire ---- cette configuration est la valeur par défaut -
La demande atteint l'application Nginx FrontEnd, Nginx a une configuration par défaut
proxy_pass_request_headers on;
et transmet automatiquement tous les en-têtes de demande à l'application backend en amont.
De cette façon, l'idée de request_id dans tout le diagramme de structure est claire. La dernière étape nous oblige seulement à extraire les informations contenues dans la requête dans l'application backend X-Request-ID
et à les utiliser comme champ de sortie clé du journal.
Cela implique comment personnaliser le LayoutRender à partir du journal .
Ce qui suit est le x_request_id
Render nommé personnalisé de NLog , qui extrait la valeur de l'en-tête X-Request-ID de la demande.
① Définir le rendu NLog
/// <summary>
/// Represent a unique identifier to represent a request from the request HTTP header X-Request-Id.
/// </summary>
[LayoutRenderer("x_request_id")]
public class XRequestIdLayoutRender : HttpContextLayoutRendererBase
{
protected override void Append(StringBuilder builder, LogEventInfo logEvent)
{
var identityName = HttpContextAccessor.HttpContext?.Request?.Headers?["X-Request-Id"].FirstOrDefault();
builder.Append(identityName);
}
}
/// <summary>
/// Represent a http context layout renderer to access the current http context.
/// </summary>
public abstract class HttpContextLayoutRendererBase : LayoutRenderer
{
private IHttpContextAccessor _httpContextAccessor;
/// <summary>
/// Gets the <see cref="IHttpContextAccessor"/>.
/// </summary>
protected IHttpContextAccessor HttpContextAccessor { get { return _httpContextAccessor ?? (_httpContextAccessor = ServiceLocator.ServiceProvider.GetService<IHttpContextAccessor>()); } }
}
internal sealed class ServiceLocator
{
public static IServiceProvider ServiceProvider { get; set; }
}
② Obtenir le X-Request-Id à partir de la requête dépend du composant IHttpContextAccessor.
Ce composant est obtenu par recherche de dépendances, veuillez donc générer le service dans Startup ConfigureService
public void ConfigureServices(IServiceCollection services)
{
// ......
ServiceLocator.ServiceProvider = services.BuildServiceProvider();
}
③ Enfin, enregistrez ce rendu NLog dans le programme:
public static void Main(string[] args)
{
LayoutRenderer.Register<XRequestIdLayoutRender>("x_request_id");
CreateHostBuilder(args).Build().Run();
}
De cette façon request_id
, ce qui est généré à partir d'Ingress-Nginx ira à l'application Backend et jouera un rôle énorme dans l'analyse des journaux, et il est également pratique de distinguer la responsabilité des pannes de l'exploitation et de la maintenance / développement.
- https://kubernetes.github.io/ingress-nginx/user-guide/nginx-configuration/configmap/#generate-request-id
- http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_pass_request_headers
Pour résumer
- Comprendre que Ingress fonctionne au niveau de la couche application et expose les services k8s en fonction de l'hôte et du chemin
- Cet article analyse la relation entre Ingress et le commun Ingress-nginx
- Pour les applications qui utilisent Ingress, l'ID de suivi du journal d'Ingress-Nginx vers WebApp a été trié, ce qui est pratique pour dépanner les pannes du réseau / de l'entreprise