feature/add-goldpinger (#648)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **New Features**
- Introduced a comprehensive Grafana dashboard for Goldpinger, offering
real-time insights into node health, error occurrences, and response
times with intuitive filtering.
- Expanded deployment configurations to include Goldpinger across
environments, streamlining release management and dependency handling.
- Launched a dedicated deployment package featuring customizable
templates for secure, efficient Kubernetes deployments—including
workloads, services, ingress, and monitoring integrations.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
This commit is contained in:
klinch0
2025-02-25 12:08:08 +03:00
committed by GitHub
parent 439381e474
commit d0d62e8847
23 changed files with 1818 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -81,6 +81,7 @@ modules/340-monitoring-kubernetes/monitoring/grafana-dashboards//main/capacity-p
modules/340-monitoring-kubernetes/monitoring/grafana-dashboards//flux/flux-control-plane.json
modules/340-monitoring-kubernetes/monitoring/grafana-dashboards//flux/flux-stats.json
modules/340-monitoring-kubernetes/monitoring/grafana-dashboards//kafka/strimzi-kafka.json
modules/340-monitoring-kubernetes/monitoring/grafana-dashboards//goldpinger/goldpinger.json
EOT

View File

@@ -364,3 +364,10 @@ releases:
cozystack:
configHash: {{ $cozyConfig | toJson | sha256sum }}
{{- end }}
- name: goldpinger
releaseName: goldpinger
chart: cozy-goldpinger
namespace: cozy-goldpinger
privileged: true
dependsOn: [monitoring-agents]

View File

@@ -245,3 +245,10 @@ releases:
cozystack:
configHash: {{ $cozyConfig | toJson | sha256sum }}
{{- end }}
- name: goldpinger
releaseName: goldpinger
chart: cozy-goldpinger
namespace: cozy-goldpinger
privileged: true
dependsOn: [monitoring-agents]

View File

@@ -35,3 +35,4 @@ kubevirt/kubevirt-control-plane
flux/flux-control-plane
flux/flux-stats
kafka/strimzi-kafka
goldpinger/goldpinger

View File

@@ -0,0 +1,3 @@
apiVersion: v2
name: cozy-goldpinger
version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process

View File

@@ -0,0 +1,7 @@
include ../../../scripts/package.mk
update:
rm -rf charts
helm repo add goldpinger https://bloomberg.github.io/goldpinger
helm repo update goldpinger
helm pull goldpinger/goldpinger --untar --untardir charts

View File

@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj
OWNERS

View File

@@ -0,0 +1,9 @@
apiVersion: v1
appVersion: 3.10.2
description: Goldpinger is a tool to help debug, troubleshoot and visualize network
connectivity and slowness issues.
home: https://github.com/bloomberg/goldpinger
name: goldpinger
sources:
- https://github.com/bloomberg/goldpinger
version: 1.0.1

View File

@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "goldpinger.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "goldpinger.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "goldpinger.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "goldpinger.labels" -}}
helm.sh/chart: {{ include "goldpinger.chart" . }}
{{ include "goldpinger.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "goldpinger.selectorLabels" -}}
app.kubernetes.io/name: {{ include "goldpinger.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "goldpinger.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "goldpinger.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,12 @@
{{- if and .Values.rbac.create .Values.rbac.clusterscoped }}
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "goldpinger.fullname" . }}-clusterrole
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
{{- end }}

View File

@@ -0,0 +1,16 @@
{{- if and .Values.rbac.create .Values.rbac.clusterscoped }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "goldpinger.fullname" . }}-clusterrolebinding
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ include "goldpinger.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: ClusterRole
name: {{ include "goldpinger.fullname" . }}-clusterrole
apiGroup: rbac.authorization.k8s.io
{{- end }}

View File

@@ -0,0 +1,8 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "goldpinger.fullname" . }}-zap
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
data:
zap.json: {{ .Values.goldpinger.zapConfig | toJson }}

View File

@@ -0,0 +1,103 @@
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: {{ include "goldpinger.fullname" . }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
spec:
{{- with .Values.updateStrategy }}
updateStrategy:
{{- toYaml . | nindent 4 }}
{{- end }}
selector:
matchLabels:
{{- include "goldpinger.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{ toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "goldpinger.selectorLabels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{ toYaml . | nindent 8 }}
{{- end }}
spec:
priorityClassName: {{ .Values.priorityClassName }}
serviceAccountName: {{ include "goldpinger.serviceAccountName" . }}
{{- if .Values.image.pullSecrets }}
imagePullSecrets:
{{- range .Values.image.pullSecrets }}
- name: {{ . }}
{{- end }}
{{- end }}
containers:
- name: goldpinger-daemon
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
volumeMounts:
- name: zap
mountPath: /config
env:
- name: HOSTNAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
- name: HOST
value: "0.0.0.0"
- name: PORT
value: "{{ .Values.goldpinger.port }}"
- name: LABEL_SELECTOR
value: "app.kubernetes.io/name={{ include "goldpinger.name" . }}"
{{- if .Values.extraEnv -}}
{{ toYaml .Values.extraEnv | nindent 12 }}
{{- end }}
{{- with .Values.containerSecurityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
ports:
- name: http
containerPort: {{ .Values.goldpinger.port }}
protocol: TCP
{{- range $k := .Values.extraEnv }}
{{- if and (eq $k.name "USE_HOST_IP") (eq $k.value "true") }}
hostPort: {{ $.Values.goldpinger.port }}
{{- end }}
{{- end }}
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: zap
configMap:
name: {{ include "goldpinger.fullname" . }}-zap
{{- range $k := .Values.extraEnv }}
{{- if and (eq $k.name "USE_HOST_IP") (eq $k.value "true") }}
hostNetwork: true
{{- end }}
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@@ -0,0 +1,61 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "goldpinger.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,19 @@
{{- if .Values.prometheusRule.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: {{ template "goldpinger.fullname" . }}
{{- if .Values.prometheusRule.namespace }}
namespace: {{ .Values.prometheusRule.namespace }}
{{- else }}
namespace: {{ .Release.Namespace | quote }}
{{- end }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
spec:
{{- with .Values.prometheusRule.rules }}
groups:
- name: {{ template "goldpinger.name" $ }}
rules: {{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
{{- end }}

View File

@@ -0,0 +1,20 @@
{{- if or .Values.podSecurityPolicy.enabled (not .Values.rbac.clusterscoped) }}
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
rules:
{{- if not .Values.rbac.clusterscoped }}
- apiGroups: [""]
resources: ["pods"]
verbs: ["list"]
{{- end }}
{{- if .Values.podSecurityPolicy.enabled }}
- apiGroups: ["extensions"]
resources: ["podsecuritypolicies"]
resourceNames: [{{ .Values.podSecurityPolicy.policyName | quote }}]
verbs: ["use"]
{{- end }}
{{- end }}

View File

@@ -0,0 +1,16 @@
{{- if or .Values.podSecurityPolicy.enabled (not .Values.rbac.clusterscoped) }}
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
roleRef:
kind: Role
name: {{ include "goldpinger.fullname" . }}-pod-security-policy
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: {{ include "goldpinger.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}
{{- end }}

View File

@@ -0,0 +1,26 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "goldpinger.fullname" . }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
{{- with .Values.service.labels }}
{{ toYaml . | indent 4 }}
{{- end }}
{{- with .Values.service.annotations }}
annotations:
{{ toYaml . | indent 4 }}
{{- end }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: {{ .Values.goldpinger.port }}
protocol: TCP
name: http
selector:
{{- include "goldpinger.selectorLabels" . | nindent 4 }}
{{- if .Values.service.loadBalancerSourceRanges }}
loadBalancerSourceRanges:
{{- toYaml .Values.service.loadBalancerSourceRanges | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,8 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "goldpinger.serviceAccountName" . }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
{{- end }}

View File

@@ -0,0 +1,32 @@
{{- if .Values.serviceMonitor.enabled }}
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: {{ include "goldpinger.fullname" . }}
{{- if .Values.serviceMonitor.namespace }}
namespace: {{ .Values.serviceMonitor.namespace }}
{{- end }}
labels:
{{- include "goldpinger.labels" . | nindent 4 }}
{{- range $key, $value := .Values.serviceMonitor.selector }}
{{ $key }}: {{ $value | quote }}
{{- end }}
spec:
endpoints:
- port: http
interval: {{ .Values.serviceMonitor.interval }}
{{- if .Values.serviceMonitor.honorLabels }}
honorLabels: true
{{- end }}
{{- with .Values.serviceMonitor.metricRelabelings }}
metricRelabelings:
{{- toYaml . | nindent 8 }}
{{- end }}
jobLabel: name
namespaceSelector:
matchNames:
- {{ .Release.Namespace }}
selector:
matchLabels:
{{- include "goldpinger.selectorLabels" . | nindent 6 }}
{{- end -}}

View File

@@ -0,0 +1,166 @@
# Default values for goldpinger.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
image:
repository: bloomberg/goldpinger
# Overrides the image tag whose default is the chart appVersion.
tag: ""
pullPolicy: IfNotPresent
## Optionally specify an array of imagePullSecrets.
## Secrets must be manually created in the namespace.
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
##
# pullSecrets:
# - myRegistryKeySecretName
rbac:
create: true
clusterscoped: true
serviceAccount:
create: true
name:
goldpinger:
port: 8080
zapConfig: |
{
"level": "info",
"encoding": "json",
"outputPaths": [
"stdout"
],
"errorOutputPaths": [
"stderr"
],
"initialFields": {
},
"encoderConfig": {
"messageKey": "message",
"levelKey": "level",
"levelEncoder": "lowercase",
"timeKey": "ts",
"timeEncoder": "ISO8601",
"callerKey": "caller",
"callerEncoder": "Short"
}
}
extraEnv: []
service:
type: ClusterIP
port: 8081
annotations: {}
labels: {}
loadBalancerSourceRanges: {}
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
## Set a priorityClassName for the pod. If left blank a default priority will be set.
priorityClassName:
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
podAnnotations: {}
podLabels: {}
updateStrategy: {}
# type: RollingUpdate
# rollingUpdate:
# maxUnavailable: 1
## Node labels for pod assignment
## Ref: https://kubernetes.io/docs/user-guide/node-selection/
##
nodeSelector: {}
## Tolerations for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/taint-and-toleration/
##
tolerations: []
## Affinity for pod assignment
## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#affinity-and-anti-affinity
##
affinity: {}
## Enable this if pod security policy enabled in your cluster
## It will bind ServiceAccount with unrestricted podSecurityPolicy
## Ref: https://kubernetes.io/docs/concepts/policy/pod-security-policy/
podSecurityPolicy:
enabled: false
policyName: unrestricted-psp
## Set security context of the goldpinger container
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
containerSecurityContext:
capabilities:
drop:
- ALL
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
runAsNonRoot: true
## Set security context of the pod
## Ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
podSecurityContext:
runAsNonRoot: true
runAsUser: 1000
fsGroup: 2000
seccompProfile:
type: RuntimeDefault
serviceMonitor:
enabled: false
selector:
prometheus: "kube-prometheus"
# namespace: monitoring
interval: 30s
# honorLabels: true
metricRelabelings: []
# - action: drop
# source_labels: [__name__]
# regex: goldpinger_peers_response_time_s_bucket
## Custom PrometheusRule to be defined
## ref: https://github.com/coreos/prometheus-operator#customresourcedefinitions
prometheusRule:
enabled: false
rules:
- alert: goldpinger_nodes_unhealthy
expr: |
sum(goldpinger_nodes_health_total{job="{{ template "goldpinger.fullname" . }}", status="unhealthy"})
BY (instance, goldpinger_instance) > 0
for: 5m
annotations:
description: |
Goldpinger instance {{ "{{ $labels.goldpinger_instance }}" }} has been reporting unhealthy nodes for at least 5 minutes.
summary: Instance {{ "{{ $labels.instance }}" }} down
labels:
severity: warning

View File

@@ -0,0 +1,5 @@
goldpinger:
serviceMonitor:
enabled: true
prometheusRule:
enabled: true