Nadat de Kubernetes Cluster ‘up-and-running’ is en er pods met applicaties op draaien, willen we de status van het cluster gaan monitoren. Datgene dat gemonitored kan worden dient ‘gescraped‘ te worden en voor Kubernetes is Prometheus daar de uitgelezen tool voor. Scrapen van de systeem-eigenschappen van de node(s) zelf kan heel goed met ‘node-exporter‘.
NameSpace
De monitoring functies zetten we in een nameSpace genaamd ‘monitoring’ Deze wordt aangemaakt met:
$ kubectl create namespace monitoring
Node Exporter
De nodes worden voorzien van een DaemonSet. Dit is een pod die door Kubernetes op alle nodes geplaatst en uitgevoerd wordt. In dit geval dus met een node-exporter als applicatie zodat de metrics van de nodes uitgelezen kunnen worden. De manifest ziet er alsvolgt uit in node-exporter-daemonset.yml:
apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter namespace: monitoring labels: k8s-app: node-exporter spec: selector: matchLabels: name: node-exporter template: metadata: labels: name: node-exporter spec: tolerations: - key: node-role.kubernetes.io/master operator: Exists effect: NoSchedule containers: - name: node-exporter image: nokkie/node-exporter:arm64 resources: limits: memory: 200Mi requests: cpu: 100m memory: 200Mi
De tolerations zorgt ervoor dat deze DaemonSet ook op de master-node(s) geïnstalleerd wordt.
Het starten van de DaemonSet gaat met het volgende commando:
$ kubectl apply -f node-exporter-daemonset.yml
Node Exporter Service
Om de metrics van de node-exporters te kunnen benaderen wordt op elke node een service aangemaakt die de metrics ‘exposed’ op TCP-port 9100. Dit is het voordeel van een standaard K3s installatie waarbij traefik de loadbalancer service verzorgt op de nodes. De node-exporter-svc.yml:
--- apiVersion: v1 kind: Service metadata: name: node-exporter-service namespace: monitoring spec: selector: name: node-exporter type: LoadBalancer ports: - port: 9100 targetPort: 9100
$ kubectl apply -f node-exporter-svc.yml
Ter controle kunnen we nu de metrics op elke node opvragen met:
$ curl http://[node-name]:9100/metrics
Prometheus roles
Kubernetes heeft serviceAccounts waarmee ‘rollen’ ingesteld kunnen worden die uitgevoerd kunnen worden met deze serviceAccounts. De rollen worden dan via ‘RoleBindings’ aan de serviceAccount gekoppeld. Een manifest om serviceAccount, Roles en RoleBindings te configureren ziet er alsvolgt uit in prometheus-roles.yml:
--- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: [""] resources: - nodes - nodes/proxy - services - endpoints - pods verbs: ["get", "list", "watch"] - apiGroups: - extensions resources: - ingresses verbs: ["get", "list", "watch"] - nonResourceURLs: ["/metrics"] verbs: ["get"] --- apiVersion: v1 kind: ServiceAccount metadata: name: default namespace: monitoring --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: prometheus subjects: - kind: ServiceAccount name: default namespace: monitoring
Om deze in te lezen en te configureren dient het volgende commando:
$ kubectl apply -f prometheus-roles.yml
Prometheus ConfigMap
Prometheus verzamelt de metrics van de aangesloten targets. De targets zijn de nodes waarop de node-exporter draait (met de ingestelde ports), dus die gaan we vervolgens in een configuratie-bestand zetten. We geven binnen Kubernetes de instructie aan Prometheus om dit configuratiebestand in te lezen via een ‘ConfigMap’. De inhoud van prometheus-config.yml:
apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: monitoring data: prometheus.yml: | global: scrape_interval: 15s evaluation_interval: 15s # Alertmanager configuration alerting: alertmanagers: - static_configs: - targets: # - alertmanager:9093 scrape_configs: - job_name: 'prometheus' static_configs: - targets: ['localhost:9090'] - job_name: 'rpi-1' static_configs: - targets: ['rpi-1:9100'] - job_name: 'rpi-2' static_configs: - targets: ['rpi-2:9100'] - job_name: 'rpi-3' static_configs: - targets: ['rpi-3:9100']
Het ‘scrapen‘ (ophalen van de metrics) laten we elke 15 seconden uitvoeren, de ‘alertManager‘ stellen we een andere keer in en de ‘targets‘ zijn de RaspBerry Pi Nodes van het cluster. De TCP-port is ingesteld via de loadbalancer van de node-exporter services. De commando’s om deze configMap in te stellen:
$ kubectl apply f prometheus-config.yml
Prometheus Deployment
De deployment van Prometheus leest de configuratie van de configMap in en zet deze in een volume van het type emptyDir. De prometheus-deployment.yml:
apiVersion: apps/v1 kind: Deployment metadata: name: prometheus-deployment namespace: monitoring labels: app: prometheus-server spec: replicas: 1 selector: matchLabels: app: prometheus-server template: metadata: labels: app: prometheus-server spec: containers: - name: prometheus image: prom/prometheus args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus/" ports: - containerPort: 9090 volumeMounts: - name: prometheus-config-volume mountPath: /etc/prometheus/ - name: prometheus-storage-volume mountPath: /prometheus/ volumes: - name: prometheus-config-volume configMap: defaultMode: 420 name: prometheus-config - name: prometheus-storage-volume emptyDir: {}
Prometheus Service
Om Prometheus te ‘exposen‘ maken we wederom dankbaar gebruik van traefik en wordt een Service aangemaakt van het type loadBalancer die luistert op TCP poort 9090 en de aanvraag doorzet naar dezelfde TCP poort 9090 van Prometheus. De manifest voor de Service is prometheus-service.yml:
--- apiVersion: v1 kind: Service metadata: name: prometheus-service namespace: monitoring spec: selector: app: prometheus-server type: LoadBalancer ports: - port: 9090 targetPort: 9090
en wordt met de volgende commando’s geconfigureerd en gecontroleerd:
$ kubectl apply -f prometheus-service.yml $ kubectl get services -n monitoring NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE node-exporter-service LoadBalancer 10.43.236.32 192.168.178.50,192.168.178.51,192.168.178.52 9100:32280/TCP 9m17s prometheus-service LoadBalancer 10.43.74.141 192.168.178.50,192.168.178.51,192.168.178.52 9090:32244/TCP 12m
De Prometheus-service kan nu in een browser aangeroepen worden op de TCP poort 9090, http://node-naam:9090
Via de ‘Status’ pagina kunnen de ‘Targets‘ bekeken worden en die zouden dan allen de status ‘UP’ moeten hebben.
In Prometheus kunnen metrics opgevraagd worden met de zogenaamde PromQL (Prometheus Query Language) en met behulp van ‘Grafana‘ kunnen de resultaten van de queries grafisch weergegeven worden.
Grafana
Om Grafana uit te rollen als deployment, de service in te stellen en om met behulp van een traefik loadBalancer de web-pagina te kunnen benaderen, zetten we dit in een manifest dat er zo uit ziet in grafana-deployment.yml:
--- apiVersion: apps/v1 kind: Deployment metadata: name: grafana namespace: monitoring labels: app: grafana spec: replicas: 1 strategy: rollingUpdate: maxSurge: 1 maxUnavailable: 1 type: RollingUpdate selector: matchLabels: app: grafana template: metadata: labels: app: grafana spec: containers: - image: grafana/grafana imagePullPolicy: Always name: grafana --- apiVersion: v1 kind: Service metadata: name: grafana-svc namespace: monitoring spec: selector: app: grafana type: LoadBalancer ports: - port: 3000 targetPort: 3000 --- apiVersion: extensions/v1beta1 kind: Ingress metadata: name: grafana-ingress namespace: monitoring spec: rules: - host: grafana-rpi.digitalinfo.local http: paths: - backend: serviceName: grafana-svc servicePort: 3000 path: / pathType: ImplementationSpecific
Het bijbehorende commando:
$ kubectl apply -f grafana-deployment.yml
Er is nu een DNS verwijzing nodig naar de hostname die in de ingress is gedefinieerd: grafana-rpi.digitalinfo.local Dit kan in een DNS-server zijn of in een lokale hosts-file. Daarna kan met de browser de Grafana site bekeken worden:
Inloggen kan met de standaard credentials: admin/admin
Als eerste dient nu de Data-Source aangemaakt te worden waarmee de metrics vanuit Prometheus ingelezen kunnen worden. Via het tandwiel-icon (Configuration) en ‘Data Sources’ kan Prometheus toegevoegd worden.
De URL wordt ‘http://prometheus:9090’ en dit gaat werken omdat de Kubernetes service genaamd ‘prometheus’ ingesteld is op poort 9090.
Via ‘Save & Test‘ wordt de data-source opgeslagen en de connectie getest.
Een voorbeeld van een Grafana Dashboard voor Kubernetes kan ge-importeerd worden met nummer 1860 en dat Dashboard ziet er zo uit: