add standalone mode support (#881)

* add standalone mode support

* update readme file

* change non-root from 1000 to 10001

* delete self sign crt content

* modify security content

* fix synatx error for readme file.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* update image repository and tag info.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix helm chart syntax issue.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix helm chart syntax issue.

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: houseme <housemecn@gmail.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: loverustfs <hello@rustfs.com>
This commit is contained in:
majinghe
2025-11-19 13:56:21 +08:00
committed by GitHub
parent a13ce08590
commit 44f3f3d070
10 changed files with 183 additions and 31 deletions
+2 -2
View File
@@ -66,8 +66,8 @@ COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /usr/bin/rustfs /entrypoint.sh RUN chmod +x /usr/bin/rustfs /entrypoint.sh
RUN addgroup -g 1000 -S rustfs && \ RUN addgroup -g 10001 -S rustfs && \
adduser -u 1000 -G rustfs -S rustfs -D && \ adduser -u 10001 -G rustfs -S rustfs -D && \
mkdir -p /data /logs && \ mkdir -p /data /logs && \
chown -R rustfs:rustfs /data /logs && \ chown -R rustfs:rustfs /data /logs && \
chmod 0750 /data /logs chmod 0750 /data /logs
+10 -6
View File
@@ -1,12 +1,14 @@
# rustfs-helm # rustfs-helm
You can use this helm chart to deploy rustfs on k8s cluster. You can use this helm chart to deploy rustfs on k8s cluster. The chart supports standalone and distributed mode. For standalone mode, there is only one pod and one pvc; for distributed mode, there are two styles, 4 pods and 16 pvcs(each pod has 4 pvcs), 16 pods and 16 pvcs(each pod has 1 pvc). You should decide which mode and style suits for your situation. You can specify the parameters `mode` and `replicaCount` to install different mode and style.
## Parameters Overview ## Parameters Overview
| parameter | description | default value | | parameter | description | default value |
| -- | -- | -- | | -- | -- | -- |
| replicaCount | Number of cluster nodes. | Default is `4`. | | replicaCount | Number of cluster nodes. | Default is `4`. |
| mode.standalone.enabled | RustFS standalone mode support, namely one pod one pvc. | Default is `false` |
| mode.distributed.enabled | RustFS distributed mode support, namely multiple pod multiple pvc. | Default is `true`. |
| image.repository | docker image repository. | rustfs/rustfs. | | image.repository | docker image repository. | rustfs/rustfs. |
| image.tag | the tag for rustfs docker image | "latest" | | image.tag | the tag for rustfs docker image | "latest" |
| secret.rustfs.access_key | RustFS Access Key ID | `rustfsadmin` | | secret.rustfs.access_key | RustFS Access Key ID | `rustfsadmin` |
@@ -15,7 +17,6 @@ You can use this helm chart to deploy rustfs on k8s cluster.
| ingress.className | Specify the ingress class, traefik or nginx. | `nginx` | | ingress.className | Specify the ingress class, traefik or nginx. | `nginx` |
**NOTE**: [`local-path`](https://github.com/rancher/local-path-provisioner) is used by k3s. If you want to use `local-path`, running the command, **NOTE**: [`local-path`](https://github.com/rancher/local-path-provisioner) is used by k3s. If you want to use `local-path`, running the command,
``` ```
@@ -25,7 +26,7 @@ kubectl apply -f https://raw.githubusercontent.com/rancher/local-path-provisione
## Requirement ## Requirement
* Helm V3 * Helm V3
* RustFS >= 1.0.0-alpha.66 * RustFS >= 1.0.0-alpha.68
## Installation ## Installation
@@ -43,6 +44,8 @@ helm install rustfs -n rustfs --create-namespace ./ --set ingress.className="ngi
> `traefik` or `nginx`, the different is the session sticky/affinity annotations. > `traefik` or `nginx`, the different is the session sticky/affinity annotations.
**NOTE**: If you want to install standalone mode, specify the installation parameter `--set mode.standalone.enabled="true",mode.distributed.enabled="false"`; If you want to install distributed mode with 16 pods, specify the installation parameter `--set replicaCount="16"`.
Check the pod status Check the pod status
``` ```
@@ -59,12 +62,12 @@ Check the ingress status
``` ```
kubectl -n rustfs get ing kubectl -n rustfs get ing
NAME CLASS HOSTS ADDRESS PORTS AGE NAME CLASS HOSTS ADDRESS PORTS AGE
rustfs nginx xmg.rustfs.com 10.43.237.152 80, 443 29m rustfs nginx your.rustfs.com 10.43.237.152 80, 443 29m
``` ```
Access the rustfs cluster via `https://xmg.rustfs.com` with the default username and password `rustfsadmin`. Access the rustfs cluster via `https://your.rustfs.com` with the default username and password `rustfsadmin`.
> Replace the `xmg.rustfs.com` with your own domain as well as the certificates. > Replace the `your.rustfs.com` with your own domain as well as the certificates.
## Uninstall ## Uninstall
@@ -73,3 +76,4 @@ Uninstalling the rustfs installation with command,
``` ```
helm uninstall rustfs -n rustfs helm uninstall rustfs -n rustfs
``` ```
+4
View File
@@ -8,9 +8,13 @@ data:
RUSTFS_OBS_LOG_DIRECTORY: {{ .Values.config.rustfs.obs_log_directory | quote }} RUSTFS_OBS_LOG_DIRECTORY: {{ .Values.config.rustfs.obs_log_directory | quote }}
RUSTFS_CONSOLE_ENABLE: {{ .Values.config.rustfs.console_enable | quote }} RUSTFS_CONSOLE_ENABLE: {{ .Values.config.rustfs.console_enable | quote }}
RUSTFS_LOG_LEVEL: {{ .Values.config.rustfs.log_level | quote }} RUSTFS_LOG_LEVEL: {{ .Values.config.rustfs.log_level | quote }}
{{- if .Values.mode.distributed.enabled }}
{{- if eq (int .Values.replicaCount) 4 }} {{- if eq (int .Values.replicaCount) 4 }}
RUSTFS_VOLUMES: "http://rustfs-{0...3}.rustfs-headless.rustfs.svc.cluster.local:9000/data/rustfs{0...3}" RUSTFS_VOLUMES: "http://rustfs-{0...3}.rustfs-headless.rustfs.svc.cluster.local:9000/data/rustfs{0...3}"
{{- else if eq (int .Values.replicaCount) 16 }} {{- else if eq (int .Values.replicaCount) 16 }}
RUSTFS_VOLUMES: "http://rustfs-{0...15}.rustfs-headless.rustfs.svc.cluster.local:9000/data" RUSTFS_VOLUMES: "http://rustfs-{0...15}.rustfs-headless.rustfs.svc.cluster.local:9000/data"
{{- end }} {{- end }}
{{- else }}
RUSTFS_VOLUMES: "/data"
{{- end }}
RUSTFS_OBS_ENVIRONMENT: "develop" RUSTFS_OBS_ENVIRONMENT: "develop"
+96
View File
@@ -0,0 +1,96 @@
{{- if .Values.mode.standalone.enabled }}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "rustfs.fullname" . }}
labels:
app: {{ include "rustfs.name" . }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ include "rustfs.name" . }}
template:
metadata:
labels:
app: {{ include "rustfs.name" . }}
spec:
{{- if .Values.podSecurityContext }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 12 }}
{{- end }}
initContainers:
- name: init-step
image: busybox
imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
runAsUser: 0
runAsGroup: 0
command:
- sh
- -c
- |
mkdir -p /data /logs
chown -R 10001:10001 /data /logs
volumeMounts:
- name: data
mountPath: /data
- name: logs
mountPath: /logs
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["/usr/bin/rustfs"]
imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.containerSecurityContext }}
securityContext:
{{- toYaml .Values.containerSecurityContext | nindent 12 }}
{{- end }}
ports:
- containerPort: {{ .Values.service.ep_port }}
name: endpoint
- containerPort: {{ .Values.service.console_port }}
name: console
envFrom:
- configMapRef:
name: {{ include "rustfs.fullname" . }}-config
- secretRef:
name: {{ include "rustfs.fullname" . }}-secret
resources:
requests:
memory: {{ .Values.resources.requests.memory }}
cpu: {{ .Values.resources.requests.cpu }}
limits:
memory: {{ .Values.resources.limits.memory }}
cpu: {{ .Values.resources.limits.cpu }}
livenessProbe:
httpGet:
path: /health
port: 9000
initialDelaySeconds: 10
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
readinessProbe:
httpGet:
path: /health
port: 9000
initialDelaySeconds: 30
periodSeconds: 5
timeoutSeconds: 3
successThreshold: 1
failureThreshold: 3
volumeMounts:
- name: logs
mountPath: /logs
- name: data
mountPath: /data
volumes:
- name: logs
persistentVolumeClaim:
claimName: {{ include "rustfs.fullname" . }}-logs
- name: data
persistentVolumeClaim:
claimName: {{ include "rustfs.fullname" . }}-data
{{- end }}
+24
View File
@@ -0,0 +1,24 @@
{{- if .Values.mode.standalone.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "rustfs.fullname" . }}-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: {{ .Values.storageclass.name }}
resources:
requests:
storage: {{ .Values.storageclass.size }}
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "rustfs.fullname" . }}-logs
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: {{ .Values.storageclass.name }}
resources:
requests:
storage: {{ .Values.storageclass.size }}
{{- end }}
+4
View File
@@ -1,3 +1,4 @@
{{- if .Values.mode.distributed.enabled }}
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
@@ -22,18 +23,21 @@ spec:
name: console name: console
selector: selector:
app: {{ include "rustfs.name" . }} app: {{ include "rustfs.name" . }}
{{- end }}
--- ---
apiVersion: v1 apiVersion: v1
kind: Service kind: Service
metadata: metadata:
name: {{ include "rustfs.fullname" . }}-svc name: {{ include "rustfs.fullname" . }}-svc
{{- if .Values.mode.distributed.enabled }}
{{- if eq .Values.ingress.className "traefik" }} {{- if eq .Values.ingress.className "traefik" }}
{{- with .Values.ingress.traefikAnnotations }} {{- with .Values.ingress.traefikAnnotations }}
annotations: annotations:
{{- toYaml . | nindent 4 }} {{- toYaml . | nindent 4 }}
{{- end }} {{- end }}
{{- end }} {{- end }}
{{- end }}
labels: labels:
{{- include "rustfs.labels" . | nindent 4 }} {{- include "rustfs.labels" . | nindent 4 }}
spec: spec:
+26 -13
View File
@@ -1,3 +1,4 @@
{{- if .Values.mode.distributed.enabled }}
apiVersion: apps/v1 apiVersion: apps/v1
kind: StatefulSet kind: StatefulSet
metadata: metadata:
@@ -14,10 +15,17 @@ spec:
labels: labels:
app: {{ include "rustfs.name" . }} app: {{ include "rustfs.name" . }}
spec: spec:
{{- if .Values.podSecurityContext }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 12 }}
{{- end }}
initContainers: initContainers:
- name: init-step - name: init-step
image: busybox image: busybox
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
securityContext:
runAsUser: 0
runAsGroup: 0
env: env:
- name: REPLICA_COUNT - name: REPLICA_COUNT
value: "{{ .Values.replicaCount }}" value: "{{ .Values.replicaCount }}"
@@ -33,8 +41,8 @@ spec:
mkdir -p /data mkdir -p /data
fi fi
chown -R 1000:1000 /data chown -R 10001:10001 /data
chown -R 1000:1000 /logs chown -R 10001:10001 /logs
volumeMounts: volumeMounts:
{{- if eq (int .Values.replicaCount) 4 }} {{- if eq (int .Values.replicaCount) 4 }}
{{- range $i := until (int .Values.replicaCount) }} {{- range $i := until (int .Values.replicaCount) }}
@@ -52,9 +60,9 @@ spec:
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
command: ["/usr/bin/rustfs"] command: ["/usr/bin/rustfs"]
imagePullPolicy: {{ .Values.image.pullPolicy }} imagePullPolicy: {{ .Values.image.pullPolicy }}
{{- if .Values.securityContext }} {{- if .Values.containerSecurityContext }}
securityContext: securityContext:
{{- toYaml .Values.securityContext | nindent 12 }} {{- toYaml .Values.containerSecurityContext | nindent 12 }}
{{- end }} {{- end }}
ports: ports:
- containerPort: {{ .Values.service.ep_port }} - containerPort: {{ .Values.service.ep_port }}
@@ -89,7 +97,6 @@ spec:
httpGet: httpGet:
path: /health path: /health
port: 9000 port: 9000
exec:
initialDelaySeconds: 30 initialDelaySeconds: 30
periodSeconds: 5 periodSeconds: 5
timeoutSeconds: 3 timeoutSeconds: 3
@@ -107,12 +114,17 @@ spec:
- name: data - name: data
mountPath: /data mountPath: /data
{{- end }} {{- end }}
volumes:
- name: logs
emptyDir: {}
volumeClaimTemplates: volumeClaimTemplates:
{{- if eq (int .Values.replicaCount) 4 }} - metadata:
{{- range $i := until (int .Values.replicaCount) }} name: logs
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: {{ $.Values.storageclass.name }}
resources:
requests:
storage: {{ $.Values.storageclass.size}}
{{- if eq (int .Values.replicaCount) 4 }}
{{- range $i := until (int .Values.replicaCount) }}
- metadata: - metadata:
name: data-rustfs-{{ $i }} name: data-rustfs-{{ $i }}
spec: spec:
@@ -121,8 +133,8 @@ spec:
resources: resources:
requests: requests:
storage: {{ $.Values.storageclass.size}} storage: {{ $.Values.storageclass.size}}
{{- end }} {{- end }}
{{- else if eq (int .Values.replicaCount) 16 }} {{- else if eq (int .Values.replicaCount) 16 }}
- metadata: - metadata:
name: data name: data
spec: spec:
@@ -131,4 +143,5 @@ spec:
resources: resources:
requests: requests:
storage: {{ $.Values.storageclass.size}} storage: {{ $.Values.storageclass.size}}
{{- end }} {{- end }}
{{- end }}
+1 -1
View File
@@ -1,3 +1,3 @@
-----BEGIN CERTIFICATE----- -----BEGIN CERTIFICATE-----
Please input your cert file content. Input your crt content.
-----END CERTIFICATE----- -----END CERTIFICATE-----
+1 -1
View File
@@ -1,3 +1,3 @@
-----BEGIN PRIVATE KEY----- -----BEGIN PRIVATE KEY-----
Please input your key file content Input your private key.
-----END PRIVATE KEY----- -----END PRIVATE KEY-----
+15 -8
View File
@@ -9,9 +9,9 @@ replicaCount: 4
image: image:
repository: rustfs/rustfs repository: rustfs/rustfs
# This sets the pull policy for images. # This sets the pull policy for images.
pullPolicy: Always pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion. # Overrides the image tag whose default is the chart appVersion.
tag: "1.0.0-alpha.66" tag: "latest"
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/ # This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: [] imagePullSecrets: []
@@ -19,6 +19,13 @@ imagePullSecrets: []
nameOverride: "" nameOverride: ""
fullnameOverride: "" fullnameOverride: ""
mode:
standalone:
enabled: false
distributed:
enabled: true
secret: secret:
rustfs: rustfs:
access_key: rustfsadmin access_key: rustfsadmin
@@ -54,16 +61,16 @@ podAnnotations: {}
podLabels: {} podLabels: {}
podSecurityContext: podSecurityContext:
{} fsGroup: 10001
# fsGroup: 2000 runAsUser: 10001
runAsGroup: 10001
securityContext: containerSecurityContext:
capabilities: capabilities:
drop: drop:
- ALL - ALL
readOnlyRootFilesystem: true readOnlyRootFilesystem: true
runAsNonRoot: true runAsNonRoot: true
runAsUser: 1000
service: service:
type: NodePort type: NodePort
@@ -87,7 +94,7 @@ ingress:
nginx.ingress.kubernetes.io/session-cookie-max-age: "3600" nginx.ingress.kubernetes.io/session-cookie-max-age: "3600"
nginx.ingress.kubernetes.io/session-cookie-name: rustfs nginx.ingress.kubernetes.io/session-cookie-name: rustfs
hosts: hosts:
- host: xmg.rustfs.com - host: your.rustfs.com
paths: paths:
- path: / - path: /
pathType: ImplementationSpecific pathType: ImplementationSpecific