Aller au contenu

Déploiement de la Pile d'observabilité Prometheus/Grafana/Alertmanager

Prérequis

  • Helm 3 installé sur la machine de l'operateur (version utilisée pour la rédaction v3.12.2)
  • Un cluster Kubernetes accessible (Version 1.24utilisée), fonctionnel, accessible avec les droits administrateur par l'usager.
  • Traefik et Cert-Manager installé sur le cluster
  • Le pilote CSI pour Openstack installé

L'ingress-controller est l’élément qui permet l'exposition de services à l’extérieur du cluster, ainsi que le routage des requètes entrantes vers les bon services.

Installation de la stack kube-prometheus-stack

La pile Prometheus/Grafana a été séléctionnée pour l'observabilité du système applicatif Gitlab.

Nous installerons la pile d'observabilité dans un namespace prévu à cet effet, le namespace monitoring sera utilisé.

Configuration du cluster des runners

Avant de deployer la pile d'observabilité, il faut: * Rendre accessible le cluster des runners (ou tout autre cluster kubernetes), au cluster de monitoring. * Configurer un ServiceAccount avec des droits suffisant pour lister tout les endpoints à monitorer, que le prometheus utilisera pour moissoner. * Deployer une pile node-exporter, afin d'exposer les metriques techniques des noeuds.

Il est à noter que cette configuration peut être repliqués sur un nombre presque infini de cluster différents.

Dans un premier temps, il faut rendre le cluster des runners accessible par le cluster de montiroing.

Pour ce faire, sur openstack, un routeur peut être deployé entre les réseau applicatifs des clusters, et une route ajoutée sur les instances pour qu'une communication inter-réseaux soit possible.

Ensuite, sur le cluster des runners, il faut creer les ressources suivante, afin de créer un serviceAccount, lié à un ClusterRole:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: prometheus-kubernetes-sd-clusterrole
rules:
- apiGroups:
  - ""
  ##Donne les droits de lister tout les endpoints des noeuds,services et pods.
  resources:
  - nodes
  - nodes/proxy
  - services
  - services/proxy
  - endpoints
  - pods
  - pods/proxy
  verbs:
  - get
  - list
  - watch
- nonResourceURLs:
  - /metrics
  verbs:
  - get
--- 
apiVersion: v1
kind: ServiceAccount
metadata:
  namespace: monitoring 
  name: prometheus-kubernetes-sd-serviceaccount
--- 
apiVersion: v1
kind: Secret
metadata:
## Depuis la 1.24, le token d'un serviceAccount n'est pas generé automatiquement, il faut creer un secret la main et lui mettre l'annotation kubernetes.io/service-account.name et le tupe service-account-token
  name: prometheus-kubernetes-sd-serviceaccount-secret
  namespace: monitoring
  annotations:
    kubernetes.io/service-account.name: prometheus-kubernetes-sd-serviceaccount
type: kubernetes.io/service-account-token
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: prometheus-kubernetes-sd-clusterrolebinding
subjects:
- kind: ServiceAccount
  name: prometheus-kubernetes-sd-serviceaccount
  namespace: monitoring
roleRef:
  kind: ClusterRole
  name: prometheus-kubernetes-sd-clusterrole
  apiGroup: rbac.authorization.k8s.io

Le token du ServiceAccount, et le certificat doivent être recupérés, car ces derniers seront utilisés pour s'authentifier par le prometheus de la pile d'observabilité.

Pour recuperer ces secrets:

kubectl get secrets prometheus-kubernetes-sd-serviceaccount-secret -o jsonpath='{.data.ca\.crt}'
kubectl get secrets prometheus-kubernetes-sd-serviceaccount-secret -o jsonpath='{.data.token}'
Conservez ces deux données, car elles seront utilisés pour configurer le prometheus.

Et enfin, il faut deployer une pile node-exporter, pour ce faire, le helm-chart du dépot de code prometheus-community est utilisé.

Les values passées à ce helm sont les suivantes:

#Ajoute une tolerations, afin que le node exporter soit aussi deployé sur les server.
#Le nom de la toleration peut être à adapter.
tolerations:
  - effect: NoExecute
    operator: Exists

Pour deployer le helm chart node-exporter dans le namespace monitoring:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm  install node-exporter  prometheus-community/prometheus-node-exporter -n monitoring --create-namespace -f <chemin_vers_values>

Deploiement de la pile d'observabilité sur le cluster monitoring

Un Helm chart, regroupant Prometheus,grafana,AlertManager et node-exporter est mis à disposition sur le dépôt de code kube-prometheus-stack.

Les commandes pour ajouter le dépot de code Helm sont les suivantes:

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

Note: Il est nécéssaire d'avoir installé l'openstack-csi driver, qui est decrit dans la documentation Kubernetes.

Comme tout chart Helm, des values doivent être passée pour adapté la pile à nos besoins, voici celles utilisées par la pile Gitlab (Lien du fichier originel):

Values de Preproduction

grafana:
  enabled: true 
  #Configuration de la persistance grafana (ie. des volumes seront crées)
  persistence:
    enabled: true
    type: pvc
    storageClassName: csi-cinder-sc-delete
    accessModes:
    - ReadWriteOnce
    size: 10Gi
    finalizers:
    - kubernetes.io/pvc-protection
  # Installation de plugin sur grafana
  plugins:
    - grafana-piechart-panel
  sidecar:
    dashboards:
      enabled: true

  #Definition de variables supplementaires, ici utilisées pour definir une URL externe pour le grafana, afin que les liens envoyés par mail soit cliquables.
  extraEnvVars:
    - name: GF_SERVER_DOMAIN
      value: "grafana.gitlab-runners-preprod.eco4.cloud.e2.rie.gouv.fr"
    - name: GF_SERVER_ROOT_URL
      value: "https://grafana.gitlab-runners-preprod.eco4.cloud.e2.rie.gouv.fr"

  #Configuration de l'envoi de mail
  grafana.ini:
    smtp:
      enabled: true
      host: mailrelay.services-infra.eco4.cloud.e2.rie.gouv.fr:25
      skip_verify: true
      from_address:  monitoring-notification.cseco@developpement-durable.gouv.fr
      from_name: Grafana
  notifiers:
  # Configuratib
    notifiers.yaml:
      notifiers:
      - name: SNUM-Mail-Alert
        type: email
        uid: email1
        settings:
          addresses: Agents.GAG.DAM.MSP.SNUM.SG@developpement-durable.gouv.fr
      - name: SNUM-Arianne-Alert
        type: slack 
        uid: rocketchat1
        is_default: true
        settings:
          username: Alerte Support Gitlab
          icon_url: https://about.gitlab.com/images/icons/logos/slp-icon.svg
          url: https://ariane.din.developpement-durable.gouv.fr/hooks/<TOKEN>
## Description de l'instance prometheus 
##
prometheus:
  prometheusSpec:
      # Les secrets contenants le token et le certificat du cluster sont montés dans le pod prometheus afin d'être référencé par prometheus
    secrets: 
      - kubernetes-runner-cluster-certificate
      - kubernetes-runner-cluster-token 

    #additionalScrapeConfigs defini toute les definitions supplémentaire de scraping.
    #Il est possible d'ajouter des configuration à la volée, il y a un reloader de configuration automatique.
    additionalScrapeConfigs:
    ##Scrape the the node exporter of the runner cluster
    - job_name: kubernetes-runner-cluster-node-exporter
      kubernetes_sd_configs:
      - api_server: https://192.168.22.221:6443
        role: endpoints
        bearer_token_file: /etc/prometheus/secrets/kubernetes-runner-cluster-token/token
        tls_config:
          ca_file: /etc/prometheus/secrets/kubernetes-runner-cluster-certificate/ca.crt
      relabel_configs:
        - source_labels: [__meta_kubernetes_service_name]
          action: keep
          regex: node-exporter-prometheus-node-exporter
    ##Scrape the metrics endpoints of the runner's pods
    - job_name: kubernetes-runner-cluster-pod-runners-metrics
      kubernetes_sd_configs:
      - api_server: https://192.168.22.221:6443
        role: pod
        bearer_token_file: /etc/prometheus/secrets/kubernetes-runner-cluster-token/token
        tls_config:
          ca_file: /etc/prometheus/secrets/kubernetes-runner-cluster-certificate/ca.crt
      relabel_configs:
        - source_labels: [__meta_kubernetes_pod_label_app]
          action: keep
          regex: gitlab-runner-gitlab-runner
    ##Scrape the metrics endpoints of the cluster node
    - job_name: kubernetes-runner-cluster-nodes-kubelet-metrics
      kubernetes_sd_configs:
      - api_server: https://192.168.22.221:6443
        role: node
        bearer_token_file: /etc/prometheus/secrets/kubernetes-runner-cluster-token/token
        tls_config:
          ca_file: /etc/prometheus/secrets/kubernetes-runner-cluster-certificate/ca.crt
      relabel_configs:
        - action: labelmap
          regex: __meta_kubernetes_node_label_(.+)
    ##Scrape the endpoints of the troubleshoot project
    - job_name: gitlab-pipeline-metrics
      scrape_interval: 60s
      scheme: https
      metrics_path: /dam/diverstests/pipeline-troubleshoot/prometheus.out.txt
      static_configs:
      - targets: 
        - snum.gitlab-pages.din.developpement-durable.gouv.fr
    ##Scrape the endpoints the official gitlab metrics endpoint     
    - job_name: gitlab-app-metrics
      scrape_interval: 10s
      scheme: https
      metrics_path: '/-/metrics'
      static_configs:
      - targets: 
        - gitlab-forge-preprod.din.developpement-durable.gouv.fr
      params:
        token: ['<token>'] #Ici utiliser un token avec droit de lecture sur l'api
    ##Scrape the endpoints the official gitlab exporter endpoint
    - job_name: gitlab-exporter
      scrape_interval: 10s
      scheme: http
      metrics_path: /metrics
      static_configs:
      - targets: 
        - 10.165.79.182:9168 #IP de l'instance applicative 
    ##Scrape the endpoints of the gitlab application instance node exporter 
    - job_name: gitlab-node-exporter
      scrape_interval: 10s
      scheme: http
      metrics_path: /metrics
      static_configs:
      - targets: 
        - 10.165.79.182:9100 #IP de l'instance applicative
    ## Node exporter instance Sonarqube
    - job_name: sonarqube-node-exporter
      scrape_interval: 10s
      scheme: https
      metrics_path: /node/metrics
      static_configs:
      - targets: 
        - node-exporter.pic2.picoshi-preprod.eco4.cloud.e2.rie.gouv.fr
    ##Endpoint monitoring Sonarqube
    - job_name: sonarqube-node-exporter
      scrape_interval: 10s
      scheme: https
      metrics_path: /sonarqube
      static_configs:
      - targets: 
        - node-exporter.pic2.picoshi-preprod.eco4.cloud.e2.rie.gouv.fr

## Extra manifests to deploy as an array
#Ici le token et le certificat du cluster des runners est placé 
extraManifests:
 - apiVersion: v1
   kind: Secret
   metadata:
     name: kubernetes-runner-cluster-certificate
   type: Opaque
   data:
    ca.crt: <car.crt_value_base64>
 - apiVersion: v1
   kind: Secret
   metadata:
     name: kubernetes-runner-cluster-token
   type: Opaque
   data:
    token: <token_value_base64>

Après que le fichier values soit adapté, il est possible de deployer la pile:

helm install kube-prometheus-stack prometheus-community/kube-prometheus-stack --value <FICHIER_VALUE> -n monitoring --create-namespace

Configuration du certificat et de l'ingress

Pour que le Grafana soit accessible depuis l'exterieur du cluster, il faut configurer une ingressRoute via Traefik et creer un certificat:

IngressRoute et Certificats de preproduction

apiVersion: traefik.containo.us/v1alpha1
kind: IngressRoute
metadata:
  name: grafana-ingress-route
  namespace: traefik
spec:
  entryPoints:
  - websecure
  routes:
  - kind: Rule
    match: Host(`grafana.gitlab-runners-preprod.eco4.cloud.e2.rie.gouv.fr`)
    middlewares:
    - name: https-redirect
      namespace: traefik 
    services:
    - name: kube-prometheus-stack-grafana
      namespace: monitoring
      port: 80
  tls:
    secretName: grafana-selfsigned-certificate
---
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
  name: grafana-selfsigned-certificate 
  namespace: traefik
spec:
  dnsNames:
    - grafana.gitlab-runners-preprod.eco4.cloud.e2.rie.gouv.fr
  secretName: grafana-selfsigned-certificate 
  issuerRef:
    name: selfsigned
    kind: ClusterIssuer
Note: La creation du certificat decrit ci-dessus implique l'installation et la configuration de traefik et de cert-manager ainsi que d'un ClusterIssuer, tout est decrit dans la documentation Kubernetes.

Configuration de la remontée de metriques vers prometheus

Gitlab

Pour surveiller des point d'accès (endpoints), des ressources telles que des ServicesMonitor et des PodMonitor doivent être déployées. Ces dernières indiquent à l'instance Prometheus de moissonner certain endpoints. Les ServiceMonitor parcourent les endpoints de services, tandis que les PodMonitor récoltent les endpoints de pods. Les services ou les pods sélectionnés par ces deux objets Kubernetes sont définis par des labels.

GitLab expose un endpoint metrics, pouvant être moissonné par Prometheus.

GitLab peut aussi être configuré pour exposer des exporter ; ces derniers sont des serveurs managés par GitLab qui vont exposer des métriques sur des éléments du GitLab.

Trois exporter sont activés sur les instance GitLab : * L'exporter Postgresql : métriques de la DB Postgresql ; * L'exporter GitLab : métriques métier et technique sur la solution GitLab ; * Le Node Exporter : métriques serveurs. Sachant que les instances GitLab et la pile de supervision ne sont pas dans le même projets openstack, le moissonage ne peut être fait sur une ip privée, ce dernier se fait donc sur l'URL publique de l'instance, et l'accès à l'endpoint se fait avec un token.