From e71ae4a9ec4094d584ec5b935408f702235620a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Moritz=20=22WanzenBug=22=20Wanzenb=C3=B6ck?= Date: Thu, 21 Jul 2022 10:59:14 +0200 Subject: [PATCH] piraeus-ha-controller: add first chart version MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Moritz "WanzenBug" Wanzenböck --- README.md | 1 + charts/piraeus-ha-controller/.helmignore | 23 ++ charts/piraeus-ha-controller/Chart.yaml | 18 ++ charts/piraeus-ha-controller/LICENSE | 202 ++++++++++++++++++ charts/piraeus-ha-controller/README.md | 196 +++++++++++++++++ .../piraeus-ha-controller/templates/NOTES.txt | 14 ++ .../templates/_helpers.tpl | 62 ++++++ .../templates/daemonset.yaml | 65 ++++++ .../piraeus-ha-controller/templates/rbac.yaml | 82 +++++++ .../templates/serviceaccount.yaml | 12 ++ charts/piraeus-ha-controller/values.yaml | 57 +++++ 11 files changed, 732 insertions(+) create mode 100644 charts/piraeus-ha-controller/.helmignore create mode 100644 charts/piraeus-ha-controller/Chart.yaml create mode 100644 charts/piraeus-ha-controller/LICENSE create mode 100644 charts/piraeus-ha-controller/README.md create mode 100644 charts/piraeus-ha-controller/templates/NOTES.txt create mode 100644 charts/piraeus-ha-controller/templates/_helpers.tpl create mode 100644 charts/piraeus-ha-controller/templates/daemonset.yaml create mode 100644 charts/piraeus-ha-controller/templates/rbac.yaml create mode 100644 charts/piraeus-ha-controller/templates/serviceaccount.yaml create mode 100644 charts/piraeus-ha-controller/values.yaml diff --git a/README.md b/README.md index 952f0f6..72e5d3b 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ A collection of helpful charts for Piraeus and other projects. * [snapshot controller](./charts/snapshot-controller) deploys a snapshot controller for CSI snapshots. * [snapshot validation webhook](./charts/snapshot-validation-webhook) offers stricter validation of snapshot resources. * [linstor-scheduler](./charts/linstor-scheduler) offers smart scheduling for Pods using LINSTOR volumes. +* [piraeus-ha-controller](./charts/piraeus-ha-controller) enabled faster fail-over of workloads when using Piraeus volumes. ### Contributing diff --git a/charts/piraeus-ha-controller/.helmignore b/charts/piraeus-ha-controller/.helmignore new file mode 100644 index 0000000..0e8a0eb --- /dev/null +++ b/charts/piraeus-ha-controller/.helmignore @@ -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/ diff --git a/charts/piraeus-ha-controller/Chart.yaml b/charts/piraeus-ha-controller/Chart.yaml new file mode 100644 index 0000000..f01c7f8 --- /dev/null +++ b/charts/piraeus-ha-controller/Chart.yaml @@ -0,0 +1,18 @@ +apiVersion: v2 +name: piraeus-ha-controller +description: | + Deploys the Piraeus High Availability Controller. Using DRBD quorum, the controller speeds up fail over of stateful + workloads in case of storage interruptions. +type: application +icon: https://raw.githubusercontent.com/piraeusdatastore/piraeus/master/artwork/sandbox-artwork/icon/color.svg +maintainers: + - name: The Piraeus Maintainers + url: https://github.com/piraeusdatastore/ +keywords: + - storage +home: https://github.com/piraeusdatastore/helm-charts +sources: + - https://github.com/piraeusdatastore/piraeus-ha-controller + +version: 1.0.1 +appVersion: "v1.0.1" diff --git a/charts/piraeus-ha-controller/LICENSE b/charts/piraeus-ha-controller/LICENSE new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/charts/piraeus-ha-controller/LICENSE @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/charts/piraeus-ha-controller/README.md b/charts/piraeus-ha-controller/README.md new file mode 100644 index 0000000..6610497 --- /dev/null +++ b/charts/piraeus-ha-controller/README.md @@ -0,0 +1,196 @@ +# Piraeus High Availability Controller + +[![GitHub release (latest by date)](https://img.shields.io/github/v/release/piraeusdatastore/piraeus-ha-controller)](https://github.com/piraeusdatastore/piraeus-ha-controller/releases) +![tests](https://github.com/piraeusdatastore/piraeus-ha-controller/workflows/tests/badge.svg) + +The Piraeus High Availability Controller will speed up the fail-over process for stateful workloads using [Piraeus] for +storage. + +[Piraeus]: https://piraeus.io + +## Usage + +First, ensure you have Piraeus/LINSTOR installed with a recent version of DRBD (>9.1.7). + +Then install this chart: + +``` +helm repo add piraeus-charts https://piraeus.io/helm-charts/ +helm install piraeus-ha-controller piraeus-charts/piraeus-ha-controller +``` + +The high availability controller will automatically watch all pods and volumes and start the fail-over process +should it detect any issues. + +We recommend using the following settings in your StorageClass, to take full advantage of the HA Controller: + +``` +parameters: + property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: suspend-io + property.linstor.csi.linbit.com/DrbdOptions/Resource/on-no-data-accessible: suspend-io + property.linstor.csi.linbit.com/DrbdOptions/Resource/on-suspended-primary-outdated: force-secondary + property.linstor.csi.linbit.com/DrbdOptions/Net/rr-conflict: retry-connect +``` + +### Options + +The Piraeus High Availability Controller itself can be configured using the following flags: + +``` +--drbd-status-interval duration time between DRBD status updates (default 5s) +--fail-over-timeout duration timeout before starting fail-over process (default 5s) +--grace-period-seconds int default grace period for deleting k8s objects, in seconds (default 10) +--node-name string the name of node this is running on. defaults to the NODE_NAME environment variable (default "n2.k8s-mwa.at.linbit.com") +--operations-timeout duration default timeout for operations (default 1m0s) +--reconcile-interval duration maximum interval between reconciliation attempts (default 5s) +--request-timeout string The length of time to wait before giving up on a single server request. Non-zero values should contain a corresponding time unit (e.g. 1s, 2m, 3h). A value of zero means don't timeout requests. (default "0") +--resync-interval duration how often the internal object cache should be resynchronized (default 5m0s) +--v int32 set log level (default 0) +``` + +You can directly set them through the helm chart using the matching `options` value. + +## What resources are monitored? + +The Piraeus High Availability Controller will monitor and manage any Pod that is attached to at least one DRBD resource. + +For the HA Controller to work properly, you need quorum, i.e. at least 3 replicas (or 2 replicas + 1 tie-breaker diskless). +If using lower replica counts, attached Pods will be ignored and are not eligible for faster fail-over. + +If you want to mark a Pod as exempt from management by the HA Controller, add the following annotation to the Pod: + +``` +kubectl annotate pod drbd.linbit.com/ignore-fail-over="" +``` + +## What & Why? + +Let's say you are using Piraeus to provision your Kubernetes PersistentVolumes. You replicate your volumes across +multiple nodes in your cluster, so that even if a node crashes, a simple re-creation of the Pod will still have access +to the same data. + +### The Problem + +We have deployed our application as a StatefulSet to ensure only one Pod can access the PersistentVolume at a time, +even in case of node failures. + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus 1/1 Running 0 5m 172.31.0.1 node01.ha.cluster +``` + +Now we simulate our node crashing and wait for Kubernetes to recognize the node as unavailable + +``` +$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +master01.ha.cluster Ready master 12d v1.19.4 +master02.ha.cluster Ready master 12d v1.19.4 +master03.ha.cluster Ready master 12d v1.19.4 +node01.ha.cluster Ready compute 12d v1.19.4 +node02.ha.cluster Ready compute 12d v1.19.4 +node03.ha.cluster NotReady compute 12d v1.19.4 +``` + +We check our pod again: + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus-0 1/1 Running 0 10m 172.31.0.1 node01.ha.cluster +``` + +Nothing happened! That's because Kubernetes, by default, adds a 5-minute grace period before pods are evicted from +unreachable nodes. So we wait. + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus-0 1/1 Terminating 0 15m 172.31.0.1 node01.ha.cluster +``` + +Now our Pod is `Terminating`, but still nothing happens. You force delete the pod + +``` +$ kubectl delete pod my-stateful-app-with-piraeus-0 --force +warning: Immediate deletion does not wait for confirmation that the running resource has been terminated. The resource may continue to run on the cluster indefinitely. +pod "my-stateful-app-with-piraeus-0" force deleted +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus-0 0/1 ContainerCreating 0 5s 172.31.0.1 node02.ha.cluster +``` + +Still, nothing happens, the new Pod is assigned to a different node, but it cannot start. Why? Because Kubernetes thinks the old volume might still be attached + +``` +$ kubectl describe pod my-stateful-app-with-piraeus-0 +... +Events: + Type Reason Age From Message + ---- ------ ---- ---- ------- + Normal Scheduled default-scheduler Successfully assigned default/my-stateful-app-with-piraeus-0 to node02.ha.cluster + Warning FailedAttachVolume 28s attachdetach-controller Multi-Attach error for volume "pvc-9d991a74-0713-448f-ac0c-0b20b842763e" Volume is already exclusively at +tached to one node and can't be attached to another +``` + +This eventually times out, and we eventually our Pod will be running on another node. + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus-0 1/1 Running 0 5m 172.31.0.1 node02.ha.cluster +``` + +This process can take up to 15 minutes using the default settings of Kubernetes, or might not even complete at all. + +### The solution + +The Piraeus High Availability Controller can speed up this fail-over process significantly. As before, we start out with a running pod: + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus 1/1 Running 0 10s 172.31.0.1 node01.ha.cluster +``` + +Again, we simulate our node crashing and wait for Kubernetes to recognize the node as unavailable + +``` +$ kubectl get nodes +NAME STATUS ROLES AGE VERSION +master01.ha.cluster Ready master 12d v1.19.4 +master02.ha.cluster Ready master 12d v1.19.4 +master03.ha.cluster Ready master 12d v1.19.4 +node01.ha.cluster Ready compute 12d v1.19.4 +node02.ha.cluster Ready compute 12d v1.19.4 +node03.ha.cluster NotReady compute 12d v1.19.4 +``` + +We check our pod again. After a short wait (by default after around 10 seconds after the node "crashed"): + +``` +$ kubectl get pod -o wide +NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES +my-stateful-app-with-piraeus-0 0/1 ContainerCreating 0 3s 172.31.0.1 node02.ha.cluster +``` + +We see that the pod was rescheduled to another node. We can also take a look the cluster events: + +``` +$ kubectl get events --sort-by=.metadata.creationTimestamp -w +... +1s Warning NodeStorageQuorumLost node/node01.ha.cluster Tainted node because some volumes have lost quorum +1s Warning VolumeWithoutQuorum pod/suspend-example-57c5c67658-t94wz Pod was evicted because attached volume lost quorum +1s Warning VolumeWithoutQuorum volumeattachment/csi-fda9f57ce4csd... Volume attachment was force-detached because node lost quorum +... +``` + +### How? + +The Piraeus High Availability Controller monitors DRBD on every node by starting an agent on every node. When DRBD +reports a resource as promotable, there can't be any currently running Pods on other nodes using the volume. The +agents then check that assumption against the reported cluster state in Kubernetes. + +If there are Pods on other nodes that should be attached to the resource, the controller can conclude that those pods +need to be removed. These Pods can't do any writes, so it is safe to delete them. diff --git a/charts/piraeus-ha-controller/templates/NOTES.txt b/charts/piraeus-ha-controller/templates/NOTES.txt new file mode 100644 index 0000000..67be067 --- /dev/null +++ b/charts/piraeus-ha-controller/templates/NOTES.txt @@ -0,0 +1,14 @@ +Piraeus High Availability Controller successfully deployed. + +We recommend using the following parameters for your storage class: + + parameters: + property.linstor.csi.linbit.com/DrbdOptions/auto-quorum: suspend-io + property.linstor.csi.linbit.com/DrbdOptions/Resource/on-no-data-accessible: suspend-io + property.linstor.csi.linbit.com/DrbdOptions/Resource/on-suspended-primary-outdated: force-secondary + property.linstor.csi.linbit.com/DrbdOptions/Net/rr-conflict: retry-connect + +To exclude specific pods from automatic fail-over, use the following annotation: + + annotations: + drbd.linbit.com/ignore-fail-over="" diff --git a/charts/piraeus-ha-controller/templates/_helpers.tpl b/charts/piraeus-ha-controller/templates/_helpers.tpl new file mode 100644 index 0000000..11186a5 --- /dev/null +++ b/charts/piraeus-ha-controller/templates/_helpers.tpl @@ -0,0 +1,62 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "piraeus-ha-controller.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 "piraeus-ha-controller.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 "piraeus-ha-controller.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "piraeus-ha-controller.labels" -}} +helm.sh/chart: {{ include "piraeus-ha-controller.chart" . }} +{{ include "piraeus-ha-controller.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "piraeus-ha-controller.selectorLabels" -}} +app.kubernetes.io/name: {{ include "piraeus-ha-controller.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "piraeus-ha-controller.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "piraeus-ha-controller.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/charts/piraeus-ha-controller/templates/daemonset.yaml b/charts/piraeus-ha-controller/templates/daemonset.yaml new file mode 100644 index 0000000..371661f --- /dev/null +++ b/charts/piraeus-ha-controller/templates/daemonset.yaml @@ -0,0 +1,65 @@ +apiVersion: apps/v1 +kind: DaemonSet +metadata: + name: {{ include "piraeus-ha-controller.fullname" . }} + labels: + {{- include "piraeus-ha-controller.labels" . | nindent 4 }} +spec: + selector: + matchLabels: + {{- include "piraeus-ha-controller.selectorLabels" . | nindent 6 }} + template: + metadata: + {{- with .Values.podAnnotations }} + annotations: + {{- toYaml . | nindent 8 }} + {{- end }} + labels: + {{- include "piraeus-ha-controller.selectorLabels" . | nindent 8 }} + spec: + {{- with .Values.imagePullSecrets }} + imagePullSecrets: + {{- toYaml . | nindent 8 }} + {{- end }} + serviceAccountName: {{ include "piraeus-ha-controller.serviceAccountName" . }} + hostNetwork: true + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + containers: + - name: {{ .Chart.Name }} + args: + - /agent + {{- range $opt, $val := .Values.options }} + - --{{ $opt | kebabcase }}={{ $val }} + {{- end }} + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + resources: + {{- toYaml .Values.resources | nindent 12 }} + env: + - name: NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + startupProbe: + httpGet: + port: 8000 + path: /healthz + livenessProbe: + httpGet: + port: 8000 + path: /healthz + {{- with .Values.nodeSelector }} + nodeSelector: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.affinity }} + affinity: + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.tolerations }} + tolerations: + {{- toYaml . | nindent 8 }} + {{- end }} diff --git a/charts/piraeus-ha-controller/templates/rbac.yaml b/charts/piraeus-ha-controller/templates/rbac.yaml new file mode 100644 index 0000000..91f92fc --- /dev/null +++ b/charts/piraeus-ha-controller/templates/rbac.yaml @@ -0,0 +1,82 @@ +{{- if .Values.rbac.create }} +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: {{ include "piraeus-ha-controller.serviceAccountName" . }} + labels: + {{- include "piraeus-ha-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +rules: + - apiGroups: + - "" + resources: + - pods + verbs: + - get + - list + - watch + - delete + - apiGroups: + - events.k8s.io + resources: + - events + verbs: + - create + - patch + - apiGroups: + - "" + resources: + - pods/eviction + verbs: + - create + - apiGroups: + - "" + resources: + - nodes + verbs: + - get + - list + - watch + - patch + - update + - apiGroups: + - "" + resources: + - persistentvolumes + verbs: + - get + - list + - watch + - apiGroups: + - "storage.k8s.io" + resources: + - volumeattachments + verbs: + - get + - list + - watch + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: {{ include "piraeus-ha-controller.serviceAccountName" . }} + labels: + {{- include "piraeus-ha-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ include "piraeus-ha-controller.serviceAccountName" . }} +subjects: + - kind: ServiceAccount + name: {{ include "piraeus-ha-controller.serviceAccountName" . }} + namespace: {{ .Release.Namespace }} +{{- end }} diff --git a/charts/piraeus-ha-controller/templates/serviceaccount.yaml b/charts/piraeus-ha-controller/templates/serviceaccount.yaml new file mode 100644 index 0000000..a351935 --- /dev/null +++ b/charts/piraeus-ha-controller/templates/serviceaccount.yaml @@ -0,0 +1,12 @@ +{{- if .Values.serviceAccount.create -}} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ include "piraeus-ha-controller.serviceAccountName" . }} + labels: + {{- include "piraeus-ha-controller.labels" . | nindent 4 }} + {{- with .Values.serviceAccount.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} +{{- end }} diff --git a/charts/piraeus-ha-controller/values.yaml b/charts/piraeus-ha-controller/values.yaml new file mode 100644 index 0000000..055cda2 --- /dev/null +++ b/charts/piraeus-ha-controller/values.yaml @@ -0,0 +1,57 @@ +image: + repository: quay.io/piraeusdatastore/piraeus-ha-controller + pullPolicy: IfNotPresent + # Overrides the image tag whose default is the chart appVersion. + tag: "" + +imagePullSecrets: [ ] +nameOverride: "" +fullnameOverride: "" + +options: + v: 2 + #drbd-status-interval: 5s + #fail-over-timeout: 5s + #operations-timeout: 30s + #reconcile-interval: 5s + #resync-interval: 15m + #grace-period-seconds: 10 + +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: "" + +rbac: + # Specifies whether RBAC resources should be created + create: true + +podAnnotations: { } + +podSecurityContext: { } + +securityContext: + privileged: true + readOnlyRootFilesystem: true + +resources: + requests: + cpu: 50m + memory: 100Mi + +nodeSelector: { } + +tolerations: + - key: node-role.kubernetes.io/master + effect: NoSchedule + - key: node-role.kubernetes.io/control-plane + effect: NoSchedule + - key: drbd.linbit.com/lost-quorum + effect: NoSchedule + - key: drbd.linbit.com/force-io-error + effect: NoSchedule +affinity: { }