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 +}