Skip to main content

Kubernetes Deployment

Chart: curvine/curvine, version 0.3.2-alpha.

Prerequisites​

  • Kubernetes 1.20+
  • Helm 3.x
  • A default StorageClass for master/worker PVCs

Architecture​

Helm release curvine is deployed in namespace curvine:

ResourceDescription
StatefulSet curvine-masterMetadata and Raft journal
StatefulSet curvine-workerData nodes
Service curvine-masterHeadless, RPC 8995
Service curvine-workerHeadless, RPC 8997

openKruise.enabled defaults to false. StatefulSets use apps/v1.

Deployment​

Add repository​

helm repo add curvine https://curvineio.github.io/helm-charts
helm repo update

Install​

helm upgrade --install curvine curvine/curvine \
--version 0.3.2-alpha \
-n curvine \
--create-namespace \
--wait --timeout 10m

Verify​

kubectl get pods,svc,pvc -n curvine

Web UI:

kubectl port-forward -n curvine svc/curvine-master 9000:9000

Master addresses​

Single replica:

curvine-master.curvine.svc.cluster.local:8995

Three replicas:

curvine-master-0.curvine-master.curvine.svc.cluster.local:8995,curvine-master-1.curvine-master.curvine.svc.cluster.local:8995,curvine-master-2.curvine-master.curvine.svc.cluster.local:8995

Upgrade​

helm upgrade curvine curvine/curvine \
--version 0.3.2-alpha \
-n curvine \
--reuse-values \
--set worker.replicas=3

master.replicas cannot be changed after install.

Uninstall​

helm uninstall curvine -n curvine
kubectl delete pvc -n curvine -l app.kubernetes.io/instance=curvine
kubectl delete namespace curvine

Troubleshooting​

SymptomCommandCause
Pod Pendingkubectl describe pod -n curvine <name>Insufficient resources; no StorageClass
Slow master startupkubectl logs curvine-master-0 -n curvineRaft replay in progress
PVC Pendingkubectl get scNo available StorageClass

Configuration Reference​

Chart version 0.3.2-alpha. Defaults below match helm show values curvine/curvine --version 0.3.2-alpha.

Global​

ParameterDefaultDescription
global.clusterDomaincluster.localKubernetes cluster domain

Cluster​

ParameterDefaultDescription
cluster.idcurvineCluster ID
cluster.formatMasterfalseFormat master data on startup
cluster.formatWorkerfalseFormat worker data on startup
cluster.formatJournalfalseFormat journal data on startup

Image​

ParameterDefaultDescription
image.repositoryghcr.io/curvineio/curvineImage repository
image.tag""Empty uses v{Chart.AppVersion}
image.pullPolicyIfNotPresentImage pull policy
image.pullSecrets[]Image pull secrets

OpenKruise​

openKruise.enabled defaults to false. Master and worker use standard apps/v1 StatefulSets.

Set openKruise.enabled=true to install the kruise subchart and switch master/worker to Advanced StatefulSet (apps.kruise.io/v1beta1).

ParameterDefaultDescription
openKruise.enabledfalseEnable Advanced StatefulSet
openKruise.podUpdatePolicyInPlaceOnlyInPlaceOnly | InPlaceIfPossible | ReCreate
openKruise.persistentPodState.autoGeneratetrueAuto-generate PersistentPodState
openKruise.persistentPodState.preferredPersistentTopologykubernetes.io/hostnamePreferred topology key
openKruise.persistentPodState.requiredPersistentTopology""Required topology key (optional)
kruise.installation.namespacekruise-systemKruise subchart namespace (when enabled)
kruise.installation.createNamespacetrueCreate Kruise namespace

Master​

ParameterDefaultDescription
master.replicas1Must be odd (1, 3, 5, â€Ļ)
master.rpcPort8995RPC port
master.journalPort8996Journal/Raft port
master.webPort9000Web UI port
master.web1Port9001Additional web port
master.startupProbe.enabledtrueStartup probe
master.startupProbe.failureThreshold90Allow long Raft replay
master.storage.meta.enabledtrueEnable metadata PVC
master.storage.meta.storageClass""Empty uses default StorageClass
master.storage.meta.size5GiMetadata PVC size
master.storage.meta.hostPath""hostPath when no StorageClass
master.storage.meta.mountPath/opt/curvine/data/metaMount path
master.storage.journal.enabledtrueEnable journal PVC
master.storage.journal.storageClass""Empty uses default StorageClass
master.storage.journal.size10GiJournal PVC size
master.storage.journal.hostPath""hostPath when no StorageClass
master.storage.journal.mountPath/opt/curvine/data/journalMount path
master.resources.requests.cpu500mCPU request
master.resources.requests.memory1GiMemory request
master.resources.limits.cpu1000mCPU limit
master.resources.limits.memory2GiMemory limit
master.antiAffinity.enabledfalsePod anti-affinity
master.antiAffinity.typerequiredrequired or preferred
master.persistentTopology.enabledtruePersistentPodState topology
master.persistentTopology.keykubernetes.io/hostnameTopology key
master.nodeSelector{}Node selector
master.tolerations[]Tolerations
master.affinity{}Affinity rules

Worker​

ParameterDefaultDescription
worker.replicas1Worker replica count
worker.rpcPort8997RPC port
worker.webPort9001Web UI port
worker.s3Gateway.enabledfalseEnable S3 gateway
worker.s3Gateway.listen0.0.0.0:9900S3 gateway listen address
worker.s3Gateway.enableDistributedAuthtrueDistributed auth for S3
worker.s3Gateway.service.typeClusterIPS3 service type
worker.hostNetworkfalseUse host network
worker.dnsPolicyClusterFirstDNS policy
worker.usePodIPAsHostnamefalseUse Pod IP as worker hostname
worker.privilegedtruePrivileged mode (FUSE)
worker.storage.dataDirs[0].namedata1Data directory name
worker.storage.dataDirs[0].typeSSDStorage type
worker.storage.dataDirs[0].enabledtrueEnable data directory
worker.storage.dataDirs[0].size20GiPVC size
worker.storage.dataDirs[0].storageClass""Empty uses default StorageClass
worker.storage.dataDirs[0].hostPath""hostPath when no StorageClass
worker.storage.dataDirs[0].mountPath/data/data1Mount path
worker.resources.requests.cpu500mCPU request
worker.resources.requests.memory1GiMemory request
worker.resources.limits.cpu1000mCPU limit
worker.resources.limits.memory2GiMemory limit
worker.antiAffinity.enabledtruePod anti-affinity
worker.antiAffinity.typepreferredrequired or preferred
worker.nodeSelector{}Node selector
worker.tolerations[]Tolerations
worker.affinity{}Affinity rules

Service​

ParameterDefaultDescription
service.master.typeClusterIPHeadless (ClusterIP: None)
service.worker.typeClusterIPHeadless (ClusterIP: None)
service.masterExternal.enabledfalseExternal master access
service.masterExternal.typeClusterIPExternal service type
service.masterExternal.loadBalancerIP""LoadBalancer IP

Service account and RBAC​

ParameterDefaultDescription
serviceAccount.createtrueCreate ServiceAccount
serviceAccount.name""Auto-generated when empty
rbac.createtrueCreate RBAC resources

Curvine config (config.*)​

ParameterDefaultDescription
config.master.metaDir/opt/curvine/data/metaMaster metadata directory
config.journal.enabletrueEnable journal
config.journal.journalDir/opt/curvine/data/journalJournal directory
config.journal.snapshotInterval6hSnapshot interval
config.journal.snapshotEntries1000000Snapshot entry threshold
config.client.blockSizeStr64MBClient block size
config.log.levelINFOLog level
config.log.logDir/opt/curvine/logsLog directory
config.log.consoletrueRoute logs to stdout

Config overrides (configOverrides.*)​

Override individual TOML sections without replacing the full config:

ParameterDefaultDescription
configOverrides.master{}Master section overrides
configOverrides.journal{}Journal section overrides
configOverrides.worker{}Worker section overrides
configOverrides.client{}Client section overrides
configOverrides.log{}Log section overrides

Storage modes​

ModeConfiguration
PVC (default)storageClass: "" uses cluster default StorageClass
Named StorageClassmaster.storage.*.storageClass, worker.storage.dataDirs[].storageClass
hostPathstorageClass: "" with hostPath set

Examples​

Lower resource requests:

helm upgrade curvine curvine/curvine -n curvine --reuse-values \
--set master.resources.requests.cpu=200m \
--set master.resources.requests.memory=512Mi \
--set worker.resources.requests.cpu=200m \
--set worker.resources.requests.memory=512Mi

Full parameter list:

helm show values curvine/curvine --version 0.3.2-alpha