diff --git a/README.md b/README.md index b6dd7f28..56399530 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ Then apply the config: kubectl apply -f deploy/all.yaml ``` + ## Options * `dashboard` Runs the webserver for Fairwinds dashboard. @@ -29,3 +30,12 @@ kubectl apply -f deploy/all.yaml * `disable-webhook-config-installer`: disable the installer in the webhook server, so it won't install webhook configuration resources during bootstrapping * `kubeconfig`: Paths to a kubeconfig. Only required if out-of-cluster. * `master`: The address of the Kubernetes API server. Overrides any value in kubeconfig. Only required if out-of-cluster. + +## Helm Deploy Option + +* Create release with Helm: +``` +helm upgrade --install fairwinds charts/fairwinds/ --namespace fairwinds --recreate-pods +kubectl port-forward --namespace fairwinds svc/fairwinds-fairwinds-dashboard 8080:80 & +open http://localhost:8080 +``` diff --git a/charts/fairwinds/Chart.yaml b/charts/fairwinds/Chart.yaml new file mode 100755 index 00000000..601908ae --- /dev/null +++ b/charts/fairwinds/Chart.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +description: Validation of best practices in your Kubernetes clusters +name: fairwinds +version: 0.1.0 diff --git a/charts/fairwinds/templates/NOTES.txt b/charts/fairwinds/templates/NOTES.txt new file mode 100644 index 00000000..9c12a4a8 --- /dev/null +++ b/charts/fairwinds/templates/NOTES.txt @@ -0,0 +1,12 @@ +** Please be patient while the chart is being deployed ** + +Enjoy Fairwinds and smooth sailing! + +{{- if contains "ClusterIP" .Values.dashboard.service.type }} + +## To view the dashboard execute these commands: + +kubectl port-forward --namespace {{ .Release.Namespace }} svc/{{ template "fullname" . }}-dashboard 8080:80 & +open http://localhost:8080 + +{{- end }} diff --git a/charts/fairwinds/templates/_helpers.tpl b/charts/fairwinds/templates/_helpers.tpl new file mode 100644 index 00000000..234480de --- /dev/null +++ b/charts/fairwinds/templates/_helpers.tpl @@ -0,0 +1,16 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 24 -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +We truncate at 24 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). +*/}} +{{- define "fullname" -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 24 -}} +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds-dash.svc.yaml b/charts/fairwinds/templates/fairwinds-dash.svc.yaml new file mode 100644 index 00000000..cf209fc9 --- /dev/null +++ b/charts/fairwinds/templates/fairwinds-dash.svc.yaml @@ -0,0 +1,19 @@ +{{- if .Values.dashboard.service -}} +apiVersion: v1 +kind: Service +metadata: + labels: + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}-dashboard' +spec: + ports: + - name: dashboard + port: 80 + protocol: TCP + targetPort: 8080 + selector: + app: '{{.Release.Name}}' + type: '{{.Values.dashboard.service.type}}' +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds.clusterrole.yaml b/charts/fairwinds/templates/fairwinds.clusterrole.yaml new file mode 100644 index 00000000..0177b444 --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.clusterrole.yaml @@ -0,0 +1,20 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRole +metadata: + labels: + app: '{{.Release.Name}}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}' +rules: + - apiGroups: + - '' + - 'apps' + - 'admissionregistration.k8s.io' + resources: + - '*' + verbs: + - '*' +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds.clusterrolebinding.yaml b/charts/fairwinds/templates/fairwinds.clusterrolebinding.yaml new file mode 100644 index 00000000..efd8ad84 --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.clusterrolebinding.yaml @@ -0,0 +1,19 @@ +{{- if .Values.rbac.create -}} +apiVersion: rbac.authorization.k8s.io/v1beta1 +kind: ClusterRoleBinding +metadata: + labels: + app: '{{.Release.Name}}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}' +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: '{{ template "fullname" . }}' +subjects: + - kind: ServiceAccount + name: '{{ template "fullname" . }}' + namespace: '{{.Release.Namespace}}' +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds.configmap.yaml b/charts/fairwinds/templates/fairwinds.configmap.yaml new file mode 100644 index 00000000..d4adbdaf --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.configmap.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + labels: + app: '{{ template "fullname" . }}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}' +data: + config.yml: {{- toYaml .Values.config | indent 2 -}} diff --git a/charts/fairwinds/templates/fairwinds.deployment-dashboard.yaml b/charts/fairwinds/templates/fairwinds.deployment-dashboard.yaml new file mode 100644 index 00000000..bc6222bc --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.deployment-dashboard.yaml @@ -0,0 +1,64 @@ +{{- if .Values.dashboard.enable -}} +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + checksum/config: '{{ include (print $.Template.BasePath "/fairwinds.configmap.yaml") . | sha256sum }}' + labels: + app: '{{.Release.Name}}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}-dashboard' +spec: + replicas: {{.Values.dashboard.replicas}} + selector: + matchLabels: + app: '{{.Release.Name}}' + template: + metadata: + labels: + app: '{{.Release.Name}}' + spec: + volumes: + - configMap: + name: '{{ template "fullname" . }}' + name: '{{ template "fullname" . }}' + - name: certs + secret: + secretName: '{{ template "fullname" . }}' + containers: + - command: + - fairwinds + - --dashboard + image: '{{.Values.webhook.image.repository}}:{{.Values.webhook.image.tag}}' + imagePullPolicy: '{{.Values.webhook.image.pullPolicy}}' + name: dashboard + ports: + - containerPort: 8080 + livenessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 5 + periodSeconds: 5 + readinessProbe: + httpGet: + path: / + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + volumeMounts: + - mountPath: /opt/app/config.yml + name: '{{ template "fullname" . }}' + readOnly: true + subPath: config.yml + serviceAccountName: '{{ template "fullname" . }}' +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds.deployment-webook.yaml b/charts/fairwinds/templates/fairwinds.deployment-webook.yaml new file mode 100644 index 00000000..32537440 --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.deployment-webook.yaml @@ -0,0 +1,67 @@ +{{- if .Values.webhook.enable -}} +apiVersion: extensions/v1beta1 +kind: Deployment +metadata: + annotations: + checksum/config: '{{ include (print $.Template.BasePath "/fairwinds.configmap.yaml") . | sha256sum }}' + labels: + app: '{{.Release.Name}}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}-webhook' +spec: + replicas: {{.Values.webhookreplicas}} + selector: + matchLabels: + app: '{{.Release.Name}}' + template: + metadata: + labels: + app: '{{.Release.Name}}' + spec: + volumes: + - configMap: + name: '{{ template "fullname" . }}' + name: '{{ template "fullname" . }}' + - name: certs + secret: + secretName: '{{ template "fullname" . }}' + containers: + - command: + - fairwinds + - --webhook + image: '{{.Values.webhook.image.repository}}:{{.Values.webhook.image.tag}}' + imagePullPolicy: '{{.Values.webhook.image.pullPolicy}}' + name: webhook + ports: + - containerPort: 9876 + livenessProbe: + exec: + command: + - sh + - -c + - ps -ef | grep fairwinds + initialDelaySeconds: 5 + periodSeconds: 5 + readinessProbe: + tcpSocket: + port: 8080 + initialDelaySeconds: 15 + periodSeconds: 20 + resources: + limits: + cpu: 100m + memory: 128Mi + requests: + cpu: 100m + memory: 128Mi + volumeMounts: + - mountPath: /tmp/cert/ + name: certs + - mountPath: /opt/app/config.yml + name: '{{ template "fullname" . }}' + readOnly: true + subPath: config.yml + serviceAccountName: '{{ template "fullname" . }}' +{{- end -}} diff --git a/charts/fairwinds/templates/fairwinds.secret.yaml b/charts/fairwinds/templates/fairwinds.secret.yaml new file mode 100644 index 00000000..bf89a33b --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.secret.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: Secret +metadata: + labels: + app: '{{ template "fullname" . }}' + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}' +type: opaque +data: diff --git a/charts/fairwinds/templates/fairwinds.serviceaccount.yaml b/charts/fairwinds/templates/fairwinds.serviceaccount.yaml new file mode 100644 index 00000000..e18624d2 --- /dev/null +++ b/charts/fairwinds/templates/fairwinds.serviceaccount.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + chart: '{{.Chart.Name}}-{{.Chart.Version}}' + heritage: '{{.Release.Service}}' + release: '{{.Release.Name}}' + name: '{{ template "fullname" . }}' diff --git a/charts/fairwinds/values.yaml b/charts/fairwinds/values.yaml new file mode 100644 index 00000000..79767ce3 --- /dev/null +++ b/charts/fairwinds/values.yaml @@ -0,0 +1,96 @@ +--- +config: | + resources: + cpuRequestsMissing: warning + cpuRequestRanges: + warning: + below: 50m + above: 1000m + error: + below: 500m + above: 2000m + cpuLimitsMissing: warning + cpuLimitRanges: + warning: + below: 50m + above: 1000m + error: + below: 500m + above: 2000m + memoryRequestsMissing: warning + memoryRequestRanges: + warning: + below: 50M + above: 2G + error: + below: 100M + above: 4G + memoryLimitsMissing: warning + memoryLimitRanges: + warning: + below: 50M + above: 2G + error: + below: 100M + above: 4G + images: + tagNotSpecified: error + pullPolicyNotAlways: warning + whitelist: + error: + - gcr.io/* + blacklist: + warning: + - docker.io/* + healthChecks: + readinessProbeMissing: warning + livenessProbeMissing: warning + networking: + hostAliasSet: error + hostIPCSet: error + hostNetworkSet: error + hostPIDSet: error + hostPortSet: error + security: + runAsPriviliged: warning + notReadOnlyRootFileSystem: warning + runAsNonRoot: warning + capabilities: + blacklist: + error: + - CHOWN + - SYS_CHROOT + - AUDIT_WRITE + whitelist: + warning: + - CHOWN + - DAC_OVERRIDE + - FSETID + - FOWNER + - MKNOD + - NET_RAW + - SETGID + - SETUID + - SETFCAP + - SETPCAP + - NET_BIND_SERVICE + - SYS_CHROOT + - KILL + - AUDIT_WRITE +dashboard: + enable: true + service: + type: ClusterIP + image: + repository: quay.io/reactiveops/fairwinds + tag: dev-80b331447bdaebe1cd0191a165e8d4c1cdaa2e60 + pullPolicy: IfNotPresent +webhook: + enable: false + image: + repository: quay.io/reactiveops/fairwinds + tag: dev-80b331447bdaebe1cd0191a165e8d4c1cdaa2e60 + pullPolicy: IfNotPresent +replicas: 1 +rbac: + create: true