Unverified Commit 69633027 authored by Jennifer Moore's avatar Jennifer Moore Committed by GitHub

feat: [influxdb3-clustered] add the initial chart (#634)

* feat: [influxdb3-clustered] add the initial chart * chore: [influxdb3-clustered] full url to maintainer team * chore: [influxdb3-clustered] full url to maintainer team * chore: [influxdb3-clustered] full url to maintainer team * chore: [influxdb3-clustered] add team email * chore: [influxdb3-clustered] use a real github user * fix[infludb3-clustered]: remove optional ingress config from default values * fix[infludb3-clustered]: remove optional ingress config from default values
parent 7df1768a
# 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/
apiVersion: v2
type: application
version: 0.1.0
appVersion: "20240326-922145"
name: influxdb3-clustered
description: InfluxDB 3.0 Clustered
maintainers:
- name: jenniferplusplus
email: team-clustered@influxdata.com
url: https://github.com/orgs/influxdata/teams/project-clustered
keywords:
- influxdb
- influxdb3
- database
- timeseries
- influxdata
home: https://www.influxdata.com/products/influxdb-clustered/
sources:
- https://github.com/influxdata/influxdb
# InfluxDB 3.0 Clustered
## Quick Start
```shell
helm repo add influxdata https://helm.influxdata.com/
helm upgrade --install influxdb influxdata/influxdb3-clustered -f values.yml --namespace influxdb
```
## Introduction
[InfluxDB](https://github.com/influxdata/influxdb) is an open source time series database written in Rust, using Apache Arrow, Apache Parquet, and Apache DataFusion as its foundational building blocks. [InfluxDB Clustered](https://www.influxdata.com/products/influxdb-clustered/) is the evolution of InfluxDB Enterprise, making it the solution for enterprises that need control over their data and underlying infrastructure.
## Installing the Chart
InfluxDB depends on a small number of external services, and these must be configured in your values file. See the [InfludDB Clustered documentation](https://docs.influxdata.com/influxdb/clustered/) for a detailed configuration guide.
To install the chart using the release name `my-release`:
```shell
helm upgrade --install my-release influxdata/influxdb3-clustered -f values.yml
```
InfluxDB Clustered is a complex distributed database, composed of numerous interconnected resources. These resources are managed using the [Kubit operator](https://github.com/kubecfg/kubit/). This helm chart will install that operator and the InfluxDB Clustered AppInstance resource, which encapsulates all of the resources and configuration for the database. Helm cannot be used to bypass the Kubit operator. If you cannot install the operator, then please consult the documentation for alternatives.
## Adopting existing resources into Helm
To allow Helm to take over managing an InfluxDB Clustered AppInstance resource, you must set some helm specific metadata on it, first. Otherwise, Helm will refuse to perform the installation or upgrade. This is a safety feature built into Helm, and is by design.
1. If you have installed the Kubit operator in its own namespace, set `skipOperator: true` in your values file. Normally, the InfluxDB 3.0 Clustered helm chart will deploy the Kubit operator along with the AppInstance resource, as a convenience. However, there's no clear mechanism to adopt existing resources from multiple namespaces into a single helm chart. So you can instead exclude the operator so it will not be managed by Helm.
2. Set your Helm values to match your existing configuration. We recommend using `helm template` to preview the generated resources and diff those against your deployed versions. Replace `DEPLOYMENT-NAME` and `NAMESPACE` to match your existing resources.
```shell
helm template DEPLOYMENT-NAME ./clustered-chart/ -f ./values.yml --namespace NAMESPACE | kubectl diff -f -
```
The AppInstance resource is a little bit more flexible than the Helm template, so there may be some small differences between them that do not actually impact the deployment. It's still best to minimize those differences, which may require updating the existing AppInstance resource slightly to more closely match the resource manifest generated by helm.
3. When you have matched your existing configuration, set the required metadata on your existing AppInstance. Replace `<NAME>` and `<NAMESPACE>` to match your existing resource's name and namespace.
```shell
kubectl label -f example-customer.yml app.kubernetes.io/managed-by=Helm
kubectl annotate -f example-customer.yml meta.helm.sh/release-name=<NAME> meta.helm.sh/release-namespace=<NAMESPACE>
```
4. Helm should now be able to manage the Clustered AppInstance resource. Again, replace `DEPLOYMENT-NAME` and `NAMESPACE` with the appropriate values to match your existing deployment.
```shell
helm install DEPLOYMENT-NAME ./clustered-chart/ -f values.yml --namespace NAMESPACE
```
The expected output will look similar to this, depending on your specific configuration.
```
NAME: clustered
LAST DEPLOYED: Wed Apr 10 17:01:11 2024
NAMESPACE: NAMESPACE
STATUS: deployed
REVISION: 3
TEST SUITE: None
NOTES:
Thank you for installing InfluxDB 3.0 Clustered
Your release is named DEPLOYMENT-NAME
You are running build number 20240326-922145
Our documentation is available at https://docs.influxdata.com/influxdb/clustered/
```
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: appinstances.kubecfg.dev
spec:
group: kubecfg.dev
names:
categories: []
kind: AppInstance
plural: appinstances
shortNames: []
singular: appinstance
scope: Namespaced
versions:
- additionalPrinterColumns: []
name: v1alpha1
schema:
openAPIV3Schema:
description: Auto-generated derived type for AppInstanceSpec via `CustomResource`
properties:
spec:
properties:
imagePullSecrets:
items:
description: LocalObjectReference contains enough information to
let you locate the referenced object inside the same namespace.
properties:
name:
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names'
type: string
type: object
nullable: true
type: array
package:
properties:
apiVersion:
type: string
image:
type: string
spec:
type: object
x-kubernetes-preserve-unknown-fields: true
required:
- apiVersion
- image
- spec
type: object
pause:
description: If true, the controller will not reconcile this application.
You can use this if you need to do some manual changes (either with
kubectl directly or with kubit CLI)
type: boolean
required:
- package
type: object
status:
nullable: true
properties:
conditions:
items:
properties:
lastTransitionTime:
description: Time is a wrapper around time.Time which supports
correct marshaling to YAML and JSON. Wrappers are provided
for many of the factory methods that the time package offers.
format: date-time
type: string
message:
type: string
observedGeneration:
format: int64
nullable: true
type: integer
reason:
type: string
status:
type: string
type:
type: string
required:
- lastTransitionTime
- message
- reason
- status
- type
type: object
type: array
lastLogs:
additionalProperties:
type: string
nullable: true
type: object
type: object
required:
- spec
title: AppInstance
type: object
served: true
storage: true
subresources:
status: {}
\ No newline at end of file
Thank you for installing {{ .Chart.Description }}
Your release is named {{ .Release.Name }}
You are running build number {{ .Chart.AppVersion }}
Our documentation is available at https://docs.influxdata.com/influxdb/clustered/
\ No newline at end of file
{{/*
Expand the name of the chart.
*/}}
{{- define "chart.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 "chart.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 "chart.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "chart.labels" -}}
helm.sh/chart: {{ include "chart.chart" . }}
{{ include "chart.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "chart.selectorLabels" -}}
app.kubernetes.io/name: {{ include "chart.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "chart.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "chart.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
apiVersion: kubecfg.dev/v1alpha1
kind: AppInstance
metadata:
name: {{.Values.nameOverride | default .Release.Name}}
namespace: {{.Values.namespaceOverride | default .Release.Namespace}}
spec:
imagePullSecrets: {{.Values.imagePullSecrets | toYaml | nindent 2}}
package:
image: "{{.Values.fullnameOverride | default "us-docker.pkg.dev/influxdb2-artifacts/clustered/influxdb"}}:{{ .Values.image.tag | default .Chart.AppVersion }}"
apiVersion: influxdata.com/v1alpha1
spec:
{{- if .Values.hostingEnvironment}}
hostingEnvironment:
{{- if hasKey .Values.hostingEnvironment "eks"}}
eks: {{.Values.hostingEnvironment.eks | include "mapTrim" | trim | nindent 10}}
{{- else if hasKey .Values.hostingEnvironment "openshift"}}
openshift: {{.Values.hostingEnvironment.openshift | include "mapTrim" | trim | nindent 10}}
{{- else if hasKey .Values.hostingEnvironment "gke"}}
gke: {{.Values.hostingEnvironment.gke | include "mapTrim" | trim | nindent 10}}
{{- end }}
{{- end}}
catalog:
dsn:
valueFrom:
secretKeyRef:
name: {{(required "missing catalog.dsn.SecretName" .Values.catalog.dsn.SecretName)}}
key: {{required "missing catalog.dsn.SecretKey" .Values.catalog.dsn.SecretKey}}
{{- if or .Values.images.overrides .Values.images.registryOverride}}
images:
{{- if .Values.images.overrides}}
overrides: {{.Values.images.overrides}}
{{- end}}
{{- if .Values.images.registryOverride}}
registryOverride: {{.Values.images.registryOverride}}
{{- end}}
{{- end}}
objectStore:
bucket: {{required "missing objectStore.bucket" .Values.objectStore.bucket}}
{{- if hasKey .Values.objectStore "s3"}}
s3: {{- .Values.objectStore.s3 | include "mapTrim" | trim | nindent 10 }}
{{- else if hasKey .Values.objectStore "azure"}}
azure: {{- .Values.objectStore.azure | include "mapTrim" | trim | nindent 10}}
{{- else if hasKey .Values.objectStore "google"}}
google: {{- .Values.objectStore.google | include "mapTrim" | trim | nindent 10}}
{{- end}}
ingesterStorage:{{.Values.ingesterStorage | include "mapTrim" | trim | nindent 8}}
monitoringStorage:{{.Values.monitoringStorage | include "mapTrim" | trim | nindent 8}}
ingress:{{- .Values.ingress | include "mapTrim" | trim | nindent 8 -}}
{{- $components := (.Values.components | include "mapTrim" | fromYaml)}}
{{- if $components}}
components:{{$components | toYaml | trim | nindent 8}}
{{- end}}
{{- $resources := (.Values.resources | include "mapTrim" | fromYaml)}}
{{- if $resources}}
resources:{{$resources | toYaml | trim | nindent 8}}
{{- end}}
admin:
users: {{required "missing admin.users" .Values.admin.users | toYaml | nindent 8}}
dsn: {{required "missing admin.dsn" .Values.admin.dsn | toYaml | nindent 10}}
identityProvider: {{required "missing admin.identityProvider" .Values.admin.identityProvider}}
jwksEndpoint: {{required "missing admin.jwksEndpoint" .Values.admin.jwksEndpoint}}
{{- if .Values.useCustomEgress}}
egress:
customCertificates: {{.Values.egress.customCertificates | toYaml | nindent 12}}
{{- end}}
{{- if .Values.featureFlags}}
featureFlags: {{.Values.featureFlags | toYaml | nindent 6}}
{{- end}}
\ No newline at end of file
{{- if not .Values.skipOperator}}
{{- if not .Values.kubitSingleNamespace}}
apiVersion: v1
kind: Namespace
metadata:
labels:
app.kubernetes.io/component: manager
app.kubernetes.io/instance: kubit
app.kubernetes.io/name: namespace
app.kubernetes.io/part-of: kubit
control-plane: kubit
name: kubit
---
{{- end}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: kubit
namespace: {{if .Values.kubitSingleNamespace}}{{.Values.namespaceOverride | default .Release.Namespace}}{{else}}kubit{{end}}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{if .Values.kubitSingleNamespace}}Role{{else}}ClusterRole{{end}}
metadata:
name: kubit
rules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- create
- update
- get
- list
- patch
- watch
- delete
---
apiVersion: rbac.authorization.k8s.io/v1
kind: {{if .Values.kubitSingleNamespace}}RoleBinding{{else}}ClusterRoleBinding{{end}}
metadata:
name: kubit
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: {{if .Values.kubitSingleNamespace}}Role{{else}}ClusterRole{{end}}
name: kubit
subjects:
- kind: ServiceAccount
name: kubit
namespace: {{if .Values.kubitSingleNamespace}}{{.Values.namespaceOverride | default .Release.Namespace}}{{else}}kubit{{end}}
---
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app.kubernetes.io/component: manager
app.kubernetes.io/instance: kubit
app.kubernetes.io/name: deployment
app.kubernetes.io/part-of: kubit
control-plane: kubit
name: kubit
namespace: {{if .Values.kubitSingleNamespace}}{{.Values.namespaceOverride | default .Release.Namespace}}{{else}}kubit{{end}}
spec:
replicas: 1
selector:
matchLabels:
control-plane: kubit
strategy:
rollingUpdate:
maxSurge: 0
maxUnavailable: 1
type: RollingUpdate
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: manager
labels:
control-plane: kubit
spec:
containers:
- env:
{{- if not .Values.kubitSingleNamespace}}
- name: KUBIT_WATCHED_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
{{- end}}
- name: KUBIT_CONTROLLER_IMAGE
value: "{{.Values.operatorImageOverride | default "ghcr.io/kubecfg/kubit"}}:{{.Values.operatorImageVersion}}"
image: "{{.Values.operatorImageOverride | default "ghcr.io/kubecfg/kubit"}}:{{.Values.operatorImageVersion}}"
livenessProbe:
httpGet:
path: /live
port: 8080
initialDelaySeconds: 15
periodSeconds: 20
name: manager
readinessProbe:
httpGet:
path: /ready
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 128Mi
requests:
cpu: 10m
memory: 64Mi
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
securityContext:
seccompProfile:
type: RuntimeDefault
serviceAccountName: kubit
terminationGracePeriodSeconds: 10
{{end}}
\ No newline at end of file
{{/*
mapTrim will recurse through a map and render it to a template string, without any null or empty values
As a named template partial, mapTrim can only render a result, it cannot modify the larger
context.
for example, let's call this object $map
hello: world
goodnight: moon
never-gonna-give:
you-up:
luke:
i-am: your father
join-me:
running mapTrim over that context would strip out the empty values and generate formatted yml (modulo a blank line)
so typical usage would look like
trimmed:{{$map | include "mapTrim" | trim | nindent 2}}
and the final result would be
trimmed:
hello: world
goodnight: moon
luke:
i-am: your father
*/}}
{{- define "mapTrim" }}
{{- $map := . -}}
{{- if not (kindIs "map" $map) }}{{fail "mapTrim requires a map"}}{{- end}}
{{- range $key, $val := $map -}}
{{- if kindIs "map" $val -}}
{{- if ($val | include "mapTrim" | fromYaml)}}
{{- (dict $key ($val | include "mapTrim" | fromYaml)) | toYaml | nindent 0 -}}
{{- end}}
{{- else if empty $val}}
{{- else}}
{{- (dict $key $val) | toYaml | nindent 0 -}}
{{- end}}
{{- end}}
{{- end}}
\ No newline at end of file
image:
# Overrides the InfluxDb Clustered OCI image tag
tag: ""
imagePullSecrets:
- name: "gar-docker-secret"
nameOverride: ""
namespaceOverride: ""
fullnameOverride: ""
kubitSingleNamespace: false
operatorImageVersion: "v0.0.14"
operatorImageOverride: ""
# set to true if you have previously installed the kubit operator from another source
skipOperator: false
hostingEnvironment: {}
# eks:
# eksRoleArn: "" # "arn:aws:iam::111111111111:role/your-influxdb-clustered-role"
# # Note: there are currently no OpenShift-specific parameters. The empty object is still required for proper function
# openshift: {}
# # Note: This setting just enables GKE specific authentication mechanism.
# # You still need to select objectStore.objectStoreApi: 'google' below if you want to use GCS.
# gke:
# workloadIdentity:
# serviceAccountEmail: "" # "service-account@project-name.iam.gserviceaccount.com"
catalog:
# secret name and key within the secret containing the dsn string to connect to the catalog
dsn:
# Kubernetes Secret name containing the dsn for the catalog.
SecretName: ""
# The key within the Secret containing the dsn.
SecretKey: ""
images:
# This can be used to override a specific image name with its FQIN
# (Fully Qualified Image Name) for testing. eg.
overrides: []
# - name: influxdb2-artifacts/iox/iox
# newFQIN: mycompany/test-iox-build:aninformativetag
# Set this variable to the prefix of your internal registry. This will be prefixed to all expected images.
# eg. us-docker.pkg.dev/iox:latest => registry.mycompany.io/us-docker.pkg.dev/iox:latest
registryOverride:
objectStore:
# Bucket that the parquet files will be stored in
bucket: ""
# (Required) Provide one of the following (s3, azure, google)
# to configure your object store
# s3:
# # URL for S3 Compatible object store
# endpoint: ""
#
# # Set to true to allow communication over HTTP (instead of HTTPS)
# allowHttp: "false"
#
# # S3 Access Key
# # This can also be provided as a valueFrom: secretKeyRef:
# accessKey:
# value: ""
#
# # S3 Secret Key
# # This can also be provided as a value:
# secretKey:
# valueFrom:
# secretKeyRef: ""
#
# # This value is required for AWS S3, it may not be required for other providers and can be omitted in that case.
# region: ""
#
# azure:
# # Azure Blob Storage Access Key
# # This can also be provided as a value:
# accessKey:
# valueFrom:
# secretKeyRef: "" # azure-access-key
#
# # Azure Blob Storage Account
# # This can also be provided as a valueFrom: secretKeyRef:
# account:
# value: ""
#
# google:
# # This section is not needed if you are using GKE Workload Identity. It is only required to use explicit
# # service account secrets (JSON files)
# serviceAccountSecret:
# # Kubernetes Secret name containing the credentials for a Google IAM Service Account.
# name: ""
# # The key within the Secret containing the credentials.
# key: ""
ingesterStorage:
# (Optional) Set the storage class. This will differ based on the K8s environment and desired storage characteristics.
# If not set, the default storage class will be used.
storageClassName: null
# Set the storage size (minimum 2Gi recommended)
storage: "2Gi"
monitoringStorage:
# Set the storage size (minimum 1Gi recommended)
storage: "1Gi"
# (Optional) Set the storage class. This will differ based on the K8s environment and desired storage characteristics.
# If not set, the default storage class will be used.
storageClassName: null
# (Optional)
# We currently only support the ingress NGINX ingress controller: https://github.com/kubernetes/ingress-nginx
ingress:
hosts:
# This is the host on which you will access Influxdb 3.0, for both reads and writes
- ""
# # (Optional)
# # The name of the Kubernetes Secret containing a TLS certificate, this should exist in the same namespace as the Clustered installation.
# # If you are using cert-manager, enter a name for the Secret it should create.
# tlsSecretName: ""
# # (Optional)
# # Usually you have only one ingress controller installed in a given cluster.
# # In case you have more than one, you have to specify the "class name" of the ingress controller you want to use
# http:
# className: nginx
# grpc:
# className: nginx
# (Optional)
# Enables specifying which 'type' of Ingress to use, alongside whether to place additional annotations
# onto those objects, this is useful for third party software in your environment, such as cert-manager.
template:
# Customizations for the InfluxDB component resources
# Use this to set custom metadata, nodeSelector, tolerations, or modify logging filter levels
components:
router:
log:
# #for example
# filters:
# - 'router::gossip=info'
# - 'debug'
template:
# #for example
# nodeSelector:
# disktype: ssd
# tolerations:
# - effect: NoSchedule
# key: example
# operator: Exists
ingester:
log:
template:
querier:
log:
template:
compactor:
log:
template:
common:
log:
template:
# #for example
# metadata:
# annotations:
# 'example.com/on-call': 'sre-team@example.com'
# Tune the cpu/memory/replicas used by InfluxDb components, based on the needs of your workload
# (see https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits)
resources:
# The ingester handles data being written
ingester:
requests:
limits:
# The compactor reorganizes old data to improve query and storage efficiency.
compactor:
requests:
limits:
# The querier handles querying data.
querier:
requests:
limits:
# The router performs some api routing.
router:
requests:
limits:
admin:
# The list of users to grant access to Clustered via influxctl
users:
- firstName: ""
lastName: ""
email: ""
# The ID as given by the OAuth Identity Provider
id: ""
# The dsn for the postgres compatible database (note this is the same as defined above)
dsn:
valueFrom:
secretKeyRef:
name: ""
key: ""
# The identity provider to be used e.g. "keycloak", "auth0", "azure", etc
# Note for Azure Active Directory it must be exactly "azure"
identityProvider: ""
# The JWKS endpoint provided by the Identity Provider
jwksEndpoint: ""
# (Optional)
useCustomEgress: false
egress:
# # If you're using a custom CA you will need to specify the full custom CA bundle here.
# #
# # NOTE: the custom CA is currently only honoured for outbound requests used to obtain
# # the JWT public keys from your identiy provider (see `jwksEndpoint`).
customCertificates:
valueFrom:
configMapKeyRef:
key: ""
name: ""
# This can be used to enable certain features that are still in testing
featureFlags: []
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment