apiVersion: v1 kind: Namespace metadata: name: observability --- apiVersion: v1 kind: PersistentVolume metadata: name: prometheus-pv spec: storageClassName: "" capacity: storage: 2Gi accessModes: - ReadWriteMany nfs: server: 192.168.2.110 path: /mnt/nfs_share/dev/prometheus readOnly: false --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: prometheus-pvc namespace: observability spec: storageClassName: "" volumeName: prometheus-pv accessModes: - ReadWriteMany resources: requests: storage: 2Gi --- apiVersion: v1 kind: ServiceAccount metadata: name: prometheus namespace: observability --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: prometheus rules: - apiGroups: [""] resources: ["nodes", "nodes/proxy", "services", "endpoints", "pods"] verbs: ["get", "list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: prometheus-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - kind: ServiceAccount name: prometheus namespace: observability --- apiVersion: v1 kind: ConfigMap metadata: name: prometheus-config namespace: observability data: prometheus.yml: | global: scrape_interval: 15s scrape_timeout: 10s external_labels: cluster: DEV scrape_configs: # Node Exporter - job_name: node-exporter static_configs: - targets: ['node-exporter.observability.svc.cluster.local:9100'] # Kube-state-metrics - job_name: kube-state-metrics static_configs: - targets: ['kube-state-metrics.observability.svc.cluster.local:8080'] # Kubelet (per node) - job_name: kubelet scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: false bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token metrics_path: /metrics/cadvisor static_configs: - targets: - 192.168.2.100:10250 - 192.168.2.101:10250 - 192.168.2.102:10250 # API server - job_name: apiserver scheme: https tls_config: ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt insecure_skip_verify: false bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token static_configs: - targets: ['kubernetes.default.svc:443'] --- apiVersion: apps/v1 kind: Deployment metadata: name: prometheus namespace: observability spec: replicas: 1 selector: matchLabels: app: prometheus template: metadata: labels: app: prometheus spec: serviceAccountName: prometheus containers: - name: prometheus image: prom/prometheus:v2.50.0 args: - "--config.file=/etc/prometheus/prometheus.yml" - "--storage.tsdb.path=/prometheus" - "--storage.tsdb.retention.time=15d" ports: - containerPort: 9090 volumeMounts: - name: config mountPath: /etc/prometheus - name: data mountPath: /prometheus volumes: - name: config configMap: name: prometheus-config - name: data persistentVolumeClaim: claimName: prometheus-pvc --- apiVersion: v1 kind: Service metadata: name: prometheus namespace: observability spec: selector: app: prometheus ports: - port: 9090 --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: prometheus namespace: observability spec: entryPoints: - websecure routes: - match: Host(`prometheus-dev.allarddcs.nl`) kind: Rule services: - name: prometheus port: 9090 tls: certResolver: letsencrypt --- # ------------------------- # NODE EXPORTER # ------------------------- apiVersion: apps/v1 kind: DaemonSet metadata: name: node-exporter namespace: observability spec: selector: matchLabels: app: node-exporter template: metadata: labels: app: node-exporter spec: hostNetwork: true hostPID: true containers: - name: node-exporter image: prom/node-exporter:v1.7.0 args: - --path.rootfs=/host ports: - containerPort: 9100 volumeMounts: - name: root mountPath: /host readOnly: true volumes: - name: root hostPath: path: / --- apiVersion: v1 kind: Service metadata: name: node-exporter namespace: observability spec: selector: app: node-exporter ports: - port: 9100 --- # ------------------------- # KUBE-STATE-METRICS # ------------------------- apiVersion: v1 kind: ServiceAccount metadata: name: kube-state-metrics namespace: observability --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: kube-state-metrics rules: - apiGroups: [""] resources: - namespaces - nodes - pods - services - persistentvolumeclaims - persistentvolumes verbs: ["list", "watch"] - apiGroups: ["apps"] resources: - deployments - replicasets - statefulsets - daemonsets verbs: ["list", "watch"] - apiGroups: ["storage.k8s.io"] resources: - storageclasses verbs: ["list", "watch"] - apiGroups: ["batch"] resources: - jobs - cronjobs verbs: ["list", "watch"] - apiGroups: ["autoscaling"] resources: - horizontalpodautoscalers verbs: ["list", "watch"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: kube-state-metrics roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: kube-state-metrics subjects: - kind: ServiceAccount name: kube-state-metrics namespace: observability --- apiVersion: apps/v1 kind: Deployment metadata: name: kube-state-metrics namespace: observability spec: replicas: 1 selector: matchLabels: app: kube-state-metrics template: metadata: labels: app: kube-state-metrics spec: serviceAccountName: kube-state-metrics containers: - name: kube-state-metrics image: registry.k8s.io/kube-state-metrics/kube-state-metrics:v2.10.1 ports: - containerPort: 8080 --- apiVersion: v1 kind: Service metadata: name: kube-state-metrics namespace: observability spec: selector: app: kube-state-metrics ports: - port: 8080 --- # ------------------------- # GRAFANA # ------------------------- apiVersion: v1 kind: PersistentVolume metadata: name: grafana-pv labels: type: local spec: storageClassName: "" capacity: storage: 2Gi accessModes: - ReadWriteMany nfs: server: 192.168.2.110 path: /mnt/nfs_share/dev/grafana readOnly: false --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: grafana-pvc namespace: observability spec: storageClassName: "" volumeName: grafana-pv accessModes: - ReadWriteMany volumeMode: Filesystem resources: requests: storage: 2Gi --- apiVersion: v1 kind: ConfigMap metadata: name: grafana-datasources namespace: observability data: datasources.yaml: | apiVersion: 1 datasources: - name: Prometheus type: prometheus access: proxy url: http://prometheus.observability.svc.cluster.local:9090 isDefault: true --- apiVersion: v1 kind: ConfigMap metadata: name: grafana-dashboard-provider namespace: observability data: dashboards.yaml: | apiVersion: 1 providers: - name: kubernetes folder: Kubernetes type: file options: path: /var/lib/grafana/dashboards --- apiVersion: apps/v1 kind: Deployment metadata: name: grafana namespace: observability spec: replicas: 1 selector: matchLabels: app: grafana template: metadata: labels: app: grafana spec: containers: - name: grafana image: grafana/grafana:10.3.1 ports: - containerPort: 3000 env: - name: GF_SECURITY_ADMIN_PASSWORD value: admin volumeMounts: - name: data mountPath: /var/lib/grafana - name: datasources mountPath: /etc/grafana/provisioning/datasources - name: providers mountPath: /etc/grafana/provisioning/dashboards - name: dashboards mountPath: /var/lib/grafana/dashboards volumes: - name: data persistentVolumeClaim: claimName: grafana-pvc - name: datasources configMap: name: grafana-datasources - name: providers configMap: name: grafana-dashboard-provider - name: dashboards emptyDir: {} --- apiVersion: v1 kind: Service metadata: name: grafana namespace: observability spec: selector: app: grafana ports: - port: 3000 --- apiVersion: traefik.io/v1alpha1 kind: IngressRoute metadata: name: grafana namespace: observability spec: entryPoints: - websecure routes: - match: Host(`grafana-dev.allarddcs.nl`) kind: Rule services: - name: grafana port: 3000 tls: certResolver: letsencrypt