diff --git a/packages/apps/bucket/Chart.yaml b/packages/apps/bucket/Chart.yaml new file mode 100644 index 00000000..94b33a62 --- /dev/null +++ b/packages/apps/bucket/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +name: bucket +description: S3 compatible storage +icon: /logos/bucket.svg + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "0.1.0" diff --git a/packages/apps/bucket/Makefile b/packages/apps/bucket/Makefile new file mode 100644 index 00000000..207e2133 --- /dev/null +++ b/packages/apps/bucket/Makefile @@ -0,0 +1,2 @@ +generate: + readme-generator -v values.yaml -s values.schema.json -r README.md diff --git a/packages/apps/bucket/logos/bucket.svg b/packages/apps/bucket/logos/bucket.svg new file mode 100644 index 00000000..9f44da57 --- /dev/null +++ b/packages/apps/bucket/logos/bucket.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/apps/bucket/templates/bucketclaim.yaml b/packages/apps/bucket/templates/bucketclaim.yaml new file mode 100644 index 00000000..cebf95b4 --- /dev/null +++ b/packages/apps/bucket/templates/bucketclaim.yaml @@ -0,0 +1,20 @@ +{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }} +{{- $seaweedfs := index $myNS.metadata.annotations "namespace.cozystack.io/seaweedfs" }} +apiVersion: objectstorage.k8s.io/v1alpha1 +kind: BucketClaim +metadata: + name: {{ .Release.Name }} +spec: + bucketClassName: {{ $seaweedfs }} + protocols: + - s3 +--- +apiVersion: objectstorage.k8s.io/v1alpha1 +kind: BucketAccess +metadata: + name: {{ .Release.Name }} +spec: + bucketAccessClassName: {{ $seaweedfs }} + bucketClaimName: {{ .Release.Name }} + credentialsSecretName: {{ .Release.Name }} + protocol: s3 diff --git a/packages/apps/bucket/templates/dashboard-resourcemap.yaml b/packages/apps/bucket/templates/dashboard-resourcemap.yaml new file mode 100644 index 00000000..560d0d29 --- /dev/null +++ b/packages/apps/bucket/templates/dashboard-resourcemap.yaml @@ -0,0 +1,12 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ .Release.Name }}-dashboard-resources +rules: +- apiGroups: + - "" + resources: + - secrets + resourceNames: + - {{ .Release.Name }} + verbs: ["get", "list", "watch"] diff --git a/packages/apps/tenant/Chart.yaml b/packages/apps/tenant/Chart.yaml index f40c3a6e..baefc0e2 100644 --- a/packages/apps/tenant/Chart.yaml +++ b/packages/apps/tenant/Chart.yaml @@ -4,4 +4,4 @@ description: Separated tenant namespace icon: /logos/tenant.svg type: application -version: 1.3.1 +version: 1.4.0 diff --git a/packages/apps/tenant/README.md b/packages/apps/tenant/README.md index 6d0373e2..6e270636 100644 --- a/packages/apps/tenant/README.md +++ b/packages/apps/tenant/README.md @@ -56,4 +56,5 @@ tenant-u1 | `etcd` | Deploy own Etcd cluster | `false` | | `monitoring` | Deploy own Monitoring Stack | `false` | | `ingress` | Deploy own Ingress Controller | `false` | +| `seaweedfs` | Deploy own SeaweedFS | `false` | | `isolated` | Enforce tenant namespace with network policies | `false` | diff --git a/packages/apps/tenant/templates/monitoring.yaml b/packages/apps/tenant/templates/monitoring.yaml index 93772546..f0fef4a2 100644 --- a/packages/apps/tenant/templates/monitoring.yaml +++ b/packages/apps/tenant/templates/monitoring.yaml @@ -23,9 +23,6 @@ spec: interval: 1m0s timeout: 5m0s values: - {{- with .Values.host }} - host: grafana.{{ . }} - {{- end }} metricsStorages: - name: shortterm retentionPeriod: "3d" diff --git a/packages/apps/tenant/templates/namespace.yaml b/packages/apps/tenant/templates/namespace.yaml index 9b20d514..3d2ec3b1 100644 --- a/packages/apps/tenant/templates/namespace.yaml +++ b/packages/apps/tenant/templates/namespace.yaml @@ -1,7 +1,7 @@ {{- define "cozystack.namespace-anotations" }} {{- $context := index . 0 }} {{- $existingNS := index . 1 }} -{{- range $x := list "etcd" "monitoring" "ingress" }} +{{- range $x := list "etcd" "monitoring" "ingress" "seaweedfs" }} {{- if (index $context.Values $x) }} namespace.cozystack.io/{{ $x }}: "{{ include "tenant.name" $context }}" {{- else }} diff --git a/packages/apps/tenant/templates/seaweedfs.yaml b/packages/apps/tenant/templates/seaweedfs.yaml new file mode 100644 index 00000000..5741d930 --- /dev/null +++ b/packages/apps/tenant/templates/seaweedfs.yaml @@ -0,0 +1,25 @@ +{{- if .Values.seaweedfs }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: seaweedfs + namespace: {{ include "tenant.name" . }} + annotations: + helm.sh/resource-policy: keep + labels: + cozystack.io/ui: "true" + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + chart: + spec: + chart: seaweedfs + reconcileStrategy: Revision + sourceRef: + kind: HelmRepository + name: cozystack-extra + namespace: cozy-public + version: "*" + interval: 1m0s + timeout: 5m0s +{{- end }} diff --git a/packages/apps/tenant/values.schema.json b/packages/apps/tenant/values.schema.json index 7f87cda1..4d270ecd 100644 --- a/packages/apps/tenant/values.schema.json +++ b/packages/apps/tenant/values.schema.json @@ -22,6 +22,11 @@ "description": "Deploy own Ingress Controller", "default": false }, + "seaweedfs": { + "type": "boolean", + "description": "Deploy own SeaweedFS", + "default": false + }, "isolated": { "type": "boolean", "description": "Enforce tenant namespace with network policies", diff --git a/packages/apps/tenant/values.yaml b/packages/apps/tenant/values.yaml index d52e99ca..ec4dcb18 100644 --- a/packages/apps/tenant/values.yaml +++ b/packages/apps/tenant/values.yaml @@ -4,9 +4,11 @@ ## @param etcd Deploy own Etcd cluster ## @param monitoring Deploy own Monitoring Stack ## @param ingress Deploy own Ingress Controller +## @param seaweedfs Deploy own SeaweedFS ## @param isolated Enforce tenant namespace with network policies host: "" etcd: false monitoring: false ingress: false +seaweedfs: false isolated: false diff --git a/packages/apps/versions_map b/packages/apps/versions_map index d763f504..2742f60f 100644 --- a/packages/apps/versions_map +++ b/packages/apps/versions_map @@ -1,3 +1,4 @@ +bucket 0.1.0 HEAD clickhouse 0.1.0 ca79f72 clickhouse 0.2.0 7cd7de73 clickhouse 0.2.1 HEAD @@ -40,7 +41,8 @@ tenant 1.0.0 7cd7de7 tenant 1.1.0 4da8ac3b tenant 1.2.0 15478a88 tenant 1.3.0 ceefae03 -tenant 1.3.1 HEAD +tenant 1.3.1 c56e5769 +tenant 1.4.0 HEAD virtual-machine 0.1.4 f2015d6 virtual-machine 0.1.5 7cd7de7 virtual-machine 0.2.0 HEAD diff --git a/packages/core/platform/templates/apps.yaml b/packages/core/platform/templates/apps.yaml index 073edbdb..859302db 100644 --- a/packages/core/platform/templates/apps.yaml +++ b/packages/core/platform/templates/apps.yaml @@ -19,6 +19,7 @@ metadata: namespace.cozystack.io/etcd: tenant-root namespace.cozystack.io/monitoring: tenant-root namespace.cozystack.io/ingress: tenant-root + namespace.cozystack.io/seaweedfs: tenant-root namespace.cozystack.io/host: "{{ $host }}" name: tenant-root --- diff --git a/packages/extra/seaweedfs/.helmignore b/packages/extra/seaweedfs/.helmignore new file mode 100644 index 00000000..1ea0ae84 --- /dev/null +++ b/packages/extra/seaweedfs/.helmignore @@ -0,0 +1,3 @@ +.helmignore +/logos +/Makefile diff --git a/packages/extra/seaweedfs/Chart.yaml b/packages/extra/seaweedfs/Chart.yaml new file mode 100644 index 00000000..741983e1 --- /dev/null +++ b/packages/extra/seaweedfs/Chart.yaml @@ -0,0 +1,25 @@ +apiVersion: v2 +name: seaweedfs +description: Seaweedfs +icon: /logos/seaweedfs.svg + +# A chart can be either an 'application' or a 'library' chart. +# +# Application charts are a collection of templates that can be packaged into versioned archives +# to be deployed. +# +# Library charts provide useful utilities or functions for the chart developer. They're included as +# a dependency of application charts to inject those utilities and functions into the rendering +# pipeline. Library charts do not define any templates and therefore cannot be deployed. +type: application + +# This is the chart version. This version number should be incremented each time you make changes +# to the chart and its templates, including the app version. +# Versions are expected to follow Semantic Versioning (https://semver.org/) +version: 0.1.0 + +# This is the version number of the application being deployed. This version number should be +# incremented each time you make changes to the application. Versions are not expected to +# follow Semantic Versioning. They should reflect the version the application is using. +# It is recommended to use it with quotes. +appVersion: "3.71" diff --git a/packages/extra/seaweedfs/Makefile b/packages/extra/seaweedfs/Makefile new file mode 100644 index 00000000..207e2133 --- /dev/null +++ b/packages/extra/seaweedfs/Makefile @@ -0,0 +1,2 @@ +generate: + readme-generator -v values.yaml -s values.schema.json -r README.md diff --git a/packages/extra/seaweedfs/README.md b/packages/extra/seaweedfs/README.md new file mode 100644 index 00000000..7b65ce17 --- /dev/null +++ b/packages/extra/seaweedfs/README.md @@ -0,0 +1,12 @@ +# Managed NATS Service + +## Parameters + +### Common parameters + +| Name | Description | Value | +| ---------- | --------------------------------------------------------------------------------------------------------- | ----- | +| `host` | The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host). | `""` | +| `replicas` | Persistent Volume size for NATS | `2` | +| `size` | Persistent Volume size | `4Gi` | + diff --git a/packages/extra/seaweedfs/logos/seaweedfs.svg b/packages/extra/seaweedfs/logos/seaweedfs.svg new file mode 100644 index 00000000..61fce568 --- /dev/null +++ b/packages/extra/seaweedfs/logos/seaweedfs.svg @@ -0,0 +1,317 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packages/extra/seaweedfs/templates/seaweedfs.yaml b/packages/extra/seaweedfs/templates/seaweedfs.yaml new file mode 100644 index 00000000..739b1fa9 --- /dev/null +++ b/packages/extra/seaweedfs/templates/seaweedfs.yaml @@ -0,0 +1,55 @@ +{{- $myNS := lookup "v1" "Namespace" "" .Release.Namespace }} +{{- $ingress := index $myNS.metadata.annotations "namespace.cozystack.io/ingress" }} +{{- $host := index $myNS.metadata.annotations "namespace.cozystack.io/host" }} +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: {{ .Release.Name }}-system +spec: + chart: + spec: + chart: cozy-seaweedfs + reconcileStrategy: Revision + sourceRef: + kind: HelmRepository + name: cozystack-system + namespace: cozy-system + version: '*' + interval: 1m0s + timeout: 5m0s + values: + global: + serviceAccountName: "{{ .Release.Namespace }}-seaweedfs" + + seaweedfs: + + volume: + replicas: {{ .Values.replicas }} + + # TODO: workaround for non-working online resize + podAnnotations: + volume-size: "{{ .Values.size }}" + + dataDirs: + - name: data1 + type: "persistentVolumeClaim" + size: "{{ .Values.size }}" + maxVolumes: 0 + + s3: + ingress: + className: {{ $ingress }} + host: {{ .Values.host | default (printf "s3.%s" $host) }} + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + acme.cert-manager.io/http01-ingress-class: {{ $ingress }} + cert-manager.io/cluster-issuer: letsencrypt-prod + tls: + - hosts: + - {{ .Values.host | default (printf "seaweedfs.%s" $host) }} + secretName: {{ .Release.Name }}-s3-ingress-tls + + cosi: + driverName: "{{ .Release.Namespace }}.seaweedfs.objectstorage.k8s.io" + bucketClassName: "{{ .Release.Namespace }}" diff --git a/packages/extra/seaweedfs/values.schema.json b/packages/extra/seaweedfs/values.schema.json new file mode 100644 index 00000000..545b840b --- /dev/null +++ b/packages/extra/seaweedfs/values.schema.json @@ -0,0 +1,21 @@ +{ + "title": "Chart Values", + "type": "object", + "properties": { + "host": { + "type": "string", + "description": "The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host).", + "default": "" + }, + "replicas": { + "type": "number", + "description": "Persistent Volume size for NATS", + "default": 2 + }, + "size": { + "type": "string", + "description": "Persistent Volume size", + "default": "4Gi" + } + } +} \ No newline at end of file diff --git a/packages/extra/seaweedfs/values.yaml b/packages/extra/seaweedfs/values.yaml new file mode 100644 index 00000000..a74695af --- /dev/null +++ b/packages/extra/seaweedfs/values.yaml @@ -0,0 +1,10 @@ +## @section Common parameters + +## @param host The hostname used to access the grafana externally (defaults to 'grafana' subdomain for the tenant host). +host: "" + +## @param replicas Persistent Volume size for NATS +## @param size Persistent Volume size +## +replicas: 2 +size: 10Gi diff --git a/packages/extra/versions_map b/packages/extra/versions_map index 8453643d..139b5c64 100644 --- a/packages/extra/versions_map +++ b/packages/extra/versions_map @@ -9,3 +9,4 @@ ingress 1.2.0 HEAD monitoring 1.0.0 f642698 monitoring 1.1.0 15478a88 monitoring 1.2.0 HEAD +seaweedfs 0.1.0 HEAD diff --git a/packages/system/seaweedfs/Chart.yaml b/packages/system/seaweedfs/Chart.yaml new file mode 100644 index 00000000..b6aee535 --- /dev/null +++ b/packages/system/seaweedfs/Chart.yaml @@ -0,0 +1,3 @@ +apiVersion: v2 +name: cozy-seaweedfs +version: 0.0.0 # Placeholder, the actual version will be automatically set during the build process diff --git a/packages/system/seaweedfs/Makefile b/packages/system/seaweedfs/Makefile new file mode 100644 index 00000000..e079734e --- /dev/null +++ b/packages/system/seaweedfs/Makefile @@ -0,0 +1,7 @@ +update: + rm -rf charts + mkdir -p charts + curl -sSL https://github.com/seaweedfs/seaweedfs/archive/refs/heads/master.tar.gz | \ + tar xzvf - --strip 3 -C charts seaweedfs-master/k8s/charts/seaweedfs + patch --no-backup-if-mismatch -p4 < patches/retention-policy-delete.yaml + patch --no-backup-if-mismatch -p4 < patches/resize-api-server-annotation.diff diff --git a/packages/system/seaweedfs/charts/seaweedfs/.helmignore b/packages/system/seaweedfs/charts/seaweedfs/.helmignore new file mode 100644 index 00000000..50af0317 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/.helmignore @@ -0,0 +1,22 @@ +# 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 +.vscode/ diff --git a/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml new file mode 100644 index 00000000..073679af --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +description: SeaweedFS +name: seaweedfs +appVersion: "3.71" +# Dev note: Trigger a helm chart release by `git tag -a helm-` +version: 4.0.0 diff --git a/packages/system/seaweedfs/charts/seaweedfs/README.md b/packages/system/seaweedfs/charts/seaweedfs/README.md new file mode 100644 index 00000000..41707ba8 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/README.md @@ -0,0 +1,146 @@ +# SEAWEEDFS - helm chart (2.x+) + +## Getting Started + +### Add the helm repo + +```bash +helm repo add seaweedfs https://seaweedfs.github.io/seaweedfs/helm +``` + +### Install the helm chart + +```bash +helm install seaweedfs seaweedfs/seaweedfs +``` + +### (Recommended) Provide `values.yaml` + +```bash +helm install --values=values.yaml seaweedfs seaweedfs/seaweedfs +``` + +## Info: +* master/filer/volume are stateful sets with anti-affinity on the hostname, +so your deployment will be spread/HA. +* chart is using memsql(mysql) as the filer backend to enable HA (multiple filer instances) and backup/HA memsql can provide. +* mysql user/password are created in a k8s secret (secret-seaweedfs-db.yaml) and injected to the filer with ENV. +* cert config exists and can be enabled, but not been tested, requires cert-manager to be installed. + +## Prerequisites +### Database + +leveldb is the default database, this supports multiple filer replicas that will [sync automatically](https://github.com/seaweedfs/seaweedfs/wiki/Filer-Store-Replication), with some [limitations](https://github.com/seaweedfs/seaweedfs/wiki/Filer-Store-Replication#limitation). + +When the [limitations](https://github.com/seaweedfs/seaweedfs/wiki/Filer-Store-Replication#limitation) apply, or for a large number of filer replicas, an external datastore is recommended. + +Such as MySQL-compatible database, as specified in the `values.yaml` at `filer.extraEnvironmentVars`. +This database should be pre-configured and initialized by running: +```sql +CREATE TABLE IF NOT EXISTS `filemeta` ( + `dirhash` BIGINT NOT NULL COMMENT 'first 64 bits of MD5 hash value of directory field', + `name` VARCHAR(766) NOT NULL COMMENT 'directory or file name', + `directory` TEXT NOT NULL COMMENT 'full path to parent directory', + `meta` LONGBLOB, + PRIMARY KEY (`dirhash`, `name`) +) DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin; +``` + +Alternative database can also be configured (e.g. leveldb, postgres) following the instructions at `filer.extraEnvironmentVars`. + +### Node Labels +Kubernetes nodes can have labels which help to define which node(Host) will run which pod: + +Here is an example: +* s3/filer/master needs the label **sw-backend=true** +* volume need the label **sw-volume=true** + +to label a node to be able to run all pod types in k8s: +``` +kubectl label node YOUR_NODE_NAME sw-volume=true,sw-backend=true +``` + +on production k8s deployment you will want each pod to have a different host, +especially the volume server and the masters, all pods (master/volume/filer) +should have anti-affinity rules to disallow running multiple component pods on the same host. + +If you still want to run multiple pods of the same component (master/volume/filer) on the same host please set/update the corresponding affinity rule in values.yaml to an empty one: + +```affinity: ""``` + +## PVC - storage class ### + +On the volume stateful set added support for k8s PVC, currently example +with the simple local-path-provisioner from Rancher (comes included with k3d / k3s) +https://github.com/rancher/local-path-provisioner + +you can use ANY storage class you like, just update the correct storage-class +for your deployment. + +## current instances config (AIO): + +1 instance for each type (master/filer+s3/volume) + +You can update the replicas count for each node type in values.yaml, +need to add more nodes with the corresponding labels if applicable. + +Most of the configuration are available through values.yaml any pull requests to expand functionality or usability are greatly appreciated. Any pull request must pass [chart-testing](https://github.com/helm/chart-testing). + +## S3 configuration + +To enable an s3 endpoint for your filer with a default install add the following to your values.yaml: + +```yaml +filer: + s3: + enabled: true +``` + +### Enabling Authentication to S3 + +To enable authentication for S3, you have two options: + +- let the helm chart create an admin user as well as a read only user +- provide your own s3 config.json file via an existing Kubernetes Secret + +#### Use the default credentials for S3 + +Example parameters for your values.yaml: + +```yaml +filer: + s3: + enabled: true + enableAuth: true +``` + +#### Provide your own credentials for S3 + +Example parameters for your values.yaml: + +```yaml +filer: + s3: + enabled: true + enableAuth: true + existingConfigSecret: my-s3-secret +``` + +Example existing secret with your s3 config to create an admin user and readonly user, both with credentials: + +```yaml +--- +# Source: seaweedfs/templates/seaweedfs-s3-secret.yaml +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: my-s3-secret + namespace: seaweedfs + labels: + app.kubernetes.io/name: seaweedfs + app.kubernetes.io/component: s3 +stringData: + # this key must be an inline json config file + seaweedfs_s3_config: '{"identities":[{"name":"anvAdmin","credentials":[{"accessKey":"snu8yoP6QAlY0ne4","secretKey":"PNzBcmeLNEdR0oviwm04NQAicOrDH1Km"}],"actions":["Admin","Read","Write"]},{"name":"anvReadOnly","credentials":[{"accessKey":"SCigFee6c5lbi04A","secretKey":"kgFhbT38R8WUYVtiFQ1OiSVOrYr3NKku"}],"actions":["Read"]}]}' +``` diff --git a/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json b/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json new file mode 100644 index 00000000..f4e3b020 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json @@ -0,0 +1,3269 @@ +{ + "annotations": { + "list": [ + { + "builtIn": 1, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "enable": true, + "hide": true, + "iconColor": "rgba(0, 211, 255, 1)", + "limit": 100, + "name": "Annotations & Alerts", + "showIn": 0, + "type": "dashboard" + } + ] + }, + "editable": true, + "fiscalYearStartMonth": 0, + "gnetId": 10423, + "graphTooltip": 0, + "id": 160, + "links": [], + "liveNow": false, + "panels": [ + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 0 + }, + "id": 67, + "panels": [], + "title": "Master", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Whether master is leader or not", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bool_yes_no", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 1 + }, + "id": 57, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "exemplar": true, + "expr": "sum by (pod) (SeaweedFS_master_is_leader{job=\"seaweedfs-master\", namespace=\"$NAMESPACE\"})", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "refId": "A", + "step": 60 + } + ], + "title": "Raft leader", + "type": "stat" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Count times leader changed", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 1 + }, + "id": 68, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.1.2", + "targets": [ + { + "exemplar": true, + "expr": "sum by (pod) (SeaweedFS_master_leader_changes{job=\"seaweedfs-master\", type=~\".+\", namespace=\"$NAMESPACE\"})", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "refId": "A", + "step": 60 + } + ], + "title": "Master leader changes", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Heartbeats received from components", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 1 + }, + "id": 69, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.1.2", + "targets": [ + { + "exemplar": true, + "expr": "sum by (type) (increase(SeaweedFS_master_received_heartbeats{job=\"seaweedfs-master\", namespace=\"$NAMESPACE\"}[$__rate_interval]))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "A", + "step": 60 + } + ], + "title": "Received heartbeats", + "type": "timeseries" + }, + { + "alert": { + "alertRuleTags": {}, + "conditions": [ + { + "evaluator": { + "params": [ + 0 + ], + "type": "gt" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "A", + "5m", + "now" + ] + }, + "reducer": { + "params": [], + "type": "avg" + }, + "type": "query" + } + ], + "executionErrorState": "alerting", + "for": "5m", + "frequency": "1m", + "handler": 1, + "message": "", + "name": "Replica Placement Mismatch alert", + "noDataState": "ok", + "notifications": [] + }, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Count replica placement mismatch", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 4, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 0, + "y": 7 + }, + "id": 70, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.1.2", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "sum (SeaweedFS_master_replica_placement_mismatch{job=\"seaweedfs-master\", namespace=\"$NAMESPACE\"} > 0) by (pod)", + "format": "time_series", + "hide": false, + "instant": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{pod}}", + "refId": "A", + "step": 60 + } + ], + "thresholds": [ + { + "colorMode": "critical", + "op": "gt", + "value": 0, + "visible": true + } + ], + "title": "Replica Placement Mismatch", + "type": "timeseries" + }, + { + "alert": { + "alertRuleTags": {}, + "conditions": [ + { + "evaluator": { + "params": [ + 1, + 1 + ], + "type": "outside_range" + }, + "operator": { + "type": "and" + }, + "query": { + "params": [ + "A", + "5m", + "now" + ] + }, + "reducer": { + "params": [], + "type": "avg" + }, + "type": "query" + } + ], + "executionErrorState": "alerting", + "for": "5m", + "frequency": "1m", + "handler": 1, + "message": "Raft leader count of master-servers not equal to 1", + "name": "Raft leader alert", + "noDataState": "no_data", + "notifications": [] + }, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Total count of raft leaders", + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "auto", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 8, + "y": 7 + }, + "id": 71, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "single", + "sort": "none" + } + }, + "pluginVersion": "8.1.2", + "targets": [ + { + "exemplar": true, + "expr": "sum (SeaweedFS_master_is_leader{job=\"seaweedfs-master\", namespace=\"$NAMESPACE\"})", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Leaders", + "refId": "A", + "step": 60 + } + ], + "thresholds": [ + { + "colorMode": "critical", + "op": "lt", + "value": 1, + "visible": true + }, + { + "colorMode": "critical", + "op": "gt", + "value": 1, + "visible": true + } + ], + "title": "Raft leader count", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "description": "Whether cluster locked or not", + "fieldConfig": { + "defaults": { + "color": { + "mode": "thresholds" + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + } + ] + }, + "unit": "bool_yes_no", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 6, + "w": 8, + "x": 16, + "y": 7 + }, + "id": 74, + "links": [], + "options": { + "colorMode": "value", + "graphMode": "area", + "justifyMode": "auto", + "orientation": "horizontal", + "reduceOptions": { + "calcs": [ + "last" + ], + "fields": "", + "values": false + }, + "showPercentChange": false, + "text": {}, + "textMode": "auto", + "wideLayout": true + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "editorMode": "code", + "exemplar": true, + "expr": "SeaweedFS_master_admin_lock{job=\"seaweedfs-master\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "Client IP: {{client}}", + "range": true, + "refId": "A", + "step": 60 + } + ], + "title": "Admin lock", + "type": "stat" + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 13 + }, + "id": 60, + "panels": [], + "title": "Filer", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 14 + }, + "id": 46, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + } + ], + "title": "Filer Request Duration 90th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 14 + }, + "id": 49, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + }, + { + "expr": "", + "format": "time_series", + "intervalFactor": 2, + "refId": "C" + } + ], + "title": "Filer Request Duration 95th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 14 + }, + "id": 45, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_filer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + }, + { + "expr": "", + "format": "time_series", + "intervalFactor": 2, + "refId": "C" + } + ], + "title": "Filer Request Duration 99th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "total" + }, + "properties": [ + { + "id": "custom.lineWidth", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsZero", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 21 + }, + "id": 2, + "links": [], + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 250 + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "exemplar": true, + "expr": "sum by (type) (rate(SeaweedFS_filer_request_total{namespace=\"$NAMESPACE\"}[$__rate_interval]))", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "A", + "step": 30 + } + ], + "title": "Filer QPS", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 28 + }, + "id": 61, + "panels": [], + "title": "S3 Gateway", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 0, + "y": 29 + }, + "id": 65, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + } + ], + "title": "S3 Request Duration 90th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 8, + "y": 29 + }, + "id": 56, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + } + ], + "title": "S3 Request Duration 95th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 8, + "x": 16, + "y": 29 + }, + "id": 58, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B", + "step": 60 + } + ], + "title": "S3 Request Duration 99th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 36 + }, + "id": 72, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "average", + "refId": "A", + "step": 60 + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type, pod))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{type}}-{{pod}}", + "refId": "B", + "step": 60 + } + ], + "title": "S3 Request. Duration 99th percentile per instance", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 43 + }, + "id": 73, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "exemplar": true, + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type, bucket))", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{type}}-{{bucket}}", + "refId": "B", + "step": 60 + } + ], + "title": "S3 Request Duration 99th percentile per bucket", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "total" + }, + "properties": [ + { + "id": "custom.lineWidth", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsZero", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 50 + }, + "id": 55, + "links": [], + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 250 + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum (rate(SeaweedFS_s3_request_total{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "A", + "step": 30 + } + ], + "title": "S3 API QPS", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "Cost in US$", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 0, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "currencyUSD", + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byName", + "options": "total" + }, + "properties": [ + { + "id": "custom.lineWidth", + "value": 0 + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsZero", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 57 + }, + "hideTimeOverride": false, + "id": 59, + "links": [], + "options": { + "legend": { + "calcs": [ + "lastNotNull", + "max" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true, + "width": 250 + }, + "tooltip": { + "mode": "multi", + "sort": "desc" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum by (type) (SeaweedFS_s3_request_total{type=~'PUT|COPY|POST|LIST', namespace=\"$NAMESPACE\"})*0.000005", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}} requests", + "refId": "A", + "step": 30 + }, + { + "expr": "sum (SeaweedFS_s3_request_total{type=~'PUT|COPY|POST|LIST', namespace=\"$NAMESPACE\"})*0.000005", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "All PUT, COPY, POST, LIST", + "refId": "C", + "step": 30 + }, + { + "expr": "sum (SeaweedFS_s3_request_total{type!~'PUT|COPY|POST|LIST', namespace=\"$NAMESPACE\"})*0.0000004", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "GET and all other", + "refId": "B" + }, + { + "expr": "sum by (type) (SeaweedFS_s3_request_total{type!~'PUT|COPY|POST|LIST', namespace=\"$NAMESPACE\"})*0.0000004", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{type}} requests", + "refId": "D" + } + ], + "timeFrom": "1M", + "title": "S3 API Monthly Cost if on AWS", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 64 + }, + "id": 62, + "panels": [], + "title": "Volume Server", + "type": "row" + }, + { + "datasource": { + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 65 + }, + "id": 47, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_volumeServer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, exported_instance))", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{exported_instance}}", + "refId": "B" + }, + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_volumeServer_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "average", + "refId": "C" + } + ], + "title": "Volume Server Request Duration 99th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [ + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsZero", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + }, + { + "matcher": { + "id": "byValue", + "options": { + "op": "gte", + "reducer": "allIsNull", + "value": 0 + } + }, + "properties": [ + { + "id": "custom.hideFrom", + "value": { + "legend": true, + "tooltip": true, + "viz": false + } + } + ] + } + ] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 65 + }, + "id": 40, + "links": [], + "options": { + "legend": { + "calcs": [ + "sum" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum(rate(SeaweedFS_volumeServer_request_total{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "A", + "step": 4 + } + ], + "title": "Volume Server QPS", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 72 + }, + "id": 48, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(SeaweedFS_volumeServer_volumes{namespace=\"$NAMESPACE\"}) by (collection, type)", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{collection}} {{type}}", + "refId": "A" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "expr": "sum(SeaweedFS_volumeServer_volumes{namespace=\"$NAMESPACE\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Total", + "refId": "B" + } + ], + "title": "Volume Count", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 79 + }, + "id": 50, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum(SeaweedFS_volumeServer_total_disk_size{namespace=\"$NAMESPACE\"}) by (collection, type)", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{collection}} {{type}}", + "refId": "A" + }, + { + "expr": "sum(SeaweedFS_volumeServer_total_disk_size{namespace=\"$NAMESPACE\"})", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "Total", + "refId": "B" + } + ], + "title": "Used Disk Space by Collection and Type", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 1, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 86 + }, + "id": 51, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum(SeaweedFS_volumeServer_total_disk_size{namespace=\"$NAMESPACE\"}) by (exported_instance)", + "format": "time_series", + "hide": false, + "intervalFactor": 2, + "legendFormat": "{{exported_instance}}", + "refId": "A" + } + ], + "title": "Used Disk Space by Host", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 93 + }, + "id": 63, + "panels": [], + "title": "Filer Store", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 94 + }, + "id": 12, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_filerStore_request_seconds_bucket{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (le, type))", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B" + } + ], + "title": "Filer Store Request Duration 99th percentile", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "short", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 94 + }, + "id": 14, + "links": [], + "options": { + "legend": { + "calcs": [ + "mean", + "lastNotNull" + ], + "displayMode": "table", + "placement": "right", + "showLegend": true + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "expr": "sum(rate(SeaweedFS_filerStore_request_total{namespace=\"$NAMESPACE\"}[$__rate_interval])) by (type)", + "format": "time_series", + "intervalFactor": 2, + "legendFormat": "{{type}}", + "refId": "B" + } + ], + "title": "Filer Store QPS", + "type": "timeseries" + }, + { + "collapsed": false, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "gridPos": { + "h": 1, + "w": 24, + "x": 0, + "y": 101 + }, + "id": 64, + "panels": [], + "title": "Filer Instances", + "type": "row" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "bytes", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 0, + "y": 102 + }, + "id": 52, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "exemplar": true, + "expr": "go_memstats_alloc_bytes{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "bytes allocated", + "refId": "B" + }, + { + "exemplar": true, + "expr": "rate(go_memstats_alloc_bytes_total{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}[$__rate_interval])", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "alloc rate", + "refId": "A" + }, + { + "exemplar": true, + "expr": "go_memstats_stack_inuse_bytes{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "stack inuse", + "refId": "C" + }, + { + "exemplar": true, + "expr": "go_memstats_heap_inuse_bytes{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "hide": false, + "interval": "", + "intervalFactor": 2, + "legendFormat": "heap inuse", + "refId": "D" + } + ], + "title": "Filer Go Memory Stats", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "s", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 12, + "x": 12, + "y": 102 + }, + "id": 54, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "exemplar": true, + "expr": "go_gc_duration_seconds{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{quantile}}", + "refId": "B" + } + ], + "title": "Filer Go GC duration quantiles", + "type": "timeseries" + }, + { + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "fieldConfig": { + "defaults": { + "color": { + "mode": "palette-classic" + }, + "custom": { + "axisBorderShow": false, + "axisCenteredZero": false, + "axisColorMode": "text", + "axisLabel": "", + "axisPlacement": "auto", + "barAlignment": 0, + "drawStyle": "line", + "fillOpacity": 10, + "gradientMode": "none", + "hideFrom": { + "legend": false, + "tooltip": false, + "viz": false + }, + "insertNulls": false, + "lineInterpolation": "linear", + "lineWidth": 2, + "pointSize": 5, + "scaleDistribution": { + "type": "linear" + }, + "showPoints": "never", + "spanNulls": false, + "stacking": { + "group": "A", + "mode": "none" + }, + "thresholdsStyle": { + "mode": "off" + } + }, + "mappings": [], + "min": 0, + "thresholds": { + "mode": "absolute", + "steps": [ + { + "color": "green", + "value": null + }, + { + "color": "red", + "value": 80 + } + ] + }, + "unit": "none", + "unitScale": true + }, + "overrides": [] + }, + "gridPos": { + "h": 7, + "w": 24, + "x": 0, + "y": 109 + }, + "id": 53, + "links": [], + "options": { + "legend": { + "calcs": [], + "displayMode": "list", + "placement": "bottom", + "showLegend": false + }, + "tooltip": { + "mode": "multi", + "sort": "none" + } + }, + "pluginVersion": "10.3.1", + "targets": [ + { + "exemplar": true, + "expr": "go_goroutines{job=\"seaweedfs-filer\", namespace=\"$NAMESPACE\"}", + "format": "time_series", + "interval": "", + "intervalFactor": 2, + "legendFormat": "{{exported_instance}}", + "refId": "B" + } + ], + "title": "Filer Go Routines", + "type": "timeseries" + } + ], + "refresh": "", + "schemaVersion": 39, + "tags": [], + "templating": { + "list": [ + { + "current": { + "selected": false, + "text": "Prometheus", + "value": "PBFA97CFB590B2093" + }, + "hide": 0, + "includeAll": false, + "label": "Datasource", + "multi": false, + "name": "DS_PROMETHEUS", + "options": [], + "query": "prometheus", + "queryValue": "", + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "type": "datasource" + }, + { + "current": { + "selected": false, + "text": "mes", + "value": "mes" + }, + "datasource": { + "type": "prometheus", + "uid": "${DS_PROMETHEUS}" + }, + "definition": "label_values(SeaweedFS_master_is_leader,namespace)", + "hide": 0, + "includeAll": false, + "label": "Namespace", + "multi": false, + "name": "NAMESPACE", + "options": [], + "query": { + "qryType": 1, + "query": "label_values(SeaweedFS_master_is_leader,namespace)", + "refId": "PrometheusVariableQueryEditor-VariableQuery" + }, + "refresh": 1, + "regex": "", + "skipUrlSync": false, + "sort": 2, + "type": "query" + } + ] + }, + "time": { + "from": "now-1d", + "to": "now" + }, + "timepicker": { + "refresh_intervals": [ + "5s", + "10s", + "30s", + "1m", + "5m", + "15m", + "30m", + "1h", + "2h", + "1d" + ], + "time_options": [ + "5m", + "15m", + "1h", + "6h", + "12h", + "24h", + "2d", + "7d", + "30d" + ] + }, + "timezone": "browser", + "title": "SeaweedFS", + "uid": "a24009d7-cbda-4443-a132-1cc1c4677304", + "version": 1, + "weekStart": "" +} \ No newline at end of file diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/_helpers.tpl b/packages/system/seaweedfs/charts/seaweedfs/templates/_helpers.tpl new file mode 100644 index 00000000..d8261eb3 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/_helpers.tpl @@ -0,0 +1,167 @@ +{{/* +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 "seaweedfs.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 "seaweedfs.chart" -}} +{{- printf "%s-helm" .Chart.Name | replace "+" "_" | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Expand the name of the chart. +*/}} +{{- define "seaweedfs.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Inject extra environment vars in the format key:value, if populated +*/}} +{{- define "seaweedfs.extraEnvironmentVars" -}} +{{- if .extraEnvironmentVars -}} +{{- range $key, $value := .extraEnvironmentVars }} +- name: {{ $key }} + value: {{ $value | quote }} +{{- end -}} +{{- end -}} +{{- end -}} + +{{/* Return the proper filer image */}} +{{- define "filer.image" -}} +{{- if .Values.filer.imageOverride -}} +{{- $imageOverride := .Values.filer.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Return the proper master image */}} +{{- define "master.image" -}} +{{- if .Values.master.imageOverride -}} +{{- $imageOverride := .Values.master.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Return the proper s3 image */}} +{{- define "s3.image" -}} +{{- if .Values.s3.imageOverride -}} +{{- $imageOverride := .Values.s3.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Return the proper volume image */}} +{{- define "volume.image" -}} +{{- if .Values.volume.imageOverride -}} +{{- $imageOverride := .Values.volume.imageOverride -}} +{{- printf "%s" $imageOverride -}} +{{- else -}} +{{- include "common.image" . }} +{{- end -}} +{{- end -}} + +{{/* Computes the container image name for all components (if they are not overridden) */}} +{{- define "common.image" -}} +{{- $registryName := default .Values.image.registry .Values.global.registry | toString -}} +{{- $repositoryName := .Values.image.repository | toString -}} +{{- $name := .Values.global.imageName | toString -}} +{{- $tag := .Chart.AppVersion | toString -}} +{{- if $registryName -}} +{{- printf "%s/%s%s:%s" $registryName $repositoryName $name $tag -}} +{{- else -}} +{{- printf "%s%s:%s" $repositoryName $name $tag -}} +{{- end -}} +{{- end -}} + +{{/* check if any Volume PVC exists */}} +{{- define "volume.pvc_exists" -}} +{{- if or (or (eq .Values.volume.data.type "persistentVolumeClaim") (and (eq .Values.volume.idx.type "persistentVolumeClaim") .Values.volume.dir_idx )) (eq .Values.volume.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + +{{/* check if any Filer PVC exists */}} +{{- define "filer.pvc_exists" -}} +{{- if or (eq .Values.filer.data.type "persistentVolumeClaim") (eq .Values.filer.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + +{{/* check if any Master PVC exists */}} +{{- define "master.pvc_exists" -}} +{{- if or (eq .Values.master.data.type "persistentVolumeClaim") (eq .Values.master.logs.type "persistentVolumeClaim") -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + +{{/* check if any InitContainers exist for Volumes */}} +{{- define "volume.initContainers_exists" -}} +{{- if or (not (empty .Values.volume.idx )) (not (empty .Values.volume.initContainers )) -}} +{{- printf "true" -}} +{{- else -}} +{{- printf "" -}} +{{- end -}} +{{- end -}} + +{{/* Return the proper imagePullSecrets */}} +{{- define "seaweedfs.imagePullSecrets" -}} +{{- if .Values.global.imagePullSecrets }} +{{- if kindIs "string" .Values.global.imagePullSecrets }} +imagePullSecrets: + - name: {{ .Values.global.imagePullSecrets }} +{{- else }} +imagePullSecrets: +{{- range .Values.global.imagePullSecrets }} + - name: {{ . }} +{{- end }} +{{- end }} +{{- end }} +{{- end -}} + +{{/* +Renders a value that contains template perhaps with scope if the scope is present. +Usage: +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ ) }} +{{ include "common.tplvalues.render" ( dict "value" .Values.path.to.the.Value "context" $ "scope" $app ) }} +*/}} +{{- define "common.tplvalues.render" -}} +{{- $value := typeIs "string" .value | ternary .value (.value | toYaml) }} +{{- if contains "{{" (toJson .value) }} + {{- if .scope }} + {{- tpl (cat "{{- with $.RelativeScope -}}" $value "{{- end }}") (merge (dict "RelativeScope" .scope) .context) }} + {{- else }} + {{- tpl $value .context }} + {{- end }} +{{- else }} + {{- $value }} +{{- end }} +{{- end -}} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/ca-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/ca-cert.yaml new file mode 100644 index 00000000..0fd6615e --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/ca-cert.yaml @@ -0,0 +1,19 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-ca-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + commonName: "{{ template "seaweedfs.name" . }}-root-ca" + isCA: true + issuerRef: + name: {{ template "seaweedfs.name" . }}-issuer + kind: Issuer +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert-caissuer.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert-caissuer.yaml new file mode 100644 index 00000000..72de126e --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert-caissuer.yaml @@ -0,0 +1,15 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Issuer +metadata: + name: {{ template "seaweedfs.name" . }}-ca-issuer + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + ca: + secretName: {{ template "seaweedfs.name" . }}-ca-cert +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cert-issuer.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cert-issuer.yaml new file mode 100644 index 00000000..9f243d07 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cert-issuer.yaml @@ -0,0 +1,13 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Issuer +metadata: + name: {{ template "seaweedfs.name" . }}-issuer + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + selfSigned: {} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/client-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/client-cert.yaml new file mode 100644 index 00000000..bda132a0 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/client-cert.yaml @@ -0,0 +1,40 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-client-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + secretName: {{ template "seaweedfs.name" . }}-client-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ .Release.Namespace }}' + - '*.{{ .Release.Namespace }}.svc' + - '*.{{ .Release.Namespace }}.svc.cluster.local' + - '*.{{ template "seaweedfs.name" . }}-master' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cluster-role.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cluster-role.yaml new file mode 100644 index 00000000..154de067 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cluster-role.yaml @@ -0,0 +1,35 @@ +{{- if .Values.global.createClusterRole }} +#hack for delete pod master after migration +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.global.serviceAccountName }}-rw-cr + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +rules: + - apiGroups: [""] + resources: ["pods"] + verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: system:serviceaccount:{{ .Values.global.serviceAccountName }}:default + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +subjects: + - kind: ServiceAccount + name: {{ .Values.global.serviceAccountName }} + namespace: {{ .Release.Namespace }} +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: {{ .Values.global.serviceAccountName }}-rw-cr +{{- end }} \ No newline at end of file diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-bucket-class.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-bucket-class.yaml new file mode 100644 index 00000000..e5503abd --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-bucket-class.yaml @@ -0,0 +1,16 @@ +{{- if and .Values.cosi.enabled .Values.cosi.bucketClassName }} +--- +kind: BucketClass +apiVersion: objectstorage.k8s.io/v1alpha1 +metadata: + name: {{ .Values.cosi.bucketClassName }} +driverName: {{ .Values.cosi.driverName }} +deletionPolicy: Delete +--- +kind: BucketAccessClass +apiVersion: objectstorage.k8s.io/v1alpha1 +metadata: + name: {{ .Values.cosi.bucketClassName }} +driverName: {{ .Values.cosi.driverName }} +authenticationType: KEY +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-cluster-role.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-cluster-role.yaml new file mode 100644 index 00000000..75d3ec32 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-cluster-role.yaml @@ -0,0 +1,69 @@ +{{- if .Values.cosi.enabled }} +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +rules: +- apiGroups: ["objectstorage.k8s.io"] + resources: + - "buckets" + - "bucketaccesses" + - "bucketclaims" + - "bucketaccessclasses" + - "buckets/status" + - "bucketaccesses/status" + - "bucketclaims/status" + - "bucketaccessclasses/status" + verbs: + - "get" + - "list" + - "watch" + - "update" + - "create" + - "delete" +- apiGroups: ["coordination.k8s.io"] + resources: ["leases"] + verbs: + - "get" + - "watch" + - "list" + - "delete" + - "update" + - "create" +- apiGroups: [""] + resources: + - "secrets" + - "events" + verbs: + - "get" + - "list" + - "watch" + - "update" + - "create" + - "delete" + - "patch" +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +subjects: + - kind: ServiceAccount + name: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + namespace: {{ .Release.Namespace }} +roleRef: + kind: ClusterRole + name: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-deployment.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-deployment.yaml new file mode 100644 index 00000000..15e5fa6d --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-deployment.yaml @@ -0,0 +1,204 @@ +{{- if .Values.cosi.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "seaweedfs.name" . }}-objectstorage-provisioner + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + replicas: {{ .Values.cosi.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: objectstorage-provisioner + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: objectstorage-provisioner + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cosi.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.cosi.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.cosi.restartPolicy }} + {{- if .Values.cosi.tolerations }} + tolerations: + {{ tpl .Values.cosi.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 10 + {{- if .Values.cosi.priorityClassName }} + priorityClassName: {{ .Values.cosi.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + serviceAccountName: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + {{- if .Values.cosi.initContainers }} + initContainers: + {{ tpl .Values.cosi.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.cosi.podSecurityContext.enabled }} + securityContext: {{- omit .Values.cosi.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs-cosi-driver + image: "{{ .Values.cosi.image }}" + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: DRIVERNAME + value: "{{ .Values.cosi.driverName }}" + - name: ENDPOINT + {{- if .Values.cosi.endpoint }} + value: "{{ .Values.cosi.endpoint }}" + {{- else if .Values.s3.ingress.enabled }} + value: "{{ printf "https://%s" .Values.s3.ingress.host }}" + {{- else if .Values.s3.enabled }} + value: "{{ printf "https://%s-s3.%s.svc" (include "seaweedfs.name" .) .Release.Namespace }}" + {{- else }} + value: "{{ printf "https://%s-filer.%s.svc" (include "seaweedfs.name" .) .Release.Namespace }}" + {{- end }} + {{- with .Values.cosi.region }} + - name: REGION + value: "{{ . }}" + {{- end }} + - name: SEAWEEDFS_FILER + value: "{{ template "seaweedfs.name" . }}-filer:{{ .Values.filer.grpcPort }}" + {{- if .Values.global.enableSecurity }} + - name: WEED_GRPC_CLIENT_KEY + value: /usr/local/share/ca-certificates/client/tls.key + - name: WEED_GRPC_CLIENT_CERT + value: /usr/local/share/ca-certificates/client/tls.crt + - name: WEED_GRPC_CA + value: /usr/local/share/ca-certificates/client/ca.crt + {{- end }} + {{- if .Values.cosi.extraEnvironmentVars }} + {{- range $key, $value := .Values.cosi.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + volumeMounts: + - mountPath: /var/lib/cosi + name: socket + {{- if .Values.cosi.enableAuth }} + - mountPath: /etc/sw + name: config-users + readOnly: true + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.cosi.extraVolumeMounts . | nindent 12 | trim }} + - name: seaweedfs-cosi-sidecar + image: "{{ .Values.cosi.sidecar.image }}" + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + args: + - {{ printf "--v=%s" (default "5" .Values.cosi.sidecar.logLevel) }} + env: + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + volumeMounts: + - mountPath: /var/lib/cosi + name: socket + {{- with .Values.cosi.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.cosi.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.cosi.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.cosi.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.cosi.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + - name: socket + emptyDir: {} + {{- if .Values.cosi.enableAuth }} + - name: config-users + secret: + defaultMode: 420 + {{- if .Values.cosi.existingConfigSecret }} + secretName: {{ .Values.cosi.existingConfigSecret }} + {{- else }} + secretName: seaweedfs-client-cert + {{- end }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.cosi.extraVolumes . | indent 8 | trim }} + {{- if .Values.cosi.nodeSelector }} + nodeSelector: + {{ tpl .Values.cosi.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-service-account.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-service-account.yaml new file mode 100644 index 00000000..78227fde --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/cosi-service-account.yaml @@ -0,0 +1,13 @@ +{{- if .Values.cosi.enabled }} +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.global.serviceAccountName }}-objectstorage-provisioner + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +automountServiceAccountToken: {{ .Values.global.automountServiceAccountToken }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-cert.yaml new file mode 100644 index 00000000..c17815af --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-cert.yaml @@ -0,0 +1,41 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-filer-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer +spec: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ .Release.Namespace }}' + - '*.{{ .Release.Namespace }}.svc' + - '*.{{ .Release.Namespace }}.svc.cluster.local' + - '*.{{ template "seaweedfs.name" . }}-master' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-ingress.yaml new file mode 100644 index 00000000..7a7c9886 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.filer.enabled }} +{{- if .Values.filer.ingress.enabled }} +{{- 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: ingress-{{ template "seaweedfs.name" . }}-filer + namespace: {{ .Release.Namespace }} + {{- with .Values.filer.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer +spec: + ingressClassName: {{ .Values.filer.ingress.className | quote }} + tls: + {{ .Values.filer.ingress.tls | default list | toYaml | nindent 6}} + rules: + - http: + paths: + - path: /sw-filer/?(.*) + pathType: ImplementationSpecific + backend: +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ template "seaweedfs.name" . }}-filer + port: + number: {{ .Values.filer.port }} + #name: +{{- else }} + serviceName: {{ template "seaweedfs.name" . }}-filer + servicePort: {{ .Values.filer.port }} +{{- end }} +{{- if .Values.filer.ingress.host }} + host: {{ .Values.filer.ingress.host }} +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service-client.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service-client.yaml new file mode 100644 index 00000000..d7618c4c --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service-client.yaml @@ -0,0 +1,36 @@ +{{- if .Values.filer.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-filer-client + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer +{{- if .Values.filer.metricsPort }} + monitoring: "true" +{{- end }} +spec: + clusterIP: None + ports: + - name: "swfs-filer" + port: {{ .Values.filer.port }} + targetPort: {{ .Values.filer.port }} + protocol: TCP + - name: "swfs-filer-grpc" + port: {{ .Values.filer.grpcPort }} + targetPort: {{ .Values.filer.grpcPort }} + protocol: TCP +{{- if .Values.filer.metricsPort }} + - name: "metrics" + port: {{ .Values.filer.metricsPort }} + targetPort: {{ .Values.filer.metricsPort }} + protocol: TCP +{{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: filer +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service.yaml new file mode 100644 index 00000000..ab7e98df --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-service.yaml @@ -0,0 +1,48 @@ +{{- if .Values.filer.enabled }} +apiVersion: v1 +kind: Service +metadata: + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" + name: {{ template "seaweedfs.name" . }}-filer + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer +spec: + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: "swfs-filer" + port: {{ .Values.filer.port }} + targetPort: {{ .Values.filer.port }} + protocol: TCP + - name: "swfs-filer-grpc" + port: {{ .Values.filer.grpcPort }} + targetPort: {{ .Values.filer.grpcPort }} + protocol: TCP + {{- if .Values.filer.s3.enabled }} + - name: "swfs-s3" + port: {{ .Values.filer.s3.port }} + targetPort: {{ .Values.filer.s3.port }} + protocol: TCP + {{- if .Values.filer.s3.httpsPort }} + - name: "swfs-s3-tls" + port: {{ .Values.filer.s3.httpsPort }} + targetPort: {{ .Values.filer.s3.httpsPort }} + protocol: TCP + {{- end }} + {{- end }} + {{- if .Values.filer.metricsPort }} + - name: "metrics" + port: {{ .Values.filer.metricsPort }} + targetPort: {{ .Values.filer.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: filer +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-servicemonitor.yaml new file mode 100644 index 00000000..76c981c1 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-servicemonitor.yaml @@ -0,0 +1,29 @@ +{{- if .Values.filer.enabled }} +{{- if .Values.filer.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-filer + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: filer +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/filer-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-statefulset.yaml new file mode 100644 index 00000000..49b62e86 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/filer-statefulset.yaml @@ -0,0 +1,402 @@ +{{- if .Values.filer.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "seaweedfs.name" . }}-filer + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer +spec: + serviceName: {{ template "seaweedfs.name" . }}-filer + podManagementPolicy: {{ .Values.filer.podManagementPolicy }} + replicas: {{ .Values.filer.replicas }} + {{- if (gt (int .Values.filer.updatePartition) 0) }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: {{ .Values.filer.updatePartition }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer + {{- with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.filer.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{- with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.filer.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- if .Values.filer.s3.existingConfigSecret }} + {{- $configSecret := (lookup "v1" "Secret" .Release.Namespace .Values.filer.s3.existingConfigSecret) | default dict }} + checksum/s3config: {{ $configSecret | toYaml | sha256sum }} + {{- else }} + checksum/s3config: {{ include (print .Template.BasePath "/s3-secret.yaml") . | sha256sum }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.filer.restartPolicy }} + {{- if .Values.filer.affinity }} + affinity: + {{ tpl .Values.filer.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.filer.tolerations }} + tolerations: + {{ tpl .Values.filer.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + serviceAccountName: {{ .Values.filer.serviceAccountName | default .Values.global.serviceAccountName | quote }} # for deleting statefulset pods after migration + terminationGracePeriodSeconds: 60 + {{- if .Values.filer.priorityClassName }} + priorityClassName: {{ .Values.filer.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.filer.initContainers }} + initContainers: + {{ tpl .Values.filer.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.filer.podSecurityContext.enabled }} + securityContext: {{- omit .Values.filer.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "filer.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: WEED_MYSQL_USERNAME + valueFrom: + secretKeyRef: + name: secret-seaweedfs-db + key: user + optional: true + - name: WEED_MYSQL_PASSWORD + valueFrom: + secretKeyRef: + name: secret-seaweedfs-db + key: password + optional: true + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.filer.extraEnvironmentVars }} + {{- range $key, $value := .Values.filer.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.filer.secretExtraEnvironmentVars }} + {{- range $key, $value := .Values.filer.secretExtraEnvironmentVars }} + - name: {{ $key }} + valueFrom: {{ toYaml $value | nindent 16 }} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.filer.logs.type "hostPath") (eq .Values.filer.logs.type "persistentVolumeClaim") (eq .Values.filer.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.filer.loggingOverrideLevel }} + -v={{ .Values.filer.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + filer \ + -port={{ .Values.filer.port }} \ + {{- if .Values.filer.metricsPort }} + -metricsPort={{ .Values.filer.metricsPort }} \ + {{- end }} + {{- if .Values.filer.redirectOnRead }} + -redirectOnRead \ + {{- end }} + {{- if .Values.filer.disableHttp }} + -disableHttp \ + {{- end }} + {{- if .Values.filer.disableDirListing }} + -disableDirListing \ + {{- end }} + -dirListLimit={{ .Values.filer.dirListLimit }} \ + {{- if .Values.global.enableReplication }} + -defaultReplicaPlacement={{ .Values.global.replicationPlacment }} \ + {{- else }} + -defaultReplicaPlacement={{ .Values.filer.defaultReplicaPlacement }} \ + {{- end }} + {{- if .Values.filer.disableDirListing }} + -disableDirListing \ + {{- end }} + {{- if .Values.filer.maxMB }} + -maxMB={{ .Values.filer.maxMB }} \ + {{- end }} + {{- if .Values.filer.encryptVolumeData }} + -encryptVolumeData \ + {{- end }} + -ip=${POD_IP} \ + {{- if .Values.filer.filerGroup}} + -filerGroup={{ .Values.filer.filerGroup}} \ + {{- end }} + {{- if .Values.filer.s3.enabled }} + -s3 \ + -s3.port={{ .Values.filer.s3.port }} \ + {{- if .Values.filer.s3.domainName }} + -s3.domainName={{ .Values.filer.s3.domainName }} \ + {{- end }} + {{- if .Values.global.enableSecurity }} + {{- if .Values.filer.s3.httpsPort }} + -s3.port.https={{ .Values.filer.s3.httpsPort }} \ + {{- end }} + -s3.cert.file=/usr/local/share/ca-certificates/client/tls.crt \ + -s3.key.file=/usr/local/share/ca-certificates/client/tls.key \ + {{- end }} + {{- if .Values.filer.s3.allowEmptyFolder }} + -s3.allowEmptyFolder={{ .Values.filer.s3.allowEmptyFolder }} \ + {{- end }} + {{- if .Values.filer.s3.enableAuth }} + -s3.config=/etc/sw/seaweedfs_s3_config \ + {{- end }} + {{- if .Values.filer.s3.auditLogConfig }} + -s3.auditLogConfig=/etc/sw/filer_s3_auditLogConfig.json \ + {{- end }} + {{- end }} + -master={{ if .Values.global.masterServer }}{{.Values.global.masterServer}}{{ else }}{{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} + volumeMounts: + {{- if (or (eq .Values.filer.logs.type "hostPath") (eq .Values.filer.logs.type "persistentVolumeClaim") (eq .Values.filer.logs.type "emptyDir")) }} + - name: seaweedfs-filer-log-volume + mountPath: "/logs/" + {{- end }} + {{- if .Values.filer.s3.enableAuth }} + - name: config-users + mountPath: /etc/sw + readOnly: true + {{- end }} + {{- if (or .Values.filer.enablePVC (or (eq .Values.filer.data.type "hostPath") (eq .Values.filer.data.type "persistentVolumeClaim") (eq .Values.filer.data.type "emptyDir"))) }} + - name: data-filer + mountPath: /data + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.filer.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.filer.port }} + name: swfs-filer + - containerPort: {{ .Values.filer.metricsPort }} + name: metrics + - containerPort: {{ .Values.filer.grpcPort }} + #name: swfs-filer-grpc + {{- if .Values.filer.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.filer.readinessProbe.httpGet.path }} + port: {{ .Values.filer.port }} + scheme: {{ .Values.filer.readinessProbe.scheme }} + initialDelaySeconds: {{ .Values.filer.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.filer.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.filer.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.filer.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.filer.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.filer.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.filer.livenessProbe.httpGet.path }} + port: {{ .Values.filer.port }} + scheme: {{ .Values.filer.livenessProbe.scheme }} + initialDelaySeconds: {{ .Values.filer.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.filer.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.filer.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.filer.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.filer.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.filer.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.filer.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.filer.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.filer.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.filer.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.filer.logs.type "hostPath" }} + - name: seaweedfs-filer-log-volume + hostPath: + path: {{ .Values.filer.logs.hostPathPrefix }}/logs/seaweedfs/filer + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.filer.logs.type "existingClaim" }} + - name: seaweedfs-filer-log-volume + persistentVolumeClaim: + claimName: {{ .Values.filer.logs.claimName }} + {{- end }} + {{- if eq .Values.filer.logs.type "emptyDir" }} + - name: seaweedfs-filer-log-volume + emptyDir: {} + {{- end }} + {{- if eq .Values.filer.data.type "hostPath" }} + - name: data-filer + hostPath: + path: {{ .Values.filer.data.hostPathPrefix }}/filer_store + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.filer.data.type "existingClaim" }} + - name: data-filer + persistentVolumeClaim: + claimName: {{ .Values.filer.data.claimName }} + {{- end }} + {{- if eq .Values.filer.data.type "emptyDir" }} + - name: data-filer + emptyDir: {} + {{- end }} + - name: db-schema-config-volume + configMap: + name: seaweedfs-db-init-config + {{- if and .Values.filer.s3.enabled .Values.filer.s3.enableAuth }} + - name: config-users + secret: + defaultMode: 420 + {{- if .Values.filer.s3.existingConfigSecret }} + secretName: {{ .Values.filer.s3.existingConfigSecret }} + {{- else }} + secretName: seaweedfs-s3-secret + {{- end }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.filer.extraVolumes . | indent 8 | trim }} + {{- if .Values.filer.nodeSelector }} + nodeSelector: + {{ tpl .Values.filer.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- if and (.Values.filer.enablePVC) (eq .Values.filer.data.type "persistentVolumeClaim") }} + # DEPRECATION: Deprecate in favor of filer.data section below + volumeClaimTemplates: + - metadata: + name: data-filer + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.filer.storage }} + {{- if .Values.filer.storageClass }} + storageClassName: {{ .Values.filer.storageClass }} + {{- end }} + {{- end }} + {{- $pvc_exists := include "filer.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.filer.data.type "persistentVolumeClaim" }} + - metadata: + name: data-filer + {{- with .Values.filer.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.filer.data.storageClass }} + resources: + requests: + storage: {{ .Values.filer.data.size }} + {{- end }} + {{- if eq .Values.filer.logs.type "persistentVolumeClaim" }} + - metadata: + name: seaweedfs-filer-log-volume + {{- with .Values.filer.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.filer.logs.storageClass }} + resources: + requests: + storage: {{ .Values.filer.logs.size }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-cert.yaml new file mode 100644 index 00000000..47dcaacd --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-cert.yaml @@ -0,0 +1,41 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-master-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master +spec: + secretName: {{ template "seaweedfs.name" . }}-master-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ .Release.Namespace }}' + - '*.{{ .Release.Namespace }}.svc' + - '*.{{ .Release.Namespace }}.svc.cluster.local' + - '*.{{ template "seaweedfs.name" . }}-master' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-configmap.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-configmap.yaml new file mode 100644 index 00000000..73155e87 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-configmap.yaml @@ -0,0 +1,15 @@ +{{- if .Values.master.enabled }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "seaweedfs.name" . }}-master-config + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +data: + master.toml: |- + {{ .Values.master.config | nindent 4 }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-ingress.yaml new file mode 100644 index 00000000..62d7f7a5 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-ingress.yaml @@ -0,0 +1,48 @@ +{{- if .Values.master.enabled }} +{{- if .Values.master.ingress.enabled }} +{{- 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: ingress-{{ template "seaweedfs.name" . }}-master + namespace: {{ .Release.Namespace }} + {{- with .Values.master.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master +spec: + ingressClassName: {{ .Values.master.ingress.className | quote }} + tls: + {{ .Values.master.ingress.tls | default list | toYaml | nindent 6 }} + rules: + - http: + paths: + - path: /sw-master/?(.*) + pathType: ImplementationSpecific + backend: +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ template "seaweedfs.name" . }}-master + port: + number: {{ .Values.master.port }} + #name: +{{- else }} + serviceName: {{ template "seaweedfs.name" . }}-master + servicePort: {{ .Values.master.port }} +{{- end }} +{{- if .Values.filer.ingress.host }} + host: {{ .Values.master.ingress.host }} +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-service.yaml new file mode 100644 index 00000000..9e69f94e --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-service.yaml @@ -0,0 +1,35 @@ +{{- if .Values.master.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-master + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: master + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + annotations: + service.alpha.kubernetes.io/tolerate-unready-endpoints: "true" +spec: + clusterIP: None + publishNotReadyAddresses: true + ports: + - name: "swfs-master" + port: {{ .Values.master.port }} + targetPort: {{ .Values.master.port }} + protocol: TCP + - name: "swfs-master-grpc" + port: {{ .Values.master.grpcPort }} + targetPort: {{ .Values.master.grpcPort }} + protocol: TCP + {{- if .Values.master.metricsPort }} + - name: "metrics" + port: {{ .Values.master.metricsPort }} + targetPort: {{ .Values.master.metricsPort }} + protocol: TCP + {{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: master +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-servicemonitor.yaml new file mode 100644 index 00000000..81cade2e --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-servicemonitor.yaml @@ -0,0 +1,29 @@ +{{- if .Values.master.enabled }} +{{- if .Values.master.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-master + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: master +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/master-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/master-statefulset.yaml new file mode 100644 index 00000000..73d1f9fb --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/master-statefulset.yaml @@ -0,0 +1,331 @@ +{{- if .Values.master.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "seaweedfs.name" . }}-master + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + serviceName: {{ template "seaweedfs.name" . }}-master + podManagementPolicy: {{ .Values.master.podManagementPolicy }} + replicas: {{ .Values.master.replicas }} + {{- if (gt (int .Values.master.updatePartition) 0) }} + updateStrategy: + type: RollingUpdate + rollingUpdate: + partition: {{ .Values.master.updatePartition }} + {{- end }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.master.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.master.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.master.restartPolicy }} + {{- if .Values.master.affinity }} + affinity: + {{ tpl .Values.master.affinity . | nindent 8 | trim }} + {{- end }} + {{- if .Values.master.tolerations }} + tolerations: + {{ tpl .Values.master.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 60 + {{- if .Values.master.priorityClassName }} + priorityClassName: {{ .Values.master.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.global.createClusterRole }} + serviceAccountName: {{ .Values.master.serviceAccountName | default .Values.global.serviceAccountName | quote }} # for deleting statefulset pods after migration + {{- end }} + {{- if .Values.master.initContainers }} + initContainers: + {{ tpl .Values.master.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.master.podSecurityContext.enabled }} + securityContext: {{- omit .Values.master.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "master.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.master.extraEnvironmentVars }} + {{- range $key, $value := .Values.master.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.master.logs.type "hostPath") (eq .Values.master.logs.type "persistentVolumeClaim") (eq .Values.master.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.master.loggingOverrideLevel }} + -v={{ .Values.master.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + master \ + -port={{ .Values.master.port }} \ + -mdir=/data \ + -ip.bind={{ .Values.master.ipBind }} \ + {{- if .Values.global.enableReplication }} + -defaultReplication={{ .Values.global.replicationPlacment }} \ + {{- else }} + -defaultReplication={{ .Values.master.defaultReplication }} \ + {{- end }} + {{- if .Values.master.volumePreallocate }} + -volumePreallocate \ + {{- end }} + {{- if .Values.global.monitoring.enabled }} + {{- if and .Values.global.monitoring.gatewayHost .Values.global.monitoring.gatewayPort }} + -metrics.address="{{ .Values.global.monitoring.gatewayHost }}:{{ .Values.global.monitoring.gatewayPort }}" \ + {{- if .Values.master.metricsIntervalSec }} + -metrics.intervalSeconds={{ .Values.master.metricsIntervalSec }} \ + {{- end }} + {{- end }} + {{- end }} + {{- if .Values.master.metricsPort }} + -metricsPort={{ .Values.master.metricsPort }} \ + {{- end }} + -volumeSizeLimitMB={{ .Values.master.volumeSizeLimitMB }} \ + {{- if .Values.master.disableHttp }} + -disableHttp \ + {{- end }} + {{- if .Values.master.pulseSeconds }} + -pulseSeconds={{ .Values.master.pulseSeconds }} \ + {{- end }} + {{- if .Values.master.garbageThreshold }} + -garbageThreshold={{ .Values.master.garbageThreshold }} \ + {{- end }} + -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-master.{{ .Release.Namespace }} \ + -peers={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }} + volumeMounts: + - name : data-{{ .Release.Namespace }} + mountPath: /data + {{- if or (eq .Values.master.logs.type "hostPath") (eq .Values.master.logs.type "persistentVolumeClaim") (eq .Values.master.logs.type "emptyDir") }} + - name: seaweedfs-master-log-volume + mountPath: "/logs/" + {{- end }} + - name: master-config + readOnly: true + mountPath: /etc/seaweedfs/master.toml + subPath: master.toml + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.master.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.master.port }} + name: swfs-master + {{- if and .Values.global.monitoring.enabled .Values.master.metricsPort }} + - containerPort: {{ .Values.master.metricsPort }} + name: metrics + {{- end }} + - containerPort: {{ .Values.master.grpcPort }} + #name: swfs-master-grpc + {{- if .Values.master.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.master.readinessProbe.httpGet.path }} + port: {{ .Values.master.port }} + scheme: {{ .Values.master.readinessProbe.scheme }} + initialDelaySeconds: {{ .Values.master.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.master.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.master.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.master.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.master.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.master.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.master.livenessProbe.httpGet.path }} + port: {{ .Values.master.port }} + scheme: {{ .Values.master.livenessProbe.scheme }} + initialDelaySeconds: {{ .Values.master.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.master.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.master.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.master.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.master.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.master.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.master.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.master.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.master.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.master.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if eq .Values.master.logs.type "hostPath" }} + - name: seaweedfs-master-log-volume + hostPath: + path: {{ .Values.master.logs.hostPathPrefix }}/logs/seaweedfs/master + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.master.logs.type "existingClaim" }} + - name: seaweedfs-master-log-volume + persistentVolumeClaim: + claimName: {{ .Values.master.logs.claimName }} + {{- end }} + {{- if eq .Values.master.logs.type "emptyDir" }} + - name: seaweedfs-master-log-volume + emptyDir: {} + {{- end }} + {{- if eq .Values.master.data.type "hostPath" }} + - name: data-{{ .Release.Namespace }} + hostPath: + path: {{ .Values.master.data.hostPathPrefix }}/seaweed-master/ + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.master.data.type "existingClaim" }} + - name: data-{{ .Release.Namespace }} + persistentVolumeClaim: + claimName: {{ .Values.master.data.claimName }} + {{- end }} + {{- if eq .Values.master.data.type "emptyDir" }} + - name: data-{{ .Release.Namespace }} + emptyDir: {} + {{- end }} + - name: master-config + configMap: + name: {{ template "seaweedfs.name" . }}-master-config + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.master.extraVolumes . | indent 8 | trim }} + {{- if .Values.master.nodeSelector }} + nodeSelector: + {{ tpl .Values.master.nodeSelector . | indent 8 | trim }} + {{- end }} + {{- $pvc_exists := include "master.pvc_exists" . -}} + {{- if $pvc_exists }} + volumeClaimTemplates: + {{- if eq .Values.master.data.type "persistentVolumeClaim"}} + - metadata: + name: data-{{ .Release.Namespace }} + {{- with .Values.master.data.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.master.data.storageClass }} + resources: + requests: + storage: {{ .Values.master.data.size }} + {{- end }} + {{- if eq .Values.master.logs.type "persistentVolumeClaim"}} + - metadata: + name: seaweedfs-master-log-volume + {{- with .Values.master.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.master.logs.storageClass }} + resources: + requests: + storage: {{ .Values.master.logs.size }} + {{- end }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/post-install-bucket-hook.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/post-install-bucket-hook.yaml new file mode 100644 index 00000000..2260bd84 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/post-install-bucket-hook.yaml @@ -0,0 +1,102 @@ +{{- if .Values.master.enabled }} +{{- if .Values.filer.s3.enabled }} +{{- if .Values.filer.s3.createBuckets }} +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ $.Release.Name }}-bucket-hook" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + annotations: + "helm.sh/hook": post-install + "helm.sh/hook-weight": "-5" + "helm.sh/hook-delete-policy": hook-succeeded +spec: + template: + metadata: + name: "{{ .Release.Name }}" + labels: + app.kubernetes.io/managed-by: {{ .Release.Service | quote }} + app.kubernetes.io/instance: {{ .Release.Name | quote }} + spec: + restartPolicy: Never + {{- if .Values.filer.podSecurityContext.enabled }} + securityContext: {{- omit .Values.filer.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: post-install-job + image: {{ template "master.image" . }} + env: + - name: WEED_CLUSTER_DEFAULT + value: "sw" + - name: WEED_CLUSTER_SW_MASTER + value: "{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}:9333" + - name: WEED_CLUSTER_SW_FILER + value: "{{ template "seaweedfs.name" . }}-filer-client.{{ .Release.Namespace }}:8888" + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + command: + - "/bin/sh" + - "-ec" + - | + {{- range $reg, $props := $.Values.filer.s3.createBuckets }} + exec /bin/echo \ + "s3.bucket.create --name {{ $props.name }}" |\ + /usr/bin/weed shell + {{- end }} + {{- range $reg, $props := $.Values.filer.s3.createBuckets }} + {{- if $props.anonymousRead }} + exec /bin/echo \ + "s3.configure --user anonymous \ + --buckets {{ $props.name }} \ + --actions Read \ + --apply true" |\ + /usr/bin/weed shell + {{- end }} + {{- end }} + {{- if .Values.filer.s3.enableAuth }} + volumeMounts: + - name: config-users + mountPath: /etc/sw + readOnly: true + {{- end }} + ports: + - containerPort: {{ .Values.master.port }} + name: swfs-master + {{- if and .Values.global.monitoring.enabled .Values.master.metricsPort }} + - containerPort: {{ .Values.master.metricsPort }} + name: metrics + {{- end }} + - containerPort: {{ .Values.master.grpcPort }} + #name: swfs-master-grpc + {{- if .Values.filer.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.filer.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.filer.s3.enableAuth }} + volumes: + - name: config-users + secret: + defaultMode: 420 + {{- if not (empty .Values.filer.s3.existingConfigSecret) }} + secretName: {{ .Values.filer.s3.existingConfigSecret }} + {{- else }} + secretName: seaweedfs-s3-secret + {{- end }} + {{- end }}{{/** if .Values.filer.s3.enableAuth **/}} +{{- end }}{{/** if .Values.master.enabled **/}} +{{- end }}{{/** if .Values.filer.s3.enabled **/}} +{{- end }}{{/** if .Values.filer.s3.createBuckets **/}} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3-deployment.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-deployment.yaml new file mode 100644 index 00000000..b678a0ef --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-deployment.yaml @@ -0,0 +1,263 @@ +{{- if .Values.s3.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ template "seaweedfs.name" . }}-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + replicas: {{ .Values.s3.replicas }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: s3 + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: s3 + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.s3.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.s3.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + restartPolicy: {{ default .Values.global.restartPolicy .Values.s3.restartPolicy }} + {{- if .Values.s3.tolerations }} + tolerations: + {{ tpl .Values.s3.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 10 + {{- if .Values.s3.priorityClassName }} + priorityClassName: {{ .Values.s3.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.s3.serviceAccountName }} + serviceAccountName: {{ .Values.s3.serviceAccountName | quote }} + {{- end }} + {{- if .Values.s3.initContainers }} + initContainers: + {{ tpl .Values.s3.initContainers . | nindent 8 | trim }} + {{- end }} + {{- if .Values.s3.podSecurityContext.enabled }} + securityContext: {{- omit .Values.s3.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "s3.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.s3.extraEnvironmentVars }} + {{- range $key, $value := .Values.s3.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if or (eq .Values.s3.logs.type "hostPath") (eq .Values.s3.logs.type "emptyDir") }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.s3.loggingOverrideLevel }} + -v={{ .Values.s3.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + s3 \ + -ip.bind={{ .Values.s3.bindAddress }} \ + -port={{ .Values.s3.port }} \ + {{- if .Values.s3.metricsPort }} + -metricsPort {{ .Values.s3.metricsPort }} \ + {{- end }} + {{- if .Values.global.enableSecurity }} + {{- if .Values.s3.httpsPort }} + -port.https={{ .Values.s3.httpsPort }} \ + {{- end }} + -cert.file=/usr/local/share/ca-certificates/client/tls.crt \ + -key.file=/usr/local/share/ca-certificates/client/tls.key \ + {{- end }} + {{- if .Values.s3.domainName }} + -domainName={{ .Values.s3.domainName }} \ + {{- end }} + {{- if .Values.s3.allowEmptyFolder }} + -allowEmptyFolder={{ .Values.s3.allowEmptyFolder }} \ + {{- end }} + {{- if .Values.s3.enableAuth }} + -config=/etc/sw/seaweedfs_s3_config \ + {{- end }} + {{- if .Values.s3.auditLogConfig }} + -auditLogConfig=/etc/sw/s3_auditLogConfig.json \ + {{- end }} + -filer={{ template "seaweedfs.name" . }}-filer-client.{{ .Release.Namespace }}:{{ .Values.filer.port }} + volumeMounts: + {{- if or (eq .Values.s3.logs.type "hostPath") (eq .Values.s3.logs.type "emptyDir") }} + - name: logs + mountPath: "/logs/" + {{- end }} + {{- if .Values.s3.enableAuth }} + - mountPath: /etc/sw + name: config-users + readOnly: true + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.s3.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.s3.port }} + name: swfs-s3 + {{- if .Values.s3.metricsPort }} + - containerPort: {{ .Values.s3.metricsPort }} + name: "metrics" + {{- end }} + {{- if .Values.s3.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.s3.readinessProbe.httpGet.path }} + port: {{ .Values.s3.port }} + scheme: {{ .Values.s3.readinessProbe.scheme }} + initialDelaySeconds: {{ .Values.s3.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.s3.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.s3.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.s3.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.s3.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.s3.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.s3.livenessProbe.httpGet.path }} + port: {{ .Values.s3.port }} + scheme: {{ .Values.s3.livenessProbe.scheme }} + initialDelaySeconds: {{ .Values.s3.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.s3.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.s3.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.s3.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.s3.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.s3.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.s3.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.s3.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.s3.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.s3.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + {{- if .Values.s3.enableAuth }} + - name: config-users + secret: + defaultMode: 420 + {{- if .Values.s3.existingConfigSecret }} + secretName: {{ .Values.s3.existingConfigSecret }} + {{- else }} + secretName: seaweedfs-s3-secret + {{- end }} + {{- end }} + {{- if eq .Values.s3.logs.type "hostPath" }} + - name: logs + hostPath: + path: {{ .Values.s3.logs.hostPathPrefix }}/logs/seaweedfs/s3 + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.s3.logs.type "emptyDir" }} + - name: logs + emptyDir: {} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{ tpl .Values.s3.extraVolumes . | indent 8 | trim }} + {{- if .Values.s3.nodeSelector }} + nodeSelector: + {{ tpl .Values.s3.nodeSelector . | indent 8 | trim }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3-ingress.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-ingress.yaml new file mode 100644 index 00000000..7b279793 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-ingress.yaml @@ -0,0 +1,46 @@ +{{- if .Values.s3.ingress.enabled }} +{{- 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: ingress-{{ template "seaweedfs.name" . }}-s3 + namespace: {{ .Release.Namespace }} + {{- with .Values.s3.ingress.annotations }} + annotations: + {{- toYaml . | nindent 4 }} + {{- end }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: s3 +spec: + ingressClassName: {{ .Values.s3.ingress.className | quote }} + tls: + {{ .Values.s3.ingress.tls | default list | toYaml | nindent 6}} + rules: + - http: + paths: + - path: / + pathType: ImplementationSpecific + backend: +{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion }} + service: + name: {{ template "seaweedfs.name" . }}-s3 + port: + number: {{ .Values.s3.port }} + #name: +{{- else }} + serviceName: {{ template "seaweedfs.name" . }}-s3 + servicePort: {{ .Values.s3.port }} +{{- end }} +{{- if .Values.s3.ingress.host }} + host: {{ .Values.s3.ingress.host }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3-secret.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-secret.yaml new file mode 100644 index 00000000..969b31f5 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-secret.yaml @@ -0,0 +1,35 @@ +{{- if or (and .Values.filer.s3.enabled .Values.filer.s3.enableAuth (not .Values.filer.s3.existingConfigSecret)) (and .Values.s3.enabled .Values.s3.enableAuth (not .Values.s3.existingConfigSecret)) }} +{{- $access_key_admin := randAlphaNum 16 -}} +{{- $secret_key_admin := randAlphaNum 32 -}} +{{- $access_key_read := randAlphaNum 16 -}} +{{- $secret_key_read := randAlphaNum 32 -}} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: seaweedfs-s3-secret + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/resource-policy": keep + "helm.sh/hook": "pre-install" + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: s3 +stringData: + admin_access_key_id: {{ $access_key_admin }} + admin_secret_access_key: {{ $secret_key_admin }} + read_access_key_id: {{ $access_key_read }} + read_secret_access_key: {{ $secret_key_read }} + seaweedfs_s3_config: '{"identities":[{"name":"anvAdmin","credentials":[{"accessKey":"{{ $access_key_admin }}","secretKey":"{{ $secret_key_admin }}"}],"actions":["Admin","Read","Write"]},{"name":"anvReadOnly","credentials":[{"accessKey":"{{ $access_key_read }}","secretKey":"{{ $secret_key_read }}"}],"actions":["Read"]}]}' + {{- if .Values.filer.s3.auditLogConfig }} + filer_s3_auditLogConfig.json: | + {{ toJson .Values.filer.s3.auditLogConfig | nindent 4 }} + {{- end }} + {{- if .Values.s3.auditLogConfig }} + s3_auditLogConfig.json: | + {{ toJson .Values.s3.auditLogConfig | nindent 4 }} + {{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-service.yaml new file mode 100644 index 00000000..01d79ad7 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-service.yaml @@ -0,0 +1,34 @@ +{{- if or .Values.s3.enabled .Values.filer.s3.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: s3 + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + internalTrafficPolicy: {{ .Values.s3.internalTrafficPolicy | default "Cluster" }} + ports: + - name: "swfs-s3" + port: {{ if .Values.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }} + targetPort: {{ if .Values.s3.enabled }}{{ .Values.s3.port }}{{ else }}{{ .Values.filer.s3.port }}{{ end }} + protocol: TCP +{{- if and .Values.s3.enabled .Values.s3.httpsPort }} + - name: "swfs-s3-tls" + port: {{ .Values.s3.httpsPort }} + targetPort: {{ .Values.s3.httpsPort }} + protocol: TCP +{{- end }} +{{- if and .Values.s3.enabled .Values.s3.metricsPort }} + - name: "metrics" + port: {{ .Values.s3.metricsPort }} + targetPort: {{ .Values.s3.metricsPort }} + protocol: TCP +{{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: {{ if .Values.s3.enabled }}s3{{ else }}filer{{ end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/s3-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-servicemonitor.yaml new file mode 100644 index 00000000..b47ba8ee --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/s3-servicemonitor.yaml @@ -0,0 +1,29 @@ +{{- if or .Values.s3.enabled .Values.filer.s3.enabled }} +{{- if .Values.s3.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-s3 + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: s3 + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app: {{ template "seaweedfs.name" . }} + component: s3 +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml new file mode 100644 index 00000000..eb5a5eba --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml @@ -0,0 +1,20 @@ +{{- if .Values.global.monitoring.enabled }} +{{- $files := .Files.Glob "dashboards/*.json" }} +{{- if $files }} +apiVersion: v1 +kind: ConfigMapList +items: +{{- range $path, $fileContents := $files }} +{{- $dashboardName := regexReplaceAll "(^.*/)(.*)\\.json$" $path "${2}" }} +- apiVersion: v1 + kind: ConfigMap + metadata: + name: {{ printf "%s" $dashboardName | lower | replace "_" "-" }} + namespace: {{ $.Release.Namespace }} + labels: + grafana_dashboard: "1" + data: + {{ $dashboardName }}.json: {{ $.Files.Get $path | toJson }} +{{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/secret-seaweedfs-db.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/secret-seaweedfs-db.yaml new file mode 100644 index 00000000..5b7a8103 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/secret-seaweedfs-db.yaml @@ -0,0 +1,21 @@ +{{- if .Values.filer.enabled }} +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: secret-seaweedfs-db + namespace: {{ .Release.Namespace }} + annotations: + "helm.sh/resource-policy": keep + "helm.sh/hook": "pre-install" + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +stringData: + user: "YourSWUser" + password: "HardCodedPassword" + # better to random generate and create in DB + # password: {{ randAlphaNum 10 | sha256sum | b64enc | trunc 32 }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/security-configmap.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/security-configmap.yaml new file mode 100644 index 00000000..884fe6bb --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/security-configmap.yaml @@ -0,0 +1,80 @@ +{{- if .Values.global.enableSecurity }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ template "seaweedfs.name" . }}-security-config + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +data: + security.toml: |- + # this file is read by master, volume server, and filer + + {{- if .Values.global.securityConfig.jwtSigning.volumeWrite }} + # the jwt signing key is read by master and volume server + # a jwt expires in 10 seconds + [jwt.signing] + key = "{{ randAlphaNum 10 | b64enc }}" + {{- end }} + + {{- if .Values.global.securityConfig.jwtSigning.volumeRead }} + # this jwt signing key is read by master and volume server, and it is used for read operations: + # - the Master server generates the JWT, which can be used to read a certain file on a volume server + # - the Volume server validates the JWT on reading + [jwt.signing.read] + key = "{{ randAlphaNum 10 | b64enc }}" + {{- end }} + + {{- if .Values.global.securityConfig.jwtSigning.filerWrite }} + # If this JWT key is configured, Filer only accepts writes over HTTP if they are signed with this JWT: + # - f.e. the S3 API Shim generates the JWT + # - the Filer server validates the JWT on writing + # the jwt defaults to expire after 10 seconds. + [jwt.filer_signing] + key = "{{ randAlphaNum 10 | b64enc }}" + {{- end }} + + {{- if .Values.global.securityConfig.jwtSigning.filerRead }} + # If this JWT key is configured, Filer only accepts reads over HTTP if they are signed with this JWT: + # - f.e. the S3 API Shim generates the JWT + # - the Filer server validates the JWT on writing + # the jwt defaults to expire after 10 seconds. + [jwt.filer_signing.read] + key = "{{ randAlphaNum 10 | b64enc }}" + {{- end }} + + # all grpc tls authentications are mutual + # the values for the following ca, cert, and key are paths to the PERM files. + [grpc] + ca = "/usr/local/share/ca-certificates/ca/tls.crt" + + [grpc.volume] + cert = "/usr/local/share/ca-certificates/volume/tls.crt" + key = "/usr/local/share/ca-certificates/volume/tls.key" + + [grpc.master] + cert = "/usr/local/share/ca-certificates/master/tls.crt" + key = "/usr/local/share/ca-certificates/master/tls.key" + + [grpc.filer] + cert = "/usr/local/share/ca-certificates/filer/tls.crt" + key = "/usr/local/share/ca-certificates/filer/tls.key" + + # use this for any place needs a grpc client + # i.e., "weed backup|benchmark|filer.copy|filer.replicate|mount|s3|upload" + [grpc.client] + cert = "/usr/local/share/ca-certificates/client/tls.crt" + key = "/usr/local/share/ca-certificates/client/tls.key" + + # volume server https options + # Note: work in progress! + # this does not work with other clients, e.g., "weed filer|mount" etc, yet. + [https.client] + enabled = false + [https.volume] + cert = "" + key = "" +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/service-account.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/service-account.yaml new file mode 100644 index 00000000..429158a2 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/service-account.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ .Values.global.serviceAccountName }} + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +automountServiceAccountToken: {{ .Values.global.automountServiceAccountToken }} \ No newline at end of file diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-cert.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-cert.yaml new file mode 100644 index 00000000..4df63db2 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-cert.yaml @@ -0,0 +1,41 @@ +{{- if and .Values.global.enableSecurity (not .Values.certificates.externalCertificates.enabled)}} +apiVersion: cert-manager.io/v1{{ if .Values.global.certificates.alphacrds }}alpha1{{ end }} +kind: Certificate +metadata: + name: {{ template "seaweedfs.name" . }}-volume-cert + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: volume +spec: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + issuerRef: + name: {{ template "seaweedfs.name" . }}-ca-issuer + kind: Issuer + commonName: {{ .Values.certificates.commonName }} + subject: + organizations: + - "SeaweedFS CA" + dnsNames: + - '*.{{ .Release.Namespace }}' + - '*.{{ .Release.Namespace }}.svc' + - '*.{{ .Release.Namespace }}.svc.cluster.local' + - '*.{{ template "seaweedfs.name" . }}-master' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc' + - '*.{{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc.cluster.local' +{{- if .Values.certificates.ipAddresses }} + ipAddresses: + {{- range .Values.certificates.ipAddresses }} + - {{ . }} + {{- end }} +{{- end }} + privateKey: + algorithm: {{ .Values.certificates.keyAlgorithm }} + size: {{ .Values.certificates.keySize }} + duration: {{ .Values.certificates.duration }} + renewBefore: {{ .Values.certificates.renewBefore }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml new file mode 100644 index 00000000..9f186eaa --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml @@ -0,0 +1,117 @@ +{{- if and .Values.volume.enabled .Values.volume.resizeHook.enabled }} +{{- $seaweedfsName := include "seaweedfs.name" $ }} +{{- $replicas := int .Values.volume.replicas -}} +{{- $statefulsetName := printf "%s-volume" $seaweedfsName -}} +{{- $statefulset := (lookup "apps/v1" "StatefulSet" .Release.Namespace $statefulsetName) -}} + +{{/* Check for changes in volumeClaimTemplates */}} +{{- $templateChangesRequired := false -}} +{{- if $statefulset -}} + {{- range $dir := .Values.volume.dataDirs -}} + {{- if eq .type "persistentVolumeClaim" -}} + {{- $desiredSize := .size -}} + {{- range $statefulset.spec.volumeClaimTemplates -}} + {{- if and (eq .metadata.name $dir.name) (ne .spec.resources.requests.storage $desiredSize) -}} + {{- $templateChangesRequired = true -}} + {{- end -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{/* Check for the need for patching existing PVCs */}} +{{- $pvcChangesRequired := false -}} +{{- range $dir := .Values.volume.dataDirs -}} + {{- if eq .type "persistentVolumeClaim" -}} + {{- $desiredSize := .size -}} + {{- range $i, $e := until $replicas }} + {{- $pvcName := printf "%s-%s-volume-%d" $dir.name $seaweedfsName $e -}} + {{- $currentPVC := (lookup "v1" "PersistentVolumeClaim" $.Release.Namespace $pvcName) -}} + {{- if and $currentPVC (ne ($currentPVC.spec.resources.requests.storage | toString) $desiredSize) -}} + {{- $pvcChangesRequired = true -}} + {{- end -}} + {{- end -}} + {{- end -}} +{{- end -}} + +{{- if or $templateChangesRequired $pvcChangesRequired }} +apiVersion: batch/v1 +kind: Job +metadata: + name: "{{ $seaweedfsName }}-volume-resize-hook" + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "0" + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation +spec: + template: + metadata: + labels: + policy.cozystack.io/allow-to-apiserver: "true" + spec: + serviceAccountName: {{ $seaweedfsName }}-volume-resize-hook + restartPolicy: Never + backoffLimit: 1 + containers: + - name: resize + image: {{ .Values.volume.resizeHook.image }} + command: ["sh", "-xec"] + args: + - | + {{- if $pvcChangesRequired -}} + {{- range $dir := .Values.volume.dataDirs -}} + {{- if eq .type "persistentVolumeClaim" -}} + {{- $desiredSize := .size -}} + {{- range $i, $e := until $replicas }} + kubectl patch pvc {{ printf "%s-%s-volume-%d" $dir.name $seaweedfsName $e }} -p '{"spec":{"resources":{"requests":{"storage":"{{ $desiredSize }}"}}}}' + {{- end }} + {{- end }} + {{- end }} + {{- end -}} + + {{- if $templateChangesRequired }} + kubectl delete statefulset {{ $statefulsetName }} --cascade=orphan + {{- end }} +{{- end }} +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + name: {{ $seaweedfsName }}-volume-resize-hook + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: {{ $seaweedfsName }}-volume-resize-hook + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation +rules: + - apiGroups: ["apps"] + resources: ["statefulsets"] + verbs: ["delete", "get", "list", "watch"] + - apiGroups: [""] + resources: ["persistentvolumeclaims"] + verbs: ["patch", "get", "list", "watch"] +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: {{ $seaweedfsName }}-volume-resize-hook + annotations: + helm.sh/hook: pre-install,pre-upgrade + helm.sh/hook-weight: "-5" + helm.sh/hook-delete-policy: before-hook-creation +subjects: + - kind: ServiceAccount + name: {{ $seaweedfsName }}-volume-resize-hook +roleRef: + kind: Role + name: {{ $seaweedfsName }}-volume-resize-hook + apiGroup: rbac.authorization.k8s.io +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-service.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-service.yaml new file mode 100644 index 00000000..1205f4fa --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-service.yaml @@ -0,0 +1,33 @@ +{{- if .Values.volume.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ template "seaweedfs.name" . }}-volume + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: volume + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +spec: + clusterIP: None + internalTrafficPolicy: {{ .Values.volume.internalTrafficPolicy | default "Cluster" }} + ports: + - name: "swfs-volume" + port: {{ .Values.volume.port }} + targetPort: {{ .Values.volume.port }} + protocol: TCP + - name: "swfs-volume-18080" + port: {{ .Values.volume.grpcPort }} + targetPort: {{ .Values.volume.grpcPort }} + protocol: TCP +{{- if .Values.volume.metricsPort }} + - name: "metrics" + port: {{ .Values.volume.metricsPort }} + targetPort: {{ .Values.volume.metricsPort }} + protocol: TCP +{{- end }} + selector: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: volume +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-servicemonitor.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-servicemonitor.yaml new file mode 100644 index 00000000..4aeacc41 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-servicemonitor.yaml @@ -0,0 +1,29 @@ +{{- if .Values.volume.enabled }} +{{- if .Values.volume.metricsPort }} +{{- if .Values.global.monitoring.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: {{ template "seaweedfs.name" . }}-volume + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: volume + {{- with .Values.global.monitoring.additionalLabels }} + {{- toYaml . | nindent 4 }} + {{- end }} +spec: + endpoints: + - interval: 30s + port: metrics + scrapeTimeout: 5s + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/component: volume +{{- end }} +{{- end }} +{{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml new file mode 100644 index 00000000..eb3bb913 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml @@ -0,0 +1,388 @@ +{{- if .Values.volume.enabled }} +apiVersion: apps/v1 +kind: StatefulSet +metadata: + name: {{ template "seaweedfs.name" . }}-volume + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + persistentVolumeClaimRetentionPolicy: + whenDeleted: Delete + whenScaled: Delete + serviceName: {{ template "seaweedfs.name" . }}-volume + replicas: {{ .Values.volume.replicas }} + podManagementPolicy: {{ .Values.volume.podManagementPolicy }} + selector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: volume + template: + metadata: + labels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: volume + {{ with .Values.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.volume.podLabels }} + {{- toYaml . | nindent 8 }} + {{- end }} + annotations: + {{ with .Values.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + {{- with .Values.volume.podAnnotations }} + {{- toYaml . | nindent 8 }} + {{- end }} + spec: + {{- if .Values.volume.affinity }} + affinity: + {{ tpl .Values.volume.affinity . | nindent 8 | trim }} + {{- end }} + restartPolicy: {{ default .Values.global.restartPolicy .Values.volume.restartPolicy }} + {{- if .Values.volume.tolerations }} + tolerations: + {{ tpl .Values.volume.tolerations . | nindent 8 | trim }} + {{- end }} + {{- include "seaweedfs.imagePullSecrets" . | nindent 6 }} + terminationGracePeriodSeconds: 150 + {{- if .Values.volume.priorityClassName }} + priorityClassName: {{ .Values.volume.priorityClassName | quote }} + {{- end }} + enableServiceLinks: false + {{- if .Values.global.createClusterRole }} + serviceAccountName: {{ .Values.volume.serviceAccountName | default .Values.global.serviceAccountName | quote }} # for deleting statefulset pods after migration + {{- end }} + {{- $initContainers_exists := include "volume.initContainers_exists" . -}} + {{- if $initContainers_exists }} + initContainers: + {{- if .Values.volume.idx }} + - name: seaweedfs-vol-move-idx + image: {{ template "volume.image" . }} + imagePullPolicy: {{ .Values.global.imagePullPolicy | default "IfNotPresent" }} + command: [ '/bin/sh', '-c' ] + args: [ '{{range $dir := .Values.volume.dataDirs }}if ls /{{$dir.name}}/*.idx >/dev/null 2>&1; then mv /{{$dir.name}}/*.idx /idx/ ; fi; {{end}}' ] + volumeMounts: + - name: idx + mountPath: /idx + {{- range $dir := .Values.volume.dataDirs }} + - name: {{ $dir.name }} + mountPath: /{{ $dir.name }} + {{- end }} + {{- end }} + {{- if .Values.volume.initContainers }} + {{ tpl .Values.volume.initContainers . | nindent 8 | trim }} + {{- end }} + {{- end }} + {{- if .Values.volume.podSecurityContext.enabled }} + securityContext: {{- omit .Values.volume.podSecurityContext "enabled" | toYaml | nindent 8 }} + {{- end }} + containers: + - name: seaweedfs + image: {{ template "volume.image" . }} + imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: SEAWEEDFS_FULLNAME + value: "{{ template "seaweedfs.name" . }}" + {{- if .Values.volume.extraEnvironmentVars }} + {{- range $key, $value := .Values.volume.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + {{- if .Values.global.extraEnvironmentVars }} + {{- range $key, $value := .Values.global.extraEnvironmentVars }} + - name: {{ $key }} + {{- if kindIs "string" $value }} + value: {{ $value | quote }} + {{- else }} + valueFrom: + {{ toYaml $value | nindent 16 | trim }} + {{- end -}} + {{- end }} + {{- end }} + command: + - "/bin/sh" + - "-ec" + - | + exec /usr/bin/weed \ + {{- if .Values.volume.logs }} + -logdir=/logs \ + {{- else }} + -logtostderr=true \ + {{- end }} + {{- if .Values.volume.loggingOverrideLevel }} + -v={{ .Values.volume.loggingOverrideLevel }} \ + {{- else }} + -v={{ .Values.global.loggingLevel }} \ + {{- end }} + volume \ + -port={{ .Values.volume.port }} \ + {{- if .Values.volume.metricsPort }} + -metricsPort={{ .Values.volume.metricsPort }} \ + {{- end }} + -dir {{range $index, $dir := .Values.volume.dataDirs }}{{if ne $index 0}},{{end}}/{{$dir.name}}{{end}} \ + {{- if .Values.volume.idx }} + -dir.idx=/idx \ + {{- end }} + -max {{range $index, $dir := .Values.volume.dataDirs }}{{if ne $index 0}},{{end}}{{$dir.maxVolumes}}{{end}} \ + {{- if .Values.volume.rack }} + -rack={{ .Values.volume.rack }} \ + {{- end }} + {{- if .Values.volume.dataCenter }} + -dataCenter={{ .Values.volume.dataCenter }} \ + {{- end }} + -ip.bind={{ .Values.volume.ipBind }} \ + -readMode={{ .Values.volume.readMode }} \ + {{- if .Values.volume.whiteList }} + -whiteList={{ .Values.volume.whiteList }} \ + {{- end }} + {{- if .Values.volume.imagesFixOrientation }} + -images.fix.orientation \ + {{- end }} + {{- if .Values.volume.pulseSeconds }} + -pulseSeconds={{ .Values.volume.pulseSeconds }} \ + {{- end }} + {{- if .Values.volume.index }} + -index={{ .Values.volume.index }} \ + {{- end }} + {{- if .Values.volume.fileSizeLimitMB }} + -fileSizeLimitMB={{ .Values.volume.fileSizeLimitMB }} \ + {{- end }} + -minFreeSpacePercent={{ .Values.volume.minFreeSpacePercent }} \ + -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-volume.{{ .Release.Namespace }} \ + -compactionMBps={{ .Values.volume.compactionMBps }} \ + -mserver={{ if .Values.global.masterServer }}{{.Values.global.masterServer}}{{ else }}{{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master.{{ $.Release.Namespace }}:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}{{ end }} + volumeMounts: + {{- range $dir := .Values.volume.dataDirs }} + - name: {{ $dir.name }} + mountPath: "/{{ $dir.name }}/" + {{- end }} + {{- if .Values.volume.logs }} + - name: logs + mountPath: "/logs/" + {{- end }} + {{- if .Values.volume.idx }} + - name: idx + mountPath: "/idx/" + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + readOnly: true + mountPath: /etc/seaweedfs/security.toml + subPath: security.toml + - name: ca-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/ca/ + - name: master-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/master/ + - name: volume-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/volume/ + - name: filer-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/filer/ + - name: client-cert + readOnly: true + mountPath: /usr/local/share/ca-certificates/client/ + {{- end }} + {{ tpl .Values.volume.extraVolumeMounts . | nindent 12 | trim }} + ports: + - containerPort: {{ .Values.volume.port }} + name: swfs-vol + {{- if .Values.volume.metricsPort }} + - containerPort: {{ .Values.volume.metricsPort }} + name: metrics + {{- end }} + - containerPort: {{ .Values.volume.grpcPort }} + name: swfs-vol-grpc + {{- if .Values.volume.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: {{ .Values.volume.readinessProbe.httpGet.path }} + port: {{ .Values.volume.port }} + scheme: {{ .Values.volume.readinessProbe.scheme }} + initialDelaySeconds: {{ .Values.volume.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.volume.readinessProbe.periodSeconds }} + successThreshold: {{ .Values.volume.readinessProbe.successThreshold }} + failureThreshold: {{ .Values.volume.readinessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.volume.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.volume.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: {{ .Values.volume.livenessProbe.httpGet.path }} + port: {{ .Values.volume.port }} + scheme: {{ .Values.volume.livenessProbe.scheme }} + initialDelaySeconds: {{ .Values.volume.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.volume.livenessProbe.periodSeconds }} + successThreshold: {{ .Values.volume.livenessProbe.successThreshold }} + failureThreshold: {{ .Values.volume.livenessProbe.failureThreshold }} + timeoutSeconds: {{ .Values.volume.livenessProbe.timeoutSeconds }} + {{- end }} + {{- with .Values.volume.resources }} + resources: + {{- toYaml . | nindent 12 }} + {{- end }} + {{- if .Values.volume.containerSecurityContext.enabled }} + securityContext: {{- omit .Values.volume.containerSecurityContext "enabled" | toYaml | nindent 12 }} + {{- end }} + {{- if .Values.volume.sidecars }} + {{- include "common.tplvalues.render" (dict "value" .Values.volume.sidecars "context" $) | nindent 8 }} + {{- end }} + volumes: + + {{- range $dir := .Values.volume.dataDirs }} + + {{- if eq $dir.type "hostPath" }} + - name: {{ $dir.name }} + hostPath: + path: {{ $dir.hostPathPrefix }}/object_store/ + type: DirectoryOrCreate + {{- end }} + {{- if eq $dir.type "existingClaim" }} + - name: {{ $dir.name }} + persistentVolumeClaim: + claimName: {{ $dir.claimName }} + {{- end }} + {{- if eq $dir.type "emptyDir" }} + - name: {{ $dir.name }} + emptyDir: {} + {{- end }} + + {{- end }} + + {{- if .Values.volume.idx }} + {{- if eq .Values.volume.idx.type "hostPath" }} + - name: idx + hostPath: + path: {{ .Values.volume.idx.hostPathPrefix }}/seaweedfs-volume-idx/ + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.volume.idx.type "existingClaim" }} + - name: idx + persistentVolumeClaim: + claimName: {{ .Values.volume.idx.claimName }} + {{- end }} + {{- if eq .Values.volume.idx.type "emptyDir" }} + - name: idx + emptyDir: {} + {{- end }} + {{- end }} + + {{- if .Values.volume.logs }} + {{- if eq .Values.volume.logs.type "hostPath" }} + - name: logs + hostPath: + path: {{ .Values.volume.logs.hostPathPrefix }}/logs/seaweedfs/volume + type: DirectoryOrCreate + {{- end }} + {{- if eq .Values.volume.logs.type "existingClaim" }} + - name: logs + persistentVolumeClaim: + claimName: {{ .Values.volume.logs.claimName }} + {{- end }} + {{- if eq .Values.volume.logs.type "emptyDir" }} + - name: logs + emptyDir: {} + {{- end }} + {{- end }} + {{- if .Values.global.enableSecurity }} + - name: security-config + configMap: + name: {{ template "seaweedfs.name" . }}-security-config + - name: ca-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-ca-cert + - name: master-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-master-cert + - name: volume-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-volume-cert + - name: filer-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-filer-cert + - name: client-cert + secret: + secretName: {{ template "seaweedfs.name" . }}-client-cert + {{- end }} + {{- if .Values.volume.extraVolumes }} + {{ tpl .Values.volume.extraVolumes . | indent 8 | trim }} + {{- end }} + {{- if .Values.volume.nodeSelector }} + nodeSelector: + {{ tpl .Values.volume.nodeSelector . | indent 8 | trim }} + {{- end }} + volumeClaimTemplates: + {{- range $dir := .Values.volume.dataDirs }} + {{- if eq $dir.type "persistentVolumeClaim" }} + - metadata: + name: {{ $dir.name }} + {{- with $dir.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ $dir.storageClass }} + resources: + requests: + storage: {{ $dir.size }} + {{- end }} + {{- end }} + + {{- if and .Values.volume.idx (eq .Values.volume.idx.type "persistentVolumeClaim") }} + - metadata: + name: idx + {{- with .Values.volume.idx.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.volume.idx.storageClass }} + resources: + requests: + storage: {{ .Values.volume.idx.size }} + {{- end }} + {{- if and .Values.volume.logs (eq .Values.volume.logs.type "persistentVolumeClaim") }} + - metadata: + name: logs + {{- with .Values.volume.logs.annotations }} + annotations: + {{- toYaml . | nindent 10 }} + {{- end }} + spec: + accessModes: [ "ReadWriteOnce" ] + storageClassName: {{ .Values.volume.logs.storageClass }} + resources: + requests: + storage: {{ .Values.volume.logs.size }} + {{- end }} + {{- end }} diff --git a/packages/system/seaweedfs/charts/seaweedfs/values.yaml b/packages/system/seaweedfs/charts/seaweedfs/values.yaml new file mode 100644 index 00000000..e53fa596 --- /dev/null +++ b/packages/system/seaweedfs/charts/seaweedfs/values.yaml @@ -0,0 +1,917 @@ +# Available parameters and their default values for the SeaweedFS chart. + +global: + createClusterRole: true + registry: "" + repository: "" + imageName: chrislusf/seaweedfs + imagePullPolicy: IfNotPresent + imagePullSecrets: "" + restartPolicy: Always + loggingLevel: 1 + enableSecurity: false + masterServer: null + securityConfig: + jwtSigning: + volumeWrite: true + volumeRead: false + filerWrite: false + filerRead: false + # we will use this serviceAccountName for all ClusterRoles/ClusterRoleBindings + serviceAccountName: "seaweedfs" + automountServiceAccountToken: true + certificates: + alphacrds: false + monitoring: + enabled: false + gatewayHost: null + gatewayPort: null + additionalLabels: {} + # if enabled will use global.replicationPlacment and override master & filer defaultReplicaPlacement config + enableReplication: false + # replication type is XYZ: + # X number of replica in other data centers + # Y number of replica in other racks in the same data center + # Z number of replica in other servers in the same rack + replicationPlacment: "001" + extraEnvironmentVars: + WEED_CLUSTER_DEFAULT: "sw" + WEED_CLUSTER_SW_MASTER: "seaweedfs-master.seaweedfs:9333" + WEED_CLUSTER_SW_FILER: "seaweedfs-filer-client.seaweedfs:8888" + # WEED_JWT_SIGNING_KEY: + # secretKeyRef: + # name: seaweedfs-signing-key + # key: signingKey + +image: + registry: "" + repository: "" + +master: + enabled: true + imageOverride: null + restartPolicy: null + replicas: 1 + port: 9333 + grpcPort: 19333 + metricsPort: 9327 + ipBind: "0.0.0.0" + volumePreallocate: false + volumeSizeLimitMB: 1000 + loggingOverrideLevel: null + # number of seconds between heartbeats, default 5 + pulseSeconds: null + # threshold to vacuum and reclaim spaces, default 0.3 (30%) + garbageThreshold: null + # Prometheus push interval in seconds, default 15 + metricsIntervalSec: 15 + # replication type is XYZ: + # X number of replica in other data centers + # Y number of replica in other racks in the same data center + # Z number of replica in other servers in the same rack + defaultReplication: "000" + + # Disable http request, only gRpc operations are allowed + disableHttp: false + + config: |- + # Enter any extra configuration for master.toml here. + # It may be a multi-line string. + + # You may use ANY storage-class, example with local-path-provisioner + # Annotations are optional. + # data: + # type: "persistentVolumeClaim" + # size: "24Ti" + # storageClass: "local-path-provisioner" + # annotations: + # "key": "value" + # + # You may also spacify an existing claim: + # data: + # type: "existingClaim" + # claimName: "my-pvc" + # + # You can also use emptyDir storage: + # data: + # type: "emptyDir" + data: + type: "hostPath" + storageClass: "" + hostPathPrefix: /ssd + + # You can also use emptyDir storage: + # logs: + # type: "emptyDir" + logs: + type: "hostPath" + size: "" + storageClass: "" + hostPathPrefix: /storage + + ## @param master.sidecars Add additional sidecar containers to the master pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + initContainers: "" + + extraVolumes: "" + extraVolumeMounts: "" + + # Labels to be added to the master pods + podLabels: {} + + # Annotations to be added to the master pods + podAnnotations: {} + + ## Set podManagementPolicy + podManagementPolicy: Parallel + + # Resource requests, limits, etc. for the master cluster placement. This + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: {} + + # updatePartition is used to control a careful rolling update of SeaweedFS + # masters. + updatePartition: 0 + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: master + topologyKey: kubernetes.io/hostname + + # Toleration Settings for master pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: "" + + # nodeSelector labels for master pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + nodeSelector: | + kubernetes.io/arch: amd64 + # nodeSelector: | + # sw-backend: "true" + + # used to assign priority to master pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # used to assign a service account. + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + serviceAccountName: "" + + # Configure security context for Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # podSecurityContext: + # enabled: true + # runAsUser: 1000 + # runAsGroup: 3000 + # fsGroup: 2000 + podSecurityContext: {} + + # Configure security context for Container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # containerSecurityContext: + # enabled: true + # runAsUser: 2000 + # allowPrivilegeEscalation: false + containerSecurityContext: {} + + ingress: + enabled: false + className: "nginx" + # host: false for "*" hostname + host: "master.seaweedfs.local" + annotations: + nginx.ingress.kubernetes.io/auth-type: "basic" + nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" + nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Master' + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/enable-rewrite-log: "true" + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + nginx.ingress.kubernetes.io/configuration-snippet: | + sub_filter '' ' '; #add base url + sub_filter '="/' '="./'; #make absolute paths to relative + sub_filter '=/' '=./'; + sub_filter '/seaweedfsstatic' './seaweedfsstatic'; + sub_filter_once off; + tls: [] + + extraEnvironmentVars: + WEED_MASTER_VOLUME_GROWTH_COPY_1: '7' + WEED_MASTER_VOLUME_GROWTH_COPY_2: '6' + WEED_MASTER_VOLUME_GROWTH_COPY_3: '3' + WEED_MASTER_VOLUME_GROWTH_COPY_OTHER: '1' + + # used to configure livenessProbe on master-server containers + # + livenessProbe: + enabled: true + httpGet: + path: /cluster/status + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 4 + timeoutSeconds: 10 + + # used to configure readinessProbe on master-server containers + # + readinessProbe: + enabled: true + httpGet: + path: /cluster/status + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 45 + successThreshold: 2 + failureThreshold: 100 + timeoutSeconds: 10 + +volume: + enabled: true + imageOverride: null + restartPolicy: null + port: 8080 + grpcPort: 18080 + metricsPort: 9327 + ipBind: "0.0.0.0" + replicas: 1 + loggingOverrideLevel: null + # number of seconds between heartbeats, must be smaller than or equal to the master's setting + pulseSeconds: null + # Choose [memory|leveldb|leveldbMedium|leveldbLarge] mode for memory~performance balance., default memory + index: null + # limit file size to avoid out of memory, default 256mb + fileSizeLimitMB: null + # minimum free disk space(in percents). If free disk space lower this value - all volumes marks as ReadOnly + minFreeSpacePercent: 7 + + # For each data disk you may use ANY storage-class, example with local-path-provisioner + # Annotations are optional. + # dataDirs: + # - name: data: + # type: "persistentVolumeClaim" + # size: "24Ti" + # storageClass: "local-path-provisioner" + # annotations: + # "key": "value" + # maxVolumes: 0 # If set to zero on non-windows OS, the limit will be auto configured. (default "7") + # + # You may also spacify an existing claim: + # - name: data + # type: "existingClaim" + # claimName: "my-pvc" + # maxVolumes: 0 # If set to zero on non-windows OS, the limit will be auto configured. (default "7") + # + # You can also use emptyDir storage: + # - name: data + # type: "emptyDir" + # maxVolumes: 0 # If set to zero on non-windows OS, the limit will be auto configured. (default "7") + + dataDirs: + - name: data1 + type: "hostPath" + hostPathPrefix: /ssd + maxVolumes: 0 + + # - name: data2 + # type: "persistentVolumeClaim" + # storageClass: "yourClassNameOfChoice" + # size: "800Gi" + # maxVolumes: 0 + + # This will automatically create a job for patching Kubernetes resources if the dataDirs type is 'persistentVolumeClaim' and the size has changed. + resizeHook: + enabled: true + image: bitnami/kubectl + + # idx can be defined by: + # + # idx: + # type: "hostPath" + # hostPathPrefix: /ssd + # + # or + # + # idx: + # type: "persistentVolumeClaim" + # size: "20Gi" + # storageClass: "local-path-provisioner" + # + # or + # + # idx: + # type: "existingClaim" + # claimName: "myClaim" + # + # or + # + # idx: + # type: "emptyDir" + + # same applies to "logs" + + idx: {} + + logs: {} + + # limit background compaction or copying speed in mega bytes per second + compactionMBps: "50" + + + # Volume server's rack name + rack: null + + # Volume server's data center name + dataCenter: null + + # Redirect moved or non-local volumes. (default proxy) + readMode: proxy + + # Comma separated Ip addresses having write permission. No limit if empty. + whiteList: null + + # Adjust jpg orientation when uploading. + imagesFixOrientation: false + + ## @param volume.sidecars Add additional sidecar containers to the volume pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + initContainers: "" + + extraVolumes: "" + extraVolumeMounts: "" + + # Labels to be added to the volume pods + podLabels: {} + + # Annotations to be added to the volume pods + podAnnotations: {} + + ## Set podManagementPolicy + podManagementPolicy: Parallel + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: volume + topologyKey: kubernetes.io/hostname + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: {} + + # Toleration Settings for server pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: "" + + # nodeSelector labels for server pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + nodeSelector: | + kubernetes.io/arch: amd64 + # nodeSelector: | + # sw-volume: "true" + + # used to assign priority to server pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # used to assign a service account. + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + serviceAccountName: "" + + extraEnvironmentVars: + + # Configure security context for Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # podSecurityContext: + # enabled: true + # runAsUser: 1000 + # runAsGroup: 3000 + # fsGroup: 2000 + podSecurityContext: {} + + # Configure security context for Container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # containerSecurityContext: + # enabled: true + # runAsUser: 2000 + # allowPrivilegeEscalation: false + containerSecurityContext: {} + + # used to configure livenessProbe on volume-server containers + # + livenessProbe: + enabled: true + httpGet: + path: /status + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 90 + successThreshold: 1 + failureThreshold: 4 + timeoutSeconds: 30 + + # used to configure readinessProbe on volume-server containers + # + readinessProbe: + enabled: true + httpGet: + path: /status + scheme: HTTP + initialDelaySeconds: 15 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 100 + timeoutSeconds: 30 + +filer: + enabled: true + imageOverride: null + restartPolicy: null + replicas: 1 + port: 8888 + grpcPort: 18888 + metricsPort: 9327 + loggingOverrideLevel: null + filerGroup: "" + # replication type is XYZ: + # X number of replica in other data centers + # Y number of replica in other racks in the same data center + # Z number of replica in other servers in the same rack + defaultReplicaPlacement: "000" + # turn off directory listing + disableDirListing: false + # split files larger than the limit, default 32 + maxMB: null + # encrypt data on volume servers + encryptVolumeData: false + + # Whether proxy or redirect to volume server during file GET request + redirectOnRead: false + + # Limit sub dir listing size (default 100000) + dirListLimit: 100000 + + # Disable http request, only gRpc operations are allowed + disableHttp: false + + # DEPRECATE: enablePVC, storage, storageClass + # Consider replacing with filer.data section below instead. + + # Settings for configuring stateful storage of filer pods. + # enablePVC will create a pvc for filer for data persistence. + enablePVC: false + # storage should be set to the disk size of the attached volume. + storage: 25Gi + # storageClass is the class of storage which defaults to null (the Kube cluster will pick the default). + storageClass: null + # You may use ANY storage-class, example with local-path-provisioner + # Annotations are optional. + # data: + # type: "persistentVolumeClaim" + # size: "24Ti" + # storageClass: "local-path-provisioner" + # annotations: + # "key": "value" + # + # You may also specify an existing claim: + # data: + # type: "existingClaim" + # claimName: "my-pvc" + # + # You can also use emptyDir storage: + # data: + # type: "emptyDir" + data: + type: "hostPath" + size: "" + storageClass: "" + hostPathPrefix: /storage + + # You can also use emptyDir storage: + # logs: + # type: "emptyDir" + logs: + type: "hostPath" + size: "" + storageClass: "" + hostPathPrefix: /storage + + ## @param filer.sidecars Add additional sidecar containers to the filer pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + initContainers: "" + + extraVolumes: "" + extraVolumeMounts: "" + + # Labels to be added to the filer pods + podLabels: {} + + # Annotations to be added to the filer pods + podAnnotations: {} + + ## Set podManagementPolicy + podManagementPolicy: Parallel + + # Affinity Settings + # Commenting out or setting as empty the affinity variable, will allow + # deployment to single node services such as Minikube + affinity: | + podAntiAffinity: + requiredDuringSchedulingIgnoredDuringExecution: + - labelSelector: + matchLabels: + app.kubernetes.io/name: {{ template "seaweedfs.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/component: filer + topologyKey: kubernetes.io/hostname + + # updatePartition is used to control a careful rolling update of SeaweedFS + # masters. + updatePartition: 0 + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: {} + + # Toleration Settings for server pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: "" + + # nodeSelector labels for server pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + nodeSelector: | + kubernetes.io/arch: amd64 + # nodeSelector: | + # sw-backend: "true" + + # used to assign priority to server pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # used to assign a service account. + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + serviceAccountName: "" + + # Configure security context for Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # podSecurityContext: + # enabled: true + # runAsUser: 1000 + # runAsGroup: 3000 + # fsGroup: 2000 + podSecurityContext: {} + + # Configure security context for Container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # containerSecurityContext: + # enabled: true + # runAsUser: 2000 + # allowPrivilegeEscalation: false + containerSecurityContext: {} + + ingress: + enabled: false + className: "nginx" + # host: false for "*" hostname + host: "seaweedfs.cluster.local" + annotations: + nginx.ingress.kubernetes.io/backend-protocol: GRPC + nginx.ingress.kubernetes.io/auth-type: "basic" + nginx.ingress.kubernetes.io/auth-secret: "default/ingress-basic-auth-secret" + nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required - SW-Filer' + nginx.ingress.kubernetes.io/service-upstream: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$1 + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/enable-rewrite-log: "true" + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/force-ssl-redirect: "false" + nginx.ingress.kubernetes.io/configuration-snippet: | + sub_filter '' ' '; #add base url + sub_filter '="/' '="./'; #make absolute paths to relative + sub_filter '=/' '=./'; + sub_filter '/seaweedfsstatic' './seaweedfsstatic'; + sub_filter_once off; + + # extraEnvVars is a list of extra enviroment variables to set with the stateful set. + extraEnvironmentVars: + WEED_MYSQL_ENABLED: "false" + WEED_MYSQL_HOSTNAME: "mysql-db-host" + WEED_MYSQL_PORT: "3306" + WEED_MYSQL_DATABASE: "sw_database" + WEED_MYSQL_CONNECTION_MAX_IDLE: "5" + WEED_MYSQL_CONNECTION_MAX_OPEN: "75" + # "refresh" connection every 10 minutes, eliminating mysql closing "old" connections + WEED_MYSQL_CONNECTION_MAX_LIFETIME_SECONDS: "600" + # enable usage of memsql as filer backend + WEED_MYSQL_INTERPOLATEPARAMS: "true" + # if you want to use leveldb2, then should enable "enablePVC". or you may lose your data. + WEED_LEVELDB2_ENABLED: "true" + # with http DELETE, by default the filer would check whether a folder is empty. + # recursive_delete will delete all sub folders and files, similar to "rm -Rf" + WEED_FILER_OPTIONS_RECURSIVE_DELETE: "false" + # directories under this folder will be automatically creating a separate bucket + WEED_FILER_BUCKETS_FOLDER: "/buckets" + + # used to configure livenessProbe on filer containers + # + livenessProbe: + enabled: true + httpGet: + path: / + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 30 + successThreshold: 1 + failureThreshold: 5 + timeoutSeconds: 10 + + # used to configure readinessProbe on filer containers + # + readinessProbe: + enabled: true + httpGet: + path: / + scheme: HTTP + initialDelaySeconds: 10 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 100 + timeoutSeconds: 10 + + # secret env variables + secretExtraEnvironmentVars: {} + # WEED_POSTGRES_USERNAME: + # secretKeyRef: + # name: postgres-credentials + # key: username + # WEED_POSTGRES_PASSWORD: + # secretKeyRef: + # name: postgres-credentials + # key: password + + s3: + enabled: false + port: 8333 + # add additional https port + httpsPort: 0 + # allow empty folders + allowEmptyFolder: false + # Suffix of the host name, {bucket}.{domainName} + domainName: "" + # enable user & permission to s3 (need to inject to all services) + enableAuth: false + # set to the name of an existing kubernetes Secret with the s3 json config file + # should have a secret key called seaweedfs_s3_config with an inline json configure + existingConfigSecret: null + auditLogConfig: {} + # You may specify buckets to be created during the install process. + # Buckets may be exposed publicly by setting `anonymousRead` to `true` + # createBuckets: + # - name: bucket-a + # anonymousRead: true + # - name: bucket-b + # anonymousRead: false + +s3: + enabled: false + imageOverride: null + restartPolicy: null + replicas: 1 + bindAddress: 0.0.0.0 + port: 8333 + # add additional https port + httpsPort: 0 + metricsPort: 9327 + loggingOverrideLevel: null + # allow empty folders + allowEmptyFolder: true + # enable user & permission to s3 (need to inject to all services) + enableAuth: false + # set to the name of an existing kubernetes Secret with the s3 json config file + # should have a secret key called seaweedfs_s3_config with an inline json config + existingConfigSecret: null + auditLogConfig: {} + + # Suffix of the host name, {bucket}.{domainName} + domainName: "" + + ## @param s3.sidecars Add additional sidecar containers to the s3 pod(s) + ## e.g: + ## sidecars: + ## - name: your-image-name + ## image: your-image + ## imagePullPolicy: Always + ## ports: + ## - name: portname + ## containerPort: 1234 + ## + sidecars: [] + initContainers: "" + + extraVolumes: "" + extraVolumeMounts: "" + + # Labels to be added to the s3 pods + podLabels: {} + + # Annotations to be added to the s3 pods + podAnnotations: {} + + # Resource requests, limits, etc. for the server cluster placement. This + # should map directly to the value of the resources field for a PodSpec, + # formatted as a multi-line string. By default no direct resource request + # is made. + resources: {} + + # Toleration Settings for server pods + # This should be a multi-line string matching the Toleration array + # in a PodSpec. + tolerations: "" + + # nodeSelector labels for server pod assignment, formatted as a muli-line string. + # ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/#nodeselector + # Example: + nodeSelector: | + kubernetes.io/arch: amd64 + # nodeSelector: | + # sw-backend: "true" + + # used to assign priority to server pods + # ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/ + priorityClassName: "" + + # used to assign a service account. + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/ + serviceAccountName: "" + + # Configure security context for Pod + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # podSecurityContext: + # enabled: true + # runAsUser: 1000 + # runAsGroup: 3000 + # fsGroup: 2000 + podSecurityContext: {} + + # Configure security context for Container + # ref: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + # Example: + # containerSecurityContext: + # enabled: true + # runAsUser: 2000 + # allowPrivilegeEscalation: false + containerSecurityContext: {} + + # You can also use emptyDir storage: + # logs: + # type: "emptyDir" + logs: + type: "hostPath" + size: "" + storageClass: "" + hostPathPrefix: /storage + + extraEnvironmentVars: + + # used to configure livenessProbe on s3 containers + # + livenessProbe: + enabled: true + httpGet: + path: /status + scheme: HTTP + initialDelaySeconds: 20 + periodSeconds: 60 + successThreshold: 1 + failureThreshold: 20 + timeoutSeconds: 10 + + # used to configure readinessProbe on s3 containers + # + readinessProbe: + enabled: true + httpGet: + path: /status + scheme: HTTP + initialDelaySeconds: 15 + periodSeconds: 15 + successThreshold: 1 + failureThreshold: 100 + timeoutSeconds: 10 + + ingress: + enabled: false + className: "nginx" + # host: false for "*" hostname + host: "seaweedfs.cluster.local" + # additional ingress annotations for the s3 endpoint + annotations: {} + tls: [] + +# Deploy Kubernetes COSI Driver for SeaweedFS +# Requires COSI CRDs and controller to be installed in the cluster +# For more information, visit: https://container-object-storage-interface.github.io/docs/deployment-guide +cosi: + enabled: false + image: "ghcr.io/seaweedfs/seaweedfs-cosi-driver:v0.1.1" + driverName: "seaweedfs.objectstorage.k8s.io" + bucketClassName: "seaweedfs" + endpoint: "" + region: "" + + sidecar: + image: gcr.io/k8s-staging-sig-storage/objectstorage-sidecar/objectstorage-sidecar:v20230130-v0.1.0-24-gc0cf995 + + # enable user & permission to s3 (need to inject to all services) + enableAuth: false + # set to the name of an existing kubernetes Secret with the s3 json config file + # should have a secret key called seaweedfs_s3_config with an inline json configure + existingConfigSecret: null + + podSecurityContext: {} + containerSecurityContext: {} + + extraVolumes: "" + extraVolumeMounts: "" + +certificates: + commonName: "SeaweedFS CA" + ipAddresses: [] + keyAlgorithm: RSA + keySize: 2048 + duration: 2160h # 90d + renewBefore: 360h # 15d + externalCertificates: + # This will avoid the need to use cert-manager and will rely on providing your own external certificates and CA + # you will need to store your provided certificates in the secret read by the different services: + # seaweedfs-master-cert, seaweedfs-filer-cert, etc. Can see any statefulset definition to see secret names + enabled: false + +# Labels to be added to all the created pods +podLabels: {} +# Annotations to be added to all the created pods +podAnnotations: {} diff --git a/packages/system/seaweedfs/patches/resize-api-server-annotation.diff b/packages/system/seaweedfs/patches/resize-api-server-annotation.diff new file mode 100644 index 00000000..2b41f297 --- /dev/null +++ b/packages/system/seaweedfs/patches/resize-api-server-annotation.diff @@ -0,0 +1,14 @@ +diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml +index 436a785..9f186ea 100644 +--- a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml ++++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-resize-hook.yaml +@@ -45,6 +45,9 @@ metadata: + helm.sh/hook-delete-policy: hook-succeeded,before-hook-creation + spec: + template: ++ metadata: ++ labels: ++ policy.cozystack.io/allow-to-apiserver: "true" + spec: + serviceAccountName: {{ $seaweedfsName }}-volume-resize-hook + restartPolicy: Never diff --git a/packages/system/seaweedfs/patches/retention-policy-delete.yaml b/packages/system/seaweedfs/patches/retention-policy-delete.yaml new file mode 100644 index 00000000..d57d1ea4 --- /dev/null +++ b/packages/system/seaweedfs/patches/retention-policy-delete.yaml @@ -0,0 +1,14 @@ +diff --git a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml +index 0a70d8c..eb3bb91 100644 +--- a/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml ++++ b/packages/system/seaweedfs/charts/seaweedfs/templates/volume-statefulset.yaml +@@ -10,6 +10,9 @@ metadata: + app.kubernetes.io/managed-by: {{ .Release.Service }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: ++ persistentVolumeClaimRetentionPolicy: ++ whenDeleted: Delete ++ whenScaled: Delete + serviceName: {{ template "seaweedfs.name" . }}-volume + replicas: {{ .Values.volume.replicas }} + podManagementPolicy: {{ .Values.volume.podManagementPolicy }} diff --git a/packages/system/seaweedfs/templates/database.yaml b/packages/system/seaweedfs/templates/database.yaml new file mode 100644 index 00000000..1b0bbf22 --- /dev/null +++ b/packages/system/seaweedfs/templates/database.yaml @@ -0,0 +1,13 @@ +--- +apiVersion: postgresql.cnpg.io/v1 +kind: Cluster +metadata: + name: seaweedfs-db +spec: + instances: 2 + storage: + size: 10Gi + + inheritedMetadata: + labels: + policy.cozystack.io/allow-to-apiserver: "true" diff --git a/packages/system/seaweedfs/values.yaml b/packages/system/seaweedfs/values.yaml new file mode 100644 index 00000000..9fb8f886 --- /dev/null +++ b/packages/system/seaweedfs/values.yaml @@ -0,0 +1,129 @@ +global: + enableSecurity: true + serviceAccountName: "tenant-foo-seaweedfs" + extraEnvironmentVars: + WEED_CLUSTER_SW_MASTER: "seaweedfs-master:9333" + WEED_CLUSTER_SW_FILER: "seaweedfs-filer-client:8888" + +seaweedfs: + + master: + replicas: 3 + volumeSizeLimitMB: 100 + # replication type is XYZ: + # X number of replica in other data centers + # Y number of replica in other racks in the same data center + # Z number of replica in other servers in the same rack + defaultReplication: "001" + + data: + type: "emptyDir" + + logs: + type: "" + + volume: + replicas: 2 + # minimum free disk space(in percents). If free disk space lower this value - all volumes marks as ReadOnly + minFreeSpacePercent: 5 + + dataDirs: + - name: data1 + type: "persistentVolumeClaim" + size: "10Gi" + maxVolumes: 0 + + filer: + replicas: 2 + # replication type is XYZ: + # X number of replica in other data centers + # Y number of replica in other racks in the same data center + # Z number of replica in other servers in the same rack + defaultReplicaPlacement: "001" + data: + type: "emptyDir" + + logs: + type: "" + + extraEnvironmentVars: + WEED_LEVELDB2_ENABLED: "false" + WEED_POSTGRES2_ENABLED: "true" + WEED_POSTGRES2_CREATETABLE: | + CREATE TABLE IF NOT EXISTS "%s" ( + dirhash BIGINT, + name VARCHAR(65535), + directory VARCHAR(65535), + meta bytea, + PRIMARY KEY (dirhash, name) + ); + secretExtraEnvironmentVars: + WEED_POSTGRES2_HOSTNAME: + secretKeyRef: + key: host + name: seaweedfs-db-app + WEED_POSTGRES2_DATABASE: + secretKeyRef: + key: dbname + name: seaweedfs-db-app + WEED_POSTGRES2_USERNAME: + secretKeyRef: + key: username + name: seaweedfs-db-app + WEED_POSTGRES2_PASSWORD: + secretKeyRef: + key: password + name: seaweedfs-db-app + + s3: + enabled: true + port: 8333 + httpsPort: 0 + # Suffix of the host name, {bucket}.{domainName} + domainName: "" + # enable user & permission to s3 (need to inject to all services) + enableAuth: false + # set to the name of an existing kubernetes Secret with the s3 json config file + # should have a secret key called seaweedfs_s3_config with an inline json configure + existingConfigSecret: null + auditLogConfig: {} + + s3: + enableAuth: true + + logs: + type: "" + + ingress: + enabled: true + className: "tenant-root" + host: "seaweedfs2.demo.cozystack.io" + annotations: + nginx.ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/backend-protocol: "HTTPS" + acme.cert-manager.io/http01-ingress-class: tenant-root + cert-manager.io/cluster-issuer: letsencrypt-prod + tls: + - hosts: + - seaweedfs.demo.cozystack.io + secretName: seaweedfs-s3-ingress-tls + + cosi: + enabled: true + podLabels: + policy.cozystack.io/allow-to-apiserver: "true" + driverName: "seaweedfs.objectstorage.k8s.io" + bucketClassName: "seaweedfs" + image: "ghcr.io/seaweedfs/seaweedfs-cosi-driver:v0.1.1" + region: "" + + sidecar: + image: "ghcr.io/kvaps/test:cosi-provisioner-sidecar-25" + + certificates: + commonName: "SeaweedFS CA" + ipAddresses: [] + keyAlgorithm: RSA + keySize: 2048 + duration: 2160h # 90d + renewBefore: 360h # 15d