Merge pull request #73 from ckotzbauer/feature/chekr

feat: first version of chekr chart
This commit is contained in:
Christian Kotzbauer 2021-10-09 12:20:38 +02:00 committed by GitHub
commit 4d55f6ad92
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 686 additions and 6 deletions

View File

@ -26,17 +26,17 @@ jobs:
- name: Run chart-testing (list-changed)
id: list-changed
run: |
changed=$(ct list-changed)
changed=$(ct list-changed --target-branch main)
if [[ -n "$changed" ]]; then
echo "::set-output name=changed::true"
fi
- name: Run chart-testing (lint)
run: ct lint
run: ct lint --target-branch main
- name: Create kind cluster
uses: helm/kind-action@v1.2.0
if: steps.list-changed.outputs.changed == 'true'
- name: Run chart-testing (install)
run: ct install
run: ct install --target-branch main

View File

@ -2,9 +2,6 @@
[![](https://github.com/ckotzbauer/helm-charts/workflows/Release%20Charts/badge.svg?branch=main)](https://github.com/ckotzbauer/helm-charts/actions)
[mergify]: https://mergify.io
[mergify-status]: https://img.shields.io/endpoint.svg?url=https://gh.mergify.io/badges/ckotzbauer/helm-charts&style=flat-square
## Usage
Add the repo:
@ -17,5 +14,6 @@ helm repo add ckotzbauer https://ckotzbauer.github.io/helm-charts
- [access-manager](https://github.com/ckotzbauer/helm-charts/tree/main/charts/access-manager)
- [cadvisor](https://github.com/ckotzbauer/helm-charts/tree/main/charts/cadvisor)
- [chekr](https://github.com/ckotzbauer/helm-charts/tree/main/charts/chekr)
- [nfs-client-provisioner](https://github.com/ckotzbauer/helm-charts/tree/main/charts/nfs-client-provisioner)
- [prometheus-blackbox-exporter](https://github.com/ckotzbauer/helm-charts/tree/main/charts/prometheus-blackbox-exporter)

23
charts/chekr/.helmignore Normal file
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
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

19
charts/chekr/Chart.yaml Normal file
View File

@ -0,0 +1,19 @@
apiVersion: v2
name: chekr
description: A inspection utility for the maintenance of Kubernetes clusters.
type: application
version: 0.5.0
appVersion: 0.5.0
home: https://github.com/ckotzbauer/chekr
sources:
- https://github.com/ckotzbauer/chekr
- https://github.com/ckotzbauer/helm-charts
keywords:
- prometheus
- kubernetes
- cli
- maintenance
- clusters
maintainers:
- name: ckotzbauer
email: christian.kotzbauer@gmail.com

144
charts/chekr/README.md Normal file
View File

@ -0,0 +1,144 @@
# Chekr
A inspection utility for the maintenance of Kubernetes clusters.
Learn more: [https://github.com/ckotzbauer/chekr](https://github.com/ckotzbauer/chekr)
## TL;DR;
```bash
$ helm install ckotzbauer/chekr
```
## Prerequisites
- Kubernetes 1.17+ (Helm chart)
## Installing the Chart
To install the chart with the release name `my-release`:
```bash
$ helm install --name my-release ckotzbauer/chekr
```
The command deploys the nginx-pod of this chart on the Kubernetes cluster using the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
## Uninstalling the Chart
To uninstall/delete the `my-release` deployment:
```bash
$ helm delete my-release
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Configuration
The following table lists the configurable parameters of the Chekr chart and their default values.
| Parameter | Description | Default |
| -------------------------------------- | ------------------------------------------------- | ------------------------------------- |
| `imagePullSecrets` | Pull-Secrets to use for each pod | `[]` |
| `nameOverride` | Name-Override | `""` |
| `fullnameOverride` | FullName-Override | `""` |
| `webserver.image.repository` | container image repository | `nginxinc/nginx-unprivileged` |
| `webserver.image.tag` | container image tag | `mainline-alpine` |
| `webserver.image.pullPolicy` | container image pull policy | `IfNotPresent` |
| `webserver.service.type` | type of the webserver-service | `ClusterIP` |
| `webserver.service.port` | port of the webserver-service | `8080` |
| `webserver.ingress.enabled` | whether to create an Ingress | `false` |
| `webserver.ingress.className` | name of the IngressClass | `""` |
| `webserver.ingress.annotations` | Annotations for the Ingress | `{}` |
| `webserver.ingress.hosts` | List of host-objects for the Ingress | `[]` |
| `webserver.ingress.tls` | List of TLS-configs for the Ingress | `[]` |
| `webserver.resources` | webserver-pod resource requests & limits | See [values.yaml](values.yaml) |
| `webserver.nodeSelector` | node labels for webserver-pod assignment | `{}` |
| `webserver.tolerations` | node tolerations for webserver-pod assignment | `[]` |
| `webserver.affinity` | node affinity for webserver-pod assignment | `{}` |
| `job.image.repository` | container image repository | `ghcr.io/ckotzbauer/chekr` |
| `job.image.tag` | container image tag | `0.5.0` |
| `job.image.pullPolicy` | container image pull policy | `IfNotPresent` |
| `job.schedule` | cron-schedule for the job | `0 22 * * *` |
| `job.commands` | Array of commands and output-files to process | `[]` See [values.yaml](values.yaml) |
| `job.config` | Global config-values for chekr-config-file | `{}` See [values.yaml](values.yaml) |
| `job.env` | List of environment-variables | `[]` See [values.yaml](values.yaml) |
| `job.resources` | job-pod resource requests & limits | See [values.yaml](values.yaml) |
| `job.nodeSelector` | node labels for job-pod assignment | `{}` |
| `job.tolerations` | node tolerations for job-pod assignment | `[]` |
| `job.affinity` | node affinity for job-pod assignment | `{}` |
| `job.serviceAccount.create` | Should we create a ServiceAccount for the Job | `true` |
| `job.serviceAccount.name` | Name of the ServiceAccount to use | null |
| `podSecurityContext` | securityContext to add to each pod | See [values.yaml](values.yaml) |
| `securityContext` | securityContext to add to each container | See [values.yaml](values.yaml) |
| `podAnnotations` | annotations to add to each pod | `{}` |
| `persistence.storageClass` | storage class of the PVC (RWX is required) | `-` |
| `persistence.size` | size of the PVC (RWX is required) | `256Mi` |
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```bash
$ helm install --name my-release \
--set key_1=value_1,key_2=value_2 \
ckotzbauer/chekr
```
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
# example for staging
$ helm install --name my-release -f values.yaml ckotzbauer/chekr
```
## Example
```yaml
webserver:
ingress:
enabled: true
className: "nginx"
hosts:
- host: chekr.myorg.com
paths:
- path: /
pathType: ImplementationSpecific
tls:
- secretName: ""
hosts:
- chekr.myorg.com
job:
commands:
- command: "deprecation list -o html"
outputFile: "deprecation.html"
- command: "resources -n flux-system --limits-threshold 20 -o json"
outputFile: "flux-system-resources.json"
- command: "resources -n infrastructure -o html"
outputFile: "infrastructure-resources.html"
config:
prometheus-url: monitoring/k8s-prometheus:9090
```
This will deploy the nginx-webserver pod under the Domain "chekr.myorg.com". The CronJob will be executed each night (default schedule) and will
execute the following commands on each run:
```
chekr deprecation list -o html --output-file deprecation.html
chekr resources -n flux-system --limits-threshold 20 -o json --output-file flux-system-resources.json
chekr resources -n infrastructure -o html --output-file infrastructure-resources.html
```
The output-files are served from the webserver:
```
https://chekr.myorg.com/deprecation.html
https://chekr.myorg.com/flux-system-resources.json
https://chekr.myorg.com/infrastructure-resources.html
```
Chekr will use the in-cluster Service `k8s-prometheus` in the `monitoring` namespace at port `9090` to query prometheus for the `resources` subcommand.
> **Tip**: You can use the default [values.yaml](values.yaml)

View File

@ -0,0 +1,3 @@
persistence:
storageClass: "standard"
accessMode: ReadWriteOnce

View File

@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "chekr.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 "chekr.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 "chekr.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "chekr.labels" -}}
helm.sh/chart: {{ include "chekr.chart" . }}
{{ include "chekr.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "chekr.selectorLabels" -}}
app.kubernetes.io/name: {{ include "chekr.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "chekr.serviceAccountName" -}}
{{- if .Values.job.serviceAccount.create }}
{{- default (include "chekr.fullname" .) .Values.job.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.job.serviceAccount.name }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,45 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
rules:
- apiGroups:
- "*"
resources:
- "*"
verbs:
- "list"
- apiGroups:
- ""
resources:
- "pods"
- "persistentvolumeclaims"
verbs:
- "get"
- apiGroups:
- ""
resources:
- "pods/portforward"
verbs:
- "*"
- apiGroups:
- "apps"
resources:
- "replicasets"
- "deployments"
- "daemonsets"
- "statefulsets"
verbs:
- "get"
- apiGroups:
- "kyverno.io"
resources:
- "clusterpolicies"
verbs:
- "get"
- "create"
- "update"
- "patch"
- "delete"

View File

@ -0,0 +1,14 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: {{ include "chekr.fullname" . }}
subjects:
- kind: ServiceAccount
name: {{ include "chekr.serviceAccountName" . }}
namespace: {{ .Release.Namespace }}

View File

@ -0,0 +1,11 @@
{{- if .Values.job.config }}
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
data:
chekr.yaml: |
{{ toYaml .Values.job.config | indent 4 }}
{{- end }}

View File

@ -0,0 +1,79 @@
{{- if semverCompare ">=1.21-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: batch/v1
{{- else -}}
apiVersion: batch/v1beta1
{{- end }}
kind: CronJob
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
spec:
schedule: {{ .Values.job.schedule | quote }}
jobTemplate:
spec:
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 12 }}
{{- end }}
labels:
{{- include "chekr.selectorLabels" . | nindent 12 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 12 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 12 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 14 }}
image: "{{ .Values.job.image.repository }}:{{ .Values.job.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.job.image.pullPolicy }}
command:
- /bin/sh
args:
- -c
- |
{{- range .Values.job.commands }}
chekr {{ .command }} --output-file /results/{{ .outputFile }}
{{- end }}
{{- with .Values.job.env }}
env:
{{- toYaml . | nindent 14 }}
{{- end }}
resources:
{{- toYaml .Values.job.resources | nindent 14 }}
volumeMounts:
- name: results
mountPath: /results
{{- if .Values.job.config }}
- name: config
mountPath: /.config/chekr
{{- end }}
volumes:
- name: results
persistentVolumeClaim:
claimName: {{ include "chekr.fullname" . }}
{{- if .Values.job.config }}
- name: config
configMap:
name: {{ include "chekr.fullname" . }}
{{- end }}
serviceAccountName: {{ include "chekr.serviceAccountName" . }}
{{- with .Values.job.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.job.affinity }}
affinity:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.job.tolerations }}
tolerations:
{{- toYaml . | nindent 12 }}
{{- end }}
restartPolicy: OnFailure

View File

@ -0,0 +1,56 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
{{- include "chekr.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "chekr.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.webserver.image.repository }}:{{ .Values.webserver.image.tag }}"
imagePullPolicy: {{ .Values.webserver.image.pullPolicy }}
ports:
- name: http
containerPort: 8080
protocol: TCP
resources:
{{- toYaml .Values.webserver.resources | nindent 12 }}
volumeMounts:
- name: results
mountPath: /usr/share/nginx/html
volumes:
- name: results
persistentVolumeClaim:
claimName: {{ include "chekr.fullname" . }}
{{- with .Values.webserver.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webserver.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webserver.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}

View File

@ -0,0 +1,61 @@
{{- if .Values.webserver.ingress.enabled -}}
{{- $fullName := include "chekr.fullname" . -}}
{{- $svcPort := .Values.webserver.service.port -}}
{{- if and .Values.webserver.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.webserver.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.webserver.ingress.annotations "kubernetes.io/ingress.class" .Values.webserver.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 "chekr.labels" . | nindent 4 }}
{{- with .Values.webserver.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if and .Values.webserver.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }}
ingressClassName: {{ .Values.webserver.ingress.className }}
{{- end }}
{{- if .Values.webserver.ingress.tls }}
tls:
{{- range .Values.webserver.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.webserver.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,18 @@
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.accessMode | default "ReadWriteMany" }}
volumeMode: Filesystem
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- if (eq "-" .Values.persistence.storageClass) }}
storageClassName: ""
{{- else }}
storageClassName: "{{ .Values.persistence.storageClass }}"
{{- end }}

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "chekr.fullname" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
spec:
type: {{ .Values.webserver.service.type }}
ports:
- port: {{ .Values.webserver.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "chekr.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,12 @@
{{- if .Values.job.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "chekr.serviceAccountName" . }}
labels:
{{- include "chekr.labels" . | nindent 4 }}
{{- with .Values.job.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}

120
charts/chekr/values.yaml Normal file
View File

@ -0,0 +1,120 @@
# Default values for chekr.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
podAnnotations: {}
podSecurityContext:
fsGroup: 101
securityContext:
capabilities:
drop:
- ALL
readOnlyRootFilesystem: false
runAsNonRoot: true
runAsUser: 101
# Storage to store and serve report files (mandatory).
persistence:
# Storage-Class to use. RWX capability is required.
storageClass: "-"
size: 256Mi
webserver:
image:
repository: nginxinc/nginx-unprivileged
pullPolicy: IfNotPresent
tag: mainline-alpine
service:
type: ClusterIP
port: 8080
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
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
nodeSelector: {}
tolerations: []
affinity: {}
job:
image:
repository: ghcr.io/ckotzbauer/chekr
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
schedule: "0 22 * * *"
commands: []
# - command: "deprecation list -o html"
# outputFile: "deprecation.html"
# - command: "resources -n shop-app --limits-threshold 20 -o json"
# outputFile: "shop-app-resources.json"
config:
# prometheus-url: monitoring/k8s-prometheus:9090
# prometheus-user: prometheus
env: []
# - name: CHEKR_SELECTOR
# value: "app.kubernetes.io/name=myapp"
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
nodeSelector: {}
tolerations: []
affinity: {}
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""