diff --git a/Dockerfile.jindoruntime b/Dockerfile.jindoruntime
new file mode 100644
index 00000000000..609c650d60a
--- /dev/null
+++ b/Dockerfile.jindoruntime
@@ -0,0 +1,31 @@
+# Build the jindoruntime-controller manager binary
+FROM golang:1.14.2 as builder
+
+WORKDIR /go/src/github.com/fluid-cloudnative/fluid
+COPY . .
+
+RUN make jindoruntime-controller-build && \
+ cp bin/jindoruntime-controller /go/bin/jindoruntime-controller
+
+FROM alpine:3.10
+RUN apk add --update curl tzdata iproute2 bash libc6-compat vim && \
+ rm -rf /var/cache/apk/* && \
+ cp /usr/share/zoneinfo/Asia/Shanghai /etc/localtime && \
+ echo "Asia/Shanghai" > /etc/timezone
+
+RUN curl -o helm-v3.0.3-linux-amd64.tar.gz http://aliacs-k8s-cn-hangzhou.oss-cn-hangzhou.aliyuncs.com/public/pkg/helm/helm-v3.0.3-linux-amd64.tar.gz && \
+ tar -xvf helm-v3.0.3-linux-amd64.tar.gz && \
+ mv linux-amd64/helm /usr/local/bin/ddc-helm && \
+ chmod u+x /usr/local/bin/ddc-helm && \
+ rm -f helm-v3.0.3-linux-amd64.tar.gz
+
+ENV K8S_VERSION v1.14.8
+RUN curl -o /usr/local/bin/kubectl https://storage.googleapis.com/kubernetes-release/release/${K8S_VERSION}/bin/linux/amd64/kubectl && chmod +x /usr/local/bin/kubectl
+
+add charts/jindofs /charts/jindo
+
+COPY --from=builder /go/bin/jindoruntime-controller /usr/local/bin/jindoruntime-controller
+RUN chmod -R u+x /usr/local/bin/
+
+CMD ["jindoruntime-controller", "start"]
+
diff --git a/Makefile b/Makefile
index f9461cba85b..bf08a0a3e4c 100644
--- a/Makefile
+++ b/Makefile
@@ -7,6 +7,7 @@ CRD_OPTIONS ?= "crd:trivialVersions=true"
# The Image URL to use in docker build and push
DATASET_CONTROLLER_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/dataset-controller
ALLUXIORUNTIME_CONTROLLER_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/alluxioruntime-controller
+JINDORUNTIME_CONTROLLER_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/jindoruntime-controller
CSI_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/fluid-csi
LOADER_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/fluid-dataloader
INIT_USERS_IMG ?= registry.cn-hangzhou.aliyuncs.com/fluid/init-users
@@ -59,6 +60,9 @@ dataset-controller-build: generate fmt vet
alluxioruntime-controller-build: generate fmt vet
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=off go build -gcflags="-N -l" -a -o bin/alluxioruntime-controller -ldflags '${LDFLAGS}' cmd/alluxio/main.go
+jindoruntime-controller-build: generate fmt vet
+ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=off go build -gcflags="-N -l" -a -o bin/jindoruntime-controller -ldflags '${LDFLAGS}' cmd/jindo/main.go
+
# Debug against the configured Kubernetes cluster in ~/.kube/config, add debug
debug: generate fmt vet manifests
CGO_ENABLED=0 GOOS=linux GOARCH=amd64 GO111MODULE=off dlv debug --headless --listen ":12345" --log --api-version=2 cmd/controller/main.go
@@ -103,6 +107,9 @@ docker-build-dataset-controller: generate fmt vet
docker-build-alluxioruntime-controller: generate fmt vet
docker build --no-cache . -f Dockerfile.alluxioruntime -t ${ALLUXIORUNTIME_CONTROLLER_IMG}:${GIT_VERSION}
+docker-build-jindoruntime-controller: generate fmt vet
+ docker build --no-cache . -f Dockerfile.jindoruntime -t ${JINDORUNTIME_CONTROLLER_IMG}:${GIT_VERSION}
+
docker-build-csi: generate fmt vet
docker build --no-cache . -f Dockerfile.csi -t ${CSI_IMG}:${GIT_VERSION}
diff --git a/PROJECT b/PROJECT
index 60034c3e553..78350a17e43 100644
--- a/PROJECT
+++ b/PROJECT
@@ -10,4 +10,7 @@ resources:
- group: data
kind: DataLoad
version: v1alpha1
+- group: data
+ kind: JindoRuntime
+ version: v1alpha1
version: "2"
diff --git a/api/v1alpha1/jindoruntime_types.go b/api/v1alpha1/jindoruntime_types.go
new file mode 100644
index 00000000000..cef7ac7f55f
--- /dev/null
+++ b/api/v1alpha1/jindoruntime_types.go
@@ -0,0 +1,257 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha1
+
+import (
+ "github.com/fluid-cloudnative/fluid/pkg/common"
+ corev1 "k8s.io/api/core/v1"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+// VersionSpec represents the settings for the Jindo version that fluid is orchestrating.
+type JindoVersionSpec struct {
+ // Image for Jindo(e.g. jindo/jindo)
+ Image string `json:"image,omitempty"`
+
+ // Image tag for Jindo(e.g. 2.3.0-SNAPSHOT)
+ ImageTag string `json:"imageTag,omitempty"`
+
+ // One of the three policies: `Always`, `IfNotPresent`, `Never`
+ ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
+}
+
+// AlluxioCompTemplateSpec is a description of the Alluxio commponents
+type JindoCompTemplateSpec struct {
+ // Replicas is the desired number of replicas of the given template.
+ // If unspecified, defaults to 1.
+ // +kubebuilder:validation:Minimum=1
+ // replicas is the min replicas of dataset in the cluster
+ // +optional
+ Replicas int32 `json:"replicas,omitempty"`
+
+ // Options for JVM
+ JvmOptions []string `json:"jvmOptions,omitempty"`
+
+ // Configurable properties for the Alluxio component.
+ // Refer to Alluxio Configuration Properties for more info
+ // +optional
+ Properties map[string]string `json:"properties,omitempty"`
+
+ // Ports used by Alluxio(e.g. rpc: 19998 for master)
+ // +optional
+ Ports map[string]int `json:"ports,omitempty"`
+
+ // Resources that will be requested by the Alluxio component.
+ //
+ // Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources
+ // already allocated to the pod.
+ // +optional
+ Resources corev1.ResourceRequirements `json:"resources,omitempty"`
+
+ // Environment variables that will be used by Alluxio component.
+ Env map[string]string `json:"env,omitempty"`
+}
+
+// AlluxioFuseSpec is a description of the Alluxio Fuse
+type JindoFuseSpec struct {
+
+ // Image for Alluxio Fuse(e.g. alluxio/alluxio-fuse)
+ Image string `json:"image,omitempty"`
+
+ // Image Tag for Alluxio Fuse(e.g. 2.3.0-SNAPSHOT)
+ ImageTag string `json:"imageTag,omitempty"`
+
+ // One of the three policies: `Always`, `IfNotPresent`, `Never`
+ ImagePullPolicy string `json:"imagePullPolicy,omitempty"`
+
+ // Options for JVM
+ JvmOptions []string `json:"jvmOptions,omitempty"`
+
+ // Configurable properties for Alluxio System.
+ // Refer to Alluxio Configuration Properties for more info
+ Properties map[string]string `json:"properties,omitempty"`
+
+ // Environment variables that will be used by Alluxio Fuse
+ Env map[string]string `json:"env,omitempty"`
+
+ // ShortCircuitPolicy string `json:"shortCircuitPolicy,omitempty"`
+
+ // Resources that will be requested by Alluxio Fuse.
+ //
+ // Resources are not allowed for ephemeral containers. Ephemeral containers use spare resources
+ // already allocated to the pod.
+ // +optional
+ Resources corev1.ResourceRequirements `json:"resources,omitempty"`
+
+ // Arguments that will be passed to Alluxio Fuse
+ Args []string `json:"args,omitempty"`
+}
+
+// JindoRuntimeSpec defines the desired state of JindoRuntime
+type JindoRuntimeSpec struct {
+ // The version information that instructs fluid to orchestrate a particular version of Alluxio.
+ JindoVersion JindoVersionSpec `json:"jindoVersion,omitempty"`
+
+ // Desired state for Alluxio master
+ Master JindoCompTemplateSpec `json:"master,omitempty"`
+
+ // Desired state for Alluxio job master
+ JobMaster JindoCompTemplateSpec `json:"jobMaster,omitempty"`
+
+ // Desired state for Alluxio worker
+ Worker JindoCompTemplateSpec `json:"worker,omitempty"`
+
+ // Desired state for Alluxio job Worker
+ JobWorker JindoCompTemplateSpec `json:"jobWorker,omitempty"`
+
+ // The spec of init users
+ InitUsers InitUsersSpec `json:"initUsers,omitempty"`
+
+ // Desired state for Alluxio Fuse
+ Fuse JindoFuseSpec `json:"fuse,omitempty"`
+
+ // Configurable properties for Alluxio system.
+ // Refer to Alluxio Configuration Properties for more info
+ Properties map[string]string `json:"properties,omitempty"`
+
+ // Options for JVM
+ JvmOptions []string `json:"jvmOptions,omitempty"`
+
+ // Tiered storage used by Alluxio
+ Tieredstore Tieredstore `json:"tieredstore,omitempty"`
+
+ // The replicas of the worker, need to be specified
+ Replicas int32 `json:"replicas,omitempty"`
+
+ // Manage the user to run Alluxio Runtime
+ RunAs *User `json:"runAs,omitempty"`
+}
+
+// JindoRuntimeStatus defines the observed state of JindoRuntime
+type JindoRuntimeStatus struct {
+ // config map used to set configurations
+ ValueFileConfigmap string `json:"valueFile"`
+
+ // MasterPhase is the master running phase
+ MasterPhase RuntimePhase `json:"masterPhase"`
+
+ // Reason for Jindo Master's condition transition
+ MasterReason string `json:"masterReason,omitempty"`
+
+ // WorkerPhase is the worker running phase
+ WorkerPhase RuntimePhase `json:"workerPhase"`
+
+ // Reason for Jindo Worker's condition transition
+ WorkerReason string `json:"workerReason,omitempty"`
+
+ // The total number of nodes that should be running the runtime worker
+ // pod (including nodes correctly running the runtime worker pod).
+ DesiredWorkerNumberScheduled int32 `json:"desiredWorkerNumberScheduled"`
+
+ // The total number of nodes that can be running the runtime worker
+ // pod (including nodes correctly running the runtime worker pod).
+ CurrentWorkerNumberScheduled int32 `json:"currentWorkerNumberScheduled"`
+
+ // The number of nodes that should be running the runtime worker pod and have one
+ // or more of the runtime worker pod running and ready.
+ WorkerNumberReady int32 `json:"workerNumberReady"`
+
+ // The number of nodes that should be running the
+ // runtime worker pod and have one or more of the runtime worker pod running and
+ // available (ready for at least spec.minReadySeconds)
+ // +optional
+ WorkerNumberAvailable int32 `json:"workerNumberAvailable,omitempty"`
+
+ // The number of nodes that should be running the
+ // runtime worker pod and have none of the runtime worker pod running and available
+ // (ready for at least spec.minReadySeconds)
+ // +optional
+ WorkerNumberUnavailable int32 `json:"workerNumberUnavailable,omitempty"`
+
+ // The total number of nodes that should be running the runtime
+ // pod (including nodes correctly running the runtime master pod).
+ DesiredMasterNumberScheduled int32 `json:"desiredMasterNumberScheduled"`
+
+ // The total number of nodes that should be running the runtime
+ // pod (including nodes correctly running the runtime master pod).
+ CurrentMasterNumberScheduled int32 `json:"currentMasterNumberScheduled"`
+
+ // The number of nodes that should be running the runtime worker pod and have zero
+ // or more of the runtime master pod running and ready.
+ MasterNumberReady int32 `json:"masterNumberReady"`
+
+ // FusePhase is the Fuse running phase
+ FusePhase RuntimePhase `json:"fusePhase"`
+
+ // Reason for the condition's last transition.
+ FuseReason string `json:"fuseReason,omitempty"`
+
+ // The total number of nodes that can be running the runtime Fuse
+ // pod (including nodes correctly running the runtime Fuse pod).
+ CurrentFuseNumberScheduled int32 `json:"currentFuseNumberScheduled"`
+
+ // The total number of nodes that should be running the runtime Fuse
+ // pod (including nodes correctly running the runtime Fuse pod).
+ DesiredFuseNumberScheduled int32 `json:"desiredFuseNumberScheduled"`
+
+ // The number of nodes that should be running the runtime Fuse pod and have one
+ // or more of the runtime Fuse pod running and ready.
+ FuseNumberReady int32 `json:"fuseNumberReady"`
+
+ // The number of nodes that should be running the
+ // runtime fuse pod and have none of the runtime fuse pod running and available
+ // (ready for at least spec.minReadySeconds)
+ // +optional
+ FuseNumberUnavailable int32 `json:"fuseNumberUnavailable,omitempty"`
+
+ // The number of nodes that should be running the
+ // runtime Fuse pod and have one or more of the runtime Fuse pod running and
+ // available (ready for at least spec.minReadySeconds)
+ // +optional
+ FuseNumberAvailable int32 `json:"fuseNumberAvailable,omitempty"`
+
+ // Represents the latest available observations of a ddc runtime's current state.
+ // +patchMergeKey=type
+ // +patchStrategy=merge
+ Conditions []RuntimeCondition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"`
+
+ // CacheStatus represents the total resources of the dataset.
+ CacheStates common.CacheStateList `json:"cacheStates,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// JindoRuntime is the Schema for the jindoruntimes API
+type JindoRuntime struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ObjectMeta `json:"metadata,omitempty"`
+
+ Spec JindoRuntimeSpec `json:"spec,omitempty"`
+ Status JindoRuntimeStatus `json:"status,omitempty"`
+}
+
+// +kubebuilder:object:root=true
+
+// JindoRuntimeList contains a list of JindoRuntime
+type JindoRuntimeList struct {
+ metav1.TypeMeta `json:",inline"`
+ metav1.ListMeta `json:"metadata,omitempty"`
+ Items []JindoRuntime `json:"items"`
+}
+
+func init() {
+ SchemeBuilder.Register(&JindoRuntime{}, &JindoRuntimeList{})
+}
diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go
index 7e3ad3a96fc..402a7d65dd0 100644
--- a/api/v1alpha1/zz_generated.deepcopy.go
+++ b/api/v1alpha1/zz_generated.deepcopy.go
@@ -595,6 +595,231 @@ func (in *InitUsersSpec) DeepCopy() *InitUsersSpec {
return out
}
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoCompTemplateSpec) DeepCopyInto(out *JindoCompTemplateSpec) {
+ *out = *in
+ if in.JvmOptions != nil {
+ in, out := &in.JvmOptions, &out.JvmOptions
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Properties != nil {
+ in, out := &in.Properties, &out.Properties
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.Ports != nil {
+ in, out := &in.Ports, &out.Ports
+ *out = make(map[string]int, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ in.Resources.DeepCopyInto(&out.Resources)
+ if in.Env != nil {
+ in, out := &in.Env, &out.Env
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoCompTemplateSpec.
+func (in *JindoCompTemplateSpec) DeepCopy() *JindoCompTemplateSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoCompTemplateSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoFuseSpec) DeepCopyInto(out *JindoFuseSpec) {
+ *out = *in
+ if in.JvmOptions != nil {
+ in, out := &in.JvmOptions, &out.JvmOptions
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ if in.Properties != nil {
+ in, out := &in.Properties, &out.Properties
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.Env != nil {
+ in, out := &in.Env, &out.Env
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ in.Resources.DeepCopyInto(&out.Resources)
+ if in.Args != nil {
+ in, out := &in.Args, &out.Args
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoFuseSpec.
+func (in *JindoFuseSpec) DeepCopy() *JindoFuseSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoFuseSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoRuntime) DeepCopyInto(out *JindoRuntime) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
+ in.Spec.DeepCopyInto(&out.Spec)
+ in.Status.DeepCopyInto(&out.Status)
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoRuntime.
+func (in *JindoRuntime) DeepCopy() *JindoRuntime {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoRuntime)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *JindoRuntime) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoRuntimeList) DeepCopyInto(out *JindoRuntimeList) {
+ *out = *in
+ out.TypeMeta = in.TypeMeta
+ in.ListMeta.DeepCopyInto(&out.ListMeta)
+ if in.Items != nil {
+ in, out := &in.Items, &out.Items
+ *out = make([]JindoRuntime, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoRuntimeList.
+func (in *JindoRuntimeList) DeepCopy() *JindoRuntimeList {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoRuntimeList)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
+func (in *JindoRuntimeList) DeepCopyObject() runtime.Object {
+ if c := in.DeepCopy(); c != nil {
+ return c
+ }
+ return nil
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoRuntimeSpec) DeepCopyInto(out *JindoRuntimeSpec) {
+ *out = *in
+ out.JindoVersion = in.JindoVersion
+ in.Master.DeepCopyInto(&out.Master)
+ in.JobMaster.DeepCopyInto(&out.JobMaster)
+ in.Worker.DeepCopyInto(&out.Worker)
+ in.JobWorker.DeepCopyInto(&out.JobWorker)
+ in.InitUsers.DeepCopyInto(&out.InitUsers)
+ in.Fuse.DeepCopyInto(&out.Fuse)
+ if in.Properties != nil {
+ in, out := &in.Properties, &out.Properties
+ *out = make(map[string]string, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+ if in.JvmOptions != nil {
+ in, out := &in.JvmOptions, &out.JvmOptions
+ *out = make([]string, len(*in))
+ copy(*out, *in)
+ }
+ in.Tieredstore.DeepCopyInto(&out.Tieredstore)
+ if in.RunAs != nil {
+ in, out := &in.RunAs, &out.RunAs
+ *out = new(User)
+ (*in).DeepCopyInto(*out)
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoRuntimeSpec.
+func (in *JindoRuntimeSpec) DeepCopy() *JindoRuntimeSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoRuntimeSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoRuntimeStatus) DeepCopyInto(out *JindoRuntimeStatus) {
+ *out = *in
+ if in.Conditions != nil {
+ in, out := &in.Conditions, &out.Conditions
+ *out = make([]RuntimeCondition, len(*in))
+ for i := range *in {
+ (*in)[i].DeepCopyInto(&(*out)[i])
+ }
+ }
+ if in.CacheStates != nil {
+ in, out := &in.CacheStates, &out.CacheStates
+ *out = make(common.CacheStateList, len(*in))
+ for key, val := range *in {
+ (*out)[key] = val
+ }
+ }
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoRuntimeStatus.
+func (in *JindoRuntimeStatus) DeepCopy() *JindoRuntimeStatus {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoRuntimeStatus)
+ in.DeepCopyInto(out)
+ return out
+}
+
+// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
+func (in *JindoVersionSpec) DeepCopyInto(out *JindoVersionSpec) {
+ *out = *in
+}
+
+// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new JindoVersionSpec.
+func (in *JindoVersionSpec) DeepCopy() *JindoVersionSpec {
+ if in == nil {
+ return nil
+ }
+ out := new(JindoVersionSpec)
+ in.DeepCopyInto(out)
+ return out
+}
+
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
func (in *Level) DeepCopyInto(out *Level) {
*out = *in
diff --git a/charts/fluid/fluid/templates/controller/alluxioruntime_controller.yaml b/charts/fluid/fluid/templates/controller/alluxioruntime_controller.yaml
index e3619ff08b3..fdee7672923 100644
--- a/charts/fluid/fluid/templates/controller/alluxioruntime_controller.yaml
+++ b/charts/fluid/fluid/templates/controller/alluxioruntime_controller.yaml
@@ -40,9 +40,9 @@ spec:
- name: ALLUXIO_FUSE_IMAGE_ENV
value: {{ .Values.runtime.alluxio.fuse.image | quote }}
{{- end }}
- {{- if .Values.runtime.mountRoot }}
+ {{- if .Values.runtime.alluxio.mountRoot }}
- name: MOUNT_ROOT
- value: {{ .Values.runtime.mountRoot | quote }}
+ value: {{ .Values.runtime.alluxio.mountRoot | quote }}
{{- end }}
ports:
- containerPort: 8080
diff --git a/charts/fluid/fluid/templates/controller/jindoruntime_controller.yaml b/charts/fluid/fluid/templates/controller/jindoruntime_controller.yaml
new file mode 100644
index 00000000000..3e1d236292d
--- /dev/null
+++ b/charts/fluid/fluid/templates/controller/jindoruntime_controller.yaml
@@ -0,0 +1,40 @@
+
+---
+apiVersion: apps/v1
+kind: Deployment
+metadata:
+ name: jindoruntime-controller
+ namespace: fluid-system
+ labels:
+ control-plane: jindoruntime-controller
+spec:
+ selector:
+ matchLabels:
+ control-plane: jindoruntime-controller
+ replicas: 1
+ template:
+ metadata:
+ labels:
+ control-plane: jindoruntime-controller
+ spec:
+ serviceAccountName: jindoruntime-controller
+ tolerations:
+ - operator: Exists
+ containers:
+ - image: registry.cn-hangzhou.aliyuncs.com/qiulingwei/jindoruntime-controller:v1
+ name: manager
+ command: ["jindoruntime-controller", "start"]
+ args:
+ - --development=false
+ ports:
+ - containerPort: 8080
+ name: metrics
+ protocol: TCP
+ resources:
+ limits:
+ cpu: 100m
+ memory: 300Mi
+ requests:
+ cpu: 100m
+ memory: 200Mi
+ terminationGracePeriodSeconds: 10
\ No newline at end of file
diff --git a/charts/fluid/fluid/templates/csi/daemonset.yaml b/charts/fluid/fluid/templates/csi/daemonset.yaml
index 3e34d933d5f..527f9b69fd2 100644
--- a/charts/fluid/fluid/templates/csi/daemonset.yaml
+++ b/charts/fluid/fluid/templates/csi/daemonset.yaml
@@ -68,8 +68,13 @@ spec:
mountPath: /var/lib/kubelet/
mountPropagation: "Bidirectional"
- name: fluid-src-dir
- mountPath: {{ .Values.runtime.mountRoot | quote }}
+ mountPath: {{ .Values.runtime.alluxio.mountRoot | quote }}
mountPropagation: "Bidirectional"
+ {{- if .Values.runtime.jindo.mountRoot }}
+ - name: jindo-src-dir
+ mountPath: { { .Values.runtime.jindo.mountRoot | quote } }
+ mountPropagation: "Bidirectional"
+ {{- end }}
volumes:
- name: kubelet-dir
hostPath:
@@ -84,6 +89,12 @@ spec:
type: DirectoryOrCreate
name: registration-dir
- hostPath:
- path: {{ .Values.runtime.mountRoot | quote }}
+ path: {{ .Values.runtime.alluxio.mountRoot | quote }}
type: DirectoryOrCreate
name: fluid-src-dir
+ {{- if .Values.runtime.jindo.mountRoot }}
+ - hostPath:
+ path: {{ .Values.runtime.jindo.mountRoot | quote }}
+ type: DirectoryOrCreate
+ name: jindo-src-dir
+ {{- end }}
\ No newline at end of file
diff --git a/charts/fluid/fluid/templates/role/jindo/rabc.yaml b/charts/fluid/fluid/templates/role/jindo/rabc.yaml
new file mode 100644
index 00000000000..9a31a153082
--- /dev/null
+++ b/charts/fluid/fluid/templates/role/jindo/rabc.yaml
@@ -0,0 +1,59 @@
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: jindoruntime-controller
+rules:
+ - apiGroups:
+ - ""
+ resources:
+ - persistentvolumeclaims
+ - persistentvolumes
+ - services
+ - endpoints
+ - configmaps
+ - events
+ - namespaces
+ - pods
+ - pods/exec
+ - secrets
+ - nodes
+ verbs:
+ - '*'
+ - apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes
+ - datasets
+ - jindoruntimes/status
+ - datasets/status
+ verbs:
+ - '*'
+ - apiGroups:
+ - apps
+ resources:
+ - daemonsets
+ - statefulsets
+ - daemonsets/status
+ - statefulsets/status
+ verbs:
+ - '*'
+---
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRoleBinding
+metadata:
+ name: jindoruntime-clusterrolebinding
+roleRef:
+ apiGroup: rbac.authorization.k8s.io
+ kind: ClusterRole
+ name: jindoruntime-controller
+subjects:
+ - kind: ServiceAccount
+ name: jindoruntime-controller
+ namespace: fluid-system
+---
+apiVersion: v1
+kind: ServiceAccount
+metadata:
+ name: jindoruntime-controller
+ namespace: fluid-system
\ No newline at end of file
diff --git a/charts/fluid/fluid/values.yaml b/charts/fluid/fluid/values.yaml
index e56fe992d78..19051a0be24 100644
--- a/charts/fluid/fluid/values.yaml
+++ b/charts/fluid/fluid/values.yaml
@@ -13,8 +13,8 @@ csi:
image: registry.cn-hangzhou.aliyuncs.com/fluid/fluid-csi:v0.5.0-ae4a7be
runtime:
- mountRoot: /alluxio-mnt
alluxio:
+ mountRoot: /alluxio-mnt
init:
image: registry.cn-hangzhou.aliyuncs.com/fluid/init-users:v0.5.0-ae4a7be
controller:
@@ -25,3 +25,5 @@ runtime:
image: registry.cn-huhehaote.aliyuncs.com/alluxio/alluxio-fuse:2.3.0-SNAPSHOT-2c41226
dataload:
image: registry.cn-huhehaote.aliyuncs.com/alluxio/alluxio:2.3.0-SNAPSHOT-2c41226
+ jindo:
+ mountRoot: /mnt/jfs
\ No newline at end of file
diff --git a/charts/jindofs/.helmignore b/charts/jindofs/.helmignore
new file mode 100755
index 00000000000..f0c13194444
--- /dev/null
+++ b/charts/jindofs/.helmignore
@@ -0,0 +1,21 @@
+# 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
diff --git a/charts/jindofs/Chart.yaml b/charts/jindofs/Chart.yaml
new file mode 100755
index 00000000000..dca5f1367cf
--- /dev/null
+++ b/charts/jindofs/Chart.yaml
@@ -0,0 +1,17 @@
+apiVersion: v1
+appVersion: 2.7.4
+description: FileSystem on the cloud based on Aliyun Object Storage aimed for data
+ acceleration.
+home: https://help.aliyun.com/document_detail/164207.html
+keywords:
+- jindofs
+- namespace:jindofs
+- releaseName:jindofs
+- category:data
+maintainers:
+- email: kunhui.skh@alibaba-inc.com
+ name: kunhui.skh
+- email: cheyang@163.com
+ name: Yang Che
+name: jindofs
+version: 2.7.4
diff --git a/charts/jindofs/README.md b/charts/jindofs/README.md
new file mode 100755
index 00000000000..3ed10e46980
--- /dev/null
+++ b/charts/jindofs/README.md
@@ -0,0 +1,558 @@
+# 使用 Kubernetes 部署 JindoFS
+
+
+
+
+# 一、快速安装
+
+## 1、创建kubernetes集群
+
+
+![image.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-001.png)
+
+#### 集群配置
+
+- 实例规格要求内存不小于16GB。
+- JindoFS使用集群内的数据盘存储缓存数据。生产环境上,建议挂载一个以上容量较大的数据盘。本文中,我们直接使用默认配置,使用单个系统盘(仅限开发测试使用)。
+
+![image.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-002.png)
+
+- 绑定弹性公网IP,或者用户有其它跳板机,可以ssh登录到集群中的其中一个节点。
+
+
+
+## 2、安装JindoFS服务
+
+### 2.1 前往容器服务->应用目录,进入“JindoFS”安装配置页面。
+![image.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-003.png)
+
+### 2.2 配置参数
+完整的配置模板如下:
这里举例的镜像资源是cn-shanghai区的地址,版本号为2.7.4。**请使用安装配置页面展示的默认的image地址和tag版本。**
+
+```yaml
+image: registry.cn-shanghai.aliyuncs.com/jindofs/smartdata
+imageTag: "2.7.4"
+imagePullPolicy: Always
+fuseImage: registry.cn-shanghai.aliyuncs.com/jindofs/jindo-fuse
+fuseImageTag: "2.7.4"
+user: 0
+group: 0
+fsGroup: 0
+useHostNetwork: true
+useHostPID: true
+properties:
+ logDir: /mnt/disk1/bigboot/log
+master:
+ replicaCount: 1
+ resources:
+ limits:
+ cpu: "4"
+ memory: "16G" # increase memory corresponding to filelet(blocklet) cache size
+ requests:
+ cpu: "1"
+ memory: "1G"
+ nodeSelector: {}
+ properties:
+ namespace.rpc.port: 8101
+ namespace.meta-dir: /mnt/disk1/bigboot/server
+ namespace.filelet.cache.size: 100000
+ namespace.blocklet.cache.size: 1000000
+ namespace.backend.type: rocksdb
+ jfs.namespaces: test
+ jfs.namespaces.test.mode : cache
+ jfs.namespaces.test.oss.uri : oss://chengli-sh-test.oss-cn-shanghai-internal.aliyuncs.com/fuyue/k8s_c1
+ jfs.namespaces.test.oss.access.key : xx
+ jfs.namespaces.test.oss.access.secret : xx
+worker:
+ resources:
+ limits:
+ cpu: "4"
+ memory: "8G" # increase memory corresponding to the number of concurrent reading/writing files
+ requests:
+ cpu: "1"
+ memory: "1G"
+ nodeSelector: {}
+ properties:
+ storage.rpc.port: 6101
+ storage.data-dirs: /mnt/disk1/bigboot, /mnt/disk2/bigboot, /mnt/disk3/bigboot
+ storage.temp-data-dirs: /mnt/disk1/bigboot/tmp
+ storage.watermark.high.ratio: 0.4
+ storage.watermark.low.ratio: 0.2
+ storage.data-dirs.capacities: 80g,80g,80g
+ storage.meta-dir: /mnt/disk1/bigboot/bignode
+fuse:
+ args:
+ hostPath: /mnt/jfs
+ properties:
+ client.storage.rpc.port: 6101
+ client.oss.retry: 5
+ client.oss.upload.threads: 4
+ client.oss.upload.queue.size: 5
+ client.oss.upload.max.parallelism: 16
+ client.oss.timeout.millisecond: 30000
+ client.oss.connection.timeout.millisecond: 3000
+mounts:
+ master:
+ # 1: /mnt/disk1
+ workersAndClients:
+ # 1: /mnt/disk1
+ # 2: /mnt/disk2
+ # 3: /mnt/disk3
+```
+
+
+- 配置OSS Bucket和AK,参考文档使用[JFS Scheme](https://help.aliyun.com/document_detail/164209.html#title-s6x-h1p-cg4)的部署方式。我们需要修改以下配置项:
+
+```yaml
+ jfs.namespaces: test
+ jfs.namespaces.test.mode : cache
+ jfs.namespaces.test.oss.uri : oss://chengli-sh-test.oss-cn-shanghai-internal.aliyuncs.com/fuyue/k8s_c1
+ jfs.namespaces.test.oss.access.key : xx
+ jfs.namespaces.test.oss.access.secret : xx
+```
+
+通过这些配置项,我们创建了一个名为test的命名空间,指向了chengli-sh-test这个OSS bucket的fuyue/k8s_c1目录。后续我们通过JindoFS操作test命名空间的时候,就等同于操作该OSS目录。
+
+- 其余配置保持默认值。
+
+本文中,我们直接使用默认值进行演示。
生产环境上,建议参考章节“配置数据目录”,持久化缓存数据。
更多配置(如磁盘水位、性能相关)请参考文档[JindoFS使用说明](https://help.aliyun.com/document_detail/164209.html)。
+
+
+### 3.3 安装服务
+![image.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-004.png)
+
+
+## 3. 验证安装成功
+
+```
+# kubectl get pods
+NAME READY STATUS RESTARTS AGE
+jindofs-fuse-267vq 1/1 Running 0 143m
+jindofs-fuse-8qwdv 1/1 Running 0 143m
+jindofs-fuse-v6q7r 1/1 Running 0 143m
+jindofs-master-0 1/1 Running 0 143m
+jindofs-worker-mncqd 1/1 Running 0 143m
+jindofs-worker-pk7j4 1/1 Running 0 143m
+jindofs-worker-r2k99 1/1 Running 0 143m
+```
+
+在宿主机上访问/mnt/jfs/目录,即等同于访问JindoFS的文件
+
+```bash
+# ls /mnt/jfs/test/
+15885689452274647042-0 17820745254765068290-0 entrypoint.sh
+```
+
+
+# 二、体验JindoFS加速服务
+通过上一章节的操作,我们成功启动了JindoFS集群。这一章节,我们将用各种方式来访问JindoFS集群,并体验JindoFS带来的加速效果。
JindoFS提供了Hadoop FileSystem接口、FUSE两种客户端来访问JindoFS集群,在容器环境下,同样支持这两种方式。
+
+
+## 方式1:在宿主机访问JindoFS集群(FUSE方式)
+通过ssh登录到集群的一个节点,在Console内直接访问JindoFS集群
ls 目录
+
+```bash
+# ls /mnt/jfs/test/
+15885689452274647042-0 17820745254765068290-0 entrypoint.sh derby.log
+```
+
+读取文件
+
+```bash
+[hadoop@emr-header-1 ~]$ cat /mnt/jfs/test/derby.log
+Thu Mar 05 23:25:53 CST 2020:
+Booting Derby version The Apache Software Foundation - Apache Derby - 10.12.1.1 - (1704137)
+```
+
+
+
+## 方式2:在pod内访问JindoFS集群(FUSE方式)
+为了演示,我们创建一个临时的pod(您也可以创建Deployment),然后将fuse目录挂载到pod内。首先,创建文件 jindofs-demo-app.yaml
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: jindofs-demo-app
+ labels:
+ app: jindofs-demo-app
+spec:
+ containers:
+ - name: jindofs-demo-app
+ image: alpine:3.7
+ command: ["tail"]
+ args: ["-f", "/dev/null"]
+ volumeMounts:
+ - name: jindofs-fuse-mount
+ mountPath: /jfs
+ volumes:
+ - name: jindofs-fuse-mount
+ hostPath:
+ path: /mnt/jfs
+ type: DirectoryOrCreate
+```
+
+执行命令
+
+```bash
+kubectl apply -f jindofs-demo-app.yaml
+```
+
+进入pod内的shell终端
+
+```bash
+kubectl exec -it jindofs-demo-app sh
+```
+
+在pod内读写JindoFS文件
+
+```bash
+/ # ls /jfs/test/
+15885689452274647042-0 17820745254765068290-0 LICENSE.txt bigboot.cfg entrypoint.sh fuse.cfg
+/ # echo hello world > /jfs/test/my_first_file
+/ # cat /jfs/test/my_first_file
+hello world
+```
+
+这种方式适合于容器内跑机器学习计算。只需要将训练数据预先放到oss bucket上,然后在容器内读取/jfs目录下的文件即可。
+
+
+## 方式3:在pod内访问JindoFS集群(FileSystem接口)
+这种方式,我们需要准备一个带有JindoFS SDK包的Hadoop Client、MapReduce、Hive或Spark镜像。请参考章节《制作带有JindoFS SDK的镜像》。
为了演示,我们直接使用jindo-fuse镜像(里面包含了Hadoop Client和JindoFS SDK)。
首先,我们创建一个临时的pod(您也可以创建Deployment),先创建文件 jindofs-demo-app2.yaml
+
+```yaml
+apiVersion: v1
+kind: Pod
+metadata:
+ name: jindofs-demo-app2
+ labels:
+ app: jindofs-demo-app2
+spec:
+ hostNetwork: true
+ dnsPolicy: ClusterFirstWithHostNet
+ containers:
+ - name: jindofs-demo-app2
+ image: "registry.cn-shanghai.aliyuncs.com/jindofs/jindo-fuse:2.7.4"
+ command: ["tail"]
+ args: ["-f", "/dev/null"]
+ env:
+ - name: CLIENT_NAMESPACE_RPC_ADDRESS
+ value: jindofs-master:8101
+ - name: CLIENT_STORAGE_RPC_PORT
+ value: "6101"
+ - name: CLIENT_STORAGE_RPC_HOST
+ valueFrom:
+ fieldRef:
+ fieldPath: status.hostIP
+ - name: JFS_CACHE_DATA_CACHE_ENABLE
+ value: "1"
+ volumeMounts:
+ - mountPath: /etc/localtime
+ name: volume-localtime
+ - name: datavolume-1
+ mountPath: "/mnt/disk1"
+ - name: datavolume-2
+ mountPath: "/mnt/disk2"
+ - name: datavolume-3
+ mountPath: "/mnt/disk3"
+ volumes:
+ - hostPath:
+ path: /etc/localtime
+ type: ''
+ name: volume-localtime
+ - hostPath:
+ path: "/mnt/disk1"
+ type: DirectoryOrCreate
+ name: datavolume-1
+ - hostPath:
+ path: "/mnt/disk2"
+ type: DirectoryOrCreate
+ name: datavolume-2
+ - hostPath:
+ path: "/mnt/disk3"
+ type: DirectoryOrCreate
+ name: datavolume-3
+
+```
+
+执行命令
+
+```bash
+kubectl apply -f jindofs-demo-app2.yaml
+```
+
+进入pod内的shell终端
+
+```bash
+kubectl exec -it jindofs-demo-app2 bash
+```
+
+在pod内读写JindoFS文件
+
+```bash
+root@iZuf6:/# hadoop fs -ls jfs://test/
+Found 7 items
+-rw-rw-rw- 1 3807 2020-06-18 12:31 jfs://test/15885689452274647042-0
+-rw-rw-rw- 1 79 2020-06-28 15:46 jfs://test/17820745254765068290-0
+-rw-rw-rw- 1 150569 2020-07-02 12:01 jfs://test/LICENSE.txt
+-rw-rw-rw- 1 306 2020-07-02 11:58 jfs://test/bigboot.cfg
+-rw-rw-rw- 1 79 2020-06-29 03:32 jfs://test/entrypoint.sh
+-rw-rw-rw- 1 360 2020-07-07 11:31 jfs://test/fuse.cfg
+-rw-rw-rw- 1 12 2020-07-16 03:16 jfs://test/my_first_file
+
+# 您还可以尝试使用hadoop fs -put和-get读写文件
+```
+
+这种方式适合于容器内跑MapReduce、Hive或Spark等大数据计算任务。
+
+## 方式4:在宿主机或其它机器访问JindoFS集群(FileSystem接口)
+将下面环境变量添加到/etc/profile文件中
export B2SDK_CONF_DIR=/root/b2sdk/conf
创建文件 /root/b2sdk/conf/bigboot.cfg 包含以下主要内容
+
+```
+[bigboot]
+logger.dir = /tmp/bigboot-log
+
+[bigboot-client]
+client.storage.rpc.port=6101
+client.namespace.rpc.address=192.168.0.xxx:8101
+client.oss.retry=5
+client.oss.upload.threads=4
+client.oss.upload.queue.size=5
+client.oss.upload.max.parallelism=16
+client.read.blocklet.prefetch.count=16
+client.oss.timeout.millisecond=30000
+client.oss.connection.timeout.millisecond=3000
+client.read.cache-on-read.enable=1
+```
+
+主要修改client.namespace.rpc.address为master服务所在节点的ip
+
下载b2sdk包进行解压
+
+```
+wget https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/b2sdk-2.7.4.tar.gz
+tar -zxvf b2sdk-2.7.4.tar.gz
+```
+
+将JindoFS SDK的jar包复制到spark目录下
+
+```
+cp sdk/lib/jindofs-sdk-*.jar /usr/lib/spark-current/jars/
+```
+
+将JindoFS SDK的jar包复制到hive目录下
+
+```
+cp sdk/lib/jindofs-sdk-*.jar /usr/lib/hive-current/lib/
+```
+
+将JindoFS SDK的jar包复制到Hadoop目录下
+
+```
+cp sdk/lib/jindofs-sdk-*.jar /usr/lib/hadoop-current/share/hadoop/common/lib/
+```
+
+如果您跑的是Presto作业,那么将JindoFS SDK的jar包复制到Presto目录下
+
+```
+/usr/lib/presto-current/plugin/hive-hadoop2/
+```
+
+
**如果您搭建的是多节点spark、hive集群,那么集群的所有节点都要进行上述配置。**
+
+
+# 三、进阶配置
+
+## 3.1 数据持久化、数据locality
+通过数据持久化我们可以使得缓存在pod重建后依然有效。JindoFS会维护缓存数据的生命周期,进行自动清理,您无需担心数据持久化后缓存遗留问题。
通过实现数据locality,缓存才能写入到本地磁盘,并且读取缓存时如果命中本地节点可以提高读取性能。
我们需要以下配置:
+
+- 网络上使用宿主机网络
+
+```yaml
+ hostNetwork: true
+ dnsPolicy: ClusterFirstWithHostNet
+```
+
+- 容器内路径,建议集群配置保持以下惯例
+
+```yaml
+properties:
+ logDir: /mnt/disk1/bigboot/log
+
+ master:
+ properties:
+ namespace.meta-dir: /mnt/disk1/bigboot/server
+
+worker:
+ properties:
+ storage.data-dirs: /mnt/disk1/bigboot, /mnt/disk2/bigboot, /mnt/disk3/bigboot
+ storage.temp-data-dirs: /mnt/disk1/bigboot/tmp
+ storage.data-dirs.capacities: 80g,80g,80g
+ storage.meta-dir: /mnt/disk1/bigboot/bignode
+```
+
+a. logDir、 namespace.meta-dir、 storage.meta-dir放置在容器内/mnt/disk1路径下,建议保持默认值。
+b. 如果宿主机有3块盘,那么分别用volume方式映射到容器内/mnt/disk{1..N}的路径,配置到storage.data-dirs用逗号分隔。同时storage.data-dirs.capacities配置N个数值,对应每块盘的磁盘容量。mounts里面配置宿主机path(按惯例,按数字顺序填写/mnt/disk{1..N})
+
+- 如何挂载多块磁盘
+
+由于云盘有配额限制,因此我们可以在创建集群时,除了系统盘(vda),我们额外挂载4块ESSD云盘(vdb,vdc,vdd,vde)。由于最后一块盘会自动挂载到/var/containers作为容器系统使用。因此我们选择使用(系统盘vda,云盘vdb,云盘vdc,云盘vdd)作为缓存数据的存储。
在每一台机器上,执行以下命令(格式化磁盘操作有风险,请确认后再操作)
+
+```
+mkfs.ext4 /dev/vdb
+mkfs.ext4 /dev/vdc
+mkfs.ext4 /dev/vdd
+mkdir /mnt/disk{1..4}
+mount -t ext4 /dev/vdb /mnt/disk2
+mount -t ext4 /dev/vdc /mnt/disk3
+mount -t ext4 /dev/vdd /mnt/disk4
+```
+
+其中/mnt/disk1使用了系统盘vda的空间,/mnt/disk{2..4}使用了3块云盘的空间。
+
+
+## 3.2 使用内存缓存
+JindoFS使用基于ramdisk的内存缓存,因此我们先挂载ramdisk(推荐使用tmpfs而不是ramfs)
在每一台机器上,执行以下命令
+
+```
+mkdir /mnt/disk1; mount -t tmpfs -o size=120G mytmpfs /mnt/disk1
+```
+
+由于目前版本JindoFS只会使用约80%左右的配额,因此ramdisk创建时大小可以按预估数据量的120%进行创建。
+容器内路径,logDir使用临时路径,避免占用内存空间。然后master、worker服务的数据目录使用一块盘/mnt/disk1即可。
+
+```yaml
+properties:
+ logDir: /tmp/bigboot-log/
+
+ master:
+ properties:
+ namespace.meta-dir: /mnt/disk1/bigboot/server
+
+worker:
+ properties:
+ storage.data-dirs: /mnt/disk1/bigboot
+ storage.temp-data-dirs: /mnt/disk1/bigboot/tmp
+ storage.watermark.high.ratio: 1
+ storage.watermark.low.ratio: 0.95
+ storage.data-dirs.capacities: 120g
+ storage.meta-dir: /mnt/disk1/bigboot/bignode
+```
+
+
+
+## 3.2 使用Node Label将Master、Worker分开部署
+一个Master需要服务于多个Worker,会成为集群中的瓶颈之一。因此建议预留至少8 vcore,16gb内存给Master。
+
+- 对于某些场景,我们使用同构机型,选择少数几台相同的超高性能的机器(比如用4台ecs.gn6v-c8g1.16xlarge做机器学习训练),那么单机拥有充足的cpu、内存资源,因此可以使用默认配置,在master所在节点上也部署上Worker服务。
+
+
+
+- 对于大部分场景(比如大数据分析场景),我们通常使用异构机型,选择1~3台cpu、内存较高的header节点,以及多台core节点用于执行计算任务,这种方式避免了计算作业任务对master服务造成影响。此时我们建议将JindoFS Master服务部署在header节点上,将Worker服务部署在core节点上。我们使用Kubernetes的Node Level功能来实现分开部署。操作方式如下:
+
+ (1)登录容器服务 Kubernetes 版控制台。
(2)在控制台左侧导航栏中,选择集群 - 节点。
(3)在节点列表页面,选择目标集群并单击页面右上角标签管理。
(4)在标签管理页面,批量选择节点,然后单击添加标签。
可以批量选择多个core节点(排除1个header节点),在弹出的添加对话框中,填写标签名称和值。请确保名称设置为role,值设置为jindofs-worker。
在同一个页面,再次选择1个header节点,然后单击添加标签。请确保名称设置为role,值设置为jindofs-master。
+
![docs-005.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-005.png)
![docs-006.png](https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/docs/docs-006.png)
+
+
+当然你可以执行kubectl命令,比如
+
+```bash
+kubectl label no cn-beijing.192.168.8.240 role=jindofs-master
+node/cn-beijing.192.168.8.240 labeled
+kubectl label no cn-beijing.192.168.8.241 role=jindofs-worker
+node/cn-beijing.192.168.8.241 labeled
+```
+
+最后在JindoFS集群时,使用以下配置:
+
+```yaml
+master:
+ nodeSelector:
+ role: jindofs-master
+
+worker:
+ nodeSelector:
+ role: jindofs-worker
+```
+
+
+
+# 四、附录
+
+## 4.1 制作带有JindoFS SDK的镜像
+制作镜像2种办法:
方法一:从镜像市场下载已有镜像,将sdk/lib/jindofs-sdk-*.jar拷贝到镜像内程序所在classpath
方法二:只接将JindoFS SDK和开源Spark(或Hadoop)一起打包成镜像。
+
+本文演示用方法二制作Spark镜像。
首先我们下载b2sdk包进行解压
+
+```
+wget https://smartdata-binary.oss-cn-shanghai.aliyuncs.com/b2sdk-2.7.4.tar.gz
+tar -zxvf b2sdk-2.7.4.tar.gz
+```
+
+从[spark下载页面](https://spark.apache.org/downloads.html)下载所需的spark版本,本次实验选择的saprk版本为2.4.6。运行如下命令下载spark并解压:
+
+```
+$ cd /root
+$ wget https://mirror.bit.edu.cn/apache/spark/spark-2.4.6/spark-2.4.6-bin-hadoop2.7.tgz
+$ tar -xf spark-2.4.6-bin-hadoop2.7.tgz
+$ export SPARK_HOME=/root/spark-2.4.6-bin-hadoop2.7
+```
+
+
将JindoFS SDK拷贝到Spark目录下
+
+```
+$ cp sdk/lib/jindofs-sdk-2.*.jar spark-2.4.6-bin-hadoop2.7/jars/
+```
+
+开始构建镜像:
+
+```
+cd ./spark-2.4.6-bin-hadoop2.7
+docker build -t spark-jindofs:2.4.6 -f kubernetes/dockerfiles/spark/Dockerfile
+```
+
+请记住镜像名称“spark-jindofs:2.4.6”,在向k8s提交spark job中会用到这个信息。
镜像构建完成以后,对镜像的处理有两种方式:
+
+- 如果有私有镜像仓库,将该镜像推送到私有镜像仓库中,同时保证k8s集群节点能够pull该镜像
+- 如果没有私有镜像仓库,那么需要使用docker save命令将该镜像导出,然后scp到k8s集群的各个节点,在每个节点上使用docker load命令将镜像导入,这样就能保证每个节点上都存在该镜像。
+
+
+## 4.2 配置项列表
+
+下列表单展示此chart的配置项与默认值,如需修改,请在参数列表中修改。
+
+| Parameter | Description | Default |
+| --- | --- | --- |
+| properties.logDir | 容器内服务的日志目录,按照惯例请保存在默认位置,并且可以将该目录映射到宿主机,方便查看日志。 | /mnt/disk1/bigboot/log |
+|
|
|
|
+| namespace.rpc.port | namespace的rpc端口,请保留默认值。 | 8101 |
+| namespace.meta-dir | 容器内master服务的元数据目录,按照惯例请保存在默认位置,并且可以将该目录映射到宿主机,持久化该数据。 | /mnt/disk1/bigboot/server |
+| namespace.filelet.cache.size | Master服务上内存中Inode缓存数量,当内存足够时适当调大该值,可以利用内存缓存提高性能。 | 100000 |
+| namespace.blocklet.cache.size | Master服务上内存中Blocklet缓存数量,当内存足够时适当调大该值,可以利用内存缓存提高性能。 | 1000000 |
+| namespace.backend.type | Master服务的元数据存储类型。目前仅支持rocksdb的方式。请保留默认值。 | rocksdb |
+| jfs.namespaces | test表示当前JindoFS支持的命名空间,多个命名空间时以逗号隔开。 | test |
+| jfs.namespaces.test.mode | cache表示test命名空间为缓存模式。block表示块模式。 | cache |
+| jfs.namespaces.test.oss.uri | 表示test命名空间的后端存储。 | oss://xxx/ |
+| jfs.namespaces.test.oss.access.key | 表示存储后端OSS的AccessKey ID | xxx |
+| jfs.namespaces.test.oss.access.secret | 表示存储后端OSS的AccessKey Secret | xxx |
+|
|
|
|
+| storage.rpc.port | worker的rpc端口,请保留默认值。 | 6101 |
+| storage.data-dirs | worker容器内的缓存数据目录,多个目录用逗号隔开。 | /mnt/disk1/bigboot, /mnt/disk2/bigboot, /mnt/disk3/bigboot |
+| storage.temp-data-dirs | worker容器内的临时文件目录,多个目录用逗号隔开。 | /mnt/disk1/bigboot/tmp |
+| storage.watermark.high.ratio | worker使用的磁盘空间的水位上限百分比。假设500GB磁盘,0.4表示最大使用200GB | 0.4 |
+| storage.watermark.low.ratio | worker使用的磁盘空间的水位下限百分比。假设500GB磁盘,0.2表示最少使用100GB | 0.2 |
+| storage.data-dirs.capacities | 每块盘的容量大小,多个盘用逗号隔开。与storage.data-dirs的个数相对应。 | 80g,80g,80g |
+| storage.meta-dir | worker的索引数据。按照惯例请保存在默认位置,并且可以将该目录映射到宿主机,方便持久化缓存信息。 | /mnt/disk1/bigboot/bignode |
+|
|
|
|
+| client.storage.rpc.port | worker的rpc端口,请保留默认值。 | 6101 |
+| client.oss.retry | 客户端连接OSS失败时的重试次数 | 5 |
+| client.oss.upload.threads | 客户端并行上传OSS的线程数 | 4 |
+| client.oss.upload.queue.size | 客户端上传OSS的队列个数 | 5 |
+| client.oss.upload.max.parallelism | 客户端并行上传OSS的最大线程数 | 16 |
+| client.oss.timeout.millisecond | 客户端发送OSS请求的超时时间 | 30000 |
+| client.oss.connection.timeout.millisecond | 客户端连接OSS的超时时间 | 3000 |
+|
|
|
|
+| mounts.master | master服务挂载的宿主机hostPath和容器内的mountPath,如需持久化,请按惯例请填写/mnt/disk1 | 无 |
+| mounts.workersAndClients | worker服务挂载的宿主机hostPath和容器内的mountPath,如需持久化,请按惯例请填写/mnt/disk1到/mnt/diskN | 无 |
+
+
+
diff --git a/charts/jindofs/crds/data.fluid.io_jindoruntimes.yaml b/charts/jindofs/crds/data.fluid.io_jindoruntimes.yaml
new file mode 100644
index 00000000000..813cb07f722
--- /dev/null
+++ b/charts/jindofs/crds/data.fluid.io_jindoruntimes.yaml
@@ -0,0 +1,661 @@
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.3.0
+ creationTimestamp: null
+ name: jindoruntimes.data.fluid.io
+spec:
+ group: data.fluid.io
+ names:
+ kind: JindoRuntime
+ listKind: JindoRuntimeList
+ plural: jindoruntimes
+ singular: jindoruntime
+ scope: Namespaced
+ validation:
+ openAPIV3Schema:
+ description: JindoRuntime is the Schema for the jindoruntimes API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: JindoRuntimeSpec defines the desired state of JindoRuntime
+ properties:
+ fuse:
+ description: Desired state for Alluxio Fuse
+ properties:
+ args:
+ description: Arguments that will be passed to Alluxio Fuse
+ items:
+ type: string
+ type: array
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ Fuse
+ type: object
+ image:
+ description: Image for Alluxio Fuse(e.g. alluxio/alluxio-fuse)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image Tag for Alluxio Fuse(e.g. 2.3.0-SNAPSHOT)
+ type: string
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for Alluxio System.
Refer
+ to Alluxio
+ Configuration Properties for more info
+ type: object
+ resources:
+ description: Resources that will be requested by Alluxio Fuse.
+
Resources are not allowed for ephemeral containers. Ephemeral
+ containers use spare resources already allocated to the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ initUsers:
+ description: The spec of init users
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by initialize
+ the users for runtime
+ type: object
+ image:
+ description: Image for initialize the users for runtime(e.g. alluxio/alluxio-User
+ init)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image Tag for initialize the users for runtime(e.g.
+ 2.3.0-SNAPSHOT)
+ type: string
+ resources:
+ description: Resources that will be requested by initialize the
+ users for runtime.
Resources are not allowed for ephemeral
+ containers. Ephemeral containers use spare resources already allocated
+ to the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jindoVersion:
+ description: The version information that instructs fluid to orchestrate
+ a particular version of Alluxio.
+ properties:
+ image:
+ description: Image for Jindo(e.g. jindo/jindo)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image tag for Jindo(e.g. 2.3.0-SNAPSHOT)
+ type: string
+ type: object
+ jobMaster:
+ description: Desired state for Alluxio job master
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jobWorker:
+ description: Desired state for Alluxio job Worker
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ master:
+ description: Desired state for Alluxio master
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for Alluxio system.
Refer
+ to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: The replicas of the worker, need to be specified
+ format: int32
+ type: integer
+ runAs:
+ description: Manage the user to run Alluxio Runtime
+ properties:
+ gid:
+ description: The gid to run the alluxio runtime
+ format: int64
+ type: integer
+ group:
+ description: The group name to run the alluxio runtime
+ type: string
+ uid:
+ description: The uid to run the alluxio runtime
+ format: int64
+ type: integer
+ user:
+ description: The user name to run the alluxio runtime
+ type: string
+ required:
+ - gid
+ - group
+ - uid
+ - user
+ type: object
+ tieredstore:
+ description: Tiered storage used by Alluxio
+ properties:
+ levels:
+ description: configurations for multiple tiers
+ items:
+ description: Level describes configurations a tier needs.
+ Refer to Configuring
+ Tiered Storage for more info
+ properties:
+ high:
+ description: Ratio of high watermark of the tier (e.g. 0.9)
+ type: string
+ low:
+ description: Ratio of low watermark of the tier (e.g. 0.7)
+ type: string
+ mediumtype:
+ description: 'Medium Type of the tier. One of the three types:
+ `MEM`, `SSD`, `HDD`'
+ enum:
+ - MEM
+ - SSD
+ - HDD
+ type: string
+ path:
+ description: File path to be used for the tier (e.g. /mnt/ramdisk)
+ minLength: 1
+ type: string
+ quota:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Quota for the tier. (e.g. 100GB)
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ required:
+ - mediumtype
+ type: object
+ type: array
+ type: object
+ worker:
+ description: Desired state for Alluxio worker
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ type: object
+ status:
+ description: JindoRuntimeStatus defines the observed state of JindoRuntime
+ properties:
+ cacheStates:
+ additionalProperties:
+ type: string
+ description: CacheStatus represents the total resources of the dataset.
+ type: object
+ conditions:
+ description: Represents the latest available observations of a ddc runtime's
+ current state.
+ items:
+ description: Condition describes the state of the cache at a certain
+ point.
+ properties:
+ lastProbeTime:
+ description: The last time this condition was updated.
+ format: date-time
+ type: string
+ lastTransitionTime:
+ description: Last time the condition transitioned from one status
+ to another.
+ format: date-time
+ type: string
+ message:
+ description: A human readable message indicating details about
+ the transition.
+ type: string
+ reason:
+ description: The reason for the condition's last transition.
+ type: string
+ status:
+ description: Status of the condition, one of True, False, Unknown.
+ type: string
+ type:
+ description: Type of cache condition.
+ type: string
+ required:
+ - status
+ - type
+ type: object
+ type: array
+ currentFuseNumberScheduled:
+ description: The total number of nodes that can be running the runtime
+ Fuse pod (including nodes correctly running the runtime Fuse pod).
+ format: int32
+ type: integer
+ currentMasterNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ pod (including nodes correctly running the runtime master pod).
+ format: int32
+ type: integer
+ currentWorkerNumberScheduled:
+ description: The total number of nodes that can be running the runtime
+ worker pod (including nodes correctly running the runtime worker pod).
+ format: int32
+ type: integer
+ desiredFuseNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ Fuse pod (including nodes correctly running the runtime Fuse pod).
+ format: int32
+ type: integer
+ desiredMasterNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ pod (including nodes correctly running the runtime master pod).
+ format: int32
+ type: integer
+ desiredWorkerNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ worker pod (including nodes correctly running the runtime worker pod).
+ format: int32
+ type: integer
+ fuseNumberAvailable:
+ description: The number of nodes that should be running the runtime
+ Fuse pod and have one or more of the runtime Fuse pod running and
+ available (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ fuseNumberReady:
+ description: The number of nodes that should be running the runtime
+ Fuse pod and have one or more of the runtime Fuse pod running and
+ ready.
+ format: int32
+ type: integer
+ fuseNumberUnavailable:
+ description: The number of nodes that should be running the runtime
+ fuse pod and have none of the runtime fuse pod running and available
+ (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ fusePhase:
+ description: FusePhase is the Fuse running phase
+ type: string
+ fuseReason:
+ description: Reason for the condition's last transition.
+ type: string
+ masterNumberReady:
+ description: The number of nodes that should be running the runtime
+ worker pod and have zero or more of the runtime master pod running
+ and ready.
+ format: int32
+ type: integer
+ masterPhase:
+ description: MasterPhase is the master running phase
+ type: string
+ masterReason:
+ description: Reason for Jindo Master's condition transition
+ type: string
+ valueFile:
+ description: config map used to set configurations
+ type: string
+ workerNumberAvailable:
+ description: The number of nodes that should be running the runtime
+ worker pod and have one or more of the runtime worker pod running
+ and available (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ workerNumberReady:
+ description: The number of nodes that should be running the runtime
+ worker pod and have one or more of the runtime worker pod running
+ and ready.
+ format: int32
+ type: integer
+ workerNumberUnavailable:
+ description: The number of nodes that should be running the runtime
+ worker pod and have none of the runtime worker pod running and available
+ (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ workerPhase:
+ description: WorkerPhase is the worker running phase
+ type: string
+ workerReason:
+ description: Reason for Jindo Worker's condition transition
+ type: string
+ required:
+ - currentFuseNumberScheduled
+ - currentMasterNumberScheduled
+ - currentWorkerNumberScheduled
+ - desiredFuseNumberScheduled
+ - desiredMasterNumberScheduled
+ - desiredWorkerNumberScheduled
+ - fuseNumberReady
+ - fusePhase
+ - masterNumberReady
+ - masterPhase
+ - valueFile
+ - workerNumberReady
+ - workerPhase
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/charts/jindofs/templates/_helpers.tpl b/charts/jindofs/templates/_helpers.tpl
new file mode 100755
index 00000000000..90f77474492
--- /dev/null
+++ b/charts/jindofs/templates/_helpers.tpl
@@ -0,0 +1,32 @@
+{{/* vim: set filetype=mustache: */}}
+{{/*
+Expand the name of the chart.
+*/}}
+{{- define "jindofs.name" -}}
+{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
+
+{{/*
+Create a default fully qualified app name.
+We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
+If release name contains chart name it will be used as a full name.
+*/}}
+{{- define "jindofs.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 "jindofs.chart" -}}
+{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
+{{- end -}}
diff --git a/charts/jindofs/templates/config/jindofs-conf.yaml b/charts/jindofs/templates/config/jindofs-conf.yaml
new file mode 100755
index 00000000000..c5ca8aa5d8c
--- /dev/null
+++ b/charts/jindofs/templates/config/jindofs-conf.yaml
@@ -0,0 +1,40 @@
+apiVersion: v1
+kind: ConfigMap
+metadata:
+ annotations:
+ "helm.sh/hook": "pre-install"
+ "helm.sh/hook-delete-policy": before-hook-creation
+ name: {{ template "jindofs.fullname" . }}-config
+ labels:
+ name: {{ template "jindofs.fullname" . }}-config
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+data:
+ master.cfg: |
+ [bigboot]
+ logger.dir = {{ .Values.properties.logDir }}
+ logger.cleanner.enable = true
+ [bigboot-namespace]
+ {{- range $key, $val := .Values.master.properties }}
+ {{ $key }} = {{ $val }}
+ {{- end}}
+ worker.cfg: |
+ [bigboot]
+ logger.dir = {{ .Values.properties.logDir }}
+ logger.cleanner.enable = true
+ [bigboot-storage]
+ {{- range $key, $val := .Values.worker.properties }}
+ {{ $key }} = {{ $val }}
+ {{- end}}
+ fuse.cfg: |
+ [bigboot]
+ logger.dir = {{ .Values.properties.logDir }}
+ logger.cleanner.enable = true
+ [bigboot-client]
+ {{- range $key, $val := .Values.fuse.properties }}
+ {{ $key }} = {{ $val }}
+ {{- end}}
+ client.rpc.max.unwritten.size = 1073741824
+ jfs.cache.data-cache.enable = 1
diff --git a/charts/jindofs/templates/fuse/daemonset.yaml b/charts/jindofs/templates/fuse/daemonset.yaml
new file mode 100755
index 00000000000..4ef547eed7f
--- /dev/null
+++ b/charts/jindofs/templates/fuse/daemonset.yaml
@@ -0,0 +1,99 @@
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: {{ template "jindofs.fullname" . }}-fuse
+ labels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-fuse
+spec:
+ selector:
+ matchLabels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-fuse
+ template:
+ metadata:
+ labels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-fuse
+ spec:
+ hostNetwork: {{ .Values.useHostNetwork }}
+ hostPID: {{ .Values.useHostPID }}
+ dnsPolicy: ClusterFirstWithHostNet
+ nodeSelector:
+{{- if .Values.fuse.nodeSelector }}
+{{ toYaml .Values.fuse.nodeSelector | trim | indent 8 }}
+{{- else if .Values.nodeSelector }}
+{{ toYaml .Values.nodeSelector | trim | indent 8 }}
+{{- end }}
+ securityContext:
+ runAsUser: {{ .Values.user }}
+ runAsGroup: {{ .Values.group }}
+ fsGroup: {{ .Values.fsGroup }}
+ containers:
+ - name: jindofs-fuse
+ image: {{ .Values.fuseImage }}:{{ .Values.fuseImageTag }}
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ command: ["/entrypoint.sh"]
+ {{- if .Values.fuse.args }}
+ args:
+{{ toYaml .Values.fuse.args | indent 12 }}
+ {{- end }}
+ env:
+ - name: CLIENT_NAMESPACE_RPC_ADDRESS
+ value: {{ template "jindofs.fullname" . }}-master:8101
+ - name: CLIENT_STORAGE_RPC_HOST
+ valueFrom:
+ fieldRef:
+ fieldPath: status.hostIP
+ securityContext:
+ privileged: true
+ capabilities:
+ add:
+ - SYS_ADMIN
+ volumeMounts:
+ - name: jindofs-fuse-device
+ mountPath: /dev/fuse
+ - name: jindofs-fuse-mount
+ mountPath: /jfs
+ mountPropagation: Bidirectional
+ - mountPath: /etc/localtime
+ name: volume-localtime
+ - name: bigboot-config
+ mountPath: /sdk/conf/bigboot.cfg
+ subPath: fuse.cfg
+ {{- range $name, $path := .Values.mounts.workersAndClients }}
+ - name: datavolume-{{ $name }}
+ mountPath: "{{ $path }}"
+ {{- end }}
+ restartPolicy: Always
+ volumes:
+ - name: jindofs-fuse-device
+ hostPath:
+ path: /dev/fuse
+ type: File
+ - hostPath:
+ path: /etc/localtime
+ type: ''
+ name: volume-localtime
+ - name: jindofs-fuse-mount
+ hostPath:
+ path: {{ .Values.fuse.hostPath }}
+ type: DirectoryOrCreate
+ {{- range $name, $path := .Values.mounts.workersAndClients }}
+ - hostPath:
+ path: "{{ $path }}"
+ type: DirectoryOrCreate
+ name: datavolume-{{ $name }}
+ {{- end }}
+ - name: bigboot-config
+ configMap:
+ name: {{ template "jindofs.fullname" . }}-config
diff --git a/charts/jindofs/templates/master/service.yaml b/charts/jindofs/templates/master/service.yaml
new file mode 100755
index 00000000000..387d367f156
--- /dev/null
+++ b/charts/jindofs/templates/master/service.yaml
@@ -0,0 +1,19 @@
+apiVersion: v1
+kind: Service
+metadata:
+ name: {{ template "jindofs.fullname" . }}-master
+ labels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-master
+spec:
+ ports:
+ - port: 8101
+ name: rpc
+ clusterIP: None
+ selector:
+ role: jindofs-master
+ app: {{ template "jindofs.name" . }}
+ release: {{ .Release.Name }}
diff --git a/charts/jindofs/templates/master/statefulset.yaml b/charts/jindofs/templates/master/statefulset.yaml
new file mode 100755
index 00000000000..be18cdeb837
--- /dev/null
+++ b/charts/jindofs/templates/master/statefulset.yaml
@@ -0,0 +1,89 @@
+apiVersion: apps/v1
+kind: StatefulSet
+metadata:
+ name: {{ template "jindofs.fullname" . }}-master
+ labels:
+ name: {{ template "jindofs.fullname" . }}-master
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-master
+spec:
+ selector:
+ matchLabels:
+ app: {{ template "jindofs.name" . }}
+ role: jindofs-master
+ name: {{ template "jindofs.fullname" . }}-master
+ serviceName: "jindofs-master"
+ replicas: {{ .Values.master.replicaCount }}
+ template:
+ metadata:
+ labels:
+ name: {{ template "jindofs.fullname" . }}-master
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-master
+ spec:
+ hostNetwork: {{ .Values.useHostNetwork }}
+ hostPID: {{ .Values.useHostPID }}
+ dnsPolicy: ClusterFirstWithHostNet
+ nodeSelector:
+{{- if .Values.master.nodeSelector }}
+{{ toYaml .Values.master.nodeSelector | trim | indent 8 }}
+{{- else if .Values.nodeSelector }}
+{{ toYaml .Values.nodeSelector | trim | indent 8 }}
+{{- end }}
+ securityContext:
+ runAsUser: {{ .Values.user }}
+ runAsGroup: {{ .Values.group }}
+ fsGroup: {{ .Values.fsGroup }}
+ containers:
+ - name: jindofs-master
+ image: {{ .Values.image }}:{{ .Values.imageTag }}
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ resources:
+ {{- if .Values.worker.resources }}
+ {{- if .Values.master.resources.limits }}
+ limits:
+ cpu: {{ .Values.master.resources.limits.cpu }}
+ memory: {{ .Values.master.resources.limits.memory }}
+ {{- end }}
+ {{- if .Values.master.resources.requests }}
+ requests:
+ cpu: {{ .Values.master.resources.requests.cpu }}
+ memory: {{ .Values.master.resources.requests.memory }}
+ {{- end }}
+ {{- end }}
+ command: ["/entrypoint.sh"]
+ args: ["master"]
+ ports:
+ - containerPort: 8101
+ name: rpc
+ volumeMounts:
+ - name: bigboot-config
+ mountPath: /smartdata/conf/bigboot.cfg
+ subPath: master.cfg
+ {{- range $name, $path := .Values.mounts.master }}
+ - name: datavolume-{{ $name }}
+ mountPath: "{{ $path }}"
+ {{- end }}
+ - mountPath: /etc/localtime
+ name: volume-localtime
+ restartPolicy: Always
+ volumes:
+ - hostPath:
+ path: /etc/localtime
+ type: ''
+ name: volume-localtime
+ {{- range $name, $path := .Values.mounts.master }}
+ - hostPath:
+ path: "{{ $path }}"
+ type: DirectoryOrCreate
+ name: datavolume-{{ $name }}
+ {{- end }}
+ - name: bigboot-config
+ configMap:
+ name: {{ template "jindofs.fullname" . }}-config
diff --git a/charts/jindofs/templates/worker/daemonset.yaml b/charts/jindofs/templates/worker/daemonset.yaml
new file mode 100755
index 00000000000..d2b18193247
--- /dev/null
+++ b/charts/jindofs/templates/worker/daemonset.yaml
@@ -0,0 +1,92 @@
+apiVersion: apps/v1
+kind: DaemonSet
+metadata:
+ name: {{ template "jindofs.fullname" . }}-worker
+ labels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-worker
+spec:
+ selector:
+ matchLabels:
+ app: {{ template "jindofs.name" . }}
+ release: {{ .Release.Name }}
+ role: jindofs-worker
+ template:
+ metadata:
+ labels:
+ app: {{ template "jindofs.name" . }}
+ chart: {{ template "jindofs.chart" . }}
+ release: {{ .Release.Name }}
+ heritage: {{ .Release.Service }}
+ role: jindofs-worker
+ spec:
+ hostNetwork: {{ .Values.useHostNetwork }}
+ hostPID: {{ .Values.useHostPID }}
+ dnsPolicy: ClusterFirstWithHostNet
+ securityContext:
+ runAsUser: {{ .Values.user }}
+ runAsGroup: {{ .Values.group }}
+ fsGroup: {{ .Values.fsGroup }}
+ nodeSelector:
+{{- if .Values.worker.nodeSelector }}
+{{ toYaml .Values.worker.nodeSelector | trim | indent 8 }}
+{{- else if .Values.nodeSelector }}
+{{ toYaml .Values.nodeSelector | trim | indent 8 }}
+{{- end }}
+ containers:
+ - name: jindofs-worker
+ image: {{ .Values.image }}:{{ .Values.imageTag }}
+ imagePullPolicy: {{ .Values.imagePullPolicy }}
+ resources:
+ limits:
+ {{- if .Values.worker.resources }}
+ {{- if .Values.worker.resources.limits }}
+ {{- if .Values.worker.resources.limits.cpu }}
+ cpu: {{ .Values.worker.resources.limits.cpu }}
+ memory: {{ .Values.worker.resources.limits.memory }}
+ {{- end }}
+ {{- end }}
+ requests:
+ {{- if .Values.worker.resources.requests }}
+ {{- if .Values.worker.resources.requests.cpu }}
+ cpu: {{ .Values.worker.resources.requests.cpu }}
+ memory: {{ .Values.worker.resources.requests.memory }}
+ {{- end }}
+ {{- end }}
+ {{- end }}
+ command: ["/entrypoint.sh"]
+ args: ["worker"]
+ env:
+ - name: STORAGE_NAMESPACE_RPC_ADDRESS
+ value: {{ template "jindofs.fullname" . }}-master:8101
+ ports:
+ - containerPort: 6101
+ name: rpc
+ volumeMounts:
+ - name: bigboot-config
+ mountPath: /smartdata/conf/bigboot.cfg
+ subPath: worker.cfg
+ {{- range $name, $path := .Values.mounts.workersAndClients }}
+ - name: datavolume-{{ $name }}
+ mountPath: "{{ $path }}"
+ {{- end }}
+ - mountPath: /etc/localtime
+ name: volume-localtime
+ restartPolicy: Always
+ volumes:
+ - hostPath:
+ path: /etc/localtime
+ type: ''
+ name: volume-localtime
+ {{- range $name, $path := .Values.mounts.workersAndClients }}
+ - hostPath:
+ path: "{{ $path }}"
+ type: DirectoryOrCreate
+ name: datavolume-{{ $name }}
+ {{- end }}
+ - name: bigboot-config
+ configMap:
+ name: {{ template "jindofs.fullname" . }}-config
diff --git a/cmd/jindo/main.go b/cmd/jindo/main.go
new file mode 100644
index 00000000000..4d5ffd90dae
--- /dev/null
+++ b/cmd/jindo/main.go
@@ -0,0 +1,130 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package main
+
+import (
+ "fmt"
+ "github.com/fluid-cloudnative/fluid"
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ jindoctl "github.com/fluid-cloudnative/fluid/pkg/controllers/v1alpha1/jindo"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/base"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/jindo"
+ "github.com/spf13/cobra"
+ zapOpt "go.uber.org/zap"
+ "go.uber.org/zap/zapcore"
+ "k8s.io/apimachinery/pkg/runtime"
+ clientgoscheme "k8s.io/client-go/kubernetes/scheme"
+ "os"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+)
+
+var (
+ scheme = runtime.NewScheme()
+ setupLog = ctrl.Log.WithName("setup")
+ // Use compiler to check if the struct implements all the interface
+ _ base.Implement = (*jindo.JindoEngine)(nil)
+
+ short bool
+ metricsAddr string
+ enableLeaderElection bool
+ development bool
+)
+
+var cmd = &cobra.Command{
+ Use: "jindoruntime-controller",
+ Short: "Controller for jindoruntime",
+}
+
+var startCmd = &cobra.Command{
+ Use: "start",
+ Short: "start jindoruntime-controller in Kubernetes",
+ Run: func(cmd *cobra.Command, args []string) {
+ handle()
+ },
+}
+
+var versionCmd = &cobra.Command{
+ Use: "version",
+ Short: "print version information",
+ Run: func(cmd *cobra.Command, args []string) {
+ fluid.PrintVersion(short)
+ },
+}
+
+func init() {
+ _ = clientgoscheme.AddToScheme(scheme)
+ _ = datav1alpha1.AddToScheme(scheme)
+
+ startCmd.Flags().StringVarP(&metricsAddr, "metrics-addr", "", ":8080", "The address the metric endpoint binds to.")
+ startCmd.Flags().BoolVarP(&enableLeaderElection, "enable-leader-election", "", false, "Enable leader election for controller manager. Enabling this will ensure there is only one active controller manager.")
+ startCmd.Flags().BoolVarP(&development, "development", "", true, "Enable development mode for pillar controller.")
+ versionCmd.Flags().BoolVar(&short, "short", false, "print just the short version info")
+
+ cmd.AddCommand(startCmd)
+ cmd.AddCommand(versionCmd)
+}
+
+func main() {
+ if err := cmd.Execute(); err != nil {
+ fmt.Fprintf(os.Stderr, "%s", err.Error())
+ os.Exit(1)
+ }
+}
+
+func handle() {
+ fluid.LogVersion()
+
+ ctrl.SetLogger(zap.New(func(o *zap.Options) {
+ o.Development = development
+ }, func(o *zap.Options) {
+ o.ZapOpts = append(o.ZapOpts, zapOpt.AddCaller())
+ }, func(o *zap.Options) {
+ if !development {
+ encCfg := zapOpt.NewProductionEncoderConfig()
+ encCfg.EncodeLevel = zapcore.CapitalLevelEncoder
+ encCfg.EncodeTime = zapcore.ISO8601TimeEncoder
+ o.Encoder = zapcore.NewConsoleEncoder(encCfg)
+ }
+ }))
+
+ mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
+ Scheme: scheme,
+ MetricsBindAddress: metricsAddr,
+ LeaderElection: enableLeaderElection,
+ LeaderElectionID: "5688274864.data.fluid.io",
+ Port: 9443,
+ })
+ if err != nil {
+ setupLog.Error(err, "unable to start jindoruntime manager")
+ os.Exit(1)
+ }
+
+ if err = (jindoctl.NewRuntimeReconciler(mgr.GetClient(),
+ ctrl.Log.WithName("jindoctl").WithName("JindoRuntime"),
+ mgr.GetScheme(),
+ mgr.GetEventRecorderFor("JindoRuntime"),
+ )).SetupWithManager(mgr); err != nil {
+ setupLog.Error(err, "unable to create controller", "controller", "JindoRuntime")
+ os.Exit(1)
+ }
+
+ setupLog.Info("starting jindoruntime-controller")
+ if err := mgr.Start(ctrl.SetupSignalHandler()); err != nil {
+ setupLog.Error(err, "problem jindoruntime-controller")
+ os.Exit(1)
+ }
+}
diff --git a/config/crd/bases/data.fluid.io_jindoruntimes.yaml b/config/crd/bases/data.fluid.io_jindoruntimes.yaml
new file mode 100644
index 00000000000..813cb07f722
--- /dev/null
+++ b/config/crd/bases/data.fluid.io_jindoruntimes.yaml
@@ -0,0 +1,661 @@
+
+---
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ controller-gen.kubebuilder.io/version: v0.3.0
+ creationTimestamp: null
+ name: jindoruntimes.data.fluid.io
+spec:
+ group: data.fluid.io
+ names:
+ kind: JindoRuntime
+ listKind: JindoRuntimeList
+ plural: jindoruntimes
+ singular: jindoruntime
+ scope: Namespaced
+ validation:
+ openAPIV3Schema:
+ description: JindoRuntime is the Schema for the jindoruntimes API
+ properties:
+ apiVersion:
+ description: 'APIVersion defines the versioned schema of this representation
+ of an object. Servers should convert recognized schemas to the latest
+ internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources'
+ type: string
+ kind:
+ description: 'Kind is a string value representing the REST resource this
+ object represents. Servers may infer this from the endpoint the client
+ submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds'
+ type: string
+ metadata:
+ type: object
+ spec:
+ description: JindoRuntimeSpec defines the desired state of JindoRuntime
+ properties:
+ fuse:
+ description: Desired state for Alluxio Fuse
+ properties:
+ args:
+ description: Arguments that will be passed to Alluxio Fuse
+ items:
+ type: string
+ type: array
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ Fuse
+ type: object
+ image:
+ description: Image for Alluxio Fuse(e.g. alluxio/alluxio-fuse)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image Tag for Alluxio Fuse(e.g. 2.3.0-SNAPSHOT)
+ type: string
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for Alluxio System.
Refer
+ to Alluxio
+ Configuration Properties for more info
+ type: object
+ resources:
+ description: Resources that will be requested by Alluxio Fuse.
+
Resources are not allowed for ephemeral containers. Ephemeral
+ containers use spare resources already allocated to the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ initUsers:
+ description: The spec of init users
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by initialize
+ the users for runtime
+ type: object
+ image:
+ description: Image for initialize the users for runtime(e.g. alluxio/alluxio-User
+ init)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image Tag for initialize the users for runtime(e.g.
+ 2.3.0-SNAPSHOT)
+ type: string
+ resources:
+ description: Resources that will be requested by initialize the
+ users for runtime.
Resources are not allowed for ephemeral
+ containers. Ephemeral containers use spare resources already allocated
+ to the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jindoVersion:
+ description: The version information that instructs fluid to orchestrate
+ a particular version of Alluxio.
+ properties:
+ image:
+ description: Image for Jindo(e.g. jindo/jindo)
+ type: string
+ imagePullPolicy:
+ description: 'One of the three policies: `Always`, `IfNotPresent`,
+ `Never`'
+ type: string
+ imageTag:
+ description: Image tag for Jindo(e.g. 2.3.0-SNAPSHOT)
+ type: string
+ type: object
+ jobMaster:
+ description: Desired state for Alluxio job master
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jobWorker:
+ description: Desired state for Alluxio job Worker
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ master:
+ description: Desired state for Alluxio master
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for Alluxio system.
Refer
+ to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: The replicas of the worker, need to be specified
+ format: int32
+ type: integer
+ runAs:
+ description: Manage the user to run Alluxio Runtime
+ properties:
+ gid:
+ description: The gid to run the alluxio runtime
+ format: int64
+ type: integer
+ group:
+ description: The group name to run the alluxio runtime
+ type: string
+ uid:
+ description: The uid to run the alluxio runtime
+ format: int64
+ type: integer
+ user:
+ description: The user name to run the alluxio runtime
+ type: string
+ required:
+ - gid
+ - group
+ - uid
+ - user
+ type: object
+ tieredstore:
+ description: Tiered storage used by Alluxio
+ properties:
+ levels:
+ description: configurations for multiple tiers
+ items:
+ description: Level describes configurations a tier needs.
+ Refer to Configuring
+ Tiered Storage for more info
+ properties:
+ high:
+ description: Ratio of high watermark of the tier (e.g. 0.9)
+ type: string
+ low:
+ description: Ratio of low watermark of the tier (e.g. 0.7)
+ type: string
+ mediumtype:
+ description: 'Medium Type of the tier. One of the three types:
+ `MEM`, `SSD`, `HDD`'
+ enum:
+ - MEM
+ - SSD
+ - HDD
+ type: string
+ path:
+ description: File path to be used for the tier (e.g. /mnt/ramdisk)
+ minLength: 1
+ type: string
+ quota:
+ anyOf:
+ - type: integer
+ - type: string
+ description: Quota for the tier. (e.g. 100GB)
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ required:
+ - mediumtype
+ type: object
+ type: array
+ type: object
+ worker:
+ description: Desired state for Alluxio worker
+ properties:
+ env:
+ additionalProperties:
+ type: string
+ description: Environment variables that will be used by Alluxio
+ component.
+ type: object
+ jvmOptions:
+ description: Options for JVM
+ items:
+ type: string
+ type: array
+ ports:
+ additionalProperties:
+ type: integer
+ description: 'Ports used by Alluxio(e.g. rpc: 19998 for master)'
+ type: object
+ properties:
+ additionalProperties:
+ type: string
+ description: Configurable properties for the Alluxio component.
+
Refer to Alluxio
+ Configuration Properties for more info
+ type: object
+ replicas:
+ description: Replicas is the desired number of replicas of the given
+ template. If unspecified, defaults to 1. replicas is the min replicas
+ of dataset in the cluster
+ format: int32
+ minimum: 1
+ type: integer
+ resources:
+ description: Resources that will be requested by the Alluxio component.
+
Resources are not allowed for ephemeral containers.
+ Ephemeral containers use spare resources already allocated to
+ the pod.
+ properties:
+ limits:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Limits describes the maximum amount of compute
+ resources allowed. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ requests:
+ additionalProperties:
+ anyOf:
+ - type: integer
+ - type: string
+ pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
+ x-kubernetes-int-or-string: true
+ description: 'Requests describes the minimum amount of compute
+ resources required. If Requests is omitted for a container,
+ it defaults to Limits if that is explicitly specified, otherwise
+ to an implementation-defined value. More info: https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/'
+ type: object
+ type: object
+ type: object
+ type: object
+ status:
+ description: JindoRuntimeStatus defines the observed state of JindoRuntime
+ properties:
+ cacheStates:
+ additionalProperties:
+ type: string
+ description: CacheStatus represents the total resources of the dataset.
+ type: object
+ conditions:
+ description: Represents the latest available observations of a ddc runtime's
+ current state.
+ items:
+ description: Condition describes the state of the cache at a certain
+ point.
+ properties:
+ lastProbeTime:
+ description: The last time this condition was updated.
+ format: date-time
+ type: string
+ lastTransitionTime:
+ description: Last time the condition transitioned from one status
+ to another.
+ format: date-time
+ type: string
+ message:
+ description: A human readable message indicating details about
+ the transition.
+ type: string
+ reason:
+ description: The reason for the condition's last transition.
+ type: string
+ status:
+ description: Status of the condition, one of True, False, Unknown.
+ type: string
+ type:
+ description: Type of cache condition.
+ type: string
+ required:
+ - status
+ - type
+ type: object
+ type: array
+ currentFuseNumberScheduled:
+ description: The total number of nodes that can be running the runtime
+ Fuse pod (including nodes correctly running the runtime Fuse pod).
+ format: int32
+ type: integer
+ currentMasterNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ pod (including nodes correctly running the runtime master pod).
+ format: int32
+ type: integer
+ currentWorkerNumberScheduled:
+ description: The total number of nodes that can be running the runtime
+ worker pod (including nodes correctly running the runtime worker pod).
+ format: int32
+ type: integer
+ desiredFuseNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ Fuse pod (including nodes correctly running the runtime Fuse pod).
+ format: int32
+ type: integer
+ desiredMasterNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ pod (including nodes correctly running the runtime master pod).
+ format: int32
+ type: integer
+ desiredWorkerNumberScheduled:
+ description: The total number of nodes that should be running the runtime
+ worker pod (including nodes correctly running the runtime worker pod).
+ format: int32
+ type: integer
+ fuseNumberAvailable:
+ description: The number of nodes that should be running the runtime
+ Fuse pod and have one or more of the runtime Fuse pod running and
+ available (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ fuseNumberReady:
+ description: The number of nodes that should be running the runtime
+ Fuse pod and have one or more of the runtime Fuse pod running and
+ ready.
+ format: int32
+ type: integer
+ fuseNumberUnavailable:
+ description: The number of nodes that should be running the runtime
+ fuse pod and have none of the runtime fuse pod running and available
+ (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ fusePhase:
+ description: FusePhase is the Fuse running phase
+ type: string
+ fuseReason:
+ description: Reason for the condition's last transition.
+ type: string
+ masterNumberReady:
+ description: The number of nodes that should be running the runtime
+ worker pod and have zero or more of the runtime master pod running
+ and ready.
+ format: int32
+ type: integer
+ masterPhase:
+ description: MasterPhase is the master running phase
+ type: string
+ masterReason:
+ description: Reason for Jindo Master's condition transition
+ type: string
+ valueFile:
+ description: config map used to set configurations
+ type: string
+ workerNumberAvailable:
+ description: The number of nodes that should be running the runtime
+ worker pod and have one or more of the runtime worker pod running
+ and available (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ workerNumberReady:
+ description: The number of nodes that should be running the runtime
+ worker pod and have one or more of the runtime worker pod running
+ and ready.
+ format: int32
+ type: integer
+ workerNumberUnavailable:
+ description: The number of nodes that should be running the runtime
+ worker pod and have none of the runtime worker pod running and available
+ (ready for at least spec.minReadySeconds)
+ format: int32
+ type: integer
+ workerPhase:
+ description: WorkerPhase is the worker running phase
+ type: string
+ workerReason:
+ description: Reason for Jindo Worker's condition transition
+ type: string
+ required:
+ - currentFuseNumberScheduled
+ - currentMasterNumberScheduled
+ - currentWorkerNumberScheduled
+ - desiredFuseNumberScheduled
+ - desiredMasterNumberScheduled
+ - desiredWorkerNumberScheduled
+ - fuseNumberReady
+ - fusePhase
+ - masterNumberReady
+ - masterPhase
+ - valueFile
+ - workerNumberReady
+ - workerPhase
+ type: object
+ type: object
+ version: v1alpha1
+ versions:
+ - name: v1alpha1
+ served: true
+ storage: true
+status:
+ acceptedNames:
+ kind: ""
+ plural: ""
+ conditions: []
+ storedVersions: []
diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml
index 18a2569e7a4..a2a5776ab7b 100644
--- a/config/crd/kustomization.yaml
+++ b/config/crd/kustomization.yaml
@@ -5,6 +5,7 @@ resources:
- bases/data.fluid.io_datasets.yaml
- bases/data.fluid.io_alluxioruntimes.yaml
- bases/data.fluid.io_dataloads.yaml
+- bases/data.fluid.io_jindoruntimes.yaml
# +kubebuilder:scaffold:crdkustomizeresource
patchesStrategicMerge:
@@ -13,6 +14,7 @@ patchesStrategicMerge:
#- patches/webhook_in_datasets.yaml
#- patches/webhook_in_alluxioruntimes.yaml
#- patches/webhook_in_dataloads.yaml
+#- patches/webhook_in_jindoruntimes.yaml
# +kubebuilder:scaffold:crdkustomizewebhookpatch
# [CERTMANAGER] To enable webhook, uncomment all the sections with [CERTMANAGER] prefix.
@@ -20,6 +22,7 @@ patchesStrategicMerge:
#- patches/cainjection_in_datasets.yaml
#- patches/cainjection_in_alluxioruntimes.yaml
#- patches/cainjection_in_dataloads.yaml
+#- patches/cainjection_in_jindoruntimes.yaml
# +kubebuilder:scaffold:crdkustomizecainjectionpatch
# the following config is for teaching kustomize how to do kustomization for CRDs.
diff --git a/config/crd/patches/cainjection_in_jindoruntimes.yaml b/config/crd/patches/cainjection_in_jindoruntimes.yaml
new file mode 100644
index 00000000000..ea76983647e
--- /dev/null
+++ b/config/crd/patches/cainjection_in_jindoruntimes.yaml
@@ -0,0 +1,8 @@
+# The following patch adds a directive for certmanager to inject CA into the CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ annotations:
+ cert-manager.io/inject-ca-from: $(CERTIFICATE_NAMESPACE)/$(CERTIFICATE_NAME)
+ name: jindoruntimes.data.fluid.io
diff --git a/config/crd/patches/webhook_in_jindoruntimes.yaml b/config/crd/patches/webhook_in_jindoruntimes.yaml
new file mode 100644
index 00000000000..a3ce96da594
--- /dev/null
+++ b/config/crd/patches/webhook_in_jindoruntimes.yaml
@@ -0,0 +1,17 @@
+# The following patch enables conversion webhook for CRD
+# CRD conversion requires k8s 1.13 or later.
+apiVersion: apiextensions.k8s.io/v1beta1
+kind: CustomResourceDefinition
+metadata:
+ name: jindoruntimes.data.fluid.io
+spec:
+ conversion:
+ strategy: Webhook
+ webhookClientConfig:
+ # this is "\n" used as a placeholder, otherwise it will be rejected by the apiserver for being blank,
+ # but we're going to set it later using the cert-manager (or potentially a patch if not using cert-manager)
+ caBundle: Cg==
+ service:
+ namespace: system
+ name: webhook-service
+ path: /convert
diff --git a/config/rbac/jindoruntime_editor_role.yaml b/config/rbac/jindoruntime_editor_role.yaml
new file mode 100644
index 00000000000..d659bfbd584
--- /dev/null
+++ b/config/rbac/jindoruntime_editor_role.yaml
@@ -0,0 +1,24 @@
+# permissions for end users to edit jindoruntimes.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: jindoruntime-editor-role
+rules:
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes/status
+ verbs:
+ - get
diff --git a/config/rbac/jindoruntime_viewer_role.yaml b/config/rbac/jindoruntime_viewer_role.yaml
new file mode 100644
index 00000000000..a0f933dd062
--- /dev/null
+++ b/config/rbac/jindoruntime_viewer_role.yaml
@@ -0,0 +1,20 @@
+# permissions for end users to view jindoruntimes.
+apiVersion: rbac.authorization.k8s.io/v1
+kind: ClusterRole
+metadata:
+ name: jindoruntime-viewer-role
+rules:
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes
+ verbs:
+ - get
+ - list
+ - watch
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes/status
+ verbs:
+ - get
diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml
index 08c1d498d90..64fcb9b4183 100644
--- a/config/rbac/role.yaml
+++ b/config/rbac/role.yaml
@@ -46,3 +46,23 @@ rules:
- get
- patch
- update
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes
+ verbs:
+ - create
+ - delete
+ - get
+ - list
+ - patch
+ - update
+ - watch
+- apiGroups:
+ - data.fluid.io
+ resources:
+ - jindoruntimes/status
+ verbs:
+ - get
+ - patch
+ - update
diff --git a/config/samples/data_v1alpha1_jindoruntime.yaml b/config/samples/data_v1alpha1_jindoruntime.yaml
new file mode 100644
index 00000000000..3cb0324140f
--- /dev/null
+++ b/config/samples/data_v1alpha1_jindoruntime.yaml
@@ -0,0 +1,7 @@
+apiVersion: data.fluid.io/v1alpha1
+kind: JindoRuntime
+metadata:
+ name: jindoruntime-sample
+spec:
+ # Add fields here
+ foo: bar
diff --git a/csi/shell/check_mount.sh b/csi/shell/check_mount.sh
index 6db74272b82..f0115339127 100644
--- a/csi/shell/check_mount.sh
+++ b/csi/shell/check_mount.sh
@@ -8,7 +8,7 @@ ConditionPathIsMountPoint="$1"
count=0
# while ! mount | grep alluxio | grep $ConditionPathIsMountPoint | grep -v grep
-while ! mount | grep $ConditionPathIsMountPoint | grep fuse.alluxio-fuse
+while ! mount | grep $ConditionPathIsMountPoint | grep fuse.*-fuse
do
sleep 3
count=`expr $count + 1`
diff --git a/pkg/controllers/v1alpha1/jindo/implement.go b/pkg/controllers/v1alpha1/jindo/implement.go
new file mode 100644
index 00000000000..949bda91447
--- /dev/null
+++ b/pkg/controllers/v1alpha1/jindo/implement.go
@@ -0,0 +1,52 @@
+package jindo
+
+import (
+ "fmt"
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/base"
+ cruntime "github.com/fluid-cloudnative/fluid/pkg/runtime"
+)
+
+const (
+ runtimeType = "jindo"
+ runtimeResourceFinalizerName = "jindo-runtime-controller-finalizer"
+)
+
+// getRuntime gets the runtime
+func (r *RuntimeReconciler) getRuntime(ctx cruntime.ReconcileRequestContext) (*datav1alpha1.JindoRuntime, error) {
+ var runtime datav1alpha1.JindoRuntime
+ if err := r.Get(ctx, ctx.NamespacedName, &runtime); err != nil {
+ return nil, err
+ }
+ return &runtime, nil
+}
+
+// GetOrCreateEngine gets the engine
+func (r *RuntimeReconciler) GetOrCreateEngine(
+ ctx cruntime.ReconcileRequestContext) (engine base.Engine, err error) {
+ found := false
+ id := fmt.Sprintf("%s-%s",
+ ctx.NamespacedName.Namespace,
+ ctx.NamespacedName.Name)
+ r.mutex.Lock()
+ defer r.mutex.Unlock()
+ if engine, found = r.engines[id]; !found {
+ engine, err = ddc.CreateEngine(id,
+ ctx)
+ if err != nil {
+ return nil, err
+ }
+ r.engines[id] = engine
+ r.Log.V(1).Info("Put Engine to engine map")
+ } else {
+ r.Log.V(1).Info("Get Engine from engine map")
+ }
+
+ return engine, err
+}
+
+// RemoveEngine removes the engine
+func (r *RuntimeReconciler) RemoveEngine(ctx cruntime.ReconcileRequestContext) {
+
+}
diff --git a/pkg/controllers/v1alpha1/jindo/jindoruntime_controller.go b/pkg/controllers/v1alpha1/jindo/jindoruntime_controller.go
new file mode 100644
index 00000000000..20bfe18a709
--- /dev/null
+++ b/pkg/controllers/v1alpha1/jindo/jindoruntime_controller.go
@@ -0,0 +1,104 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package jindo
+
+import (
+ "context"
+ "sync"
+
+ "github.com/pkg/errors"
+
+ "github.com/go-logr/logr"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/tools/record"
+ ctrl "sigs.k8s.io/controller-runtime"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ "github.com/fluid-cloudnative/fluid/pkg/common"
+ "github.com/fluid-cloudnative/fluid/pkg/controllers"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/base"
+ cruntime "github.com/fluid-cloudnative/fluid/pkg/runtime"
+ "github.com/fluid-cloudnative/fluid/pkg/utils"
+)
+
+// Use compiler to check if the struct implements all the interface
+var _ controllers.RuntimeReconcilerInterface = (*RuntimeReconciler)(nil)
+
+// RuntimeReconciler reconciles a JindoRuntime object
+type RuntimeReconciler struct {
+ Scheme *runtime.Scheme
+ engines map[string]base.Engine
+ mutex *sync.Mutex
+ *controllers.RuntimeReconciler
+}
+
+// NewRuntimeReconciler create controller for watching runtime custom resources created
+func NewRuntimeReconciler(client client.Client,
+ log logr.Logger,
+ scheme *runtime.Scheme,
+ recorder record.EventRecorder) *RuntimeReconciler {
+ r := &RuntimeReconciler{
+ Scheme: scheme,
+ mutex: &sync.Mutex{},
+ engines: map[string]base.Engine{},
+ }
+ r.RuntimeReconciler = controllers.NewRuntimeReconciler(r, client, log, recorder)
+ return r
+}
+
+//Reconcile reconciles jindo runtime
+// +kubebuilder:rbac:groups=data.fluid.io,resources=jindoruntimes,verbs=get;list;watch;create;update;patch;delete
+// +kubebuilder:rbac:groups=data.fluid.io,resources=jindoruntimes/status,verbs=get;update;patch
+
+func (r *RuntimeReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) {
+ ctx := cruntime.ReconcileRequestContext{
+ Context: context.Background(),
+ Log: r.Log.WithValues("jindoruntime", req.NamespacedName),
+ NamespacedName: req.NamespacedName,
+ Recorder: r.Recorder,
+ Category: common.AccelerateCategory,
+ RuntimeType: runtimeType,
+ Client: r.Client,
+ FinalizerName: runtimeResourceFinalizerName,
+ }
+
+ ctx.Log.V(1).Info("process the request", "request", req)
+
+ // 1.Load the Runtime
+ runtime, err := r.getRuntime(ctx)
+ if err != nil {
+ if utils.IgnoreNotFound(err) == nil {
+ ctx.Log.V(1).Info("The runtime is not found", "runtime", ctx.NamespacedName)
+ return ctrl.Result{}, nil
+ } else {
+ ctx.Log.Error(err, "Failed to get the ddc runtime")
+ return utils.RequeueIfError(errors.Wrap(err, "Unable to get ddc runtime"))
+ }
+ }
+ ctx.Runtime = runtime
+ ctx.Log.V(1).Info("process the runtime", "runtime", ctx.Runtime)
+
+ // reconcile the implement
+ return r.ReconcileInternal(ctx)
+}
+
+//SetupWithManager setups the manager with RuntimeReconciler
+func (r *RuntimeReconciler) SetupWithManager(mgr ctrl.Manager) error {
+ return ctrl.NewControllerManagedBy(mgr).
+ For(&datav1alpha1.JindoRuntime{}).
+ Complete(r)
+}
diff --git a/pkg/controllers/v1alpha1/jindo/suite_test.go b/pkg/controllers/v1alpha1/jindo/suite_test.go
new file mode 100644
index 00000000000..d76ba5f4fcc
--- /dev/null
+++ b/pkg/controllers/v1alpha1/jindo/suite_test.go
@@ -0,0 +1,80 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package jindo
+
+import (
+ "path/filepath"
+ "testing"
+
+ . "github.com/onsi/ginkgo"
+ . "github.com/onsi/gomega"
+ "k8s.io/client-go/kubernetes/scheme"
+ "k8s.io/client-go/rest"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+ "sigs.k8s.io/controller-runtime/pkg/envtest"
+ "sigs.k8s.io/controller-runtime/pkg/envtest/printer"
+ logf "sigs.k8s.io/controller-runtime/pkg/log"
+ "sigs.k8s.io/controller-runtime/pkg/log/zap"
+
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ // +kubebuilder:scaffold:imports
+)
+
+// These tests use Ginkgo (BDD-style Go testing framework). Refer to
+// http://onsi.github.io/ginkgo/ to learn more about Ginkgo.
+
+var cfg *rest.Config
+var k8sClient client.Client
+var testEnv *envtest.Environment
+
+func TestAPIs(t *testing.T) {
+ RegisterFailHandler(Fail)
+
+ RunSpecsWithDefaultAndCustomReporters(t,
+ "Controller Suite",
+ []Reporter{printer.NewlineReporter{}})
+}
+
+var _ = BeforeSuite(func(done Done) {
+ logf.SetLogger(zap.LoggerTo(GinkgoWriter, true))
+
+ By("bootstrapping test environment")
+ testEnv = &envtest.Environment{
+ CRDDirectoryPaths: []string{filepath.Join("..", "config", "crd", "bases")},
+ }
+
+ var err error
+ cfg, err = testEnv.Start()
+ Expect(err).ToNot(HaveOccurred())
+ Expect(cfg).ToNot(BeNil())
+
+ err = datav1alpha1.AddToScheme(scheme.Scheme)
+ Expect(err).NotTo(HaveOccurred())
+
+ // +kubebuilder:scaffold:scheme
+
+ k8sClient, err = client.New(cfg, client.Options{Scheme: scheme.Scheme})
+ Expect(err).ToNot(HaveOccurred())
+ Expect(k8sClient).ToNot(BeNil())
+
+ close(done)
+}, 60)
+
+var _ = AfterSuite(func() {
+ By("tearing down the test environment")
+ err := testEnv.Stop()
+ Expect(err).ToNot(HaveOccurred())
+})
diff --git a/pkg/ddc/factory.go b/pkg/ddc/factory.go
index eb7822cc017..9e5b61dea84 100644
--- a/pkg/ddc/factory.go
+++ b/pkg/ddc/factory.go
@@ -15,6 +15,7 @@ package ddc
import (
"github.com/fluid-cloudnative/fluid/pkg/ddc/alluxio"
"github.com/fluid-cloudnative/fluid/pkg/ddc/base"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/jindo"
cruntime "github.com/fluid-cloudnative/fluid/pkg/runtime"
"fmt"
@@ -27,6 +28,7 @@ var buildFuncMap map[string]buildFunc
func init() {
buildFuncMap = map[string]buildFunc{
"alluxio": alluxio.Build,
+ "jindo": jindo.Build,
}
}
diff --git a/pkg/ddc/jindo/create_volume.go b/pkg/ddc/jindo/create_volume.go
new file mode 100644
index 00000000000..1dce0c6ff02
--- /dev/null
+++ b/pkg/ddc/jindo/create_volume.go
@@ -0,0 +1,126 @@
+package jindo
+
+import (
+ "context"
+ "github.com/fluid-cloudnative/fluid/pkg/utils/kubeclient"
+ corev1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/api/resource"
+ metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+)
+
+
+
+var (
+ expectedAnnotations = map[string]string{
+ "CreatedBy": "fluid",
+ }
+)
+
+// CreateVolume creates volume
+func (e *JindoEngine) CreateVolume() (err error) {
+ if e.runtime == nil {
+ e.runtime, err = e.getRuntime()
+ if err != nil {
+ return
+ }
+ }
+
+ err = e.createFusePersistentVolume()
+ if err != nil {
+ return err
+ }
+
+ err = e.createFusePersistentVolumeClaim()
+ if err != nil {
+ return err
+ }
+
+
+ return nil
+
+}
+
+// createFusePersistentVolume
+func (e *JindoEngine) createFusePersistentVolume() (err error) {
+
+
+ mountPath := "/mnt/jfs"
+
+
+ found, err := kubeclient.IsPersistentVolumeExist(e.Client, e.runtime.Name, expectedAnnotations)
+ if err != nil {
+ return err
+ }
+
+ if !found {
+ pv := &corev1.PersistentVolume{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: e.runtime.Name,
+ Namespace: e.runtime.Namespace,
+ Annotations: expectedAnnotations,
+ },
+ Spec: corev1.PersistentVolumeSpec{
+ AccessModes: []corev1.PersistentVolumeAccessMode{
+ corev1.ReadWriteMany,
+ },
+ Capacity: corev1.ResourceList{
+ corev1.ResourceStorage: resource.MustParse("100Gi"),
+ },
+ PersistentVolumeSource: corev1.PersistentVolumeSource{
+ CSI: &corev1.CSIPersistentVolumeSource{
+ Driver: "fuse.csi.fluid.io",
+ VolumeHandle: e.runtime.Name,
+ VolumeAttributes: map[string]string{
+ "fluid_path": mountPath,
+ },
+ },
+ },
+ },
+ }
+
+ err = e.Client.Create(context.TODO(), pv)
+ if err != nil {
+ return err
+ }
+ } else {
+ e.Log.Info("The persistent volume is created", "name", e.runtime.Name)
+ }
+
+ return err
+}
+
+// createFusePersistentVolume
+func (e *JindoEngine) createFusePersistentVolumeClaim() (err error) {
+
+ found, err := kubeclient.IsPersistentVolumeClaimExist(e.Client, e.runtime.Name, e.runtime.Namespace, expectedAnnotations)
+ if err != nil {
+ return err
+ }
+
+ if !found {
+ pvc := &corev1.PersistentVolumeClaim{
+ ObjectMeta: metav1.ObjectMeta{
+ Name: e.runtime.Name,
+ Namespace: e.runtime.Namespace,
+ Annotations: expectedAnnotations,
+ },
+ Spec: corev1.PersistentVolumeClaimSpec{
+ AccessModes: []corev1.PersistentVolumeAccessMode{
+ corev1.ReadWriteMany,
+ },
+ Resources: corev1.ResourceRequirements{
+ Requests: corev1.ResourceList{
+ corev1.ResourceStorage: resource.MustParse("100Gi"),
+ },
+ },
+ },
+ }
+
+ err = e.Client.Create(context.TODO(), pvc)
+ if err != nil {
+ return err
+ }
+ }
+
+ return err
+}
diff --git a/pkg/ddc/jindo/dataset.go b/pkg/ddc/jindo/dataset.go
new file mode 100644
index 00000000000..ff674bf5a38
--- /dev/null
+++ b/pkg/ddc/jindo/dataset.go
@@ -0,0 +1,30 @@
+package jindo
+
+import (
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ "github.com/fluid-cloudnative/fluid/pkg/utils"
+ "k8s.io/client-go/util/retry"
+ "context"
+)
+
+func (e *JindoEngine) UpdateDatasetStatus(phase datav1alpha1.DatasetPhase) (err error) {
+ err = retry.RetryOnConflict(retry.DefaultBackoff, func() error {
+ dataset, err := utils.GetDataset(e.Client, e.name, e.namespace)
+ if err != nil {
+ return err
+ }
+ datasetToUpdate := dataset.DeepCopy()
+ datasetToUpdate.Status.Phase = phase
+ err = e.Client.Status().Update(context.TODO(), datasetToUpdate)
+ if err != nil {
+ e.Log.Error(err, "Update dataset")
+ return err
+ }
+ return nil
+ })
+ return nil
+}
+
+func (e *JindoEngine) UpdateCacheOfDataset() (err error) {
+ return
+}
\ No newline at end of file
diff --git a/pkg/ddc/jindo/delete_volume.go b/pkg/ddc/jindo/delete_volume.go
new file mode 100644
index 00000000000..264e4dde674
--- /dev/null
+++ b/pkg/ddc/jindo/delete_volume.go
@@ -0,0 +1,5 @@
+package jindo
+
+func (e *JindoEngine) DeleteVolume() (err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/engine.go b/pkg/ddc/jindo/engine.go
new file mode 100644
index 00000000000..b21fccffcfc
--- /dev/null
+++ b/pkg/ddc/jindo/engine.go
@@ -0,0 +1,52 @@
+package jindo
+
+import (
+ "fmt"
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ "github.com/fluid-cloudnative/fluid/pkg/ddc/base"
+ cruntime "github.com/fluid-cloudnative/fluid/pkg/runtime"
+ "github.com/fluid-cloudnative/fluid/pkg/utils/kubeclient"
+ "github.com/go-logr/logr"
+ "sigs.k8s.io/controller-runtime/pkg/client"
+)
+
+type JindoEngine struct {
+ runtime *datav1alpha1.JindoRuntime
+ name string
+ namespace string
+ runtimeType string
+ Log logr.Logger
+ client.Client
+ //When reaching this gracefulShutdownLimits, the system is forced to clean up.
+ gracefulShutdownLimits int32
+ retryShutdown int32
+ initImage string
+}
+
+func Build(id string, ctx cruntime.ReconcileRequestContext) (base.Engine, error) {
+ engine := &JindoEngine{
+ name: ctx.Name,
+ namespace: ctx.Namespace,
+ Client: ctx.Client,
+ Log: ctx.Log,
+ runtimeType: ctx.RuntimeType,
+ gracefulShutdownLimits: 5,
+ retryShutdown: 0,
+ }
+ // var implement base.Implement = engine
+ // engine.TemplateEngine = template
+ if ctx.Runtime != nil {
+ runtime, ok := ctx.Runtime.(*datav1alpha1.JindoRuntime)
+ if !ok {
+ return nil, fmt.Errorf("engine %s is failed to parse", ctx.Name)
+ }
+ engine.runtime = runtime
+ } else {
+ return nil, fmt.Errorf("engine %s is failed to parse", ctx.Name)
+ }
+
+ template := base.NewTemplateEngine(engine, id, ctx)
+
+ err := kubeclient.EnsureNamespace(ctx.Client, ctx.Namespace)
+ return template, err
+}
diff --git a/pkg/ddc/jindo/health_check.go b/pkg/ddc/jindo/health_check.go
new file mode 100644
index 00000000000..9f3b20bed54
--- /dev/null
+++ b/pkg/ddc/jindo/health_check.go
@@ -0,0 +1,5 @@
+package jindo
+
+func (e *JindoEngine) CheckRuntimeHealthy() (err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/master.go b/pkg/ddc/jindo/master.go
new file mode 100644
index 00000000000..4dc54b1c0de
--- /dev/null
+++ b/pkg/ddc/jindo/master.go
@@ -0,0 +1,49 @@
+package jindo
+
+import (
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ apierrs "k8s.io/apimachinery/pkg/api/errors"
+)
+
+func (e *JindoEngine) CheckMasterReady() (ready bool, err error) {
+ return true, nil
+}
+
+// ShouldSetupMaster checks if we need setup the master
+func (e *JindoEngine) ShouldSetupMaster() (should bool, err error) {
+ runtime, err := e.getRuntime()
+ if err != nil {
+ return
+ }
+
+ switch runtime.Status.MasterPhase {
+ case datav1alpha1.RuntimePhaseNone:
+ should = true
+ default:
+ should = false
+ }
+
+ return
+}
+
+// SetupMaster setups the master and updates the status
+// It will print the information in the Debug window according to the Master status
+// It return any cache error encountered
+func (e *JindoEngine) SetupMaster() (err error) {
+
+ // Setup the Jindo cluster
+ master, err := e.getMasterStatefulset(e.name+"-jindofs-master", e.namespace)
+ if err != nil && apierrs.IsNotFound(err) {
+ //1. Is not found error
+ e.Log.V(1).Info("SetupMaster", "master", e.name+"-master")
+ return e.setupMasterInernal()
+ } else if err != nil {
+ //2. Other errors
+ return
+ } else {
+ //3.The master has been set up
+ e.Log.V(1).Info("The master has been set.", "replicas", master.Status.ReadyReplicas)
+ }
+
+ return nil
+}
diff --git a/pkg/ddc/jindo/master_internal.go b/pkg/ddc/jindo/master_internal.go
new file mode 100644
index 00000000000..8603afae4c1
--- /dev/null
+++ b/pkg/ddc/jindo/master_internal.go
@@ -0,0 +1,55 @@
+package jindo
+
+import (
+ "fmt"
+ "github.com/fluid-cloudnative/fluid/pkg/utils/helm"
+ "github.com/fluid-cloudnative/fluid/pkg/utils/kubeclient"
+ "gopkg.in/yaml.v2"
+ "io/ioutil"
+ "os"
+)
+
+func (e *JindoEngine) setupMasterInernal() (err error) {
+ valuefileName, err := e.generateAlluxioValueFile()
+ if err != nil {
+ return
+ }
+ found, err := helm.CheckRelease(e.name, e.namespace)
+ if err != nil {
+ return
+ }
+ if found {
+ e.Log.Info("The release is already installed", "name", e.name, "namespace", e.namespace)
+ return
+ }
+
+ return helm.InstallRelease(e.name, e.namespace, valuefileName, "/charts/jindo")
+}
+
+func (e *JindoEngine) generateAlluxioValueFile() (valueFileName string, err error) {
+ err = kubeclient.DeleteConfigMap(e.Client, e.name + "-jindofs-config", e.namespace)
+ if err != nil {
+ e.Log.Error(err, "Failed to clean value files")
+ }
+ value, err := e.transform(e.runtime)
+ if err != nil {
+ return
+ }
+ data, err := yaml.Marshal(value)
+ if err != nil {
+ return
+ }
+ valueFile, err := ioutil.TempFile(os.TempDir(), fmt.Sprintf("%s-%s-values.yaml", e.name, e.runtimeType))
+ if err != nil {
+ e.Log.Error(err, "failed to create value file", "valueFile", valueFile.Name())
+ return valueFileName, err
+ }
+ valueFileName = valueFile.Name()
+ e.Log.V(1).Info("Save the values file", "valueFile", valueFileName)
+
+ err = ioutil.WriteFile(valueFileName, data, 0400)
+ if err != nil {
+ return
+ }
+ return valueFileName, err
+}
diff --git a/pkg/ddc/jindo/metadata.go b/pkg/ddc/jindo/metadata.go
new file mode 100644
index 00000000000..009e149f0b3
--- /dev/null
+++ b/pkg/ddc/jindo/metadata.go
@@ -0,0 +1,5 @@
+package jindo
+
+func (e *JindoEngine) SyncMetadata() (err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/node.go b/pkg/ddc/jindo/node.go
new file mode 100644
index 00000000000..8854fd42401
--- /dev/null
+++ b/pkg/ddc/jindo/node.go
@@ -0,0 +1,5 @@
+package jindo
+
+func (e *JindoEngine) AssignNodesToCache(desiredNum int32) (currentScheduleNum int32, err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/replicas.go b/pkg/ddc/jindo/replicas.go
new file mode 100644
index 00000000000..19b9354b7cd
--- /dev/null
+++ b/pkg/ddc/jindo/replicas.go
@@ -0,0 +1,7 @@
+package jindo
+
+import cruntime "github.com/fluid-cloudnative/fluid/pkg/runtime"
+
+func (e JindoEngine) SyncReplicas(ctx cruntime.ReconcileRequestContext) (err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/shutdown.go b/pkg/ddc/jindo/shutdown.go
new file mode 100644
index 00000000000..5bb75c00df5
--- /dev/null
+++ b/pkg/ddc/jindo/shutdown.go
@@ -0,0 +1,5 @@
+package jindo
+
+func (e *JindoEngine) Shutdown() (err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/status.go b/pkg/ddc/jindo/status.go
new file mode 100644
index 00000000000..49fbe8fd513
--- /dev/null
+++ b/pkg/ddc/jindo/status.go
@@ -0,0 +1,6 @@
+package jindo
+
+func (e *JindoEngine) CheckAndUpdateRuntimeStatus() (ready bool, err error) {
+ ready = true
+ return ready, nil
+}
diff --git a/pkg/ddc/jindo/transform.go b/pkg/ddc/jindo/transform.go
new file mode 100644
index 00000000000..faec0157ab3
--- /dev/null
+++ b/pkg/ddc/jindo/transform.go
@@ -0,0 +1,126 @@
+package jindo
+
+import (
+
+ "fmt"
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ "github.com/fluid-cloudnative/fluid/pkg/utils"
+ "strings"
+)
+
+func (e *JindoEngine) transform(runtime *datav1alpha1.JindoRuntime) (value *Jindo, err error) {
+ if runtime == nil {
+ err = fmt.Errorf("The jindoRuntime is null")
+ return
+ }
+
+ value = &Jindo{
+ Image: "registry.cn-shanghai.aliyuncs.com/jindofs/smartdata",
+ ImageTag:"2.7.4",
+ ImagePullPolicy:"Always",
+ FuseImage:"registry.cn-shanghai.aliyuncs.com/jindofs/jindo-fuse",
+ FuseImageTag:"2.7.4",
+ User:0,
+ Group:0,
+ FsGroup:0,
+ UseHostNetwork:true,
+ UseHostPID:true,
+ Properties:map[string]string{
+ "logDir": "/mnt/disk1/bigboot/log",
+ },
+ Master: Master{
+ ReplicaCount: 1,
+ Resources: Resources{
+ Limits: Resource{
+ CPU: "4",
+ Memory: "16G",
+ },
+ Requests: Resource{
+ CPU: "1",
+ Memory: "1G",
+ },
+ },
+ NodeSelector: map[string]string{},
+ MasterProperties: e.transformMaster(),
+ },
+ Worker: Worker{
+ Resources: Resources{
+ Limits: Resource{
+ CPU: "4",
+ Memory: "8G",
+ },
+ Requests: Resource{
+ CPU: "1",
+ Memory: "1G",
+ },
+ },
+ NodeSelector: map[string]string{},
+ WorkerProperties: e.transformWorker(),
+ },
+ Fuse: Fuse{
+ Args: nil,
+ HostPath: "/mnt/jfs",
+ NodeSelector: map[string]string{},
+ FuseProperties: e.transformFuse(),
+ },
+
+ }
+ return value, nil
+
+}
+
+func (e *JindoEngine) transformMaster() map[string]string {
+ properties := map[string]string{
+ "namespace.rpc.port": "8101",
+ "namespace.meta-dir": "/mnt/disk1/bigboot/server",
+ "namespace.filelet.cache.size": "100000",
+ "namespace.blocklet.cache.size": "1000000",
+ "namespace.backend.type": "rocksdb",
+ }
+ dataset, err := utils.GetDataset(e.Client, e.name, e.namespace)
+ if err != nil{
+ return properties
+ }
+ jfsNamespace := ""
+ for _, mount := range dataset.Spec.Mounts{
+ if !strings.HasPrefix(mount.MountPoint, "oss://"){
+ continue
+ }
+ jfsNamespace = jfsNamespace + mount.Name + ","
+ properties["jfs.namespaces." + mount.Name + ".oss.uri"] = mount.MountPoint + "." + mount.Options["fs.oss.endpoint"]
+ properties["jfs.namespaces." + mount.Name + ".oss.access.key"] = mount.Options["fs.oss.accessKeyId"]
+ properties["jfs.namespaces." + mount.Name + ".oss.access.secret"] = mount.Options["fs.oss.accessKeySecret"]
+ }
+ if strings.HasSuffix(jfsNamespace,","){
+ jfsNamespace = strings.TrimRight(jfsNamespace,",")
+ }
+ properties["jfs.namespaces"] = jfsNamespace
+ return properties
+}
+
+
+func (e *JindoEngine) transformWorker() map[string]string {
+ properties := map[string]string{
+ "storage.rpc.port" : "6101",
+ "storage.data-dirs" : "/mnt/disk1/bigboot, /mnt/disk2/bigboot, /mnt/disk3/bigboot",
+ "storage.temp-data-dirs" : "/mnt/disk1/bigboot/tmp",
+ "storage.watermark.high.ratio": "0.4",
+ "storage.watermark.low.ratio" : "0.2",
+ "storage.data-dirs.capacities": "80g,80g,80g",
+ "storage.meta-dir" : "/mnt/disk1/bigboot/bignode",
+ }
+ return properties
+}
+
+func (e *JindoEngine) transformFuse() map[string]int {
+ properties := map[string]int{
+ "client.storage.rpc.port" : 6101,
+ "client.oss.retry" : 5,
+ "client.oss.upload.threads" : 4,
+ "client.oss.upload.queue.size" : 5,
+ "client.oss.upload.max.parallelism" : 16,
+ "client.oss.timeout.millisecond" : 30000,
+ "client.oss.connection.timeout.millisecond" : 3000,
+ }
+ return properties
+}
\ No newline at end of file
diff --git a/pkg/ddc/jindo/types.go b/pkg/ddc/jindo/types.go
new file mode 100644
index 00000000000..0966e42a35e
--- /dev/null
+++ b/pkg/ddc/jindo/types.go
@@ -0,0 +1,62 @@
+package jindo
+
+type Jindo struct {
+ Image string `yaml:"image"`
+ ImageTag string `yaml:"imageTag"`
+ ImagePullPolicy string `yaml:"imagePullPolicy"`
+ FuseImage string `yaml:"fuseImage"`
+ FuseImageTag string `yaml:"fuseImageTag"`
+ User int `yaml:"user"`
+ Group int `yaml:"group"`
+ FsGroup int `yaml:"fsGroup"`
+ UseHostNetwork bool `yaml:"useHostNetwork"`
+ UseHostPID bool `yaml:"useHostPID"`
+ Properties map[string]string `yaml:"properties"`
+ Master Master `yaml:"master"`
+ Worker Worker `yaml:"worker"`
+ Fuse Fuse `yaml:"fuse"`
+ Mounts Mounts `yaml:"mounts"`
+}
+
+type Master struct {
+ ReplicaCount int `yaml:"replicaCount"`
+ Resources Resources `yaml:"resources"`
+ NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
+ MasterProperties map[string]string `yaml:"properties"`
+}
+
+type Worker struct {
+ Resources Resources `yaml:"resources"`
+ NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
+ WorkerProperties map[string]string `yaml:"properties"`
+}
+
+type Fuse struct {
+ Args []string `yaml:"args"`
+ HostPath string `yaml:"hostPath"`
+ NodeSelector map[string]string `yaml:"nodeSelector,omitempty"`
+ FuseProperties map[string]int `yaml:"properties"`
+}
+
+type Mounts struct {
+ Master []string `yaml:"master"`
+ WorkersAndClients []string `yaml:"workersAndClients"`
+}
+
+type Resources struct {
+ Limits Resource `yaml:"limits"`
+ Requests Resource `yaml:"requests"`
+}
+
+type Resource struct {
+ CPU string `yaml:"cpu"`
+ Memory string `yaml:"memory"`
+}
+
+
+
+
+
+
+
+
diff --git a/pkg/ddc/jindo/ufs.go b/pkg/ddc/jindo/ufs.go
new file mode 100644
index 00000000000..c8d4f150fa7
--- /dev/null
+++ b/pkg/ddc/jindo/ufs.go
@@ -0,0 +1,35 @@
+package jindo
+
+// ShouldCheckUFS checks if it requires checking UFS
+func (e *JindoEngine) ShouldCheckUFS() (should bool, err error) {
+ should = true
+ return
+}
+
+// PrepareUFS do all the UFS preparations
+func (e *JindoEngine) PrepareUFS() (err error) {
+ // For Jindo Engine, not need to prepare UFS
+ return
+}
+
+// UsedStorageBytes returns used storage size of Alluxio in bytes
+func (e *JindoEngine) UsedStorageBytes() (value int64, err error) {
+
+ return
+}
+
+// FreeStorageBytes returns free storage size of Alluxio in bytes
+func (e *JindoEngine) FreeStorageBytes() (value int64, err error) {
+
+ return
+}
+
+// return total storage size of Alluxio in bytes
+func (e *JindoEngine) TotalStorageBytes() (value int64, err error) {
+ return
+}
+
+// return the total num of files in Alluxio
+func (e *JindoEngine) TotalFileNums() (value int64, err error) {
+ return
+}
diff --git a/pkg/ddc/jindo/utils.go b/pkg/ddc/jindo/utils.go
new file mode 100644
index 00000000000..2fd14b01a7c
--- /dev/null
+++ b/pkg/ddc/jindo/utils.go
@@ -0,0 +1,33 @@
+package jindo
+
+import (
+ "context"
+ datav1alpha1 "github.com/fluid-cloudnative/fluid/api/v1alpha1"
+ appsv1 "k8s.io/api/apps/v1"
+ "k8s.io/apimachinery/pkg/types"
+)
+
+// getRuntime gets the jindo runtime
+func (e *JindoEngine) getRuntime() (*datav1alpha1.JindoRuntime, error) {
+
+ key := types.NamespacedName{
+ Name: e.name,
+ Namespace: e.namespace,
+ }
+
+ var runtime datav1alpha1.JindoRuntime
+ if err := e.Get(context.TODO(), key, &runtime); err != nil {
+ return nil, err
+ }
+ return &runtime, nil
+}
+
+func (e *JindoEngine) getMasterStatefulset(name string, namespace string) (master *appsv1.StatefulSet, err error) {
+ master = &appsv1.StatefulSet{}
+ err = e.Client.Get(context.TODO(), types.NamespacedName{
+ Namespace: namespace,
+ Name: name,
+ }, master)
+
+ return master, err
+}
diff --git a/pkg/ddc/jindo/worker.go b/pkg/ddc/jindo/worker.go
new file mode 100644
index 00000000000..b535e06744a
--- /dev/null
+++ b/pkg/ddc/jindo/worker.go
@@ -0,0 +1,33 @@
+/*
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package jindo
+
+// SetupWorkers checks the desired and current replicas of workers and makes an update
+// over the status by setting phases and conditions. The function
+// calls for a status update and finally returns error if anything unexpected happens.
+func (e *JindoEngine) SetupWorkers() (err error) {
+ return
+}
+
+// ShouldSetupWorkers checks if we need setup the workers
+func (e *JindoEngine) ShouldSetupWorkers() (should bool, err error) {
+ return true, nil
+}
+
+// are the workers ready
+func (e *JindoEngine) CheckWorkersReady() (ready bool, err error) {
+ return true, nil
+}