aboutsummaryrefslogtreecommitdiff
path: root/k8s
diff options
context:
space:
mode:
Diffstat (limited to 'k8s')
-rw-r--r--k8s/README.md48
-rw-r--r--k8s/seaweedfs/.helmignore22
-rw-r--r--k8s/seaweedfs/Chart.yaml5
-rw-r--r--k8s/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json1856
-rw-r--r--k8s/seaweedfs/templates/_helpers.tpl151
-rw-r--r--k8s/seaweedfs/templates/ca-cert.yaml14
-rw-r--r--k8s/seaweedfs/templates/cert-clusterissuer.yaml8
-rw-r--r--k8s/seaweedfs/templates/client-cert.yaml33
-rw-r--r--k8s/seaweedfs/templates/cronjob.yaml58
-rw-r--r--k8s/seaweedfs/templates/filer-cert.yaml33
-rw-r--r--k8s/seaweedfs/templates/filer-service-client.yaml31
-rw-r--r--k8s/seaweedfs/templates/filer-service.yaml25
-rw-r--r--k8s/seaweedfs/templates/filer-servicemonitor.yaml18
-rw-r--r--k8s/seaweedfs/templates/filer-statefulset.yaml267
-rw-r--r--k8s/seaweedfs/templates/ingress.yaml59
-rw-r--r--k8s/seaweedfs/templates/master-cert.yaml33
-rw-r--r--k8s/seaweedfs/templates/master-service.yaml25
-rw-r--r--k8s/seaweedfs/templates/master-statefulset.yaml227
-rw-r--r--k8s/seaweedfs/templates/s3-deployment.yaml188
-rw-r--r--k8s/seaweedfs/templates/s3-service.yaml23
-rw-r--r--k8s/seaweedfs/templates/s3-servicemonitor.yaml18
-rw-r--r--k8s/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml20
-rw-r--r--k8s/seaweedfs/templates/seaweedfs-s3-secret.yaml21
-rw-r--r--k8s/seaweedfs/templates/secret-seaweedfs-db.yaml14
-rw-r--r--k8s/seaweedfs/templates/security-configmap.yaml52
-rw-r--r--k8s/seaweedfs/templates/service-account.yaml29
-rw-r--r--k8s/seaweedfs/templates/volume-cert.yaml33
-rw-r--r--k8s/seaweedfs/templates/volume-service.yaml28
-rw-r--r--k8s/seaweedfs/templates/volume-servicemonitor.yaml18
-rw-r--r--k8s/seaweedfs/templates/volume-statefulset.yaml276
-rw-r--r--k8s/seaweedfs/values.yaml418
31 files changed, 4051 insertions, 0 deletions
diff --git a/k8s/README.md b/k8s/README.md
new file mode 100644
index 000000000..c5615522c
--- /dev/null
+++ b/k8s/README.md
@@ -0,0 +1,48 @@
+## SEAWEEDFS - helm chart (2.x)
+
+### 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.
+
+### prerequisites
+kubernetes node have labels which help to define which node(Host) will run which pod.
+
+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 & the masters, currently all pods (master/volume/filer)
+have anti-affinity rule to disallow running multiple pod type on the same host.
+if you still want to run multiple pods of the same type (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.
+
+most of the configuration are available through values.yaml
+
diff --git a/k8s/seaweedfs/.helmignore b/k8s/seaweedfs/.helmignore
new file mode 100644
index 000000000..50af03172
--- /dev/null
+++ b/k8s/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/k8s/seaweedfs/Chart.yaml b/k8s/seaweedfs/Chart.yaml
new file mode 100644
index 000000000..0025c9760
--- /dev/null
+++ b/k8s/seaweedfs/Chart.yaml
@@ -0,0 +1,5 @@
+apiVersion: v1
+description: SeaweedFS
+name: seaweedfs
+appVersion: "2.41"
+version: 2.41
diff --git a/k8s/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json b/k8s/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json
new file mode 100644
index 000000000..d492a0695
--- /dev/null
+++ b/k8s/seaweedfs/dashboards/seaweedfs-grafana-dashboard.json
@@ -0,0 +1,1856 @@
+{
+ "__inputs": [
+ {
+ "name": "DS_PROMETHEUS-DEV",
+ "label": "prometheus-dev",
+ "description": "",
+ "type": "datasource",
+ "pluginId": "prometheus",
+ "pluginName": "Prometheus"
+ }
+ ],
+ "__requires": [
+ {
+ "type": "grafana",
+ "id": "grafana",
+ "name": "Grafana",
+ "version": "4.6.2"
+ },
+ {
+ "type": "panel",
+ "id": "graph",
+ "name": "Graph",
+ "version": ""
+ },
+ {
+ "type": "datasource",
+ "id": "prometheus",
+ "name": "Prometheus",
+ "version": "1.0.0"
+ }
+ ],
+ "annotations": {
+ "list": [
+ {
+ "builtIn": 1,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "enable": true,
+ "hide": true,
+ "iconColor": "rgba(0, 211, 255, 1)",
+ "limit": 100,
+ "name": "Annotations & Alerts",
+ "showIn": 0,
+ "type": "dashboard"
+ }
+ ]
+ },
+ "editable": true,
+ "gnetId": 10423,
+ "graphTooltip": 0,
+ "hideControls": false,
+ "id": null,
+ "links": [],
+ "refresh": "30s",
+ "rows": [
+ {
+ "collapse": true,
+ "height": 251,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 46,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_filer_request_seconds_bucket[1m])) 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[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Request Duration 90th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 49,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_filer_request_seconds_bucket[1m])) 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[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ },
+ {
+ "expr": "",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "C"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Request Duration 95th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 45,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_filer_request_seconds_bucket[1m])) 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[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ },
+ {
+ "expr": "",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "refId": "C"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Request Duration 99th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 2,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 250,
+ "sort": "max",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "minSpan": 12,
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "total",
+ "lines": false
+ }
+ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "rate(SeaweedFS_filer_request_total[1m]) * 5",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "A",
+ "step": 30
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer QPS",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Filer",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": false,
+ "height": 250,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 56,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.90, sum(rate(SeaweedFS_s3_request_seconds_bucket[1m])) 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[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "S3 Request Duration 90th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 57,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.95, sum(rate(SeaweedFS_s3_request_seconds_bucket[1m])) 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[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "S3 Request Duration 95th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 58,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 4,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket[1m])) by (le))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "average",
+ "refId": "A",
+ "step": 60
+ },
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_s3_request_seconds_bucket[1m])) by (le, type))",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B",
+ "step": 60
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "S3 Request Duration 99th percentile",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "id": 55,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 250,
+ "sort": "max",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "minSpan": 12,
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "total",
+ "lines": false
+ }
+ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "rate(SeaweedFS_s3_request_total[1m]) * 5",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "A",
+ "step": 30
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "S3 API QPS",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 0,
+ "grid": {},
+ "hideTimeOverride": false,
+ "id": 59,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": true,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": true,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sideWidth": 250,
+ "sort": "max",
+ "sortDesc": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "minSpan": 12,
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [
+ {
+ "alias": "total",
+ "lines": false
+ }
+ ],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum by (type) (SeaweedFS_s3_request_total{type=~'PUT|COPY|POST|LIST'})*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'})*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'})*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'})*0.0000004",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{type}} requests",
+ "refId": "D"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": "1M",
+ "timeShift": null,
+ "title": "S3 API Monthly Cost if on AWS",
+ "tooltip": {
+ "msResolution": true,
+ "shared": true,
+ "sort": 2,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "currencyUSD",
+ "label": "Cost in US$",
+ "logBase": 1,
+ "max": null,
+ "min": "0",
+ "show": true
+ },
+ {
+ "format": "currencyUSD",
+ "label": "Write Cost",
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": false
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "S3 Gateway",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 252,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 47,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_volumeServer_request_seconds_bucket[1m])) 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[1m])) by (le))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "average",
+ "refId": "C"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Volume Server Request Duration 99th percentile",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 40,
+ "legend": {
+ "alignAsTable": true,
+ "avg": false,
+ "current": false,
+ "hideEmpty": true,
+ "hideZero": true,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "sort": "total",
+ "sortDesc": true,
+ "total": true,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(SeaweedFS_volumeServer_request_total[1m])) by (type)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "A",
+ "step": 4
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Volume Server QPS",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "fill": 1,
+ "id": 48,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(SeaweedFS_volumeServer_volumes) by (collection, type)",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{collection}} {{type}}",
+ "refId": "A"
+ },
+ {
+ "expr": "sum(SeaweedFS_volumeServer_max_volumes)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Total",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Volume Count",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "fill": 1,
+ "id": 50,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(SeaweedFS_volumeServer_total_disk_size) by (collection, type)",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{collection}} {{type}}",
+ "refId": "A"
+ },
+ {
+ "expr": "sum(SeaweedFS_volumeServer_total_disk_size)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "Total",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Used Disk Space by Collection and Type",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "fill": 1,
+ "id": 51,
+ "legend": {
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": true,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 1,
+ "links": [],
+ "nullPointMode": "null",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(SeaweedFS_volumeServer_total_disk_size) by (exported_instance)",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "{{exported_instance}}",
+ "refId": "A"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Used Disk Space by Host",
+ "tooltip": {
+ "shared": true,
+ "sort": 0,
+ "value_type": "individual"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Volume Server",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 251,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 12,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "histogram_quantile(0.99, sum(rate(SeaweedFS_filerStore_request_seconds_bucket[1m])) by (le, type))",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Store Request Duration 99th percentile",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 14,
+ "legend": {
+ "alignAsTable": true,
+ "avg": true,
+ "current": true,
+ "hideEmpty": false,
+ "hideZero": false,
+ "max": false,
+ "min": false,
+ "rightSide": true,
+ "show": true,
+ "total": false,
+ "values": true
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "sum(rate(SeaweedFS_filerStore_request_total [1m])) by (type)",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{type}}",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Store QPS",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Filer Store",
+ "titleSize": "h6"
+ },
+ {
+ "collapse": true,
+ "height": 242,
+ "panels": [
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 52,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "go_memstats_alloc_bytes{exported_job=\"filer\"}",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "bytes allocated",
+ "refId": "B"
+ },
+ {
+ "expr": "rate(go_memstats_alloc_bytes_total{exported_job=\"filer\"}[30s])",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "alloc rate",
+ "refId": "A"
+ },
+ {
+ "expr": "go_memstats_stack_inuse_bytes{exported_job=\"filer\"}",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "stack inuse",
+ "refId": "C"
+ },
+ {
+ "expr": "go_memstats_heap_inuse_bytes{exported_job=\"filer\"}",
+ "format": "time_series",
+ "hide": false,
+ "intervalFactor": 2,
+ "legendFormat": "heap inuse",
+ "refId": "D"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Go Memory Stats",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "bytes",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 54,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 6,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "go_gc_duration_seconds{exported_job=\"filer\"}",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{quantile}}",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Go GC duration quantiles",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "s",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "Bps",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ },
+ {
+ "aliasColors": {},
+ "bars": false,
+ "dashLength": 10,
+ "dashes": false,
+ "datasource": "${DS_PROMETHEUS-DEV}",
+ "editable": true,
+ "error": false,
+ "fill": 1,
+ "grid": {},
+ "id": 53,
+ "legend": {
+ "alignAsTable": false,
+ "avg": false,
+ "current": false,
+ "max": false,
+ "min": false,
+ "show": false,
+ "total": false,
+ "values": false
+ },
+ "lines": true,
+ "linewidth": 2,
+ "links": [],
+ "nullPointMode": "null as zero",
+ "percentage": false,
+ "pointradius": 5,
+ "points": false,
+ "renderer": "flot",
+ "seriesOverrides": [],
+ "spaceLength": 10,
+ "span": 12,
+ "stack": false,
+ "steppedLine": false,
+ "targets": [
+ {
+ "expr": "go_goroutines{exported_job=\"filer\"}",
+ "format": "time_series",
+ "intervalFactor": 2,
+ "legendFormat": "{{exported_instance}}",
+ "refId": "B"
+ }
+ ],
+ "thresholds": [],
+ "timeFrom": null,
+ "timeShift": null,
+ "title": "Filer Go Routines",
+ "tooltip": {
+ "msResolution": false,
+ "shared": true,
+ "sort": 0,
+ "value_type": "cumulative"
+ },
+ "type": "graph",
+ "xaxis": {
+ "buckets": null,
+ "mode": "time",
+ "name": null,
+ "show": true,
+ "values": []
+ },
+ "yaxes": [
+ {
+ "format": "none",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": 0,
+ "show": true
+ },
+ {
+ "format": "short",
+ "label": null,
+ "logBase": 1,
+ "max": null,
+ "min": null,
+ "show": true
+ }
+ ]
+ }
+ ],
+ "repeat": null,
+ "repeatIteration": null,
+ "repeatRowId": null,
+ "showTitle": true,
+ "title": "Filer Instances",
+ "titleSize": "h6"
+ }
+ ],
+ "schemaVersion": 14,
+ "style": "dark",
+ "tags": [],
+ "templating": {
+ "list": []
+ },
+ "time": {
+ "from": "now-30d",
+ "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",
+ "version": 2
+} \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/_helpers.tpl b/k8s/seaweedfs/templates/_helpers.tpl
new file mode 100644
index 000000000..a9ee89f03
--- /dev/null
+++ b/k8s/seaweedfs/templates/_helpers.tpl
@@ -0,0 +1,151 @@
+{{/*
+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 -}}
+{{- $registryName := default .Values.image.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.image.repository | toString -}}
+{{- $name := .Values.global.imageName | toString -}}
+{{- $tag := .Chart.AppVersion | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the proper dbSchema image */}}
+{{- define "filer.dbSchema.image" -}}
+{{- if .Values.filer.dbSchema.imageOverride -}}
+{{- $imageOverride := .Values.filer.dbSchema.imageOverride -}}
+{{- printf "%s" $imageOverride -}}
+{{- else -}}
+{{- $registryName := default .Values.global.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.global.repository | toString -}}
+{{- $name := .Values.filer.dbSchema.imageName | toString -}}
+{{- $tag := .Values.filer.dbSchema.imageTag | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the proper master image */}}
+{{- define "master.image" -}}
+{{- if .Values.master.imageOverride -}}
+{{- $imageOverride := .Values.master.imageOverride -}}
+{{- printf "%s" $imageOverride -}}
+{{- else -}}
+{{- $registryName := default .Values.image.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.image.repository | toString -}}
+{{- $name := .Values.global.imageName | toString -}}
+{{- $tag := .Chart.AppVersion | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the proper s3 image */}}
+{{- define "s3.image" -}}
+{{- if .Values.s3.imageOverride -}}
+{{- $imageOverride := .Values.s3.imageOverride -}}
+{{- printf "%s" $imageOverride -}}
+{{- else -}}
+{{- $registryName := default .Values.image.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.image.repository | toString -}}
+{{- $name := .Values.global.imageName | toString -}}
+{{- $tag := .Chart.AppVersion | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the proper volume image */}}
+{{- define "volume.image" -}}
+{{- if .Values.volume.imageOverride -}}
+{{- $imageOverride := .Values.volume.imageOverride -}}
+{{- printf "%s" $imageOverride -}}
+{{- else -}}
+{{- $registryName := default .Values.image.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.image.repository | toString -}}
+{{- $name := .Values.global.imageName | toString -}}
+{{- $tag := .Chart.AppVersion | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+{{/* Return the proper cronjob image */}}
+{{- define "cronjob.image" -}}
+{{- if .Values.cronjob.imageOverride -}}
+{{- $imageOverride := .Values.cronjob.imageOverride -}}
+{{- printf "%s" $imageOverride -}}
+{{- else -}}
+{{- $registryName := default .Values.image.registry .Values.global.localRegistry | toString -}}
+{{- $repositoryName := .Values.image.repository | toString -}}
+{{- $name := .Values.global.imageName | toString -}}
+{{- $tag := .Chart.AppVersion | toString -}}
+{{- printf "%s%s%s:%s" $registryName $repositoryName $name $tag -}}
+{{- end -}}
+{{- end -}}
+
+
+{{/* check if any 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 "false" -}}
+{{- end -}}
+{{- end -}}
+
+{{/* check if any HostPath exists */}}
+{{- define "volume.hostpath_exists" -}}
+{{- if or (or (eq .Values.volume.data.type "hostPath") (and (eq .Values.volume.idx.type "hostPath") .Values.volume.dir_idx )) (eq .Values.volume.logs.type "hostPath") -}}
+{{- printf "true" -}}
+{{- else -}}
+{{- if or .Values.global.enableSecurity .Values.volume.extraVolumes -}}
+{{- printf "true" -}}
+{{- else -}}
+{{- printf "false" -}}
+{{- end -}}
+{{- end -}}
+{{- end -}}
diff --git a/k8s/seaweedfs/templates/ca-cert.yaml b/k8s/seaweedfs/templates/ca-cert.yaml
new file mode 100644
index 000000000..056f01502
--- /dev/null
+++ b/k8s/seaweedfs/templates/ca-cert.yaml
@@ -0,0 +1,14 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+ name: {{ template "seaweedfs.name" . }}-ca-cert
+ namespace: {{ .Release.Namespace }}
+spec:
+ secretName: {{ template "seaweedfs.name" . }}-ca-cert
+ commonName: "{{ template "seaweedfs.name" . }}-root-ca"
+ isCA: true
+ issuerRef:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+ kind: ClusterIssuer
+{{- end }}
diff --git a/k8s/seaweedfs/templates/cert-clusterissuer.yaml b/k8s/seaweedfs/templates/cert-clusterissuer.yaml
new file mode 100644
index 000000000..d0bd42593
--- /dev/null
+++ b/k8s/seaweedfs/templates/cert-clusterissuer.yaml
@@ -0,0 +1,8 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: ClusterIssuer
+metadata:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+spec:
+ selfSigned: {}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/client-cert.yaml b/k8s/seaweedfs/templates/client-cert.yaml
new file mode 100644
index 000000000..4d27b5659
--- /dev/null
+++ b/k8s/seaweedfs/templates/client-cert.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+ name: {{ template "seaweedfs.name" . }}-client-cert
+ namespace: {{ .Release.Namespace }}
+spec:
+ secretName: {{ template "seaweedfs.name" . }}-client-cert
+ issuerRef:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+ kind: ClusterIssuer
+ commonName: {{ .Values.certificates.commonName }}
+ organization:
+ - "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 }}
+ keyAlgorithm: {{ .Values.certificates.keyAlgorithm }}
+ keySize: {{ .Values.certificates.keySize }}
+ duration: {{ .Values.certificates.duration }}
+ renewBefore: {{ .Values.certificates.renewBefore }}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/cronjob.yaml b/k8s/seaweedfs/templates/cronjob.yaml
new file mode 100644
index 000000000..4caf4bad1
--- /dev/null
+++ b/k8s/seaweedfs/templates/cronjob.yaml
@@ -0,0 +1,58 @@
+{{- if .Values.cronjob }}
+{{- if .Values.cronjob.enabled }}
+apiVersion: batch/v1beta1
+kind: CronJob
+metadata:
+ name: {{ include "seaweedfs.fullname" . }}-cronjob
+spec:
+ schedule: "{{ .Values.cronjob.schedule }}"
+ startingDeadlineSeconds: 200
+ concurrencyPolicy: Forbid
+ failedJobsHistoryLimit: 2
+ successfulJobsHistoryLimit: 2
+ jobTemplate:
+ spec:
+ backoffLimit: 2
+ template:
+ spec:
+ {{- if .Values.cronjob.nodeSelector }}
+ nodeSelector:
+ {{ tpl .Values.cronjob.nodeSelector . | indent 12 | trim }}
+ {{- end }}
+ {{- if .Values.cronjob.tolerations }}
+ tolerations:
+ {{ tpl .Values.cronjob.tolerations . | nindent 12 | trim }}
+ {{- end }}
+ restartPolicy: OnFailure
+ containers:
+ - name: shell
+ image: {{ template "cronjob.image" . }}
+ imagePullPolicy: {{ default "IfNotPresent" .Values.global.imagePullPolicy }}
+ resources:
+ {{- toYaml .Values.cronjob.resources| nindent 16 }}
+ command:
+ - sh
+ - -c
+ - |
+ set -ex
+ echo -e "lock\n\
+ volume.balance -force \
+ {{ if .Values.volume.dataCenter }} -dataCenter {{ .Values.volume.dataCenter }}{{ end }}\
+ {{ if .Values.cronjob.collection }} -collection {{ .Values.cronjob.collection }}{{ end }}\n\
+ {{- if .Values.cronjob.enableFixReplication }}
+ volume.fix.replication -collectionPattern={{ .Values.cronjob.collectionPattern }} \n\
+ {{- end }}
+ unlock\n" | \
+ /usr/bin/weed shell \
+ {{- if .Values.cronjob.master }}
+ -master {{ .Values.cronjob.master }} \
+ {{- else }}
+ -master {{ template "seaweedfs.name" . }}-master.{{ .Release.Namespace }}.svc:{{ .Values.master.port }} \
+ {{- end }}
+ {{- if .Values.cronjob.filer }}
+ -filer {{ .Values.cronjob.filer }}
+ {{- else }}
+ -filer {{ template "seaweedfs.name" . }}-filer.{{ .Release.Namespace }}.svc:{{ .Values.filer.port }}
+ {{- end }}
+{{- end }}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/filer-cert.yaml b/k8s/seaweedfs/templates/filer-cert.yaml
new file mode 100644
index 000000000..855183c54
--- /dev/null
+++ b/k8s/seaweedfs/templates/filer-cert.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+ name: {{ template "seaweedfs.name" . }}-filer-cert
+ namespace: {{ .Release.Namespace }}
+spec:
+ secretName: {{ template "seaweedfs.name" . }}-filer-cert
+ issuerRef:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+ kind: ClusterIssuer
+ commonName: {{ .Values.certificates.commonName }}
+ organization:
+ - "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 }}
+ keyAlgorithm: {{ .Values.certificates.keyAlgorithm }}
+ keySize: {{ .Values.certificates.keySize }}
+ duration: {{ .Values.certificates.duration }}
+ renewBefore: {{ .Values.certificates.renewBefore }}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/filer-service-client.yaml b/k8s/seaweedfs/templates/filer-service-client.yaml
new file mode 100644
index 000000000..929b6f8bc
--- /dev/null
+++ b/k8s/seaweedfs/templates/filer-service-client.yaml
@@ -0,0 +1,31 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "seaweedfs.name" . }}-filer-client
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ 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: {{ template "seaweedfs.name" . }}
+ component: filer
diff --git a/k8s/seaweedfs/templates/filer-service.yaml b/k8s/seaweedfs/templates/filer-service.yaml
new file mode 100644
index 000000000..45035fc27
--- /dev/null
+++ b/k8s/seaweedfs/templates/filer-service.yaml
@@ -0,0 +1,25 @@
+apiVersion: v1
+kind: Service
+metadata:
+ annotations:
+ service.alpha.kubernetes.io/tolerate-unready-endpoints: "true"
+ name: {{ template "seaweedfs.name" . }}-filer
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ 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
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: filer
diff --git a/k8s/seaweedfs/templates/filer-servicemonitor.yaml b/k8s/seaweedfs/templates/filer-servicemonitor.yaml
new file mode 100644
index 000000000..f07f6ebef
--- /dev/null
+++ b/k8s/seaweedfs/templates/filer-servicemonitor.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.filer.metricsPort }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "seaweedfs.name" . }}-filer
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: filer
+spec:
+ endpoints:
+ - interval: 30s
+ port: swfs-filer-metrics
+ scrapeTimeout: 5s
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: filer
+{{- end }} \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/filer-statefulset.yaml b/k8s/seaweedfs/templates/filer-statefulset.yaml
new file mode 100644
index 000000000..fc1253479
--- /dev/null
+++ b/k8s/seaweedfs/templates/filer-statefulset.yaml
@@ -0,0 +1,267 @@
+{{- if .Values.filer.enabled }}
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ template "seaweedfs.name" . }}-filer
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+spec:
+ serviceName: {{ template "seaweedfs.name" . }}-filer
+ podManagementPolicy: Parallel
+ replicas: {{ .Values.filer.replicas }}
+ {{- if (gt (int .Values.filer.updatePartition) 0) }}
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ partition: {{ .Values.filer.updatePartition }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: filer
+ template:
+ metadata:
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: filer
+ 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 }}
+ {{- if .Values.global.imagePullSecrets }}
+ imagePullSecrets:
+ - name: {{ .Values.global.imagePullSecrets }}
+ {{- end }}
+ serviceAccountName: seaweefds-rw-sa #hack for delete pod master after migration
+ terminationGracePeriodSeconds: 60
+ {{- if .Values.filer.priorityClassName }}
+ priorityClassName: {{ .Values.filer.priorityClassName | quote }}
+ {{- end }}
+ enableServiceLinks: false
+ 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
+ - name: WEED_MYSQL_PASSWORD
+ valueFrom:
+ secretKeyRef:
+ name: secret-seaweedfs-db
+ key: password
+ - name: SEAWEEDFS_FULLNAME
+ value: "{{ template "seaweedfs.name" . }}"
+ {{- if .Values.filer.extraEnvironmentVars }}
+ {{- range $key, $value := .Values.filer.extraEnvironmentVars }}
+ - name: {{ $key }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.global.extraEnvironmentVars }}
+ {{- range $key, $value := .Values.global.extraEnvironmentVars }}
+ - name: {{ $key }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ command:
+ - "/bin/sh"
+ - "-ec"
+ - |
+ exec /usr/bin/weed -logdir=/logs \
+ {{- 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.enable_peers }}
+ {{- if gt (.Values.filer.replicas | int) 1 }}
+ -peers=$(echo -n "{{ range $index := until (.Values.filer.replicas | int) }}${SEAWEEDFS_FULLNAME}-filer-{{ $index }}.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}{{ if lt $index (sub ($.Values.filer.replicas | int) 1) }},{{ end }}{{ end }}" | sed "s/$HOSTNAME.${SEAWEEDFS_FULLNAME}-filer:{{ $.Values.filer.port }}//" | sed 's/,$//; 's/^,//'; s/,,/,/;' ) \
+ {{- end }}
+ {{- 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 }}
+ -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 }}
+ {{- end }}
+ -master={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
+ {{- if or (.Values.global.enableSecurity) (.Values.filer.extraVolumeMounts) }}
+ volumeMounts:
+ - name: seaweedfs-filer-log-volume
+ mountPath: "/logs/"
+ - mountPath: /etc/sw
+ name: config-users
+ readOnly: true
+ {{- 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 }}
+ {{- end }}
+ ports:
+ - containerPort: {{ .Values.filer.port }}
+ name: swfs-filer
+ - containerPort: {{ .Values.filer.grpcPort }}
+ #name: swfs-filer-grpc
+ readinessProbe:
+ httpGet:
+ path: /
+ port: {{ .Values.filer.port }}
+ scheme: HTTP
+ initialDelaySeconds: 10
+ periodSeconds: 15
+ successThreshold: 1
+ failureThreshold: 100
+ timeoutSeconds: 10
+ livenessProbe:
+ httpGet:
+ path: /
+ port: {{ .Values.filer.port }}
+ scheme: HTTP
+ initialDelaySeconds: 20
+ periodSeconds: 30
+ successThreshold: 1
+ failureThreshold: 5
+ timeoutSeconds: 10
+ {{- if .Values.filer.resources }}
+ resources:
+ {{ tpl .Values.filer.resources . | nindent 12 | trim }}
+ {{- end }}
+ volumes:
+ - name: seaweedfs-filer-log-volume
+ hostPath:
+ path: /storage/logs/seaweedfs/filer
+ type: DirectoryOrCreate
+ - name: db-schema-config-volume
+ configMap:
+ name: seaweedfs-db-init-config
+ - name: config-users
+ secret:
+ defaultMode: 420
+ secretName: seaweedfs-s3-secret
+ {{- 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 }}
+{{/* volumeClaimTemplates:*/}}
+{{/* - metadata:*/}}
+{{/* name: data-{{ .Release.Namespace }}*/}}
+{{/* spec:*/}}
+{{/* accessModes:*/}}
+{{/* - ReadWriteOnce*/}}
+{{/* resources:*/}}
+{{/* requests:*/}}
+{{/* storage: {{ .Values.filer.storage }}*/}}
+{{/* {{- if .Values.filer.storageClass }}*/}}
+{{/* storageClassName: {{ .Values.filer.storageClass }}*/}}
+{{/* {{- end }}*/}}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/ingress.yaml b/k8s/seaweedfs/templates/ingress.yaml
new file mode 100644
index 000000000..dcd52c138
--- /dev/null
+++ b/k8s/seaweedfs/templates/ingress.yaml
@@ -0,0 +1,59 @@
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: ingress-{{ template "seaweedfs.name" . }}-filer
+ annotations:
+ kubernetes.io/ingress.class: "nginx"
+ 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 '<head>' '<head> <base href="/sw-filer/">'; #add base url
+ sub_filter '="/' '="./'; #make absolute paths to relative
+ sub_filter '=/' '=./';
+ sub_filter '/seaweedfsstatic' './seaweedfsstatic';
+ sub_filter_once off;
+spec:
+ rules:
+ - http:
+ paths:
+ - path: /sw-filer/?(.*)
+ backend:
+ serviceName: {{ template "seaweedfs.name" . }}-filer
+ servicePort: {{ .Values.filer.port }}
+---
+apiVersion: extensions/v1beta1
+kind: Ingress
+metadata:
+ name: ingress-{{ template "seaweedfs.name" . }}-master
+ annotations:
+ kubernetes.io/ingress.class: "nginx"
+ 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 '<head>' '<head> <base href="/sw-master/">'; #add base url
+ sub_filter '="/' '="./'; #make absolute paths to relative
+ sub_filter '=/' '=./';
+ sub_filter '/seaweedfsstatic' './seaweedfsstatic';
+ sub_filter_once off;
+spec:
+ rules:
+ - http:
+ paths:
+ - path: /sw-master/?(.*)
+ backend:
+ serviceName: {{ template "seaweedfs.name" . }}-master
+ servicePort: {{ .Values.master.port }}
diff --git a/k8s/seaweedfs/templates/master-cert.yaml b/k8s/seaweedfs/templates/master-cert.yaml
new file mode 100644
index 000000000..a8b0fc1d1
--- /dev/null
+++ b/k8s/seaweedfs/templates/master-cert.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+ name: {{ template "seaweedfs.name" . }}-master-cert
+ namespace: {{ .Release.Namespace }}
+spec:
+ secretName: {{ template "seaweedfs.name" . }}-master-cert
+ issuerRef:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+ kind: ClusterIssuer
+ commonName: {{ .Values.certificates.commonName }}
+ organization:
+ - "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 }}
+ keyAlgorithm: {{ .Values.certificates.keyAlgorithm }}
+ keySize: {{ .Values.certificates.keySize }}
+ duration: {{ .Values.certificates.duration }}
+ renewBefore: {{ .Values.certificates.renewBefore }}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/master-service.yaml b/k8s/seaweedfs/templates/master-service.yaml
new file mode 100644
index 000000000..0ce467538
--- /dev/null
+++ b/k8s/seaweedfs/templates/master-service.yaml
@@ -0,0 +1,25 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "seaweedfs.name" . }}-master
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: master
+ 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
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: master
diff --git a/k8s/seaweedfs/templates/master-statefulset.yaml b/k8s/seaweedfs/templates/master-statefulset.yaml
new file mode 100644
index 000000000..e5a7a537a
--- /dev/null
+++ b/k8s/seaweedfs/templates/master-statefulset.yaml
@@ -0,0 +1,227 @@
+{{- if .Values.master.enabled }}
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ template "seaweedfs.name" . }}-master
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+spec:
+ serviceName: {{ template "seaweedfs.name" . }}-master
+ podManagementPolicy: Parallel
+ replicas: {{ .Values.master.replicas }}
+ {{- if (gt (int .Values.master.updatePartition) 0) }}
+ updateStrategy:
+ type: RollingUpdate
+ rollingUpdate:
+ partition: {{ .Values.master.updatePartition }}
+ {{- end }}
+ selector:
+ matchLabels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: master
+ template:
+ metadata:
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: master
+ 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 }}
+ {{- if .Values.global.imagePullSecrets }}
+ imagePullSecrets:
+ - name: {{ .Values.global.imagePullSecrets }}
+ {{- end }}
+ terminationGracePeriodSeconds: 60
+ {{- if .Values.master.priorityClassName }}
+ priorityClassName: {{ .Values.master.priorityClassName | quote }}
+ {{- end }}
+ enableServiceLinks: false
+ 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 }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ {{- if .Values.global.extraEnvironmentVars }}
+ {{- range $key, $value := .Values.global.extraEnvironmentVars }}
+ - name: {{ $key }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ command:
+ - "/bin/sh"
+ - "-ec"
+ - |
+ exec /usr/bin/weed -logdir=/logs \
+ {{- 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 }}
+ -metrics.address="{{ .Values.global.monitoring.gatewayHost }}:{{ .Values.global.monitoring.gatewayPort }}" \
+ {{- 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 }}
+ {{- if .Values.master.metricsIntervalSec }}
+ -metrics.intervalSeconds={{ .Values.master.metricsIntervalSec }} \
+ {{- end }}
+ -ip=${POD_NAME}.${SEAWEEDFS_FULLNAME}-master \
+ -peers={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
+ volumeMounts:
+ - name : data-{{ .Release.Namespace }}
+ mountPath: /data
+ - name: seaweedfs-master-log-volume
+ mountPath: "/logs/"
+ {{- 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
+ - containerPort: {{ .Values.master.grpcPort }}
+ #name: swfs-master-grpc
+ readinessProbe:
+ httpGet:
+ path: /cluster/status
+ port: {{ .Values.master.port }}
+ scheme: HTTP
+ initialDelaySeconds: 10
+ periodSeconds: 45
+ successThreshold: 2
+ failureThreshold: 100
+ timeoutSeconds: 10
+ livenessProbe:
+ httpGet:
+ path: /cluster/status
+ port: {{ .Values.master.port }}
+ scheme: HTTP
+ initialDelaySeconds: 20
+ periodSeconds: 30
+ successThreshold: 1
+ failureThreshold: 4
+ timeoutSeconds: 10
+ {{- if .Values.master.resources }}
+ resources:
+ {{ tpl .Values.master.resources . | nindent 12 | trim }}
+ {{- end }}
+ volumes:
+ - name: seaweedfs-master-log-volume
+ hostPath:
+ path: /storage/logs/seaweedfs/master
+ type: DirectoryOrCreate
+ - name: data-{{ .Release.Namespace }}
+ hostPath:
+ path: /ssd/seaweed-master/
+ type: DirectoryOrCreate
+ {{- 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 }}
+{{/* volumeClaimTemplates:*/}}
+{{/* - metadata:*/}}
+{{/* name: data-{{ .Release.Namespace }}*/}}
+{{/* spec:*/}}
+{{/* accessModes:*/}}
+{{/* - ReadWriteOnce*/}}
+{{/* resources:*/}}
+{{/* requests:*/}}
+{{/* storage: {{ .Values.master.storage }}*/}}
+{{/* {{- if .Values.master.storageClass }}*/}}
+{{/* storageClassName: {{ .Values.master.storageClass }}*/}}
+{{/* {{- end }}*/}}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/s3-deployment.yaml b/k8s/seaweedfs/templates/s3-deployment.yaml
new file mode 100644
index 000000000..b513e937b
--- /dev/null
+++ b/k8s/seaweedfs/templates/s3-deployment.yaml
@@ -0,0 +1,188 @@
+{{- if .Values.s3.enabled }}
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: {{ template "seaweedfs.name" . }}-s3
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+spec:
+ serviceName: {{ template "seaweedfs.name" . }}-s3
+ replicas: {{ .Values.s3.replicas }}
+ selector:
+ matchLabels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: s3
+ template:
+ metadata:
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: s3
+ spec:
+ restartPolicy: {{ default .Values.global.restartPolicy .Values.s3.restartPolicy }}
+ {{- if .Values.s3.tolerations }}
+ tolerations:
+ {{ tpl .Values.s3.tolerations . | nindent 8 | trim }}
+ {{- end }}
+ {{- if .Values.global.imagePullSecrets }}
+ imagePullSecrets:
+ - name: {{ .Values.global.imagePullSecrets }}
+ {{- end }}
+ terminationGracePeriodSeconds: 10
+ {{- if .Values.s3.priorityClassName }}
+ priorityClassName: {{ .Values.s3.priorityClassName | quote }}
+ {{- end }}
+ enableServiceLinks: false
+ 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.global.extraEnvironmentVars }}
+ {{- range $key, $value := .Values.global.extraEnvironmentVars }}
+ - name: {{ $key }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ command:
+ - "/bin/sh"
+ - "-ec"
+ - |
+ exec /usr/bin/weed -logdir=/logs \
+ {{- if .Values.s3.loggingOverrideLevel }}
+ -v={{ .Values.s3.loggingOverrideLevel }} \
+ {{- else }}
+ -v={{ .Values.global.loggingLevel }} \
+ {{- end }}
+ s3 \
+ -port={{ .Values.s3.port }} \
+ {{- if .Values.s3.metricsPort }}
+ -metricsPort {{ .Values.s3.metricsPort }} \
+ {{- end }}
+ {{- if .Values.global.enableSecurity }}
+ -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 }}
+ -filer={{ template "seaweedfs.name" . }}-filer-client:{{ .Values.filer.port }}
+ volumeMounts:
+ - name: logs
+ mountPath: "/logs/"
+ - mountPath: /etc/sw
+ name: config-users
+ readOnly: true
+ {{- 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
+ readinessProbe:
+ httpGet:
+ path: /
+ port: {{ .Values.s3.port }}
+ scheme: HTTP
+ initialDelaySeconds: 15
+ periodSeconds: 15
+ successThreshold: 1
+ failureThreshold: 100
+ timeoutSeconds: 10
+ livenessProbe:
+ httpGet:
+ path: /
+ port: {{ .Values.s3.port }}
+ scheme: HTTP
+ initialDelaySeconds: 20
+ periodSeconds: 60
+ successThreshold: 1
+ failureThreshold: 20
+ timeoutSeconds: 10
+ {{- if .Values.s3.resources }}
+ resources:
+ {{ tpl .Values.s3.resources . | nindent 12 | trim }}
+ {{- end }}
+ volumes:
+ - name: config-users
+ secret:
+ defaultMode: 420
+ secretName: seaweedfs-s3-secret
+ {{- if eq .Values.s3.logs.type "hostPath" }}
+ - name: logs
+ hostPath:
+ path: /storage/logs/seaweedfs/s3
+ type: DirectoryOrCreate
+ {{- 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/k8s/seaweedfs/templates/s3-service.yaml b/k8s/seaweedfs/templates/s3-service.yaml
new file mode 100644
index 000000000..122b33298
--- /dev/null
+++ b/k8s/seaweedfs/templates/s3-service.yaml
@@ -0,0 +1,23 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "seaweedfs.name" . }}-s3
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: s3
+spec:
+ 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.metricsPort }}
+ - name: "metrics"
+ port: {{ .Values.s3.metricsPort }}
+ targetPort: {{ .Values.s3.metricsPort }}
+ protocol: TCP
+{{- end }}
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: {{ if .Values.s3.enabled }}s3{{ else }}filer{{ end }}
diff --git a/k8s/seaweedfs/templates/s3-servicemonitor.yaml b/k8s/seaweedfs/templates/s3-servicemonitor.yaml
new file mode 100644
index 000000000..7f18f00f5
--- /dev/null
+++ b/k8s/seaweedfs/templates/s3-servicemonitor.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.s3.metricsPort }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "seaweedfs.name" . }}-s3
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: s3
+spec:
+ endpoints:
+ - interval: 30s
+ port: swfs-s3-metrics
+ scrapeTimeout: 5s
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: s3
+{{- end }} \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml b/k8s/seaweedfs/templates/seaweedfs-grafana-dashboard.yaml
new file mode 100644
index 000000000..eb5a5ebac
--- /dev/null
+++ b/k8s/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/k8s/seaweedfs/templates/seaweedfs-s3-secret.yaml b/k8s/seaweedfs/templates/seaweedfs-s3-secret.yaml
new file mode 100644
index 000000000..66fd5f28e
--- /dev/null
+++ b/k8s/seaweedfs/templates/seaweedfs-s3-secret.yaml
@@ -0,0 +1,21 @@
+{{- if not (or .Values.filer.s3.skipAuthSecretCreation .Values.s3.skipAuthSecretCreation) }}
+{{- $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"
+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"]}]}'
+{{- end }} \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/secret-seaweedfs-db.yaml b/k8s/seaweedfs/templates/secret-seaweedfs-db.yaml
new file mode 100644
index 000000000..c6132c9ea
--- /dev/null
+++ b/k8s/seaweedfs/templates/secret-seaweedfs-db.yaml
@@ -0,0 +1,14 @@
+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"
+stringData:
+ user: "YourSWUser"
+ password: "HardCodedPassword"
+ # better to random generate and create in DB
+ # password: {{ randAlphaNum 10 | sha256sum | b64enc | trunc 32 }}
diff --git a/k8s/seaweedfs/templates/security-configmap.yaml b/k8s/seaweedfs/templates/security-configmap.yaml
new file mode 100644
index 000000000..7d06614ec
--- /dev/null
+++ b/k8s/seaweedfs/templates/security-configmap.yaml
@@ -0,0 +1,52 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ name: {{ template "seaweedfs.name" . }}-security-config
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+data:
+ security.toml: |-
+ # this file is read by master, volume server, and filer
+
+ # the jwt signing key is read by master and volume server
+ # a jwt expires in 10 seconds
+ [jwt.signing]
+ key = "{{ randAlphaNum 10 | b64enc }}"
+
+ # 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/k8s/seaweedfs/templates/service-account.yaml b/k8s/seaweedfs/templates/service-account.yaml
new file mode 100644
index 000000000..e82ef7d62
--- /dev/null
+++ b/k8s/seaweedfs/templates/service-account.yaml
@@ -0,0 +1,29 @@
+#hack for delete pod master after migration
+---
+kind: ClusterRole
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: seaweefds-rw-cr
+rules:
+ - apiGroups: [""]
+ resources: ["pods"]
+ verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: seaweefds-rw-sa
+ namespace: {{ .Release.Namespace }}
+---
+kind: ClusterRoleBinding
+apiVersion: rbac.authorization.k8s.io/v1beta1
+metadata:
+ name: system:serviceaccount:seaweefds-rw-sa:default
+subjects:
+- kind: ServiceAccount
+ name: seaweefds-rw-sa
+ namespace: {{ .Release.Namespace }}
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: seaweefds-rw-cr \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/volume-cert.yaml b/k8s/seaweedfs/templates/volume-cert.yaml
new file mode 100644
index 000000000..72c62a0f5
--- /dev/null
+++ b/k8s/seaweedfs/templates/volume-cert.yaml
@@ -0,0 +1,33 @@
+{{- if .Values.global.enableSecurity }}
+apiVersion: certmanager.k8s.io/v1alpha1
+kind: Certificate
+metadata:
+ name: {{ template "seaweedfs.name" . }}-volume-cert
+ namespace: {{ .Release.Namespace }}
+spec:
+ secretName: {{ template "seaweedfs.name" . }}-volume-cert
+ issuerRef:
+ name: {{ template "seaweedfs.name" . }}-clusterissuer
+ kind: ClusterIssuer
+ commonName: {{ .Values.certificates.commonName }}
+ organization:
+ - "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 }}
+ keyAlgorithm: {{ .Values.certificates.keyAlgorithm }}
+ keySize: {{ .Values.certificates.keySize }}
+ duration: {{ .Values.certificates.duration }}
+ renewBefore: {{ .Values.certificates.renewBefore }}
+{{- end }}
diff --git a/k8s/seaweedfs/templates/volume-service.yaml b/k8s/seaweedfs/templates/volume-service.yaml
new file mode 100644
index 000000000..0a9173fde
--- /dev/null
+++ b/k8s/seaweedfs/templates/volume-service.yaml
@@ -0,0 +1,28 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "seaweedfs.name" . }}-volume
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: volume
+spec:
+ clusterIP: None
+ 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: "swfs-volume-metrics"
+ port: {{ .Values.volume.metricsPort }}
+ targetPort: {{ .Values.volume.metricsPort }}
+ protocol: TCP
+{{- end }}
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: volume \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/volume-servicemonitor.yaml b/k8s/seaweedfs/templates/volume-servicemonitor.yaml
new file mode 100644
index 000000000..1b286e9b6
--- /dev/null
+++ b/k8s/seaweedfs/templates/volume-servicemonitor.yaml
@@ -0,0 +1,18 @@
+{{- if .Values.volume.metricsPort }}
+apiVersion: monitoring.coreos.com/v1
+kind: ServiceMonitor
+metadata:
+ name: {{ template "seaweedfs.name" . }}-volume
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ component: volume
+spec:
+ endpoints:
+ - interval: 30s
+ port: swfs-volume-metrics
+ scrapeTimeout: 5s
+ selector:
+ app: {{ template "seaweedfs.name" . }}
+ component: volume
+{{- end }} \ No newline at end of file
diff --git a/k8s/seaweedfs/templates/volume-statefulset.yaml b/k8s/seaweedfs/templates/volume-statefulset.yaml
new file mode 100644
index 000000000..652fd9ea3
--- /dev/null
+++ b/k8s/seaweedfs/templates/volume-statefulset.yaml
@@ -0,0 +1,276 @@
+{{- if .Values.volume.enabled }}
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ template "seaweedfs.name" . }}-volume
+ namespace: {{ .Release.Namespace }}
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ heritage: {{ .Release.Service }}
+ release: {{ .Release.Name }}
+spec:
+ serviceName: {{ template "seaweedfs.name" . }}-volume
+ replicas: {{ .Values.volume.replicas }}
+ podManagementPolicy: Parallel
+ selector:
+ matchLabels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: volume
+ template:
+ metadata:
+ labels:
+ app: {{ template "seaweedfs.name" . }}
+ chart: {{ template "seaweedfs.chart" . }}
+ release: {{ .Release.Name }}
+ component: volume
+ 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 }}
+ {{- if .Values.global.imagePullSecrets }}
+ imagePullSecrets:
+ - name: {{ .Values.global.imagePullSecrets }}
+ {{- end }}
+ terminationGracePeriodSeconds: 10
+ {{- if .Values.volume.priorityClassName }}
+ priorityClassName: {{ .Values.volume.priorityClassName | quote }}
+ {{- end }}
+ enableServiceLinks: false
+ {{- if .Values.volume.dir_idx }}
+ initContainers:
+ - name: seaweedfs-vol-move-idx
+ image: {{ template "volume.image" . }}
+ imagePullPolicy: {{ .Values.global.pullPolicy | default "IfNotPresent" }}
+ command: [ '/bin/sh', '-c' ]
+ args: ['if ls {{ .Values.volume.dir }}/*.idx >/dev/null 2>&1; then mv {{ .Values.volume.dir }}/*.idx {{ .Values.volume.dir_idx }}/; fi;']
+ volumeMounts:
+ - name: idx
+ mountPath: {{ .Values.volume.dir_idx }}
+ - name: data
+ mountPath: {{ .Values.volume.dir }}
+ {{- 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.global.extraEnvironmentVars }}
+ {{- range $key, $value := .Values.global.extraEnvironmentVars }}
+ - name: {{ $key }}
+ value: {{ $value | quote }}
+ {{- end }}
+ {{- end }}
+ command:
+ - "/bin/sh"
+ - "-ec"
+ - |
+ exec /usr/bin/weed -logdir=/logs \
+ {{- 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={{ .Values.volume.dir }} \
+ {{- if .Values.volume.dir_idx }}
+ -dir.idx={{ .Values.volume.dir_idx }} \
+ {{- end }}
+ -max={{ .Values.volume.maxVolumes }} \
+ {{- if .Values.volume.rack }}
+ -rack={{ .Values.volume.rack }} \
+ {{- end }}
+ {{- if .Values.volume.dataCenter }}
+ -dataCenter={{ .Values.volume.dataCenter }} \
+ {{- end }}
+ -ip.bind={{ .Values.volume.ipBind }} \
+ -read.redirect={{ .Values.volume.readRedirect }} \
+ {{- 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 \
+ -compactionMBps={{ .Values.volume.compactionMBps }} \
+ -mserver={{ range $index := until (.Values.master.replicas | int) }}${SEAWEEDFS_FULLNAME}-master-{{ $index }}.${SEAWEEDFS_FULLNAME}-master:{{ $.Values.master.port }}{{ if lt $index (sub ($.Values.master.replicas | int) 1) }},{{ end }}{{ end }}
+ volumeMounts:
+ - name: data
+ mountPath: "{{ .Values.volume.dir }}/"
+ {{- if .Values.volume.dir_idx }}
+ - name: idx
+ mountPath: "{{ .Values.volume.dir_idx }}/"
+ {{- end }}
+ - name: logs
+ mountPath: "/logs/"
+ {{- 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
+ - containerPort: {{ .Values.volume.grpcPort }}
+ #name: swfs-vol-grpc
+ readinessProbe:
+ httpGet:
+ path: /status
+ port: {{ .Values.volume.port }}
+ scheme: HTTP
+ initialDelaySeconds: 15
+ periodSeconds: 90
+ successThreshold: 1
+ failureThreshold: 100
+ timeoutSeconds: 30
+ livenessProbe:
+ httpGet:
+ path: /status
+ port: {{ .Values.volume.port }}
+ scheme: HTTP
+ initialDelaySeconds: 20
+ periodSeconds: 90
+ successThreshold: 1
+ failureThreshold: 4
+ timeoutSeconds: 30
+ {{- if .Values.volume.resources }}
+ resources:
+ {{ tpl .Values.volume.resources . | nindent 12 | trim }}
+ {{- end }}
+ {{- $hostpath_exists := include "volume.hostpath_exists" . -}}
+ {{- if $hostpath_exists }}
+ volumes:
+ {{- if eq .Values.volume.data.type "hostPath" }}
+ - name: data
+ hostPath:
+ path: /storage/object_store/
+ type: DirectoryOrCreate
+ {{- end }}
+ {{- if and (eq .Values.volume.idx.type "hostPath") .Values.volume.dir_idx }}
+ - name: idx
+ hostPath:
+ path: /ssd/seaweedfs-volume-idx/
+ type: DirectoryOrCreate
+ {{- end }}
+ {{- if eq .Values.volume.logs.type "hostPath" }}
+ - name: logs
+ hostPath:
+ path: /storage/logs/seaweedfs/volume
+ type: DirectoryOrCreate
+ {{- 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 }}
+ {{- end }}
+ {{- if .Values.volume.nodeSelector }}
+ nodeSelector:
+ {{ tpl .Values.volume.nodeSelector . | indent 8 | trim }}
+ {{- end }}
+ {{- $pvc_exists := include "volume.pvc_exists" . -}}
+ {{- if $pvc_exists }}
+ volumeClaimTemplates:
+ {{- if eq .Values.volume.data.type "persistentVolumeClaim"}}
+ - metadata:
+ name: data
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ storageClassName: {{ .Values.volume.data.storageClass }}
+ resources:
+ requests:
+ storage: {{ .Values.volume.data.size }}
+ {{- end }}
+ {{- if and (eq .Values.volume.idx.type "persistentVolumeClaim") .Values.volume.dir_idx }}
+ - metadata:
+ name: idx
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ storageClassName: {{ .Values.volume.idx.storageClass }}
+ resources:
+ requests:
+ storage: {{ .Values.volume.idx.size }}
+ {{- end }}
+ {{- if eq .Values.volume.logs.type "persistentVolumeClaim" }}
+ - metadata:
+ name: logs
+ spec:
+ accessModes: [ "ReadWriteOnce" ]
+ storageClassName: {{ .Values.volume.logs.storageClass }}
+ resources:
+ requests:
+ storage: {{ .Values.volume.logs.size }}
+ {{- end }}
+ {{- end }}
+{{- end }}
diff --git a/k8s/seaweedfs/values.yaml b/k8s/seaweedfs/values.yaml
new file mode 100644
index 000000000..a4abaccf3
--- /dev/null
+++ b/k8s/seaweedfs/values.yaml
@@ -0,0 +1,418 @@
+# Available parameters and their default values for the SeaweedFS chart.
+
+global:
+ registry: ""
+ repository: ""
+ imageName: chrislusf/seaweedfs
+ # imageTag: "2.41" - started using {.Chart.appVersion}
+ imagePullPolicy: IfNotPresent
+ imagePullSecrets: imagepullsecret
+ restartPolicy: Always
+ loggingLevel: 1
+ enableSecurity: false
+ monitoring:
+ enabled: false
+ gatewayHost: null
+ gatewayPort: null
+ # 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:9333"
+ WEED_CLUSTER_SW_FILER: "seaweedfs-filer-client:8888"
+
+image:
+ registry: ""
+ repository: ""
+
+master:
+ enabled: true
+ repository: null
+ imageName: null
+ imageTag: null
+ imageOverride: null
+ restartPolicy: null
+ replicas: 1
+ port: 9333
+ grpcPort: 19333
+ ipBind: "0.0.0.0"
+ volumePreallocate: false
+ #Master stops directing writes to oversized volumes
+ volumeSizeLimitMB: 30000
+ 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
+
+ extraVolumes: ""
+ extraVolumeMounts: ""
+
+ # storage and storageClass are the settings for configuring stateful
+ # storage for the master pods. storage should be set to the disk size of
+ # the attached volume. storageClass is the class of storage which defaults
+ # to null (the Kube cluster will pick the default).
+ storage: 25Gi
+ storageClass: null
+
+ # 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: null
+
+ # 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: {{ template "seaweedfs.name" . }}
+ release: "{{ .Release.Name }}"
+ 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: |
+ # beta.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: ""
+
+ 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
+
+volume:
+ enabled: true
+ repository: null
+ imageName: null
+ imageTag: null
+ 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
+
+# can use ANY storage-class , example with local-path-provisner
+# data:
+# type: "persistentVolumeClaim"
+# size: "24Ti"
+# storageClass: "local-path-provisioner"
+ data:
+ type: "hostPath"
+ size: ""
+ storageClass: ""
+ idx:
+ type: "hostPath"
+ size: ""
+ storageClass: ""
+
+ logs:
+ type: "hostPath"
+ size: ""
+ storageClass: ""
+
+ # limit background compaction or copying speed in mega bytes per second
+ compactionMBps: "50"
+
+ # Directories to store data files. dir[,dir]... (default "/tmp")
+ dir: "/data"
+ # Directories to store index files. dir[,dir]... (default "/tmp")
+ dir_idx: null
+
+ # Maximum numbers of volumes, count[,count]...
+ # If set to zero on non-windows OS, the limit will be auto configured. (default "7")
+ maxVolumes: "0"
+
+ # Volume server's rack name
+ rack: null
+
+ # Volume server's data center name
+ dataCenter: null
+
+ # Redirect moved or non-local volumes. (default true)
+ readRedirect: true
+
+ # Comma separated Ip addresses having write permission. No limit if empty.
+ whiteList: null
+
+ # Adjust jpg orientation when uploading.
+ imagesFixOrientation: false
+
+ extraVolumes: ""
+ extraVolumeMounts: ""
+
+ # 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: {{ template "seaweedfs.name" . }}
+ release: "{{ .Release.Name }}"
+ 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: null
+
+ # 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: |
+ # beta.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: ""
+
+
+filer:
+ enabled: true
+ repository: null
+ imageName: null
+ imageTag: null
+ imageOverride: null
+ restartPolicy: null
+ replicas: 1
+ port: 8888
+ grpcPort: 18888
+ metricsPort: 9327
+ loggingOverrideLevel: null
+ # 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
+ # enable peers sync metadata, for leveldb (localdb for filer but with sync across)
+ enable_peers: false
+
+ # Whether proxy or redirect to volume server during file GET request
+ redirectOnRead: false
+
+ # Limit sub dir listing size (default 100000)
+ dirListLimit: 100000
+
+ # Turn off directory listing
+ disableDirListing: false
+
+ # Disable http request, only gRpc operations are allowed
+ disableHttp: false
+
+ # storage and storageClass are the settings for configuring stateful
+ # storage for the master pods. storage should be set to the disk size of
+ # the attached volume. storageClass is the class of storage which defaults
+ # to null (the Kube cluster will pick the default).
+ storage: 25Gi
+ storageClass: null
+
+ extraVolumes: ""
+ extraVolumeMounts: ""
+
+ # 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: {{ template "seaweedfs.name" . }}
+ release: "{{ .Release.Name }}"
+ 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: null
+
+ # 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: |
+ # beta.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: ""
+
+ # extraEnvVars is a list of extra enviroment variables to set with the stateful set.
+ extraEnvironmentVars:
+ WEED_MYSQL_ENABLED: "true"
+ 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"
+ WEED_LEVELDB2_ENABLED: "false"
+ # 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"
+
+ s3:
+ enabled: true
+ port: 8333
+ #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
+ skipAuthSecretCreation: false
+
+s3:
+ enabled: false
+ repository: null
+ imageName: null
+ imageTag: null
+ restartPolicy: null
+ replicas: 1
+ port: 8333
+ metricsPort: 9327
+ loggingOverrideLevel: null
+ #allow empty folders
+ allowEmptyFolder: true
+ # enable user & permission to s3 (need to inject to all services)
+ enableAuth: false
+ skipAuthSecretCreation: false
+
+ # Suffix of the host name, {bucket}.{domainName}
+ domainName: ""
+
+ extraVolumes: ""
+ extraVolumeMounts: ""
+
+ # 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: null
+
+ # 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: |
+ # beta.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: ""
+
+ logs:
+ type: "hostPath"
+ size: ""
+ storageClass: ""
+
+cronjob:
+ enabled: true
+ master: "seaweedfs-master:9333"
+ filer: "seaweedfs-filer-client:8888"
+ tolerations: ""
+ nodeSelector: |
+ sw-backend: "true"
+ replication:
+ enable: true
+ collectionPattern: ""
+ schedule: "*/7 * * * *"
+ resources: null
+ # balance all volumes among volume servers
+ # ALL|EACH_COLLECTION|<collection_name>
+ collection: ""
+
+
+certificates:
+ commonName: "SeaweedFS CA"
+ ipAddresses: []
+ keyAlgorithm: rsa
+ keySize: 2048
+ duration: 2160h # 90d
+ renewBefore: 360h # 15d