From 99a0fc2fb862206013828ea5bfb00572f729072b Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 11:46:01 +0800 Subject: [PATCH 01/18] feat: support hadoop and hbase addons on KubeBlocks 1.1 - add addons/hadoop and addons/hbase - add addons-cluster/hadoop and addons-cluster/hbase --- addons-cluster/hadoop/.helmignore | 23 + addons-cluster/hadoop/Chart.yaml | 25 ++ addons-cluster/hadoop/releases_notes.yaml | 7 + addons-cluster/hadoop/templates/_helpers.tpl | 10 + addons-cluster/hadoop/templates/cluster.yaml | 223 ++++++++++ addons-cluster/hadoop/values.schema.json | 178 ++++++++ addons-cluster/hadoop/values.yaml | 120 ++++++ addons-cluster/hbase/.helmignore | 23 + addons-cluster/hbase/Chart.yaml | 25 ++ addons-cluster/hbase/releases_notes.yaml | 10 + addons-cluster/hbase/templates/_helpers.tpl | 10 + addons-cluster/hbase/templates/cluster.yaml | 123 ++++++ addons-cluster/hbase/values.schema.json | 137 ++++++ addons-cluster/hbase/values.yaml | 54 +++ addons/hadoop/.helmignore | 23 + addons/hadoop/Chart.yaml | 27 ++ addons/hadoop/README.md | 34 ++ addons/hadoop/config/core-site-standalone.tpl | 70 ++++ addons/hadoop/config/core-site.tpl | 89 ++++ addons/hadoop/config/dfs.exclude | 3 + addons/hadoop/config/dfs.include | 3 + .../config/hadoop-core-config-constraint.cue | 153 +++++++ addons/hadoop/config/hadoop-env.sh.tpl | 20 + .../config/hadoop-metrics2.properties.tpl | 19 + .../hdfs-datanode-config-constraint.cue | 156 +++++++ .../config/hdfs-datanode-standalone.tpl | 105 +++++ addons/hadoop/config/hdfs-datanode.tpl | 129 ++++++ .../hdfs-journalnode-config-constraint.cue | 75 ++++ addons/hadoop/config/hdfs-journalnode.tpl | 49 +++ .../hdfs-namenode-config-constraint.cue | 252 +++++++++++ .../config/hdfs-namenode-standalone.tpl | 89 ++++ addons/hadoop/config/hdfs-namenode.tpl | 221 ++++++++++ addons/hadoop/config/log4j.properties | 59 +++ addons/hadoop/releases_notes.yaml | 5 + addons/hadoop/scripts/check-data-status.sh | 13 + addons/hadoop/scripts/check-journal-status.sh | 23 + addons/hadoop/scripts/check-name-status.sh | 30 ++ .../hadoop/scripts/datanode-decommission.sh | 39 ++ addons/hadoop/scripts/init-namenode-format.sh | 38 ++ .../scripts/init-nn-bootstrap-standby.sh | 48 +++ addons/hadoop/scripts/init-refresh-nodes.sh | 13 + addons/hadoop/scripts/init-zkfc-format.sh | 13 + addons/hadoop/scripts/start-datanode.sh | 27 ++ addons/hadoop/scripts/start-journalnode.sh | 27 ++ addons/hadoop/scripts/start-namenode.sh | 81 ++++ addons/hadoop/scripts/start-zkfc.sh | 37 ++ addons/hadoop/templates/_helpers.tpl | 102 +++++ .../hadoop/templates/clusterdefinition.yaml | 49 +++ .../cmpd-hadoop-core-standalone.yaml | 82 ++++ addons/hadoop/templates/cmpd-hadoop-core.yaml | 96 +++++ .../cmpd-hdfs-datanode-standalone.yaml | 191 +++++++++ .../hadoop/templates/cmpd-hdfs-datanode.yaml | 203 +++++++++ .../templates/cmpd-hdfs-journalnode.yaml | 180 ++++++++ .../cmpd-hdfs-namenode-standalone.yaml | 229 ++++++++++ .../hadoop/templates/cmpd-hdfs-namenode.yaml | 396 ++++++++++++++++++ addons/hadoop/templates/cmpv-hadoop-core.yaml | 20 + .../hadoop/templates/cmpv-hdfs-datanode.yaml | 21 + .../templates/cmpv-hdfs-journalnode.yaml | 20 + .../hadoop/templates/cmpv-hdfs-namenode.yaml | 21 + .../hadoop-core-config-template.yaml | 19 + ...adoop-core-standalone-config-template.yaml | 19 + .../hdfs-datanode-config-template.yaml | 11 + ...s-datanode-standalone-config-template.yaml | 11 + .../hdfs-journalnode-config-template.yaml | 11 + .../hdfs-namenode-config-template.yaml | 11 + ...s-namenode-standalone-config-template.yaml | 11 + .../templates/hdfs-scripts-template.yaml | 31 ++ .../templates/paramsdef-hadoop-core.yaml | 12 + .../templates/paramsdef-hdfs-datanode.yaml | 12 + .../templates/paramsdef-hdfs-journalnode.yaml | 12 + .../templates/paramsdef-hdfs-namenode.yaml | 12 + .../templates/pcr-hadoop-core-standalone.yaml | 16 + addons/hadoop/templates/pcr-hadoop-core.yaml | 16 + .../pcr-hdfs-datanode-standalone.yaml | 16 + .../hadoop/templates/pcr-hdfs-datanode.yaml | 16 + .../templates/pcr-hdfs-journalnode.yaml | 16 + .../pcr-hdfs-namenode-standalone.yaml | 16 + .../hadoop/templates/pcr-hdfs-namenode.yaml | 16 + addons/hadoop/templates/scripts.yaml | 0 addons/hadoop/values.yaml | 166 ++++++++ addons/hbase/.helmignore | 23 + addons/hbase/Chart.yaml | 27 ++ addons/hbase/README.md | 144 +++++++ addons/hbase/config/hadoop-core-site.tpl | 78 ++++ .../hadoop-metrics2-hbase.properties.tpl | 4 + addons/hbase/config/hbase-env.sh.tpl | 17 + addons/hbase/config/hbase-site-cluster.tpl | 300 +++++++++++++ addons/hbase/config/hbase-site-standalone.tpl | 138 ++++++ addons/hbase/config/hdfs-client-site.tpl | 53 +++ addons/hbase/config/log4j.properties | 69 +++ addons/hbase/releases_notes.yaml | 9 + addons/hbase/scripts/check-hmaster-status.sh | 18 + .../scripts/check-hregionserver-status.sh | 18 + addons/hbase/scripts/init-hdfs-root-layout.sh | 28 ++ addons/hbase/scripts/start-hmaster.sh | 17 + addons/hbase/scripts/start-hregionserver.sh | 32 ++ addons/hbase/templates/_helpers.tpl | 70 ++++ addons/hbase/templates/clusterdefinition.yaml | 31 ++ .../templates/cmpd-hbase-standalone.yaml | 186 ++++++++ addons/hbase/templates/cmpd-hmaster.yaml | 244 +++++++++++ .../hbase/templates/cmpd-hregionserver.yaml | 207 +++++++++ .../templates/cmpv-hbase-standalone.yaml | 19 + addons/hbase/templates/cmpv-hmaster.yaml | 20 + .../hbase/templates/cmpv-hregionserver.yaml | 19 + .../hbase-cluster-config-template.yaml | 19 + .../templates/hbase-scripts-template.yaml | 17 + .../hbase-standalone-config-template.yaml | 15 + addons/hbase/values.yaml | 72 ++++ 108 files changed, 6892 insertions(+) create mode 100644 addons-cluster/hadoop/.helmignore create mode 100644 addons-cluster/hadoop/Chart.yaml create mode 100644 addons-cluster/hadoop/releases_notes.yaml create mode 100644 addons-cluster/hadoop/templates/_helpers.tpl create mode 100644 addons-cluster/hadoop/templates/cluster.yaml create mode 100644 addons-cluster/hadoop/values.schema.json create mode 100644 addons-cluster/hadoop/values.yaml create mode 100644 addons-cluster/hbase/.helmignore create mode 100644 addons-cluster/hbase/Chart.yaml create mode 100644 addons-cluster/hbase/releases_notes.yaml create mode 100644 addons-cluster/hbase/templates/_helpers.tpl create mode 100644 addons-cluster/hbase/templates/cluster.yaml create mode 100644 addons-cluster/hbase/values.schema.json create mode 100644 addons-cluster/hbase/values.yaml create mode 100644 addons/hadoop/.helmignore create mode 100644 addons/hadoop/Chart.yaml create mode 100644 addons/hadoop/README.md create mode 100644 addons/hadoop/config/core-site-standalone.tpl create mode 100644 addons/hadoop/config/core-site.tpl create mode 100644 addons/hadoop/config/dfs.exclude create mode 100644 addons/hadoop/config/dfs.include create mode 100644 addons/hadoop/config/hadoop-core-config-constraint.cue create mode 100644 addons/hadoop/config/hadoop-env.sh.tpl create mode 100644 addons/hadoop/config/hadoop-metrics2.properties.tpl create mode 100644 addons/hadoop/config/hdfs-datanode-config-constraint.cue create mode 100644 addons/hadoop/config/hdfs-datanode-standalone.tpl create mode 100644 addons/hadoop/config/hdfs-datanode.tpl create mode 100644 addons/hadoop/config/hdfs-journalnode-config-constraint.cue create mode 100644 addons/hadoop/config/hdfs-journalnode.tpl create mode 100644 addons/hadoop/config/hdfs-namenode-config-constraint.cue create mode 100644 addons/hadoop/config/hdfs-namenode-standalone.tpl create mode 100644 addons/hadoop/config/hdfs-namenode.tpl create mode 100644 addons/hadoop/config/log4j.properties create mode 100644 addons/hadoop/releases_notes.yaml create mode 100644 addons/hadoop/scripts/check-data-status.sh create mode 100644 addons/hadoop/scripts/check-journal-status.sh create mode 100644 addons/hadoop/scripts/check-name-status.sh create mode 100644 addons/hadoop/scripts/datanode-decommission.sh create mode 100644 addons/hadoop/scripts/init-namenode-format.sh create mode 100644 addons/hadoop/scripts/init-nn-bootstrap-standby.sh create mode 100644 addons/hadoop/scripts/init-refresh-nodes.sh create mode 100644 addons/hadoop/scripts/init-zkfc-format.sh create mode 100644 addons/hadoop/scripts/start-datanode.sh create mode 100644 addons/hadoop/scripts/start-journalnode.sh create mode 100644 addons/hadoop/scripts/start-namenode.sh create mode 100644 addons/hadoop/scripts/start-zkfc.sh create mode 100644 addons/hadoop/templates/_helpers.tpl create mode 100644 addons/hadoop/templates/clusterdefinition.yaml create mode 100644 addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml create mode 100644 addons/hadoop/templates/cmpd-hadoop-core.yaml create mode 100644 addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml create mode 100644 addons/hadoop/templates/cmpd-hdfs-datanode.yaml create mode 100644 addons/hadoop/templates/cmpd-hdfs-journalnode.yaml create mode 100644 addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml create mode 100644 addons/hadoop/templates/cmpd-hdfs-namenode.yaml create mode 100644 addons/hadoop/templates/cmpv-hadoop-core.yaml create mode 100644 addons/hadoop/templates/cmpv-hdfs-datanode.yaml create mode 100644 addons/hadoop/templates/cmpv-hdfs-journalnode.yaml create mode 100644 addons/hadoop/templates/cmpv-hdfs-namenode.yaml create mode 100644 addons/hadoop/templates/hadoop-core-config-template.yaml create mode 100644 addons/hadoop/templates/hadoop-core-standalone-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-datanode-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-datanode-standalone-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-journalnode-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-namenode-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-namenode-standalone-config-template.yaml create mode 100644 addons/hadoop/templates/hdfs-scripts-template.yaml create mode 100644 addons/hadoop/templates/paramsdef-hadoop-core.yaml create mode 100644 addons/hadoop/templates/paramsdef-hdfs-datanode.yaml create mode 100644 addons/hadoop/templates/paramsdef-hdfs-journalnode.yaml create mode 100644 addons/hadoop/templates/paramsdef-hdfs-namenode.yaml create mode 100644 addons/hadoop/templates/pcr-hadoop-core-standalone.yaml create mode 100644 addons/hadoop/templates/pcr-hadoop-core.yaml create mode 100644 addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml create mode 100644 addons/hadoop/templates/pcr-hdfs-datanode.yaml create mode 100644 addons/hadoop/templates/pcr-hdfs-journalnode.yaml create mode 100644 addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml create mode 100644 addons/hadoop/templates/pcr-hdfs-namenode.yaml create mode 100644 addons/hadoop/templates/scripts.yaml create mode 100644 addons/hadoop/values.yaml create mode 100644 addons/hbase/.helmignore create mode 100644 addons/hbase/Chart.yaml create mode 100644 addons/hbase/README.md create mode 100644 addons/hbase/config/hadoop-core-site.tpl create mode 100644 addons/hbase/config/hadoop-metrics2-hbase.properties.tpl create mode 100644 addons/hbase/config/hbase-env.sh.tpl create mode 100644 addons/hbase/config/hbase-site-cluster.tpl create mode 100644 addons/hbase/config/hbase-site-standalone.tpl create mode 100644 addons/hbase/config/hdfs-client-site.tpl create mode 100644 addons/hbase/config/log4j.properties create mode 100644 addons/hbase/releases_notes.yaml create mode 100644 addons/hbase/scripts/check-hmaster-status.sh create mode 100644 addons/hbase/scripts/check-hregionserver-status.sh create mode 100644 addons/hbase/scripts/init-hdfs-root-layout.sh create mode 100644 addons/hbase/scripts/start-hmaster.sh create mode 100644 addons/hbase/scripts/start-hregionserver.sh create mode 100644 addons/hbase/templates/_helpers.tpl create mode 100644 addons/hbase/templates/clusterdefinition.yaml create mode 100644 addons/hbase/templates/cmpd-hbase-standalone.yaml create mode 100644 addons/hbase/templates/cmpd-hmaster.yaml create mode 100644 addons/hbase/templates/cmpd-hregionserver.yaml create mode 100644 addons/hbase/templates/cmpv-hbase-standalone.yaml create mode 100644 addons/hbase/templates/cmpv-hmaster.yaml create mode 100644 addons/hbase/templates/cmpv-hregionserver.yaml create mode 100644 addons/hbase/templates/hbase-cluster-config-template.yaml create mode 100644 addons/hbase/templates/hbase-scripts-template.yaml create mode 100644 addons/hbase/templates/hbase-standalone-config-template.yaml create mode 100644 addons/hbase/values.yaml diff --git a/addons-cluster/hadoop/.helmignore b/addons-cluster/hadoop/.helmignore new file mode 100644 index 0000000000..691fa13d6a --- /dev/null +++ b/addons-cluster/hadoop/.helmignore @@ -0,0 +1,23 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/addons-cluster/hadoop/Chart.yaml b/addons-cluster/hadoop/Chart.yaml new file mode 100644 index 0000000000..2979cdb6d8 --- /dev/null +++ b/addons-cluster/hadoop/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + category: BigData + kubeblocks.io/min-version: "1.1.0" +apiVersion: v2 +name: hadoop +type: application +version: 1.1.0-alpha.0 +description: A Hadoop HDFS cluster Helm chart for KubeBlocks. +dependencies: + - name: kblib + version: 0.1.2 + repository: file://../kblib + alias: extra +appVersion: "3.3.4" +keywords: + - hadoop + - hdfs + - bigdata +home: https://github.com/apecloud/kubeblocks/tree/main/deploy/hadoop +icon: https://kubeblocks.io/img/logo.png +maintainers: + - name: ApeCloud + url: https://kubeblocks.io/ +sources: + - https://github.com/apecloud/kubeblocks/ diff --git a/addons-cluster/hadoop/releases_notes.yaml b/addons-cluster/hadoop/releases_notes.yaml new file mode 100644 index 0000000000..c07f490f76 --- /dev/null +++ b/addons-cluster/hadoop/releases_notes.yaml @@ -0,0 +1,7 @@ +releases: + - version: 1.1.0-alpha.0 + notes: + en: > + Minimum supported KubeBlocks version is 1.1.0. + zh: > + 最低支持的 KubeBlocks 版本为 1.1.0。 diff --git a/addons-cluster/hadoop/templates/_helpers.tpl b/addons-cluster/hadoop/templates/_helpers.tpl new file mode 100644 index 0000000000..73241d78f1 --- /dev/null +++ b/addons-cluster/hadoop/templates/_helpers.tpl @@ -0,0 +1,10 @@ +{{- define "hadoop-cluster.clusterCommon" }} +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: {{ include "kblib.clusterName" . }} + namespace: {{ .Release.Namespace }} + labels: {{ include "kblib.clusterLabels" . | nindent 4 }} +spec: + terminationPolicy: {{ .Values.extra.terminationPolicy }} +{{- end }} \ No newline at end of file diff --git a/addons-cluster/hadoop/templates/cluster.yaml b/addons-cluster/hadoop/templates/cluster.yaml new file mode 100644 index 0000000000..6a4d44947b --- /dev/null +++ b/addons-cluster/hadoop/templates/cluster.yaml @@ -0,0 +1,223 @@ +{{- $isCluster := eq .Values.topology "cluster" }} +{{- $isStandalone := eq .Values.topology "standalone" }} +{{- if not (or $isCluster $isStandalone) }} +{{- fail "topology must be either 'cluster' or 'standalone'" }} +{{- end }} +{{- include "hadoop-cluster.clusterCommon" . }} + clusterDef: hadoop + topology: {{ .Values.topology }} + componentSpecs: + - name: hadoop-core + componentDef: {{ ternary "hadoop-core" "hadoop-core-standalone" $isCluster }} +{{- if $isCluster }} + serviceRefs: + - name: hadoopZookeeper + namespace: {{ .Values.serviceRefs.hadoopZookeeper.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.port }} + configs: + - name: hadoop-core-config + variables: + HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + HDFS_ZKFC_HEAP: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} + HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} + HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} +{{- else }} + configs: + - name: hadoop-core-config + variables: + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} + HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + HDFS_ZKFC_HEAP: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} + HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} +{{- end }} + replicas: {{ .Values.replicas.core }} + resources: + requests: + cpu: {{ .Values.resources.core.requests.cpu | quote }} + memory: {{ .Values.resources.core.requests.memory }} + limits: + cpu: {{ .Values.resources.core.limits.cpu | quote }} + memory: {{ .Values.resources.core.limits.memory }} +{{- if $isCluster }} + - name: journalnode + componentDef: hdfs-journalnode + configs: + - name: journalnode-config + variables: + HDFS_JOURNALNODE_EDITS_DIR: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} + HDFS_JOURNALNODE_RPC_PORT: {{ .Values.hdfs.ports.journalnode.rpc | quote }} + HDFS_JOURNALNODE_HTTP_PORT: {{ .Values.hdfs.ports.journalnode.http | quote }} + replicas: {{ .Values.replicas.journalnode }} + resources: + requests: + cpu: {{ .Values.resources.journalnode.requests.cpu | quote }} + memory: {{ .Values.resources.journalnode.requests.memory }} + limits: + cpu: {{ .Values.resources.journalnode.limits.cpu | quote }} + memory: {{ .Values.resources.journalnode.limits.memory }} + schedulingPolicy: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + apps.kubeblocks.io/component-name: journalnode + volumes: + - name: hadoop-core-config + configMap: + name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config + volumeClaimTemplates: + - name: edits-dir + spec: + accessModes: +{{ toYaml .Values.storage.journalnode.accessModes | indent 14 }} + resources: + requests: + storage: {{ .Values.storage.journalnode.size }} +{{- if .Values.storage.journalnode.storageClassName }} + storageClassName: {{ .Values.storage.journalnode.storageClassName }} +{{- end }} +{{- end }} + - name: namenode + componentDef: {{ ternary "hdfs-namenode" "hdfs-namenode-standalone" $isCluster }} +{{- if $isCluster }} + serviceRefs: + - name: hadoopZookeeper + namespace: {{ .Values.serviceRefs.hadoopZookeeper.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.port }} +{{- end }} + configs: + - name: namenode-config + variables: + HDFS_NAMENODE_NAME_DIR: {{ .Values.hdfs.paths.namenodeMetadataDir | quote }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} + HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.ports.namenode.http | quote }} + HDFS_NAMENODE_HANDLER_COUNT: {{ .Values.hdfs.namenode.handlerCount | quote }} + HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissions.enabled | quote }} + HDFS_REGISTRATION_IP_HOSTNAME_CHECK: {{ .Values.hdfs.registration.ipHostnameCheck | quote }} +{{- if $isCluster }} + HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} + HDFS_REPLICATION_MAX: {{ .Values.hdfs.replicationMax | quote }} + HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY: {{ .Values.hdfs.client.replaceDatanodeOnFailurePolicy | quote }} + HDFS_JOURNALNODE_RPC_PORT: {{ .Values.hdfs.ports.journalnode.rpc | quote }} + HDFS_HA_AUTOMATIC_FAILOVER_ENABLED: {{ .Values.hdfs.ha.automaticFailoverEnabled | quote }} + HDFS_HA_FENCING_METHODS: {{ .Values.hdfs.ha.fencingMethods | quote }} + HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} + HDFS_HA_ZOOKEEPER_OPERATION_RETRIES: {{ .Values.hdfs.ha.zookeeper.operationRetries | quote }} +{{- else }} + HDFS_REPLICATION: "1" + HDFS_REPLICATION_MAX: "1" + HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY: "NEVER" +{{- end }} + replicas: {{ ternary (.Values.replicas.namenode | int) 1 $isCluster }} + resources: + requests: + cpu: {{ .Values.resources.namenode.requests.cpu | quote }} + memory: {{ .Values.resources.namenode.requests.memory }} + limits: + cpu: {{ .Values.resources.namenode.limits.cpu | quote }} + memory: {{ .Values.resources.namenode.limits.memory }} +{{- if $isCluster }} + schedulingPolicy: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + apps.kubeblocks.io/component-name: namenode +{{- end }} + volumes: + - name: hadoop-core-config + configMap: + name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config + volumeClaimTemplates: + - name: metadata-dir + spec: + accessModes: +{{ toYaml .Values.storage.namenode.accessModes | indent 14 }} + resources: + requests: + storage: {{ .Values.storage.namenode.size }} +{{- if .Values.storage.namenode.storageClassName }} + storageClassName: {{ .Values.storage.namenode.storageClassName }} +{{- end }} + - name: datanode + componentDef: {{ ternary "hdfs-datanode" "hdfs-datanode-standalone" $isCluster }} + configs: + - name: datanode-config + variables: + HDFS_DATANODE_DATA_DIR: {{ .Values.hdfs.paths.datanodeDataDir | quote }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} + HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.ports.namenode.http | quote }} + HDFS_DATANODE_HANDLER_COUNT: {{ .Values.hdfs.datanode.handlerCount | quote }} + HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissions.enabled | quote }} +{{- if $isCluster }} + HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} + HDFS_REPLICATION_MAX: {{ .Values.hdfs.replicationMax | quote }} + HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY: {{ .Values.hdfs.client.replaceDatanodeOnFailurePolicy | quote }} +{{- else }} + HDFS_REPLICATION: "1" + HDFS_REPLICATION_MAX: "1" + HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY: "NEVER" +{{- end }} + replicas: {{ ternary (.Values.replicas.datanode | int) 1 $isCluster }} + resources: + requests: + cpu: {{ .Values.resources.datanode.requests.cpu | quote }} + memory: {{ .Values.resources.datanode.requests.memory }} + limits: + cpu: {{ .Values.resources.datanode.limits.cpu | quote }} + memory: {{ .Values.resources.datanode.limits.memory }} +{{- if $isCluster }} + schedulingPolicy: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + apps.kubeblocks.io/component-name: datanode +{{- end }} + volumes: + - name: hadoop-core-config + configMap: + name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config + volumeClaimTemplates: + - name: hdfs-data-0 + spec: + accessModes: +{{ toYaml .Values.storage.datanode.accessModes | indent 14 }} + resources: + requests: + storage: {{ .Values.storage.datanode.size }} +{{- if .Values.storage.datanode.storageClassName }} + storageClassName: {{ .Values.storage.datanode.storageClassName }} +{{- end }} diff --git a/addons-cluster/hadoop/values.schema.json b/addons-cluster/hadoop/values.schema.json new file mode 100644 index 0000000000..b0c35f3bda --- /dev/null +++ b/addons-cluster/hadoop/values.schema.json @@ -0,0 +1,178 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "topology": { + "type": "string", + "enum": ["standalone", "cluster"], + "default": "cluster" + }, + "replicas": { + "type": "object", + "properties": { + "core": { "type": "integer", "default": 1, "minimum": 1 }, + "journalnode": { "type": "integer", "default": 3, "minimum": 3 }, + "namenode": { "type": "integer", "default": 2, "minimum": 1, "maximum": 2 }, + "datanode": { "type": "integer", "default": 1, "minimum": 1 } + } + }, + "resources": { + "type": "object", + "properties": { + "core": { "$ref": "#/definitions/resourceSchema" }, + "journalnode": { "$ref": "#/definitions/resourceSchema" }, + "namenode": { "$ref": "#/definitions/resourceSchema" }, + "datanode": { "$ref": "#/definitions/resourceSchema" } + } + }, + "storage": { + "type": "object", + "properties": { + "journalnode": { "$ref": "#/definitions/storageSchema" }, + "namenode": { "$ref": "#/definitions/storageSchema" }, + "datanode": { "$ref": "#/definitions/storageSchema" } + } + }, + "hdfs": { + "type": "object", + "properties": { + "ports": { + "type": "object", + "properties": { + "namenode": { + "type": "object", + "properties": { + "rpc": { "type": "integer", "default": 8020, "minimum": 1, "maximum": 65535 }, + "http": { "type": "integer", "default": 9870, "minimum": 1, "maximum": 65535 } + } + }, + "journalnode": { + "type": "object", + "properties": { + "rpc": { "type": "integer", "default": 8485, "minimum": 1, "maximum": 65535 }, + "http": { "type": "integer", "default": 8480, "minimum": 1, "maximum": 65535 } + } + } + } + }, + "paths": { + "type": "object", + "properties": { + "namenodeMetadataDir": { "type": "string", "default": "/hadoop/dfs/metadata" }, + "datanodeDataDir": { "type": "string", "default": "/hadoop/dfs/data0" }, + "journalnodeEditsDir": { "type": "string", "default": "/hadoop/dfs/journal" } + } + }, + "replication": { "type": "integer", "default": 1, "minimum": 1 }, + "client": { + "type": "object", + "properties": { + "replaceDatanodeOnFailurePolicy": { + "type": "string", + "enum": ["NEVER", "DEFAULT", "ALWAYS"], + "default": "NEVER" + } + } + }, + "permissions": { + "type": "object", + "properties": { + "enabled": { "type": "boolean", "default": false } + } + }, + "registration": { + "type": "object", + "properties": { + "ipHostnameCheck": { "type": "boolean", "default": false } + } + }, + "ha": { + "type": "object", + "properties": { + "automaticFailoverEnabled": { "type": "boolean", "default": true }, + "fencingMethods": { "type": "string", "default": "shell(/bin/true)" }, + "zookeeper": { + "type": "object", + "properties": { + "parentZnodePrefix": { "type": "string", "default": "/hadoop-ha" }, + "includeClusterUID": { "type": "boolean", "default": true }, + "sessionTimeoutMs": { "type": "integer", "default": 60000, "minimum": 1 }, + "operationRetries": { "type": "integer", "default": 3, "minimum": 0 } + } + } + } + }, + "ipc": { + "type": "object", + "properties": { + "clientConnectionMaxIdleTimeMs": { "type": "integer", "default": 300000, "minimum": 1 }, + "clientConnectTimeoutMs": { "type": "integer", "default": 20000, "minimum": 1 }, + "clientConnectionPoolSize": { "type": "integer", "default": 8, "minimum": 1 }, + "clientConnectRetryIntervalMs": { "type": "integer", "default": 1000, "minimum": 1 }, + "clientPing": { "type": "boolean", "default": true }, + "pingIntervalMs": { "type": "integer", "default": 30000, "minimum": 1 } + } + } + } + }, + "serviceRefs": { + "type": "object", + "properties": { + "hadoopZookeeper": { + "type": "object", + "properties": { + "namespace": { "type": "string", "default": "kubeblocks" }, + "clusterServiceSelector": { + "type": "object", + "properties": { + "cluster": { "type": "string", "default": "zk" }, + "service": { + "type": "object", + "properties": { + "component": { "type": "string", "default": "zookeeper" }, + "service": { "type": "string", "default": "headless" }, + "port": { "type": "string", "default": "client" } + } + } + } + } + } + } + } + } + }, + "definitions": { + "resourceSchema": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "cpu": { "type": "string", "default": "0.5" }, + "memory": { "type": "string", "default": "0.5Gi" } + } + }, + "limits": { + "type": "object", + "properties": { + "cpu": { "type": "string", "default": "0.5" }, + "memory": { "type": "string", "default": "2Gi" } + } + } + } + }, + "storageSchema": { + "type": "object", + "properties": { + "size": { "type": "string", "default": "10Gi" }, + "storageClassName": { "type": "string", "default": "" }, + "accessModes": { + "type": "array", + "items": { "type": "string" }, + "default": ["ReadWriteOnce"], + "minItems": 1 + } + } + } + } +} diff --git a/addons-cluster/hadoop/values.yaml b/addons-cluster/hadoop/values.yaml new file mode 100644 index 0000000000..350980d14b --- /dev/null +++ b/addons-cluster/hadoop/values.yaml @@ -0,0 +1,120 @@ +topology: cluster + +replicas: + core: 1 + journalnode: 3 + namenode: 2 + datanode: 3 + +resources: + core: + requests: + cpu: "100m" + memory: 256Mi + limits: + cpu: "500m" + memory: 1Gi + journalnode: + requests: + cpu: "500m" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi + namenode: + requests: + cpu: "1" + memory: 2Gi + limits: + cpu: "4" + memory: 4Gi + datanode: + requests: + cpu: "500m" + memory: 1Gi + limits: + cpu: "2" + memory: 2Gi + zkfc: + requests: + cpu: "100m" + memory: 256Mi + limits: + cpu: "500m" + memory: 512Mi + +storage: + journalnode: + size: 20Gi + storageClassName: "" + accessModes: + - ReadWriteOnce + namenode: + size: 50Gi + storageClassName: "" + accessModes: + - ReadWriteOnce + datanode: + size: 100Gi + storageClassName: "" + accessModes: + - ReadWriteOnce + +hdfs: + ports: + namenode: + rpc: 8020 + http: 9870 + journalnode: + rpc: 8485 + http: 8480 + paths: + namenodeMetadataDir: /hadoop/dfs/metadata + datanodeDataDir: /hadoop/dfs/data0 + journalnodeEditsDir: /hadoop/dfs/journal + replication: 3 + client: + replaceDatanodeOnFailurePolicy: DEFAULT + permissions: + enabled: false + registration: + ipHostnameCheck: false + ha: + automaticFailoverEnabled: true + fencingMethods: "sshfence\nshell(/bin/true)" + zookeeper: + parentZnodePrefix: /hadoop-ha + includeClusterUID: true + sessionTimeoutMs: 60000 + operationRetries: 3 + ipc: + clientConnectionMaxIdleTimeMs: 300000 + clientConnectTimeoutMs: 20000 + clientConnectionPoolSize: 8 + clientConnectRetryIntervalMs: 1000 + clientPing: true + pingIntervalMs: 30000 + trash: + interval: 1440 + jvm: + namenodeHeapSize: "2g" + datanodeHeapSize: "1g" + journalnodeHeapSize: "1g" + zkfcHeapSize: "256m" + datanode: + handlerCount: 64 + namenode: + handlerCount: 64 + +serviceRefs: + hadoopZookeeper: + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless + port: client + +extra: + terminationPolicy: Delete diff --git a/addons-cluster/hbase/.helmignore b/addons-cluster/hbase/.helmignore new file mode 100644 index 0000000000..691fa13d6a --- /dev/null +++ b/addons-cluster/hbase/.helmignore @@ -0,0 +1,23 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/addons-cluster/hbase/Chart.yaml b/addons-cluster/hbase/Chart.yaml new file mode 100644 index 0000000000..d374e67535 --- /dev/null +++ b/addons-cluster/hbase/Chart.yaml @@ -0,0 +1,25 @@ +annotations: + category: BigData + kubeblocks.io/min-version: "1.1.0" +apiVersion: v2 +name: hbase-cluster +type: application +version: 1.1.0-alpha.0 +description: A HBase Helm chart for KubeBlocks. +dependencies: + - name: kblib + version: 0.1.2 + repository: file://../kblib + alias: extra +appVersion: "2.5.6" +keywords: + - hbase + - bigdata + - database +home: https://github.com/apecloud/kubeblocks/tree/main/deploy/hbase +icon: https://kubeblocks.io/img/logo.png +maintainers: + - name: ApeCloud + url: https://kubeblocks.io/ +sources: + - https://github.com/apecloud/kubeblocks/ diff --git a/addons-cluster/hbase/releases_notes.yaml b/addons-cluster/hbase/releases_notes.yaml new file mode 100644 index 0000000000..50ab69fe68 --- /dev/null +++ b/addons-cluster/hbase/releases_notes.yaml @@ -0,0 +1,10 @@ +releases: +- version: 1.1.0 + released_at: '2026-05-21' + status: stable + git_branch: release-1.1 + git_tag: v1.1.0 + commit_sha: '' + notes: + en: Minimum supported KubeBlocks version is 1.1.0. + zh: 最低支持的 KubeBlocks 版本为 1.1.0。 diff --git a/addons-cluster/hbase/templates/_helpers.tpl b/addons-cluster/hbase/templates/_helpers.tpl new file mode 100644 index 0000000000..5ef39e6c78 --- /dev/null +++ b/addons-cluster/hbase/templates/_helpers.tpl @@ -0,0 +1,10 @@ +{{- define "hbase-cluster.clusterCommon" }} +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: {{ include "kblib.clusterName" . }} + namespace: {{ .Release.Namespace }} + labels: {{ include "kblib.clusterLabels" . | nindent 4 }} +spec: + terminationPolicy: {{ .Values.extra.terminationPolicy }} +{{- end }} \ No newline at end of file diff --git a/addons-cluster/hbase/templates/cluster.yaml b/addons-cluster/hbase/templates/cluster.yaml new file mode 100644 index 0000000000..30b5720442 --- /dev/null +++ b/addons-cluster/hbase/templates/cluster.yaml @@ -0,0 +1,123 @@ +{{- $isCluster := eq .Values.topology "cluster" }} +{{- $isStandalone := eq .Values.topology "standalone" }} +{{- if not (or $isCluster $isStandalone) }} +{{- fail "topology must be either 'cluster' or 'standalone'" }} +{{- end }} +{{- include "hbase-cluster.clusterCommon" . }} + clusterDef: hbase + topology: {{ .Values.topology }} + componentSpecs: +{{- if $isCluster }} + - name: hmaster + componentDef: hbase-hmaster-2.5 + serviceVersion: 2.5.6 + replicas: {{ .Values.replicas.hmaster }} + serviceRefs: + - name: hbase-zookeeper + namespace: {{ .Values.serviceRefs.hbaseZookeeper.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.port }} + - name: hdfs-namenode + namespace: {{ .Values.serviceRefs.hdfsNamenode.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.port }} + configs: + - name: hbase-config + variables: + HDFS_NAMESERVICE: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster | quote }} + resources: + requests: + cpu: {{ .Values.resources.hmaster.requests.cpu | quote }} + memory: {{ .Values.resources.hmaster.requests.memory }} + limits: + cpu: {{ .Values.resources.hmaster.limits.cpu | quote }} + memory: {{ .Values.resources.hmaster.limits.memory }} + schedulingPolicy: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + apps.kubeblocks.io/component-name: hmaster + - name: hregionserver + componentDef: hbase-hregionserver-2.5 + serviceVersion: 2.5.6 + replicas: {{ .Values.replicas.hregionserver }} + serviceRefs: + - name: hbase-zookeeper + namespace: {{ .Values.serviceRefs.hbaseZookeeper.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.port }} + - name: hdfs-namenode + namespace: {{ .Values.serviceRefs.hdfsNamenode.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.service.port }} + configs: + - name: hbase-config + variables: + HDFS_NAMESERVICE: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster | quote }} + resources: + requests: + cpu: {{ .Values.resources.hregionserver.requests.cpu | quote }} + memory: {{ .Values.resources.hregionserver.requests.memory }} + limits: + cpu: {{ .Values.resources.hregionserver.limits.cpu | quote }} + memory: {{ .Values.resources.hregionserver.limits.memory }} + schedulingPolicy: + topologySpreadConstraints: + - maxSkew: 1 + topologyKey: kubernetes.io/hostname + whenUnsatisfiable: DoNotSchedule + labelSelector: + matchLabels: + apps.kubeblocks.io/component-name: hregionserver +{{- else }} + - name: hbase-standalone + componentDef: hbase-standalone-2.5 + serviceVersion: 2.5.6 + replicas: 1 + serviceRefs: + - name: hbase-zookeeper + namespace: {{ .Values.serviceRefs.hbaseZookeeper.namespace }} + clusterServiceSelector: + cluster: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster }} + service: + component: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.component }} + service: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.service }} + port: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.port }} + resources: + requests: + cpu: {{ .Values.resources.hbasestandalone.requests.cpu | quote }} + memory: {{ .Values.resources.hbasestandalone.requests.memory }} + limits: + cpu: {{ .Values.resources.hbasestandalone.limits.cpu | quote }} + memory: {{ .Values.resources.hbasestandalone.limits.memory }} + volumeClaimTemplates: + - name: data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.storage.standalone.data }} +{{- if .Values.storage.storageClassName }} + storageClassName: {{ .Values.storage.storageClassName }} +{{- end }} +{{- end }} diff --git a/addons-cluster/hbase/values.schema.json b/addons-cluster/hbase/values.schema.json new file mode 100644 index 0000000000..702f2a9c56 --- /dev/null +++ b/addons-cluster/hbase/values.schema.json @@ -0,0 +1,137 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "object", + "properties": { + "topology": { + "type": "string", + "enum": [ + "cluster", + "standalone" + ], + "default": "cluster" + }, + "replicas": { + "type": "object", + "properties": { + "hmaster": { + "type": "integer", + "default": 2, + "minimum": 1 + }, + "hregionserver": { + "type": "integer", + "default": 2, + "minimum": 1 + } + } + }, + "resources": { + "type": "object", + "properties": { + "hmaster": { + "$ref": "#/definitions/resourceSchema" + }, + "hregionserver": { + "$ref": "#/definitions/resourceSchema" + }, + "hbasestandalone": { + "$ref": "#/definitions/resourceSchema" + } + } + }, + "storage": { + "type": "object", + "properties": { + "storageClassName": { + "type": "string", + "default": "" + }, + "standalone": { + "type": "object", + "properties": { + "data": { + "type": "string", + "default": "20Gi" + } + } + } + } + }, + "serviceRefs": { + "type": "object", + "properties": { + "hbaseZookeeper": { + "$ref": "#/definitions/serviceRefSchema" + }, + "hdfsNamenode": { + "$ref": "#/definitions/serviceRefSchema" + } + } + } + }, + "definitions": { + "resourceSchema": { + "type": "object", + "properties": { + "requests": { + "type": "object", + "properties": { + "cpu": { + "type": "string", + "default": "0.5" + }, + "memory": { + "type": "string", + "default": "1Gi" + } + } + }, + "limits": { + "type": "object", + "properties": { + "cpu": { + "type": "string", + "default": "2" + }, + "memory": { + "type": "string", + "default": "4Gi" + } + } + } + } + }, + "serviceRefSchema": { + "type": "object", + "properties": { + "namespace": { + "type": "string", + "default": "kubeblocks" + }, + "clusterServiceSelector": { + "type": "object", + "properties": { + "cluster": { + "type": "string" + }, + "service": { + "type": "object", + "properties": { + "component": { + "type": "string" + }, + "service": { + "type": "string", + "default": "headless" + }, + "port": { + "type": "string" + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/addons-cluster/hbase/values.yaml b/addons-cluster/hbase/values.yaml new file mode 100644 index 0000000000..bfc596a181 --- /dev/null +++ b/addons-cluster/hbase/values.yaml @@ -0,0 +1,54 @@ +topology: cluster + +replicas: + hmaster: 2 + hregionserver: 2 + +resources: + hmaster: + requests: + cpu: "0.5" + memory: 1Gi + limits: + cpu: "2" + memory: 4Gi + hregionserver: + requests: + cpu: "0.5" + memory: 1Gi + limits: + cpu: "2" + memory: 6Gi + hbasestandalone: + requests: + cpu: "0.2" + memory: 0.5Gi + limits: + cpu: "1" + memory: 1Gi + +storage: + storageClassName: "" + standalone: + data: 20Gi + +serviceRefs: + hbaseZookeeper: + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless + port: client + hdfsNamenode: + namespace: kubeblocks + clusterServiceSelector: + cluster: hdfs + service: + component: namenode + service: headless + port: client + +extra: + terminationPolicy: Delete diff --git a/addons/hadoop/.helmignore b/addons/hadoop/.helmignore new file mode 100644 index 0000000000..691fa13d6a --- /dev/null +++ b/addons/hadoop/.helmignore @@ -0,0 +1,23 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/addons/hadoop/Chart.yaml b/addons/hadoop/Chart.yaml new file mode 100644 index 0000000000..4630c38285 --- /dev/null +++ b/addons/hadoop/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + category: BigData + addon.kubeblocks.io/kubeblocks-version: ">=1.0.0" + addon.kubeblocks.io/model: "key-value" + addon.kubeblocks.io/provider: "community" +apiVersion: v2 +name: hadoop +description: A Helm chart for Hadoop HDFS on KubeBlocks. +type: application +version: 1.1.0-alpha.0 +appVersion: "3.3.4" +dependencies: + - name: kblib + version: 0.1.0 + repository: file://../kblib + alias: extra +keywords: + - hadoop + - hdfs + - bigdata +home: https://github.com/apecloud/kubeblocks/tree/main/deploy/hadoop +icon: https://kubeblocks.io/img/logo.png +maintainers: + - name: ApeCloud + url: https://kubeblocks.io/ +sources: + - https://github.com/apecloud/kubeblocks/ \ No newline at end of file diff --git a/addons/hadoop/README.md b/addons/hadoop/README.md new file mode 100644 index 0000000000..35df96bd52 --- /dev/null +++ b/addons/hadoop/README.md @@ -0,0 +1,34 @@ +# Hadoop HDFS Addon for KubeBlocks + +## Overview + +This addon provides Hadoop HDFS support on KubeBlocks, including: + +- **HA Cluster Topology**: 4-component architecture (hadoop-core, journalnode, namenode, datanode) +- **ZooKeeper Integration**: Automatic failover via ZK service reference +- **Host Network**: DataNode supports hostNetwork for optimal I/O performance +- **Configuration Management**: Dynamic parameter tuning via Parameters API + +## Components + +| Component | Role | Default Replicas | +|-----------|------|-----------------| +| hadoop-core | Orchestration (config generation only) | 1 | +| hdfs-journalnode | HA Journal | 3 | +| hdfs-namenode | NameNode (nn0/nn1) | 2 | +| hdfs-datanode | DataNode (hostNetwork) | 1 | + +## Quick Start + +```bash +# Install addon +helm install hadoop kubeblocks-addons/hadoop + +# Create cluster +helm install mycluster kubeblocks-addons-cluster/hadoop +``` + +## Requirements + +- KubeBlocks >= 1.1.0 +- ZooKeeper cluster for HA coordination \ No newline at end of file diff --git a/addons/hadoop/config/core-site-standalone.tpl b/addons/hadoop/config/core-site-standalone.tpl new file mode 100644 index 0000000000..d41458cbef --- /dev/null +++ b/addons/hadoop/config/core-site-standalone.tpl @@ -0,0 +1,70 @@ + + + + + + fs.defaultFS + hdfs://{{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + + fs.trash.interval + {{- .HDFS_TRASH_INTERVAL }} + + + + io.compression.codecs + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec + + + + hadoop.http.staticuser.user + hdfs + + + + hadoop.security.authentication + simple + + + + hadoop.security.authorization + false + + + + ipc.client.connection.maxidletime + {{- .HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS }} + + + + ipc.client.connect.timeout + {{- .HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS }} + + + + ipc.client.connection.pool.size + {{- .HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE }} + + + + ipc.client.connect.retry.interval + {{- .HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS }} + + + + ipc.client.ping + {{- .HDFS_IPC_CLIENT_PING }} + + + + ipc.ping.interval + {{- .HDFS_IPC_PING_INTERVAL_MS }} + + + + hadoop.tmp.dir + /hadoop/tmp + + diff --git a/addons/hadoop/config/core-site.tpl b/addons/hadoop/config/core-site.tpl new file mode 100644 index 0000000000..c7017df998 --- /dev/null +++ b/addons/hadoop/config/core-site.tpl @@ -0,0 +1,89 @@ + + + + + + fs.defaultFS + hdfs://{{- .CLUSTER_NAME }} + + + + fs.trash.interval + {{- .HDFS_TRASH_INTERVAL }} + + + + io.compression.codecs + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec + + + + ha.zookeeper.quorum + {{- .ZOOKEEPER_ENDPOINTS }} + + + + ha.zookeeper.parent-znode + {{- .HDFS_HA_ZOOKEEPER_PARENT_ZNODE }} + + + + ha.zookeeper.session-timeout.ms + {{- .HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS }} + + + + hadoop.http.staticuser.user + hdfs + + + + hadoop.security.authentication + simple + + + + hadoop.security.authorization + false + + + + ipc.client.connection.maxidletime + {{- .HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS }} + + + + ipc.client.connect.timeout + {{- .HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS }} + + + + ipc.client.connection.pool.size + {{- .HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE }} + + + + ipc.client.connect.retry.interval + {{- .HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS }} + + + + ipc.client.ping + {{- .HDFS_IPC_CLIENT_PING }} + + + + ipc.ping.interval + {{- .HDFS_IPC_PING_INTERVAL_MS }} + + + + hadoop.tmp.dir + /hadoop/tmp + + + + hadoop.home.dir + /user + + diff --git a/addons/hadoop/config/dfs.exclude b/addons/hadoop/config/dfs.exclude new file mode 100644 index 0000000000..62275f3622 --- /dev/null +++ b/addons/hadoop/config/dfs.exclude @@ -0,0 +1,3 @@ +# dfs.exclude - DataNode decommission list (blacklist) +# Add DN hostnames/IPs here and run `hdfs dfsadmin -refreshNodes` to start decommission. +# DataNodes listed here will be decommissioned and excluded from the cluster. diff --git a/addons/hadoop/config/dfs.include b/addons/hadoop/config/dfs.include new file mode 100644 index 0000000000..e94637cf8c --- /dev/null +++ b/addons/hadoop/config/dfs.include @@ -0,0 +1,3 @@ +# dfs.include - DataNode include list (whitelist) +# Initially empty; add DN hostnames/IPs to explicitly allow them to register. +# When non-empty, only DataNodes listed here can connect to the NameNode. diff --git a/addons/hadoop/config/hadoop-core-config-constraint.cue b/addons/hadoop/config/hadoop-core-config-constraint.cue new file mode 100644 index 0000000000..de393d76c1 --- /dev/null +++ b/addons/hadoop/config/hadoop-core-config-constraint.cue @@ -0,0 +1,153 @@ +// Copyright (C) 2022-2023 ApeCloud Co., Ltd +// +// This file is part of KubeBlocks project +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#HadoopCoreParameter: { + // 说明: Hadoop tmp 数据目录。 + "hadoop.tmp.dir": string | *"/tmp/hadoop" + + // 说明:默认的文件系统名。 + "fs.defaultFS": string | *"hdfs://{{- .CLUSTER_NAME }}" + + // A comma separated list of class names. Each class in the list must extend org.apache.hadoop.http.FilterInitializer. The corresponding Filter will be initialized. Then, the Filter will be applied to all user facing jsp and servlet web pages. The ordering of the list defines the ordering of the filters + "hadoop.http.filter.initializers": string | "org.apache.hadoop.http.lib.StaticUserWebFilter" + + // NN/JN/DN Server connection timeout in milliseconds. + "hadoop.http.idle_timeout.ms": int | 60000 + + // The name of the Network Interface from which the service should determine its host name for Kerberos login. e.g. eth2. In a multi-homed environment, the setting can be used to affect the _HOST substitution in the service Kerberos principal. If this configuration value is not set, the service will use its default hostname as returned by InetAddress.getLocalHost().getCanonicalHostName(). Most clusters will not require this setting. + "hadoop.security.dns.interface"?: string + + // The host name or IP address of the name server (DNS) which a service Node should use to determine its own host name for Kerberos Login. Requires hadoop.security.dns.interface. Most clusters will not require this setting. + "hadoop.security.dns.nameserver"?: string + + // The resolver implementation used to resolve FQDN for Kerberos + "hadoop.security.resolver.impl": string | *"org.apache.hadoop.net.DNSDomainNameResolver" + + // Time name lookups (via SecurityUtil) and log them if they exceed the configured threshold. + "hadoop.security.dns.log-slow-lookups.enabled": bool & (true | false) | *false + + // If slow lookup logging is enabled, this threshold is used to decide if a lookup is considered slow enough to be logged. + "hadoop.security.dns.log-slow-lookups.threshold.ms": int | *1000 + + // This is the config controlling the validity of the entries in the cache containing the user->group mapping. When this duration has expired, then the implementation of the group mapping provider is invoked to get the groups of the user and then cached back. + "hadoop.security.groups.cache.secs": int | *300 + + // Expiration time for entries in the the negative user-to-group mapping caching, in seconds. This is useful when invalid users are retrying frequently. It is suggested to set a small value for this expiration, since a transient error in group lookup could temporarily lock out a legitimate user. Set this to zero or negative value to disable negative user-to-group caching. + "hadoop.security.groups.negative-cache.secs": int | *30 + + // If looking up a single user to group takes longer than this amount of milliseconds, we will log a warning message. + "hadoop.security.groups.cache.warn.after.ms": int | *5000 + + // Whether to reload expired user->group mappings using a background thread pool. If set to true, a pool of hadoop.security.groups.cache.background.reload.threads is created to update the cache in the background. + "hadoop.security.groups.cache.background.reload": bool & (true | false) | *false + + // 3 Only relevant if hadoop.security.groups.cache.background.reload is true. Controls the number of concurrent background user->group cache entry refreshes. Pending refresh requests beyond this value are queued and processed when a thread is free. + "hadoop.security.groups.cache.background.reload.threads": int | *3 + + // 说明:与内置的sshfence相关的SSH连接超时时间。单位:毫秒。 默认值:10000 取值范围:1~3600000 + "dfs.ha.fencing.ssh.connect-timeout": int & >=1 & <=3600000 | *10000 + + // 说明:创建文件及目录时使用的umask。可以是八进制数或符号型的。比如:"022"(这是八进制数,对应的符号型数值是"u=rwx,g=r-x,o=r-x")或"u=rwx,g=rwx,o="(这是符号型数值,对应的八进制数是007)。 默认值:022 + "fs.permissions.umask-mode": string | *"022" + + // 说明:访问S3A文件系统使用的秘钥ID,若不设置默认为空。 + "fs.s3a.access.key"?: string + + // 说明:是否启动SSL连接和S3服务。 默认值:false 取值范围:true, false + "fs.s3a.connection.ssl.enabled": bool | *false + + // 说明:访问S3A文件系统使用的秘钥,若不设置默认为空。 + "fs.s3a.secret.key"?: string + + // 说明:访问S3时使用的签名算法。默认使用旧版本S3SignerType签名算法。如果不指定此参数,则使用默认的签名算法但可能存在兼容性问题。 默认值:S3SignerType 取值范围:S3SignerType或不指定。 + "fs.s3a.signing-algorithm": string & ("S3SignerType") | *"S3SignerType" + + // 说明:zkfc对namenode健康状态检查的超时时间。单位:毫秒。增大该参数值,可以防止出现双Active NameNode,降低客户端应用运行异常的概率。 默认值:180000 取值范围:30000~3600000 + "ha.health-monitor.rpc-timeout.ms": int & >=30000 & <=3600000 | *180000 + + // 说明:Zkfc连接到ZooKeeper时使用的会话超时时间。单位:毫秒。如果将该参数设置为较小的值,那可以更快地监测到服务器瘫痪故障,但如果出现瞬变错误或网络中断则有强制触发切换的风险。 默认值:90000 取值范围:1~3600000 + "ha.zookeeper.session-timeout.ms": int & >=1 & <=3600000 | *90000 + + // 说明:存储鉴权令牌的HTTP cookie所使用的域。为了在所有Hadoop节点web控制台间正确地进行鉴权,该域必须配置正确。重要:使用IP地址时,浏览器会忽略带有域设置的cookies。为保证该设置的正常使用,集群中的所有节点都必须配置为使用上面的hostname.domain名来生成URL。 + "hadoop.http.authentication.cookie.domain"?: string + + // 说明:通过静态网页可以呈现内容的用户名。 默认值:hdfs + "hadoop.http.staticuser.user": string | *"hdfs" + + // 说明:设置Hadoop中各模块的RPC通道是否加密。对RPC的加密方式,有如下三种取值: authentication:只进行认证,不加密; integrity:进行认证和一致性校验; privacy:进行认证、一致性校验、加密。 默认值:S的上层服务,且不支持滚动重启。重启过程中会造成业务中断,请谨慎修改。 + "hadoop.rpc.protection": string & ("authentication" | "privacy" | "integrity") | *"privacy" + + // 说明: 选择 Hadoop 使用的身份验证机制. 默认值:kerberos 取值范围:kerberos + "hadoop.security.authentication": string & ("kerberos") | *"kerberos" + + // 说明: 启用授权. 默认值:true 取值范围:true, false 注意:修改该配置为false后会停用Kerberos,存在安全风险,请谨慎操作。 + "hadoop.security.authorization": bool | *true + + // 说明:ACL中用于用户和组之间的映射(为指定用户获取组)的类。该类使用bash -c groups命令临时接入到Linux/Unix环境为用户获取组清单。org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback决定JNI(Ja用,将使用ShellBasedUnixGroupsMapping。 默认值:org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback 取值范围:org.apache.hadoop.security.ShellBasedUnixGroupsMapping 或 org.apache.hadoop.securityroupsMappingWithFallback + "hadoop.security.group.mapping": string & ("org.apache.hadoop.security.ShellBasedUnixGroupsMapping" | "org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback") | *"org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback" + + // 说明:由ShellBasedUnixGroupsMapping类使用,此属性控制要等待运行获取组的shell命令的时间。配置值可采用时间后缀s/m/h表示,分别表示秒,分钟和小时。 如果运行命令的时间比配置的值长,则该命令将中止并返回没有找到任何组的结果。配置为“0s”表示无限等待 (即等待命令自行退出)。 默认值:60s + "hadoop.security.groups.shell.command.timeout": string | *"60s" + + // 说明:通过HTTP或HTTPS访问HDFS的JMX, METRICS, CONF, STACKS等信息时,是否需要管理员权限。 默认值:true 取值范围:true, false 注意:修改该配置为false后,降低了安全等级,请谨慎操作。 + "hadoop.security.instrumentation.requires.admin": bool | *true + + // 说明:通过delegation token认证时,是否使用ip地址作为tokens的service key。 默认值:true 取值范围:true, false + "hadoop.security.token.service.use_ip": bool | *true + + // 说明:SSL支持的协议列表(用逗号分隔)。 默认值:TLSv1.2 注意:使用低版本协议,存在安全风险,请谨慎操作。 + "hadoop.ssl.enabled.protocols": string | *"TLSv1.2" + + // 说明:定义压缩编码解码库中的所有压缩编码。可用于压缩/解压缩的压缩编码类的列表,列表中各项以逗号分隔。除了带有该属性的类(优先级高)之外,类路径上的压缩编码类也都是通过Java ServiceLoader发现的。 默认值:oache.hadoop.io.compress.DeflateCodec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.GzipCodec. + "io.compression.codecs": string | *"org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.DeflateCodec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.ZStandardCodec" + + // 说明:用于指定写入Sequence文件时的缓冲数据的长度,也用于指定读写文件时的缓冲数据的长度,单位为Byte。 默认值:131072 取值范围:大于或等于4096 注意:该大小需要设置为硬件页面大小(Intel x86硬件上,页面大小为4096)的整数倍。 + "io.file.buffer.size": int & >=1024 | *131072 + + // 说明:客户端与服务端建立Socket连接超时时,客户端的重试次数。 默认值:45 取值范围:1~256 + "ipc.client.connect.max.retries.on.timeouts": int & >=1 & <=256 | *45 + + // 说明:客户端与服务端建立socket连接的超时时间。单位:毫秒。 默认值:20000 取值范围:1~3600000 + "ipc.client.connect.timeout": int & >=1 & <=3600000 | *20000 + + // 说明:当客户端连接安全服务后,转向连接非安全服务时,服务端指引客户端进行非安全认证。该配置项控制客户端是否进行非安全认证。当设置为默认false时,禁止客户端回落到非安全认证,并断开连接。 默认值:true + "ipc.client.fallback-to-simple-auth-allowed": bool | *true + + // 说明:进行空闲情况检查的连接的个数阈值。 默认值:4000 取值范围:大于 0 + "ipc.client.idlethreshold": int & >=1 | *4000 + + // 说明:一次操作中可断连的最大客户端数。 默认值:10 取值范围:大于 0 + "ipc.client.kill.max": int & >=1 | *10 + + // 说明:表示是否要启用在RPC客户端上ping服务器。 默认值:true 取值范围:true 或 false + "ipc.client.ping": bool | *true + + // 说明:客户端ipc超时时间。单位:毫秒。 默认值:300000 取值范围:1~3600000 + "ipc.client.rpc-timeout.ms": int & >=1 & <=3600000 | *300000 + + // 说明:DataNode连接NameNode时可用的最大IPC数据大小。 默认值:268435456 取值范围:67108864~4294967296 + "ipc.maximum.data.length": int & >=67108864 & <=4294967296 | *268435456 + + // 说明:从RPC客户端向服务器发送ping包的间隔。单位:毫秒。 默认值:60000 取值范围:1~3600000 + "ipc.ping.interval": int & >=1 & <=3600000 | *60000 + + // 说明:表示服务器接受客户端连接的监听队列的长度。 默认值:128 取值范围:1~8192 + "ipc.server.listen.queue.size": int & >=1 & <=8192 | *128 + + // 说明:此设置可用于解决各种服务的性能问题。如果该值设置为true,处理时间多于99%的RPC请求的请求视为慢请求,记录于日志中并增加RpcSlowCalls的值。 默认值:false 取值范围:true 或 false + "ipc.server.log.slow.rpc": bool | *false +} diff --git a/addons/hadoop/config/hadoop-env.sh.tpl b/addons/hadoop/config/hadoop-env.sh.tpl new file mode 100644 index 0000000000..1c921b89db --- /dev/null +++ b/addons/hadoop/config/hadoop-env.sh.tpl @@ -0,0 +1,20 @@ +export JAVA_HOME=${JAVA_HOME:-/usr/local/openjdk-8} +export HADOOP_HOME=${HADOOP_HOME:-/opt/hadoop} +export HADOOP_CONF_DIR=${HADOOP_CONF_DIR:-${HADOOP_HOME}/etc/hadoop} +export HADOOP_LOG_DIR=${HADOOP_LOG_DIR:-/var/log/hadoop} +export HADOOP_PID_DIR=${HADOOP_PID_DIR:-/tmp/hadoop} +export HADOOP_IDENT_STRING=${HADOOP_IDENT_STRING:-$USER} + +export HADOOP_OPTS="${HADOOP_OPTS} -Djava.net.preferIPv4Stack=true -Dsun.net.inetaddr.ttl=10 -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelGCThreads=8" + +export HDFS_NAMENODE_OPTS="${HDFS_NAMENODE_OPTS:-} -Xms{{ .HDFS_NAMENODE_HEAP }} -Xmx{{ .HDFS_NAMENODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender" + +export HDFS_DATANODE_OPTS="${HDFS_DATANODE_OPTS:-} -Xms{{ .HDFS_DATANODE_HEAP }} -Xmx{{ .HDFS_DATANODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=ERROR,RFAS" + +export HDFS_JOURNALNODE_OPTS="${HDFS_JOURNALNODE_OPTS:-} -Xms{{ .HDFS_JOURNALNODE_HEAP }} -Xmx{{ .HDFS_JOURNALNODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" + +export HDFS_ZKFC_OPTS="${HDFS_ZKFC_OPTS:-} -Xms{{ .HDFS_ZKFC_HEAP }} -Xmx{{ .HDFS_ZKFC_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" + +export HADOOP_CLIENT_OPTS="${HADOOP_CLIENT_OPTS:-} -Xmx512m" + +export LD_LIBRARY_PATH="${HADOOP_HOME}/lib/native:${LD_LIBRARY_PATH:-}" diff --git a/addons/hadoop/config/hadoop-metrics2.properties.tpl b/addons/hadoop/config/hadoop-metrics2.properties.tpl new file mode 100644 index 0000000000..c440564474 --- /dev/null +++ b/addons/hadoop/config/hadoop-metrics2.properties.tpl @@ -0,0 +1,19 @@ +# Hadoop Metrics 2 configuration - JMX sink for all components +*.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +*.sink.jmx.period=10 + +# NameNode metrics +namenode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +namenode.sink.jmx.period=10 + +# DataNode metrics +datanode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +datanode.sink.jmx.period=10 + +# JournalNode metrics +journalnode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +journalnode.sink.jmx.period=10 + +# ZKFC metrics +zkfc.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +zkfc.sink.jmx.period=10 diff --git a/addons/hadoop/config/hdfs-datanode-config-constraint.cue b/addons/hadoop/config/hdfs-datanode-config-constraint.cue new file mode 100644 index 0000000000..0dbad5c79b --- /dev/null +++ b/addons/hadoop/config/hdfs-datanode-config-constraint.cue @@ -0,0 +1,156 @@ +// Copyright (C) 2022-2023 ApeCloud Co., Ltd +// +// This file is part of KubeBlocks project +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#DataNodeParameter: { + // The datanode server address and port for data transfer. + "dfs.datanode.address": string | "0.0.0.0:9866" + + // The datanode http server address and port. + "dfs.datanode.http.address": string | "0.0.0.0:9864" + + // The datanode ipc server address and port. + "dfs.datanode.ipc.address ": string | "0.0.0.0:9867" + + // DataNode配置中用于指定允许进行短路读操作的用户的密钥。 + "dfs.block.local-path-access.user"?: string + + // 若设置为正整数,表示从DataNode向NameNode上报新增块的等待时间,单位:ms。默认值0,取值范围0~86400000 + "dfs.blockreport.incremental.intervalMsec": int & <=86400000 | *0 + + // 首次块上报的延时时间,单位:秒。默认值0,取值范围0~1500 + "dfs.blockreport.initialDelay": int & <=1500 | *0 + + // 块上报间隔时间,单位:毫秒。默认值21600000,取值范围100~86400000 + "dfs.blockreport.intervalMsec": int & >=100 & <=86400000 | *21600000 + + // DataNode上的块数低于此阈值时将单个消息发送块报告,超过时分开发送。默认值1000000,取值范围0~2000000 + "dfs.blockreport.split.threshold": int & <=2000000 | *1000000 + + // 每个校验和的字节数,不能大于dfs.stream-buffer-size且必须能被dfs.blocksize整除。默认值512,取值范围大于0 + "dfs.bytes-per-checksum": int & >=1 | *512 + + // 控制新块分配到拥有更多可用磁盘空间的卷的比例,适用于AvailableSpaceVolumeChoosingPolicy。默认值0.75,取值范围0~1 + "dfs.datanode.available-space-volume-choosing-policy.balanced-space-preference-fraction": number | *0.75 + + // 控制DataNode卷的负载均衡范围,适用于AvailableSpaceVolumeChoosingPolicy。默认值10737418240,取值范围大于0 + "dfs.datanode.available-space-volume-choosing-policy.balanced-space-threshold": int & >=1 | *10737418240 + + // DataNode可用于负载均衡的最大带宽量(每秒的字节数)。默认值20971520,取值范围1048576~1073741824 + "dfs.datanode.balance.bandwidthPerSec": int & >=1048576 & <=1073741824 | *20971520 + + // 允许在DataNode上进行负载均衡的最大线程数。默认值32,取值范围5~1000 + "dfs.datanode.balance.max.concurrent.moves": int & >=5 & <=1000 | *32 + + // 是否禁止移动写入指定DataNode上的数据块。默认值false + "dfs.datanode.block-pinning.enabled": bool | *false + + // DataNode升级时创建前一版本到当前版本硬链接的线程数。默认值24,取值范围大于1 + "dfs.datanode.block.id.layout.upgrade.threads": int & >=1 | *24 + + // DataNode在本地文件系统中存储块的位置。默认值%{@auto.detect.datapart.dn} + "dfs.datanode.data.dir": string | *"%{@auto.detect.datapart.dn}" + + // dfs.datanode.data.dir的权限。默认值700 + "dfs.datanode.data.dir.perm": string | *700 + + // DataNode扫描数据目录在磁盘上的块和内存中的块之间的区别的间隔时间,单位:秒。默认值21600,取值范围1~258000 + "dfs.datanode.directoryscan.interval": int & >=1 & <=258000 | *21600 + + // 并行扫描DataNode目录并生成报告的线程数。默认值1,取值范围1~1024 + "dfs.datanode.directoryscan.threads": int & >=1 & <=1024 | *1 + + // DataNode应该上报它IP地址的网络接口名称。默认值"default" + "dfs.datanode.dns.interface": string | *"default" + + // DataNode在和NameNode交流时应该用的DNS服务地址主机名或IP地址。默认值"default" + "dfs.datanode.dns.nameserver": string | *"default" + + // 是否在读取数据后自动清除缓存中的数据。默认值false + "dfs.datanode.drop.cache.behind.reads": bool | *false + + // 是否在写入磁盘后自动清除缓存中的数据。默认值false + "dfs.datanode.drop.cache.behind.writes": bool | *false + + // 每个磁盘的保留空间,单位:字节。默认值0,取值范围大于等于0 + "dfs.datanode.du.reserved": int | *0 + + // DataNode上EC数据块的读取缓存大小,单位:字节。默认值131072,取值范围大于1024 + "dfs.datanode.ec.reconstruction.stripedread.buffer.size": int & >=1024 | *131072 + + // DataNode上EC数据块的读取超时时间,单位:毫秒。默认值15000,取值范围大于2000 + "dfs.datanode.ec.reconstruction.stripedread.timeout.millis": int & >=2000 | *15000 + + // DataNode进行EC数据块恢复的线程数。默认值32,取值范围1~1024 + "dfs.datanode.ec.reconstruction.threads": int & >=1 & <=1024 | *32 + + // EC数据块恢复线程数的比重。默认值0.5,取值范围0~1 + "dfs.datanode.ec.reconstruction.xmits.weight": number | *0.5 + + // DataNode停止提供服务前允许失败的卷数。默认值-1,取值范围-1~32768 + "dfs.datanode.failed.volumes.tolerated": int & >=-1 & <=32768 | *-1 + + // DataNode写操作时选择副本的存放位置时考虑每个卷的可用磁盘空间。默认值AvailableSpaceVolumeChoosingPolicy + "dfs.datanode.fsdataset.volume.choosing.policy": string & ("org.apache.hadoop.hdfs.server.datanode.fsdataset.RoundRobinVolumeChoosingPolicy" | "org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy") | *"org.apache.hadoop.hdfs.server.datanode.fsdataset.AvailableSpaceVolumeChoosingPolicy" + + // 每个卷用于缓存新数据的最大线程数。默认值4,取值范围大于0 + "dfs.datanode.fsdatasetcache.max.threads.per.volume": int & >=1 | *4 + + // DataNode的服务线程数。默认值32,取值范围1~1024 + "dfs.datanode.handler.count": int & >=1 & <=1024 | *32 + + // DataNode的内部web代理端口。默认值50175,取值范围1024~65535 + "dfs.datanode.http.internal-proxy.port": int & >=1024 & <=65535 | *50175 + + // 从DataNode向NameNode发送Lifeline协议消息的间隔周期,单位:秒 + "dfs.datanode.lifeline.interval.seconds"?: int + + // DataNode用于缓存块副本的内存大小,单位:字节。默认值0,取值范围0~1800000000000 + "dfs.datanode.max.locked.memory": int & <=1800000000000 | *0 + + // DataNode间传输数据的线程的最大数。默认值8192,取值范围1~32768 + "dfs.datanode.max.transfer.threads": int & >=1 & <=32768 | *8192 + + // 要激活的DataNode插件清单 + "dfs.datanode.plugins"?: string + + // DataNode尝试预先读取的字节数。默认值4194304,取值范围大于等于0 + "dfs.datanode.readahead.bytes": int | *4194304 + + // DataNode是否指示操作系统在写数据后立即写入磁盘。默认值true,取值范围true或false + "dfs.datanode.sync.behind.writes": bool | *true + + // DataNode向NameNode发送心跳的时间间隔,单位:秒。默认值10,取值范围3~180 + "dfs.heartbeat.interval": int & >=3 & <=180 | *10 + + // DataNode启用拥塞信令能力。默认值false,取值范围true或false + "dfs.pipeline.ecn": bool | *false + + // 流文件缓冲区的大小。默认值4096,取值范围大于0 + "dfs.stream-buffer-size": int & >=1 | *4096 + + // 【说明】是否禁止移动写入指定DataNode上的数据块。该参数值设置为true,在进行Balancer或Mover时,使用colocation写入的文件将不会被移动。【默认值】false + "dfs.datanode.block-pinning.enabled": bool | *false + + // 【说明】设置从DataNode向NameNode发送DataNode Lifeline协议消息的间隔周期。单位:秒。该参数值必须大于dfs.heartbeat.interval的值。如果不定义该参数,则默认计算值是dfs.heartbeat.interval值的3倍。 + "dfs.datanode.lifeline.interval.seconds"?: int + + // 【说明】是否允许备/从NameNode跟踪in-progress状态的edit logs。当客户希望备/从NameNode节点拥有更多较新的数据时,可以设置该参数为true。当QuorumJournalManager共享edit logs时,该参数允许通过RPC机制获取edit logs,而不是文件流,这使得数据传输更快。当使用从NameNode处理读操作时,该参数必须设置为true。【默认值】true + "dfs.ha.tail-edits.in-progress": bool | *true + + // 【说明】DataNode向NameNode发送心跳的时间间隔,单位为秒。【默认值】10【取值范围】3~180 + "dfs.heartbeat.interval": int & >=3 & <=180 | *10 +} \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-datanode-standalone.tpl b/addons/hadoop/config/hdfs-datanode-standalone.tpl new file mode 100644 index 0000000000..d2bc8cc558 --- /dev/null +++ b/addons/hadoop/config/hdfs-datanode-standalone.tpl @@ -0,0 +1,105 @@ + + + + + + dfs.datanode.data.dir + {{- .HDFS_DATANODE_DATA_DIR }} + + + + dfs.datanode.data.dir.perm + 700 + + + + dfs.datanode.failed.volumes.tolerated + 0 + + + + dfs.datanode.max.transfer.threads + {{- .HDFS_DATANODE_HANDLER_COUNT }} + + + + dfs.datanode.handler.count + {{- .HDFS_DATANODE_HANDLER_COUNT }} + + + + dfs.datanode.address + 0.0.0.0:9866 + + + + dfs.datanode.http.address + 0.0.0.0:9864 + + + + dfs.datanode.ipc.address + 0.0.0.0:9867 + + + + dfs.datanode.du.reserved + 1073741824 + + + + dfs.datanode.use.datanode.hostname + false + + + + dfs.datanode.hostname + {{- .POD_FQDN }} + + + + dfs.namenode.rpc-address + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + dfs.namenode.http-address + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.client.block.write.replace-datanode-on-failure.policy + {{- .HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY }} + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + + + dfs.hosts + {{- .HDFS_CONF_DIR }}/dfs.include + + + + dfs.hosts.exclude + {{- .HDFS_CONF_DIR }}/dfs.exclude + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 1000,1 + + \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-datanode.tpl b/addons/hadoop/config/hdfs-datanode.tpl new file mode 100644 index 0000000000..e67620f75e --- /dev/null +++ b/addons/hadoop/config/hdfs-datanode.tpl @@ -0,0 +1,129 @@ + + + + + + dfs.nameservices + {{- .CLUSTER_NAME }} + + + + dfs.datanode.data.dir + {{- .HDFS_DATANODE_DATA_DIR }} + + + + dfs.datanode.data.dir.perm + 700 + + + + dfs.datanode.failed.volumes.tolerated + 0 + + + + dfs.datanode.max.transfer.threads + {{- .HDFS_DATANODE_HANDLER_COUNT }} + + + + dfs.datanode.handler.count + {{- .HDFS_DATANODE_HANDLER_COUNT }} + + + + dfs.datanode.address + 0.0.0.0:9866 + + + + dfs.datanode.http.address + 0.0.0.0:9864 + + + + dfs.datanode.ipc.address + 0.0.0.0:9867 + + + + dfs.datanode.du.reserved + 1073741824 + + + + dfs.datanode.use.datanode.hostname + false + + + + dfs.datanode.hostname + {{- .POD_FQDN }} + + + + dfs.ha.namenodes.{{- .CLUSTER_NAME }} + nn0,nn1 + + + dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn0 + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn1 + {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn0 + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn1 + {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + + dfs.client.failover.proxy.provider.{{- .CLUSTER_NAME }} + org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.client.block.write.replace-datanode-on-failure.policy + {{- .HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY }} + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + + + dfs.hosts + {{- .HDFS_CONF_DIR }}/dfs.include + + + + dfs.hosts.exclude + {{- .HDFS_CONF_DIR }}/dfs.exclude + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 1000,1 + + \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-journalnode-config-constraint.cue b/addons/hadoop/config/hdfs-journalnode-config-constraint.cue new file mode 100644 index 0000000000..a98583de7c --- /dev/null +++ b/addons/hadoop/config/hdfs-journalnode-config-constraint.cue @@ -0,0 +1,75 @@ +// Copyright (C) 2022-2023 ApeCloud Co., Ltd +// +// This file is part of KubeBlocks project +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#JournalNodeParameter: { + // 【说明】JournalNode守护进程存储其本地状态的路径。该路径是JournalNode在所在机器上的使用的用来存储edits和其状态一个绝对路径。只可以配置为单个路径。【默认值】${BIGDATA_DATADIR}/journalnode【注意】${BIGDATA_DATADIR}为系统安装时指定的集群数据根目录。请谨慎修改该项。如果配置不当,将造成服务不可用。 + "dfs.journalnode.edits.dir": string | *"/hadoop/dfs/journal" + + // Permissions for the directories on on the local filesystem where the DFS journal node stores the edits. The permissions can either be octal or symbolic. + "dfs.journalnode.edits.dir.perm": int | *"700" + + // The JournalNode RPC server address and port. + "dfs.journalnode.rpc-address": string | "0.0.0.0:8485" + + // The address and port the JournalNode HTTP server listens on. If the port is 0 then the server will start on a free port. + "dfs.journalnode.http-address": string | "0.0.0.0:8480" + + // The address and port the JournalNode HTTPS server listens on. If the port is 0 then the server will start on a free port. + "dfs.journalnode.https-address": string | "0.0.0.0:8481" + + // The actual address the HTTP server will bind to. If this optional address is set, it overrides only the hostname portion of dfs.journalnode.http-address. This is useful for making the JournalNode HTTP server listen on allinterfaces by setting it to 0.0.0.0. + "dfs.journalnode.enable.sync": bool | *true + + // 【说明】JournalNode在内存中缓存的edit logs的大小,单位是byte。该缓存用于备/从NameNode通过RPC机制跟踪edit logs,仅当dfs.ha.tail-edits.in-progress时有效。事务的平均大小约为200字节,因此该参数的默认值100MB可以储存大约500000个事务。【默认值】104857600【取值范围】大于1048576 + "dfs.journalnode.edit-cache-size.bytes": int & >=1048576 | *104857600 + + // Time interval, in milliseconds, between two Journal Node syncs. This configuration takes effect only if the journalnode sync is enabled by setting the configuration parameter dfs.journalnode.enable.sync to true. + "dfs.journalnode.sync.interval": int & >=1 & <=360000 | *120000 + + // 【说明】JVM用于gc的参数。仅当GC_PROFILE设置为custom时该配置才会生效。需确保GC_OPTS参数设置正确,否则进程启动会失败。【默认值】-Xms1G -Xmx2G -XX:NewSize=64M -XX:MaxNewSize=128M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M -Djdk.tls.ephemeralDHKeySize=3072 -Djdk.tls.rejectClientInitiatedRenegotiation=true -Djava.io.tmpdir=${Bigdata_tmp_dir} + "GC_OPTS": string | *"-Xms1G -Xmx2G -XX:NewSize=64M -XX:MaxNewSize=128M -XX:MetaspaceSize=128M -XX:MaxMetaspaceSize=128M -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:CMSInitiatingOccupancyFraction=65 -XX:PrintGCDateStamps -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=1M -Djdk.tls.ephemeralDHKeySize=3072 -Djdk.tls.rejectClientInitiatedRenegotiation=true -Djava.io.tmpdir=${Bigdata_tmp_dir}" + + // 【说明】设置可用于gc的内存大小等级。high表示4G,medium表示2G,low表示256M,custom表示根据实际数据量大小在GC_OPTS中设置内存大小。【默认值】custom【取值范围】high,medium,low,custom + "GC_PROFILE": string & ("high" | "medium" | "low" | "custom") | *"custom" + + // 【说明】web服务器允许的最大请求数。【默认值】2000【取值范围】1~1000000 + "hadoop.http.server.MaxRequests": int & >=1 & <=1000000 | *2000 + + // 【说明】运行日志文件的最大个数。【默认值】100【取值范围】1~999 + "hadoop.log.maxbackupindex": int & >=1 & <=999 | *100 + + // 【说明】单个运行日志文件的最大大小。【默认值】100 MB + "hadoop.log.maxfilesize": string | *"100MB" + + // 【说明】审计日志级别。【默认值】INFO【取值范围】TRACE、DEBUG、INFO、WARN、ERROR、OFF + "hdfs.audit.log.level": string & ("TRACE" | "DEBUG" | "INFO" | "WARN" | "ERROR" | "OFF") | *"INFO" + + // 【说明】审计日志文件的最大个数。【默认值】100【取值范围】1~999 + "hdfs.audit.log.maxbackupindex": int & >=1 & <=999 | *100 + + // 【说明】单个审计日志文件的最大大小。【默认值】100MB + "hdfs.audit.log.maxfilesize": string | *"100MB" + + // 【说明】日志级别。【默认值】INFO【取值范围】DEBUG、INFO、WARN、ERROR、FATAL + "hdfs.log.level": string & ("DEBUG" | "INFO" | "WARN" | "ERROR" | "FATAL") | *"INFO" + + // 【说明】安全审计日志级别。【默认值】WARN【取值范围】INFO、WARN、ERROR、OFF + "hdfs.security.log.level": string & ("INFO" | "WARN" | "ERROR" | "OFF") | *"WARN" + + // 【说明】用于指定写入Sequence文件时的缓冲数据的长度,也用于指定读写文件时的缓冲数据的长度,单位为Byte。【默认值】131072【取值范围】大于或等于4096【注意】该大小需要设置为硬件页面大小(Intel x86硬件上,页面大小为4096)的整数倍。 + "io.file.buffer.size": int & >=1024 | *131072 +} diff --git a/addons/hadoop/config/hdfs-journalnode.tpl b/addons/hadoop/config/hdfs-journalnode.tpl new file mode 100644 index 0000000000..bd3f1214a3 --- /dev/null +++ b/addons/hadoop/config/hdfs-journalnode.tpl @@ -0,0 +1,49 @@ + + + + + + dfs.nameservices + {{- .CLUSTER_NAME }} + + + + dfs.journalnode.edits.dir + {{- .HDFS_JOURNALNODE_EDITS_DIR }} + + + + dfs.journalnode.rpc-address + 0.0.0.0:{{- .HDFS_JOURNALNODE_RPC_PORT }} + + + + dfs.journalnode.http-address + 0.0.0.0:{{- .HDFS_JOURNALNODE_HTTP_PORT }} + + + + dfs.journalnode.bind-host + 0.0.0.0 + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.hosts + {{- .HDFS_CONF_DIR }}/dfs.include + + + + dfs.hosts.exclude + {{- .HDFS_CONF_DIR }}/dfs.exclude + + diff --git a/addons/hadoop/config/hdfs-namenode-config-constraint.cue b/addons/hadoop/config/hdfs-namenode-config-constraint.cue new file mode 100644 index 0000000000..79a9a1e0e4 --- /dev/null +++ b/addons/hadoop/config/hdfs-namenode-config-constraint.cue @@ -0,0 +1,252 @@ +// Copyright (C) 2022-2023 ApeCloud Co., Ltd +// +// This file is part of KubeBlocks project +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#NameNodeParameter: { + // Cluster + "dfs.nameservices"?: string | "{{- .CLUSTER_NAME }}" + + // DFS NameNode在本地文件系统存储事务(edits)文件的位置。默认值同dfs.namenode.name.dir的默认值 + "dfs.namenode.edits.dir": string | *"/hadoop/dfs/metadata" + + // DFS NameNode在本地文件系统存储fsimage的目录,默认值/hadoop/dfs/metadata + "dfs.namenode.name.dir": string | *"/hadoop/dfs/metadata" + + // 是否让NameNode尝试恢复失败的dfs.namenode.name.dir。默认值true,取值范围true或false + "dfs.namenode.name.dir.restore": bool | *true + + // 执行Balancer时,字节数小于该参数值的块将不会被移动(单位:字节)。默认值10485760,取值范围大于0 + "dfs.balancer.getBlocks.min-block-size": int | *10485760 + + // 在Balancer中,从NameNode获取源DataNode的块列表时,所获取的所有块的总大小 (单位:字节)。默认值2147483648,取值范围大于1073741824 + "dfs.balancer.getBlocks.size": int & >=1073741824 | *2147483648 + + // 执行Balancer时,每次迭代移动的最大字节数。默认值32212254720,取值范围大于1073741824 + "dfs.balancer.max-size-to-move": int & >=1073741824 | *32212254720 + + // 指定NameNode扫描DataNode待删除块的最大数量及向DataNode发送的待删除块数量。默认值10000,取值范围100~1000000 + "dfs.block.invalidate.limit": int & >=100 & <=1000000 | *10000 + + // 选择EC文件的块放置DataNode策略。默认值org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyRackFaultTolerant + "dfs.block.placement.ec.classname": string & ("org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyDefault" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithRackGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNonAffinityNodeGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyRackFaultTolerant" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithAZExpression") | *"org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyRackFaultTolerant" + + // 选择副本放置DataNode策略。默认值org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy + "dfs.block.replicator.classname": string & ("org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyDefault" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithRackGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeLabel" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNodeGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithNonAffinityNodeGroup" | "org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyRackFaultTolerant" | "org.apache.hadoop.hdfs.server.blockmanagement.BlockPlacementPolicyWithAZExpression") | *"org.apache.hadoop.hdfs.server.blockmanagement.AvailableSpaceBlockPlacementPolicy" + + // 每个校验和的字节数,不能大于dfs.stream-buffer-size值且必须能被dfs.blocksize值整除。默认值512,取值范围大于0 + "dfs.bytes-per-checksum": int & >=1 | *512 + + // 读取EC文件的并发线程数。默认值256,取值范围大于16 + "dfs.client.read.striped.threadpool.size": int & >=16 | *256 + + // 禁止移动写入指定DataNode上的数据块,默认为false。进行Balancer或Mover时,colocation写入的文件不会被移动 + "dfs.datanode.block-pinning.enabled": bool | *false + + // 设置DataNode向NameNode发送Lifeline协议消息的时间间隔。单位:秒,值必须大于dfs.heartbeat.interval的值 + "dfs.datanode.lifeline.interval.seconds"?: int + + // 设置磁盘均衡操作时磁盘存储量与理想状态的差异阈值,默认值10,取值范围1~100 + "dfs.disk.balancer.block.tolerance.percent": int & >=1 & <=100 | *10 + + // 设置数据移动过程中容忍的最大错误次数,超过此阈值则移动失败,默认值5,取值范围大于0 + "dfs.disk.balancer.max.disk.errors": int & >=1 | *5 + + // 设置Disk Balancer特性传输数据时使用的最大磁盘带宽,单位:MB/s,默认值10,取值范围大于0 + "dfs.disk.balancer.max.disk.throughputInMBperSec": int & >=1 | *10 + + // 设置两磁盘之间数据密度域值差的容忍阈值,超过此值则需要数据均衡,默认值10,取值范围1~100 + "dfs.disk.balancer.plan.threshold.percent": int & >=1 & <=100 | *10 + + // 备用节点连接主用节点进行edit日志拆分的时间间隔,单位:秒,默认值120,取值范围0~86400 + "dfs.ha.log-roll.period": int & <=86400 | *120 + + // 备用节点检查共享edit日志的时间间隔,单位:毫秒,默认值60000,取值范围0~864000 + "dfs.ha.tail-edits.period": int & <=864000 | *60000 + + // DataNode向NameNode发送心跳的时间间隔,单位:秒,默认值10,取值范围3~180 + "dfs.heartbeat.interval": int & >=3 & <=180 | *10 + + // 是否压缩fsimage,默认值false,取值范围true或false + "dfs.image.compress": bool | *false + + // 设置fsimage压缩的codec,默认值org.apache.hadoop.io.compress.DefaultCodec + "dfs.image.compression.codec": string & ("none" | "org.apache.hadoop.io.compress.BZip2Codec" | "org.apache.hadoop.io.compress.DefaultCodec" | "org.apache.hadoop.io.compress.DeflateCodec" | "org.apache.hadoop.io.compress.Lz4Codec" | "org.apache.hadoop.io.compress.SnappyCodec" | "org.apache.hadoop.io.compress.GzipCodec" | "org.apache.hadoop.io.compress.ZStandardCodec") | *"org.apache.hadoop.io.compress.DefaultCodec" + + // fsimage包含的inode数量少于该阈值时不生成sub-section,禁用并行加载特性,默认值1000000 + "dfs.image.parallel.inode.threshold": int & >=1 | *1000000 + + // 是否启用fsimage并行加载特性,默认值true,取值范围true或false + "dfs.image.parallel.load": bool | *true + + // 生成fsimage时将一个section分解为多少个sub-section,默认值100 + "dfs.image.parallel.target.sections": int & >=1 | *100 + + // 并行加载的线程数量,默认值50,取值范围大于等于1 + "dfs.image.parallel.threads": int & >=1 | *50 + + // fsimage传输带宽,单位:B/s,默认值104857600,取值范围0~1073741824 + "dfs.image.transfer.bandwidthPerSec": int & <=1073741824 | *104857600 + + // fsimage传输超时时间,单位:毫秒,默认值600000,取值范围1~3600000 + "dfs.image.transfer.timeout": int & >=1 & <=3600000 | *600000 + + // HDFS文件访问时间精确到该值,默认值3600000,取值范围大于等于0 + "dfs.namenode.accesstime.precision": int | *3600000 + + // 是否启用HDFS ACL,默认值true,取值范围true或false + "dfs.namenode.acls.enabled": bool | *true + + // 是否启用异步审计日志,默认值false,取值范围true或false + "dfs.namenode.audit.log.async": bool | *false + + // 审计日志命令列表,默认值"open,getfileinfo,getAclStatus" + "dfs.namenode.audit.log.debug.cmdlist": string | *"open,getfileinfo,getAclStatus" + + // 是否优先选择客户端所在节点的DataNode,默认值false + "dfs.namenode.available-space-block-placement-policy.balance-local-node": bool | *false + + // 控制新块分配到拥有更多可用磁盘空间的DataNode的比例,默认值0.6,取值范围0~1 + "dfs.namenode.available-space-block-placement-policy.balanced-space-preference-fraction": number | *0.6 + + // 是否避免写入失效DataNode,默认值true,取值范围true或false + "dfs.namenode.avoid.write.stale.datanode": bool | *true + + // 增量删除块的数量,默认值1000,取值范围大于等于1 + "dfs.namenode.block.deletion.increment": int & >=1 | *1000 + + // 备NameNode每隔dfs.namenode.checkpoint.check.period秒轮询查询未检查点的事务,默认值60,取值范围0~86400 + "dfs.namenode.checkpoint.check.period": int & <=86400 | *60 + + // 两个检查点间的时间间隔,单位:秒,默认值3600 + "dfs.namenode.checkpoint.period": int | *360 + + // 让备NameNode或检查点节点创建检查点的事务数,无论"dfs.namenode.checkpoint.period"是否到达。默认值5000000,取值范围1~10000000000 + "dfs.namenode.checkpoint.txns": int & >=1 & <=10000000000 | *5000000 + + // EC策略可以设置的数据块大小的最大值,单位为Byte。默认值4194304,取值范围大于131072 + "dfs.namenode.ec.policies.max.cellsize": int & >=131072 | *4194304 + + // 给目录设置EC策略时,如果不指定具体的EC策略,将默认使用该策略。默认值RS-6-3-1024k + "dfs.namenode.ec.system.default.policy": string & ("RS-3-2-1024k" | "RS-6-3-1024k" | "RS-10-4-1024k" | "RS-LEGACY-6-3-1024k" | "XOR-2-1-1024k") | *"RS-6-3-1024k" + + // 是否对edit日志文件通道进行持久化。默认值false + "dfs.namenode.edits.noeditlogchannelflush": bool | *false + + // 是否在NameNode启用重试缓存。默认值true,取值范围true或false + "dfs.namenode.enable.retrycache": bool | *true + + // 所有块提交后文件才关闭,N个块提交且其他块完成后才关闭文件。默认值0,取值范围大于等于0 + "dfs.namenode.file.close.num-committed-allowed": int | *0 + + // 每个文件可包含的最大块数,NameNode写操作时使用。默认值1048576,取值范围大于0 + "dfs.namenode.fs-limits.max-blocks-per-file": int & >=1 | *1048576 + + // 定义路径的每个组成部分中的最大UTF-8编码字节数。默认值7999,取值范围255~7999 + "dfs.namenode.fs-limits.max-component-length": int & >=255 & <=7999 | *7999 + + // 定义目录中包含的最大条目数。默认值1048576,取值范围1~6400000 + "dfs.namenode.fs-limits.max-directory-items": int & >=1 & <=6400000 | *1048576 + + // 最小块大小,NameNode创建块时使用。单位:字节,默认值1048576,取值范围大于0 + "dfs.namenode.fs-limits.min-block-size": int & >=1 | *1048576 + + // NameNode的RPC服务端用于监听客户端请求的线程数。默认值128,取值范围1~1024 + "dfs.namenode.handler.count": int & >=1 & <=1024 | *128 + + // 再次检查DataNode可用性的间隔,单位:毫秒。默认值300000,取值范围1000~86400000 + "dfs.namenode.heartbeat.recheck-interval": int & >=1000 & <=86400000 | *300000 + + // Inode属性插件。默认值com.huawei.hadoop.adapter.hdfs.plugin.HWRangerHdfsAuthorizer + "dfs.namenode.inode.attributes.provider.class": string | *"com.huawei.hadoop.adapter.hdfs.plugin.HWRangerHdfsAuthorizer" + + // NameNode扫描待删除块时扫描的DataNode数量占总DN数量的百分比。默认值0.32,取值范围0~1 + "dfs.namenode.invalidate.work.pct.per.iteration": number | *0.32 + + // NameNode的RPC服务端用于处理DataNode的lifeline协议和HA健康检查请求的线程数。默认值16,取值范围1~1024 + "dfs.namenode.lifeline.handler.count": int & >=1 & <=1024 | *16 + + // NameNode保存的fsimage文件个数。默认值3,取值范围1~86400 + "dfs.namenode.num.checkpoints.retained": int & >=1 & <=86400 | *3 + + // 为NameNode重启所保留的额外事务数。默认值1000000,取值范围大于等于0 + "dfs.namenode.num.extra.edits.retained": int | *1000000 + + // 为缓存块映射分配的Java堆比例。默认值"0.25f" + "dfs.namenode.path.based.cache.block.map.allocation.percent": string | *"0.25f" + + // 初始化Quota的并发线程数。默认值32,取值范围大于0 + "dfs.namenode.quota.init-threads": int & >=1 | *32 + + // 块重建的超时参数,单位:秒。默认值900,取值范围大于等于-1 + "dfs.namenode.reconstruction.pending.timeout-sec": int & >=-1 | *900 + + // 给新文件选择DataNode时是否考虑DataNode的负载。默认值true,取值范围true或false + "dfs.namenode.redundancy.considerLoad": bool | *true + + // 当DataNode负载超过平均负载的倍数时,不会选择它存储新文件。默认值4,取值范围1~100 + "dfs.namenode.redundancy.considerLoad.factor": number | *4 + + // NameNode发送块复制命令时并行传输的块总量。默认值32,取值范围0~9223372036854775807 + "dfs.namenode.replication.work.multiplier.per.iteration": int & <=9223372036854775807 | *32 + + // 重试缓存条目保留时长,单位:毫秒。默认值600000,取值范围大于0 + "dfs.namenode.retrycache.expirytime.millis": int & >=1 | *600000 + + // 为重试缓存分配的堆大小比例。默认值"0.03f" + "dfs.namenode.retrycache.heap.percent": string | *"0.03f" + + // NameNode退出安全模式前的时间,单位:毫秒。默认值15000,取值范围0~3600000 + "dfs.namenode.safemode.extension": int & <=3600000 | *15000 + + // NameNode退出安全模式前必须处于alive状态的DataNode数。默认值0,取值范围0~65535 + "dfs.namenode.safemode.min.datanodes": int & <=65535 | *0 + + // NameNode的RPC服务端用于监听DataNode请求的线程数。默认值32,取值范围1~1024 + "dfs.namenode.service.handler.count": int & >=1 & <=1024 | *32 + + // 将DataNode标记为失效的时间间隔。默认值30000,取值范围大于0 + "dfs.namenode.stale.datanode.interval": int | *30000 + + // NameNode启动后,块删除的延迟时间,单位:秒。默认值3600,取值范围0~65535 + "dfs.namenode.startup.delay.block.deletion.sec": int & <=65535 | *3600 + + // 当失效DataNode数和总数比值大于该比例时,停止避免写入失效DataNode。默认值0.5f,取值范围0~1f + "dfs.namenode.write.stale.datanode.ratio": string | *"0.5f" + + // 是否为HDFS启用权限检查。默认值true,取值范围true或false + "dfs.permissions.ContentSummary.subAccess": bool | *true + + // 是否为HDFS启用权限检查。默认值true,取值范围true或false + "dfs.permissions.enabled": bool | *true + + // quorum journal edits的队列大小,单位:MB。默认值150,取值范围10~4096 + "dfs.qjournal.queued-edits.limit.mb": int & >=10 & <=4096 | *150 + + // 将事务写入大部分quorum journal节点的等待时间,单位:毫秒。默认值20000,取值范围1~3600000 + "dfs.qjournal.write-txns.timeout.ms": int & >=1 & <=3600000 | *20000 + + // 最大块副本数。默认值512,取值范围3~1024 + "dfs.replication.max": int & >=3 & <=1024 | *512 + + // 启用异构存储。默认值true,取值范围true或false + "dfs.storage.policy.enabled": bool | *true + + // 流文件缓冲区大小。默认值4096,取值范围大于0 + "dfs.stream-buffer-size": int & >=1 | *4096 + + // 是否使用DFSNetworkTopology选择副本放置的DataNode。默认值true,取值范围true或false + "dfs.use.dfs.network.topology": bool | *true +} diff --git a/addons/hadoop/config/hdfs-namenode-standalone.tpl b/addons/hadoop/config/hdfs-namenode-standalone.tpl new file mode 100644 index 0000000000..6159dc67be --- /dev/null +++ b/addons/hadoop/config/hdfs-namenode-standalone.tpl @@ -0,0 +1,89 @@ + + + + + + dfs.namenode.name.dir + {{- .HDFS_NAMENODE_NAME_DIR }} + + + + dfs.namenode.rpc-address + 0.0.0.0:{{- .HDFS_NAMENODE_RPC_PORT }} + + + + dfs.namenode.http-address + 0.0.0.0:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + + dfs.namenode.rpc-bind-host + 0.0.0.0 + + + + dfs.namenode.http-bind-host + 0.0.0.0 + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + + + dfs.permissions.superusergroup + hadoop + + + + dfs.namenode.datanode.registration.ip-hostname-check + {{- .HDFS_REGISTRATION_IP_HOSTNAME_CHECK }} + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.replication.max + {{- .HDFS_REPLICATION_MAX }} + + + + dfs.client.block.write.replace-datanode-on-failure.policy + {{- .HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY }} + + + + dfs.namenode.handler.count + {{- .HDFS_NAMENODE_HANDLER_COUNT }} + + + + dfs.hosts + {{- .HDFS_CONF_DIR }}/dfs.include + + + + dfs.hosts.exclude + {{- .HDFS_CONF_DIR }}/dfs.exclude + + + + dfs.webhdfs.enabled + false + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 1000,1 + + diff --git a/addons/hadoop/config/hdfs-namenode.tpl b/addons/hadoop/config/hdfs-namenode.tpl new file mode 100644 index 0000000000..a1401e2c07 --- /dev/null +++ b/addons/hadoop/config/hdfs-namenode.tpl @@ -0,0 +1,221 @@ + + + +{{- $fqnds := splitList "," .JOURNALNODE_POD_FQDN_LIST }} +{{- $journalnode_fqdns := printf "qjournal://" }} +{{- $journalnode_rpc_port := .HDFS_JOURNALNODE_RPC_PORT }} +{{- range $i, $fqdn := $fqnds }} +{{- $journalnode_fqdns = printf "%s%s:%s" $journalnode_fqdns $fqdn $journalnode_rpc_port }} +{{- if lt $i (sub (len $fqnds) 1) }} +{{- $journalnode_fqdns = printf "%s;" $journalnode_fqdns }} +{{- end }} +{{- end }} +{{- $journalnode_fqdns = printf "%s/%s" $journalnode_fqdns .CLUSTER_NAME }} + + + + dfs.nameservices + {{- .CLUSTER_NAME }} + + + + dfs.namenode.name.dir + {{- .HDFS_NAMENODE_NAME_DIR }} + + + + dfs.ha.namenodes.{{- .CLUSTER_NAME }} + nn0,nn1 + + + + dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn0 + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn1 + {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + + + + dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn0 + {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn1 + {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- + .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + + + + dfs.namenode.rpc-bind-host + 0.0.0.0 + + + dfs.namenode.http-bind-host + 0.0.0.0 + + + + dfs.namenode.shared.edits.dir + {{- $journalnode_fqdns }} + + + + dfs.client.failover.proxy.provider.{{- .CLUSTER_NAME }} + org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider + + + + dfs.ha.fencing.methods + {{- .HDFS_HA_FENCING_METHODS }} + + + + dfs.ha.fencing.ssh.private-key-files + /var/lib/hadoop-hdfs/.ssh/id_dsa + + + + dfs.ha.fencing.ssh.connect-timeout + 30000 + + + + dfs.ha.automatic-failover.enabled + {{- .HDFS_HA_AUTOMATIC_FAILOVER_ENABLED }} + + + + dfs.ha.failover-controller.active-standby-elector.zk.op.retries + {{- .HDFS_HA_ZOOKEEPER_OPERATION_RETRIES }} + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + + + dfs.permissions.superusergroup + hadoop + + + + dfs.namenode.datanode.registration.ip-hostname-check + {{- .HDFS_REGISTRATION_IP_HOSTNAME_CHECK }} + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.replication.max + {{- .HDFS_REPLICATION_MAX }} + + + + dfs.client.block.write.replace-datanode-on-failure.policy + {{- .HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY }} + + + + dfs.namenode.handler.count + {{- .HDFS_NAMENODE_HANDLER_COUNT }} + + + + dfs.namenode.service.handler.count + {{- .HDFS_NAMENODE_HANDLER_COUNT }} + + + + dfs.hosts + {{- .HDFS_CONF_DIR }}/dfs.include + + + + dfs.hosts.exclude + {{- .HDFS_CONF_DIR }}/dfs.exclude + + + + dfs.webhdfs.enabled + false + + + + dfs.datanode.block-pinning.enabled + true + + + + dfs.namenode.avoid.read.stale.datanode + true + + + + dfs.namenode.avoid.write.stale.datanode + true + + + + dfs.namenode.resource.du.reserved + 1073741824 + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 1000,1 + + + + dfs.namenode.stale.datanode.interval + 30000 + + + + dfs.ha.log-roll.period + 120 + + + + dfs.ha.tail-edits.period + 60 + + + + dfs.image.transfer.bandwidthPerSec + 0 + + + + dfs.namenode.num.checkpoints.retained + 2 + + + + dfs.namenode.num.extra.edits.retained + 1000000 + + + + dfs.journalnode.http-address + 0.0.0.0:8480 + + + + dfs.journalnode.rpc-address + 0.0.0.0:8485 + + \ No newline at end of file diff --git a/addons/hadoop/config/log4j.properties b/addons/hadoop/config/log4j.properties new file mode 100644 index 0000000000..91504edb77 --- /dev/null +++ b/addons/hadoop/config/log4j.properties @@ -0,0 +1,59 @@ +# Set root logger level to INFO and output to console and file +log4j.rootLogger=INFO, console, file + +# Console log output +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# File log output +log4j.appender.file=org.apache.log4j.RollingFileAppender +log4j.appender.file.File=${hadoop.log.dir}/hadoop.log +log4j.appender.file.MaxFileSize=256MB +log4j.appender.file.MaxBackupIndex=5 +log4j.appender.file.layout=org.apache.log4j.PatternLayout +log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# NameNode log configuration +log4j.logger.org.apache.hadoop.hdfs.server.namenode.NameNode=INFO, namenodeAppender +log4j.appender.namenodeAppender=org.apache.log4j.RollingFileAppender +log4j.appender.namenodeAppender.File=${hadoop.log.dir}/hadoop-hdfs-namenode.log +log4j.appender.namenodeAppender.MaxFileSize=256MB +log4j.appender.namenodeAppender.MaxBackupIndex=5 +log4j.appender.namenodeAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.namenodeAppender.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# DataNode log configuration +log4j.logger.org.apache.hadoop.hdfs.server.datanode.DataNode=INFO, datanodeAppender +log4j.appender.datanodeAppender=org.apache.log4j.RollingFileAppender +log4j.appender.datanodeAppender.File=${hadoop.log.dir}/hadoop-hdfs-datanode.log +log4j.appender.datanodeAppender.MaxFileSize=256MB +log4j.appender.datanodeAppender.MaxBackupIndex=5 +log4j.appender.datanodeAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.datanodeAppender.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# ResourceManager log configuration +log4j.logger.org.apache.hadoop.yarn.server.resourcemanager.ResourceManager=INFO, resourcemanagerAppender +log4j.appender.resourcemanagerAppender=org.apache.log4j.RollingFileAppender +log4j.appender.resourcemanagerAppender.File=${hadoop.log.dir}/hadoop-yarn-resourcemanager.log +log4j.appender.resourcemanagerAppender.MaxFileSize=256MB +log4j.appender.resourcemanagerAppender.MaxBackupIndex=5 +log4j.appender.resourcemanagerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.resourcemanagerAppender.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# NodeManager log configuration +log4j.logger.org.apache.hadoop.yarn.server.nodemanager.NodeManager=INFO, nodemanagerAppender +log4j.appender.nodemanagerAppender=org.apache.log4j.RollingFileAppender +log4j.appender.nodemanagerAppender.File=${hadoop.log.dir}/hadoop-yarn-nodemanager.log +log4j.appender.nodemanagerAppender.MaxFileSize=256MB +log4j.appender.nodemanagerAppender.MaxBackupIndex=5 +log4j.appender.nodemanagerAppender.layout=org.apache.log4j.PatternLayout +log4j.appender.nodemanagerAppender.layout.ConversionPattern=%d{ISO8601} %-5p %c{2}: %m%n + +# Log configuration for other components +log4j.logger.org.apache.hadoop.security=INFO +log4j.logger.org.apache.hadoop.ipc=INFO +log4j.logger.org.apache.hadoop.mapred=INFO +log4j.logger.org.apache.hadoop.hdfs=INFO +log4j.logger.org.apache.hadoop.yarn=INFO diff --git a/addons/hadoop/releases_notes.yaml b/addons/hadoop/releases_notes.yaml new file mode 100644 index 0000000000..5816a13013 --- /dev/null +++ b/addons/hadoop/releases_notes.yaml @@ -0,0 +1,5 @@ +releases: + - version: 1.1.0 + notes: + en: Initial HDFS HA cluster support on KubeBlocks + zh: 在 KubeBlocks 上的初始 HDFS HA 集群支持 \ No newline at end of file diff --git a/addons/hadoop/scripts/check-data-status.sh b/addons/hadoop/scripts/check-data-status.sh new file mode 100644 index 0000000000..3ee9371bac --- /dev/null +++ b/addons/hadoop/scripts/check-data-status.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +_PORTS="9864" +_URL_PATH="jmx?qry=Hadoop:service=DataNode,name=DataNodeInfo" +_CLUSTER_ID="" +for _PORT in $_PORTS; do + _CLUSTER_ID+=$(curl -s http://localhost:${_PORT}/$_URL_PATH | grep ClusterId) || true +done +echo $_CLUSTER_ID | grep -q -v null diff --git a/addons/hadoop/scripts/check-journal-status.sh b/addons/hadoop/scripts/check-journal-status.sh new file mode 100644 index 0000000000..9bed332a6b --- /dev/null +++ b/addons/hadoop/scripts/check-journal-status.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# Exit on error. Append "|| true" if you expect an error. +set -o errexit +# Exit on error inside any functions or subshells. +set -o errtrace +# Do not allow use of undefined vars. Use ${VAR:-} to use an undefined VAR +set -o nounset +# Catch an error in command pipes. e.g. mysqldump fails (but gzip succeeds) +# in `mysqldump |gzip` +set -o pipefail +# Turn on traces, useful while debugging. +set -o xtrace + +# Check if datanode registered with the namenode and got non-null cluster ID. +_PORTS="8480" +_URL_PATH="jmx?qry=Hadoop:service=JournalNode,name=JournalNodeInfo" +_CLUSTER_ID="" +for _PORT in $_PORTS; do + _CLUSTER_ID+=$(curl -s http://localhost:${_PORT}/$_URL_PATH | \ + grep ClusterId) || true +done +echo $_CLUSTER_ID | grep -q -v null \ No newline at end of file diff --git a/addons/hadoop/scripts/check-name-status.sh b/addons/hadoop/scripts/check-name-status.sh new file mode 100644 index 0000000000..d309144ad1 --- /dev/null +++ b/addons/hadoop/scripts/check-name-status.sh @@ -0,0 +1,30 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +_NN_HTTP_PORT=9870 + +CLUSTER_ID_RESP=$(curl -s --connect-timeout 5 --max-time 10 "http://localhost:${_NN_HTTP_PORT}/jmx?qry=Hadoop:service=NameNode,name=NameNodeInfo" 2>/dev/null || echo "") +if echo "${CLUSTER_ID_RESP}" | grep -q '"ClusterId"'; then + NN_STATUS=$(curl -s --connect-timeout 5 --max-time 10 "http://localhost:${_NN_HTTP_PORT}/jmx?qry=Hadoop:service=NameNode,name=NameNodeStatus" 2>/dev/null || echo "") + STATE=$(echo "${NN_STATUS}" | grep -o '"State"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"State"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/') + if [[ -z "$STATE" ]]; then + echo "NameNode is up but state could not be determined, considering alive" + exit 0 + fi + if [[ "$STATE" == "active" || "$STATE" == "standby" ]]; then + echo "NameNode is ${STATE}" + exit 0 + fi + echo "NameNode is in unexpected state: ${STATE}" + exit 1 +fi + +echo "NameNode JMX not ready yet" +exit 1 diff --git a/addons/hadoop/scripts/datanode-decommission.sh b/addons/hadoop/scripts/datanode-decommission.sh new file mode 100644 index 0000000000..d8ea6c32f1 --- /dev/null +++ b/addons/hadoop/scripts/datanode-decommission.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +EXCLUDE_FILE="${HADOOP_CONF_DIR}/dfs.exclude" +CURRENT_HOST=$(hostname -f 2>/dev/null || hostname) + +echo "[$(date)] Starting DataNode decommission for ${CURRENT_HOST}..." + +if [[ -f "$EXCLUDE_FILE" ]]; then + if grep -q "${CURRENT_HOST}" "$EXCLUDE_FILE" 2>/dev/null; then + echo "[$(date)] Host already in exclude file" + else + echo "${CURRENT_HOST}" >> "$EXCLUDE_FILE" + fi +else + echo "${CURRENT_HOST}" > "$EXCLUDE_FILE" +fi + +"${HADOOP_HOME}/bin/hdfs" dfsadmin -refreshNodes || true + +echo "[$(date)] Waiting for decommission to complete (max wait 300s)..." +for i in $(seq 1 60); do + DECOMM_STATUS=$("${HADOOP_HOME}/bin/hdfs" dfsadmin -report 2>/dev/null | grep -A 5 "Name: ${CURRENT_HOST}" | grep "Decommission Status" | head -1 || echo "") + if echo "$DECOMM_STATUS" | grep -q "Decommissioned"; then + echo "[$(date)] DataNode ${CURRENT_HOST} successfully decommissioned" + exit 0 + fi + sleep 5 +done + +echo "[$(date)] Decommission wait timed out, proceeding with shutdown anyway" +exit 0 diff --git a/addons/hadoop/scripts/init-namenode-format.sh b/addons/hadoop/scripts/init-namenode-format.sh new file mode 100644 index 0000000000..74a3ff4b62 --- /dev/null +++ b/addons/hadoop/scripts/init-namenode-format.sh @@ -0,0 +1,38 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +POD_NAME="${POD_NAME:-$(hostname)}" +if [[ "$POD_NAME" != *"-0" ]] && [[ "$(hostname)" != *"-0" ]]; then + echo "Only namenode ordinal 0 formats; this pod is $(hostname), skipping format" + exit 0 +fi + +SLEEP_TIME=$((RANDOM % 120)) +echo "Sleeping ${SLEEP_TIME}s to reduce race risk between NN-0 and NN-1 bootstrap..." +sleep "$SLEEP_TIME" + +NAME_DIRS=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.namenode.name.dir 2>/dev/null || echo "") +NN_DIR="${NAME_DIRS%%,*}" +NN_DIR="${NN_DIR#file://}" +NN_CURRENT_DIR="${NN_DIR}/current" + +if [[ -d "$NN_CURRENT_DIR" ]] && find "$NN_CURRENT_DIR" -maxdepth 1 -type f -name 'fsimage_*' ! -name '*.md5' 2>/dev/null | grep -q .; then + echo "Valid fsimage already exists, skipping format" + exit 0 +fi + +NAMESERVICES=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.nameservices 2>/dev/null || echo "") +if [[ -z "$NAMESERVICES" ]]; then + echo "No dfs.nameservices configured (standalone mode), using default format" + echo "N" | "${HADOOP_HOME}/bin/hdfs" namenode -format || true +else + echo "Formatting NameNode for nameservice ${NAMESERVICES}" + echo "N" | "${HADOOP_HOME}/bin/hdfs" namenode -format "$NAMESERVICES" || true +fi diff --git a/addons/hadoop/scripts/init-nn-bootstrap-standby.sh b/addons/hadoop/scripts/init-nn-bootstrap-standby.sh new file mode 100644 index 0000000000..cc350a69f4 --- /dev/null +++ b/addons/hadoop/scripts/init-nn-bootstrap-standby.sh @@ -0,0 +1,48 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +NAME_DIRS=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.namenode.name.dir 2>/dev/null || echo "") +if [[ -z "$NAME_DIRS" ]]; then + echo "No dfs.namenode.name.dir configured, skipping bootstrapStandby" + exit 0 +fi + +NN_DIR="${NAME_DIRS%%,*}" +NN_DIR="${NN_DIR#file://}" +NN_CURRENT_DIR="${NN_DIR}/current" + +has_valid_fsimage() { + [[ -d "$NN_CURRENT_DIR" ]] || return 1 + find "$NN_CURRENT_DIR" -maxdepth 1 -type f -name 'fsimage_*' ! -name '*.md5' 2>/dev/null | grep -q . +} + +if has_valid_fsimage; then + echo "Valid fsimage found at ${NN_CURRENT_DIR}, skipping bootstrapStandby" + exit 0 +fi + +if [[ -d "$NN_CURRENT_DIR" ]]; then + BACKUP_DIR="${NN_CURRENT_DIR}.incomplete.$(date +%s)" + echo "Incomplete metadata found, moving ${NN_CURRENT_DIR} to ${BACKUP_DIR}" + mv "$NN_CURRENT_DIR" "$BACKUP_DIR" || true +fi + +echo "No valid fsimage, running bootstrapStandby with retries..." +for attempt in $(seq 1 30); do + if "${HADOOP_HOME}/bin/hdfs" namenode -bootstrapStandby -nonInteractive; then + echo "bootstrapStandby succeeded on attempt ${attempt}" + exit 0 + fi + echo "bootstrapStandby failed on attempt ${attempt}, retrying in 10s..." + sleep 10 +done + +echo "bootstrapStandby failed after 30 attempts" +exit 1 diff --git a/addons/hadoop/scripts/init-refresh-nodes.sh b/addons/hadoop/scripts/init-refresh-nodes.sh new file mode 100644 index 0000000000..ccfa149ff0 --- /dev/null +++ b/addons/hadoop/scripts/init-refresh-nodes.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +echo "[$(date)] Refreshing DataNode include/exclude lists on NameNode..." +"${HADOOP_HOME}/bin/hdfs" dfsadmin -refreshNodes || true +echo "[$(date)] refreshNodes completed" diff --git a/addons/hadoop/scripts/init-zkfc-format.sh b/addons/hadoop/scripts/init-zkfc-format.sh new file mode 100644 index 0000000000..deae5f36a2 --- /dev/null +++ b/addons/hadoop/scripts/init-zkfc-format.sh @@ -0,0 +1,13 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR + +echo "Formatting ZKFC (creating HA znode in ZooKeeper)..." +echo "N" | "${HADOOP_HOME}/bin/hdfs" zkfc -formatZK || true +echo "ZKFC format completed" diff --git a/addons/hadoop/scripts/start-datanode.sh b/addons/hadoop/scripts/start-datanode.sh new file mode 100644 index 0000000000..83c882e47e --- /dev/null +++ b/addons/hadoop/scripts/start-datanode.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +: "${HADOOP_LOG_DIR:=/var/log/hadoop}" +: "${HADOOP_PID_DIR:=/tmp/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR HADOOP_LOG_DIR HADOOP_PID_DIR +mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" + +USER=$(whoami) +LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-datanode-$(hostname).log" + +shutdown() { + echo "[$(date)] Stopping DataNode..." + "${HADOOP_HOME}/bin/hdfs" --daemon stop datanode || true + exit 0 +} +trap shutdown SIGTERM SIGINT + +echo "[$(date)] Starting DataNode..." +"${HADOOP_HOME}/bin/hdfs" datanode 2>&1 | tee -a "$LOG_FILE" & +DN_PID=$! +wait $DN_PID diff --git a/addons/hadoop/scripts/start-journalnode.sh b/addons/hadoop/scripts/start-journalnode.sh new file mode 100644 index 0000000000..2652a7b41b --- /dev/null +++ b/addons/hadoop/scripts/start-journalnode.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +: "${HADOOP_LOG_DIR:=/var/log/hadoop}" +: "${HADOOP_PID_DIR:=/tmp/hadoop}" +export HADOOP_HOME HADOOP_CONF_DIR HADOOP_LOG_DIR HADOOP_PID_DIR +mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" + +USER=$(whoami) +LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-journalnode-$(hostname).log" + +shutdown() { + echo "[$(date)] Stopping JournalNode..." + "${HADOOP_HOME}/bin/hdfs" --daemon stop journalnode || true + exit 0 +} +trap shutdown SIGTERM SIGINT + +echo "[$(date)] Starting JournalNode..." +"${HADOOP_HOME}/bin/hdfs" journalnode 2>&1 | tee -a "$LOG_FILE" & +JN_PID=$! +wait $JN_PID diff --git a/addons/hadoop/scripts/start-namenode.sh b/addons/hadoop/scripts/start-namenode.sh new file mode 100644 index 0000000000..e20fb39142 --- /dev/null +++ b/addons/hadoop/scripts/start-namenode.sh @@ -0,0 +1,81 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +: "${HADOOP_LOG_DIR:=/var/log/hadoop}" +: "${HADOOP_PID_DIR:=/tmp/hadoop}" +: "${LIFECYCLE_DIR:=/lifecycle}" + +export HADOOP_HOME HADOOP_CONF_DIR HADOOP_LOG_DIR HADOOP_PID_DIR +mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" "${LIFECYCLE_DIR}" + +USER=$(whoami) +LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-namenode-$(hostname).log" + +shutdown() { + echo "[$(date)] Received SIGTERM, stopping NameNode gracefully..." + local is_active=0 + if "${HADOOP_HOME}/bin/hdfs" haadmin -getAllServiceState 2>/dev/null | grep -q "$(hostname -f).*active"; then + is_active=1 + fi + + if [[ $is_active -eq 1 ]]; then + local nameservices standby_service="" + nameservices=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.nameservices 2>/dev/null || echo "") + if [[ -n "$nameservices" ]]; then + local nns + nns=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.ha.namenodes.${nameservices}" 2>/dev/null || echo "") + for nn_id in $(echo "$nns" | tr ',' '\n'); do + local state + state=$("${HADOOP_HOME}/bin/hdfs" haadmin -getServiceState "$nn_id" 2>/dev/null || echo "") + if [[ "$state" == "standby" ]]; then + standby_service="$nn_id" + break + fi + done + + local my_service="" + for nn_id in $(echo "$nns" | tr ',' '\n'); do + local rpc_addr + rpc_addr=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.namenode.rpc-address.${nameservices}.${nn_id}" 2>/dev/null || echo "") + local rpc_host="${rpc_addr%:*}" + if [[ "$rpc_host" == "$(hostname -f)" ]] || [[ "$rpc_host" == "$(hostname)" ]]; then + my_service="$nn_id" + break + fi + done + + if [[ -n "$my_service" && -n "$standby_service" && "$my_service" != "$standby_service" ]]; then + echo "[$(date)] Active NN ${my_service}, failing over to standby ${standby_service}" + "${HADOOP_HOME}/bin/hdfs" haadmin -failover "$my_service" "$standby_service" || true + else + echo "[$(date)] Cannot determine my_service/standby_service (my=${my_service}, standby=${standby_service}), skipping explicit failover" + fi + fi + echo "[$(date)] Waiting 60s for failover to complete..." + sleep 60 + else + echo "[$(date)] NameNode is not active, no failover needed" + fi + + touch "${LIFECYCLE_DIR}/nn-terminated" + echo "[$(date)] Stopping NameNode daemon" + "${HADOOP_HOME}/bin/hdfs" --daemon stop namenode || true + exit 0 +} + +EXCLUDE_PATH=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.hosts.exclude 2>/dev/null || echo "") +if [[ -n "$EXCLUDE_PATH" ]]; then + touch "$EXCLUDE_PATH" || true +fi + +trap shutdown SIGTERM SIGINT + +echo "[$(date)] Starting NameNode..." +"${HADOOP_HOME}/bin/hdfs" namenode 2>&1 | tee -a "$LOG_FILE" & +NN_PID=$! +wait $NN_PID diff --git a/addons/hadoop/scripts/start-zkfc.sh b/addons/hadoop/scripts/start-zkfc.sh new file mode 100644 index 0000000000..7c576d9fd4 --- /dev/null +++ b/addons/hadoop/scripts/start-zkfc.sh @@ -0,0 +1,37 @@ +#!/usr/bin/env bash +set -o errexit +set -o errtrace +set -o nounset +set -o pipefail + +: "${HADOOP_HOME:=/opt/hadoop}" +: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" +: "${HADOOP_LOG_DIR:=/var/log/hadoop}" +: "${HADOOP_PID_DIR:=/tmp/hadoop}" +: "${LIFECYCLE_DIR:=/lifecycle}" + +export HADOOP_HOME HADOOP_CONF_DIR HADOOP_LOG_DIR HADOOP_PID_DIR +mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" "${LIFECYCLE_DIR}" + +USER=$(whoami) +LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-zkfc-$(hostname).log" + +shutdown() { + echo "[$(date)] Received SIGTERM, waiting for NameNode to terminate..." + while true; do + if [[ -f "${LIFECYCLE_DIR}/nn-terminated" ]]; then + echo "[$(date)] NameNode terminated signal received, stopping ZKFC" + sleep 10 + "${HADOOP_HOME}/bin/hdfs" --daemon stop zkfc || true + exit 0 + fi + sleep 2 + done +} + +trap shutdown SIGTERM SIGINT + +echo "[$(date)] Starting ZKFC..." +"${HADOOP_HOME}/bin/hdfs" zkfc 2>&1 | tee -a "$LOG_FILE" & +ZKFC_PID=$! +wait $ZKFC_PID diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl new file mode 100644 index 0000000000..112e3753de --- /dev/null +++ b/addons/hadoop/templates/_helpers.tpl @@ -0,0 +1,102 @@ +{{/* +Chart name +*/}} +{{- define "hadoop.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Chart name and version for labels +*/}} +{{- define "hadoop.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hadoop.labels" -}} +helm.sh/chart: {{ include "hadoop.chart" . }} +{{ include "hadoop.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hadoop.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hadoop.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Common annotations +*/}} +{{- define "hadoop.annotations" -}} +{{ include "kblib.helm.resourcePolicy" . }} +{{ include "hadoop.apiVersion" . }} +{{- end }} + +{{/* +API version annotation +*/}} +{{- define "hadoop.apiVersion" -}} +kubeblocks.io/crd-api-version: apps.kubeblocks.io/v1 +{{- end }} + +{{/* +Component definition regex patterns +*/}} +{{- define "hadoop.hadoopCoreCmpdRegexPattern" -}} +^hadoop-core$ +{{- end }} + +{{- define "hadoop.hadoopCoreStandaloneCmpdRegexPattern" -}} +^hadoop-core-standalone$ +{{- end }} + +{{- define "hadoop.hdfsJournalnodeCmpdRegexPattern" -}} +^hdfs-journalnode$ +{{- end }} + +{{- define "hadoop.hdfsNamenodeCmpdRegexPattern" -}} +^hdfs-namenode$ +{{- end }} + +{{- define "hadoop.hdfsNamenodeStandaloneCmpdRegexPattern" -}} +^hdfs-namenode-standalone$ +{{- end }} + +{{- define "hadoop.hdfsDatanodeCmpdRegexPattern" -}} +^hdfs-datanode$ +{{- end }} + +{{- define "hadoop.hdfsDatanodeStandaloneCmpdRegexPattern" -}} +^hdfs-datanode-standalone$ +{{- end }} + +{{/* +Image references +*/}} +{{- define "hadoop.commonImage" -}} +{{ .Values.image.common.registry }}/{{ .Values.image.common.repository }}:{{ .Values.image.common.tag }} +{{- end }} + +{{- define "hadoop.coreImage" -}} +{{ .Values.core.image.registry }}/{{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} +{{- end }} + +{{- define "hadoop.journalNodeImage" -}} +{{ .Values.journalNode.image.registry }}/{{ .Values.journalNode.image.repository }}:{{ .Values.journalNode.image.tag }} +{{- end }} + +{{- define "hadoop.nameNodeImage" -}} +{{ .Values.nameNode.image.registry }}/{{ .Values.nameNode.image.repository }}:{{ .Values.nameNode.image.tag }} +{{- end }} + +{{- define "hadoop.dataNodeImage" -}} +{{ .Values.dataNode.image.registry }}/{{ .Values.dataNode.image.repository }}:{{ .Values.dataNode.image.tag }} +{{- end }} diff --git a/addons/hadoop/templates/clusterdefinition.yaml b/addons/hadoop/templates/clusterdefinition.yaml new file mode 100644 index 0000000000..2b59a02617 --- /dev/null +++ b/addons/hadoop/templates/clusterdefinition.yaml @@ -0,0 +1,49 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ClusterDefinition +metadata: + name: hadoop + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + topologies: + - name: standalone + components: + - name: hadoop-core + compDef: {{ include "hadoop.hadoopCoreStandaloneCmpdRegexPattern" . }} + - name: namenode + compDef: {{ include "hadoop.hdfsNamenodeStandaloneCmpdRegexPattern" . }} + - name: datanode + compDef: {{ include "hadoop.hdfsDatanodeStandaloneCmpdRegexPattern" . }} + orders: + provision: + - hadoop-core + - namenode + - datanode + terminate: + - datanode + - namenode + - hadoop-core + - name: cluster + default: true + components: + - name: hadoop-core + compDef: {{ include "hadoop.hadoopCoreCmpdRegexPattern" . }} + - name: journalnode + compDef: {{ include "hadoop.hdfsJournalnodeCmpdRegexPattern" . }} + - name: namenode + compDef: {{ include "hadoop.hdfsNamenodeCmpdRegexPattern" . }} + - name: datanode + compDef: {{ include "hadoop.hdfsDatanodeCmpdRegexPattern" . }} + orders: + provision: + - hadoop-core + - journalnode + - namenode + - datanode + terminate: + - datanode + - namenode + - journalnode + - hadoop-core diff --git a/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml b/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml new file mode 100644 index 0000000000..e2d1ebf7a8 --- /dev/null +++ b/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml @@ -0,0 +1,82 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hadoop-core-standalone + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hadoop-core-standalone + runtime: + containers: + - name: hadoop-core + image: {{ include "hadoop.coreImage" . | quote }} + imagePullPolicy: {{ .Values.core.image.pullPolicy }} + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + volumeMounts: + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + securityContext: + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.securityContext.runAsUser }} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HDFS_TRASH_INTERVAL + value: {{ .Values.hdfs.trash.interval | quote }} + - name: HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS + value: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + - name: HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS + value: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + - name: HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE + value: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + - name: HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS + value: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + - name: HDFS_IPC_CLIENT_PING + value: {{ .Values.hdfs.ipc.clientPing | quote }} + - name: HDFS_IPC_PING_INTERVAL_MS + value: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} + - name: HDFS_NAMENODE_HEAP + value: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + - name: HDFS_DATANODE_HEAP + value: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + - name: HDFS_JOURNALNODE_HEAP + value: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + - name: HDFS_ZKFC_HEAP + value: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + configs: + - name: hadoop-core-config + template: hadoop-core-standalone-config-template + volumeName: hadoop-core-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hadoop-core.yaml b/addons/hadoop/templates/cmpd-hadoop-core.yaml new file mode 100644 index 0000000000..cdff8233f1 --- /dev/null +++ b/addons/hadoop/templates/cmpd-hadoop-core.yaml @@ -0,0 +1,96 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hadoop-core + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hadoop-core + serviceRefDeclarations: + - name: hadoopZookeeper + serviceRefDeclarationSpecs: + - serviceKind: zookeeper + serviceVersion: "^*" + runtime: + containers: + - name: hadoop-core + image: {{ include "hadoop.coreImage" . | quote }} + imagePullPolicy: {{ .Values.core.image.pullPolicy }} + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + volumeMounts: + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + securityContext: + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.securityContext.runAsUser }} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: ZOOKEEPER_ENDPOINTS + valueFrom: + serviceRefVarRef: + name: hadoopZookeeper + endpoint: Required + - name: HDFS_TRASH_INTERVAL + value: {{ .Values.hdfs.trash.interval | quote }} + - name: HDFS_HA_ZOOKEEPER_PARENT_ZNODE + value: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} + - name: HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS + value: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} + - name: HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS + value: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + - name: HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS + value: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + - name: HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE + value: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + - name: HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS + value: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + - name: HDFS_IPC_CLIENT_PING + value: {{ .Values.hdfs.ipc.clientPing | quote }} + - name: HDFS_IPC_PING_INTERVAL_MS + value: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} + - name: HDFS_NAMENODE_HEAP + value: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + - name: HDFS_DATANODE_HEAP + value: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + - name: HDFS_JOURNALNODE_HEAP + value: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + - name: HDFS_ZKFC_HEAP + value: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + configs: + - name: hadoop-core-config + template: hadoop-core-config-template + volumeName: hadoop-core-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml new file mode 100644 index 0000000000..155d973a99 --- /dev/null +++ b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml @@ -0,0 +1,191 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hdfs-datanode-standalone + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hdfs-datanode-standalone + runtime: + hostNetwork: {{ .Values.runtime.datanode.hostNetwork }} + hostPID: {{ .Values.runtime.datanode.hostPID }} + dnsPolicy: {{ .Values.runtime.datanode.dnsPolicy }} + terminationGracePeriodSeconds: 120 + initContainers: + - name: hadoop-common + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.initRunAsUser }} + command: + - /bin/bash + args: + - -ec + - | + cp -r {{ .Values.runtime.hadoopSoftwareDir }}/* {{ .Values.runtime.hadoopHome }} + mkdir -p {{ .Values.hdfs.paths.datanodeDataDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.runtime.hadoopHome }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.hdfs.paths.datanodeDataDir }} + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hdfs-data-0 + mountPath: {{ .Values.hdfs.paths.datanodeDataDir }} + subPath: data0 + containers: + - name: hdfs-datanode + image: {{ include "hadoop.dataNodeImage" . | quote }} + imagePullPolicy: {{ .Values.dataNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-datanode.sh + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: {{ .Values.hdfs.ports.datanode.data }} + name: data + - containerPort: {{ .Values.hdfs.ports.datanode.ipc }} + name: ipc + - containerPort: {{ .Values.hdfs.ports.datanode.http }} + name: http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + livenessProbe: + failureThreshold: {{ .Values.probes.datanode.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.datanode.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.datanode.liveness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.datanode.liveness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + readinessProbe: + failureThreshold: {{ .Values.probes.datanode.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.datanode.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.datanode.readiness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.datanode.readiness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties + subPath: hadoop-metrics2.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + - name: datanode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: datanode-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: hdfs-data-0 + mountPath: {{ .Values.hdfs.paths.datanodeDataDir }} + subPath: data0 + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + securityContext: + fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hadoop-common + emptyDir: {} + - name: hadoop-logs + emptyDir: {} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HDFS_DATANODE_DATA_DIR + value: {{ .Values.hdfs.paths.datanodeDataDir | quote }} + - name: HDFS_DATANODE_HANDLER_COUNT + value: {{ .Values.hdfs.datanode.handlerCount | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.ports.namenode.rpc | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.ports.namenode.http | quote }} + - name: HDFS_REPLICATION + value: "1" + - name: HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY + value: "NEVER" + - name: HDFS_PERMISSIONS_ENABLED + value: {{ .Values.hdfs.permissions.enabled | quote }} + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + apiVersion: v1 + configs: + - name: datanode-config + template: datanode-standalone-config-template + volumeName: datanode-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} + scripts: + - name: hadoop-scripts + template: hadoop-scripts + volumeName: scripts + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.scripts.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml new file mode 100644 index 0000000000..41247714c1 --- /dev/null +++ b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml @@ -0,0 +1,203 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hdfs-datanode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hdfs-datanode + runtime: + hostNetwork: {{ .Values.runtime.datanode.hostNetwork }} + hostPID: {{ .Values.runtime.datanode.hostPID }} + dnsPolicy: {{ .Values.runtime.datanode.dnsPolicy }} + terminationGracePeriodSeconds: 300 + initContainers: + - name: hadoop-common + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.initRunAsUser }} + command: + - /bin/bash + args: + - -ec + - | + cp -r {{ .Values.runtime.hadoopSoftwareDir }}/* {{ .Values.runtime.hadoopHome }} + mkdir -p {{ .Values.hdfs.paths.datanodeDataDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.runtime.hadoopHome }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.hdfs.paths.datanodeDataDir }} + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hdfs-data-0 + mountPath: {{ .Values.hdfs.paths.datanodeDataDir }} + subPath: data0 + containers: + - name: hdfs-datanode + image: {{ include "hadoop.dataNodeImage" . | quote }} + imagePullPolicy: {{ .Values.dataNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-datanode.sh + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: {{ .Values.hdfs.ports.datanode.data }} + name: data + - containerPort: {{ .Values.hdfs.ports.datanode.ipc }} + name: ipc + - containerPort: {{ .Values.hdfs.ports.datanode.http }} + name: http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + livenessProbe: + failureThreshold: {{ .Values.probes.datanode.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.datanode.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.datanode.liveness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.datanode.liveness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + readinessProbe: + failureThreshold: {{ .Values.probes.datanode.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.datanode.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.datanode.readiness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.datanode.readiness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-data-status.sh + lifecycle: + preStop: + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/datanode-decommission.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties + subPath: hadoop-metrics2.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + - name: datanode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: datanode-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: hdfs-data-0 + mountPath: {{ .Values.hdfs.paths.datanodeDataDir }} + subPath: data0 + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + securityContext: + fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hadoop-common + emptyDir: {} + - name: hadoop-logs + emptyDir: {} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: NAMENODE_POD_FQDN_LIST + valueFrom: + componentVarRef: + compDef: hdfs-namenode + optional: false + podFQDNs: Required + - name: HDFS_DATANODE_DATA_DIR + value: {{ .Values.hdfs.paths.datanodeDataDir | quote }} + - name: HDFS_DATANODE_HANDLER_COUNT + value: {{ .Values.hdfs.datanode.handlerCount | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.ports.namenode.rpc | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.ports.namenode.http | quote }} + - name: HDFS_REPLICATION + value: {{ .Values.hdfs.replication | quote }} + - name: HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY + value: {{ .Values.hdfs.client.replaceDatanodeOnFailurePolicy | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: {{ .Values.hdfs.permissions.enabled | quote }} + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + apiVersion: v1 + configs: + - name: datanode-config + template: datanode-config-template + volumeName: datanode-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} + scripts: + - name: hadoop-scripts + template: hadoop-scripts + volumeName: scripts + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.scripts.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml new file mode 100644 index 0000000000..79fe02a2e5 --- /dev/null +++ b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml @@ -0,0 +1,180 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hdfs-journalnode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hdfs-journalnode + services: + - name: default + spec: + ports: + - name: jn + port: {{ .Values.hdfs.ports.journalnode.rpc }} + - name: http + port: {{ .Values.hdfs.ports.journalnode.http }} + runtime: + terminationGracePeriodSeconds: 60 + initContainers: + - name: hadoop-common + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.initRunAsUser }} + command: + - /bin/bash + args: + - -ec + - | + cp -r {{ .Values.runtime.hadoopSoftwareDir }}/* {{ .Values.runtime.hadoopHome }} + mkdir -p {{ .Values.hdfs.paths.journalnodeEditsDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.hdfs.paths.journalnodeEditsDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.runtime.hadoopHome }} + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: edits-dir + mountPath: {{ .Values.hdfs.paths.journalnodeEditsDir }} + subPath: journal + containers: + - name: hdfs-journalnode + image: {{ include "hadoop.journalNodeImage" . | quote }} + imagePullPolicy: {{ .Values.journalNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-journalnode.sh + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: {{ .Values.hdfs.ports.journalnode.rpc }} + name: jn + - containerPort: {{ .Values.hdfs.ports.journalnode.http }} + name: http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-journal-status.sh + livenessProbe: + failureThreshold: {{ .Values.probes.journalnode.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.journalnode.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.journalnode.liveness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.journalnode.liveness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-journal-status.sh + readinessProbe: + failureThreshold: {{ .Values.probes.journalnode.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.journalnode.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.journalnode.readiness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.journalnode.readiness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-journal-status.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: edits-dir + mountPath: {{ .Values.hdfs.paths.journalnodeEditsDir }} + subPath: journal + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties + subPath: hadoop-metrics2.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + - name: journalnode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: journalnode-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + securityContext: + fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hadoop-common + emptyDir: {} + - name: hadoop-logs + emptyDir: {} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: JOURNALNODE_POD_FQDN_LIST + valueFrom: + componentVarRef: + optional: false + podFQDNs: Required + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HDFS_JOURNALNODE_EDITS_DIR + value: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} + - name: HDFS_JOURNALNODE_RPC_PORT + value: {{ .Values.hdfs.ports.journalnode.rpc | quote }} + - name: HDFS_JOURNALNODE_HTTP_PORT + value: {{ .Values.hdfs.ports.journalnode.http | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: {{ .Values.hdfs.permissions.enabled | quote }} + - name: HDFS_REPLICATION + value: {{ .Values.hdfs.replication | quote }} + configs: + - name: journalnode-config + template: journalnode-config-template + volumeName: journalnode-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} + scripts: + - name: hadoop-scripts + template: hadoop-scripts + volumeName: scripts + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.scripts.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml new file mode 100644 index 0000000000..34375a465b --- /dev/null +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -0,0 +1,229 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hdfs-namenode-standalone + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hdfs-namenode-standalone + services: + - name: default + spec: + ports: + - name: fs + port: {{ .Values.hdfs.ports.namenode.rpc }} + - name: http + port: {{ .Values.hdfs.ports.namenode.http }} + runtime: + terminationGracePeriodSeconds: 120 + initContainers: + - name: hadoop-common + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.initRunAsUser }} + command: + - /bin/bash + args: + - -ec + - | + cp -r {{ .Values.runtime.hadoopSoftwareDir }}/* {{ .Values.runtime.hadoopHome }} + mkdir -p {{ .Values.hdfs.paths.namenodeMetadataDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} /hadoop + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.runtime.hadoopHome }} + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: init-namenode-format + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/init-namenode-format.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + containers: + - name: hdfs-namenode + image: {{ include "hadoop.nameNodeImage" . | quote }} + imagePullPolicy: {{ .Values.nameNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-namenode.sh + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + - name: CURRENT_POD + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: {{ .Values.hdfs.ports.namenode.rpc }} + name: fs + - containerPort: {{ .Values.hdfs.ports.namenode.http }} + name: http + startupProbe: + failureThreshold: 60 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + livenessProbe: + failureThreshold: {{ .Values.probes.namenode.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.namenode.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.namenode.liveness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.namenode.liveness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + readinessProbe: + failureThreshold: {{ .Values.probes.namenode.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.namenode.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.namenode.readiness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.namenode.readiness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties + subPath: hadoop-metrics2.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + securityContext: + fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hadoop-common + emptyDir: {} + - name: hadoop-logs + emptyDir: {} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: CLUSTER_UID + valueFrom: + clusterVarRef: + clusterUID: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HDFS_NAMENODE_NAME_DIR + value: {{ .Values.hdfs.paths.namenodeMetadataDir | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.ports.namenode.rpc | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.ports.namenode.http | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: {{ .Values.hdfs.permissions.enabled | quote }} + - name: HDFS_REGISTRATION_IP_HOSTNAME_CHECK + value: {{ .Values.hdfs.registration.ipHostnameCheck | quote }} + - name: HDFS_REPLICATION + value: "1" + - name: HDFS_REPLICATION_MAX + value: "1" + - name: HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY + value: "NEVER" + - name: HDFS_NAMENODE_HANDLER_COUNT + value: {{ .Values.hdfs.namenode.handlerCount | quote }} + configs: + - name: namenode-config + template: namenode-standalone-config-template + volumeName: namenode-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} + scripts: + - name: hadoop-scripts + template: hadoop-scripts + volumeName: scripts + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.scripts.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml new file mode 100644 index 0000000000..1e172bfc0c --- /dev/null +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -0,0 +1,396 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hdfs-namenode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hdfs-namenode + services: + - name: default + spec: + ports: + - name: fs + port: {{ .Values.hdfs.ports.namenode.rpc }} + - name: http + port: {{ .Values.hdfs.ports.namenode.http }} + serviceRefDeclarations: + - name: hadoopZookeeper + serviceRefDeclarationSpecs: + - serviceKind: zookeeper + serviceVersion: "^*" + runtime: + terminationGracePeriodSeconds: 300 + initContainers: + - name: hadoop-common + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.initRunAsUser }} + command: + - /bin/bash + args: + - -ec + - | + cp -r {{ .Values.runtime.hadoopSoftwareDir }}/* {{ .Values.runtime.hadoopHome }} + mkdir -p {{ .Values.hdfs.paths.namenodeMetadataDir }} + mkdir -p {{ .Values.hdfs.paths.namenodeJournalDir }} + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} /hadoop + chown -R {{ .Values.securityContext.runAsUser }}:{{ .Values.securityContext.runAsGroup }} {{ .Values.runtime.hadoopHome }} + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: init-namenode-format + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + env: + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/init-namenode-format.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: init-zkfc-format + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + env: + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/init-zkfc-format.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: init-nn-bootstrap-standby + imagePullPolicy: IfNotPresent + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + env: + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/init-nn-bootstrap-standby.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + containers: + - name: hdfs-namenode + image: {{ include "hadoop.nameNodeImage" . | quote }} + imagePullPolicy: {{ .Values.nameNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-namenode.sh + env: + - name: DEBUG_MODEL + value: {{ .Values.runtime.debug | quote }} + - name: CURRENT_POD + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: {{ .Values.hdfs.ports.namenode.rpc }} + name: fs + - containerPort: {{ .Values.hdfs.ports.namenode.http }} + name: http + startupProbe: + failureThreshold: 60 + initialDelaySeconds: 30 + periodSeconds: 10 + successThreshold: 1 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + livenessProbe: + failureThreshold: {{ .Values.probes.namenode.liveness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.namenode.liveness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.namenode.liveness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.namenode.liveness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + readinessProbe: + failureThreshold: {{ .Values.probes.namenode.readiness.failureThreshold }} + initialDelaySeconds: {{ .Values.probes.namenode.readiness.initialDelaySeconds }} + periodSeconds: {{ .Values.probes.namenode.readiness.periodSeconds }} + successThreshold: 1 + timeoutSeconds: {{ .Values.probes.namenode.readiness.timeoutSeconds }} + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-name-status.sh + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: metadata-dir + mountPath: /hadoop + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties + subPath: hadoop-metrics2.properties + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: lifecycle + mountPath: /lifecycle + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: hdfs-zkfc + image: {{ include "hadoop.nameNodeImage" . | quote }} + imagePullPolicy: {{ .Values.nameNode.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-zkfc.sh + env: + - name: HADOOP_HOME + value: {{ .Values.runtime.hadoopHome }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: HADOOP_LOG_DIR + value: {{ .Values.runtime.hadoopLogDir }} + ports: + - containerPort: 8019 + name: zkfc + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - -ec + - "jps | grep -q DFSZKFailoverController || pgrep -f DFSZKFailoverController > /dev/null" + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - -ec + - "jps | grep -q DFSZKFailoverController || pgrep -f DFSZKFailoverController > /dev/null" + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - -ec + - "jps | grep -q DFSZKFailoverController || pgrep -f DFSZKFailoverController > /dev/null" + volumeMounts: + - name: hadoop-common + mountPath: {{ .Values.runtime.hadoopHome }} + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/core-site.xml + subPath: core-site.xml + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh + subPath: hadoop-env.sh + - name: hadoop-core-config + mountPath: {{ .Values.runtime.configDir }}/log4j.properties + subPath: log4j.properties + - name: namenode-config + mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: lifecycle + mountPath: /lifecycle + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} + - name: scripts + mountPath: {{ .Values.runtime.scriptsDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: {{ .Values.securityContext.privileged }} + allowPrivilegeEscalation: {{ .Values.securityContext.allowPrivilegeEscalation }} + capabilities: +{{ toYaml .Values.securityContext.capabilities | nindent 12 }} + seccompProfile: +{{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + securityContext: + fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hadoop-common + emptyDir: {} + - name: lifecycle + emptyDir: {} + - name: hadoop-logs + emptyDir: {} + updateStrategy: {{ .Values.updateStrategy }} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: CLUSTER_UID + valueFrom: + clusterVarRef: + clusterUID: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HDFS_CONF_DIR + value: {{ .Values.runtime.configDir }} + - name: JOURNALNODE_POD_FQDN_LIST + valueFrom: + componentVarRef: + compDef: hdfs-journalnode + optional: false + podFQDNs: Required + - name: ZOOKEEPER_ENDPOINTS + valueFrom: + serviceRefVarRef: + name: hadoopZookeeper + endpoint: Required + - name: HDFS_NAMENODE_NAME_DIR + value: {{ .Values.hdfs.paths.namenodeMetadataDir | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.ports.namenode.rpc | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.ports.namenode.http | quote }} + - name: HDFS_JOURNALNODE_RPC_PORT + value: {{ .Values.hdfs.ports.journalnode.rpc | quote }} + - name: HDFS_HA_FENCING_METHODS + value: {{ .Values.hdfs.ha.fencingMethods | quote }} + - name: HDFS_HA_AUTOMATIC_FAILOVER_ENABLED + value: {{ .Values.hdfs.ha.automaticFailoverEnabled | quote }} + - name: HDFS_HA_ZOOKEEPER_OPERATION_RETRIES + value: {{ .Values.hdfs.ha.zookeeper.operationRetries | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: {{ .Values.hdfs.permissions.enabled | quote }} + - name: HDFS_REGISTRATION_IP_HOSTNAME_CHECK + value: {{ .Values.hdfs.registration.ipHostnameCheck | quote }} + - name: HDFS_REPLICATION + value: {{ .Values.hdfs.replication | quote }} + - name: HDFS_REPLICATION_MAX + value: {{ .Values.hdfs.replicationMax | quote }} + - name: HDFS_CLIENT_REPLACE_DATANODE_ON_FAILURE_POLICY + value: {{ .Values.hdfs.client.replaceDatanodeOnFailurePolicy | quote }} + - name: HDFS_NAMENODE_HANDLER_COUNT + value: {{ .Values.hdfs.namenode.handlerCount | quote }} + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + apiVersion: v1 + configs: + - name: namenode-config + template: namenode-config-template + volumeName: namenode-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} + scripts: + - name: hadoop-scripts + template: hadoop-scripts + volumeName: scripts + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.scripts.defaultMode }} diff --git a/addons/hadoop/templates/cmpv-hadoop-core.yaml b/addons/hadoop/templates/cmpv-hadoop-core.yaml new file mode 100644 index 0000000000..8edfb15bcc --- /dev/null +++ b/addons/hadoop/templates/cmpv-hadoop-core.yaml @@ -0,0 +1,20 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hadoop-core + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - releases: + - v3.3.4 + compDefs: + - hadoop-core + - hadoop-core-standalone + releases: + - name: v3.3.4 + serviceVersion: v3.3.4 + images: + hadoop-core: {{ include "hadoop.coreImage" . | quote }} diff --git a/addons/hadoop/templates/cmpv-hdfs-datanode.yaml b/addons/hadoop/templates/cmpv-hdfs-datanode.yaml new file mode 100644 index 0000000000..867eb8d350 --- /dev/null +++ b/addons/hadoop/templates/cmpv-hdfs-datanode.yaml @@ -0,0 +1,21 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hdfs-datanode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - releases: + - v3.3.4 + compDefs: + - hdfs-datanode + - hdfs-datanode-standalone + releases: + - name: v3.3.4 + serviceVersion: v3.3.4 + images: + hadoop-common: {{ include "hadoop.commonImage" . | quote }} + hdfs-datanode: {{ include "hadoop.dataNodeImage" . | quote }} diff --git a/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml b/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml new file mode 100644 index 0000000000..1144a66250 --- /dev/null +++ b/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml @@ -0,0 +1,20 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hdfs-journalnode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - releases: + - v3.3.4 + compDefs: + - hdfs-journalnode + releases: + - name: v3.3.4 + serviceVersion: v3.3.4 + images: + hadoop-common: {{ include "hadoop.commonImage" . | quote }} + hdfs-journalnode: {{ include "hadoop.journalNodeImage" . | quote }} \ No newline at end of file diff --git a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml new file mode 100644 index 0000000000..2f14e75206 --- /dev/null +++ b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml @@ -0,0 +1,21 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hdfs-namenode + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - releases: + - v3.3.4 + compDefs: + - hdfs-namenode + - hdfs-namenode-standalone + releases: + - name: v3.3.4 + serviceVersion: v3.3.4 + images: + hadoop-common: {{ include "hadoop.commonImage" . | quote }} + hdfs-namenode: {{ include "hadoop.nameNodeImage" . | quote }} diff --git a/addons/hadoop/templates/hadoop-core-config-template.yaml b/addons/hadoop/templates/hadoop-core-config-template.yaml new file mode 100644 index 0000000000..75db43148c --- /dev/null +++ b/addons/hadoop/templates/hadoop-core-config-template.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hadoop-core-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + core-site.xml: |- + {{- .Files.Get "config/core-site.tpl" | nindent 4 }} + hadoop-env.sh: |- + {{- .Files.Get "config/hadoop-env.sh.tpl" | nindent 4 }} + hadoop-metrics2.properties: |- + {{- .Files.Get "config/hadoop-metrics2.properties.tpl" | nindent 4 }} + dfs.include: | + {{- .Files.Get "config/dfs.include" | nindent 4 }} + dfs.exclude: | + {{- .Files.Get "config/dfs.exclude" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hadoop/templates/hadoop-core-standalone-config-template.yaml b/addons/hadoop/templates/hadoop-core-standalone-config-template.yaml new file mode 100644 index 0000000000..9c42ea0d00 --- /dev/null +++ b/addons/hadoop/templates/hadoop-core-standalone-config-template.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hadoop-core-standalone-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + core-site.xml: |- + {{- .Files.Get "config/core-site-standalone.tpl" | nindent 4 }} + hadoop-env.sh: |- + {{- .Files.Get "config/hadoop-env.sh.tpl" | nindent 4 }} + hadoop-metrics2.properties: |- + {{- .Files.Get "config/hadoop-metrics2.properties.tpl" | nindent 4 }} + dfs.include: | + {{- .Files.Get "config/dfs.include" | nindent 4 }} + dfs.exclude: | + {{- .Files.Get "config/dfs.exclude" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hadoop/templates/hdfs-datanode-config-template.yaml b/addons/hadoop/templates/hdfs-datanode-config-template.yaml new file mode 100644 index 0000000000..797e265548 --- /dev/null +++ b/addons/hadoop/templates/hdfs-datanode-config-template.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: datanode-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-datanode.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} \ No newline at end of file diff --git a/addons/hadoop/templates/hdfs-datanode-standalone-config-template.yaml b/addons/hadoop/templates/hdfs-datanode-standalone-config-template.yaml new file mode 100644 index 0000000000..eea7458e57 --- /dev/null +++ b/addons/hadoop/templates/hdfs-datanode-standalone-config-template.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: datanode-standalone-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-datanode-standalone.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hadoop/templates/hdfs-journalnode-config-template.yaml b/addons/hadoop/templates/hdfs-journalnode-config-template.yaml new file mode 100644 index 0000000000..256ef5d9ff --- /dev/null +++ b/addons/hadoop/templates/hdfs-journalnode-config-template.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: journalnode-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-journalnode.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} \ No newline at end of file diff --git a/addons/hadoop/templates/hdfs-namenode-config-template.yaml b/addons/hadoop/templates/hdfs-namenode-config-template.yaml new file mode 100644 index 0000000000..c5e754d0e4 --- /dev/null +++ b/addons/hadoop/templates/hdfs-namenode-config-template.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: namenode-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-namenode.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} \ No newline at end of file diff --git a/addons/hadoop/templates/hdfs-namenode-standalone-config-template.yaml b/addons/hadoop/templates/hdfs-namenode-standalone-config-template.yaml new file mode 100644 index 0000000000..95f0fa19a5 --- /dev/null +++ b/addons/hadoop/templates/hdfs-namenode-standalone-config-template.yaml @@ -0,0 +1,11 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: namenode-standalone-config-template + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-namenode-standalone.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hadoop/templates/hdfs-scripts-template.yaml b/addons/hadoop/templates/hdfs-scripts-template.yaml new file mode 100644 index 0000000000..791908547a --- /dev/null +++ b/addons/hadoop/templates/hdfs-scripts-template.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hadoop-scripts + labels: + {{- include "hadoop.labels" . | nindent 4 }} +data: + check-journal-status.sh: |- + {{- .Files.Get "scripts/check-journal-status.sh" | nindent 4 }} + check-name-status.sh: |- + {{- .Files.Get "scripts/check-name-status.sh" | nindent 4 }} + check-data-status.sh: |- + {{- .Files.Get "scripts/check-data-status.sh" | nindent 4 }} + start-namenode.sh: |- + {{- .Files.Get "scripts/start-namenode.sh" | nindent 4 }} + start-zkfc.sh: |- + {{- .Files.Get "scripts/start-zkfc.sh" | nindent 4 }} + start-journalnode.sh: |- + {{- .Files.Get "scripts/start-journalnode.sh" | nindent 4 }} + start-datanode.sh: |- + {{- .Files.Get "scripts/start-datanode.sh" | nindent 4 }} + init-namenode-format.sh: |- + {{- .Files.Get "scripts/init-namenode-format.sh" | nindent 4 }} + init-zkfc-format.sh: |- + {{- .Files.Get "scripts/init-zkfc-format.sh" | nindent 4 }} + init-nn-bootstrap-standby.sh: |- + {{- .Files.Get "scripts/init-nn-bootstrap-standby.sh" | nindent 4 }} + init-refresh-nodes.sh: |- + {{- .Files.Get "scripts/init-refresh-nodes.sh" | nindent 4 }} + datanode-decommission.sh: |- + {{- .Files.Get "scripts/datanode-decommission.sh" | nindent 4 }} diff --git a/addons/hadoop/templates/paramsdef-hadoop-core.yaml b/addons/hadoop/templates/paramsdef-hadoop-core.yaml new file mode 100644 index 0000000000..3b310c4ab8 --- /dev/null +++ b/addons/hadoop/templates/paramsdef-hadoop-core.yaml @@ -0,0 +1,12 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParametersDefinition +metadata: + name: hadoop-core-config-constraints + labels: + {{- include "hadoop.labels" . | nindent 4 }} +spec: + fileName: core-site.xml + parametersSchema: + topLevelKey: HadoopCoreParameter + cue: |- + {{- .Files.Get "config/hadoop-core-config-constraint.cue" | nindent 6 }} \ No newline at end of file diff --git a/addons/hadoop/templates/paramsdef-hdfs-datanode.yaml b/addons/hadoop/templates/paramsdef-hdfs-datanode.yaml new file mode 100644 index 0000000000..ae4099c95d --- /dev/null +++ b/addons/hadoop/templates/paramsdef-hdfs-datanode.yaml @@ -0,0 +1,12 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParametersDefinition +metadata: + name: datanode-config-constraints + labels: + {{- include "hadoop.labels" . | nindent 4 }} +spec: + fileName: hdfs-site.xml + parametersSchema: + topLevelKey: DataNodeParameter + cue: |- + {{- .Files.Get "config/hdfs-datanode-config-constraint.cue" | nindent 6 }} \ No newline at end of file diff --git a/addons/hadoop/templates/paramsdef-hdfs-journalnode.yaml b/addons/hadoop/templates/paramsdef-hdfs-journalnode.yaml new file mode 100644 index 0000000000..008f34b93f --- /dev/null +++ b/addons/hadoop/templates/paramsdef-hdfs-journalnode.yaml @@ -0,0 +1,12 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParametersDefinition +metadata: + name: journalnode-config-constraints + labels: + {{- include "hadoop.labels" . | nindent 4 }} +spec: + fileName: hdfs-site.xml + parametersSchema: + topLevelKey: JournalNodeParameter + cue: |- + {{- .Files.Get "config/hdfs-journalnode-config-constraint.cue" | nindent 6 }} \ No newline at end of file diff --git a/addons/hadoop/templates/paramsdef-hdfs-namenode.yaml b/addons/hadoop/templates/paramsdef-hdfs-namenode.yaml new file mode 100644 index 0000000000..e4702ff531 --- /dev/null +++ b/addons/hadoop/templates/paramsdef-hdfs-namenode.yaml @@ -0,0 +1,12 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParametersDefinition +metadata: + name: namenode-config-constraints + labels: + {{- include "hadoop.labels" . | nindent 4 }} +spec: + fileName: hdfs-site.xml + parametersSchema: + topLevelKey: NameNodeParameter + cue: |- + {{- .Files.Get "config/hdfs-namenode-config-constraint.cue" | nindent 6 }} \ No newline at end of file diff --git a/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml b/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml new file mode 100644 index 0000000000..b1169536f5 --- /dev/null +++ b/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hadoop-core-standalone-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hadoop-core-standalone + parametersDefs: + - hadoop-core-config-constraints + configs: + - name: core-site.xml + fileFormatConfig: + format: xml diff --git a/addons/hadoop/templates/pcr-hadoop-core.yaml b/addons/hadoop/templates/pcr-hadoop-core.yaml new file mode 100644 index 0000000000..36cb45bb53 --- /dev/null +++ b/addons/hadoop/templates/pcr-hadoop-core.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hadoop-core-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hadoop-core + parametersDefs: + - hadoop-core-config-constraints + configs: + - name: core-site.xml + fileFormatConfig: + format: xml \ No newline at end of file diff --git a/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml new file mode 100644 index 0000000000..259770fe52 --- /dev/null +++ b/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hdfs-datanode-standalone-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hdfs-datanode-standalone + parametersDefs: + - datanode-config-constraints + configs: + - name: hdfs-site.xml + fileFormatConfig: + format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-datanode.yaml b/addons/hadoop/templates/pcr-hdfs-datanode.yaml new file mode 100644 index 0000000000..c9883aed69 --- /dev/null +++ b/addons/hadoop/templates/pcr-hdfs-datanode.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hdfs-datanode-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hdfs-datanode + parametersDefs: + - datanode-config-constraints + configs: + - name: hdfs-site.xml + fileFormatConfig: + format: xml \ No newline at end of file diff --git a/addons/hadoop/templates/pcr-hdfs-journalnode.yaml b/addons/hadoop/templates/pcr-hdfs-journalnode.yaml new file mode 100644 index 0000000000..1a7c2c0e5b --- /dev/null +++ b/addons/hadoop/templates/pcr-hdfs-journalnode.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hdfs-journalnode-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hdfs-journalnode + parametersDefs: + - journalnode-config-constraints + configs: + - name: hdfs-site.xml + fileFormatConfig: + format: xml \ No newline at end of file diff --git a/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml new file mode 100644 index 0000000000..11d8d664b6 --- /dev/null +++ b/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hdfs-namenode-standalone-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hdfs-namenode-standalone + parametersDefs: + - namenode-config-constraints + configs: + - name: hdfs-site.xml + fileFormatConfig: + format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-namenode.yaml b/addons/hadoop/templates/pcr-hdfs-namenode.yaml new file mode 100644 index 0000000000..406e01713c --- /dev/null +++ b/addons/hadoop/templates/pcr-hdfs-namenode.yaml @@ -0,0 +1,16 @@ +apiVersion: parameters.kubeblocks.io/v1alpha1 +kind: ParamConfigRenderer +metadata: + name: hdfs-namenode-config-renderer + labels: + {{- include "hadoop.labels" . | nindent 4 }} + annotations: + {{- include "hadoop.annotations" . | nindent 4 }} +spec: + componentDef: hdfs-namenode + parametersDefs: + - namenode-config-constraints + configs: + - name: hdfs-site.xml + fileFormatConfig: + format: xml \ No newline at end of file diff --git a/addons/hadoop/templates/scripts.yaml b/addons/hadoop/templates/scripts.yaml new file mode 100644 index 0000000000..e69de29bb2 diff --git a/addons/hadoop/values.yaml b/addons/hadoop/values.yaml new file mode 100644 index 0000000000..e4bb050801 --- /dev/null +++ b/addons/hadoop/values.yaml @@ -0,0 +1,166 @@ +# Hadoop common image (used by initContainers via ComponentVersion.hadoop-common) +image: + common: + registry: docker.io + repository: apecloud/hdfs-journalnode + tag: "v3.3.4-1.0.0" + pullPolicy: IfNotPresent + +# Component-specific images +core: + image: + registry: docker.io + repository: apecloud/hdfs-journalnode + tag: "v3.3.4-1.0.0" + pullPolicy: IfNotPresent + +journalNode: + image: + registry: docker.io + repository: apecloud/hdfs-journalnode + tag: "v3.3.4-1.0.0" + pullPolicy: IfNotPresent + +nameNode: + image: + registry: docker.io + repository: apecloud/hdfs-namenode + tag: "v3.3.4-1.0.0" + pullPolicy: IfNotPresent + +dataNode: + image: + registry: docker.io + repository: apecloud/hdfs-datanode + tag: "v3.3.4-1.0.0" + pullPolicy: IfNotPresent + +# kblib extension config +extra: + disableExporter: true + terminationPolicy: Delete + clusterDomain: cluster.local + +runtime: + debug: false + hadoopHome: /opt/kubeemr/hadoop/hadoop-3.3.4 + hadoopSoftwareDir: /opt/software/hadoop-3.3.4 + configDir: /hadoop/conf + scriptsDir: /kubeblocks/scripts + hadoopLogDir: /var/log/hadoop + datanode: + hostNetwork: true + hostPID: true + dnsPolicy: ClusterFirstWithHostNet + journalnode: + waitZkToReady: false + +hdfs: + replication: 3 + replicationMax: 6 + permissions: + enabled: false + superusergroup: supergroup + registration: + ipHostnameCheck: false + client: + replaceDatanodeOnFailurePolicy: DEFAULT + namenode: + handlerCount: 64 + datanode: + handlerCount: 64 + ha: + automaticFailoverEnabled: true + fencingMethods: "sshfence\nshell(/bin/true)" + zookeeper: + sessionTimeoutMs: 60000 + operationRetries: 3 + parentZnodePrefix: /hadoop-ha + trash: + interval: 1440 + ipc: + clientConnectionMaxIdleTimeMs: 300000 + clientConnectTimeoutMs: 20000 + clientConnectionPoolSize: 8 + clientConnectRetryIntervalMs: 1000 + clientPing: true + pingIntervalMs: 30000 + jvm: + namenodeHeapSize: "3g" + datanodeHeapSize: "1g" + journalnodeHeapSize: "1g" + zkfcHeapSize: "512m" + ports: + namenode: + rpc: 8020 + http: 9870 + journalnode: + rpc: 8485 + http: 8480 + datanode: + data: 9866 + ipc: 9867 + http: 9864 + paths: + namenodeMetadataDir: /hadoop/dfs/metadata + namenodeJournalDir: /hadoop/dfs/journal + datanodeDataDir: /hadoop/dfs/data0 + journalnodeEditsDir: /hadoop/dfs/journal + +securityContext: + initRunAsUser: 0 + runAsUser: 10000 + runAsGroup: 1000 + fsGroup: 1000 + fsGroupChangePolicy: Always + runAsNonRoot: true + privileged: false + allowPrivilegeEscalation: false + seccompProfile: + type: RuntimeDefault + capabilities: + drop: + - ALL + +probes: + namenode: + liveness: + failureThreshold: 6 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + readiness: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + journalnode: + liveness: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + readiness: + failureThreshold: 6 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + datanode: + liveness: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + readiness: + failureThreshold: 6 + initialDelaySeconds: 10 + periodSeconds: 10 + timeoutSeconds: 5 + +config: + defaultMode: 0755 + +scripts: + defaultMode: 0755 + +updateStrategy: BestEffortParallel diff --git a/addons/hbase/.helmignore b/addons/hbase/.helmignore new file mode 100644 index 0000000000..691fa13d6a --- /dev/null +++ b/addons/hbase/.helmignore @@ -0,0 +1,23 @@ +# 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 +*.orig +*~ +# Various IDEs +.project +.idea/ +*.tmproj +.vscode/ \ No newline at end of file diff --git a/addons/hbase/Chart.yaml b/addons/hbase/Chart.yaml new file mode 100644 index 0000000000..a5c9b01d47 --- /dev/null +++ b/addons/hbase/Chart.yaml @@ -0,0 +1,27 @@ +annotations: + category: BigData + addon.kubeblocks.io/kubeblocks-version: ">=1.0.0" + addon.kubeblocks.io/model: "key-value" + addon.kubeblocks.io/provider: "community" +apiVersion: v2 +name: hbase +description: A Helm chart for HBase on KubeBlocks. +type: application +version: 1.1.0-alpha.0 +appVersion: "2.5.6" +dependencies: + - name: kblib + version: 0.1.0 + repository: file://../kblib + alias: extra +keywords: + - hbase + - bigdata + - hadoop +home: https://github.com/apecloud/kubeblocks/tree/main/deploy/hbase +icon: https://kubeblocks.io/img/logo.png +maintainers: + - name: ApeCloud + url: https://kubeblocks.io/ +sources: + - https://github.com/apecloud/kubeblocks/ \ No newline at end of file diff --git a/addons/hbase/README.md b/addons/hbase/README.md new file mode 100644 index 0000000000..c98946ee86 --- /dev/null +++ b/addons/hbase/README.md @@ -0,0 +1,144 @@ +# HBase + +Apache HBase is an open-source, distributed, versioned, column-oriented store modeled after Google's Bigtable. This addon enables HBase cluster management on KubeBlocks. + +## Features In KubeBlocks + +### Lifecycle Management + +| Topology | Horizontal Scaling | Vertical Scaling | Expand Volume | Restart | Stop/Start | +|----------|--------------------|------------------|---------------|---------|------------| +| hbase-cluster | Yes | Yes | Yes | Yes | Yes | + +### Versions + +| Major Version | Description | +|---------------|-------------| +| 2.5 | 2.5.6 | + +## Prerequisites + +- Kubernetes cluster >= v1.21 +- KubeBlocks installed and running +- ZooKeeper Addon enabled (HBase depends on ZooKeeper) +- Hadoop HDFS Addon enabled (HBase depends on HDFS Namenode) + +## Examples + +### Create a HBase Cluster + +```yaml +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: hbase-cluster + namespace: demo +spec: + terminationPolicy: Delete + clusterDef: hbase + topology: hbase-cluster + componentSpecs: + - name: hmaster + componentDef: hbase-hmaster-2.5 + serviceVersion: 2.5.6 + replicas: 1 + resources: + requests: + cpu: "0.1" + memory: 0.5Gi + limits: + cpu: "1" + memory: 2Gi + serviceRefs: + - name: hbase-zookeeper + namespace: default + clusterServiceSelector: + cluster: zkcluster + service: + component: zookeeper + service: headless + port: client + - name: hadoop-namenode + namespace: default + clusterServiceSelector: + cluster: hadoop2 + service: + component: namenode + service: headless + port: client + env: + - name: HADOOP_CLUSTER_NAME + value: "hadoop2" + volumes: + - name: hadoop-core-config + configMap: + name: hadoop2-hadoop-core-config + - name: hadoop-hdfs-config + configMap: + name: hadoop2-namenode-config + volumeClaimTemplates: + - name: hbase-log + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 2Gi + - name: hregionserver + componentDef: hbase-hregionserver-2.5 + serviceVersion: 2.5.6 + replicas: 1 + resources: + requests: + cpu: "0.1" + memory: 0.5Gi + limits: + cpu: "1" + memory: 2Gi + serviceRefs: + - name: hbase-zookeeper + namespace: default + clusterServiceSelector: + cluster: zkcluster + service: + component: zookeeper + service: headless + port: client + - name: hadoop-namenode + namespace: default + clusterServiceSelector: + cluster: hadoop2 + service: + component: namenode + service: headless + port: client + env: + - name: HADOOP_CLUSTER_NAME + value: "hadoop2" + volumes: + - name: hadoop-core-config + configMap: + name: hadoop2-hadoop-core-config + - name: hadoop-hdfs-config + configMap: + name: hadoop2-namenode-config + volumeClaimTemplates: + - name: hbase-temp-data + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 10Gi +``` + +```bash +kubectl apply -f examples/hbase/cluster.yaml +``` + +### Delete + +```bash +kubectl patch cluster -n demo hbase-cluster -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge" +kubectl delete cluster -n demo hbase-cluster +``` \ No newline at end of file diff --git a/addons/hbase/config/hadoop-core-site.tpl b/addons/hbase/config/hadoop-core-site.tpl new file mode 100644 index 0000000000..5a59d89708 --- /dev/null +++ b/addons/hbase/config/hadoop-core-site.tpl @@ -0,0 +1,78 @@ + + + + + fs.defaultFS + hdfs://{{ .HDFS_NAMESERVICE }} + + + + fs.trash.interval + 1440 + + + + io.compression.codecs + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec + + + + ha.zookeeper.quorum + {{ .ZOOKEEPER_ENDPOINTS }} + + + + ha.zookeeper.parent-znode + {{ .HDFS_HA_ZK_PARENT }} + + + + hadoop.http.staticuser.user + hbase + + + + hadoop.security.authentication + simple + + + + hadoop.security.authorization + false + + + + ipc.client.connection.maxidletime + 30000 + + + + ipc.client.connect.timeout + 10000 + + + + ipc.client.ping + true + + + + ipc.ping.interval + 60000 + + + + hadoop.tmp.dir + /hadoop/tmp + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 1000,1 + + diff --git a/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl b/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl new file mode 100644 index 0000000000..d400f079cc --- /dev/null +++ b/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl @@ -0,0 +1,4 @@ +*.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink +*.period=10 + +hbase.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink diff --git a/addons/hbase/config/hbase-env.sh.tpl b/addons/hbase/config/hbase-env.sh.tpl new file mode 100644 index 0000000000..bb824ea300 --- /dev/null +++ b/addons/hbase/config/hbase-env.sh.tpl @@ -0,0 +1,17 @@ +export HBASE_CONF_DIR={{ .HBASE_CONF_DIR }} +export HBASE_PID_DIR={{ .HBASE_PID_DIR }} +export HBASE_LOG_DIR={{ .HBASE_LOG_DIR }} +export HBASE_MANAGES_ZK=false + +export HBASE_OPTS="${HBASE_OPTS:-} -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelGCThreads=20 -Dsun.net.inetaddr.ttl=10 -Djava.net.preferIPv4Stack=true" +export SERVER_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${HBASE_LOG_DIR}/gc-server.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=50M" +export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps" + +export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" +export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_MASTER_JMX_PORT }} -Xms{{ .HBASE_MASTER_HEAP_SIZE }} -Xmx{{ .HBASE_MASTER_HEAP_SIZE }}" +export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Xms{{ .HBASE_REGIONSERVER_HEAP_SIZE }} -Xmx{{ .HBASE_REGIONSERVER_HEAP_SIZE }}" +export HBASE_HEAPSIZE={{ .HBASE_HEAP_SIZE }} + +export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP=true +export LD_LIBRARY_PATH={{ .HADOOP_NATIVE_LIB_PATH }}:${LD_LIBRARY_PATH:-} +export JAVA_HOME={{ .JAVA_HOME }} diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl new file mode 100644 index 0000000000..49abd36e63 --- /dev/null +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -0,0 +1,300 @@ + + + + + hbase.cluster.distributed + true + + + + hbase.rootdir + hdfs://{{ .HDFS_NAMESERVICE }}/{{ .HBASE_ROOT_DIR }} + + + + hbase.zookeeper.quorum + {{ .ZOOKEEPER_QUORUM }} + + + + hbase.zookeeper.property.clientPort + {{ .ZOOKEEPER_CLIENT_PORT }} + + + + zookeeper.znode.parent + {{ .HBASE_ZK_PARENT }} + + + + zookeeper.session.timeout + 30000 + + + + hbase.zookeeper.property.tickTime + 6000 + + + + hbase.zookeeper.property.4lw.commands.whitelist + * + + + + hbase.zookeeper.property.maxClientCnxns + 4000 + + + + hbase.zookeeper.property.autopurge.purgeInterval + 1 + + + + hbase.zookeeper.property.autopurge.snapRetainCount + 3 + + + + hbase.master.port + 16000 + + + + hbase.master.info.port + 16010 + + + + hbase.regionserver.port + 16020 + + + + hbase.regionserver.info.port + 16030 + + + + hbase.regionserver.hostname + {{ .POD_FQDN }} + + + + hbase.regionserver.hostname.disable.master.reversedns + true + + + + hbase.tmp.dir + {{ .HBASE_TMP_DIR }} + + + + hbase.regionserver.handler.count + 100 + + + + hbase.hstore.flusher.count + 4 + + + + hbase.client.scanner.caching + 100 + + + + hbase.hregion.max.filesize + 53687091200 + + + + hbase.hregion.memstore.flush.size + 134217728 + + + + hbase.hregion.majorcompaction + 0 + + + + hbase.storescanner.parallel.seek.enable + true + + + + hbase.ipc.server.callqueue.type + plunger + + + + hbase.master.wait.on.regionservers.timeout + 300000 + + + + hbase.master.startup.retainassign.timeout + 300000 + + + + hbase.assignment.usezk + false + + + + hbase.oldwals.cleaner.thread.timeout.msec + 60000 + + + + hbase.master.logcleaner.ttl + 60000 + + + + hbase.master.hfilecleaner.ttl + 600000 + + + + hbase.balancer.period + 1800000 + + + + hbase.master.balancer.stochastic.runMaxSteps + true + + + + hbase.master.loadbalancer.class + org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer + + + + hbase.procedure.store.wal.use.hsync + true + + + + hbase.regionserver.optionalcacheflushinterval + 28800000 + + + + hbase.regionserver.startup.retries + 10 + + + + hbase.regionserver.startup.retry.interval + 10000 + + + + hbase.wal.provider + filesystem + + + + hbase.replication + true + + + + hbase.security.authentication + simple + + + + hbase.security.authorization + false + + + + hbase.unsafe.stream.capability.enforce + false + + + + hbase.master.logcleaner.plugins + + org.apache.hadoop.hbase.master.cleaner.TimeToLiveLogCleaner,org.apache.hadoop.hbase.master.cleaner.TimeToLiveProcedureWALCleaner,org.apache.hadoop.hbase.replication.master.ReplicationLogCleaner + + + + hbase.master.hfilecleaner.plugins + org.apache.hadoop.hbase.master.cleaner.TimeToLiveHFileCleaner + + + + hbase.master.procedure.tlogcleaner.plugins + org.apache.hadoop.hbase.master.cleaner.TimeToLiveProcedureWALCleaner + + + + hbase.coprocessor.master.classes + + org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint,org.apache.hadoop.hbase.rsgroup.RSGroupAdminEndpoint + + + + hbase.coprocessor.regionserver.classes + org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint + + + + dfs.client.failover.max.attempts + 15 + + + + dfs.client.failover.sleep.base.millis + 500 + + + + dfs.client.failover.sleep.max.millis + 15000 + + + + dfs.client.retry.policy.enabled + true + + + + dfs.client.retry.policy.spec + 10000,6,60000,10 + + + + ipc.client.connect.timeout + 30000 + + + + ipc.client.connect.max.retries + 10 + + + + hbase.regionserver.wal.codec + org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec + + + + hbase.regionserver.wal.rs.bulkload.enabled + true + + + + hbase.splitlog.manager.timeout + 600000 + + \ No newline at end of file diff --git a/addons/hbase/config/hbase-site-standalone.tpl b/addons/hbase/config/hbase-site-standalone.tpl new file mode 100644 index 0000000000..f152f16d4d --- /dev/null +++ b/addons/hbase/config/hbase-site-standalone.tpl @@ -0,0 +1,138 @@ + + + + + hbase.cluster.distributed + false + + + + hbase.rootdir + file://{{ .HBASE_DATA_DIR }}/hbase + + + + hbase.zookeeper.quorum + {{ .ZOOKEEPER_QUORUM }} + + + + hbase.zookeeper.property.clientPort + {{ .ZOOKEEPER_CLIENT_PORT }} + + + + zookeeper.znode.parent + {{ .HBASE_ZK_PARENT }} + + + + zookeeper.session.timeout + 30000 + + + + hbase.zookeeper.property.tickTime + 6000 + + + + hbase.zookeeper.property.4lw.commands.whitelist + * + + + + hbase.zookeeper.property.maxClientCnxns + 4000 + + + + hbase.zookeeper.property.autopurge.purgeInterval + 1 + + + + hbase.zookeeper.property.autopurge.snapRetainCount + 3 + + + + hbase.master.port + 16000 + + + + hbase.master.info.port + 16010 + + + + hbase.regionserver.port + 16020 + + + + hbase.regionserver.info.port + 16030 + + + + hbase.tmp.dir + {{ .HBASE_TMP_DIR }} + + + + hbase.regionserver.handler.count + 30 + + + + hbase.hstore.flusher.count + 2 + + + + hbase.client.scanner.caching + 100 + + + + hbase.hregion.max.filesize + 10737418240 + + + + hbase.hregion.memstore.flush.size + 134217728 + + + + hbase.unsafe.stream.capability.enforce + false + + + + hbase.procedure.store.wal.use.hsync + false + + + + hbase.wal.provider + filesystem + + + + hbase.replication + false + + + + hbase.security.authentication + simple + + + + hbase.security.authorization + false + + diff --git a/addons/hbase/config/hdfs-client-site.tpl b/addons/hbase/config/hdfs-client-site.tpl new file mode 100644 index 0000000000..d0b34f0a10 --- /dev/null +++ b/addons/hbase/config/hdfs-client-site.tpl @@ -0,0 +1,53 @@ + + + + + + dfs.nameservices + {{- .HDFS_NAMESERVICE }} + + + + dfs.ha.namenodes.{{- .HDFS_NAMESERVICE }} + {{- .HDFS_NAMENODE_NODES }} + + +{{- $nodes := splitList "," .HDFS_NAMENODE_NODES }} +{{- $rpcPort := .HDFS_NAMENODE_RPC_PORT }} +{{- $httpPort := .HDFS_NAMENODE_HTTP_PORT }} +{{- $ns := .HDFS_NAMESERVICE }} +{{- $clusterDomain := .CLUSTER_DOMAIN }} +{{- $namespace := .NAMESPACE }} +{{- $headlessSvc := printf "%s-namenode-headless" $ns }} +{{- range $nn := $nodes }} +{{- $ordinal := trimPrefix "nn" $nn }} + + dfs.namenode.rpc-address.{{ $ns }}.{{ $nn }} + {{ $ns }}-namenode-{{ $ordinal }}.{{ $headlessSvc }}.{{ $namespace }}.svc.{{ $clusterDomain }}:{{ $rpcPort }} + + + dfs.namenode.http-address.{{ $ns }}.{{ $nn }} + {{ $ns }}-namenode-{{ $ordinal }}.{{ $headlessSvc }}.{{ $namespace }}.svc.{{ $clusterDomain }}:{{ $httpPort }} + +{{- end }} + + + dfs.client.failover.proxy.provider.{{- .HDFS_NAMESERVICE }} + org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider + + + + dfs.replication + {{- .HDFS_REPLICATION }} + + + + dfs.webhdfs.enabled + false + + + + dfs.permissions.enabled + {{- .HDFS_PERMISSIONS_ENABLED }} + + diff --git a/addons/hbase/config/log4j.properties b/addons/hbase/config/log4j.properties new file mode 100644 index 0000000000..8266ee95a5 --- /dev/null +++ b/addons/hbase/config/log4j.properties @@ -0,0 +1,69 @@ +# 根日志配置 +log4j.rootLogger=INFO, console, RFA + +# 禁用某些包的日志 +log4j.logger.org.apache.zookeeper=WARN +log4j.logger.org.apache.hadoop.hbase.zookeeper.RecoverableZooKeeper=WARN +log4j.logger.org.apache.hadoop.hbase.zookeeper.ZKUtil=WARN +log4j.logger.org.apache.hadoop.hbase.HBaseConfiguration=INFO + +# 控制台输出配置 +log4j.appender.console=org.apache.log4j.ConsoleAppender +log4j.appender.console.target=System.err +log4j.appender.console.layout=org.apache.log4j.PatternLayout +log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n + +# 日志文件输出配置 (Daily Rolling File Appender) +log4j.appender.DRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.DRFA.File=${hbase.log.dir}/${hbase.log.file} +log4j.appender.DRFA.DatePattern=.yyyy-MM-dd +log4j.appender.DRFA.layout=org.apache.log4j.PatternLayout +log4j.appender.DRFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n + +# 安全审计日志配置 +log4j.logger.SecurityLogger=INFO,RFAS +log4j.appender.RFAS=org.apache.log4j.DailyRollingFileAppender +log4j.appender.RFAS.File=${hbase.log.dir}/security.log +log4j.appender.RFAS.layout=org.apache.log4j.PatternLayout +log4j.appender.RFAS.layout.ConversionPattern=%d{ISO8601} %p %c: %m%n +log4j.appender.RFAS.DatePattern=.yyyy-MM-dd + +# HBase UI 访问日志配置 +log4j.logger.http.requests.hbase=INFO,HRFA +log4j.appender.HRFA=org.apache.log4j.DailyRollingFileAppender +log4j.appender.HRFA.File=${hbase.log.dir}/http-access.log +log4j.appender.HRFA.layout=org.apache.log4j.PatternLayout +log4j.appender.HRFA.layout.ConversionPattern=%t %h %l %u %t "%r" %>s %b "%{Referer}i" "%{User-Agent}i" +log4j.appender.HRFA.DatePattern=.yyyy-MM-dd + +# 特定组件日志级别配置 +log4j.logger.org.apache.hadoop.hbase.master=INFO +log4j.logger.org.apache.hadoop.hbase.regionserver=INFO +log4j.logger.org.apache.hadoop.hbase.client=INFO +log4j.logger.org.apache.hadoop.hbase.replication=INFO +log4j.logger.org.apache.hadoop.hbase.metrics=INFO + +# 性能相关日志配置 +log4j.logger.org.apache.hadoop.hbase.regionserver.HRegionServer=INFO +log4j.logger.org.apache.hadoop.hbase.regionserver.CompactSplitThread=INFO +log4j.logger.org.apache.hadoop.hbase.regionserver.MemStoreFlusher=INFO + +# 添加异步 Appender(提高性能) +log4j.appender.ASYNC=org.apache.log4j.AsyncAppender +log4j.appender.ASYNC.Blocking=false +log4j.appender.ASYNC.BufferSize=10000 +log4j.appender.ASYNC.appenders=DRFA + +# 日志大小滚动配置 +log4j.appender.RFA=org.apache.log4j.RollingFileAppender +log4j.appender.RFA.File=${hbase.log.dir}/${hbase.log.file} +log4j.appender.RFA.MaxFileSize=256MB +log4j.appender.RFA.MaxBackupIndex=20 +log4j.appender.RFA.layout=org.apache.log4j.PatternLayout +log4j.appender.RFA.layout.ConversionPattern=%d{ISO8601} %-5p [%t] %c{2}: %m%n + +# 添加额外的调试信息(需要时取消注释) +#log4j.logger.org.apache.hadoop.hbase=DEBUG +#log4j.logger.org.apache.hadoop.hbase.regionserver.StoreFile=DEBUG +#log4j.logger.org.apache.hadoop.hbase.regionserver.Region=DEBUG +#log4j.logger.org.apache.hadoop.hbase.regionserver.HStore=DEBUG diff --git a/addons/hbase/releases_notes.yaml b/addons/hbase/releases_notes.yaml new file mode 100644 index 0000000000..ea44d0becc --- /dev/null +++ b/addons/hbase/releases_notes.yaml @@ -0,0 +1,9 @@ +releases: +- version: 1.1.0 + released_at: '2026-05-21' + status: stable + git_branch: release-1.1 + git_tag: v1.1.0 + commit_sha: '' +- version: 0.9.0 + git_branch: release-0.9 \ No newline at end of file diff --git a/addons/hbase/scripts/check-hmaster-status.sh b/addons/hbase/scripts/check-hmaster-status.sh new file mode 100644 index 0000000000..2405184e65 --- /dev/null +++ b/addons/hbase/scripts/check-hmaster-status.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +HMASTER_INFO_PORT=${HMASTER_INFO_PORT:-16010} + +if jps 2>/dev/null | grep -q HMaster; then + exit 0 +fi + +if pgrep -f "org.apache.hadoop.hbase.master.HMaster" > /dev/null 2>&1; then + exit 0 +fi + +if curl -sf -o /dev/null "http://127.0.0.1:${HMASTER_INFO_PORT}/master-status" 2>/dev/null; then + exit 0 +fi + +exit 1 diff --git a/addons/hbase/scripts/check-hregionserver-status.sh b/addons/hbase/scripts/check-hregionserver-status.sh new file mode 100644 index 0000000000..63063c5654 --- /dev/null +++ b/addons/hbase/scripts/check-hregionserver-status.sh @@ -0,0 +1,18 @@ +#!/bin/bash +set -e + +REGIONSERVER_INFO_PORT=${REGIONSERVER_INFO_PORT:-16030} + +if jps 2>/dev/null | grep -q HRegionServer; then + exit 0 +fi + +if pgrep -f "org.apache.hadoop.hbase.regionserver.HRegionServer" > /dev/null 2>&1; then + exit 0 +fi + +if curl -sf -o /dev/null "http://127.0.0.1:${REGIONSERVER_INFO_PORT}/rs-status" 2>/dev/null; then + exit 0 +fi + +exit 1 diff --git a/addons/hbase/scripts/init-hdfs-root-layout.sh b/addons/hbase/scripts/init-hdfs-root-layout.sh new file mode 100644 index 0000000000..193357664d --- /dev/null +++ b/addons/hbase/scripts/init-hdfs-root-layout.sh @@ -0,0 +1,28 @@ +#!/bin/bash +set -e + +source ${HBASE_CONF_DIR}/hbase-env.sh 2>/dev/null || true +mkdir -p ${HBASE_LOG_DIR} + +echo "[$(date)] Initializing HBase root layout in HDFS..." + +PATHS=( + "/${HBASE_ROOT_DIR}" + "/${HBASE_ROOT_DIR}/WALs" + "/${HBASE_ROOT_DIR}/data" + "/${HBASE_ROOT_DIR}/archive" + "/${HBASE_ROOT_DIR}/.tmp" + "/${HBASE_ROOT_DIR}/MasterData" + "/${HBASE_ROOT_DIR}/MasterData/WALs" +) + +for p in "${PATHS[@]}"; do + if timeout 30 ${HBASE_HOME}/bin/hbase org.apache.hadoop.fs.FsShell -test -e "${p}" 2>/dev/null; then + echo "[$(date)] Path ${p} already exists, skipping." + else + echo "[$(date)] Creating ${p}..." + timeout 30 ${HBASE_HOME}/bin/hbase org.apache.hadoop.fs.FsShell -mkdir -p "${p}" || true + fi +done + +echo "[$(date)] HBase root layout initialized." diff --git a/addons/hbase/scripts/start-hmaster.sh b/addons/hbase/scripts/start-hmaster.sh new file mode 100644 index 0000000000..a54a0f8c12 --- /dev/null +++ b/addons/hbase/scripts/start-hmaster.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e + +source ${HBASE_CONF_DIR}/hbase-env.sh 2>/dev/null || true +mkdir -p ${HBASE_LOG_DIR} ${HBASE_PID_DIR} + +function shutdown() { + echo "[$(date)] Stopping HMaster gracefully..." + ${HBASE_HOME}/bin/hbase-daemon.sh stop master || true + echo "[$(date)] HMaster stopped." +} + +trap shutdown SIGTERM SIGINT + +${HBASE_HOME}/bin/hbase master start & +master_pid=$! +wait $master_pid diff --git a/addons/hbase/scripts/start-hregionserver.sh b/addons/hbase/scripts/start-hregionserver.sh new file mode 100644 index 0000000000..4b29f87ef7 --- /dev/null +++ b/addons/hbase/scripts/start-hregionserver.sh @@ -0,0 +1,32 @@ +#!/bin/bash +set -e + +source ${HBASE_CONF_DIR}/hbase-env.sh 2>/dev/null || true +mkdir -p ${HBASE_LOG_DIR} ${HBASE_PID_DIR} + +function shutdown() { + echo "[$(date)] Stopping RegionServer gracefully..." + host=$(hostname -f 2>/dev/null || hostname) + export HBASE_STOP_TIMEOUT=20 + + echo "[$(date)] Disabling balancer before region unload..." + echo "balance_switch false" | ${HBASE_HOME}/bin/hbase shell 2>/dev/null || true + + echo "[$(date)] Unloading regions from ${host}..." + ${HBASE_HOME}/bin/hbase org.apache.hadoop.hbase.util.RegionMover -m 6 -r ${host} -o unload 2>&1 || true + + sleep 5 + + echo "[$(date)] Re-enabling balancer..." + echo "balance_switch true" | ${HBASE_HOME}/bin/hbase shell 2>/dev/null || true + + echo "[$(date)] Stopping RegionServer daemon..." + ${HBASE_HOME}/bin/hbase-daemon.sh stop regionserver || true + echo "[$(date)] RegionServer stopped." +} + +trap shutdown SIGTERM SIGINT + +${HBASE_HOME}/bin/hbase regionserver start & +rs_pid=$! +wait $rs_pid diff --git a/addons/hbase/templates/_helpers.tpl b/addons/hbase/templates/_helpers.tpl new file mode 100644 index 0000000000..e2ccdede15 --- /dev/null +++ b/addons/hbase/templates/_helpers.tpl @@ -0,0 +1,70 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "hbase.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Create chart name and version as used by the chart label. +*/}} +{{- define "hbase.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "hbase.labels" -}} +helm.sh/chart: {{ include "hbase.chart" . }} +{{ include "hbase.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "hbase.selectorLabels" -}} +app.kubernetes.io/name: {{ include "hbase.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +API version annotation +*/}} +{{- define "hbase.apiVersion" -}} +kubeblocks.io/crd-api-version: apps.kubeblocks.io/v1 +{{- end }} + +{{/* +Component definition regex patterns +*/}} +{{- define "hbase.hmasterCmpdRegexPattern" -}} +^hbase-hmaster-\d+\.?\d*$ +{{- end }} + +{{- define "hbase.hregionserverCmpdRegexPattern" -}} +^hbase-hregionserver-\d+\.?\d*$ +{{- end }} + +{{- define "hbase.hbaseStandaloneCmpdRegexPattern" -}} +^hbase-standalone-\d+\.?\d*$ +{{- end }} + +{{/* +Image references +*/}} +{{- define "hbase.hmasterImage" -}} +{{ .Values.hmaster.image.registry }}/{{ .Values.hmaster.image.repository }}:{{ .Values.hmaster.image.tag }} +{{- end }} + +{{- define "hbase.hregionserverImage" -}} +{{ .Values.hregionserver.image.registry }}/{{ .Values.hregionserver.image.repository }}:{{ .Values.hregionserver.image.tag }} +{{- end }} + +{{- define "hbase.hbaseStandaloneImage" -}} +{{ .Values.hbasestandalone.image.registry }}/{{ .Values.hbasestandalone.image.repository }}:{{ .Values.hbasestandalone.image.tag }} +{{- end }} diff --git a/addons/hbase/templates/clusterdefinition.yaml b/addons/hbase/templates/clusterdefinition.yaml new file mode 100644 index 0000000000..886ba5d199 --- /dev/null +++ b/addons/hbase/templates/clusterdefinition.yaml @@ -0,0 +1,31 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ClusterDefinition +metadata: + name: hbase + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + topologies: + - name: hbase-cluster + default: true + components: + - name: hmaster + compDef: {{ include "hbase.hmasterCmpdRegexPattern" . }} + - name: hregionserver + compDef: {{ include "hbase.hregionserverCmpdRegexPattern" . }} + orders: + provision: + - hmaster + - hregionserver + terminate: + - hregionserver + - hmaster + update: + - hregionserver + - hmaster + - name: hbase-standalone + components: + - name: hbase-standalone + compDef: {{ include "hbase.hbaseStandaloneCmpdRegexPattern" . }} diff --git a/addons/hbase/templates/cmpd-hbase-standalone.yaml b/addons/hbase/templates/cmpd-hbase-standalone.yaml new file mode 100644 index 0000000000..2660dfa179 --- /dev/null +++ b/addons/hbase/templates/cmpd-hbase-standalone.yaml @@ -0,0 +1,186 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hbase-standalone-2.5 + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hbase-standalone + serviceVersion: 2.5.6 + updateStrategy: BestEffortParallel + services: + - name: default + spec: + ports: + - name: hmaster + port: {{ .Values.ports.hmaster.rpc }} + - name: http + port: {{ .Values.ports.hmaster.info }} + - name: hregionserver + port: {{ .Values.ports.hregionserver.rpc }} + - name: rs-http + port: {{ .Values.ports.hregionserver.info }} + serviceRefDeclarations: + - name: hbase-zookeeper + serviceRefDeclarationSpecs: + - serviceKind: zookeeper + serviceVersion: "^*" + runtime: + terminationGracePeriodSeconds: 120 + containers: + - name: hbase-standalone + imagePullPolicy: {{ default "IfNotPresent" .Values.hbasestandalone.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-hmaster.sh + env: + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_HOME + value: {{ .Values.runtime.hbaseHome }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: HMASTER_INFO_PORT + value: {{ .Values.ports.hmaster.info | quote }} + ports: + - containerPort: {{ .Values.ports.hmaster.rpc }} + name: hmaster + - containerPort: {{ .Values.ports.hmaster.info }} + name: http + - containerPort: {{ .Values.ports.hregionserver.rpc }} + name: hregionserver + - containerPort: {{ .Values.ports.hregionserver.info }} + name: rs-http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 60 + periodSeconds: 30 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 20 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + volumeMounts: + - name: hbase-standalone-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-site.xml + subPath: hbase-site.xml + - name: hbase-standalone-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh + subPath: hbase-env.sh + - name: hbase-standalone-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties + subPath: hadoop-metrics2-hbase.properties + - name: hbase-standalone-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties + subPath: log4j.properties + - name: hbase-scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: data + mountPath: {{ .Values.runtime.hbaseDataDir }} + - name: hbase-logs + mountPath: {{ .Values.runtime.hbaseLogDir }} + - name: hbase-tmp + mountPath: {{ .Values.runtime.hbaseTmpDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: false + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: "RuntimeDefault" + securityContext: + fsGroupChangePolicy: Always + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hbase-logs + emptyDir: {} + - name: hbase-tmp + emptyDir: {} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: HBASE_TMP_DIR + value: {{ .Values.runtime.hbaseTmpDir }} + - name: HBASE_DATA_DIR + value: {{ .Values.runtime.hbaseDataDir }} + - name: HADOOP_NATIVE_LIB_PATH + value: {{ .Values.runtime.hadoopNativeLibPath }} + - name: JAVA_HOME + value: {{ .Values.runtime.javaHome }} + - name: HBASE_MASTER_HEAP_SIZE + value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} + - name: HBASE_REGIONSERVER_HEAP_SIZE + value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} + - name: HBASE_MASTER_JMX_PORT + value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_REGIONSERVER_JMX_PORT + value: {{ .Values.ports.hregionserver.jmx | quote }} + - name: HBASE_HEAP_SIZE + value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} + - name: ZOOKEEPER_QUORUM + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + host: Required + - name: ZOOKEEPER_CLIENT_PORT + value: {{ .Values.hbase.zkClientPort | quote }} + - name: ZOOKEEPER_ENDPOINTS + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + endpoint: Required + - name: HBASE_ZK_PARENT + value: {{ .Values.hbase.zkParent | quote }} + configs: + - name: hbase-standalone-config + template: hbase-standalone-config-template + volumeName: hbase-standalone-config + namespace: {{ .Release.Namespace }} + defaultMode: 0755 + scripts: + - name: hbase-scripts + template: hbase-scripts + volumeName: hbase-scripts + namespace: {{ .Release.Namespace }} + defaultMode: 0755 diff --git a/addons/hbase/templates/cmpd-hmaster.yaml b/addons/hbase/templates/cmpd-hmaster.yaml new file mode 100644 index 0000000000..f8a6be604f --- /dev/null +++ b/addons/hbase/templates/cmpd-hmaster.yaml @@ -0,0 +1,244 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hbase-hmaster-2.5 + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hbase-hmaster + serviceVersion: 2.5.6 + updateStrategy: BestEffortParallel + services: + - name: default + spec: + ports: + - name: hmaster + port: {{ .Values.ports.hmaster.rpc }} + - name: http + port: {{ .Values.ports.hmaster.info }} + serviceRefDeclarations: + - name: hbase-zookeeper + serviceRefDeclarationSpecs: + - serviceKind: zookeeper + serviceVersion: "^*" + - name: hdfs-namenode + serviceRefDeclarationSpecs: + - serviceKind: hdfs-namenode + serviceVersion: "^*" + runtime: + terminationGracePeriodSeconds: 120 + initContainers: + - name: init-hdfs-root-layout + imagePullPolicy: {{ default "IfNotPresent" .Values.hmaster.image.pullPolicy }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + env: + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_HOME + value: {{ .Values.runtime.hbaseHome }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_ROOT_DIR + value: {{ .Values.hbase.rootDir }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/init-hdfs-root-layout.sh + volumeMounts: + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-site.xml + subPath: hbase-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/core-site.xml + subPath: core-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh + subPath: hbase-env.sh + - name: hbase-scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: hbase-logs + mountPath: {{ .Values.runtime.hbaseLogDir }} + - name: hbase-tmp + mountPath: {{ .Values.runtime.hbaseTmpDir }} + containers: + - name: hbase-hmaster + imagePullPolicy: {{ default "IfNotPresent" .Values.hmaster.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-hmaster.sh + env: + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_HOME + value: {{ .Values.runtime.hbaseHome }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: HMASTER_INFO_PORT + value: {{ .Values.ports.hmaster.info | quote }} + ports: + - containerPort: {{ .Values.ports.hmaster.rpc }} + name: hmaster + - containerPort: {{ .Values.ports.hmaster.info }} + name: http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 120 + periodSeconds: 30 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hmaster-status.sh + volumeMounts: + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-site.xml + subPath: hbase-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/core-site.xml + subPath: core-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh + subPath: hbase-env.sh + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties + subPath: hadoop-metrics2-hbase.properties + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties + subPath: log4j.properties + - name: hbase-scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: hbase-logs + mountPath: {{ .Values.runtime.hbaseLogDir }} + - name: hbase-tmp + mountPath: {{ .Values.runtime.hbaseTmpDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: false + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: "RuntimeDefault" + securityContext: + fsGroupChangePolicy: Always + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hbase-logs + emptyDir: {} + - name: hbase-tmp + emptyDir: {} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: HBASE_TMP_DIR + value: {{ .Values.runtime.hbaseTmpDir }} + - name: HADOOP_NATIVE_LIB_PATH + value: {{ .Values.runtime.hadoopNativeLibPath }} + - name: JAVA_HOME + value: {{ .Values.runtime.javaHome }} + - name: HBASE_MASTER_HEAP_SIZE + value: {{ .Values.jvm.hmasterHeapSize | quote }} + - name: HBASE_REGIONSERVER_HEAP_SIZE + value: {{ .Values.jvm.hregionserverHeapSize | quote }} + - name: HBASE_MASTER_JMX_PORT + value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_REGIONSERVER_JMX_PORT + value: {{ .Values.ports.hregionserver.jmx | quote }} + - name: HBASE_HEAP_SIZE + value: {{ .Values.jvm.hmasterHeapSize | quote }} + - name: ZOOKEEPER_QUORUM + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + host: Required + - name: ZOOKEEPER_CLIENT_PORT + value: {{ .Values.hbase.zkClientPort | quote }} + - name: ZOOKEEPER_ENDPOINTS + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + endpoint: Required + - name: HBASE_ROOT_DIR + value: {{ .Values.hbase.rootDir | quote }} + - name: HBASE_ZK_PARENT + value: {{ .Values.hbase.zkParent | quote }} + - name: HDFS_NAMESERVICE + value: {{ .Values.hdfs.nameservice | quote }} + - name: HDFS_NAMENODE_NODES + value: {{ .Values.hdfs.namenodeNodes | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.namenodeRpcPort | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.namenodeHttpPort | quote }} + - name: HDFS_HA_ZK_PARENT + value: {{ .Values.hdfs.haZkParent | quote }} + - name: HDFS_REPLICATION + value: {{ .Values.hdfs.replication | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: "false" + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + apiVersion: v1 + configs: + - name: hbase-config + template: hbase-cluster-config-template + volumeName: hbase-config + namespace: {{ .Release.Namespace }} + defaultMode: 0755 + scripts: + - name: hbase-scripts + template: hbase-scripts + volumeName: hbase-scripts + namespace: {{ .Release.Namespace }} + defaultMode: 0755 diff --git a/addons/hbase/templates/cmpd-hregionserver.yaml b/addons/hbase/templates/cmpd-hregionserver.yaml new file mode 100644 index 0000000000..0cf7625ea2 --- /dev/null +++ b/addons/hbase/templates/cmpd-hregionserver.yaml @@ -0,0 +1,207 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentDefinition +metadata: + name: hbase-hregionserver-2.5 + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + provider: kubeblocks + description: {{ .Chart.Description }} + serviceKind: hbase-hregionserver + serviceVersion: 2.5.6 + updateStrategy: BestEffortParallel + services: + - name: default + spec: + ports: + - name: hregionserver + port: {{ .Values.ports.hregionserver.rpc }} + - name: http + port: {{ .Values.ports.hregionserver.info }} + serviceRefDeclarations: + - name: hbase-zookeeper + serviceRefDeclarationSpecs: + - serviceKind: zookeeper + serviceVersion: "^*" + - name: hdfs-namenode + serviceRefDeclarationSpecs: + - serviceKind: hdfs-namenode + serviceVersion: "^*" + runtime: + terminationGracePeriodSeconds: 300 + containers: + - name: hbase-hregionserver + imagePullPolicy: {{ default "IfNotPresent" .Values.hregionserver.image.pullPolicy }} + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/start-hregionserver.sh + env: + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HADOOP_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_HOME + value: {{ .Values.runtime.hbaseHome }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: REGIONSERVER_INFO_PORT + value: {{ .Values.ports.hregionserver.info | quote }} + ports: + - containerPort: {{ .Values.ports.hregionserver.rpc }} + name: hregionserver + - containerPort: {{ .Values.ports.hregionserver.info }} + name: http + startupProbe: + failureThreshold: 30 + initialDelaySeconds: 60 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hregionserver-status.sh + livenessProbe: + failureThreshold: 6 + initialDelaySeconds: 120 + periodSeconds: 30 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hregionserver-status.sh + readinessProbe: + failureThreshold: 6 + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + exec: + command: + - /bin/bash + - {{ .Values.runtime.scriptsDir }}/check-hregionserver-status.sh + volumeMounts: + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-site.xml + subPath: hbase-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/core-site.xml + subPath: core-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hdfs-site.xml + subPath: hdfs-site.xml + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh + subPath: hbase-env.sh + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties + subPath: hadoop-metrics2-hbase.properties + - name: hbase-config + mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties + subPath: log4j.properties + - name: hbase-scripts + mountPath: {{ .Values.runtime.scriptsDir }} + - name: hbase-logs + mountPath: {{ .Values.runtime.hbaseLogDir }} + - name: hbase-tmp + mountPath: {{ .Values.runtime.hbaseTmpDir }} + securityContext: + runAsUser: {{ .Values.securityContext.runAsUser }} + runAsGroup: {{ .Values.securityContext.runAsGroup }} + runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} + privileged: false + allowPrivilegeEscalation: false + capabilities: + drop: [ "ALL" ] + seccompProfile: + type: "RuntimeDefault" + securityContext: + fsGroupChangePolicy: Always + fsGroup: {{ .Values.securityContext.fsGroup }} + volumes: + - name: hbase-logs + emptyDir: {} + - name: hbase-tmp + emptyDir: {} + vars: + - name: CLUSTER_NAME + valueFrom: + clusterVarRef: + clusterName: Required + - name: NAMESPACE + valueFrom: + clusterVarRef: + namespace: Required + - name: CLUSTER_DOMAIN + value: {{ .Values.extra.clusterDomain }} + - name: HBASE_CONF_DIR + value: {{ .Values.runtime.hbaseConfDir }} + - name: HBASE_LOG_DIR + value: {{ .Values.runtime.hbaseLogDir }} + - name: HBASE_PID_DIR + value: {{ .Values.runtime.hbasePidDir }} + - name: HBASE_TMP_DIR + value: {{ .Values.runtime.hbaseTmpDir }} + - name: HADOOP_NATIVE_LIB_PATH + value: {{ .Values.runtime.hadoopNativeLibPath }} + - name: JAVA_HOME + value: {{ .Values.runtime.javaHome }} + - name: HBASE_MASTER_HEAP_SIZE + value: {{ .Values.jvm.hmasterHeapSize | quote }} + - name: HBASE_REGIONSERVER_HEAP_SIZE + value: {{ .Values.jvm.hregionserverHeapSize | quote }} + - name: HBASE_MASTER_JMX_PORT + value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_REGIONSERVER_JMX_PORT + value: {{ .Values.ports.hregionserver.jmx | quote }} + - name: HBASE_HEAP_SIZE + value: {{ .Values.jvm.hregionserverHeapSize | quote }} + - name: ZOOKEEPER_QUORUM + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + host: Required + - name: ZOOKEEPER_CLIENT_PORT + value: {{ .Values.hbase.zkClientPort | quote }} + - name: ZOOKEEPER_ENDPOINTS + valueFrom: + serviceRefVarRef: + name: hbase-zookeeper + endpoint: Required + - name: HBASE_ROOT_DIR + value: {{ .Values.hbase.rootDir | quote }} + - name: HBASE_ZK_PARENT + value: {{ .Values.hbase.zkParent | quote }} + - name: HDFS_NAMESERVICE + value: {{ .Values.hdfs.nameservice | quote }} + - name: HDFS_NAMENODE_NODES + value: {{ .Values.hdfs.namenodeNodes | quote }} + - name: HDFS_NAMENODE_RPC_PORT + value: {{ .Values.hdfs.namenodeRpcPort | quote }} + - name: HDFS_NAMENODE_HTTP_PORT + value: {{ .Values.hdfs.namenodeHttpPort | quote }} + - name: HDFS_HA_ZK_PARENT + value: {{ .Values.hdfs.haZkParent | quote }} + - name: HDFS_REPLICATION + value: {{ .Values.hdfs.replication | quote }} + - name: HDFS_PERMISSIONS_ENABLED + value: "false" + - name: POD_FQDN + valueFrom: + fieldRef: + fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] + apiVersion: v1 + configs: + - name: hbase-config + template: hbase-cluster-config-template + volumeName: hbase-config + namespace: {{ .Release.Namespace }} + defaultMode: 0755 + scripts: + - name: hbase-scripts + template: hbase-scripts + volumeName: hbase-scripts + namespace: {{ .Release.Namespace }} + defaultMode: 0755 diff --git a/addons/hbase/templates/cmpv-hbase-standalone.yaml b/addons/hbase/templates/cmpv-hbase-standalone.yaml new file mode 100644 index 0000000000..8533d2122d --- /dev/null +++ b/addons/hbase/templates/cmpv-hbase-standalone.yaml @@ -0,0 +1,19 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hbase-standalone + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - compDefs: + - hbase-standalone-2.5 + releases: + - 2.5.6 + releases: + - name: 2.5.6 + serviceVersion: 2.5.6 + images: + hbase-standalone: {{ include "hbase.hbaseStandaloneImage" . | quote }} diff --git a/addons/hbase/templates/cmpv-hmaster.yaml b/addons/hbase/templates/cmpv-hmaster.yaml new file mode 100644 index 0000000000..8669d6c677 --- /dev/null +++ b/addons/hbase/templates/cmpv-hmaster.yaml @@ -0,0 +1,20 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hbase-hmaster + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - compDefs: + - hbase-hmaster-2.5 + releases: + - 2.5.6 + releases: + - name: 2.5.6 + serviceVersion: 2.5.6 + images: + init-hdfs-root-layout: {{ include "hbase.hmasterImage" . | quote }} + hbase-hmaster: {{ include "hbase.hmasterImage" . | quote }} diff --git a/addons/hbase/templates/cmpv-hregionserver.yaml b/addons/hbase/templates/cmpv-hregionserver.yaml new file mode 100644 index 0000000000..a4208ea1f6 --- /dev/null +++ b/addons/hbase/templates/cmpv-hregionserver.yaml @@ -0,0 +1,19 @@ +apiVersion: apps.kubeblocks.io/v1 +kind: ComponentVersion +metadata: + name: hbase-hregionserver + labels: + {{- include "hbase.labels" . | nindent 4 }} + annotations: + {{- include "hbase.apiVersion" . | nindent 4 }} +spec: + compatibilityRules: + - compDefs: + - hbase-hregionserver-2.5 + releases: + - 2.5.6 + releases: + - name: 2.5.6 + serviceVersion: 2.5.6 + images: + hbase-hregionserver: {{ include "hbase.hregionserverImage" . | quote }} diff --git a/addons/hbase/templates/hbase-cluster-config-template.yaml b/addons/hbase/templates/hbase-cluster-config-template.yaml new file mode 100644 index 0000000000..a4b5b9ea6f --- /dev/null +++ b/addons/hbase/templates/hbase-cluster-config-template.yaml @@ -0,0 +1,19 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hbase-cluster-config-template + labels: + {{- include "hbase.labels" . | nindent 4 }} +data: + hbase-site.xml: |- + {{- .Files.Get "config/hbase-site-cluster.tpl" | nindent 4 }} + core-site.xml: |- + {{- .Files.Get "config/hadoop-core-site.tpl" | nindent 4 }} + hdfs-site.xml: |- + {{- .Files.Get "config/hdfs-client-site.tpl" | nindent 4 }} + hbase-env.sh: |- + {{- .Files.Get "config/hbase-env.sh.tpl" | nindent 4 }} + hadoop-metrics2-hbase.properties: |- + {{- .Files.Get "config/hadoop-metrics2-hbase.properties.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hbase/templates/hbase-scripts-template.yaml b/addons/hbase/templates/hbase-scripts-template.yaml new file mode 100644 index 0000000000..4de69a179d --- /dev/null +++ b/addons/hbase/templates/hbase-scripts-template.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hbase-scripts + labels: + {{- include "hbase.labels" . | nindent 4 }} +data: + start-hmaster.sh: |- + {{- .Files.Get "scripts/start-hmaster.sh" | nindent 4 }} + start-hregionserver.sh: |- + {{- .Files.Get "scripts/start-hregionserver.sh" | nindent 4 }} + init-hdfs-root-layout.sh: |- + {{- .Files.Get "scripts/init-hdfs-root-layout.sh" | nindent 4 }} + check-hmaster-status.sh: |- + {{- .Files.Get "scripts/check-hmaster-status.sh" | nindent 4 }} + check-hregionserver-status.sh: |- + {{- .Files.Get "scripts/check-hregionserver-status.sh" | nindent 4 }} diff --git a/addons/hbase/templates/hbase-standalone-config-template.yaml b/addons/hbase/templates/hbase-standalone-config-template.yaml new file mode 100644 index 0000000000..34332f371a --- /dev/null +++ b/addons/hbase/templates/hbase-standalone-config-template.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: hbase-standalone-config-template + labels: + {{- include "hbase.labels" . | nindent 4 }} +data: + hbase-site.xml: |- + {{- .Files.Get "config/hbase-site-standalone.tpl" | nindent 4 }} + hbase-env.sh: |- + {{- .Files.Get "config/hbase-env.sh.tpl" | nindent 4 }} + hadoop-metrics2-hbase.properties: |- + {{- .Files.Get "config/hadoop-metrics2-hbase.properties.tpl" | nindent 4 }} + log4j.properties: |- + {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hbase/values.yaml b/addons/hbase/values.yaml new file mode 100644 index 0000000000..ce65c083ae --- /dev/null +++ b/addons/hbase/values.yaml @@ -0,0 +1,72 @@ +hmaster: + image: + registry: docker.io + repository: apecloud/hbase-hmaster + tag: "v2.5.6-1.0.0" + pullPolicy: IfNotPresent + +hregionserver: + image: + registry: docker.io + repository: apecloud/hbase-hregionserver + tag: "v2.5.6-1.0.0" + pullPolicy: IfNotPresent + +hbasestandalone: + image: + registry: docker.io + repository: apecloud/hbase-hmaster + tag: "v2.5.6-1.0.0" + pullPolicy: IfNotPresent + +runtime: + hbaseHome: /opt/hbase-2.5.6 + hbaseConfDir: /hbase/conf + hbaseLogDir: /var/log/hbase + hbasePidDir: /var/run/hbase + hbaseTmpDir: /hbase/tmp + hbaseDataDir: /data/hbase + scriptsDir: /hbase/scripts + hadoopConfDir: /hadoop/conf + hadoopHome: /opt/hadoop + hadoopNativeLibPath: /opt/hadoop/lib/native + javaHome: /usr/local/openjdk-8 + +ports: + hmaster: + rpc: 16000 + info: 16010 + jmx: 10103 + hregionserver: + rpc: 16020 + info: 16030 + jmx: 10104 + +jvm: + hmasterHeapSize: 3g + hregionserverHeapSize: 4g + hbasestandaloneHeapSize: 512m + +hbase: + rootDir: hbase + zkParent: /hbase + zkClientPort: 2181 + +hdfs: + nameservice: "" + namenodeNodes: nn0,nn1 + namenodeRpcPort: 8020 + namenodeHttpPort: 9870 + haZkParent: /hadoop-ha + replication: "3" + +extra: + disableExporter: true + terminationPolicy: Delete + clusterDomain: cluster.local + +securityContext: + runAsUser: 10000 + runAsGroup: 1000 + runAsNonRoot: true + fsGroup: 1000 From 41ec2c66cb9fa9ab4cea2688738cce8cb8fbb7d0 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 15:56:24 +0800 Subject: [PATCH 02/18] fix(hadoop,hbase): fix hbase topology/serviceRef and parameterize runtime ports --- addons-cluster/hbase/templates/cluster.yaml | 10 ++++++ addons-cluster/hbase/values.schema.json | 31 ++++++++++++++++++- addons-cluster/hbase/values.yaml | 9 +++++- .../config/hdfs-datanode-standalone.tpl | 8 ++--- addons/hadoop/config/hdfs-datanode.tpl | 8 ++--- addons/hadoop/scripts/check-data-status.sh | 2 +- addons/hadoop/scripts/check-journal-status.sh | 4 +-- addons/hadoop/scripts/check-name-status.sh | 2 +- .../cmpd-hdfs-datanode-standalone.yaml | 6 ++++ .../hadoop/templates/cmpd-hdfs-datanode.yaml | 6 ++++ addons/hbase/config/hbase-site-cluster.tpl | 10 +++--- addons/hbase/config/hbase-site-standalone.tpl | 8 ++--- addons/hbase/templates/clusterdefinition.yaml | 4 +-- .../templates/cmpd-hbase-standalone.yaml | 8 +++++ addons/hbase/templates/cmpd-hmaster.yaml | 8 +++++ .../hbase/templates/cmpd-hregionserver.yaml | 8 +++++ 16 files changed, 107 insertions(+), 25 deletions(-) diff --git a/addons-cluster/hbase/templates/cluster.yaml b/addons-cluster/hbase/templates/cluster.yaml index 30b5720442..919a45f088 100644 --- a/addons-cluster/hbase/templates/cluster.yaml +++ b/addons-cluster/hbase/templates/cluster.yaml @@ -33,6 +33,11 @@ - name: hbase-config variables: HDFS_NAMESERVICE: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster | quote }} + HDFS_NAMENODE_NODES: {{ .Values.hdfs.namenodeNodes | quote }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.namenodeRpcPort | quote }} + HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.namenodeHttpPort | quote }} + HDFS_HA_ZK_PARENT: {{ .Values.hdfs.haZkParent | quote }} + HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} resources: requests: cpu: {{ .Values.resources.hmaster.requests.cpu | quote }} @@ -73,6 +78,11 @@ - name: hbase-config variables: HDFS_NAMESERVICE: {{ .Values.serviceRefs.hdfsNamenode.clusterServiceSelector.cluster | quote }} + HDFS_NAMENODE_NODES: {{ .Values.hdfs.namenodeNodes | quote }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.namenodeRpcPort | quote }} + HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.namenodeHttpPort | quote }} + HDFS_HA_ZK_PARENT: {{ .Values.hdfs.haZkParent | quote }} + HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} resources: requests: cpu: {{ .Values.resources.hregionserver.requests.cpu | quote }} diff --git a/addons-cluster/hbase/values.schema.json b/addons-cluster/hbase/values.schema.json index 702f2a9c56..dae56e3984 100644 --- a/addons-cluster/hbase/values.schema.json +++ b/addons-cluster/hbase/values.schema.json @@ -67,6 +67,35 @@ "$ref": "#/definitions/serviceRefSchema" } } + }, + "hdfs": { + "type": "object", + "properties": { + "namenodeNodes": { + "type": "string", + "default": "nn0,nn1" + }, + "namenodeRpcPort": { + "type": "integer", + "default": 8020, + "minimum": 1, + "maximum": 65535 + }, + "namenodeHttpPort": { + "type": "integer", + "default": 9870, + "minimum": 1, + "maximum": 65535 + }, + "haZkParent": { + "type": "string", + "default": "/hadoop-ha" + }, + "replication": { + "type": "string", + "default": "3" + } + } } }, "definitions": { @@ -134,4 +163,4 @@ } } } -} \ No newline at end of file +} diff --git a/addons-cluster/hbase/values.yaml b/addons-cluster/hbase/values.yaml index bfc596a181..5c66060bab 100644 --- a/addons-cluster/hbase/values.yaml +++ b/addons-cluster/hbase/values.yaml @@ -48,7 +48,14 @@ serviceRefs: service: component: namenode service: headless - port: client + port: fs + +hdfs: + namenodeNodes: nn0,nn1 + namenodeRpcPort: 8020 + namenodeHttpPort: 9870 + haZkParent: /hadoop-ha + replication: "3" extra: terminationPolicy: Delete diff --git a/addons/hadoop/config/hdfs-datanode-standalone.tpl b/addons/hadoop/config/hdfs-datanode-standalone.tpl index d2bc8cc558..5b517422fb 100644 --- a/addons/hadoop/config/hdfs-datanode-standalone.tpl +++ b/addons/hadoop/config/hdfs-datanode-standalone.tpl @@ -29,17 +29,17 @@ dfs.datanode.address - 0.0.0.0:9866 + 0.0.0.0:{{- .HDFS_DATANODE_DATA_PORT }} dfs.datanode.http.address - 0.0.0.0:9864 + 0.0.0.0:{{- .HDFS_DATANODE_HTTP_PORT }} dfs.datanode.ipc.address - 0.0.0.0:9867 + 0.0.0.0:{{- .HDFS_DATANODE_IPC_PORT }} @@ -102,4 +102,4 @@ dfs.client.retry.policy.spec 1000,1 - \ No newline at end of file + diff --git a/addons/hadoop/config/hdfs-datanode.tpl b/addons/hadoop/config/hdfs-datanode.tpl index e67620f75e..ddddf036ea 100644 --- a/addons/hadoop/config/hdfs-datanode.tpl +++ b/addons/hadoop/config/hdfs-datanode.tpl @@ -34,17 +34,17 @@ dfs.datanode.address - 0.0.0.0:9866 + 0.0.0.0:{{- .HDFS_DATANODE_DATA_PORT }} dfs.datanode.http.address - 0.0.0.0:9864 + 0.0.0.0:{{- .HDFS_DATANODE_HTTP_PORT }} dfs.datanode.ipc.address - 0.0.0.0:9867 + 0.0.0.0:{{- .HDFS_DATANODE_IPC_PORT }} @@ -126,4 +126,4 @@ dfs.client.retry.policy.spec 1000,1 - \ No newline at end of file + diff --git a/addons/hadoop/scripts/check-data-status.sh b/addons/hadoop/scripts/check-data-status.sh index 3ee9371bac..6b89f4adb9 100644 --- a/addons/hadoop/scripts/check-data-status.sh +++ b/addons/hadoop/scripts/check-data-status.sh @@ -4,7 +4,7 @@ set -o errtrace set -o nounset set -o pipefail -_PORTS="9864" +_PORTS="${HDFS_DATANODE_HTTP_PORT:-9864}" _URL_PATH="jmx?qry=Hadoop:service=DataNode,name=DataNodeInfo" _CLUSTER_ID="" for _PORT in $_PORTS; do diff --git a/addons/hadoop/scripts/check-journal-status.sh b/addons/hadoop/scripts/check-journal-status.sh index 9bed332a6b..eb34b26592 100644 --- a/addons/hadoop/scripts/check-journal-status.sh +++ b/addons/hadoop/scripts/check-journal-status.sh @@ -13,11 +13,11 @@ set -o pipefail set -o xtrace # Check if datanode registered with the namenode and got non-null cluster ID. -_PORTS="8480" +_PORTS="${HDFS_JOURNALNODE_HTTP_PORT:-8480}" _URL_PATH="jmx?qry=Hadoop:service=JournalNode,name=JournalNodeInfo" _CLUSTER_ID="" for _PORT in $_PORTS; do _CLUSTER_ID+=$(curl -s http://localhost:${_PORT}/$_URL_PATH | \ grep ClusterId) || true done -echo $_CLUSTER_ID | grep -q -v null \ No newline at end of file +echo $_CLUSTER_ID | grep -q -v null diff --git a/addons/hadoop/scripts/check-name-status.sh b/addons/hadoop/scripts/check-name-status.sh index d309144ad1..198d6d80af 100644 --- a/addons/hadoop/scripts/check-name-status.sh +++ b/addons/hadoop/scripts/check-name-status.sh @@ -8,7 +8,7 @@ set -o pipefail : "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" export HADOOP_HOME HADOOP_CONF_DIR -_NN_HTTP_PORT=9870 +_NN_HTTP_PORT="${HDFS_NAMENODE_HTTP_PORT:-9870}" CLUSTER_ID_RESP=$(curl -s --connect-timeout 5 --max-time 10 "http://localhost:${_NN_HTTP_PORT}/jmx?qry=Hadoop:service=NameNode,name=NameNodeInfo" 2>/dev/null || echo "") if echo "${CLUSTER_ID_RESP}" | grep -q '"ClusterId"'; then diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml index 155d973a99..4f909306b7 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml @@ -162,6 +162,12 @@ spec: value: {{ .Values.hdfs.paths.datanodeDataDir | quote }} - name: HDFS_DATANODE_HANDLER_COUNT value: {{ .Values.hdfs.datanode.handlerCount | quote }} + - name: HDFS_DATANODE_DATA_PORT + value: {{ .Values.hdfs.ports.datanode.data | quote }} + - name: HDFS_DATANODE_HTTP_PORT + value: {{ .Values.hdfs.ports.datanode.http | quote }} + - name: HDFS_DATANODE_IPC_PORT + value: {{ .Values.hdfs.ports.datanode.ipc | quote }} - name: HDFS_NAMENODE_RPC_PORT value: {{ .Values.hdfs.ports.namenode.rpc | quote }} - name: HDFS_NAMENODE_HTTP_PORT diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml index 41247714c1..f9f661d818 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml @@ -174,6 +174,12 @@ spec: value: {{ .Values.hdfs.paths.datanodeDataDir | quote }} - name: HDFS_DATANODE_HANDLER_COUNT value: {{ .Values.hdfs.datanode.handlerCount | quote }} + - name: HDFS_DATANODE_DATA_PORT + value: {{ .Values.hdfs.ports.datanode.data | quote }} + - name: HDFS_DATANODE_HTTP_PORT + value: {{ .Values.hdfs.ports.datanode.http | quote }} + - name: HDFS_DATANODE_IPC_PORT + value: {{ .Values.hdfs.ports.datanode.ipc | quote }} - name: HDFS_NAMENODE_RPC_PORT value: {{ .Values.hdfs.ports.namenode.rpc | quote }} - name: HDFS_NAMENODE_HTTP_PORT diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index 49abd36e63..cafcd45940 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -58,22 +58,22 @@ hbase.master.port - 16000 + {{ .HBASE_MASTER_PORT }} hbase.master.info.port - 16010 + {{ .HBASE_MASTER_INFO_PORT }} hbase.regionserver.port - 16020 + {{ .HBASE_REGIONSERVER_PORT }} hbase.regionserver.info.port - 16030 + {{ .HBASE_REGIONSERVER_INFO_PORT }} @@ -297,4 +297,4 @@ hbase.splitlog.manager.timeout 600000 - \ No newline at end of file + diff --git a/addons/hbase/config/hbase-site-standalone.tpl b/addons/hbase/config/hbase-site-standalone.tpl index f152f16d4d..4a3690fa53 100644 --- a/addons/hbase/config/hbase-site-standalone.tpl +++ b/addons/hbase/config/hbase-site-standalone.tpl @@ -58,22 +58,22 @@ hbase.master.port - 16000 + {{ .HBASE_MASTER_PORT }} hbase.master.info.port - 16010 + {{ .HBASE_MASTER_INFO_PORT }} hbase.regionserver.port - 16020 + {{ .HBASE_REGIONSERVER_PORT }} hbase.regionserver.info.port - 16030 + {{ .HBASE_REGIONSERVER_INFO_PORT }} diff --git a/addons/hbase/templates/clusterdefinition.yaml b/addons/hbase/templates/clusterdefinition.yaml index 886ba5d199..3b291e89c8 100644 --- a/addons/hbase/templates/clusterdefinition.yaml +++ b/addons/hbase/templates/clusterdefinition.yaml @@ -8,7 +8,7 @@ metadata: {{- include "hbase.apiVersion" . | nindent 4 }} spec: topologies: - - name: hbase-cluster + - name: cluster default: true components: - name: hmaster @@ -25,7 +25,7 @@ spec: update: - hregionserver - hmaster - - name: hbase-standalone + - name: standalone components: - name: hbase-standalone compDef: {{ include "hbase.hbaseStandaloneCmpdRegexPattern" . }} diff --git a/addons/hbase/templates/cmpd-hbase-standalone.yaml b/addons/hbase/templates/cmpd-hbase-standalone.yaml index 2660dfa179..e405b3d8d7 100644 --- a/addons/hbase/templates/cmpd-hbase-standalone.yaml +++ b/addons/hbase/templates/cmpd-hbase-standalone.yaml @@ -154,6 +154,14 @@ spec: value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_MASTER_PORT + value: {{ .Values.ports.hmaster.rpc | quote }} + - name: HBASE_MASTER_INFO_PORT + value: {{ .Values.ports.hmaster.info | quote }} + - name: HBASE_REGIONSERVER_PORT + value: {{ .Values.ports.hregionserver.rpc | quote }} + - name: HBASE_REGIONSERVER_INFO_PORT + value: {{ .Values.ports.hregionserver.info | quote }} - name: HBASE_REGIONSERVER_JMX_PORT value: {{ .Values.ports.hregionserver.jmx | quote }} - name: HBASE_HEAP_SIZE diff --git a/addons/hbase/templates/cmpd-hmaster.yaml b/addons/hbase/templates/cmpd-hmaster.yaml index f8a6be604f..93a5c52415 100644 --- a/addons/hbase/templates/cmpd-hmaster.yaml +++ b/addons/hbase/templates/cmpd-hmaster.yaml @@ -191,6 +191,14 @@ spec: value: {{ .Values.jvm.hregionserverHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_MASTER_PORT + value: {{ .Values.ports.hmaster.rpc | quote }} + - name: HBASE_MASTER_INFO_PORT + value: {{ .Values.ports.hmaster.info | quote }} + - name: HBASE_REGIONSERVER_PORT + value: {{ .Values.ports.hregionserver.rpc | quote }} + - name: HBASE_REGIONSERVER_INFO_PORT + value: {{ .Values.ports.hregionserver.info | quote }} - name: HBASE_REGIONSERVER_JMX_PORT value: {{ .Values.ports.hregionserver.jmx | quote }} - name: HBASE_HEAP_SIZE diff --git a/addons/hbase/templates/cmpd-hregionserver.yaml b/addons/hbase/templates/cmpd-hregionserver.yaml index 0cf7625ea2..a14446ffeb 100644 --- a/addons/hbase/templates/cmpd-hregionserver.yaml +++ b/addons/hbase/templates/cmpd-hregionserver.yaml @@ -154,6 +154,14 @@ spec: value: {{ .Values.jvm.hregionserverHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT value: {{ .Values.ports.hmaster.jmx | quote }} + - name: HBASE_MASTER_PORT + value: {{ .Values.ports.hmaster.rpc | quote }} + - name: HBASE_MASTER_INFO_PORT + value: {{ .Values.ports.hmaster.info | quote }} + - name: HBASE_REGIONSERVER_PORT + value: {{ .Values.ports.hregionserver.rpc | quote }} + - name: HBASE_REGIONSERVER_INFO_PORT + value: {{ .Values.ports.hregionserver.info | quote }} - name: HBASE_REGIONSERVER_JMX_PORT value: {{ .Values.ports.hregionserver.jmx | quote }} - name: HBASE_HEAP_SIZE From 785d107d8161758d4c23c0627f5429faaee51785 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 16:57:16 +0800 Subject: [PATCH 03/18] fix(hbase): avoid rendering POD_FQDN in config template by injecting regionserver hostname at runtime --- addons/hbase/config/hbase-env.sh.tpl | 2 +- addons/hbase/config/hbase-site-cluster.tpl | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/addons/hbase/config/hbase-env.sh.tpl b/addons/hbase/config/hbase-env.sh.tpl index bb824ea300..de80b4a649 100644 --- a/addons/hbase/config/hbase-env.sh.tpl +++ b/addons/hbase/config/hbase-env.sh.tpl @@ -9,7 +9,7 @@ export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps" export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_MASTER_JMX_PORT }} -Xms{{ .HBASE_MASTER_HEAP_SIZE }} -Xmx{{ .HBASE_MASTER_HEAP_SIZE }}" -export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Xms{{ .HBASE_REGIONSERVER_HEAP_SIZE }} -Xmx{{ .HBASE_REGIONSERVER_HEAP_SIZE }}" +export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Dhbase.regionserver.hostname=${POD_FQDN} -Xms{{ .HBASE_REGIONSERVER_HEAP_SIZE }} -Xmx{{ .HBASE_REGIONSERVER_HEAP_SIZE }}" export HBASE_HEAPSIZE={{ .HBASE_HEAP_SIZE }} export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP=true diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index cafcd45940..ad3568d365 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -76,11 +76,6 @@ {{ .HBASE_REGIONSERVER_INFO_PORT }} - - hbase.regionserver.hostname - {{ .POD_FQDN }} - - hbase.regionserver.hostname.disable.master.reversedns true @@ -297,4 +292,4 @@ hbase.splitlog.manager.timeout 600000 - + \ No newline at end of file From 31b6788e705dd284089c8960a17697101b7a5175 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 17:33:01 +0800 Subject: [PATCH 04/18] feat(hbase): change pid dir into /tmp --- addons/hbase/values.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/hbase/values.yaml b/addons/hbase/values.yaml index ce65c083ae..d4588c4bf1 100644 --- a/addons/hbase/values.yaml +++ b/addons/hbase/values.yaml @@ -23,7 +23,7 @@ runtime: hbaseHome: /opt/hbase-2.5.6 hbaseConfDir: /hbase/conf hbaseLogDir: /var/log/hbase - hbasePidDir: /var/run/hbase + hbasePidDir: /tmp/hbase hbaseTmpDir: /hbase/tmp hbaseDataDir: /data/hbase scriptsDir: /hbase/scripts From f125b412431928b318c2e653e0cc0b3672d190dd Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 19:48:24 +0800 Subject: [PATCH 05/18] feat(hadoop): make namenode init container images explicit and configurable --- addons/hadoop/templates/_helpers.tpl | 12 ++++++++++++ .../templates/cmpd-hdfs-namenode-standalone.yaml | 3 ++- addons/hadoop/templates/cmpd-hdfs-namenode.yaml | 9 ++++++--- addons/hadoop/values.yaml | 16 ++++++++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl index 112e3753de..53d111bcbd 100644 --- a/addons/hadoop/templates/_helpers.tpl +++ b/addons/hadoop/templates/_helpers.tpl @@ -97,6 +97,18 @@ Image references {{ .Values.nameNode.image.registry }}/{{ .Values.nameNode.image.repository }}:{{ .Values.nameNode.image.tag }} {{- end }} +{{- define "hadoop.initNameNodeFormatImage" -}} +{{ default .Values.nameNode.image.registry .Values.nameNode.initImages.initNameNodeFormat.registry }}/{{ default .Values.nameNode.image.repository .Values.nameNode.initImages.initNameNodeFormat.repository }}:{{ default .Values.nameNode.image.tag .Values.nameNode.initImages.initNameNodeFormat.tag }} +{{- end }} + +{{- define "hadoop.initZkfcFormatImage" -}} +{{ default .Values.nameNode.image.registry .Values.nameNode.initImages.initZkfcFormat.registry }}/{{ default .Values.nameNode.image.repository .Values.nameNode.initImages.initZkfcFormat.repository }}:{{ default .Values.nameNode.image.tag .Values.nameNode.initImages.initZkfcFormat.tag }} +{{- end }} + +{{- define "hadoop.initNnBootstrapStandbyImage" -}} +{{ default .Values.nameNode.image.registry .Values.nameNode.initImages.initNnBootstrapStandby.registry }}/{{ default .Values.nameNode.image.repository .Values.nameNode.initImages.initNnBootstrapStandby.repository }}:{{ default .Values.nameNode.image.tag .Values.nameNode.initImages.initNnBootstrapStandby.tag }} +{{- end }} + {{- define "hadoop.dataNodeImage" -}} {{ .Values.dataNode.image.registry }}/{{ .Values.dataNode.image.repository }}:{{ .Values.dataNode.image.tag }} {{- end }} diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml index 34375a465b..de959cee49 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -40,7 +40,8 @@ spec: - name: metadata-dir mountPath: /hadoop - name: init-namenode-format - imagePullPolicy: IfNotPresent + image: {{ include "hadoop.initNameNodeFormatImage" . | quote }} + imagePullPolicy: {{ default .Values.nameNode.image.pullPolicy .Values.nameNode.initImages.initNameNodeFormat.pullPolicy }} securityContext: runAsUser: {{ .Values.securityContext.runAsUser }} runAsGroup: {{ .Values.securityContext.runAsGroup }} diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index 1e172bfc0c..c4d217e5f5 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -46,7 +46,8 @@ spec: - name: metadata-dir mountPath: /hadoop - name: init-namenode-format - imagePullPolicy: IfNotPresent + image: {{ include "hadoop.initNameNodeFormatImage" . | quote }} + imagePullPolicy: {{ default .Values.nameNode.image.pullPolicy .Values.nameNode.initImages.initNameNodeFormat.pullPolicy }} securityContext: runAsUser: {{ .Values.securityContext.runAsUser }} runAsGroup: {{ .Values.securityContext.runAsGroup }} @@ -79,7 +80,8 @@ spec: - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} - name: init-zkfc-format - imagePullPolicy: IfNotPresent + image: {{ include "hadoop.initZkfcFormatImage" . | quote }} + imagePullPolicy: {{ default .Values.nameNode.image.pullPolicy .Values.nameNode.initImages.initZkfcFormat.pullPolicy }} securityContext: runAsUser: {{ .Values.securityContext.runAsUser }} runAsGroup: {{ .Values.securityContext.runAsGroup }} @@ -106,7 +108,8 @@ spec: - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} - name: init-nn-bootstrap-standby - imagePullPolicy: IfNotPresent + image: {{ include "hadoop.initNnBootstrapStandbyImage" . | quote }} + imagePullPolicy: {{ default .Values.nameNode.image.pullPolicy .Values.nameNode.initImages.initNnBootstrapStandby.pullPolicy }} securityContext: runAsUser: {{ .Values.securityContext.runAsUser }} runAsGroup: {{ .Values.securityContext.runAsGroup }} diff --git a/addons/hadoop/values.yaml b/addons/hadoop/values.yaml index e4bb050801..c654283e09 100644 --- a/addons/hadoop/values.yaml +++ b/addons/hadoop/values.yaml @@ -27,6 +27,22 @@ nameNode: repository: apecloud/hdfs-namenode tag: "v3.3.4-1.0.0" pullPolicy: IfNotPresent + initImages: + initNameNodeFormat: + registry: "" + repository: "" + tag: "" + pullPolicy: "" + initZkfcFormat: + registry: "" + repository: "" + tag: "" + pullPolicy: "" + initNnBootstrapStandby: + registry: "" + repository: "" + tag: "" + pullPolicy: "" dataNode: image: From 5ad1311ad780626c7664667bb2160f5e25e90403 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 20:22:32 +0800 Subject: [PATCH 06/18] feat(hadoop): make namenode init container images explicit and configurable --- addons/hadoop/templates/cmpv-hdfs-namenode.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml index 2f14e75206..0eee2db958 100644 --- a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml @@ -18,4 +18,7 @@ spec: serviceVersion: v3.3.4 images: hadoop-common: {{ include "hadoop.commonImage" . | quote }} + init-namenode-format: {{ include "hadoop.initNameNodeFormatImage" . | quote }} + init-zkfc-format: {{ include "hadoop.initZkfcFormatImage" . | quote }} + init-nn-bootstrap-standby: {{ include "hadoop.initNnBootstrapStandbyImage" . | quote }} hdfs-namenode: {{ include "hadoop.nameNodeImage" . | quote }} From 4a6ed57dfa6619ba1b2e2ba38f1a8f6998a876bf Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 20:37:55 +0800 Subject: [PATCH 07/18] feat(hadoop): make namenode init container images explicit and configurable --- addons/hadoop/templates/cmpv-hdfs-namenode.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml index 0eee2db958..a18aeb6b1f 100644 --- a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml @@ -22,3 +22,4 @@ spec: init-zkfc-format: {{ include "hadoop.initZkfcFormatImage" . | quote }} init-nn-bootstrap-standby: {{ include "hadoop.initNnBootstrapStandbyImage" . | quote }} hdfs-namenode: {{ include "hadoop.nameNodeImage" . | quote }} + hdfs-zkfc: {{ include "hadoop.nameNodeImage" . | quote }} From 0ab9b0b647ee3f709d7a7553a657458f60813903 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 21:03:56 +0800 Subject: [PATCH 08/18] feat(hadoop): mount hadoop logs for namenode init containers --- addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml | 2 ++ addons/hadoop/templates/cmpd-hdfs-namenode.yaml | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml index de959cee49..f9ec9d1135 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -71,6 +71,8 @@ spec: - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} containers: diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index c4d217e5f5..66c88822ad 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -77,6 +77,8 @@ spec: - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} - name: init-zkfc-format @@ -105,6 +107,8 @@ spec: - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} - name: init-nn-bootstrap-standby @@ -135,6 +139,8 @@ spec: - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml + - name: hadoop-logs + mountPath: {{ .Values.runtime.hadoopLogDir }} - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} containers: From f40bf584986b2aa05dcf2e5c00fdc7ed787f29ca Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 21:31:13 +0800 Subject: [PATCH 09/18] feat(hadoop): move namenode bootstrapStandby to runtime startup --- .../scripts/init-nn-bootstrap-standby.sh | 48 -------------- addons/hadoop/scripts/start-namenode.sh | 65 +++++++++++++++++++ addons/hadoop/templates/_helpers.tpl | 4 -- .../hadoop/templates/cmpd-hdfs-namenode.yaml | 32 --------- .../hadoop/templates/cmpv-hdfs-namenode.yaml | 1 - .../templates/hdfs-scripts-template.yaml | 2 - addons/hadoop/values.yaml | 5 -- 7 files changed, 65 insertions(+), 92 deletions(-) delete mode 100644 addons/hadoop/scripts/init-nn-bootstrap-standby.sh diff --git a/addons/hadoop/scripts/init-nn-bootstrap-standby.sh b/addons/hadoop/scripts/init-nn-bootstrap-standby.sh deleted file mode 100644 index cc350a69f4..0000000000 --- a/addons/hadoop/scripts/init-nn-bootstrap-standby.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/usr/bin/env bash -set -o errexit -set -o errtrace -set -o nounset -set -o pipefail - -: "${HADOOP_HOME:=/opt/hadoop}" -: "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" -export HADOOP_HOME HADOOP_CONF_DIR - -NAME_DIRS=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.namenode.name.dir 2>/dev/null || echo "") -if [[ -z "$NAME_DIRS" ]]; then - echo "No dfs.namenode.name.dir configured, skipping bootstrapStandby" - exit 0 -fi - -NN_DIR="${NAME_DIRS%%,*}" -NN_DIR="${NN_DIR#file://}" -NN_CURRENT_DIR="${NN_DIR}/current" - -has_valid_fsimage() { - [[ -d "$NN_CURRENT_DIR" ]] || return 1 - find "$NN_CURRENT_DIR" -maxdepth 1 -type f -name 'fsimage_*' ! -name '*.md5' 2>/dev/null | grep -q . -} - -if has_valid_fsimage; then - echo "Valid fsimage found at ${NN_CURRENT_DIR}, skipping bootstrapStandby" - exit 0 -fi - -if [[ -d "$NN_CURRENT_DIR" ]]; then - BACKUP_DIR="${NN_CURRENT_DIR}.incomplete.$(date +%s)" - echo "Incomplete metadata found, moving ${NN_CURRENT_DIR} to ${BACKUP_DIR}" - mv "$NN_CURRENT_DIR" "$BACKUP_DIR" || true -fi - -echo "No valid fsimage, running bootstrapStandby with retries..." -for attempt in $(seq 1 30); do - if "${HADOOP_HOME}/bin/hdfs" namenode -bootstrapStandby -nonInteractive; then - echo "bootstrapStandby succeeded on attempt ${attempt}" - exit 0 - fi - echo "bootstrapStandby failed on attempt ${attempt}, retrying in 10s..." - sleep 10 -done - -echo "bootstrapStandby failed after 30 attempts" -exit 1 diff --git a/addons/hadoop/scripts/start-namenode.sh b/addons/hadoop/scripts/start-namenode.sh index e20fb39142..93161fb746 100644 --- a/addons/hadoop/scripts/start-namenode.sh +++ b/addons/hadoop/scripts/start-namenode.sh @@ -16,6 +16,69 @@ mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" "${LIFECYCLE_DIR}" USER=$(whoami) LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-namenode-$(hostname).log" +# 仅在 standby ordinal 上执行 bootstrapStandby,避免与 OrderedReady 启动顺序冲突。 +bootstrap_standby_if_needed() { + local pod_name host_name ordinal nameservices nn_ids peer_id peer_rpc peer_host + local name_dirs nn_dir nn_current_dir + + pod_name="${POD_NAME:-$(hostname)}" + host_name="$(hostname)" + ordinal="${pod_name##*-}" + [[ "$ordinal" == "$pod_name" ]] && ordinal="${host_name##*-}" + + # ponytail: 当前 HA 只支持双 NameNode,standby 固定为 ordinal 1;如后续拓扑扩展,再显式映射 nnId。 + [[ "$ordinal" == "1" ]] || return 0 + + nameservices=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.nameservices 2>/dev/null || echo "") + [[ -n "$nameservices" ]] || return 0 + + nn_ids=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.ha.namenodes.${nameservices}" 2>/dev/null || echo "") + [[ "$nn_ids" == *","* ]] || return 0 + + name_dirs=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.namenode.name.dir 2>/dev/null || echo "") + [[ -n "$name_dirs" ]] || return 0 + nn_dir="${name_dirs%%,*}" + nn_dir="${nn_dir#file://}" + nn_current_dir="${nn_dir}/current" + + if [[ -d "$nn_current_dir" ]] && find "$nn_current_dir" -maxdepth 1 -type f -name 'fsimage_*' ! -name '*.md5' 2>/dev/null | grep -q .; then + echo "[$(date)] Valid fsimage found at ${nn_current_dir}, skipping bootstrapStandby" + return 0 + fi + + peer_id="nn0" + peer_rpc=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.namenode.rpc-address.${nameservices}.${peer_id}" 2>/dev/null || echo "") + peer_host="${peer_rpc%:*}" + if [[ -z "$peer_host" || "$peer_host" == "$peer_rpc" ]]; then + echo "[$(date)] Cannot determine active peer host for ${peer_id}, skipping bootstrapStandby" + return 1 + fi + + for attempt in $(seq 1 30); do + if getent hosts "$peer_host" >/dev/null 2>&1; then + break + fi + if [[ "$attempt" -eq 30 ]]; then + echo "[$(date)] Peer ${peer_host} is still unresolved after 60s" >&2 + return 1 + fi + sleep 2 + done + + echo "[$(date)] No valid fsimage, running bootstrapStandby with retries..." + for attempt in $(seq 1 30); do + if "${HADOOP_HOME}/bin/hdfs" namenode -bootstrapStandby -nonInteractive; then + echo "[$(date)] bootstrapStandby succeeded on attempt ${attempt}" + return 0 + fi + echo "[$(date)] bootstrapStandby failed on attempt ${attempt}, retrying in 10s..." + sleep 10 + done + + echo "[$(date)] bootstrapStandby failed after 30 attempts" >&2 + return 1 +} + shutdown() { echo "[$(date)] Received SIGTERM, stopping NameNode gracefully..." local is_active=0 @@ -75,6 +138,8 @@ fi trap shutdown SIGTERM SIGINT +bootstrap_standby_if_needed + echo "[$(date)] Starting NameNode..." "${HADOOP_HOME}/bin/hdfs" namenode 2>&1 | tee -a "$LOG_FILE" & NN_PID=$! diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl index 53d111bcbd..5a3f92622c 100644 --- a/addons/hadoop/templates/_helpers.tpl +++ b/addons/hadoop/templates/_helpers.tpl @@ -105,10 +105,6 @@ Image references {{ default .Values.nameNode.image.registry .Values.nameNode.initImages.initZkfcFormat.registry }}/{{ default .Values.nameNode.image.repository .Values.nameNode.initImages.initZkfcFormat.repository }}:{{ default .Values.nameNode.image.tag .Values.nameNode.initImages.initZkfcFormat.tag }} {{- end }} -{{- define "hadoop.initNnBootstrapStandbyImage" -}} -{{ default .Values.nameNode.image.registry .Values.nameNode.initImages.initNnBootstrapStandby.registry }}/{{ default .Values.nameNode.image.repository .Values.nameNode.initImages.initNnBootstrapStandby.repository }}:{{ default .Values.nameNode.image.tag .Values.nameNode.initImages.initNnBootstrapStandby.tag }} -{{- end }} - {{- define "hadoop.dataNodeImage" -}} {{ .Values.dataNode.image.registry }}/{{ .Values.dataNode.image.repository }}:{{ .Values.dataNode.image.tag }} {{- end }} diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index 66c88822ad..ec4c7de82d 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -111,38 +111,6 @@ spec: mountPath: {{ .Values.runtime.hadoopLogDir }} - name: scripts mountPath: {{ .Values.runtime.scriptsDir }} - - name: init-nn-bootstrap-standby - image: {{ include "hadoop.initNnBootstrapStandbyImage" . | quote }} - imagePullPolicy: {{ default .Values.nameNode.image.pullPolicy .Values.nameNode.initImages.initNnBootstrapStandby.pullPolicy }} - securityContext: - runAsUser: {{ .Values.securityContext.runAsUser }} - runAsGroup: {{ .Values.securityContext.runAsGroup }} - env: - - name: HADOOP_HOME - value: {{ .Values.runtime.hadoopHome }} - - name: HADOOP_CONF_DIR - value: {{ .Values.runtime.configDir }} - command: - - /bin/bash - - {{ .Values.runtime.scriptsDir }}/init-nn-bootstrap-standby.sh - volumeMounts: - - name: hadoop-common - mountPath: {{ .Values.runtime.hadoopHome }} - - name: metadata-dir - mountPath: /hadoop - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/core-site.xml - subPath: core-site.xml - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh - subPath: hadoop-env.sh - - name: namenode-config - mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml - subPath: hdfs-site.xml - - name: hadoop-logs - mountPath: {{ .Values.runtime.hadoopLogDir }} - - name: scripts - mountPath: {{ .Values.runtime.scriptsDir }} containers: - name: hdfs-namenode image: {{ include "hadoop.nameNodeImage" . | quote }} diff --git a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml index a18aeb6b1f..3b6aebbd9d 100644 --- a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml @@ -20,6 +20,5 @@ spec: hadoop-common: {{ include "hadoop.commonImage" . | quote }} init-namenode-format: {{ include "hadoop.initNameNodeFormatImage" . | quote }} init-zkfc-format: {{ include "hadoop.initZkfcFormatImage" . | quote }} - init-nn-bootstrap-standby: {{ include "hadoop.initNnBootstrapStandbyImage" . | quote }} hdfs-namenode: {{ include "hadoop.nameNodeImage" . | quote }} hdfs-zkfc: {{ include "hadoop.nameNodeImage" . | quote }} diff --git a/addons/hadoop/templates/hdfs-scripts-template.yaml b/addons/hadoop/templates/hdfs-scripts-template.yaml index 791908547a..8a54223421 100644 --- a/addons/hadoop/templates/hdfs-scripts-template.yaml +++ b/addons/hadoop/templates/hdfs-scripts-template.yaml @@ -23,8 +23,6 @@ data: {{- .Files.Get "scripts/init-namenode-format.sh" | nindent 4 }} init-zkfc-format.sh: |- {{- .Files.Get "scripts/init-zkfc-format.sh" | nindent 4 }} - init-nn-bootstrap-standby.sh: |- - {{- .Files.Get "scripts/init-nn-bootstrap-standby.sh" | nindent 4 }} init-refresh-nodes.sh: |- {{- .Files.Get "scripts/init-refresh-nodes.sh" | nindent 4 }} datanode-decommission.sh: |- diff --git a/addons/hadoop/values.yaml b/addons/hadoop/values.yaml index c654283e09..f55997a510 100644 --- a/addons/hadoop/values.yaml +++ b/addons/hadoop/values.yaml @@ -38,11 +38,6 @@ nameNode: repository: "" tag: "" pullPolicy: "" - initNnBootstrapStandby: - registry: "" - repository: "" - tag: "" - pullPolicy: "" dataNode: image: From ad83316ea1c4dcdc03778f87a4072ab7de20e457 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 22:23:17 +0800 Subject: [PATCH 10/18] - refactor(hadoop)!: remove hadoop-core component and rename shared config to hdfs-common - refactor(hadoop): centralize namenode ha constraints for dual-nn topology - fix(hadoop): move datanode hostname injection to runtime --- addons-cluster/hadoop/templates/cluster.yaml | 93 +++++------ addons-cluster/hadoop/values.yaml | 8 - addons/hadoop/README.md | 5 +- .../config/hadoop-core-config-constraint.cue | 153 ------------------ addons/hadoop/config/hadoop-env.sh.tpl | 2 +- .../config/hdfs-common-config-constraint.cue | 72 +++++++++ .../config/hdfs-datanode-standalone.tpl | 7 +- addons/hadoop/config/hdfs-datanode.tpl | 47 ++---- addons/hadoop/config/hdfs-namenode.tpl | 31 ++-- addons/hadoop/scripts/start-namenode.sh | 19 ++- addons/hadoop/templates/_helpers.tpl | 19 +-- .../hadoop/templates/clusterdefinition.yaml | 8 - .../cmpd-hadoop-core-standalone.yaml | 82 ---------- addons/hadoop/templates/cmpd-hadoop-core.yaml | 96 ----------- .../cmpd-hdfs-datanode-standalone.yaml | 15 +- .../hadoop/templates/cmpd-hdfs-datanode.yaml | 15 +- .../templates/cmpd-hdfs-journalnode.yaml | 15 +- .../cmpd-hdfs-namenode-standalone.yaml | 21 ++- .../hadoop/templates/cmpd-hdfs-namenode.yaml | 31 ++-- addons/hadoop/templates/cmpv-hadoop-core.yaml | 20 --- ....yaml => hdfs-common-config-template.yaml} | 2 +- ...fs-common-standalone-config-template.yaml} | 2 +- ...p-core.yaml => paramsdef-hdfs-common.yaml} | 6 +- .../templates/pcr-hadoop-core-standalone.yaml | 16 -- addons/hadoop/templates/pcr-hadoop-core.yaml | 16 -- .../pcr-hdfs-datanode-standalone.yaml | 4 + .../hadoop/templates/pcr-hdfs-datanode.yaml | 6 +- .../templates/pcr-hdfs-journalnode.yaml | 6 +- .../pcr-hdfs-namenode-standalone.yaml | 4 + .../hadoop/templates/pcr-hdfs-namenode.yaml | 6 +- addons/hadoop/values.yaml | 8 - addons/hbase/README.md | 10 +- ...oop-core-site.tpl => hdfs-common-site.tpl} | 0 .../hbase-cluster-config-template.yaml | 2 +- 34 files changed, 263 insertions(+), 584 deletions(-) delete mode 100644 addons/hadoop/config/hadoop-core-config-constraint.cue create mode 100644 addons/hadoop/config/hdfs-common-config-constraint.cue delete mode 100644 addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml delete mode 100644 addons/hadoop/templates/cmpd-hadoop-core.yaml delete mode 100644 addons/hadoop/templates/cmpv-hadoop-core.yaml rename addons/hadoop/templates/{hadoop-core-config-template.yaml => hdfs-common-config-template.yaml} (94%) rename addons/hadoop/templates/{hadoop-core-standalone-config-template.yaml => hdfs-common-standalone-config-template.yaml} (92%) rename addons/hadoop/templates/{paramsdef-hadoop-core.yaml => paramsdef-hdfs-common.yaml} (57%) delete mode 100644 addons/hadoop/templates/pcr-hadoop-core-standalone.yaml delete mode 100644 addons/hadoop/templates/pcr-hadoop-core.yaml rename addons/hbase/config/{hadoop-core-site.tpl => hdfs-common-site.tpl} (100%) diff --git a/addons-cluster/hadoop/templates/cluster.yaml b/addons-cluster/hadoop/templates/cluster.yaml index 6a4d44947b..987c194394 100644 --- a/addons-cluster/hadoop/templates/cluster.yaml +++ b/addons-cluster/hadoop/templates/cluster.yaml @@ -3,24 +3,18 @@ {{- if not (or $isCluster $isStandalone) }} {{- fail "topology must be either 'cluster' or 'standalone'" }} {{- end }} +{{- if and $isCluster (ne (.Values.replicas.namenode | int) 2) }} +{{- fail "cluster topology requires replicas.namenode = 2; this addon currently supports only active/standby NameNode HA" }} +{{- end }} {{- include "hadoop-cluster.clusterCommon" . }} clusterDef: hadoop topology: {{ .Values.topology }} componentSpecs: - - name: hadoop-core - componentDef: {{ ternary "hadoop-core" "hadoop-core-standalone" $isCluster }} {{- if $isCluster }} - serviceRefs: - - name: hadoopZookeeper - namespace: {{ .Values.serviceRefs.hadoopZookeeper.namespace }} - clusterServiceSelector: - cluster: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.cluster }} - service: - component: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.component }} - service: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.service }} - port: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.port }} + - name: journalnode + componentDef: hdfs-journalnode configs: - - name: hadoop-core-config + - name: hdfs-common-config variables: HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} @@ -34,35 +28,6 @@ HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} -{{- else }} - configs: - - name: hadoop-core-config - variables: - HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} - HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} - HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} - HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} - HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} - HDFS_ZKFC_HEAP: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} - HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} - HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} - HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} - HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} - HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} - HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} -{{- end }} - replicas: {{ .Values.replicas.core }} - resources: - requests: - cpu: {{ .Values.resources.core.requests.cpu | quote }} - memory: {{ .Values.resources.core.requests.memory }} - limits: - cpu: {{ .Values.resources.core.limits.cpu | quote }} - memory: {{ .Values.resources.core.limits.memory }} -{{- if $isCluster }} - - name: journalnode - componentDef: hdfs-journalnode - configs: - name: journalnode-config variables: HDFS_JOURNALNODE_EDITS_DIR: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} @@ -84,10 +49,6 @@ labelSelector: matchLabels: apps.kubeblocks.io/component-name: journalnode - volumes: - - name: hadoop-core-config - configMap: - name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config volumeClaimTemplates: - name: edits-dir spec: @@ -114,6 +75,24 @@ port: {{ .Values.serviceRefs.hadoopZookeeper.clusterServiceSelector.service.port }} {{- end }} configs: + - name: hdfs-common-config + variables: + HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + HDFS_ZKFC_HEAP: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} + HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} +{{- if $isCluster }} + HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} +{{- else }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} +{{- end }} - name: namenode-config variables: HDFS_NAMENODE_NAME_DIR: {{ .Values.hdfs.paths.namenodeMetadataDir | quote }} @@ -154,10 +133,6 @@ matchLabels: apps.kubeblocks.io/component-name: namenode {{- end }} - volumes: - - name: hadoop-core-config - configMap: - name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config volumeClaimTemplates: - name: metadata-dir spec: @@ -172,6 +147,22 @@ - name: datanode componentDef: {{ ternary "hdfs-datanode" "hdfs-datanode-standalone" $isCluster }} configs: + - name: hdfs-common-config + variables: + HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} + HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} + HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} + HDFS_ZKFC_HEAP: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} + HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} + HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} + HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} + HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} + HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} + HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} +{{- if not $isCluster }} + HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} +{{- end }} - name: datanode-config variables: HDFS_DATANODE_DATA_DIR: {{ .Values.hdfs.paths.datanodeDataDir | quote }} @@ -206,10 +197,6 @@ matchLabels: apps.kubeblocks.io/component-name: datanode {{- end }} - volumes: - - name: hadoop-core-config - configMap: - name: {{ include "kblib.clusterName" . }}-hadoop-core-hadoop-core-config volumeClaimTemplates: - name: hdfs-data-0 spec: diff --git a/addons-cluster/hadoop/values.yaml b/addons-cluster/hadoop/values.yaml index 350980d14b..f3cfae92aa 100644 --- a/addons-cluster/hadoop/values.yaml +++ b/addons-cluster/hadoop/values.yaml @@ -1,19 +1,11 @@ topology: cluster replicas: - core: 1 journalnode: 3 namenode: 2 datanode: 3 resources: - core: - requests: - cpu: "100m" - memory: 256Mi - limits: - cpu: "500m" - memory: 1Gi journalnode: requests: cpu: "500m" diff --git a/addons/hadoop/README.md b/addons/hadoop/README.md index 35df96bd52..21ecea81a6 100644 --- a/addons/hadoop/README.md +++ b/addons/hadoop/README.md @@ -4,7 +4,7 @@ This addon provides Hadoop HDFS support on KubeBlocks, including: -- **HA Cluster Topology**: 4-component architecture (hadoop-core, journalnode, namenode, datanode) +- **HA Cluster Topology**: 3-component architecture (journalnode, namenode, datanode) - **ZooKeeper Integration**: Automatic failover via ZK service reference - **Host Network**: DataNode supports hostNetwork for optimal I/O performance - **Configuration Management**: Dynamic parameter tuning via Parameters API @@ -13,7 +13,6 @@ This addon provides Hadoop HDFS support on KubeBlocks, including: | Component | Role | Default Replicas | |-----------|------|-----------------| -| hadoop-core | Orchestration (config generation only) | 1 | | hdfs-journalnode | HA Journal | 3 | | hdfs-namenode | NameNode (nn0/nn1) | 2 | | hdfs-datanode | DataNode (hostNetwork) | 1 | @@ -31,4 +30,4 @@ helm install mycluster kubeblocks-addons-cluster/hadoop ## Requirements - KubeBlocks >= 1.1.0 -- ZooKeeper cluster for HA coordination \ No newline at end of file +- ZooKeeper cluster for HA coordination diff --git a/addons/hadoop/config/hadoop-core-config-constraint.cue b/addons/hadoop/config/hadoop-core-config-constraint.cue deleted file mode 100644 index de393d76c1..0000000000 --- a/addons/hadoop/config/hadoop-core-config-constraint.cue +++ /dev/null @@ -1,153 +0,0 @@ -// Copyright (C) 2022-2023 ApeCloud Co., Ltd -// -// This file is part of KubeBlocks project -// -// This program is free software: you can redistribute it and/or modify -// it under the terms of the GNU Affero General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Affero General Public License for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -#HadoopCoreParameter: { - // 说明: Hadoop tmp 数据目录。 - "hadoop.tmp.dir": string | *"/tmp/hadoop" - - // 说明:默认的文件系统名。 - "fs.defaultFS": string | *"hdfs://{{- .CLUSTER_NAME }}" - - // A comma separated list of class names. Each class in the list must extend org.apache.hadoop.http.FilterInitializer. The corresponding Filter will be initialized. Then, the Filter will be applied to all user facing jsp and servlet web pages. The ordering of the list defines the ordering of the filters - "hadoop.http.filter.initializers": string | "org.apache.hadoop.http.lib.StaticUserWebFilter" - - // NN/JN/DN Server connection timeout in milliseconds. - "hadoop.http.idle_timeout.ms": int | 60000 - - // The name of the Network Interface from which the service should determine its host name for Kerberos login. e.g. eth2. In a multi-homed environment, the setting can be used to affect the _HOST substitution in the service Kerberos principal. If this configuration value is not set, the service will use its default hostname as returned by InetAddress.getLocalHost().getCanonicalHostName(). Most clusters will not require this setting. - "hadoop.security.dns.interface"?: string - - // The host name or IP address of the name server (DNS) which a service Node should use to determine its own host name for Kerberos Login. Requires hadoop.security.dns.interface. Most clusters will not require this setting. - "hadoop.security.dns.nameserver"?: string - - // The resolver implementation used to resolve FQDN for Kerberos - "hadoop.security.resolver.impl": string | *"org.apache.hadoop.net.DNSDomainNameResolver" - - // Time name lookups (via SecurityUtil) and log them if they exceed the configured threshold. - "hadoop.security.dns.log-slow-lookups.enabled": bool & (true | false) | *false - - // If slow lookup logging is enabled, this threshold is used to decide if a lookup is considered slow enough to be logged. - "hadoop.security.dns.log-slow-lookups.threshold.ms": int | *1000 - - // This is the config controlling the validity of the entries in the cache containing the user->group mapping. When this duration has expired, then the implementation of the group mapping provider is invoked to get the groups of the user and then cached back. - "hadoop.security.groups.cache.secs": int | *300 - - // Expiration time for entries in the the negative user-to-group mapping caching, in seconds. This is useful when invalid users are retrying frequently. It is suggested to set a small value for this expiration, since a transient error in group lookup could temporarily lock out a legitimate user. Set this to zero or negative value to disable negative user-to-group caching. - "hadoop.security.groups.negative-cache.secs": int | *30 - - // If looking up a single user to group takes longer than this amount of milliseconds, we will log a warning message. - "hadoop.security.groups.cache.warn.after.ms": int | *5000 - - // Whether to reload expired user->group mappings using a background thread pool. If set to true, a pool of hadoop.security.groups.cache.background.reload.threads is created to update the cache in the background. - "hadoop.security.groups.cache.background.reload": bool & (true | false) | *false - - // 3 Only relevant if hadoop.security.groups.cache.background.reload is true. Controls the number of concurrent background user->group cache entry refreshes. Pending refresh requests beyond this value are queued and processed when a thread is free. - "hadoop.security.groups.cache.background.reload.threads": int | *3 - - // 说明:与内置的sshfence相关的SSH连接超时时间。单位:毫秒。 默认值:10000 取值范围:1~3600000 - "dfs.ha.fencing.ssh.connect-timeout": int & >=1 & <=3600000 | *10000 - - // 说明:创建文件及目录时使用的umask。可以是八进制数或符号型的。比如:"022"(这是八进制数,对应的符号型数值是"u=rwx,g=r-x,o=r-x")或"u=rwx,g=rwx,o="(这是符号型数值,对应的八进制数是007)。 默认值:022 - "fs.permissions.umask-mode": string | *"022" - - // 说明:访问S3A文件系统使用的秘钥ID,若不设置默认为空。 - "fs.s3a.access.key"?: string - - // 说明:是否启动SSL连接和S3服务。 默认值:false 取值范围:true, false - "fs.s3a.connection.ssl.enabled": bool | *false - - // 说明:访问S3A文件系统使用的秘钥,若不设置默认为空。 - "fs.s3a.secret.key"?: string - - // 说明:访问S3时使用的签名算法。默认使用旧版本S3SignerType签名算法。如果不指定此参数,则使用默认的签名算法但可能存在兼容性问题。 默认值:S3SignerType 取值范围:S3SignerType或不指定。 - "fs.s3a.signing-algorithm": string & ("S3SignerType") | *"S3SignerType" - - // 说明:zkfc对namenode健康状态检查的超时时间。单位:毫秒。增大该参数值,可以防止出现双Active NameNode,降低客户端应用运行异常的概率。 默认值:180000 取值范围:30000~3600000 - "ha.health-monitor.rpc-timeout.ms": int & >=30000 & <=3600000 | *180000 - - // 说明:Zkfc连接到ZooKeeper时使用的会话超时时间。单位:毫秒。如果将该参数设置为较小的值,那可以更快地监测到服务器瘫痪故障,但如果出现瞬变错误或网络中断则有强制触发切换的风险。 默认值:90000 取值范围:1~3600000 - "ha.zookeeper.session-timeout.ms": int & >=1 & <=3600000 | *90000 - - // 说明:存储鉴权令牌的HTTP cookie所使用的域。为了在所有Hadoop节点web控制台间正确地进行鉴权,该域必须配置正确。重要:使用IP地址时,浏览器会忽略带有域设置的cookies。为保证该设置的正常使用,集群中的所有节点都必须配置为使用上面的hostname.domain名来生成URL。 - "hadoop.http.authentication.cookie.domain"?: string - - // 说明:通过静态网页可以呈现内容的用户名。 默认值:hdfs - "hadoop.http.staticuser.user": string | *"hdfs" - - // 说明:设置Hadoop中各模块的RPC通道是否加密。对RPC的加密方式,有如下三种取值: authentication:只进行认证,不加密; integrity:进行认证和一致性校验; privacy:进行认证、一致性校验、加密。 默认值:S的上层服务,且不支持滚动重启。重启过程中会造成业务中断,请谨慎修改。 - "hadoop.rpc.protection": string & ("authentication" | "privacy" | "integrity") | *"privacy" - - // 说明: 选择 Hadoop 使用的身份验证机制. 默认值:kerberos 取值范围:kerberos - "hadoop.security.authentication": string & ("kerberos") | *"kerberos" - - // 说明: 启用授权. 默认值:true 取值范围:true, false 注意:修改该配置为false后会停用Kerberos,存在安全风险,请谨慎操作。 - "hadoop.security.authorization": bool | *true - - // 说明:ACL中用于用户和组之间的映射(为指定用户获取组)的类。该类使用bash -c groups命令临时接入到Linux/Unix环境为用户获取组清单。org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback决定JNI(Ja用,将使用ShellBasedUnixGroupsMapping。 默认值:org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback 取值范围:org.apache.hadoop.security.ShellBasedUnixGroupsMapping 或 org.apache.hadoop.securityroupsMappingWithFallback - "hadoop.security.group.mapping": string & ("org.apache.hadoop.security.ShellBasedUnixGroupsMapping" | "org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback") | *"org.apache.hadoop.security.JniBasedUnixGroupsMappingWithFallback" - - // 说明:由ShellBasedUnixGroupsMapping类使用,此属性控制要等待运行获取组的shell命令的时间。配置值可采用时间后缀s/m/h表示,分别表示秒,分钟和小时。 如果运行命令的时间比配置的值长,则该命令将中止并返回没有找到任何组的结果。配置为“0s”表示无限等待 (即等待命令自行退出)。 默认值:60s - "hadoop.security.groups.shell.command.timeout": string | *"60s" - - // 说明:通过HTTP或HTTPS访问HDFS的JMX, METRICS, CONF, STACKS等信息时,是否需要管理员权限。 默认值:true 取值范围:true, false 注意:修改该配置为false后,降低了安全等级,请谨慎操作。 - "hadoop.security.instrumentation.requires.admin": bool | *true - - // 说明:通过delegation token认证时,是否使用ip地址作为tokens的service key。 默认值:true 取值范围:true, false - "hadoop.security.token.service.use_ip": bool | *true - - // 说明:SSL支持的协议列表(用逗号分隔)。 默认值:TLSv1.2 注意:使用低版本协议,存在安全风险,请谨慎操作。 - "hadoop.ssl.enabled.protocols": string | *"TLSv1.2" - - // 说明:定义压缩编码解码库中的所有压缩编码。可用于压缩/解压缩的压缩编码类的列表,列表中各项以逗号分隔。除了带有该属性的类(优先级高)之外,类路径上的压缩编码类也都是通过Java ServiceLoader发现的。 默认值:oache.hadoop.io.compress.DeflateCodec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.GzipCodec. - "io.compression.codecs": string | *"org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.DeflateCodec,org.apache.hadoop.io.compress.Lz4Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.ZStandardCodec" - - // 说明:用于指定写入Sequence文件时的缓冲数据的长度,也用于指定读写文件时的缓冲数据的长度,单位为Byte。 默认值:131072 取值范围:大于或等于4096 注意:该大小需要设置为硬件页面大小(Intel x86硬件上,页面大小为4096)的整数倍。 - "io.file.buffer.size": int & >=1024 | *131072 - - // 说明:客户端与服务端建立Socket连接超时时,客户端的重试次数。 默认值:45 取值范围:1~256 - "ipc.client.connect.max.retries.on.timeouts": int & >=1 & <=256 | *45 - - // 说明:客户端与服务端建立socket连接的超时时间。单位:毫秒。 默认值:20000 取值范围:1~3600000 - "ipc.client.connect.timeout": int & >=1 & <=3600000 | *20000 - - // 说明:当客户端连接安全服务后,转向连接非安全服务时,服务端指引客户端进行非安全认证。该配置项控制客户端是否进行非安全认证。当设置为默认false时,禁止客户端回落到非安全认证,并断开连接。 默认值:true - "ipc.client.fallback-to-simple-auth-allowed": bool | *true - - // 说明:进行空闲情况检查的连接的个数阈值。 默认值:4000 取值范围:大于 0 - "ipc.client.idlethreshold": int & >=1 | *4000 - - // 说明:一次操作中可断连的最大客户端数。 默认值:10 取值范围:大于 0 - "ipc.client.kill.max": int & >=1 | *10 - - // 说明:表示是否要启用在RPC客户端上ping服务器。 默认值:true 取值范围:true 或 false - "ipc.client.ping": bool | *true - - // 说明:客户端ipc超时时间。单位:毫秒。 默认值:300000 取值范围:1~3600000 - "ipc.client.rpc-timeout.ms": int & >=1 & <=3600000 | *300000 - - // 说明:DataNode连接NameNode时可用的最大IPC数据大小。 默认值:268435456 取值范围:67108864~4294967296 - "ipc.maximum.data.length": int & >=67108864 & <=4294967296 | *268435456 - - // 说明:从RPC客户端向服务器发送ping包的间隔。单位:毫秒。 默认值:60000 取值范围:1~3600000 - "ipc.ping.interval": int & >=1 & <=3600000 | *60000 - - // 说明:表示服务器接受客户端连接的监听队列的长度。 默认值:128 取值范围:1~8192 - "ipc.server.listen.queue.size": int & >=1 & <=8192 | *128 - - // 说明:此设置可用于解决各种服务的性能问题。如果该值设置为true,处理时间多于99%的RPC请求的请求视为慢请求,记录于日志中并增加RpcSlowCalls的值。 默认值:false 取值范围:true 或 false - "ipc.server.log.slow.rpc": bool | *false -} diff --git a/addons/hadoop/config/hadoop-env.sh.tpl b/addons/hadoop/config/hadoop-env.sh.tpl index 1c921b89db..18e410085c 100644 --- a/addons/hadoop/config/hadoop-env.sh.tpl +++ b/addons/hadoop/config/hadoop-env.sh.tpl @@ -9,7 +9,7 @@ export HADOOP_OPTS="${HADOOP_OPTS} -Djava.net.preferIPv4Stack=true -Dsun.net.ine export HDFS_NAMENODE_OPTS="${HDFS_NAMENODE_OPTS:-} -Xms{{ .HDFS_NAMENODE_HEAP }} -Xmx{{ .HDFS_NAMENODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender" -export HDFS_DATANODE_OPTS="${HDFS_DATANODE_OPTS:-} -Xms{{ .HDFS_DATANODE_HEAP }} -Xmx{{ .HDFS_DATANODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=ERROR,RFAS" +export HDFS_DATANODE_OPTS="${HDFS_DATANODE_OPTS:-} -Xms{{ .HDFS_DATANODE_HEAP }} -Xmx{{ .HDFS_DATANODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=ERROR,RFAS -Ddfs.datanode.hostname=${POD_FQDN}" export HDFS_JOURNALNODE_OPTS="${HDFS_JOURNALNODE_OPTS:-} -Xms{{ .HDFS_JOURNALNODE_HEAP }} -Xmx{{ .HDFS_JOURNALNODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" diff --git a/addons/hadoop/config/hdfs-common-config-constraint.cue b/addons/hadoop/config/hdfs-common-config-constraint.cue new file mode 100644 index 0000000000..eddde1662e --- /dev/null +++ b/addons/hadoop/config/hdfs-common-config-constraint.cue @@ -0,0 +1,72 @@ +package kubeblocks + +import "strings" + +#HDFSCommonParameter: { + fsDefaultFS?: string + ioFileBufferSize?: int + ioBytesPerChecksum?: int + ipcClientConnectTimeout?: int + ipcClientConnectMaxRetries?: int + ipcClientConnectRetryInterval?: int + ipcServerListenQueueSize?: int + hadoopSecurityAuthorization?: bool +} + +parameter: [string]: { + value: string + description?: string + type: "string" | "int" | "bool" + mutable?: bool +} + +parameter: { + "fs.defaultFS": { + value: #HDFSCommonParameter.fsDefaultFS + description: "The name of the default file system. A URI whose scheme and authority determine the FileSystem implementation." + type: "string" + mutable: false + } + "io.file.buffer.size": { + value: "\( #HDFSCommonParameter.ioFileBufferSize )" + description: "The size of buffer for use in sequence files, RPC, etc." + type: "int" + mutable: true + } + "io.bytes.per.checksum": { + value: "\( #HDFSCommonParameter.ioBytesPerChecksum )" + description: "The number of bytes per checksum. Must be less than or equal to io.file.buffer.size." + type: "int" + mutable: false + } + "ipc.client.connect.timeout": { + value: "\( #HDFSCommonParameter.ipcClientConnectTimeout )" + description: "The socket connect timeout in milliseconds." + type: "int" + mutable: true + } + "ipc.client.connect.max.retries": { + value: "\( #HDFSCommonParameter.ipcClientConnectMaxRetries )" + description: "The number of retries for socket connections." + type: "int" + mutable: true + } + "ipc.client.connect.retry.interval": { + value: "\( #HDFSCommonParameter.ipcClientConnectRetryInterval )" + description: "The retry interval in milliseconds for socket connections." + type: "int" + mutable: true + } + "ipc.server.listen.queue.size": { + value: "\( #HDFSCommonParameter.ipcServerListenQueueSize )" + description: "The maximum backlog of TCP connections." + type: "int" + mutable: true + } + "hadoop.security.authorization": { + value: strings.ToLower("\( #HDFSCommonParameter.hadoopSecurityAuthorization )") + description: "Enable service-level authorization checks." + type: "bool" + mutable: false + } +} diff --git a/addons/hadoop/config/hdfs-datanode-standalone.tpl b/addons/hadoop/config/hdfs-datanode-standalone.tpl index 5b517422fb..1ec1f685f4 100644 --- a/addons/hadoop/config/hdfs-datanode-standalone.tpl +++ b/addons/hadoop/config/hdfs-datanode-standalone.tpl @@ -52,11 +52,6 @@ false - - dfs.datanode.hostname - {{- .POD_FQDN }} - - dfs.namenode.rpc-address {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- @@ -102,4 +97,4 @@ dfs.client.retry.policy.spec 1000,1 - + \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-datanode.tpl b/addons/hadoop/config/hdfs-datanode.tpl index ddddf036ea..7cf2b197b4 100644 --- a/addons/hadoop/config/hdfs-datanode.tpl +++ b/addons/hadoop/config/hdfs-datanode.tpl @@ -1,6 +1,7 @@ +{{- $name_node_ids := splitList "," (include "hadoop.haNameNodeIds" .) }} dfs.nameservices @@ -57,37 +58,23 @@ false - - dfs.datanode.hostname - {{- .POD_FQDN }} - - dfs.ha.namenodes.{{- .CLUSTER_NAME }} - nn0,nn1 - - - dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn0 - {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} - - - dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn1 - {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} - - - dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn0 - {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} - - - dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn1 - {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} - - - + {{ join "," $name_node_ids }} + {{- range $nn_id := + $name_node_ids }} + dfs.namenode.rpc-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} + {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME + }}-namenode-headless.{{- + $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_RPC_PORT }} + + {{- end }} {{- range $nn_id := $name_node_ids }} + dfs.namenode.http-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} + {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME + }}-namenode-headless.{{- + $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_HTTP_PORT }} + + {{- end }} dfs.client.failover.proxy.provider.{{- .CLUSTER_NAME }} org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider @@ -126,4 +113,4 @@ dfs.client.retry.policy.spec 1000,1 - + \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-namenode.tpl b/addons/hadoop/config/hdfs-namenode.tpl index a1401e2c07..2f15c35bca 100644 --- a/addons/hadoop/config/hdfs-namenode.tpl +++ b/addons/hadoop/config/hdfs-namenode.tpl @@ -4,6 +4,7 @@ {{- $fqnds := splitList "," .JOURNALNODE_POD_FQDN_LIST }} {{- $journalnode_fqdns := printf "qjournal://" }} {{- $journalnode_rpc_port := .HDFS_JOURNALNODE_RPC_PORT }} +{{- $name_node_ids := splitList "," (include "hadoop.haNameNodeIds" .) }} {{- range $i, $fqdn := $fqnds }} {{- $journalnode_fqdns = printf "%s%s:%s" $journalnode_fqdns $fqdn $journalnode_rpc_port }} {{- if lt $i (sub (len $fqnds) 1) }} @@ -25,30 +26,24 @@ dfs.ha.namenodes.{{- .CLUSTER_NAME }} - nn0,nn1 + {{ join "," $name_node_ids }} +{{- range $nn_id := $name_node_ids }} - dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn0 - {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} - - - dfs.namenode.rpc-address.{{- .CLUSTER_NAME }}.nn1 - {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_RPC_PORT }} + dfs.namenode.rpc-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} + {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- + $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_RPC_PORT }} +{{- end }} +{{- range $nn_id := $name_node_ids }} - dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn0 - {{- .CLUSTER_NAME }}-namenode-0.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} - - - dfs.namenode.http-address.{{- .CLUSTER_NAME }}.nn1 - {{- .CLUSTER_NAME }}-namenode-1.{{- .CLUSTER_NAME }}-namenode-headless.{{- - .NAMESPACE }}.svc.{{- .CLUSTER_DOMAIN }}:{{- .HDFS_NAMENODE_HTTP_PORT }} + dfs.namenode.http-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} + {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- + $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_HTTP_PORT }} +{{- end }} dfs.namenode.rpc-bind-host @@ -218,4 +213,4 @@ dfs.journalnode.rpc-address 0.0.0.0:8485 - \ No newline at end of file + diff --git a/addons/hadoop/scripts/start-namenode.sh b/addons/hadoop/scripts/start-namenode.sh index 93161fb746..ef824284c2 100644 --- a/addons/hadoop/scripts/start-namenode.sh +++ b/addons/hadoop/scripts/start-namenode.sh @@ -8,6 +8,8 @@ set -o pipefail : "${HADOOP_CONF_DIR:=${HADOOP_HOME}/etc/hadoop}" : "${HADOOP_LOG_DIR:=/var/log/hadoop}" : "${HADOOP_PID_DIR:=/tmp/hadoop}" +: "${HDFS_HA_NAMENODE_IDS:=nn0,nn1}" +: "${HDFS_HA_STANDBY_ORDINAL:=1}" : "${LIFECYCLE_DIR:=/lifecycle}" export HADOOP_HOME HADOOP_CONF_DIR HADOOP_LOG_DIR HADOOP_PID_DIR @@ -16,7 +18,9 @@ mkdir -p "${HADOOP_LOG_DIR}" "${HADOOP_PID_DIR}" "${LIFECYCLE_DIR}" USER=$(whoami) LOG_FILE="${HADOOP_LOG_DIR}/hadoop-${USER}-namenode-$(hostname).log" -# 仅在 standby ordinal 上执行 bootstrapStandby,避免与 OrderedReady 启动顺序冲突。 +# 功能:仅在 standby ordinal 上执行 bootstrapStandby,避免与 OrderedReady 启动顺序冲突。 +# 参数:无,依赖 POD_NAME、HADOOP_HOME、HADOOP_CONF_DIR 等环境变量。 +# 返回值:成功返回 0,失败返回非 0。 bootstrap_standby_if_needed() { local pod_name host_name ordinal nameservices nn_ids peer_id peer_rpc peer_host local name_dirs nn_dir nn_current_dir @@ -26,8 +30,8 @@ bootstrap_standby_if_needed() { ordinal="${pod_name##*-}" [[ "$ordinal" == "$pod_name" ]] && ordinal="${host_name##*-}" - # ponytail: 当前 HA 只支持双 NameNode,standby 固定为 ordinal 1;如后续拓扑扩展,再显式映射 nnId。 - [[ "$ordinal" == "1" ]] || return 0 + # ponytail: 当前 addon 的 HA 语义固定为双 NameNode,standby ordinal 集中在这里;扩展更多 NN 时再引入显式 nnId 映射。 + [[ "$ordinal" == "${HDFS_HA_STANDBY_ORDINAL}" ]] || return 0 nameservices=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.nameservices 2>/dev/null || echo "") [[ -n "$nameservices" ]] || return 0 @@ -46,7 +50,14 @@ bootstrap_standby_if_needed() { return 0 fi - peer_id="nn0" + peer_id="" + for nn_id in $(echo "${HDFS_HA_NAMENODE_IDS}" | tr ',' '\n'); do + if [[ "$nn_id" != "nn${ordinal}" ]]; then + peer_id="$nn_id" + break + fi + done + [[ -n "$peer_id" ]] || peer_id="nn0" peer_rpc=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.namenode.rpc-address.${nameservices}.${peer_id}" 2>/dev/null || echo "") peer_host="${peer_rpc%:*}" if [[ -z "$peer_host" || "$peer_host" == "$peer_rpc" ]]; then diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl index 5a3f92622c..5bb6943465 100644 --- a/addons/hadoop/templates/_helpers.tpl +++ b/addons/hadoop/templates/_helpers.tpl @@ -50,14 +50,6 @@ kubeblocks.io/crd-api-version: apps.kubeblocks.io/v1 {{/* Component definition regex patterns */}} -{{- define "hadoop.hadoopCoreCmpdRegexPattern" -}} -^hadoop-core$ -{{- end }} - -{{- define "hadoop.hadoopCoreStandaloneCmpdRegexPattern" -}} -^hadoop-core-standalone$ -{{- end }} - {{- define "hadoop.hdfsJournalnodeCmpdRegexPattern" -}} ^hdfs-journalnode$ {{- end }} @@ -78,6 +70,13 @@ Component definition regex patterns ^hdfs-datanode-standalone$ {{- end }} +{{/* +HA NameNode ids for the current addon implementation. +*/}} +{{- define "hadoop.haNameNodeIds" -}} +nn0,nn1 +{{- end }} + {{/* Image references */}} @@ -85,10 +84,6 @@ Image references {{ .Values.image.common.registry }}/{{ .Values.image.common.repository }}:{{ .Values.image.common.tag }} {{- end }} -{{- define "hadoop.coreImage" -}} -{{ .Values.core.image.registry }}/{{ .Values.core.image.repository }}:{{ .Values.core.image.tag }} -{{- end }} - {{- define "hadoop.journalNodeImage" -}} {{ .Values.journalNode.image.registry }}/{{ .Values.journalNode.image.repository }}:{{ .Values.journalNode.image.tag }} {{- end }} diff --git a/addons/hadoop/templates/clusterdefinition.yaml b/addons/hadoop/templates/clusterdefinition.yaml index 2b59a02617..ae42eec5d4 100644 --- a/addons/hadoop/templates/clusterdefinition.yaml +++ b/addons/hadoop/templates/clusterdefinition.yaml @@ -10,26 +10,20 @@ spec: topologies: - name: standalone components: - - name: hadoop-core - compDef: {{ include "hadoop.hadoopCoreStandaloneCmpdRegexPattern" . }} - name: namenode compDef: {{ include "hadoop.hdfsNamenodeStandaloneCmpdRegexPattern" . }} - name: datanode compDef: {{ include "hadoop.hdfsDatanodeStandaloneCmpdRegexPattern" . }} orders: provision: - - hadoop-core - namenode - datanode terminate: - datanode - namenode - - hadoop-core - name: cluster default: true components: - - name: hadoop-core - compDef: {{ include "hadoop.hadoopCoreCmpdRegexPattern" . }} - name: journalnode compDef: {{ include "hadoop.hdfsJournalnodeCmpdRegexPattern" . }} - name: namenode @@ -38,7 +32,6 @@ spec: compDef: {{ include "hadoop.hdfsDatanodeCmpdRegexPattern" . }} orders: provision: - - hadoop-core - journalnode - namenode - datanode @@ -46,4 +39,3 @@ spec: - datanode - namenode - journalnode - - hadoop-core diff --git a/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml b/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml deleted file mode 100644 index e2d1ebf7a8..0000000000 --- a/addons/hadoop/templates/cmpd-hadoop-core-standalone.yaml +++ /dev/null @@ -1,82 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1 -kind: ComponentDefinition -metadata: - name: hadoop-core-standalone - labels: - {{- include "hadoop.labels" . | nindent 4 }} - annotations: - {{- include "hadoop.apiVersion" . | nindent 4 }} -spec: - provider: kubeblocks - description: {{ .Chart.Description }} - serviceKind: hadoop-core-standalone - runtime: - containers: - - name: hadoop-core - image: {{ include "hadoop.coreImage" . | quote }} - imagePullPolicy: {{ .Values.core.image.pullPolicy }} - env: - - name: DEBUG_MODEL - value: {{ .Values.runtime.debug | quote }} - volumeMounts: - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/core-site.xml - subPath: core-site.xml - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh - subPath: hadoop-env.sh - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/log4j.properties - subPath: log4j.properties - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/dfs.include - subPath: dfs.include - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/dfs.exclude - subPath: dfs.exclude - securityContext: - runAsGroup: {{ .Values.securityContext.runAsGroup }} - runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} - runAsUser: {{ .Values.securityContext.runAsUser }} - updateStrategy: {{ .Values.updateStrategy }} - vars: - - name: CLUSTER_NAME - valueFrom: - clusterVarRef: - clusterName: Required - - name: NAMESPACE - valueFrom: - clusterVarRef: - namespace: Required - - name: CLUSTER_DOMAIN - value: {{ .Values.extra.clusterDomain }} - - name: HDFS_CONF_DIR - value: {{ .Values.runtime.configDir }} - - name: HDFS_TRASH_INTERVAL - value: {{ .Values.hdfs.trash.interval | quote }} - - name: HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS - value: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} - - name: HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS - value: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} - - name: HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE - value: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} - - name: HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS - value: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} - - name: HDFS_IPC_CLIENT_PING - value: {{ .Values.hdfs.ipc.clientPing | quote }} - - name: HDFS_IPC_PING_INTERVAL_MS - value: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} - - name: HDFS_NAMENODE_HEAP - value: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} - - name: HDFS_DATANODE_HEAP - value: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} - - name: HDFS_JOURNALNODE_HEAP - value: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} - - name: HDFS_ZKFC_HEAP - value: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} - configs: - - name: hadoop-core-config - template: hadoop-core-standalone-config-template - volumeName: hadoop-core-config - namespace: {{ .Release.Namespace }} - defaultMode: {{ .Values.config.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hadoop-core.yaml b/addons/hadoop/templates/cmpd-hadoop-core.yaml deleted file mode 100644 index cdff8233f1..0000000000 --- a/addons/hadoop/templates/cmpd-hadoop-core.yaml +++ /dev/null @@ -1,96 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1 -kind: ComponentDefinition -metadata: - name: hadoop-core - labels: - {{- include "hadoop.labels" . | nindent 4 }} - annotations: - {{- include "hadoop.apiVersion" . | nindent 4 }} -spec: - provider: kubeblocks - description: {{ .Chart.Description }} - serviceKind: hadoop-core - serviceRefDeclarations: - - name: hadoopZookeeper - serviceRefDeclarationSpecs: - - serviceKind: zookeeper - serviceVersion: "^*" - runtime: - containers: - - name: hadoop-core - image: {{ include "hadoop.coreImage" . | quote }} - imagePullPolicy: {{ .Values.core.image.pullPolicy }} - env: - - name: DEBUG_MODEL - value: {{ .Values.runtime.debug | quote }} - volumeMounts: - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/core-site.xml - subPath: core-site.xml - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh - subPath: hadoop-env.sh - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/log4j.properties - subPath: log4j.properties - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/dfs.include - subPath: dfs.include - - name: hadoop-core-config - mountPath: {{ .Values.runtime.configDir }}/dfs.exclude - subPath: dfs.exclude - securityContext: - runAsGroup: {{ .Values.securityContext.runAsGroup }} - runAsNonRoot: {{ .Values.securityContext.runAsNonRoot }} - runAsUser: {{ .Values.securityContext.runAsUser }} - updateStrategy: {{ .Values.updateStrategy }} - vars: - - name: CLUSTER_NAME - valueFrom: - clusterVarRef: - clusterName: Required - - name: NAMESPACE - valueFrom: - clusterVarRef: - namespace: Required - - name: CLUSTER_DOMAIN - value: {{ .Values.extra.clusterDomain }} - - name: HDFS_CONF_DIR - value: {{ .Values.runtime.configDir }} - - name: ZOOKEEPER_ENDPOINTS - valueFrom: - serviceRefVarRef: - name: hadoopZookeeper - endpoint: Required - - name: HDFS_TRASH_INTERVAL - value: {{ .Values.hdfs.trash.interval | quote }} - - name: HDFS_HA_ZOOKEEPER_PARENT_ZNODE - value: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} - - name: HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS - value: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} - - name: HDFS_IPC_CLIENT_CONNECTION_MAX_IDLE_TIME_MS - value: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTimeMs | quote }} - - name: HDFS_IPC_CLIENT_CONNECT_TIMEOUT_MS - value: {{ .Values.hdfs.ipc.clientConnectTimeoutMs | quote }} - - name: HDFS_IPC_CLIENT_CONNECTION_POOL_SIZE - value: {{ .Values.hdfs.ipc.clientConnectionPoolSize | quote }} - - name: HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS - value: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} - - name: HDFS_IPC_CLIENT_PING - value: {{ .Values.hdfs.ipc.clientPing | quote }} - - name: HDFS_IPC_PING_INTERVAL_MS - value: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} - - name: HDFS_NAMENODE_HEAP - value: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} - - name: HDFS_DATANODE_HEAP - value: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} - - name: HDFS_JOURNALNODE_HEAP - value: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} - - name: HDFS_ZKFC_HEAP - value: {{ .Values.hdfs.jvm.zkfcHeapSize | quote }} - configs: - - name: hadoop-core-config - template: hadoop-core-config-template - volumeName: hadoop-core-config - namespace: {{ .Release.Namespace }} - defaultMode: {{ .Values.config.defaultMode }} diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml index 4f909306b7..ba0bd695d2 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml @@ -98,19 +98,19 @@ spec: volumeMounts: - name: hadoop-common mountPath: {{ .Values.runtime.hadoopHome }} - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties subPath: hadoop-metrics2.properties - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.exclude subPath: dfs.exclude - name: datanode-config @@ -184,6 +184,11 @@ spec: fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] apiVersion: v1 configs: + - name: hdfs-common-config + template: hdfs-common-standalone-config-template + volumeName: hdfs-common-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} - name: datanode-config template: datanode-standalone-config-template volumeName: datanode-config diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml index f9f661d818..de4c57f9ea 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml @@ -104,19 +104,19 @@ spec: volumeMounts: - name: hadoop-common mountPath: {{ .Values.runtime.hadoopHome }} - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties subPath: hadoop-metrics2.properties - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.exclude subPath: dfs.exclude - name: datanode-config @@ -196,6 +196,11 @@ spec: fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] apiVersion: v1 configs: + - name: hdfs-common-config + template: hdfs-common-config-template + volumeName: hdfs-common-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} - name: datanode-config template: datanode-config-template volumeName: datanode-config diff --git a/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml index 79fe02a2e5..62bce66f20 100644 --- a/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml @@ -96,19 +96,19 @@ spec: - name: edits-dir mountPath: {{ .Values.hdfs.paths.journalnodeEditsDir }} subPath: journal - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties subPath: hadoop-metrics2.properties - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.exclude subPath: dfs.exclude - name: journalnode-config @@ -167,6 +167,11 @@ spec: - name: HDFS_REPLICATION value: {{ .Values.hdfs.replication | quote }} configs: + - name: hdfs-common-config + template: hdfs-common-config-template + volumeName: hdfs-common-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} - name: journalnode-config template: journalnode-config-template volumeName: journalnode-config diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml index f9ec9d1135..8472445971 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -62,10 +62,10 @@ spec: mountPath: {{ .Values.runtime.hadoopHome }} - name: metadata-dir mountPath: /hadoop - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - name: namenode-config @@ -139,22 +139,22 @@ spec: mountPath: {{ .Values.runtime.hadoopHome }} - name: metadata-dir mountPath: /hadoop - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties subPath: hadoop-metrics2.properties - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.exclude subPath: dfs.exclude - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/log4j.properties subPath: log4j.properties - name: namenode-config @@ -219,6 +219,11 @@ spec: - name: HDFS_NAMENODE_HANDLER_COUNT value: {{ .Values.hdfs.namenode.handlerCount | quote }} configs: + - name: hdfs-common-config + template: hdfs-common-standalone-config-template + volumeName: hdfs-common-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} - name: namenode-config template: namenode-standalone-config-template volumeName: namenode-config diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index ec4c7de82d..9dea991fce 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -68,10 +68,10 @@ spec: mountPath: {{ .Values.runtime.hadoopHome }} - name: metadata-dir mountPath: /hadoop - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - name: namenode-config @@ -98,10 +98,10 @@ spec: volumeMounts: - name: hadoop-common mountPath: {{ .Values.runtime.hadoopHome }} - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - name: namenode-config @@ -175,22 +175,22 @@ spec: mountPath: {{ .Values.runtime.hadoopHome }} - name: metadata-dir mountPath: /hadoop - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties subPath: hadoop-metrics2.properties - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.exclude subPath: dfs.exclude - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/log4j.properties subPath: log4j.properties - name: namenode-config @@ -261,13 +261,13 @@ spec: volumeMounts: - name: hadoop-common mountPath: {{ .Values.runtime.hadoopHome }} - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/core-site.xml subPath: core-site.xml - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hadoop-core-config + - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/log4j.properties subPath: log4j.properties - name: namenode-config @@ -360,6 +360,11 @@ spec: fieldPath: metadata.annotations['kubeblocks.io/pod-fqdn'] apiVersion: v1 configs: + - name: hdfs-common-config + template: hdfs-common-config-template + volumeName: hdfs-common-config + namespace: {{ .Release.Namespace }} + defaultMode: {{ .Values.config.defaultMode }} - name: namenode-config template: namenode-config-template volumeName: namenode-config diff --git a/addons/hadoop/templates/cmpv-hadoop-core.yaml b/addons/hadoop/templates/cmpv-hadoop-core.yaml deleted file mode 100644 index 8edfb15bcc..0000000000 --- a/addons/hadoop/templates/cmpv-hadoop-core.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps.kubeblocks.io/v1 -kind: ComponentVersion -metadata: - name: hadoop-core - labels: - {{- include "hadoop.labels" . | nindent 4 }} - annotations: - {{- include "hadoop.apiVersion" . | nindent 4 }} -spec: - compatibilityRules: - - releases: - - v3.3.4 - compDefs: - - hadoop-core - - hadoop-core-standalone - releases: - - name: v3.3.4 - serviceVersion: v3.3.4 - images: - hadoop-core: {{ include "hadoop.coreImage" . | quote }} diff --git a/addons/hadoop/templates/hadoop-core-config-template.yaml b/addons/hadoop/templates/hdfs-common-config-template.yaml similarity index 94% rename from addons/hadoop/templates/hadoop-core-config-template.yaml rename to addons/hadoop/templates/hdfs-common-config-template.yaml index 75db43148c..a8fd138f41 100644 --- a/addons/hadoop/templates/hadoop-core-config-template.yaml +++ b/addons/hadoop/templates/hdfs-common-config-template.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: hadoop-core-config-template + name: hdfs-common-config-template labels: {{- include "hadoop.labels" . | nindent 4 }} data: diff --git a/addons/hadoop/templates/hadoop-core-standalone-config-template.yaml b/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml similarity index 92% rename from addons/hadoop/templates/hadoop-core-standalone-config-template.yaml rename to addons/hadoop/templates/hdfs-common-standalone-config-template.yaml index 9c42ea0d00..316a3655e0 100644 --- a/addons/hadoop/templates/hadoop-core-standalone-config-template.yaml +++ b/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml @@ -1,7 +1,7 @@ apiVersion: v1 kind: ConfigMap metadata: - name: hadoop-core-standalone-config-template + name: hdfs-common-standalone-config-template labels: {{- include "hadoop.labels" . | nindent 4 }} data: diff --git a/addons/hadoop/templates/paramsdef-hadoop-core.yaml b/addons/hadoop/templates/paramsdef-hdfs-common.yaml similarity index 57% rename from addons/hadoop/templates/paramsdef-hadoop-core.yaml rename to addons/hadoop/templates/paramsdef-hdfs-common.yaml index 3b310c4ab8..f023028c54 100644 --- a/addons/hadoop/templates/paramsdef-hadoop-core.yaml +++ b/addons/hadoop/templates/paramsdef-hdfs-common.yaml @@ -1,12 +1,12 @@ apiVersion: parameters.kubeblocks.io/v1alpha1 kind: ParametersDefinition metadata: - name: hadoop-core-config-constraints + name: hdfs-common-config-constraints labels: {{- include "hadoop.labels" . | nindent 4 }} spec: fileName: core-site.xml parametersSchema: - topLevelKey: HadoopCoreParameter + topLevelKey: HDFSCommonParameter cue: |- - {{- .Files.Get "config/hadoop-core-config-constraint.cue" | nindent 6 }} \ No newline at end of file + {{- .Files.Get "config/hdfs-common-config-constraint.cue" | nindent 6 }} diff --git a/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml b/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml deleted file mode 100644 index b1169536f5..0000000000 --- a/addons/hadoop/templates/pcr-hadoop-core-standalone.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: parameters.kubeblocks.io/v1alpha1 -kind: ParamConfigRenderer -metadata: - name: hadoop-core-standalone-config-renderer - labels: - {{- include "hadoop.labels" . | nindent 4 }} - annotations: - {{- include "hadoop.annotations" . | nindent 4 }} -spec: - componentDef: hadoop-core-standalone - parametersDefs: - - hadoop-core-config-constraints - configs: - - name: core-site.xml - fileFormatConfig: - format: xml diff --git a/addons/hadoop/templates/pcr-hadoop-core.yaml b/addons/hadoop/templates/pcr-hadoop-core.yaml deleted file mode 100644 index 36cb45bb53..0000000000 --- a/addons/hadoop/templates/pcr-hadoop-core.yaml +++ /dev/null @@ -1,16 +0,0 @@ -apiVersion: parameters.kubeblocks.io/v1alpha1 -kind: ParamConfigRenderer -metadata: - name: hadoop-core-config-renderer - labels: - {{- include "hadoop.labels" . | nindent 4 }} - annotations: - {{- include "hadoop.annotations" . | nindent 4 }} -spec: - componentDef: hadoop-core - parametersDefs: - - hadoop-core-config-constraints - configs: - - name: core-site.xml - fileFormatConfig: - format: xml \ No newline at end of file diff --git a/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml index 259770fe52..cfcba9e101 100644 --- a/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml +++ b/addons/hadoop/templates/pcr-hdfs-datanode-standalone.yaml @@ -9,8 +9,12 @@ metadata: spec: componentDef: hdfs-datanode-standalone parametersDefs: + - hdfs-common-config-constraints - datanode-config-constraints configs: + - name: core-site.xml + fileFormatConfig: + format: xml - name: hdfs-site.xml fileFormatConfig: format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-datanode.yaml b/addons/hadoop/templates/pcr-hdfs-datanode.yaml index c9883aed69..4d830873f3 100644 --- a/addons/hadoop/templates/pcr-hdfs-datanode.yaml +++ b/addons/hadoop/templates/pcr-hdfs-datanode.yaml @@ -9,8 +9,12 @@ metadata: spec: componentDef: hdfs-datanode parametersDefs: + - hdfs-common-config-constraints - datanode-config-constraints configs: + - name: core-site.xml + fileFormatConfig: + format: xml - name: hdfs-site.xml fileFormatConfig: - format: xml \ No newline at end of file + format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-journalnode.yaml b/addons/hadoop/templates/pcr-hdfs-journalnode.yaml index 1a7c2c0e5b..98479aaa1b 100644 --- a/addons/hadoop/templates/pcr-hdfs-journalnode.yaml +++ b/addons/hadoop/templates/pcr-hdfs-journalnode.yaml @@ -9,8 +9,12 @@ metadata: spec: componentDef: hdfs-journalnode parametersDefs: + - hdfs-common-config-constraints - journalnode-config-constraints configs: + - name: core-site.xml + fileFormatConfig: + format: xml - name: hdfs-site.xml fileFormatConfig: - format: xml \ No newline at end of file + format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml index 11d8d664b6..9bf03ab59c 100644 --- a/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/pcr-hdfs-namenode-standalone.yaml @@ -9,8 +9,12 @@ metadata: spec: componentDef: hdfs-namenode-standalone parametersDefs: + - hdfs-common-config-constraints - namenode-config-constraints configs: + - name: core-site.xml + fileFormatConfig: + format: xml - name: hdfs-site.xml fileFormatConfig: format: xml diff --git a/addons/hadoop/templates/pcr-hdfs-namenode.yaml b/addons/hadoop/templates/pcr-hdfs-namenode.yaml index 406e01713c..59d8e9443f 100644 --- a/addons/hadoop/templates/pcr-hdfs-namenode.yaml +++ b/addons/hadoop/templates/pcr-hdfs-namenode.yaml @@ -9,8 +9,12 @@ metadata: spec: componentDef: hdfs-namenode parametersDefs: + - hdfs-common-config-constraints - namenode-config-constraints configs: + - name: core-site.xml + fileFormatConfig: + format: xml - name: hdfs-site.xml fileFormatConfig: - format: xml \ No newline at end of file + format: xml diff --git a/addons/hadoop/values.yaml b/addons/hadoop/values.yaml index f55997a510..8652a17e6e 100644 --- a/addons/hadoop/values.yaml +++ b/addons/hadoop/values.yaml @@ -6,14 +6,6 @@ image: tag: "v3.3.4-1.0.0" pullPolicy: IfNotPresent -# Component-specific images -core: - image: - registry: docker.io - repository: apecloud/hdfs-journalnode - tag: "v3.3.4-1.0.0" - pullPolicy: IfNotPresent - journalNode: image: registry: docker.io diff --git a/addons/hbase/README.md b/addons/hbase/README.md index c98946ee86..32a55c0829 100644 --- a/addons/hbase/README.md +++ b/addons/hbase/README.md @@ -70,9 +70,9 @@ spec: - name: HADOOP_CLUSTER_NAME value: "hadoop2" volumes: - - name: hadoop-core-config + - name: hdfs-common-config configMap: - name: hadoop2-hadoop-core-config + name: hadoop2-namenode-hdfs-common-config - name: hadoop-hdfs-config configMap: name: hadoop2-namenode-config @@ -116,9 +116,9 @@ spec: - name: HADOOP_CLUSTER_NAME value: "hadoop2" volumes: - - name: hadoop-core-config + - name: hdfs-common-config configMap: - name: hadoop2-hadoop-core-config + name: hadoop2-namenode-hdfs-common-config - name: hadoop-hdfs-config configMap: name: hadoop2-namenode-config @@ -141,4 +141,4 @@ kubectl apply -f examples/hbase/cluster.yaml ```bash kubectl patch cluster -n demo hbase-cluster -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge" kubectl delete cluster -n demo hbase-cluster -``` \ No newline at end of file +``` diff --git a/addons/hbase/config/hadoop-core-site.tpl b/addons/hbase/config/hdfs-common-site.tpl similarity index 100% rename from addons/hbase/config/hadoop-core-site.tpl rename to addons/hbase/config/hdfs-common-site.tpl diff --git a/addons/hbase/templates/hbase-cluster-config-template.yaml b/addons/hbase/templates/hbase-cluster-config-template.yaml index a4b5b9ea6f..20793f0872 100644 --- a/addons/hbase/templates/hbase-cluster-config-template.yaml +++ b/addons/hbase/templates/hbase-cluster-config-template.yaml @@ -8,7 +8,7 @@ data: hbase-site.xml: |- {{- .Files.Get "config/hbase-site-cluster.tpl" | nindent 4 }} core-site.xml: |- - {{- .Files.Get "config/hadoop-core-site.tpl" | nindent 4 }} + {{- .Files.Get "config/hdfs-common-site.tpl" | nindent 4 }} hdfs-site.xml: |- {{- .Files.Get "config/hdfs-client-site.tpl" | nindent 4 }} hbase-env.sh: |- From 11ba0efa26b4fc0aac1ae2af7167285d8d5a12ee Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 22:44:15 +0800 Subject: [PATCH 11/18] feat(hbase): stop overriding JAVA_HOME from the image --- addons/hbase/config/hbase-env.sh.tpl | 1 - addons/hbase/templates/cmpd-hbase-standalone.yaml | 2 -- addons/hbase/templates/cmpd-hmaster.yaml | 2 -- addons/hbase/templates/cmpd-hregionserver.yaml | 2 -- addons/hbase/values.yaml | 1 - 5 files changed, 8 deletions(-) diff --git a/addons/hbase/config/hbase-env.sh.tpl b/addons/hbase/config/hbase-env.sh.tpl index de80b4a649..de7ec996aa 100644 --- a/addons/hbase/config/hbase-env.sh.tpl +++ b/addons/hbase/config/hbase-env.sh.tpl @@ -14,4 +14,3 @@ export HBASE_HEAPSIZE={{ .HBASE_HEAP_SIZE }} export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP=true export LD_LIBRARY_PATH={{ .HADOOP_NATIVE_LIB_PATH }}:${LD_LIBRARY_PATH:-} -export JAVA_HOME={{ .JAVA_HOME }} diff --git a/addons/hbase/templates/cmpd-hbase-standalone.yaml b/addons/hbase/templates/cmpd-hbase-standalone.yaml index e405b3d8d7..1bed3a8fc2 100644 --- a/addons/hbase/templates/cmpd-hbase-standalone.yaml +++ b/addons/hbase/templates/cmpd-hbase-standalone.yaml @@ -146,8 +146,6 @@ spec: value: {{ .Values.runtime.hbaseDataDir }} - name: HADOOP_NATIVE_LIB_PATH value: {{ .Values.runtime.hadoopNativeLibPath }} - - name: JAVA_HOME - value: {{ .Values.runtime.javaHome }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE diff --git a/addons/hbase/templates/cmpd-hmaster.yaml b/addons/hbase/templates/cmpd-hmaster.yaml index 93a5c52415..6d076277fd 100644 --- a/addons/hbase/templates/cmpd-hmaster.yaml +++ b/addons/hbase/templates/cmpd-hmaster.yaml @@ -183,8 +183,6 @@ spec: value: {{ .Values.runtime.hbaseTmpDir }} - name: HADOOP_NATIVE_LIB_PATH value: {{ .Values.runtime.hadoopNativeLibPath }} - - name: JAVA_HOME - value: {{ .Values.runtime.javaHome }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hmasterHeapSize | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE diff --git a/addons/hbase/templates/cmpd-hregionserver.yaml b/addons/hbase/templates/cmpd-hregionserver.yaml index a14446ffeb..2bbd15b653 100644 --- a/addons/hbase/templates/cmpd-hregionserver.yaml +++ b/addons/hbase/templates/cmpd-hregionserver.yaml @@ -146,8 +146,6 @@ spec: value: {{ .Values.runtime.hbaseTmpDir }} - name: HADOOP_NATIVE_LIB_PATH value: {{ .Values.runtime.hadoopNativeLibPath }} - - name: JAVA_HOME - value: {{ .Values.runtime.javaHome }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hmasterHeapSize | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE diff --git a/addons/hbase/values.yaml b/addons/hbase/values.yaml index d4588c4bf1..58c85ce454 100644 --- a/addons/hbase/values.yaml +++ b/addons/hbase/values.yaml @@ -30,7 +30,6 @@ runtime: hadoopConfDir: /hadoop/conf hadoopHome: /opt/hadoop hadoopNativeLibPath: /opt/hadoop/lib/native - javaHome: /usr/local/openjdk-8 ports: hmaster: From 2b69f709ae307aafcd963017bd3beaef7531bb4a Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Tue, 7 Jul 2026 23:38:24 +0800 Subject: [PATCH 12/18] feat(hadoop): make ha namenode ids configurable for runtime hdfs config --- addons-cluster/hadoop/templates/cluster.yaml | 9 +++++++ addons-cluster/hadoop/values.yaml | 1 + addons/hadoop/config/hadoop-env.sh.tpl | 1 + addons/hadoop/config/hdfs-datanode.tpl | 10 ++++---- addons/hadoop/config/hdfs-namenode.tpl | 25 ++++++++------------ addons/hadoop/scripts/start-namenode.sh | 20 +++++++++------- addons/hadoop/templates/_helpers.tpl | 7 ------ 7 files changed, 37 insertions(+), 36 deletions(-) diff --git a/addons-cluster/hadoop/templates/cluster.yaml b/addons-cluster/hadoop/templates/cluster.yaml index 987c194394..6515a1ac16 100644 --- a/addons-cluster/hadoop/templates/cluster.yaml +++ b/addons-cluster/hadoop/templates/cluster.yaml @@ -1,11 +1,15 @@ {{- $isCluster := eq .Values.topology "cluster" }} {{- $isStandalone := eq .Values.topology "standalone" }} +{{- $haNameNodeIds := splitList "," .Values.hdfs.ha.nameNodeIds }} {{- if not (or $isCluster $isStandalone) }} {{- fail "topology must be either 'cluster' or 'standalone'" }} {{- end }} {{- if and $isCluster (ne (.Values.replicas.namenode | int) 2) }} {{- fail "cluster topology requires replicas.namenode = 2; this addon currently supports only active/standby NameNode HA" }} {{- end }} +{{- if and $isCluster (ne (len $haNameNodeIds) 2) }} +{{- fail "cluster topology requires exactly 2 hdfs.ha.nameNodeIds entries while active/standby NameNode HA is enforced" }} +{{- end }} {{- include "hadoop-cluster.clusterCommon" . }} clusterDef: hadoop topology: {{ .Values.topology }} @@ -28,6 +32,7 @@ HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} + HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} - name: journalnode-config variables: HDFS_JOURNALNODE_EDITS_DIR: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} @@ -88,6 +93,7 @@ HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} + HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} {{- if $isCluster }} HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} {{- else }} @@ -110,6 +116,7 @@ HDFS_HA_FENCING_METHODS: {{ .Values.hdfs.ha.fencingMethods | quote }} HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} HDFS_HA_ZOOKEEPER_OPERATION_RETRIES: {{ .Values.hdfs.ha.zookeeper.operationRetries | quote }} + HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} {{- else }} HDFS_REPLICATION: "1" HDFS_REPLICATION_MAX: "1" @@ -160,6 +167,7 @@ HDFS_IPC_CLIENT_CONNECT_RETRY_INTERVAL_MS: {{ .Values.hdfs.ipc.clientConnectRetryIntervalMs | quote }} HDFS_IPC_CLIENT_PING: {{ .Values.hdfs.ipc.clientPing | quote }} HDFS_IPC_PING_INTERVAL_MS: {{ .Values.hdfs.ipc.pingIntervalMs | quote }} + HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} {{- if not $isCluster }} HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} {{- end }} @@ -170,6 +178,7 @@ HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.ports.namenode.http | quote }} HDFS_DATANODE_HANDLER_COUNT: {{ .Values.hdfs.datanode.handlerCount | quote }} HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissions.enabled | quote }} + HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} {{- if $isCluster }} HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} HDFS_REPLICATION_MAX: {{ .Values.hdfs.replicationMax | quote }} diff --git a/addons-cluster/hadoop/values.yaml b/addons-cluster/hadoop/values.yaml index f3cfae92aa..ba711847a2 100644 --- a/addons-cluster/hadoop/values.yaml +++ b/addons-cluster/hadoop/values.yaml @@ -72,6 +72,7 @@ hdfs: registration: ipHostnameCheck: false ha: + nameNodeIds: "nn0,nn1" automaticFailoverEnabled: true fencingMethods: "sshfence\nshell(/bin/true)" zookeeper: diff --git a/addons/hadoop/config/hadoop-env.sh.tpl b/addons/hadoop/config/hadoop-env.sh.tpl index 18e410085c..21c5a0ca0e 100644 --- a/addons/hadoop/config/hadoop-env.sh.tpl +++ b/addons/hadoop/config/hadoop-env.sh.tpl @@ -6,6 +6,7 @@ export HADOOP_PID_DIR=${HADOOP_PID_DIR:-/tmp/hadoop} export HADOOP_IDENT_STRING=${HADOOP_IDENT_STRING:-$USER} export HADOOP_OPTS="${HADOOP_OPTS} -Djava.net.preferIPv4Stack=true -Dsun.net.inetaddr.ttl=10 -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelGCThreads=8" +export HDFS_HA_NAMENODE_IDS="${HDFS_HA_NAMENODE_IDS:-{{ .HDFS_HA_NAMENODE_IDS }}}" export HDFS_NAMENODE_OPTS="${HDFS_NAMENODE_OPTS:-} -Xms{{ .HDFS_NAMENODE_HEAP }} -Xmx{{ .HDFS_NAMENODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender" diff --git a/addons/hadoop/config/hdfs-datanode.tpl b/addons/hadoop/config/hdfs-datanode.tpl index 7cf2b197b4..ff1838986a 100644 --- a/addons/hadoop/config/hdfs-datanode.tpl +++ b/addons/hadoop/config/hdfs-datanode.tpl @@ -1,7 +1,7 @@ -{{- $name_node_ids := splitList "," (include "hadoop.haNameNodeIds" .) }} +{{- $name_node_ids := splitList "," .HDFS_HA_NAMENODE_IDS }} dfs.nameservices @@ -61,16 +61,16 @@ dfs.ha.namenodes.{{- .CLUSTER_NAME }} {{ join "," $name_node_ids }} - {{- range $nn_id := + {{- range $nn_ordinal, $nn_id := $name_node_ids }} dfs.namenode.rpc-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} - {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME + {{- $.CLUSTER_NAME }}-namenode-{{ $nn_ordinal }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_RPC_PORT }} - {{- end }} {{- range $nn_id := $name_node_ids }} + {{- end }} {{- range $nn_ordinal, $nn_id := $name_node_ids }} dfs.namenode.http-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} - {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME + {{- $.CLUSTER_NAME }}-namenode-{{ $nn_ordinal }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_HTTP_PORT }} diff --git a/addons/hadoop/config/hdfs-namenode.tpl b/addons/hadoop/config/hdfs-namenode.tpl index 2f15c35bca..cc0e2cbd8f 100644 --- a/addons/hadoop/config/hdfs-namenode.tpl +++ b/addons/hadoop/config/hdfs-namenode.tpl @@ -4,7 +4,7 @@ {{- $fqnds := splitList "," .JOURNALNODE_POD_FQDN_LIST }} {{- $journalnode_fqdns := printf "qjournal://" }} {{- $journalnode_rpc_port := .HDFS_JOURNALNODE_RPC_PORT }} -{{- $name_node_ids := splitList "," (include "hadoop.haNameNodeIds" .) }} +{{- $name_node_ids := splitList "," .HDFS_HA_NAMENODE_IDS }} {{- range $i, $fqdn := $fqnds }} {{- $journalnode_fqdns = printf "%s%s:%s" $journalnode_fqdns $fqdn $journalnode_rpc_port }} {{- if lt $i (sub (len $fqnds) 1) }} @@ -27,25 +27,20 @@ dfs.ha.namenodes.{{- .CLUSTER_NAME }} {{ join "," $name_node_ids }} - - -{{- range $nn_id := $name_node_ids }} - + {{- range $nn_ordinal, $nn_id := + $name_node_ids }} dfs.namenode.rpc-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} - {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- + {{- $.CLUSTER_NAME }}-namenode-{{ $nn_ordinal }}.{{- $.CLUSTER_NAME + }}-namenode-headless.{{- $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_RPC_PORT }} -{{- end }} - -{{- range $nn_id := $name_node_ids }} - + {{- end }} {{- range $nn_ordinal, $nn_id := $name_node_ids }} dfs.namenode.http-address.{{- $.CLUSTER_NAME }}.{{ $nn_id }} - {{- $.CLUSTER_NAME }}-namenode-{{ trimPrefix "nn" $nn_id }}.{{- $.CLUSTER_NAME }}-namenode-headless.{{- + {{- $.CLUSTER_NAME }}-namenode-{{ $nn_ordinal }}.{{- $.CLUSTER_NAME + }}-namenode-headless.{{- $.NAMESPACE }}.svc.{{- $.CLUSTER_DOMAIN }}:{{- $.HDFS_NAMENODE_HTTP_PORT }} -{{- end }} - - + {{- end }} dfs.namenode.rpc-bind-host 0.0.0.0 @@ -213,4 +208,4 @@ dfs.journalnode.rpc-address 0.0.0.0:8485 - + \ No newline at end of file diff --git a/addons/hadoop/scripts/start-namenode.sh b/addons/hadoop/scripts/start-namenode.sh index ef824284c2..a132d64cc5 100644 --- a/addons/hadoop/scripts/start-namenode.sh +++ b/addons/hadoop/scripts/start-namenode.sh @@ -30,7 +30,7 @@ bootstrap_standby_if_needed() { ordinal="${pod_name##*-}" [[ "$ordinal" == "$pod_name" ]] && ordinal="${host_name##*-}" - # ponytail: 当前 addon 的 HA 语义固定为双 NameNode,standby ordinal 集中在这里;扩展更多 NN 时再引入显式 nnId 映射。 + # ponytail: 当前 addon 的 HA 语义固定为双 NameNode,standby ordinal 集中在这里;扩展更多 NN 时再引入 observer/多角色编排。 [[ "$ordinal" == "${HDFS_HA_STANDBY_ORDINAL}" ]] || return 0 nameservices=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey dfs.nameservices 2>/dev/null || echo "") @@ -50,14 +50,16 @@ bootstrap_standby_if_needed() { return 0 fi - peer_id="" - for nn_id in $(echo "${HDFS_HA_NAMENODE_IDS}" | tr ',' '\n'); do - if [[ "$nn_id" != "nn${ordinal}" ]]; then - peer_id="$nn_id" - break - fi - done - [[ -n "$peer_id" ]] || peer_id="nn0" + IFS=',' read -r -a nn_id_array <<< "${HDFS_HA_NAMENODE_IDS}" + if [[ "${#nn_id_array[@]}" -lt 2 ]]; then + echo "[$(date)] HDFS_HA_NAMENODE_IDS must contain two entries for active/standby HA" >&2 + return 1 + fi + if [[ "$ordinal" == "0" ]]; then + peer_id="${nn_id_array[1]}" + else + peer_id="${nn_id_array[0]}" + fi peer_rpc=$("${HADOOP_HOME}/bin/hdfs" getconf -confKey "dfs.namenode.rpc-address.${nameservices}.${peer_id}" 2>/dev/null || echo "") peer_host="${peer_rpc%:*}" if [[ -z "$peer_host" || "$peer_host" == "$peer_rpc" ]]; then diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl index 5bb6943465..4f100766fc 100644 --- a/addons/hadoop/templates/_helpers.tpl +++ b/addons/hadoop/templates/_helpers.tpl @@ -70,13 +70,6 @@ Component definition regex patterns ^hdfs-datanode-standalone$ {{- end }} -{{/* -HA NameNode ids for the current addon implementation. -*/}} -{{- define "hadoop.haNameNodeIds" -}} -nn0,nn1 -{{- end }} - {{/* Image references */}} From 434189d9aa30da9d2e6e2b36ec8a36b2e9554be3 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Wed, 8 Jul 2026 09:30:54 +0800 Subject: [PATCH 13/18] fix(hbase): remove unsupported wal codec from cluster config --- addons/hbase/config/hbase-site-cluster.tpl | 5 ----- 1 file changed, 5 deletions(-) diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index ad3568d365..11885e1de0 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -278,11 +278,6 @@ 10 - - hbase.regionserver.wal.codec - org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec - - hbase.regionserver.wal.rs.bulkload.enabled true From 962962823b293b19b011a978acd89a855b70e2ac Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Wed, 8 Jul 2026 10:57:59 +0800 Subject: [PATCH 14/18] feat(hbase&hadoop): expose first batch of hbase/hdfs config overrides via cluster chart --- addons-cluster/hadoop/templates/cluster.yaml | 27 ++ addons-cluster/hadoop/values.schema.json | 51 ++- addons-cluster/hadoop/values.yaml | 20 ++ addons-cluster/hbase/templates/cluster.yaml | 94 ++++++ addons-cluster/hbase/values.schema.json | 280 ++++++++++++++++ addons-cluster/hbase/values.yaml | 60 ++++ addons/hadoop/README.md | 278 +++++++++++++++- addons/hadoop/README.zh-CN.md | 280 ++++++++++++++++ addons/hadoop/config/core-site-standalone.tpl | 11 +- addons/hadoop/config/core-site.tpl | 11 +- .../config/hdfs-datanode-standalone.tpl | 8 +- addons/hadoop/config/hdfs-datanode.tpl | 8 +- addons/hadoop/config/hdfs-journalnode.tpl | 15 + .../config/hdfs-namenode-standalone.tpl | 8 +- addons/hadoop/config/hdfs-namenode.tpl | 16 +- addons/hbase/README.md | 312 +++++++++++++----- addons/hbase/README.zh-CN.md | 303 +++++++++++++++++ addons/hbase/config/hbase-site-cluster.tpl | 58 ++-- addons/hbase/config/hbase-site-standalone.tpl | 22 +- addons/hbase/config/hdfs-client-site.tpl | 2 +- addons/hbase/config/hdfs-common-site.tpl | 18 +- 21 files changed, 1704 insertions(+), 178 deletions(-) create mode 100644 addons/hadoop/README.zh-CN.md create mode 100644 addons/hbase/README.zh-CN.md diff --git a/addons-cluster/hadoop/templates/cluster.yaml b/addons-cluster/hadoop/templates/cluster.yaml index 6515a1ac16..6189e4c239 100644 --- a/addons-cluster/hadoop/templates/cluster.yaml +++ b/addons-cluster/hadoop/templates/cluster.yaml @@ -21,6 +21,10 @@ - name: hdfs-common-config variables: HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_HADOOP_TMP_DIR: {{ .Values.hdfs.core.hadoopTmpDir | quote }} + HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} + HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} + HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} @@ -38,6 +42,9 @@ HDFS_JOURNALNODE_EDITS_DIR: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} HDFS_JOURNALNODE_RPC_PORT: {{ .Values.hdfs.ports.journalnode.rpc | quote }} HDFS_JOURNALNODE_HTTP_PORT: {{ .Values.hdfs.ports.journalnode.http | quote }} + HDFS_JOURNALNODE_ENABLE_SYNC: {{ .Values.hdfs.journalnode.enableSync | quote }} + HDFS_JOURNALNODE_EDIT_CACHE_SIZE_BYTES: {{ .Values.hdfs.journalnode.editCacheSizeBytes | quote }} + HDFS_JOURNALNODE_SYNC_INTERVAL_MS: {{ .Values.hdfs.journalnode.syncIntervalMs | quote }} replicas: {{ .Values.replicas.journalnode }} resources: requests: @@ -83,6 +90,10 @@ - name: hdfs-common-config variables: HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_HADOOP_TMP_DIR: {{ .Values.hdfs.core.hadoopTmpDir | quote }} + HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} + HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} + HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} @@ -106,7 +117,12 @@ HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.ports.namenode.http | quote }} HDFS_NAMENODE_HANDLER_COUNT: {{ .Values.hdfs.namenode.handlerCount | quote }} HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissions.enabled | quote }} + HDFS_PERMISSIONS_SUPERUSERGROUP: {{ .Values.hdfs.permissions.superusergroup | quote }} HDFS_REGISTRATION_IP_HOSTNAME_CHECK: {{ .Values.hdfs.registration.ipHostnameCheck | quote }} + HDFS_NAMENODE_WEBHDFS_ENABLED: {{ .Values.hdfs.namenode.webhdfsEnabled | quote }} + HDFS_NAMENODE_RESOURCE_DU_RESERVED: {{ .Values.hdfs.namenode.resourceDuReserved | quote }} + HDFS_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.retryPolicyEnabled | quote }} + HDFS_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.retryPolicySpec | quote }} {{- if $isCluster }} HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} HDFS_REPLICATION_MAX: {{ .Values.hdfs.replicationMax | quote }} @@ -114,9 +130,12 @@ HDFS_JOURNALNODE_RPC_PORT: {{ .Values.hdfs.ports.journalnode.rpc | quote }} HDFS_HA_AUTOMATIC_FAILOVER_ENABLED: {{ .Values.hdfs.ha.automaticFailoverEnabled | quote }} HDFS_HA_FENCING_METHODS: {{ .Values.hdfs.ha.fencingMethods | quote }} + HDFS_HA_FENCING_SSH_CONNECT_TIMEOUT_MS: {{ .Values.hdfs.ha.fencingSshConnectTimeoutMs | quote }} HDFS_HA_ZOOKEEPER_SESSION_TIMEOUT_MS: {{ .Values.hdfs.ha.zookeeper.sessionTimeoutMs | quote }} HDFS_HA_ZOOKEEPER_OPERATION_RETRIES: {{ .Values.hdfs.ha.zookeeper.operationRetries | quote }} HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} + HDFS_HA_LOG_ROLL_PERIOD: {{ .Values.hdfs.namenode.haLogRollPeriod | quote }} + HDFS_HA_TAIL_EDITS_PERIOD: {{ .Values.hdfs.namenode.haTailEditsPeriod | quote }} {{- else }} HDFS_REPLICATION: "1" HDFS_REPLICATION_MAX: "1" @@ -157,6 +176,10 @@ - name: hdfs-common-config variables: HDFS_TRASH_INTERVAL: {{ .Values.hdfs.trash.interval | quote }} + HDFS_HADOOP_TMP_DIR: {{ .Values.hdfs.core.hadoopTmpDir | quote }} + HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} + HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} + HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} @@ -177,8 +200,12 @@ HDFS_NAMENODE_RPC_PORT: {{ .Values.hdfs.ports.namenode.rpc | quote }} HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.ports.namenode.http | quote }} HDFS_DATANODE_HANDLER_COUNT: {{ .Values.hdfs.datanode.handlerCount | quote }} + HDFS_DATANODE_FAILED_VOLUMES_TOLERATED: {{ .Values.hdfs.datanode.failedVolumesTolerated | quote }} + HDFS_DATANODE_DU_RESERVED: {{ .Values.hdfs.datanode.duReserved | quote }} HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissions.enabled | quote }} HDFS_HA_NAMENODE_IDS: {{ .Values.hdfs.ha.nameNodeIds | quote }} + HDFS_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.retryPolicyEnabled | quote }} + HDFS_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.retryPolicySpec | quote }} {{- if $isCluster }} HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} HDFS_REPLICATION_MAX: {{ .Values.hdfs.replicationMax | quote }} diff --git a/addons-cluster/hadoop/values.schema.json b/addons-cluster/hadoop/values.schema.json index b0c35f3bda..582a349f0d 100644 --- a/addons-cluster/hadoop/values.schema.json +++ b/addons-cluster/hadoop/values.schema.json @@ -63,7 +63,14 @@ "journalnodeEditsDir": { "type": "string", "default": "/hadoop/dfs/journal" } } }, - "replication": { "type": "integer", "default": 1, "minimum": 1 }, + "core": { + "type": "object", + "properties": { + "hadoopTmpDir": { "type": "string", "default": "/hadoop/tmp" } + } + }, + "replication": { "type": "integer", "default": 1, "minimum": 1 }, + "replicationMax": { "type": "integer", "default": 6, "minimum": 1 }, "client": { "type": "object", "properties": { @@ -71,13 +78,23 @@ "type": "string", "enum": ["NEVER", "DEFAULT", "ALWAYS"], "default": "NEVER" - } + }, + "retryPolicyEnabled": { "type": "boolean", "default": true }, + "retryPolicySpec": { "type": "string", "default": "1000,1" } } }, "permissions": { "type": "object", "properties": { - "enabled": { "type": "boolean", "default": false } + "enabled": { "type": "boolean", "default": false }, + "superusergroup": { "type": "string", "default": "hadoop" } + } + }, + "security": { + "type": "object", + "properties": { + "authentication": { "type": "string", "default": "simple" }, + "authorization": { "type": "boolean", "default": false } } }, "registration": { @@ -89,8 +106,10 @@ "ha": { "type": "object", "properties": { + "nameNodeIds": { "type": "string", "default": "nn0,nn1" }, "automaticFailoverEnabled": { "type": "boolean", "default": true }, "fencingMethods": { "type": "string", "default": "shell(/bin/true)" }, + "fencingSshConnectTimeoutMs": { "type": "integer", "default": 30000, "minimum": 1 }, "zookeeper": { "type": "object", "properties": { @@ -102,6 +121,14 @@ } } }, + "journalnode": { + "type": "object", + "properties": { + "enableSync": { "type": "boolean", "default": true }, + "editCacheSizeBytes": { "type": "integer", "default": 104857600, "minimum": 1 }, + "syncIntervalMs": { "type": "integer", "default": 120000, "minimum": 1 } + } + }, "ipc": { "type": "object", "properties": { @@ -112,6 +139,24 @@ "clientPing": { "type": "boolean", "default": true }, "pingIntervalMs": { "type": "integer", "default": 30000, "minimum": 1 } } + }, + "namenode": { + "type": "object", + "properties": { + "handlerCount": { "type": "integer", "default": 64, "minimum": 1 }, + "webhdfsEnabled": { "type": "boolean", "default": false }, + "resourceDuReserved": { "type": "integer", "default": 1073741824, "minimum": 0 }, + "haLogRollPeriod": { "type": "integer", "default": 120, "minimum": 0 }, + "haTailEditsPeriod": { "type": "integer", "default": 60, "minimum": 0 } + } + }, + "datanode": { + "type": "object", + "properties": { + "handlerCount": { "type": "integer", "default": 64, "minimum": 1 }, + "failedVolumesTolerated": { "type": "integer", "default": 0, "minimum": 0 }, + "duReserved": { "type": "integer", "default": 1073741824, "minimum": 0 } + } } } }, diff --git a/addons-cluster/hadoop/values.yaml b/addons-cluster/hadoop/values.yaml index ba711847a2..c6597e05d3 100644 --- a/addons-cluster/hadoop/values.yaml +++ b/addons-cluster/hadoop/values.yaml @@ -53,6 +53,11 @@ storage: - ReadWriteOnce hdfs: + core: + hadoopTmpDir: /hadoop/tmp + security: + authentication: simple + authorization: false ports: namenode: rpc: 8020 @@ -65,16 +70,21 @@ hdfs: datanodeDataDir: /hadoop/dfs/data0 journalnodeEditsDir: /hadoop/dfs/journal replication: 3 + replicationMax: 6 client: replaceDatanodeOnFailurePolicy: DEFAULT + retryPolicyEnabled: true + retryPolicySpec: "1000,1" permissions: enabled: false + superusergroup: hadoop registration: ipHostnameCheck: false ha: nameNodeIds: "nn0,nn1" automaticFailoverEnabled: true fencingMethods: "sshfence\nshell(/bin/true)" + fencingSshConnectTimeoutMs: 30000 zookeeper: parentZnodePrefix: /hadoop-ha includeClusterUID: true @@ -96,8 +106,18 @@ hdfs: zkfcHeapSize: "256m" datanode: handlerCount: 64 + failedVolumesTolerated: 0 + duReserved: 1073741824 namenode: handlerCount: 64 + webhdfsEnabled: false + resourceDuReserved: 1073741824 + haLogRollPeriod: 120 + haTailEditsPeriod: 60 + journalnode: + enableSync: true + editCacheSizeBytes: 104857600 + syncIntervalMs: 120000 serviceRefs: hadoopZookeeper: diff --git a/addons-cluster/hbase/templates/cluster.yaml b/addons-cluster/hbase/templates/cluster.yaml index 919a45f088..a2fa20b47e 100644 --- a/addons-cluster/hbase/templates/cluster.yaml +++ b/addons-cluster/hbase/templates/cluster.yaml @@ -38,6 +38,46 @@ HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.namenodeHttpPort | quote }} HDFS_HA_ZK_PARENT: {{ .Values.hdfs.haZkParent | quote }} HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} + HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissionsEnabled | quote }} + HDFS_FS_TRASH_INTERVAL: {{ .Values.hdfs.fs.trashInterval | quote }} + HADOOP_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} + HADOOP_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} + HADOOP_IPC_CLIENT_CONNECTION_MAXIDLETIME: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTime | quote }} + HADOOP_IPC_CLIENT_CONNECT_TIMEOUT: {{ .Values.hdfs.ipc.clientConnectTimeout | quote }} + HADOOP_IPC_PING_INTERVAL: {{ .Values.hdfs.ipc.pingInterval | quote }} + HADOOP_TMP_DIR: {{ .Values.hdfs.paths.tmpDir | quote }} + HDFS_COMMON_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.commonRetryPolicy.enabled | quote }} + HDFS_COMMON_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.commonRetryPolicy.spec | quote }} + HDFS_WEBHDFS_ENABLED: {{ .Values.hdfs.client.webhdfsEnabled | quote }} + HDFS_CLIENT_FAILOVER_MAX_ATTEMPTS: {{ .Values.hdfs.client.failoverMaxAttempts | quote }} + HDFS_CLIENT_FAILOVER_SLEEP_BASE_MILLIS: {{ .Values.hdfs.client.failoverSleepBaseMillis | quote }} + HDFS_CLIENT_FAILOVER_SLEEP_MAX_MILLIS: {{ .Values.hdfs.client.failoverSleepMaxMillis | quote }} + HBASE_HDFS_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.retryPolicy.enabled | quote }} + HBASE_HDFS_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.retryPolicy.spec | quote }} + HBASE_IPC_CLIENT_CONNECT_TIMEOUT: {{ .Values.hdfs.hbaseClient.ipcClientConnectTimeout | quote }} + HBASE_IPC_CLIENT_CONNECT_MAX_RETRIES: {{ .Values.hdfs.hbaseClient.ipcClientConnectMaxRetries | quote }} + HBASE_ZOOKEEPER_SESSION_TIMEOUT: {{ .Values.hbase.zk.sessionTimeout | quote }} + HBASE_ZOOKEEPER_MAX_CLIENT_CNXNS: {{ .Values.hbase.zk.maxClientCnxns | quote }} + HBASE_REGIONSERVER_HANDLER_COUNT: {{ .Values.hbase.cluster.regionserverHandlerCount | quote }} + HBASE_HSTORE_FLUSHER_COUNT: {{ .Values.hbase.cluster.hstoreFlusherCount | quote }} + HBASE_CLIENT_SCANNER_CACHING: {{ .Values.hbase.common.clientScannerCaching | quote }} + HBASE_HREGION_MAX_FILESIZE: {{ .Values.hbase.cluster.regionMaxFileSize | quote }} + HBASE_HREGION_MEMSTORE_FLUSH_SIZE: {{ .Values.hbase.common.regionMemstoreFlushSize | quote }} + HBASE_HREGION_MAJORCOMPACTION: {{ .Values.hbase.cluster.regionMajorCompaction | quote }} + HBASE_MASTER_WAIT_ON_REGIONSERVERS_TIMEOUT: {{ .Values.hbase.cluster.masterWaitOnRegionserversTimeout | quote }} + HBASE_MASTER_STARTUP_RETAINASSIGN_TIMEOUT: {{ .Values.hbase.cluster.masterStartupRetainassignTimeout | quote }} + HBASE_OLDWALS_CLEANER_THREAD_TIMEOUT_MSEC: {{ .Values.hbase.cluster.oldWalsCleanerThreadTimeoutMsec | quote }} + HBASE_MASTER_LOGCLEANER_TTL: {{ .Values.hbase.cluster.masterLogCleanerTtl | quote }} + HBASE_MASTER_HFILECLEANER_TTL: {{ .Values.hbase.cluster.masterHfileCleanerTtl | quote }} + HBASE_BALANCER_PERIOD: {{ .Values.hbase.cluster.balancerPeriod | quote }} + HBASE_PROCEDURE_STORE_WAL_USE_HSYNC: {{ .Values.hbase.cluster.procedureStoreWalUseHsync | quote }} + HBASE_REGIONSERVER_OPTIONALCACHEFLUSHINTERVAL: {{ .Values.hbase.cluster.regionserverOptionalCacheFlushInterval | quote }} + HBASE_REGIONSERVER_STARTUP_RETRIES: {{ .Values.hbase.cluster.regionserverStartupRetries | quote }} + HBASE_REGIONSERVER_STARTUP_RETRY_INTERVAL: {{ .Values.hbase.cluster.regionserverStartupRetryInterval | quote }} + HBASE_REPLICATION_ENABLED: {{ .Values.hbase.cluster.replicationEnabled | quote }} + HBASE_SECURITY_AUTHENTICATION: {{ .Values.hbase.security.authentication | quote }} + HBASE_SECURITY_AUTHORIZATION: {{ .Values.hbase.security.authorization | quote }} + HBASE_SPLITLOG_MANAGER_TIMEOUT: {{ .Values.hbase.cluster.splitlogManagerTimeout | quote }} resources: requests: cpu: {{ .Values.resources.hmaster.requests.cpu | quote }} @@ -83,6 +123,46 @@ HDFS_NAMENODE_HTTP_PORT: {{ .Values.hdfs.namenodeHttpPort | quote }} HDFS_HA_ZK_PARENT: {{ .Values.hdfs.haZkParent | quote }} HDFS_REPLICATION: {{ .Values.hdfs.replication | quote }} + HDFS_PERMISSIONS_ENABLED: {{ .Values.hdfs.permissionsEnabled | quote }} + HDFS_FS_TRASH_INTERVAL: {{ .Values.hdfs.fs.trashInterval | quote }} + HADOOP_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} + HADOOP_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} + HADOOP_IPC_CLIENT_CONNECTION_MAXIDLETIME: {{ .Values.hdfs.ipc.clientConnectionMaxIdleTime | quote }} + HADOOP_IPC_CLIENT_CONNECT_TIMEOUT: {{ .Values.hdfs.ipc.clientConnectTimeout | quote }} + HADOOP_IPC_PING_INTERVAL: {{ .Values.hdfs.ipc.pingInterval | quote }} + HADOOP_TMP_DIR: {{ .Values.hdfs.paths.tmpDir | quote }} + HDFS_COMMON_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.commonRetryPolicy.enabled | quote }} + HDFS_COMMON_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.commonRetryPolicy.spec | quote }} + HDFS_WEBHDFS_ENABLED: {{ .Values.hdfs.client.webhdfsEnabled | quote }} + HDFS_CLIENT_FAILOVER_MAX_ATTEMPTS: {{ .Values.hdfs.client.failoverMaxAttempts | quote }} + HDFS_CLIENT_FAILOVER_SLEEP_BASE_MILLIS: {{ .Values.hdfs.client.failoverSleepBaseMillis | quote }} + HDFS_CLIENT_FAILOVER_SLEEP_MAX_MILLIS: {{ .Values.hdfs.client.failoverSleepMaxMillis | quote }} + HBASE_HDFS_CLIENT_RETRY_POLICY_ENABLED: {{ .Values.hdfs.client.retryPolicy.enabled | quote }} + HBASE_HDFS_CLIENT_RETRY_POLICY_SPEC: {{ .Values.hdfs.client.retryPolicy.spec | quote }} + HBASE_IPC_CLIENT_CONNECT_TIMEOUT: {{ .Values.hdfs.hbaseClient.ipcClientConnectTimeout | quote }} + HBASE_IPC_CLIENT_CONNECT_MAX_RETRIES: {{ .Values.hdfs.hbaseClient.ipcClientConnectMaxRetries | quote }} + HBASE_ZOOKEEPER_SESSION_TIMEOUT: {{ .Values.hbase.zk.sessionTimeout | quote }} + HBASE_ZOOKEEPER_MAX_CLIENT_CNXNS: {{ .Values.hbase.zk.maxClientCnxns | quote }} + HBASE_REGIONSERVER_HANDLER_COUNT: {{ .Values.hbase.cluster.regionserverHandlerCount | quote }} + HBASE_HSTORE_FLUSHER_COUNT: {{ .Values.hbase.cluster.hstoreFlusherCount | quote }} + HBASE_CLIENT_SCANNER_CACHING: {{ .Values.hbase.common.clientScannerCaching | quote }} + HBASE_HREGION_MAX_FILESIZE: {{ .Values.hbase.cluster.regionMaxFileSize | quote }} + HBASE_HREGION_MEMSTORE_FLUSH_SIZE: {{ .Values.hbase.common.regionMemstoreFlushSize | quote }} + HBASE_HREGION_MAJORCOMPACTION: {{ .Values.hbase.cluster.regionMajorCompaction | quote }} + HBASE_MASTER_WAIT_ON_REGIONSERVERS_TIMEOUT: {{ .Values.hbase.cluster.masterWaitOnRegionserversTimeout | quote }} + HBASE_MASTER_STARTUP_RETAINASSIGN_TIMEOUT: {{ .Values.hbase.cluster.masterStartupRetainassignTimeout | quote }} + HBASE_OLDWALS_CLEANER_THREAD_TIMEOUT_MSEC: {{ .Values.hbase.cluster.oldWalsCleanerThreadTimeoutMsec | quote }} + HBASE_MASTER_LOGCLEANER_TTL: {{ .Values.hbase.cluster.masterLogCleanerTtl | quote }} + HBASE_MASTER_HFILECLEANER_TTL: {{ .Values.hbase.cluster.masterHfileCleanerTtl | quote }} + HBASE_BALANCER_PERIOD: {{ .Values.hbase.cluster.balancerPeriod | quote }} + HBASE_PROCEDURE_STORE_WAL_USE_HSYNC: {{ .Values.hbase.cluster.procedureStoreWalUseHsync | quote }} + HBASE_REGIONSERVER_OPTIONALCACHEFLUSHINTERVAL: {{ .Values.hbase.cluster.regionserverOptionalCacheFlushInterval | quote }} + HBASE_REGIONSERVER_STARTUP_RETRIES: {{ .Values.hbase.cluster.regionserverStartupRetries | quote }} + HBASE_REGIONSERVER_STARTUP_RETRY_INTERVAL: {{ .Values.hbase.cluster.regionserverStartupRetryInterval | quote }} + HBASE_REPLICATION_ENABLED: {{ .Values.hbase.cluster.replicationEnabled | quote }} + HBASE_SECURITY_AUTHENTICATION: {{ .Values.hbase.security.authentication | quote }} + HBASE_SECURITY_AUTHORIZATION: {{ .Values.hbase.security.authorization | quote }} + HBASE_SPLITLOG_MANAGER_TIMEOUT: {{ .Values.hbase.cluster.splitlogManagerTimeout | quote }} resources: requests: cpu: {{ .Values.resources.hregionserver.requests.cpu | quote }} @@ -112,6 +192,20 @@ component: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.component }} service: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.service }} port: {{ .Values.serviceRefs.hbaseZookeeper.clusterServiceSelector.service.port }} + configs: + - name: hbase-standalone-config + variables: + HBASE_ZOOKEEPER_SESSION_TIMEOUT: {{ .Values.hbase.zk.sessionTimeout | quote }} + HBASE_ZOOKEEPER_MAX_CLIENT_CNXNS: {{ .Values.hbase.zk.maxClientCnxns | quote }} + HBASE_REGIONSERVER_HANDLER_COUNT: {{ .Values.hbase.standalone.regionserverHandlerCount | quote }} + HBASE_HSTORE_FLUSHER_COUNT: {{ .Values.hbase.standalone.hstoreFlusherCount | quote }} + HBASE_CLIENT_SCANNER_CACHING: {{ .Values.hbase.common.clientScannerCaching | quote }} + HBASE_HREGION_MAX_FILESIZE: {{ .Values.hbase.standalone.regionMaxFileSize | quote }} + HBASE_HREGION_MEMSTORE_FLUSH_SIZE: {{ .Values.hbase.common.regionMemstoreFlushSize | quote }} + HBASE_PROCEDURE_STORE_WAL_USE_HSYNC: {{ .Values.hbase.standalone.procedureStoreWalUseHsync | quote }} + HBASE_REPLICATION_ENABLED: {{ .Values.hbase.standalone.replicationEnabled | quote }} + HBASE_SECURITY_AUTHENTICATION: {{ .Values.hbase.security.authentication | quote }} + HBASE_SECURITY_AUTHORIZATION: {{ .Values.hbase.security.authorization | quote }} resources: requests: cpu: {{ .Values.resources.hbasestandalone.requests.cpu | quote }} diff --git a/addons-cluster/hbase/values.schema.json b/addons-cluster/hbase/values.schema.json index dae56e3984..a0b125e1d6 100644 --- a/addons-cluster/hbase/values.schema.json +++ b/addons-cluster/hbase/values.schema.json @@ -94,6 +94,286 @@ "replication": { "type": "string", "default": "3" + }, + "permissionsEnabled": { + "type": "boolean", + "default": false + }, + "fs": { + "type": "object", + "properties": { + "trashInterval": { + "type": "integer", + "default": 1440, + "minimum": 0 + } + } + }, + "security": { + "type": "object", + "properties": { + "authentication": { + "type": "string", + "default": "simple" + }, + "authorization": { + "type": "boolean", + "default": false + } + } + }, + "ipc": { + "type": "object", + "properties": { + "clientConnectionMaxIdleTime": { + "type": "integer", + "default": 30000, + "minimum": 0 + }, + "clientConnectTimeout": { + "type": "integer", + "default": 10000, + "minimum": 1 + }, + "pingInterval": { + "type": "integer", + "default": 60000, + "minimum": 1 + } + } + }, + "paths": { + "type": "object", + "properties": { + "tmpDir": { + "type": "string", + "default": "/hadoop/tmp" + } + } + }, + "client": { + "type": "object", + "properties": { + "webhdfsEnabled": { + "type": "boolean", + "default": false + }, + "failoverMaxAttempts": { + "type": "integer", + "default": 15, + "minimum": 1 + }, + "failoverSleepBaseMillis": { + "type": "integer", + "default": 500, + "minimum": 0 + }, + "failoverSleepMaxMillis": { + "type": "integer", + "default": 15000, + "minimum": 0 + }, + "retryPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "spec": { + "type": "string", + "default": "10000,6,60000,10" + } + } + }, + "commonRetryPolicy": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": true + }, + "spec": { + "type": "string", + "default": "1000,1" + } + } + } + } + }, + "hbaseClient": { + "type": "object", + "properties": { + "ipcClientConnectTimeout": { + "type": "integer", + "default": 30000, + "minimum": 1 + }, + "ipcClientConnectMaxRetries": { + "type": "integer", + "default": 10, + "minimum": 0 + } + } + } + } + }, + "hbase": { + "type": "object", + "properties": { + "zk": { + "type": "object", + "properties": { + "sessionTimeout": { + "type": "integer", + "default": 30000, + "minimum": 1 + }, + "maxClientCnxns": { + "type": "integer", + "default": 4000, + "minimum": 1 + } + } + }, + "security": { + "type": "object", + "properties": { + "authentication": { + "type": "string", + "default": "simple" + }, + "authorization": { + "type": "boolean", + "default": false + } + } + }, + "common": { + "type": "object", + "properties": { + "clientScannerCaching": { + "type": "integer", + "default": 100, + "minimum": 1 + }, + "regionMemstoreFlushSize": { + "type": "integer", + "default": 134217728, + "minimum": 1 + } + } + }, + "cluster": { + "type": "object", + "properties": { + "regionserverHandlerCount": { + "type": "integer", + "default": 100, + "minimum": 1 + }, + "hstoreFlusherCount": { + "type": "integer", + "default": 4, + "minimum": 1 + }, + "regionMaxFileSize": { + "type": "integer", + "default": 53687091200, + "minimum": 1 + }, + "regionMajorCompaction": { + "type": "integer", + "default": 0, + "minimum": 0 + }, + "masterWaitOnRegionserversTimeout": { + "type": "integer", + "default": 300000, + "minimum": 0 + }, + "masterStartupRetainassignTimeout": { + "type": "integer", + "default": 300000, + "minimum": 0 + }, + "oldWalsCleanerThreadTimeoutMsec": { + "type": "integer", + "default": 60000, + "minimum": 0 + }, + "masterLogCleanerTtl": { + "type": "integer", + "default": 60000, + "minimum": 0 + }, + "masterHfileCleanerTtl": { + "type": "integer", + "default": 600000, + "minimum": 0 + }, + "balancerPeriod": { + "type": "integer", + "default": 1800000, + "minimum": 0 + }, + "procedureStoreWalUseHsync": { + "type": "boolean", + "default": true + }, + "regionserverOptionalCacheFlushInterval": { + "type": "integer", + "default": 28800000, + "minimum": 0 + }, + "regionserverStartupRetries": { + "type": "integer", + "default": 10, + "minimum": 0 + }, + "regionserverStartupRetryInterval": { + "type": "integer", + "default": 10000, + "minimum": 0 + }, + "replicationEnabled": { + "type": "boolean", + "default": true + }, + "splitlogManagerTimeout": { + "type": "integer", + "default": 600000, + "minimum": 0 + } + } + }, + "standalone": { + "type": "object", + "properties": { + "regionserverHandlerCount": { + "type": "integer", + "default": 30, + "minimum": 1 + }, + "hstoreFlusherCount": { + "type": "integer", + "default": 2, + "minimum": 1 + }, + "regionMaxFileSize": { + "type": "integer", + "default": 10737418240, + "minimum": 1 + }, + "procedureStoreWalUseHsync": { + "type": "boolean", + "default": false + }, + "replicationEnabled": { + "type": "boolean", + "default": false + } + } } } } diff --git a/addons-cluster/hbase/values.yaml b/addons-cluster/hbase/values.yaml index 5c66060bab..74b5dc9701 100644 --- a/addons-cluster/hbase/values.yaml +++ b/addons-cluster/hbase/values.yaml @@ -56,6 +56,66 @@ hdfs: namenodeHttpPort: 9870 haZkParent: /hadoop-ha replication: "3" + permissionsEnabled: false + fs: + trashInterval: 1440 + security: + authentication: simple + authorization: false + ipc: + clientConnectionMaxIdleTime: 30000 + clientConnectTimeout: 10000 + pingInterval: 60000 + paths: + tmpDir: /hadoop/tmp + client: + webhdfsEnabled: false + failoverMaxAttempts: 15 + failoverSleepBaseMillis: 500 + failoverSleepMaxMillis: 15000 + retryPolicy: + enabled: true + spec: "10000,6,60000,10" + commonRetryPolicy: + enabled: true + spec: "1000,1" + hbaseClient: + ipcClientConnectTimeout: 30000 + ipcClientConnectMaxRetries: 10 + +hbase: + zk: + sessionTimeout: 30000 + maxClientCnxns: 4000 + security: + authentication: simple + authorization: false + common: + clientScannerCaching: 100 + regionMemstoreFlushSize: 134217728 + cluster: + regionserverHandlerCount: 100 + hstoreFlusherCount: 4 + regionMaxFileSize: 53687091200 + regionMajorCompaction: 0 + masterWaitOnRegionserversTimeout: 300000 + masterStartupRetainassignTimeout: 300000 + oldWalsCleanerThreadTimeoutMsec: 60000 + masterLogCleanerTtl: 60000 + masterHfileCleanerTtl: 600000 + balancerPeriod: 1800000 + procedureStoreWalUseHsync: true + regionserverOptionalCacheFlushInterval: 28800000 + regionserverStartupRetries: 10 + regionserverStartupRetryInterval: 10000 + replicationEnabled: true + splitlogManagerTimeout: 600000 + standalone: + regionserverHandlerCount: 30 + hstoreFlusherCount: 2 + regionMaxFileSize: 10737418240 + procedureStoreWalUseHsync: false + replicationEnabled: false extra: terminationPolicy: Delete diff --git a/addons/hadoop/README.md b/addons/hadoop/README.md index 21ecea81a6..9c8ba109b0 100644 --- a/addons/hadoop/README.md +++ b/addons/hadoop/README.md @@ -1,33 +1,277 @@ # Hadoop HDFS Addon for KubeBlocks +[中文说明](./README.zh-CN.md) + +This document describes what the Hadoop HDFS addon provides, how it is structured, what configuration surfaces are available today, and what was added recently for deploy-time configuration through the cluster chart. + ## Overview -This addon provides Hadoop HDFS support on KubeBlocks, including: +The Hadoop addon under `addons/hadoop` provides HDFS on KubeBlocks with: + +- `cluster` topology: `journalnode + namenode + datanode` +- `standalone` topology: `namenode + datanode` +- ZooKeeper-backed HA failover for cluster mode +- configurable DataNode `hostNetwork` +- standard parameter management resources in the addon itself: + - `ParametersDefinition` + - `ParamConfigRenderer` + - CUE config constraints +- an additional deploy-time configuration surface in `addons-cluster/hadoop` + +Supported service version: + +| Major Version | Actual Version | +|---------------|----------------| +| 3.3 | 3.3.4 | + +## What This Addon Contains + +The addon package under `addons/hadoop` defines: + +- `ClusterDefinition` named `hadoop` +- component definitions for: + - `hdfs-journalnode` + - `hdfs-namenode` + - `hdfs-namenode-standalone` + - `hdfs-datanode` + - `hdfs-datanode-standalone` +- component versions for NameNode, DataNode, and JournalNode +- config templates for: + - `core-site.xml` + - `hdfs-site.xml` + - `hadoop-env.sh` + - `hadoop-metrics2.properties` +- startup and init scripts for NameNode, DataNode, JournalNode, and ZKFC +- parameter management resources: + - `paramsdef-hdfs-common.yaml` + - `paramsdef-hdfs-namenode.yaml` + - `paramsdef-hdfs-datanode.yaml` + - `paramsdef-hdfs-journalnode.yaml` + - corresponding `pcr-*` resources + +The deployable cluster chart under `addons-cluster/hadoop` provides a ready-to-use `Cluster` manifest and exposes a first batch of deploy-time overrides through `values.yaml`. -- **HA Cluster Topology**: 3-component architecture (journalnode, namenode, datanode) -- **ZooKeeper Integration**: Automatic failover via ZK service reference -- **Host Network**: DataNode supports hostNetwork for optimal I/O performance -- **Configuration Management**: Dynamic parameter tuning via Parameters API +## Topologies -## Components +### Cluster Topology + +Cluster mode is the default topology and contains: | Component | Role | Default Replicas | -|-----------|------|-----------------| -| hdfs-journalnode | HA Journal | 3 | -| hdfs-namenode | NameNode (nn0/nn1) | 2 | -| hdfs-datanode | DataNode (hostNetwork) | 1 | +|-----------|------|------------------| +| `journalnode` | quorum journal for HA edits | 3 | +| `namenode` | active/standby NameNode pair | 2 | +| `datanode` | HDFS data service | 3 | + +Behavior notes: + +- HA is implemented as active/standby NameNode, not arbitrary multi-NN observer mode. +- `hdfs.ha.nameNodeIds` is configurable, but cluster mode currently requires exactly 2 entries. +- JournalNode count is not hard-coded to 3 by template logic, but odd replica counts such as 3 or 5 remain the practical recommendation. +- DataNode count is a deployment default, not an addon hard limit. + +### Standalone Topology + +Standalone mode contains: + +| Component | Role | Default Replicas | +|-----------|------|------------------| +| `namenode` | local NameNode | 1 | +| `datanode` | local DataNode | 1 | + +This topology is intended for development, smoke testing, and functional verification. + +## Prerequisites + +- Kubernetes >= v1.21 +- KubeBlocks >= 1.1 +- the Hadoop addon installed +- a ZooKeeper cluster available when using `cluster` topology +- a dedicated namespace is recommended, for example: + +```bash +kubectl create ns demo +``` + +## Configuration Surfaces + +There are two different configuration surfaces in this repository. + +### 1. Standard KubeBlocks Parameter Management in the Addon + +The addon itself already contains standard parameter-management artifacts: + +- `ParametersDefinition` +- `ParamConfigRenderer` +- CUE constraints + +These resources are defined in `addons/hadoop/templates/paramsdef-*` and `addons/hadoop/templates/pcr-*`. + +This means the addon is not limited to raw static config templates. The standard KubeBlocks parameter chain already exists for addon-managed configuration files such as: + +- `hdfs-common-config` +- `namenode-config` +- `datanode-config` +- `journalnode-config` + +### 2. Deploy-Time Overrides in the Cluster Chart + +In addition, `addons-cluster/hadoop` now exposes a first batch of deploy-time values that flow through: + +`values.yaml -> templates/cluster.yaml -> configs.variables -> runtime config templates` + +This deploy-time surface is useful for: + +- environment-specific defaults +- cluster bootstrap-time sizing +- HA/network/security knobs that should be set before the cluster starts + +## Newly Exposed Deploy-Time Values + +The cluster chart now exposes deploy-time overrides for the following groups. + +| Value Path | Purpose | +|------------|---------| +| `hdfs.core.hadoopTmpDir` | `hadoop.tmp.dir` | +| `hdfs.security.authentication` | Hadoop auth mode | +| `hdfs.security.authorization` | Hadoop authorization switch | +| `hdfs.client.retryPolicyEnabled` | client retry enablement | +| `hdfs.client.retryPolicySpec` | retry policy spec | +| `hdfs.permissions.superusergroup` | HDFS superuser group | +| `hdfs.ha.nameNodeIds` | configurable HA NameNode IDs | +| `hdfs.ha.fencingSshConnectTimeoutMs` | fencing SSH timeout | +| `hdfs.namenode.webhdfsEnabled` | WebHDFS switch | +| `hdfs.namenode.resourceDuReserved` | NameNode reserved local disk | +| `hdfs.namenode.haLogRollPeriod` | HA log roll period | +| `hdfs.namenode.haTailEditsPeriod` | HA tail edits period | +| `hdfs.datanode.failedVolumesTolerated` | tolerated failed volumes | +| `hdfs.datanode.duReserved` | DataNode reserved disk | +| `hdfs.journalnode.enableSync` | JournalNode sync switch | +| `hdfs.journalnode.editCacheSizeBytes` | JournalNode edit cache size | +| `hdfs.journalnode.syncIntervalMs` | JournalNode sync interval | +| `hdfs.replicationMax` | `dfs.replication.max` | + +The deploy-time defaults live in: + +- `addons-cluster/hadoop/values.yaml` +- `addons-cluster/hadoop/values.schema.json` + +## Config Templates + +The addon renders different template files for different components and topologies. + +| Source Template | Rendered File | Used By | Purpose | +|----------------|---------------|---------|---------| +| `config/core-site.tpl` | `core-site.xml` | cluster components | common Hadoop client settings for cluster mode | +| `config/core-site-standalone.tpl` | `core-site.xml` | standalone components | common Hadoop client settings for standalone mode | +| `config/hdfs-namenode.tpl` | `hdfs-site.xml` | cluster NameNode | HA NameNode configuration | +| `config/hdfs-namenode-standalone.tpl` | `hdfs-site.xml` | standalone NameNode | standalone NameNode configuration | +| `config/hdfs-datanode.tpl` | `hdfs-site.xml` | cluster DataNode | HA-aware DataNode configuration | +| `config/hdfs-datanode-standalone.tpl` | `hdfs-site.xml` | standalone DataNode | standalone DataNode configuration | +| `config/hdfs-journalnode.tpl` | `hdfs-site.xml` | JournalNode | JournalNode configuration | +| `config/hadoop-env.sh.tpl` | `hadoop-env.sh` | all components | runtime environment variables | + +## Runtime and Image Notes + +### DataNode Network Mode + +DataNode supports runtime network tuning through addon values: + +- `runtime.datanode.hostNetwork` +- `runtime.datanode.hostPID` +- `runtime.datanode.dnsPolicy` + +### NameNode and Init Container Images + +By default, NameNode init containers reuse the NameNode image unless explicitly overridden. + +Relevant values: + +- `nameNode.image.*` +- `nameNode.initImages.initNameNodeFormat.*` +- `nameNode.initImages.initZkfcFormat.*` + +This keeps the default path simple while still allowing custom init-container images when needed. + +## HA Notes and Current Limits + +Current HA behavior is intentionally conservative: + +- cluster topology enforces `replicas.namenode = 2` +- `hdfs.ha.nameNodeIds` must contain exactly 2 entries in cluster mode +- the NameNode startup script maps peer nodes by configured ID order +- standby bootstrap is guarded to avoid the old `OrderedReady` timing problem during initial bring-up + +This means the current addon supports configurable NameNode IDs for the existing 2NN active/standby model, not general N-way NameNode scaling. ## Quick Start +### Install the Addon + +From the repository root: + +```bash +helm install hadoop-addon ./addons/hadoop +``` + +### Deploy with the Cluster Chart + +Cluster mode: + ```bash -# Install addon -helm install hadoop kubeblocks-addons/hadoop +helm install hdfs-cluster ./addons-cluster/hadoop \ + -n demo \ + --create-namespace \ + --set topology=cluster \ + --set serviceRefs.hadoopZookeeper.namespace=kubeblocks \ + --set serviceRefs.hadoopZookeeper.clusterServiceSelector.cluster=zk +``` + +Standalone mode: + +```bash +helm install hdfs-standalone ./addons-cluster/hadoop \ + -n demo \ + --create-namespace \ + --set topology=standalone +``` + +### Example Deploy-Time Overrides + +```yaml +topology: cluster + +replicas: + journalnode: 3 + namenode: 2 + datanode: 3 -# Create cluster -helm install mycluster kubeblocks-addons-cluster/hadoop +hdfs: + core: + hadoopTmpDir: /hadoop/tmp + security: + authentication: simple + authorization: false + ha: + nameNodeIds: "nn0,nn1" + fencingSshConnectTimeoutMs: 30000 + namenode: + webhdfsEnabled: false + resourceDuReserved: 1073741824 + haLogRollPeriod: 120 + haTailEditsPeriod: 60 + datanode: + failedVolumesTolerated: 0 + duReserved: 1073741824 + journalnode: + enableSync: true + editCacheSizeBytes: 104857600 + syncIntervalMs: 120000 ``` -## Requirements +## Requirements and Caveats -- KubeBlocks >= 1.1.0 -- ZooKeeper cluster for HA coordination +- cluster mode requires ZooKeeper service references +- current HA implementation is strictly a 2NN active/standby model +- deploy-time values in `addons-cluster/hadoop` are not a replacement for the addon's standard parameter-management resources; they are an additional deployment convenience layer +- if you need environment-specific image layout or custom bootstrap images, use the image override fields instead of patching vendor manifests directly diff --git a/addons/hadoop/README.zh-CN.md b/addons/hadoop/README.zh-CN.md new file mode 100644 index 0000000000..09690067fe --- /dev/null +++ b/addons/hadoop/README.zh-CN.md @@ -0,0 +1,280 @@ +# Hadoop HDFS Addon for KubeBlocks + +[English](./README.md) + +本文档说明 `addons/hadoop` 当前提供的能力、拓扑结构、参数入口,以及 `addons-cluster/hadoop` 这次新增的部署阶段配置能力。 + +## 概览 + +`addons/hadoop` 当前提供: + +- `cluster` 拓扑:`journalnode + namenode + datanode` +- `standalone` 拓扑:`namenode + datanode` +- 基于 ZooKeeper 的 HDFS HA failover +- 可配置的 DataNode `hostNetwork` +- Addon 内置的标准参数管理链路: + - `ParametersDefinition` + - `ParamConfigRenderer` + - CUE config constraints +- `addons-cluster/hadoop` 中额外暴露的一批部署阶段可覆盖项 + +当前支持的服务版本: + +| 大版本 | 实际版本 | +|--------|----------| +| 3.3 | 3.3.4 | + +## Addon 当前包含的内容 + +`addons/hadoop` 目录定义了: + +- `ClusterDefinition`:`hadoop` +- 组件定义: + - `hdfs-journalnode` + - `hdfs-namenode` + - `hdfs-namenode-standalone` + - `hdfs-datanode` + - `hdfs-datanode-standalone` +- 组件版本定义:NameNode、DataNode、JournalNode +- 配置模板: + - `core-site.xml` + - `hdfs-site.xml` + - `hadoop-env.sh` + - `hadoop-metrics2.properties` +- NameNode、DataNode、JournalNode、ZKFC 的启动和初始化脚本 +- 标准参数管理资源: + - `paramsdef-hdfs-common.yaml` + - `paramsdef-hdfs-namenode.yaml` + - `paramsdef-hdfs-datanode.yaml` + - `paramsdef-hdfs-journalnode.yaml` + - 对应的 `pcr-*` 资源 + +`addons-cluster/hadoop` 目录则提供了一个可直接部署的 cluster chart,并通过 `values.yaml` 暴露了一批部署阶段参数。 + +## 拓扑说明 + +### Cluster 拓扑 + +Cluster 模式是默认拓扑,包含: + +| 组件 | 角色 | 默认副本数 | +|------|------|------------| +| `journalnode` | HA edits quorum | 3 | +| `namenode` | Active/Standby NameNode 对 | 2 | +| `datanode` | HDFS 数据服务 | 3 | + +行为说明: + +- 当前 HA 实现是 active/standby 2NN 模型,不是任意多 NameNode 的 observer 模式。 +- `hdfs.ha.nameNodeIds` 已支持配置,但 cluster 模式下当前强制要求正好 2 个条目。 +- JournalNode 模板能力本身没有写死只能 3 个,但工程上仍建议使用 3 或 5 这类奇数副本。 +- DataNode 副本数只是部署默认值,不是 addon 代码硬限制。 + +### Standalone 拓扑 + +Standalone 模式包含: + +| 组件 | 角色 | 默认副本数 | +|------|------|------------| +| `namenode` | 本地 NameNode | 1 | +| `datanode` | 本地 DataNode | 1 | + +该拓扑适合开发、冒烟验证和轻量功能测试。 + +## 前置条件 + +- Kubernetes >= v1.21 +- KubeBlocks >= 1.1 +- Hadoop addon 已安装 +- 使用 `cluster` 拓扑时,需要可用的 ZooKeeper 集群 +- 建议使用独立 namespace,例如: + +```bash +kubectl create ns demo +``` + +## 配置入口说明 + +当前仓库里有两类配置入口,需要分清楚。 + +### 1. Addon 内的标准参数管理链路 + +`addons/hadoop` 本身已经包含标准 KubeBlocks 参数链路: + +- `ParametersDefinition` +- `ParamConfigRenderer` +- CUE constraints + +这些资源定义在: + +- `addons/hadoop/templates/paramsdef-*` +- `addons/hadoop/templates/pcr-*` + +因此,README 不能简单理解成“只有静态配置模板”。Addon 自身已经具备标准参数管理能力,覆盖的配置集合包括: + +- `hdfs-common-config` +- `namenode-config` +- `datanode-config` +- `journalnode-config` + +### 2. Cluster Chart 的部署阶段覆盖入口 + +除此之外,`addons-cluster/hadoop` 这次新增了一批部署阶段参数,链路是: + +`values.yaml -> templates/cluster.yaml -> configs.variables -> runtime config templates` + +这层主要用于: + +- 环境差异化默认值 +- 集群首次部署时的容量和网络参数 +- 需要在启动前就确定的 HA / 安全 / 路径类参数 + +## 本次新增的部署阶段参数面 + +当前 cluster chart 已经暴露以下第一批参数: + +| 参数路径 | 作用 | +|----------|------| +| `hdfs.core.hadoopTmpDir` | `hadoop.tmp.dir` | +| `hdfs.security.authentication` | Hadoop 认证模式 | +| `hdfs.security.authorization` | Hadoop 鉴权开关 | +| `hdfs.client.retryPolicyEnabled` | 客户端重试开关 | +| `hdfs.client.retryPolicySpec` | 客户端重试策略 | +| `hdfs.permissions.superusergroup` | HDFS 超级用户组 | +| `hdfs.ha.nameNodeIds` | HA NameNode ID 列表 | +| `hdfs.ha.fencingSshConnectTimeoutMs` | fencing SSH 超时 | +| `hdfs.namenode.webhdfsEnabled` | WebHDFS 开关 | +| `hdfs.namenode.resourceDuReserved` | NameNode 本地保留磁盘 | +| `hdfs.namenode.haLogRollPeriod` | HA log roll 周期 | +| `hdfs.namenode.haTailEditsPeriod` | HA tail edits 周期 | +| `hdfs.datanode.failedVolumesTolerated` | 容忍坏盘数 | +| `hdfs.datanode.duReserved` | DataNode 保留磁盘 | +| `hdfs.journalnode.enableSync` | JournalNode sync 开关 | +| `hdfs.journalnode.editCacheSizeBytes` | JournalNode edit cache 大小 | +| `hdfs.journalnode.syncIntervalMs` | JournalNode sync 周期 | +| `hdfs.replicationMax` | `dfs.replication.max` | + +这些默认值和 schema 定义位于: + +- `addons-cluster/hadoop/values.yaml` +- `addons-cluster/hadoop/values.schema.json` + +## 配置模板与组件映射 + +当前 addon 会为不同组件和拓扑渲染不同模板: + +| 模板文件 | 最终文件 | 使用组件 | 作用 | +|----------|----------|----------|------| +| `config/core-site.tpl` | `core-site.xml` | cluster 组件 | cluster 模式下的 Hadoop 通用客户端配置 | +| `config/core-site-standalone.tpl` | `core-site.xml` | standalone 组件 | standalone 模式下的 Hadoop 通用客户端配置 | +| `config/hdfs-namenode.tpl` | `hdfs-site.xml` | cluster NameNode | HA NameNode 配置 | +| `config/hdfs-namenode-standalone.tpl` | `hdfs-site.xml` | standalone NameNode | standalone NameNode 配置 | +| `config/hdfs-datanode.tpl` | `hdfs-site.xml` | cluster DataNode | HA 感知的 DataNode 配置 | +| `config/hdfs-datanode-standalone.tpl` | `hdfs-site.xml` | standalone DataNode | standalone DataNode 配置 | +| `config/hdfs-journalnode.tpl` | `hdfs-site.xml` | JournalNode | JournalNode 配置 | +| `config/hadoop-env.sh.tpl` | `hadoop-env.sh` | 全部组件 | 运行时环境变量 | + +## 运行时与镜像说明 + +### DataNode 网络模式 + +DataNode 当前支持以下网络相关配置: + +- `runtime.datanode.hostNetwork` +- `runtime.datanode.hostPID` +- `runtime.datanode.dnsPolicy` + +### NameNode 与 initContainer 镜像 + +默认情况下,NameNode 的 initContainer 复用 NameNode 主镜像;如果有特殊需求,也支持单独覆盖。 + +相关参数为: + +- `nameNode.image.*` +- `nameNode.initImages.initNameNodeFormat.*` +- `nameNode.initImages.initZkfcFormat.*` + +这样做既保留了默认路径的简洁性,也支持在必要时做定制镜像切换。 + +## HA 说明与当前限制 + +当前 HA 设计是有意收敛的: + +- cluster 模式强制要求 `replicas.namenode = 2` +- cluster 模式下 `hdfs.ha.nameNodeIds` 必须正好包含 2 个条目 +- NameNode 启动脚本按配置列表顺序解析 peer,而不是依赖固定的 `nn0/nn1` 字面值 +- standby bootstrap 已做启动时序保护,避免首次拉起时再次遇到 `OrderedReady` 场景下的 bootstrapStandby 问题 + +因此,当前能力是“可配置 NameNode ID 的 2NN active/standby 模型”,不是通用 N 个 NameNode 横向扩展模型。 + +## 快速开始 + +### 安装 Addon + +在仓库根目录执行: + +```bash +helm install hadoop-addon ./addons/hadoop +``` + +### 使用 Cluster Chart 部署 + +Cluster 模式: + +```bash +helm install hdfs-cluster ./addons-cluster/hadoop \ + -n demo \ + --create-namespace \ + --set topology=cluster \ + --set serviceRefs.hadoopZookeeper.namespace=kubeblocks \ + --set serviceRefs.hadoopZookeeper.clusterServiceSelector.cluster=zk +``` + +Standalone 模式: + +```bash +helm install hdfs-standalone ./addons-cluster/hadoop \ + -n demo \ + --create-namespace \ + --set topology=standalone +``` + +### 部署阶段参数覆盖示例 + +```yaml +topology: cluster + +replicas: + journalnode: 3 + namenode: 2 + datanode: 3 + +hdfs: + core: + hadoopTmpDir: /hadoop/tmp + security: + authentication: simple + authorization: false + ha: + nameNodeIds: "nn0,nn1" + fencingSshConnectTimeoutMs: 30000 + namenode: + webhdfsEnabled: false + resourceDuReserved: 1073741824 + haLogRollPeriod: 120 + haTailEditsPeriod: 60 + datanode: + failedVolumesTolerated: 0 + duReserved: 1073741824 + journalnode: + enableSync: true + editCacheSizeBytes: 104857600 + syncIntervalMs: 120000 +``` + +## 注意事项 + +- cluster 模式依赖 ZooKeeper serviceRef +- 当前 HA 实现严格限定为 2NN active/standby +- `addons-cluster/hadoop` 里的 deploy-time values 不是对 addon 标准参数链路的替代,而是一层额外的部署便利入口 +- 如果需要按环境切换镜像或 initContainer 镜像,请使用 values 覆盖,不要直接改 vendor 产物 diff --git a/addons/hadoop/config/core-site-standalone.tpl b/addons/hadoop/config/core-site-standalone.tpl index d41458cbef..5a480d1cb6 100644 --- a/addons/hadoop/config/core-site-standalone.tpl +++ b/addons/hadoop/config/core-site-standalone.tpl @@ -15,7 +15,8 @@ io.compression.codecs - org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec + + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec @@ -25,12 +26,12 @@ hadoop.security.authentication - simple + {{- .HDFS_SECURITY_AUTHENTICATION }} hadoop.security.authorization - false + {{- .HDFS_SECURITY_AUTHORIZATION }} @@ -65,6 +66,6 @@ hadoop.tmp.dir - /hadoop/tmp + {{- .HDFS_HADOOP_TMP_DIR }} - + \ No newline at end of file diff --git a/addons/hadoop/config/core-site.tpl b/addons/hadoop/config/core-site.tpl index c7017df998..cd107b6213 100644 --- a/addons/hadoop/config/core-site.tpl +++ b/addons/hadoop/config/core-site.tpl @@ -14,7 +14,8 @@ io.compression.codecs - org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec + + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.io.compress.Lz4Codec @@ -39,12 +40,12 @@ hadoop.security.authentication - simple + {{- .HDFS_SECURITY_AUTHENTICATION }} hadoop.security.authorization - false + {{- .HDFS_SECURITY_AUTHORIZATION }} @@ -79,11 +80,11 @@ hadoop.tmp.dir - /hadoop/tmp + {{- .HDFS_HADOOP_TMP_DIR }} hadoop.home.dir /user - + \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-datanode-standalone.tpl b/addons/hadoop/config/hdfs-datanode-standalone.tpl index 1ec1f685f4..70393f2675 100644 --- a/addons/hadoop/config/hdfs-datanode-standalone.tpl +++ b/addons/hadoop/config/hdfs-datanode-standalone.tpl @@ -14,7 +14,7 @@ dfs.datanode.failed.volumes.tolerated - 0 + {{- .HDFS_DATANODE_FAILED_VOLUMES_TOLERATED }} @@ -44,7 +44,7 @@ dfs.datanode.du.reserved - 1073741824 + {{- .HDFS_DATANODE_DU_RESERVED }} @@ -90,11 +90,11 @@ dfs.client.retry.policy.enabled - true + {{- .HDFS_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 1000,1 + {{- .HDFS_CLIENT_RETRY_POLICY_SPEC }} \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-datanode.tpl b/addons/hadoop/config/hdfs-datanode.tpl index ff1838986a..e812de6cca 100644 --- a/addons/hadoop/config/hdfs-datanode.tpl +++ b/addons/hadoop/config/hdfs-datanode.tpl @@ -20,7 +20,7 @@ dfs.datanode.failed.volumes.tolerated - 0 + {{- .HDFS_DATANODE_FAILED_VOLUMES_TOLERATED }} @@ -50,7 +50,7 @@ dfs.datanode.du.reserved - 1073741824 + {{- .HDFS_DATANODE_DU_RESERVED }} @@ -106,11 +106,11 @@ dfs.client.retry.policy.enabled - true + {{- .HDFS_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 1000,1 + {{- .HDFS_CLIENT_RETRY_POLICY_SPEC }} \ No newline at end of file diff --git a/addons/hadoop/config/hdfs-journalnode.tpl b/addons/hadoop/config/hdfs-journalnode.tpl index bd3f1214a3..744afe4578 100644 --- a/addons/hadoop/config/hdfs-journalnode.tpl +++ b/addons/hadoop/config/hdfs-journalnode.tpl @@ -46,4 +46,19 @@ dfs.hosts.exclude {{- .HDFS_CONF_DIR }}/dfs.exclude + + + dfs.journalnode.enable.sync + {{- .HDFS_JOURNALNODE_ENABLE_SYNC }} + + + + dfs.journalnode.edit-cache-size.bytes + {{- .HDFS_JOURNALNODE_EDIT_CACHE_SIZE_BYTES }} + + + + dfs.journalnode.sync.interval + {{- .HDFS_JOURNALNODE_SYNC_INTERVAL_MS }} + diff --git a/addons/hadoop/config/hdfs-namenode-standalone.tpl b/addons/hadoop/config/hdfs-namenode-standalone.tpl index 6159dc67be..781c062272 100644 --- a/addons/hadoop/config/hdfs-namenode-standalone.tpl +++ b/addons/hadoop/config/hdfs-namenode-standalone.tpl @@ -34,7 +34,7 @@ dfs.permissions.superusergroup - hadoop + {{- .HDFS_PERMISSIONS_SUPERUSERGROUP }} @@ -74,16 +74,16 @@ dfs.webhdfs.enabled - false + {{- .HDFS_NAMENODE_WEBHDFS_ENABLED }} dfs.client.retry.policy.enabled - true + {{- .HDFS_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 1000,1 + {{- .HDFS_CLIENT_RETRY_POLICY_SPEC }} diff --git a/addons/hadoop/config/hdfs-namenode.tpl b/addons/hadoop/config/hdfs-namenode.tpl index cc0e2cbd8f..5294b97182 100644 --- a/addons/hadoop/config/hdfs-namenode.tpl +++ b/addons/hadoop/config/hdfs-namenode.tpl @@ -71,7 +71,7 @@ dfs.ha.fencing.ssh.connect-timeout - 30000 + {{- .HDFS_HA_FENCING_SSH_CONNECT_TIMEOUT_MS }} @@ -91,7 +91,7 @@ dfs.permissions.superusergroup - hadoop + {{- .HDFS_PERMISSIONS_SUPERUSERGROUP }} @@ -136,7 +136,7 @@ dfs.webhdfs.enabled - false + {{- .HDFS_NAMENODE_WEBHDFS_ENABLED }} @@ -156,17 +156,17 @@ dfs.namenode.resource.du.reserved - 1073741824 + {{- .HDFS_NAMENODE_RESOURCE_DU_RESERVED }} dfs.client.retry.policy.enabled - true + {{- .HDFS_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 1000,1 + {{- .HDFS_CLIENT_RETRY_POLICY_SPEC }} @@ -176,12 +176,12 @@ dfs.ha.log-roll.period - 120 + {{- .HDFS_HA_LOG_ROLL_PERIOD }} dfs.ha.tail-edits.period - 60 + {{- .HDFS_HA_TAIL_EDITS_PERIOD }} diff --git a/addons/hbase/README.md b/addons/hbase/README.md index 32a55c0829..8cbdf95e8c 100644 --- a/addons/hbase/README.md +++ b/addons/hbase/README.md @@ -1,31 +1,131 @@ # HBase -Apache HBase is an open-source, distributed, versioned, column-oriented store modeled after Google's Bigtable. This addon enables HBase cluster management on KubeBlocks. +[中文说明](./README.zh-CN.md) -## Features In KubeBlocks +Apache HBase is an open-source, distributed, versioned, column-oriented store modeled after Google's Bigtable. This addon enables HBase deployment and lifecycle management on KubeBlocks. -### Lifecycle Management +## Overview -| Topology | Horizontal Scaling | Vertical Scaling | Expand Volume | Restart | Stop/Start | -|----------|--------------------|------------------|---------------|---------|------------| -| hbase-cluster | Yes | Yes | Yes | Yes | Yes | +The HBase addon currently provides two topologies: -### Versions +| Topology | Components | Storage Backend | External Dependencies | Notes | +|----------|------------|-----------------|-----------------------|-------| +| `cluster` | `hmaster`, `hregionserver` | HDFS | ZooKeeper, HDFS NameNode | Recommended for production-like deployments | +| `standalone` | `hbase-standalone` | Local filesystem | ZooKeeper | Good for development and functional verification | + +Supported service version: | Major Version | Description | |---------------|-------------| | 2.5 | 2.5.6 | +## What This Addon Contains + +The addon package under `addons/hbase` defines: + +- `ClusterDefinition` named `hbase` +- component definitions for `hbase-hmaster`, `hbase-hregionserver`, and `hbase-standalone` +- config templates for: + - `hbase-site.xml` + - `core-site.xml` + - `hdfs-site.xml` + - `hbase-env.sh` +- runtime scripts and image mappings + +The deployment chart under `addons-cluster/hbase` provides a ready-to-use Cluster chart with deploy-time configuration knobs for: + +- HBase runtime tuning +- HDFS client retry / timeout / failover +- ZooKeeper session and connection settings +- security-related flags + ## Prerequisites - Kubernetes cluster >= v1.21 -- KubeBlocks installed and running -- ZooKeeper Addon enabled (HBase depends on ZooKeeper) -- Hadoop HDFS Addon enabled (HBase depends on HDFS Namenode) +- KubeBlocks >= 1.1 installed and running +- HBase addon installed +- ZooKeeper addon enabled +- Hadoop HDFS addon enabled if you want to use `cluster` topology +- a dedicated namespace for your test or deployment, for example: + +```bash +kubectl create ns demo +``` + +## Topology Details + +### Cluster Topology + +Cluster topology uses: + +- `hmaster` for master coordination +- `hregionserver` for serving data +- external ZooKeeper for coordination +- external HDFS NameNode service for `hbase.rootdir` + +Cluster topology name in `ClusterDefinition`: + +```yaml +spec: + clusterDef: hbase + topology: cluster +``` + +### Standalone Topology + +Standalone topology uses: + +- a single `hbase-standalone` component +- local filesystem for `hbase.rootdir` +- ZooKeeper service reference only + +Standalone topology name in `ClusterDefinition`: -## Examples +```yaml +spec: + clusterDef: hbase + topology: standalone +``` + +## Quick Start + +### Install the Addon -### Create a HBase Cluster +From the repository root: + +```bash +helm install hbase-addon ./addons/hbase +``` + +### Deploy with the Cluster Chart + +Cluster topology: + +```bash +helm install hbase-cluster ./addons-cluster/hbase \ + -n demo \ + --create-namespace \ + --set topology=cluster \ + --set serviceRefs.hbaseZookeeper.namespace=kubeblocks \ + --set serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster=zk \ + --set serviceRefs.hdfsNamenode.namespace=kubeblocks \ + --set serviceRefs.hdfsNamenode.clusterServiceSelector.cluster=hdfs +``` + +Standalone topology: + +```bash +helm install hbase-standalone ./addons-cluster/hbase \ + -n demo \ + --create-namespace \ + --set topology=standalone \ + --set serviceRefs.hbaseZookeeper.namespace=kubeblocks \ + --set serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster=zk +``` + +## Raw Cluster Examples + +### Minimal Cluster Mode Example ```yaml apiVersion: apps.kubeblocks.io/v1 @@ -36,107 +136,163 @@ metadata: spec: terminationPolicy: Delete clusterDef: hbase - topology: hbase-cluster + topology: cluster componentSpecs: - name: hmaster componentDef: hbase-hmaster-2.5 serviceVersion: 2.5.6 - replicas: 1 - resources: - requests: - cpu: "0.1" - memory: 0.5Gi - limits: - cpu: "1" - memory: 2Gi + replicas: 2 serviceRefs: - name: hbase-zookeeper - namespace: default + namespace: kubeblocks clusterServiceSelector: - cluster: zkcluster + cluster: zk service: component: zookeeper service: headless port: client - - name: hadoop-namenode - namespace: default + - name: hdfs-namenode + namespace: kubeblocks clusterServiceSelector: - cluster: hadoop2 + cluster: hdfs service: component: namenode service: headless - port: client - env: - - name: HADOOP_CLUSTER_NAME - value: "hadoop2" - volumes: - - name: hdfs-common-config - configMap: - name: hadoop2-namenode-hdfs-common-config - - name: hadoop-hdfs-config - configMap: - name: hadoop2-namenode-config - volumeClaimTemplates: - - name: hbase-log - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 2Gi + port: fs - name: hregionserver componentDef: hbase-hregionserver-2.5 serviceVersion: 2.5.6 - replicas: 1 - resources: - requests: - cpu: "0.1" - memory: 0.5Gi - limits: - cpu: "1" - memory: 2Gi + replicas: 2 serviceRefs: - name: hbase-zookeeper - namespace: default + namespace: kubeblocks clusterServiceSelector: - cluster: zkcluster + cluster: zk service: component: zookeeper service: headless port: client - - name: hadoop-namenode - namespace: default + - name: hdfs-namenode + namespace: kubeblocks clusterServiceSelector: - cluster: hadoop2 + cluster: hdfs service: component: namenode service: headless + port: fs +``` + +### Minimal Standalone Mode Example + +```yaml +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: hbase-standalone + namespace: demo +spec: + terminationPolicy: Delete + clusterDef: hbase + topology: standalone + componentSpecs: + - name: hbase-standalone + componentDef: hbase-standalone-2.5 + serviceVersion: 2.5.6 + replicas: 1 + serviceRefs: + - name: hbase-zookeeper + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless port: client - env: - - name: HADOOP_CLUSTER_NAME - value: "hadoop2" - volumes: - - name: hdfs-common-config - configMap: - name: hadoop2-namenode-hdfs-common-config - - name: hadoop-hdfs-config - configMap: - name: hadoop2-namenode-config - volumeClaimTemplates: - - name: hbase-temp-data - spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 10Gi ``` +## Configuration Files + +The addon renders different config files for different topologies: + +| Source Template | Rendered File | Used By | Purpose | +|----------------|---------------|---------|---------| +| `config/hbase-site-cluster.tpl` | `hbase-site.xml` | `hmaster`, `hregionserver` | Cluster-mode HBase configuration | +| `config/hbase-site-standalone.tpl` | `hbase-site.xml` | `hbase-standalone` | Standalone-mode HBase configuration | +| `config/hdfs-common-site.tpl` | `core-site.xml` | cluster topology | Hadoop common client settings | +| `config/hdfs-client-site.tpl` | `hdfs-site.xml` | cluster topology | HDFS nameservice and failover client settings | +| `config/hbase-env.sh.tpl` | `hbase-env.sh` | all components | runtime environment variables and JVM flags | + +## Deploy-Time Configuration Surface + +The cluster chart exposes deploy-time values through `addons-cluster/hbase/values.yaml`. + +### Main Value Groups + +| Value Prefix | Applies To | Example Keys | +|-------------|------------|--------------| +| `hbase.zk.*` | cluster and standalone | `sessionTimeout`, `maxClientCnxns` | +| `hbase.security.*` | cluster and standalone | `authentication`, `authorization` | +| `hbase.common.*` | cluster and standalone | `clientScannerCaching`, `regionMemstoreFlushSize` | +| `hbase.cluster.*` | cluster only | `regionserverHandlerCount`, `masterWaitOnRegionserversTimeout`, `splitlogManagerTimeout` | +| `hbase.standalone.*` | standalone only | `regionserverHandlerCount`, `hstoreFlusherCount`, `regionMaxFileSize` | +| `hdfs.fs.*` | cluster only | `trashInterval` | +| `hdfs.security.*` | cluster only | `authentication`, `authorization` | +| `hdfs.ipc.*` | cluster only | `clientConnectionMaxIdleTime`, `clientConnectTimeout`, `pingInterval` | +| `hdfs.client.*` | cluster only | `webhdfsEnabled`, `failoverMaxAttempts`, `retryPolicy.*`, `commonRetryPolicy.*` | +| `hdfs.hbaseClient.*` | cluster only | `ipcClientConnectTimeout`, `ipcClientConnectMaxRetries` | + +### Example Overrides + +```yaml +topology: cluster + +hbase: + zk: + sessionTimeout: 45000 + cluster: + regionserverHandlerCount: 200 + hstoreFlusherCount: 8 + regionserverStartupRetries: 20 + +hdfs: + fs: + trashInterval: 2880 + client: + failoverMaxAttempts: 30 + webhdfsEnabled: true +``` + +## Validation and Operations + +Check the generated Cluster: + +```bash +kubectl get cluster -n demo +kubectl describe cluster -n demo hbase-cluster +``` + +Check pods: + ```bash -kubectl apply -f examples/hbase/cluster.yaml +kubectl get pods -n demo -l app.kubernetes.io/instance=hbase-cluster ``` -### Delete +Inspect rendered config inside a pod: + +```bash +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/hbase-site.xml +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/core-site.xml +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/hdfs-site.xml +``` + +## Current Limitations + +- `cluster` topology requires external ZooKeeper and HDFS NameNode service references. +- Deploy-time configuration is currently exposed through the cluster chart values and `configs.variables`. +- The HBase addon does **not** yet provide the standard `ParametersDefinition` / `ParamConfigRenderer` / config-constraint based parameter reconfiguration chain. +- Most HBase and Hadoop client settings here should be treated as deployment-time settings. + +## Delete ```bash kubectl patch cluster -n demo hbase-cluster -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge" diff --git a/addons/hbase/README.zh-CN.md b/addons/hbase/README.zh-CN.md new file mode 100644 index 0000000000..9fefa8ca7e --- /dev/null +++ b/addons/hbase/README.zh-CN.md @@ -0,0 +1,303 @@ +# HBase + +[English](./README.md) + +本文档介绍 KubeBlocks HBase addon 的结构、拓扑、依赖关系、部署方式以及当前可用的配置入口。 + +## 概览 + +当前 HBase addon 提供两种拓扑: + +| 拓扑 | 组件 | 存储后端 | 外部依赖 | 说明 | +|------|------|----------|----------|------| +| `cluster` | `hmaster`、`hregionserver` | HDFS | ZooKeeper、HDFS NameNode | 适合真实集群部署 | +| `standalone` | `hbase-standalone` | 本地文件系统 | ZooKeeper | 适合开发、验证和轻量场景 | + +当前支持的服务版本: + +| 大版本 | 说明 | +|--------|------| +| 2.5 | 2.5.6 | + +## Addon 提供的内容 + +`addons/hbase` 目录当前定义了: + +- `ClusterDefinition`:`hbase` +- `ComponentDefinition`: + - `hbase-hmaster` + - `hbase-hregionserver` + - `hbase-standalone` +- 配置模板: + - `hbase-site.xml` + - `core-site.xml` + - `hdfs-site.xml` + - `hbase-env.sh` +- 运行脚本和镜像映射 + +`addons-cluster/hbase` 目录提供了一个可直接部署的 cluster chart,并已经暴露出一批部署阶段可配置项,用于: + +- HBase 运行参数调优 +- HDFS 客户端超时、重试、failover 参数 +- ZooKeeper 会话和连接参数 +- 安全相关开关 + +## 前置条件 + +- Kubernetes >= v1.21 +- KubeBlocks >= 1.1 已安装并正常运行 +- HBase addon 已安装 +- ZooKeeper addon 已启用 +- 如果使用 `cluster` 拓扑,还需要 Hadoop HDFS addon 已启用 +- 建议准备独立 namespace,例如: + +```bash +kubectl create ns demo +``` + +## 拓扑说明 + +### Cluster 拓扑 + +Cluster 拓扑包含: + +- `hmaster` +- `hregionserver` +- 外部 ZooKeeper +- 外部 HDFS NameNode 服务引用 + +对应的 Cluster 配置: + +```yaml +spec: + clusterDef: hbase + topology: cluster +``` + +### Standalone 拓扑 + +Standalone 拓扑包含: + +- 单个 `hbase-standalone` 组件 +- 本地文件系统 `hbase.rootdir` +- 仅依赖 ZooKeeper serviceRef + +对应的 Cluster 配置: + +```yaml +spec: + clusterDef: hbase + topology: standalone +``` + +## 快速开始 + +### 安装 Addon + +在仓库根目录执行: + +```bash +helm install hbase-addon ./addons/hbase +``` + +### 使用 Cluster Chart 部署 + +Cluster 模式: + +```bash +helm install hbase-cluster ./addons-cluster/hbase \ + -n demo \ + --create-namespace \ + --set topology=cluster \ + --set serviceRefs.hbaseZookeeper.namespace=kubeblocks \ + --set serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster=zk \ + --set serviceRefs.hdfsNamenode.namespace=kubeblocks \ + --set serviceRefs.hdfsNamenode.clusterServiceSelector.cluster=hdfs +``` + +Standalone 模式: + +```bash +helm install hbase-standalone ./addons-cluster/hbase \ + -n demo \ + --create-namespace \ + --set topology=standalone \ + --set serviceRefs.hbaseZookeeper.namespace=kubeblocks \ + --set serviceRefs.hbaseZookeeper.clusterServiceSelector.cluster=zk +``` + +## 原生 Cluster API 示例 + +### 最小 Cluster 模式示例 + +```yaml +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: hbase-cluster + namespace: demo +spec: + terminationPolicy: Delete + clusterDef: hbase + topology: cluster + componentSpecs: + - name: hmaster + componentDef: hbase-hmaster-2.5 + serviceVersion: 2.5.6 + replicas: 2 + serviceRefs: + - name: hbase-zookeeper + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless + port: client + - name: hdfs-namenode + namespace: kubeblocks + clusterServiceSelector: + cluster: hdfs + service: + component: namenode + service: headless + port: fs + - name: hregionserver + componentDef: hbase-hregionserver-2.5 + serviceVersion: 2.5.6 + replicas: 2 + serviceRefs: + - name: hbase-zookeeper + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless + port: client + - name: hdfs-namenode + namespace: kubeblocks + clusterServiceSelector: + cluster: hdfs + service: + component: namenode + service: headless + port: fs +``` + +### 最小 Standalone 模式示例 + +```yaml +apiVersion: apps.kubeblocks.io/v1 +kind: Cluster +metadata: + name: hbase-standalone + namespace: demo +spec: + terminationPolicy: Delete + clusterDef: hbase + topology: standalone + componentSpecs: + - name: hbase-standalone + componentDef: hbase-standalone-2.5 + serviceVersion: 2.5.6 + replicas: 1 + serviceRefs: + - name: hbase-zookeeper + namespace: kubeblocks + clusterServiceSelector: + cluster: zk + service: + component: zookeeper + service: headless + port: client +``` + +## 配置文件结构 + +当前 addon 会根据不同拓扑渲染不同配置文件: + +| 模板文件 | 最终文件 | 使用组件 | 作用 | +|----------|----------|----------|------| +| `config/hbase-site-cluster.tpl` | `hbase-site.xml` | `hmaster`、`hregionserver` | cluster 模式 HBase 主配置 | +| `config/hbase-site-standalone.tpl` | `hbase-site.xml` | `hbase-standalone` | standalone 模式 HBase 主配置 | +| `config/hdfs-common-site.tpl` | `core-site.xml` | cluster 模式 | Hadoop 通用客户端配置 | +| `config/hdfs-client-site.tpl` | `hdfs-site.xml` | cluster 模式 | HDFS nameservice / failover 客户端配置 | +| `config/hbase-env.sh.tpl` | `hbase-env.sh` | 全部组件 | 运行时环境变量和 JVM 参数 | + +## 当前部署阶段配置入口 + +当前 cluster chart 通过 `addons-cluster/hbase/values.yaml` 暴露部署阶段配置。 + +### 主要参数分组 + +| 参数前缀 | 适用范围 | 典型参数 | +|----------|----------|----------| +| `hbase.zk.*` | cluster + standalone | `sessionTimeout`、`maxClientCnxns` | +| `hbase.security.*` | cluster + standalone | `authentication`、`authorization` | +| `hbase.common.*` | cluster + standalone | `clientScannerCaching`、`regionMemstoreFlushSize` | +| `hbase.cluster.*` | cluster | `regionserverHandlerCount`、`masterWaitOnRegionserversTimeout`、`splitlogManagerTimeout` | +| `hbase.standalone.*` | standalone | `regionserverHandlerCount`、`hstoreFlusherCount`、`regionMaxFileSize` | +| `hdfs.fs.*` | cluster | `trashInterval` | +| `hdfs.security.*` | cluster | `authentication`、`authorization` | +| `hdfs.ipc.*` | cluster | `clientConnectionMaxIdleTime`、`clientConnectTimeout`、`pingInterval` | +| `hdfs.client.*` | cluster | `webhdfsEnabled`、`failoverMaxAttempts`、`retryPolicy.*`、`commonRetryPolicy.*` | +| `hdfs.hbaseClient.*` | cluster | `ipcClientConnectTimeout`、`ipcClientConnectMaxRetries` | + +### 覆盖示例 + +```yaml +topology: cluster + +hbase: + zk: + sessionTimeout: 45000 + cluster: + regionserverHandlerCount: 200 + hstoreFlusherCount: 8 + regionserverStartupRetries: 20 + +hdfs: + fs: + trashInterval: 2880 + client: + failoverMaxAttempts: 30 + webhdfsEnabled: true +``` + +## 验证与排查 + +检查生成的 Cluster: + +```bash +kubectl get cluster -n demo +kubectl describe cluster -n demo hbase-cluster +``` + +检查 Pod: + +```bash +kubectl get pods -n demo -l app.kubernetes.io/instance=hbase-cluster +``` + +查看容器内最终渲染出的配置: + +```bash +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/hbase-site.xml +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/core-site.xml +kubectl exec -n demo hbase-cluster-hmaster-0 -- cat /opt/bitnami/hbase/conf/hdfs-site.xml +``` + +## 当前限制 + +- `cluster` 拓扑必须依赖外部 ZooKeeper 和 HDFS NameNode 的 serviceRef。 +- 当前这批参数是通过 cluster chart values 和 `configs.variables` 暴露的部署阶段能力。 +- HBase addon 目前**还没有**接入标准的 `ParametersDefinition` / `ParamConfigRenderer` / config-constraint 参数重配链路。 +- 因此当前这些参数应视为部署阶段参数,而不是统一参数管理入口。 + +## 删除集群 + +```bash +kubectl patch cluster -n demo hbase-cluster -p '{"spec":{"terminationPolicy":"WipeOut"}}' --type="merge" +kubectl delete cluster -n demo hbase-cluster +``` diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index 11885e1de0..ccd31e37f3 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -28,7 +28,7 @@ zookeeper.session.timeout - 30000 + {{ .HBASE_ZOOKEEPER_SESSION_TIMEOUT }} @@ -43,7 +43,7 @@ hbase.zookeeper.property.maxClientCnxns - 4000 + {{ .HBASE_ZOOKEEPER_MAX_CLIENT_CNXNS }} @@ -88,32 +88,32 @@ hbase.regionserver.handler.count - 100 + {{ .HBASE_REGIONSERVER_HANDLER_COUNT }} hbase.hstore.flusher.count - 4 + {{ .HBASE_HSTORE_FLUSHER_COUNT }} hbase.client.scanner.caching - 100 + {{ .HBASE_CLIENT_SCANNER_CACHING }} hbase.hregion.max.filesize - 53687091200 + {{ .HBASE_HREGION_MAX_FILESIZE }} hbase.hregion.memstore.flush.size - 134217728 + {{ .HBASE_HREGION_MEMSTORE_FLUSH_SIZE }} hbase.hregion.majorcompaction - 0 + {{ .HBASE_HREGION_MAJORCOMPACTION }} @@ -128,12 +128,12 @@ hbase.master.wait.on.regionservers.timeout - 300000 + {{ .HBASE_MASTER_WAIT_ON_REGIONSERVERS_TIMEOUT }} hbase.master.startup.retainassign.timeout - 300000 + {{ .HBASE_MASTER_STARTUP_RETAINASSIGN_TIMEOUT }} @@ -143,22 +143,22 @@ hbase.oldwals.cleaner.thread.timeout.msec - 60000 + {{ .HBASE_OLDWALS_CLEANER_THREAD_TIMEOUT_MSEC }} hbase.master.logcleaner.ttl - 60000 + {{ .HBASE_MASTER_LOGCLEANER_TTL }} hbase.master.hfilecleaner.ttl - 600000 + {{ .HBASE_MASTER_HFILECLEANER_TTL }} hbase.balancer.period - 1800000 + {{ .HBASE_BALANCER_PERIOD }} @@ -173,22 +173,22 @@ hbase.procedure.store.wal.use.hsync - true + {{ .HBASE_PROCEDURE_STORE_WAL_USE_HSYNC }} hbase.regionserver.optionalcacheflushinterval - 28800000 + {{ .HBASE_REGIONSERVER_OPTIONALCACHEFLUSHINTERVAL }} hbase.regionserver.startup.retries - 10 + {{ .HBASE_REGIONSERVER_STARTUP_RETRIES }} hbase.regionserver.startup.retry.interval - 10000 + {{ .HBASE_REGIONSERVER_STARTUP_RETRY_INTERVAL }} @@ -198,17 +198,17 @@ hbase.replication - true + {{ .HBASE_REPLICATION_ENABLED }} hbase.security.authentication - simple + {{ .HBASE_SECURITY_AUTHENTICATION }} hbase.security.authorization - false + {{ .HBASE_SECURITY_AUTHORIZATION }} @@ -245,37 +245,37 @@ dfs.client.failover.max.attempts - 15 + {{ .HDFS_CLIENT_FAILOVER_MAX_ATTEMPTS }} dfs.client.failover.sleep.base.millis - 500 + {{ .HDFS_CLIENT_FAILOVER_SLEEP_BASE_MILLIS }} dfs.client.failover.sleep.max.millis - 15000 + {{ .HDFS_CLIENT_FAILOVER_SLEEP_MAX_MILLIS }} dfs.client.retry.policy.enabled - true + {{ .HBASE_HDFS_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 10000,6,60000,10 + {{ .HBASE_HDFS_CLIENT_RETRY_POLICY_SPEC }} ipc.client.connect.timeout - 30000 + {{ .HBASE_IPC_CLIENT_CONNECT_TIMEOUT }} ipc.client.connect.max.retries - 10 + {{ .HBASE_IPC_CLIENT_CONNECT_MAX_RETRIES }} @@ -285,6 +285,6 @@ hbase.splitlog.manager.timeout - 600000 + {{ .HBASE_SPLITLOG_MANAGER_TIMEOUT }} \ No newline at end of file diff --git a/addons/hbase/config/hbase-site-standalone.tpl b/addons/hbase/config/hbase-site-standalone.tpl index 4a3690fa53..0a59c11fef 100644 --- a/addons/hbase/config/hbase-site-standalone.tpl +++ b/addons/hbase/config/hbase-site-standalone.tpl @@ -28,7 +28,7 @@ zookeeper.session.timeout - 30000 + {{ .HBASE_ZOOKEEPER_SESSION_TIMEOUT }} @@ -43,7 +43,7 @@ hbase.zookeeper.property.maxClientCnxns - 4000 + {{ .HBASE_ZOOKEEPER_MAX_CLIENT_CNXNS }} @@ -83,27 +83,27 @@ hbase.regionserver.handler.count - 30 + {{ .HBASE_REGIONSERVER_HANDLER_COUNT }} hbase.hstore.flusher.count - 2 + {{ .HBASE_HSTORE_FLUSHER_COUNT }} hbase.client.scanner.caching - 100 + {{ .HBASE_CLIENT_SCANNER_CACHING }} hbase.hregion.max.filesize - 10737418240 + {{ .HBASE_HREGION_MAX_FILESIZE }} hbase.hregion.memstore.flush.size - 134217728 + {{ .HBASE_HREGION_MEMSTORE_FLUSH_SIZE }} @@ -113,7 +113,7 @@ hbase.procedure.store.wal.use.hsync - false + {{ .HBASE_PROCEDURE_STORE_WAL_USE_HSYNC }} @@ -123,16 +123,16 @@ hbase.replication - false + {{ .HBASE_REPLICATION_ENABLED }} hbase.security.authentication - simple + {{ .HBASE_SECURITY_AUTHENTICATION }} hbase.security.authorization - false + {{ .HBASE_SECURITY_AUTHORIZATION }} diff --git a/addons/hbase/config/hdfs-client-site.tpl b/addons/hbase/config/hdfs-client-site.tpl index d0b34f0a10..a18aebc40d 100644 --- a/addons/hbase/config/hdfs-client-site.tpl +++ b/addons/hbase/config/hdfs-client-site.tpl @@ -43,7 +43,7 @@ dfs.webhdfs.enabled - false + {{- .HDFS_WEBHDFS_ENABLED }} diff --git a/addons/hbase/config/hdfs-common-site.tpl b/addons/hbase/config/hdfs-common-site.tpl index 5a59d89708..389d7de245 100644 --- a/addons/hbase/config/hdfs-common-site.tpl +++ b/addons/hbase/config/hdfs-common-site.tpl @@ -8,7 +8,7 @@ fs.trash.interval - 1440 + {{ .HDFS_FS_TRASH_INTERVAL }} @@ -33,22 +33,22 @@ hadoop.security.authentication - simple + {{ .HADOOP_SECURITY_AUTHENTICATION }} hadoop.security.authorization - false + {{ .HADOOP_SECURITY_AUTHORIZATION }} ipc.client.connection.maxidletime - 30000 + {{ .HADOOP_IPC_CLIENT_CONNECTION_MAXIDLETIME }} ipc.client.connect.timeout - 10000 + {{ .HADOOP_IPC_CLIENT_CONNECT_TIMEOUT }} @@ -58,21 +58,21 @@ ipc.ping.interval - 60000 + {{ .HADOOP_IPC_PING_INTERVAL }} hadoop.tmp.dir - /hadoop/tmp + {{ .HADOOP_TMP_DIR }} dfs.client.retry.policy.enabled - true + {{ .HDFS_COMMON_CLIENT_RETRY_POLICY_ENABLED }} dfs.client.retry.policy.spec - 1000,1 + {{ .HDFS_COMMON_CLIENT_RETRY_POLICY_SPEC }} From f502c23cdeb471862ef6eae6c4385a5436313e44 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Wed, 8 Jul 2026 12:00:45 +0800 Subject: [PATCH 15/18] fix(hbase): load MultiRowMutationEndpoint as region coprocessor only --- addons/hbase/config/hbase-site-cluster.tpl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index ccd31e37f3..80dc5b1a17 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -234,12 +234,11 @@ hbase.coprocessor.master.classes - - org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint,org.apache.hadoop.hbase.rsgroup.RSGroupAdminEndpoint + org.apache.hadoop.hbase.rsgroup.RSGroupAdminEndpoint - hbase.coprocessor.regionserver.classes + hbase.coprocessor.region.classes org.apache.hadoop.hbase.coprocessor.MultiRowMutationEndpoint From d9c5e6ce3f87c85f7f0d768bdb547286e9b3b2f6 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Wed, 8 Jul 2026 12:25:18 +0800 Subject: [PATCH 16/18] fix(hadoop): mount dfs include files in namenode init containers --- .../templates/cmpd-hdfs-namenode-standalone.yaml | 6 ++++++ addons/hadoop/templates/cmpd-hdfs-namenode.yaml | 12 ++++++++++++ 2 files changed, 18 insertions(+) diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml index 8472445971..6fc6c1a346 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -68,6 +68,12 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index 9dea991fce..26a926421a 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -74,6 +74,12 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml @@ -104,6 +110,12 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.include + subPath: dfs.include + - name: hdfs-common-config + mountPath: {{ .Values.runtime.configDir }}/dfs.exclude + subPath: dfs.exclude - name: namenode-config mountPath: {{ .Values.runtime.configDir }}/hdfs-site.xml subPath: hdfs-site.xml From 44b83b691df910f2bfceb6392c7276e2c2540689 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Wed, 8 Jul 2026 12:52:51 +0800 Subject: [PATCH 17/18] feat(obs): remove obsolete hadoop metrics2 config templates --- addons-cluster/hadoop/templates/cluster.yaml | 15 ++++++++ .../hadoop/templates/prometheus/monitor.yaml | 20 ++++++++++ addons-cluster/hadoop/values.schema.json | 27 +++++++++++++- addons-cluster/hadoop/values.yaml | 9 +++++ .../hbase/templates/prometheus/monitor.yaml | 20 ++++++++++ addons-cluster/hbase/values.schema.json | 11 +++++- addons-cluster/hbase/values.yaml | 3 ++ addons/hadoop/README.md | 21 ++++++++++- addons/hadoop/README.zh-CN.md | 21 ++++++++++- addons/hadoop/config/hadoop-env.sh.tpl | 9 +++-- .../config/hadoop-metrics2.properties.tpl | 19 ---------- .../hadoop/config/hdfs-jmx-exporter.yaml.tpl | 9 +++++ addons/hadoop/templates/_helpers.tpl | 4 ++ .../cmpd-hdfs-datanode-standalone.yaml | 37 +++++++++++++++++-- .../hadoop/templates/cmpd-hdfs-datanode.yaml | 37 +++++++++++++++++-- .../templates/cmpd-hdfs-journalnode.yaml | 37 +++++++++++++++++-- .../cmpd-hdfs-namenode-standalone.yaml | 37 +++++++++++++++++-- .../hadoop/templates/cmpd-hdfs-namenode.yaml | 37 +++++++++++++++++-- .../hadoop/templates/cmpv-hdfs-datanode.yaml | 1 + .../templates/cmpv-hdfs-journalnode.yaml | 3 +- .../hadoop/templates/cmpv-hdfs-namenode.yaml | 1 + .../hdfs-common-config-template.yaml | 4 +- ...dfs-common-standalone-config-template.yaml | 4 +- addons/hadoop/values.yaml | 17 +++++++++ addons/hbase/README.md | 19 ++++++++++ addons/hbase/README.zh-CN.md | 19 ++++++++++ .../hadoop-metrics2-hbase.properties.tpl | 4 -- addons/hbase/config/hbase-env.sh.tpl | 6 +-- .../hbase/config/hbase-jmx-exporter.yaml.tpl | 9 +++++ addons/hbase/templates/_helpers.tpl | 4 ++ .../templates/cmpd-hbase-standalone.yaml | 29 +++++++++++++-- addons/hbase/templates/cmpd-hmaster.yaml | 29 +++++++++++++-- .../hbase/templates/cmpd-hregionserver.yaml | 29 +++++++++++++-- .../templates/cmpv-hbase-standalone.yaml | 1 + addons/hbase/templates/cmpv-hmaster.yaml | 1 + .../hbase/templates/cmpv-hregionserver.yaml | 1 + .../hbase-cluster-config-template.yaml | 4 +- .../hbase-standalone-config-template.yaml | 4 +- addons/hbase/values.yaml | 14 +++++++ 39 files changed, 508 insertions(+), 68 deletions(-) create mode 100644 addons-cluster/hadoop/templates/prometheus/monitor.yaml create mode 100644 addons-cluster/hbase/templates/prometheus/monitor.yaml delete mode 100644 addons/hadoop/config/hadoop-metrics2.properties.tpl create mode 100644 addons/hadoop/config/hdfs-jmx-exporter.yaml.tpl delete mode 100644 addons/hbase/config/hadoop-metrics2-hbase.properties.tpl create mode 100644 addons/hbase/config/hbase-jmx-exporter.yaml.tpl diff --git a/addons-cluster/hadoop/templates/cluster.yaml b/addons-cluster/hadoop/templates/cluster.yaml index 6189e4c239..0c305962d1 100644 --- a/addons-cluster/hadoop/templates/cluster.yaml +++ b/addons-cluster/hadoop/templates/cluster.yaml @@ -25,6 +25,11 @@ HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} + HDFS_JMX_PORT: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + HDFS_NAMENODE_JMX_PORT: {{ .Values.hdfs.ports.namenode.jmx | quote }} + HDFS_DATANODE_JMX_PORT: {{ .Values.hdfs.ports.datanode.jmx | quote }} + HDFS_JOURNALNODE_JMX_PORT: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + HDFS_ZKFC_JMX_PORT: {{ .Values.hdfs.ports.zkfc.jmx | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} @@ -94,6 +99,11 @@ HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} + HDFS_JMX_PORT: {{ .Values.hdfs.ports.namenode.jmx | quote }} + HDFS_NAMENODE_JMX_PORT: {{ .Values.hdfs.ports.namenode.jmx | quote }} + HDFS_DATANODE_JMX_PORT: {{ .Values.hdfs.ports.datanode.jmx | quote }} + HDFS_JOURNALNODE_JMX_PORT: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + HDFS_ZKFC_JMX_PORT: {{ .Values.hdfs.ports.zkfc.jmx | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} @@ -180,6 +190,11 @@ HDFS_SECURITY_AUTHENTICATION: {{ .Values.hdfs.security.authentication | quote }} HDFS_SECURITY_AUTHORIZATION: {{ .Values.hdfs.security.authorization | quote }} HDFS_HA_ZOOKEEPER_PARENT_ZNODE: {{ .Values.hdfs.ha.zookeeper.parentZnodePrefix | quote }} + HDFS_JMX_PORT: {{ .Values.hdfs.ports.datanode.jmx | quote }} + HDFS_NAMENODE_JMX_PORT: {{ .Values.hdfs.ports.namenode.jmx | quote }} + HDFS_DATANODE_JMX_PORT: {{ .Values.hdfs.ports.datanode.jmx | quote }} + HDFS_JOURNALNODE_JMX_PORT: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + HDFS_ZKFC_JMX_PORT: {{ .Values.hdfs.ports.zkfc.jmx | quote }} HDFS_NAMENODE_HEAP: {{ .Values.hdfs.jvm.namenodeHeapSize | quote }} HDFS_DATANODE_HEAP: {{ .Values.hdfs.jvm.datanodeHeapSize | quote }} HDFS_JOURNALNODE_HEAP: {{ .Values.hdfs.jvm.journalnodeHeapSize | quote }} diff --git a/addons-cluster/hadoop/templates/prometheus/monitor.yaml b/addons-cluster/hadoop/templates/prometheus/monitor.yaml new file mode 100644 index 0000000000..95adf6f28c --- /dev/null +++ b/addons-cluster/hadoop/templates/prometheus/monitor.yaml @@ -0,0 +1,20 @@ +{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PodMonitor") .Values.prometheus.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "kblib.clusterName" . }}-metrics-monitor + namespace: {{ .Release.Namespace }} + labels: + {{- include "kblib.clusterLabels" . | nindent 4 }} +spec: + podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/instance: {{ include "kblib.clusterName" . | quote }} +{{- end }} diff --git a/addons-cluster/hadoop/values.schema.json b/addons-cluster/hadoop/values.schema.json index 582a349f0d..13ff4157eb 100644 --- a/addons-cluster/hadoop/values.schema.json +++ b/addons-cluster/hadoop/values.schema.json @@ -43,14 +43,28 @@ "type": "object", "properties": { "rpc": { "type": "integer", "default": 8020, "minimum": 1, "maximum": 65535 }, - "http": { "type": "integer", "default": 9870, "minimum": 1, "maximum": 65535 } + "http": { "type": "integer", "default": 9870, "minimum": 1, "maximum": 65535 }, + "jmx": { "type": "integer", "default": 10101, "minimum": 1, "maximum": 65535 } } }, "journalnode": { "type": "object", "properties": { "rpc": { "type": "integer", "default": 8485, "minimum": 1, "maximum": 65535 }, - "http": { "type": "integer", "default": 8480, "minimum": 1, "maximum": 65535 } + "http": { "type": "integer", "default": 8480, "minimum": 1, "maximum": 65535 }, + "jmx": { "type": "integer", "default": 10103, "minimum": 1, "maximum": 65535 } + } + }, + "datanode": { + "type": "object", + "properties": { + "jmx": { "type": "integer", "default": 10102, "minimum": 1, "maximum": 65535 } + } + }, + "zkfc": { + "type": "object", + "properties": { + "jmx": { "type": "integer", "default": 10104, "minimum": 1, "maximum": 65535 } } } } @@ -184,6 +198,15 @@ } } } + }, + "prometheus": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + } + } } }, "definitions": { diff --git a/addons-cluster/hadoop/values.yaml b/addons-cluster/hadoop/values.yaml index c6597e05d3..4accdf7f40 100644 --- a/addons-cluster/hadoop/values.yaml +++ b/addons-cluster/hadoop/values.yaml @@ -62,9 +62,15 @@ hdfs: namenode: rpc: 8020 http: 9870 + jmx: 10101 journalnode: rpc: 8485 http: 8480 + jmx: 10103 + datanode: + jmx: 10102 + zkfc: + jmx: 10104 paths: namenodeMetadataDir: /hadoop/dfs/metadata datanodeDataDir: /hadoop/dfs/data0 @@ -129,5 +135,8 @@ serviceRefs: service: headless port: client +prometheus: + enabled: false + extra: terminationPolicy: Delete diff --git a/addons-cluster/hbase/templates/prometheus/monitor.yaml b/addons-cluster/hbase/templates/prometheus/monitor.yaml new file mode 100644 index 0000000000..95adf6f28c --- /dev/null +++ b/addons-cluster/hbase/templates/prometheus/monitor.yaml @@ -0,0 +1,20 @@ +{{- if and (.Capabilities.APIVersions.Has "monitoring.coreos.com/v1/PodMonitor") .Values.prometheus.enabled }} +apiVersion: monitoring.coreos.com/v1 +kind: PodMonitor +metadata: + name: {{ include "kblib.clusterName" . }}-metrics-monitor + namespace: {{ .Release.Namespace }} + labels: + {{- include "kblib.clusterLabels" . | nindent 4 }} +spec: + podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http + namespaceSelector: + matchNames: + - {{ .Release.Namespace }} + selector: + matchLabels: + app.kubernetes.io/instance: {{ include "kblib.clusterName" . | quote }} +{{- end }} diff --git a/addons-cluster/hbase/values.schema.json b/addons-cluster/hbase/values.schema.json index a0b125e1d6..359bfe76f6 100644 --- a/addons-cluster/hbase/values.schema.json +++ b/addons-cluster/hbase/values.schema.json @@ -376,6 +376,15 @@ } } } + }, + "prometheus": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "default": false + } + } } }, "definitions": { @@ -443,4 +452,4 @@ } } } -} +} \ No newline at end of file diff --git a/addons-cluster/hbase/values.yaml b/addons-cluster/hbase/values.yaml index 74b5dc9701..77ec11c8af 100644 --- a/addons-cluster/hbase/values.yaml +++ b/addons-cluster/hbase/values.yaml @@ -117,5 +117,8 @@ hbase: procedureStoreWalUseHsync: false replicationEnabled: false +prometheus: + enabled: false + extra: terminationPolicy: Delete diff --git a/addons/hadoop/README.md b/addons/hadoop/README.md index 9c8ba109b0..3ac09f37db 100644 --- a/addons/hadoop/README.md +++ b/addons/hadoop/README.md @@ -40,7 +40,7 @@ The addon package under `addons/hadoop` defines: - `core-site.xml` - `hdfs-site.xml` - `hadoop-env.sh` - - `hadoop-metrics2.properties` + - `hdfs-jmx-exporter.yaml` - startup and init scripts for NameNode, DataNode, JournalNode, and ZKFC - parameter management resources: - `paramsdef-hdfs-common.yaml` @@ -204,6 +204,25 @@ Current HA behavior is intentionally conservative: This means the current addon supports configurable NameNode IDs for the existing 2NN active/standby model, not general N-way NameNode scaling. +## Observability + +Hadoop metrics are now exposed through a `jmx-exporter` sidecar instead of the old `metrics2 JmxSink` path. + +- the old `hadoop-metrics2.properties` JmxSink path has been removed +- NameNode, DataNode, and JournalNode pods now include a `jmx-exporter` sidecar +- the exporter scrapes local JVM JMX over loopback and exposes `/metrics` + +If you want Prometheus discovery metadata on the component service, set `spec.componentSpecs[*].disableExporter=false` in the deployed `Cluster`. + +Typical PodMonitor endpoint: + +```yaml +podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http +``` + ## Quick Start ### Install the Addon diff --git a/addons/hadoop/README.zh-CN.md b/addons/hadoop/README.zh-CN.md index 09690067fe..bd66dafaa0 100644 --- a/addons/hadoop/README.zh-CN.md +++ b/addons/hadoop/README.zh-CN.md @@ -40,7 +40,7 @@ - `core-site.xml` - `hdfs-site.xml` - `hadoop-env.sh` - - `hadoop-metrics2.properties` + - `hdfs-jmx-exporter.yaml` - NameNode、DataNode、JournalNode、ZKFC 的启动和初始化脚本 - 标准参数管理资源: - `paramsdef-hdfs-common.yaml` @@ -207,6 +207,25 @@ DataNode 当前支持以下网络相关配置: 因此,当前能力是“可配置 NameNode ID 的 2NN active/standby 模型”,不是通用 N 个 NameNode 横向扩展模型。 +## 监控说明 + +Hadoop 当前的监控出口已经切到 `jmx-exporter` sidecar,不再依赖旧的 `metrics2 JmxSink`。 + +- 旧的 `hadoop-metrics2.properties` JmxSink 路径已经移除 +- NameNode、DataNode、JournalNode Pod 现在都会带一个 `jmx-exporter` sidecar +- sidecar 通过本地 loopback 抓取 JVM JMX,并对外暴露 `/metrics` + +如果希望组件 Service 上带 Prometheus 发现信息,需要在实际部署的 `Cluster` 里将 `spec.componentSpecs[*].disableExporter=false`。 + +典型的 `PodMonitor` endpoint 如下: + +```yaml +podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http +``` + ## 快速开始 ### 安装 Addon diff --git a/addons/hadoop/config/hadoop-env.sh.tpl b/addons/hadoop/config/hadoop-env.sh.tpl index 21c5a0ca0e..50fe62b23e 100644 --- a/addons/hadoop/config/hadoop-env.sh.tpl +++ b/addons/hadoop/config/hadoop-env.sh.tpl @@ -7,14 +7,15 @@ export HADOOP_IDENT_STRING=${HADOOP_IDENT_STRING:-$USER} export HADOOP_OPTS="${HADOOP_OPTS} -Djava.net.preferIPv4Stack=true -Dsun.net.inetaddr.ttl=10 -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:ParallelGCThreads=8" export HDFS_HA_NAMENODE_IDS="${HDFS_HA_NAMENODE_IDS:-{{ .HDFS_HA_NAMENODE_IDS }}}" +export HADOOP_JMX_BASE="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Djava.rmi.server.hostname=127.0.0.1" -export HDFS_NAMENODE_OPTS="${HDFS_NAMENODE_OPTS:-} -Xms{{ .HDFS_NAMENODE_HEAP }} -Xmx{{ .HDFS_NAMENODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender" +export HDFS_NAMENODE_OPTS="${HDFS_NAMENODE_OPTS:-} $HADOOP_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HDFS_NAMENODE_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HDFS_NAMENODE_JMX_PORT }} -Xms{{ .HDFS_NAMENODE_HEAP }} -Xmx{{ .HDFS_NAMENODE_HEAP }} -Dhadoop.security.logger=INFO,RFAS -Dhdfs.audit.logger=INFO,NullAppender" -export HDFS_DATANODE_OPTS="${HDFS_DATANODE_OPTS:-} -Xms{{ .HDFS_DATANODE_HEAP }} -Xmx{{ .HDFS_DATANODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dhadoop.security.logger=ERROR,RFAS -Ddfs.datanode.hostname=${POD_FQDN}" +export HDFS_DATANODE_OPTS="${HDFS_DATANODE_OPTS:-} $HADOOP_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HDFS_DATANODE_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HDFS_DATANODE_JMX_PORT }} -Xms{{ .HDFS_DATANODE_HEAP }} -Xmx{{ .HDFS_DATANODE_HEAP }} -Dhadoop.security.logger=ERROR,RFAS -Ddfs.datanode.hostname=${POD_FQDN}" -export HDFS_JOURNALNODE_OPTS="${HDFS_JOURNALNODE_OPTS:-} -Xms{{ .HDFS_JOURNALNODE_HEAP }} -Xmx{{ .HDFS_JOURNALNODE_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" +export HDFS_JOURNALNODE_OPTS="${HDFS_JOURNALNODE_OPTS:-} $HADOOP_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HDFS_JOURNALNODE_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HDFS_JOURNALNODE_JMX_PORT }} -Xms{{ .HDFS_JOURNALNODE_HEAP }} -Xmx{{ .HDFS_JOURNALNODE_HEAP }}" -export HDFS_ZKFC_OPTS="${HDFS_ZKFC_OPTS:-} -Xms{{ .HDFS_ZKFC_HEAP }} -Xmx{{ .HDFS_ZKFC_HEAP }} -Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false" +export HDFS_ZKFC_OPTS="${HDFS_ZKFC_OPTS:-} $HADOOP_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HDFS_ZKFC_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HDFS_ZKFC_JMX_PORT }} -Xms{{ .HDFS_ZKFC_HEAP }} -Xmx{{ .HDFS_ZKFC_HEAP }}" export HADOOP_CLIENT_OPTS="${HADOOP_CLIENT_OPTS:-} -Xmx512m" diff --git a/addons/hadoop/config/hadoop-metrics2.properties.tpl b/addons/hadoop/config/hadoop-metrics2.properties.tpl deleted file mode 100644 index c440564474..0000000000 --- a/addons/hadoop/config/hadoop-metrics2.properties.tpl +++ /dev/null @@ -1,19 +0,0 @@ -# Hadoop Metrics 2 configuration - JMX sink for all components -*.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -*.sink.jmx.period=10 - -# NameNode metrics -namenode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -namenode.sink.jmx.period=10 - -# DataNode metrics -datanode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -datanode.sink.jmx.period=10 - -# JournalNode metrics -journalnode.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -journalnode.sink.jmx.period=10 - -# ZKFC metrics -zkfc.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -zkfc.sink.jmx.period=10 diff --git a/addons/hadoop/config/hdfs-jmx-exporter.yaml.tpl b/addons/hadoop/config/hdfs-jmx-exporter.yaml.tpl new file mode 100644 index 0000000000..29b8b50c22 --- /dev/null +++ b/addons/hadoop/config/hdfs-jmx-exporter.yaml.tpl @@ -0,0 +1,9 @@ +jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:{{ .HDFS_JMX_PORT }}/jmxrmi +ssl: false +lowercaseOutputName: true +lowercaseOutputLabelNames: true +whitelistObjectNames: + - "Hadoop:*" + - "java.lang:*" +rules: + - pattern: ".*" diff --git a/addons/hadoop/templates/_helpers.tpl b/addons/hadoop/templates/_helpers.tpl index 4f100766fc..c0f77179d4 100644 --- a/addons/hadoop/templates/_helpers.tpl +++ b/addons/hadoop/templates/_helpers.tpl @@ -96,3 +96,7 @@ Image references {{- define "hadoop.dataNodeImage" -}} {{ .Values.dataNode.image.registry }}/{{ .Values.dataNode.image.repository }}:{{ .Values.dataNode.image.tag }} {{- end }} + +{{- define "hadoop.jmxExporterImage" -}} +{{ .Values.image.jmxExporter.registry }}/{{ .Values.image.jmxExporter.repository }}:{{ .Values.image.jmxExporter.tag }} +{{- end }} diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml index ba0bd695d2..0b13ffccb4 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode-standalone.yaml @@ -10,6 +10,9 @@ spec: provider: kubeblocks description: {{ .Chart.Description }} serviceKind: hdfs-datanode-standalone + exporter: + containerName: jmx-exporter + scrapePath: /metrics runtime: hostNetwork: {{ .Values.runtime.datanode.hostNetwork }} hostPID: {{ .Values.runtime.datanode.hostPID }} @@ -104,9 +107,6 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hdfs-common-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties - subPath: hadoop-metrics2.properties - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include @@ -136,6 +136,27 @@ spec: {{ toYaml .Values.securityContext.capabilities | nindent 12 }} seccompProfile: {{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hdfs-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hdfs-common-config + mountPath: /etc/jmx-exporter/hdfs-jmx-exporter.yaml + subPath: hdfs-jmx-exporter.yaml securityContext: fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} fsGroup: {{ .Values.securityContext.fsGroup }} @@ -158,6 +179,16 @@ spec: value: {{ .Values.extra.clusterDomain }} - name: HDFS_CONF_DIR value: {{ .Values.runtime.configDir }} + - name: HDFS_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_NAMENODE_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_DATANODE_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_JOURNALNODE_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_ZKFC_JMX_PORT + value: {{ .Values.hdfs.ports.zkfc.jmx | quote }} - name: HDFS_DATANODE_DATA_DIR value: {{ .Values.hdfs.paths.datanodeDataDir | quote }} - name: HDFS_DATANODE_HANDLER_COUNT diff --git a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml index de4c57f9ea..8c3c472dd3 100644 --- a/addons/hadoop/templates/cmpd-hdfs-datanode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-datanode.yaml @@ -10,6 +10,9 @@ spec: provider: kubeblocks description: {{ .Chart.Description }} serviceKind: hdfs-datanode + exporter: + containerName: jmx-exporter + scrapePath: /metrics runtime: hostNetwork: {{ .Values.runtime.datanode.hostNetwork }} hostPID: {{ .Values.runtime.datanode.hostPID }} @@ -110,9 +113,6 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hdfs-common-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties - subPath: hadoop-metrics2.properties - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include @@ -142,6 +142,27 @@ spec: {{ toYaml .Values.securityContext.capabilities | nindent 12 }} seccompProfile: {{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hdfs-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hdfs-common-config + mountPath: /etc/jmx-exporter/hdfs-jmx-exporter.yaml + subPath: hdfs-jmx-exporter.yaml securityContext: fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} fsGroup: {{ .Values.securityContext.fsGroup }} @@ -164,6 +185,16 @@ spec: value: {{ .Values.extra.clusterDomain }} - name: HDFS_CONF_DIR value: {{ .Values.runtime.configDir }} + - name: HDFS_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_NAMENODE_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_DATANODE_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_JOURNALNODE_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_ZKFC_JMX_PORT + value: {{ .Values.hdfs.ports.zkfc.jmx | quote }} - name: NAMENODE_POD_FQDN_LIST valueFrom: componentVarRef: diff --git a/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml index 62bce66f20..8895fe3c52 100644 --- a/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-journalnode.yaml @@ -10,6 +10,9 @@ spec: provider: kubeblocks description: {{ .Chart.Description }} serviceKind: hdfs-journalnode + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -102,9 +105,6 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hdfs-common-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties - subPath: hadoop-metrics2.properties - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include @@ -131,6 +131,27 @@ spec: {{ toYaml .Values.securityContext.capabilities | nindent 12 }} seccompProfile: {{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hdfs-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hdfs-common-config + mountPath: /etc/jmx-exporter/hdfs-jmx-exporter.yaml + subPath: hdfs-jmx-exporter.yaml securityContext: fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} fsGroup: {{ .Values.securityContext.fsGroup }} @@ -156,6 +177,16 @@ spec: podFQDNs: Required - name: HDFS_CONF_DIR value: {{ .Values.runtime.configDir }} + - name: HDFS_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_NAMENODE_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_DATANODE_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_JOURNALNODE_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_ZKFC_JMX_PORT + value: {{ .Values.hdfs.ports.zkfc.jmx | quote }} - name: HDFS_JOURNALNODE_EDITS_DIR value: {{ .Values.hdfs.paths.journalnodeEditsDir | quote }} - name: HDFS_JOURNALNODE_RPC_PORT diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml index 6fc6c1a346..cad435ff48 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode-standalone.yaml @@ -10,6 +10,9 @@ spec: provider: kubeblocks description: {{ .Chart.Description }} serviceKind: hdfs-namenode-standalone + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -151,9 +154,6 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hdfs-common-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties - subPath: hadoop-metrics2.properties - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include @@ -180,6 +180,27 @@ spec: {{ toYaml .Values.securityContext.capabilities | nindent 12 }} seccompProfile: {{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hdfs-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hdfs-common-config + mountPath: /etc/jmx-exporter/hdfs-jmx-exporter.yaml + subPath: hdfs-jmx-exporter.yaml securityContext: fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} fsGroup: {{ .Values.securityContext.fsGroup }} @@ -206,6 +227,16 @@ spec: value: {{ .Values.extra.clusterDomain }} - name: HDFS_CONF_DIR value: {{ .Values.runtime.configDir }} + - name: HDFS_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_NAMENODE_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_DATANODE_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_JOURNALNODE_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_ZKFC_JMX_PORT + value: {{ .Values.hdfs.ports.zkfc.jmx | quote }} - name: HDFS_NAMENODE_NAME_DIR value: {{ .Values.hdfs.paths.namenodeMetadataDir | quote }} - name: HDFS_NAMENODE_RPC_PORT diff --git a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml index 26a926421a..94193d5867 100644 --- a/addons/hadoop/templates/cmpd-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpd-hdfs-namenode.yaml @@ -10,6 +10,9 @@ spec: provider: kubeblocks description: {{ .Chart.Description }} serviceKind: hdfs-namenode + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -193,9 +196,6 @@ spec: - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/hadoop-env.sh subPath: hadoop-env.sh - - name: hdfs-common-config - mountPath: {{ .Values.runtime.configDir }}/hadoop-metrics2.properties - subPath: hadoop-metrics2.properties - name: hdfs-common-config mountPath: {{ .Values.runtime.configDir }}/dfs.include subPath: dfs.include @@ -301,6 +301,27 @@ spec: {{ toYaml .Values.securityContext.capabilities | nindent 12 }} seccompProfile: {{ toYaml .Values.securityContext.seccompProfile | nindent 12 }} + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hdfs-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hdfs-common-config + mountPath: /etc/jmx-exporter/hdfs-jmx-exporter.yaml + subPath: hdfs-jmx-exporter.yaml securityContext: fsGroupChangePolicy: {{ .Values.securityContext.fsGroupChangePolicy }} fsGroup: {{ .Values.securityContext.fsGroup }} @@ -329,6 +350,16 @@ spec: value: {{ .Values.extra.clusterDomain }} - name: HDFS_CONF_DIR value: {{ .Values.runtime.configDir }} + - name: HDFS_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_NAMENODE_JMX_PORT + value: {{ .Values.hdfs.ports.namenode.jmx | quote }} + - name: HDFS_DATANODE_JMX_PORT + value: {{ .Values.hdfs.ports.datanode.jmx | quote }} + - name: HDFS_JOURNALNODE_JMX_PORT + value: {{ .Values.hdfs.ports.journalnode.jmx | quote }} + - name: HDFS_ZKFC_JMX_PORT + value: {{ .Values.hdfs.ports.zkfc.jmx | quote }} - name: JOURNALNODE_POD_FQDN_LIST valueFrom: componentVarRef: diff --git a/addons/hadoop/templates/cmpv-hdfs-datanode.yaml b/addons/hadoop/templates/cmpv-hdfs-datanode.yaml index 867eb8d350..82d934d8a7 100644 --- a/addons/hadoop/templates/cmpv-hdfs-datanode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-datanode.yaml @@ -19,3 +19,4 @@ spec: images: hadoop-common: {{ include "hadoop.commonImage" . | quote }} hdfs-datanode: {{ include "hadoop.dataNodeImage" . | quote }} + jmx-exporter: {{ include "hadoop.jmxExporterImage" . | quote }} diff --git a/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml b/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml index 1144a66250..6b0a67cc82 100644 --- a/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-journalnode.yaml @@ -17,4 +17,5 @@ spec: serviceVersion: v3.3.4 images: hadoop-common: {{ include "hadoop.commonImage" . | quote }} - hdfs-journalnode: {{ include "hadoop.journalNodeImage" . | quote }} \ No newline at end of file + hdfs-journalnode: {{ include "hadoop.journalNodeImage" . | quote }} + jmx-exporter: {{ include "hadoop.jmxExporterImage" . | quote }} diff --git a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml index 3b6aebbd9d..3f21f367ac 100644 --- a/addons/hadoop/templates/cmpv-hdfs-namenode.yaml +++ b/addons/hadoop/templates/cmpv-hdfs-namenode.yaml @@ -22,3 +22,4 @@ spec: init-zkfc-format: {{ include "hadoop.initZkfcFormatImage" . | quote }} hdfs-namenode: {{ include "hadoop.nameNodeImage" . | quote }} hdfs-zkfc: {{ include "hadoop.nameNodeImage" . | quote }} + jmx-exporter: {{ include "hadoop.jmxExporterImage" . | quote }} diff --git a/addons/hadoop/templates/hdfs-common-config-template.yaml b/addons/hadoop/templates/hdfs-common-config-template.yaml index a8fd138f41..f3e3d79a5e 100644 --- a/addons/hadoop/templates/hdfs-common-config-template.yaml +++ b/addons/hadoop/templates/hdfs-common-config-template.yaml @@ -9,8 +9,8 @@ data: {{- .Files.Get "config/core-site.tpl" | nindent 4 }} hadoop-env.sh: |- {{- .Files.Get "config/hadoop-env.sh.tpl" | nindent 4 }} - hadoop-metrics2.properties: |- - {{- .Files.Get "config/hadoop-metrics2.properties.tpl" | nindent 4 }} + hdfs-jmx-exporter.yaml: |- + {{- .Files.Get "config/hdfs-jmx-exporter.yaml.tpl" | nindent 4 }} dfs.include: | {{- .Files.Get "config/dfs.include" | nindent 4 }} dfs.exclude: | diff --git a/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml b/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml index 316a3655e0..ee34eefd33 100644 --- a/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml +++ b/addons/hadoop/templates/hdfs-common-standalone-config-template.yaml @@ -9,8 +9,8 @@ data: {{- .Files.Get "config/core-site-standalone.tpl" | nindent 4 }} hadoop-env.sh: |- {{- .Files.Get "config/hadoop-env.sh.tpl" | nindent 4 }} - hadoop-metrics2.properties: |- - {{- .Files.Get "config/hadoop-metrics2.properties.tpl" | nindent 4 }} + hdfs-jmx-exporter.yaml: |- + {{- .Files.Get "config/hdfs-jmx-exporter.yaml.tpl" | nindent 4 }} dfs.include: | {{- .Files.Get "config/dfs.include" | nindent 4 }} dfs.exclude: | diff --git a/addons/hadoop/values.yaml b/addons/hadoop/values.yaml index 8652a17e6e..bf06c23f5a 100644 --- a/addons/hadoop/values.yaml +++ b/addons/hadoop/values.yaml @@ -5,6 +5,10 @@ image: repository: apecloud/hdfs-journalnode tag: "v3.3.4-1.0.0" pullPolicy: IfNotPresent + jmxExporter: + registry: docker.io + repository: apecloud/jmx-exporter + tag: 0.18.0-debian-11-r20 journalNode: image: @@ -44,6 +48,14 @@ extra: terminationPolicy: Delete clusterDomain: cluster.local +exporter: + securityContext: + runAsNonRoot: true + runAsUser: 1001 + +jmxExporter: + port: 5556 + runtime: debug: false hadoopHome: /opt/kubeemr/hadoop/hadoop-3.3.4 @@ -97,13 +109,18 @@ hdfs: namenode: rpc: 8020 http: 9870 + jmx: 10101 journalnode: rpc: 8485 http: 8480 + jmx: 10103 datanode: data: 9866 ipc: 9867 http: 9864 + jmx: 10102 + zkfc: + jmx: 10104 paths: namenodeMetadataDir: /hadoop/dfs/metadata namenodeJournalDir: /hadoop/dfs/journal diff --git a/addons/hbase/README.md b/addons/hbase/README.md index 8cbdf95e8c..ec91e0aacf 100644 --- a/addons/hbase/README.md +++ b/addons/hbase/README.md @@ -87,6 +87,25 @@ spec: topology: standalone ``` +## Observability + +HBase metrics are now exposed through a `jmx-exporter` sidecar instead of the old `metrics2 JmxSink` path. + +- the old `hadoop-metrics2-hbase.properties` JmxSink path has been removed +- `hmaster`, `hregionserver`, and `hbase-standalone` now include a `jmx-exporter` sidecar +- the exporter scrapes local JVM JMX over loopback and exposes `/metrics` + +If you want Prometheus discovery metadata on the component service, set `spec.componentSpecs[*].disableExporter=false` in the deployed `Cluster`. + +Typical PodMonitor endpoint: + +```yaml +podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http +``` + ## Quick Start ### Install the Addon diff --git a/addons/hbase/README.zh-CN.md b/addons/hbase/README.zh-CN.md index 9fefa8ca7e..5b2d100588 100644 --- a/addons/hbase/README.zh-CN.md +++ b/addons/hbase/README.zh-CN.md @@ -90,6 +90,25 @@ spec: topology: standalone ``` +## 监控说明 + +HBase 当前的监控出口已经切到 `jmx-exporter` sidecar,不再依赖旧的 `metrics2 JmxSink`。 + +- 旧的 `hadoop-metrics2-hbase.properties` JmxSink 路径已经移除 +- `hmaster`、`hregionserver` 和 `hbase-standalone` 现在都会带一个 `jmx-exporter` sidecar +- sidecar 通过本地 loopback 抓取 JVM JMX,并对外暴露 `/metrics` + +如果希望组件 Service 上带 Prometheus 发现信息,需要在实际部署的 `Cluster` 里将 `spec.componentSpecs[*].disableExporter=false`。 + +典型的 `PodMonitor` endpoint 如下: + +```yaml +podMetricsEndpoints: + - path: /metrics + port: http-metrics + scheme: http +``` + ## 快速开始 ### 安装 Addon diff --git a/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl b/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl deleted file mode 100644 index d400f079cc..0000000000 --- a/addons/hbase/config/hadoop-metrics2-hbase.properties.tpl +++ /dev/null @@ -1,4 +0,0 @@ -*.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink -*.period=10 - -hbase.sink.jmx.class=org.apache.hadoop.metrics2.sink.JmxSink diff --git a/addons/hbase/config/hbase-env.sh.tpl b/addons/hbase/config/hbase-env.sh.tpl index de7ec996aa..d94f85e38d 100644 --- a/addons/hbase/config/hbase-env.sh.tpl +++ b/addons/hbase/config/hbase-env.sh.tpl @@ -7,9 +7,9 @@ export HBASE_OPTS="${HBASE_OPTS:-} -XX:+UseG1GC -XX:MaxGCPauseMillis=50 -XX:Para export SERVER_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:${HBASE_LOG_DIR}/gc-server.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=50M" export CLIENT_GC_OPTS="-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps" -export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false" -export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_MASTER_JMX_PORT }} -Xms{{ .HBASE_MASTER_HEAP_SIZE }} -Xmx{{ .HBASE_MASTER_HEAP_SIZE }}" -export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Dhbase.regionserver.hostname=${POD_FQDN} -Xms{{ .HBASE_REGIONSERVER_HEAP_SIZE }} -Xmx{{ .HBASE_REGIONSERVER_HEAP_SIZE }}" +export HBASE_JMX_BASE="-Dcom.sun.management.jmxremote -Dcom.sun.management.jmxremote.local.only=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote.authenticate=false -Djava.rmi.server.hostname=127.0.0.1" +export HBASE_MASTER_OPTS="$HBASE_MASTER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_MASTER_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HBASE_MASTER_JMX_PORT }} -Xms{{ .HBASE_MASTER_HEAP_SIZE }} -Xmx{{ .HBASE_MASTER_HEAP_SIZE }}" +export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS $HBASE_JMX_BASE -Dcom.sun.management.jmxremote.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Dcom.sun.management.jmxremote.rmi.port={{ .HBASE_REGIONSERVER_JMX_PORT }} -Dhbase.regionserver.hostname=${POD_FQDN} -Xms{{ .HBASE_REGIONSERVER_HEAP_SIZE }} -Xmx{{ .HBASE_REGIONSERVER_HEAP_SIZE }}" export HBASE_HEAPSIZE={{ .HBASE_HEAP_SIZE }} export HBASE_DISABLE_HADOOP_CLASSPATH_LOOKUP=true diff --git a/addons/hbase/config/hbase-jmx-exporter.yaml.tpl b/addons/hbase/config/hbase-jmx-exporter.yaml.tpl new file mode 100644 index 0000000000..050f7e28e7 --- /dev/null +++ b/addons/hbase/config/hbase-jmx-exporter.yaml.tpl @@ -0,0 +1,9 @@ +jmxUrl: service:jmx:rmi:///jndi/rmi://127.0.0.1:{{ .HBASE_JMX_PORT }}/jmxrmi +ssl: false +lowercaseOutputName: true +lowercaseOutputLabelNames: true +whitelistObjectNames: + - "Hadoop:*" + - "java.lang:*" +rules: + - pattern: ".*" diff --git a/addons/hbase/templates/_helpers.tpl b/addons/hbase/templates/_helpers.tpl index e2ccdede15..02c59b357d 100644 --- a/addons/hbase/templates/_helpers.tpl +++ b/addons/hbase/templates/_helpers.tpl @@ -68,3 +68,7 @@ Image references {{- define "hbase.hbaseStandaloneImage" -}} {{ .Values.hbasestandalone.image.registry }}/{{ .Values.hbasestandalone.image.repository }}:{{ .Values.hbasestandalone.image.tag }} {{- end }} + +{{- define "hbase.jmxExporterImage" -}} +{{ .Values.images.jmxExporter.registry }}/{{ .Values.images.jmxExporter.repository }}:{{ .Values.images.jmxExporter.tag }} +{{- end }} diff --git a/addons/hbase/templates/cmpd-hbase-standalone.yaml b/addons/hbase/templates/cmpd-hbase-standalone.yaml index 1bed3a8fc2..d626203931 100644 --- a/addons/hbase/templates/cmpd-hbase-standalone.yaml +++ b/addons/hbase/templates/cmpd-hbase-standalone.yaml @@ -12,6 +12,9 @@ spec: serviceKind: hbase-standalone serviceVersion: 2.5.6 updateStrategy: BestEffortParallel + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -91,9 +94,6 @@ spec: - name: hbase-standalone-config mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh subPath: hbase-env.sh - - name: hbase-standalone-config - mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties - subPath: hadoop-metrics2-hbase.properties - name: hbase-standalone-config mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties subPath: log4j.properties @@ -115,6 +115,27 @@ spec: drop: [ "ALL" ] seccompProfile: type: "RuntimeDefault" + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hbase-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hbase-standalone-config + mountPath: /etc/jmx-exporter/hbase-jmx-exporter.yaml + subPath: hbase-jmx-exporter.yaml securityContext: fsGroupChangePolicy: Always fsGroup: {{ .Values.securityContext.fsGroup }} @@ -148,6 +169,8 @@ spec: value: {{ .Values.runtime.hadoopNativeLibPath }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} + - name: HBASE_JMX_PORT + value: {{ .Values.ports.hmaster.jmx | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE value: {{ .Values.jvm.hbasestandaloneHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT diff --git a/addons/hbase/templates/cmpd-hmaster.yaml b/addons/hbase/templates/cmpd-hmaster.yaml index 6d076277fd..c206f6ff8b 100644 --- a/addons/hbase/templates/cmpd-hmaster.yaml +++ b/addons/hbase/templates/cmpd-hmaster.yaml @@ -12,6 +12,9 @@ spec: serviceKind: hbase-hmaster serviceVersion: 2.5.6 updateStrategy: BestEffortParallel + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -132,9 +135,6 @@ spec: - name: hbase-config mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh subPath: hbase-env.sh - - name: hbase-config - mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties - subPath: hadoop-metrics2-hbase.properties - name: hbase-config mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties subPath: log4j.properties @@ -154,6 +154,27 @@ spec: drop: [ "ALL" ] seccompProfile: type: "RuntimeDefault" + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hbase-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hbase-config + mountPath: /etc/jmx-exporter/hbase-jmx-exporter.yaml + subPath: hbase-jmx-exporter.yaml securityContext: fsGroupChangePolicy: Always fsGroup: {{ .Values.securityContext.fsGroup }} @@ -185,6 +206,8 @@ spec: value: {{ .Values.runtime.hadoopNativeLibPath }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hmasterHeapSize | quote }} + - name: HBASE_JMX_PORT + value: {{ .Values.ports.hmaster.jmx | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE value: {{ .Values.jvm.hregionserverHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT diff --git a/addons/hbase/templates/cmpd-hregionserver.yaml b/addons/hbase/templates/cmpd-hregionserver.yaml index 2bbd15b653..c7af573ca4 100644 --- a/addons/hbase/templates/cmpd-hregionserver.yaml +++ b/addons/hbase/templates/cmpd-hregionserver.yaml @@ -12,6 +12,9 @@ spec: serviceKind: hbase-hregionserver serviceVersion: 2.5.6 updateStrategy: BestEffortParallel + exporter: + containerName: jmx-exporter + scrapePath: /metrics services: - name: default spec: @@ -95,9 +98,6 @@ spec: - name: hbase-config mountPath: {{ .Values.runtime.hbaseConfDir }}/hbase-env.sh subPath: hbase-env.sh - - name: hbase-config - mountPath: {{ .Values.runtime.hbaseConfDir }}/hadoop-metrics2-hbase.properties - subPath: hadoop-metrics2-hbase.properties - name: hbase-config mountPath: {{ .Values.runtime.hbaseConfDir }}/log4j.properties subPath: log4j.properties @@ -117,6 +117,27 @@ spec: drop: [ "ALL" ] seccompProfile: type: "RuntimeDefault" + - name: jmx-exporter + imagePullPolicy: IfNotPresent + securityContext: + runAsNonRoot: {{ .Values.exporter.securityContext.runAsNonRoot }} + runAsUser: {{ .Values.exporter.securityContext.runAsUser }} + command: + - java + args: + - -XX:MaxRAMPercentage=100 + - -XshowSettings:vm + - -jar + - jmx_prometheus_httpserver.jar + - {{ .Values.jmxExporter.port | quote }} + - /etc/jmx-exporter/hbase-jmx-exporter.yaml + ports: + - name: http-metrics + containerPort: {{ .Values.jmxExporter.port }} + volumeMounts: + - name: hbase-config + mountPath: /etc/jmx-exporter/hbase-jmx-exporter.yaml + subPath: hbase-jmx-exporter.yaml securityContext: fsGroupChangePolicy: Always fsGroup: {{ .Values.securityContext.fsGroup }} @@ -148,6 +169,8 @@ spec: value: {{ .Values.runtime.hadoopNativeLibPath }} - name: HBASE_MASTER_HEAP_SIZE value: {{ .Values.jvm.hmasterHeapSize | quote }} + - name: HBASE_JMX_PORT + value: {{ .Values.ports.hregionserver.jmx | quote }} - name: HBASE_REGIONSERVER_HEAP_SIZE value: {{ .Values.jvm.hregionserverHeapSize | quote }} - name: HBASE_MASTER_JMX_PORT diff --git a/addons/hbase/templates/cmpv-hbase-standalone.yaml b/addons/hbase/templates/cmpv-hbase-standalone.yaml index 8533d2122d..31eb225a42 100644 --- a/addons/hbase/templates/cmpv-hbase-standalone.yaml +++ b/addons/hbase/templates/cmpv-hbase-standalone.yaml @@ -17,3 +17,4 @@ spec: serviceVersion: 2.5.6 images: hbase-standalone: {{ include "hbase.hbaseStandaloneImage" . | quote }} + jmx-exporter: {{ include "hbase.jmxExporterImage" . | quote }} diff --git a/addons/hbase/templates/cmpv-hmaster.yaml b/addons/hbase/templates/cmpv-hmaster.yaml index 8669d6c677..e6c321c859 100644 --- a/addons/hbase/templates/cmpv-hmaster.yaml +++ b/addons/hbase/templates/cmpv-hmaster.yaml @@ -18,3 +18,4 @@ spec: images: init-hdfs-root-layout: {{ include "hbase.hmasterImage" . | quote }} hbase-hmaster: {{ include "hbase.hmasterImage" . | quote }} + jmx-exporter: {{ include "hbase.jmxExporterImage" . | quote }} diff --git a/addons/hbase/templates/cmpv-hregionserver.yaml b/addons/hbase/templates/cmpv-hregionserver.yaml index a4208ea1f6..01970cc976 100644 --- a/addons/hbase/templates/cmpv-hregionserver.yaml +++ b/addons/hbase/templates/cmpv-hregionserver.yaml @@ -17,3 +17,4 @@ spec: serviceVersion: 2.5.6 images: hbase-hregionserver: {{ include "hbase.hregionserverImage" . | quote }} + jmx-exporter: {{ include "hbase.jmxExporterImage" . | quote }} diff --git a/addons/hbase/templates/hbase-cluster-config-template.yaml b/addons/hbase/templates/hbase-cluster-config-template.yaml index 20793f0872..6409b7284f 100644 --- a/addons/hbase/templates/hbase-cluster-config-template.yaml +++ b/addons/hbase/templates/hbase-cluster-config-template.yaml @@ -13,7 +13,7 @@ data: {{- .Files.Get "config/hdfs-client-site.tpl" | nindent 4 }} hbase-env.sh: |- {{- .Files.Get "config/hbase-env.sh.tpl" | nindent 4 }} - hadoop-metrics2-hbase.properties: |- - {{- .Files.Get "config/hadoop-metrics2-hbase.properties.tpl" | nindent 4 }} + hbase-jmx-exporter.yaml: |- + {{- .Files.Get "config/hbase-jmx-exporter.yaml.tpl" | nindent 4 }} log4j.properties: |- {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hbase/templates/hbase-standalone-config-template.yaml b/addons/hbase/templates/hbase-standalone-config-template.yaml index 34332f371a..cd673611ed 100644 --- a/addons/hbase/templates/hbase-standalone-config-template.yaml +++ b/addons/hbase/templates/hbase-standalone-config-template.yaml @@ -9,7 +9,7 @@ data: {{- .Files.Get "config/hbase-site-standalone.tpl" | nindent 4 }} hbase-env.sh: |- {{- .Files.Get "config/hbase-env.sh.tpl" | nindent 4 }} - hadoop-metrics2-hbase.properties: |- - {{- .Files.Get "config/hadoop-metrics2-hbase.properties.tpl" | nindent 4 }} + hbase-jmx-exporter.yaml: |- + {{- .Files.Get "config/hbase-jmx-exporter.yaml.tpl" | nindent 4 }} log4j.properties: |- {{- .Files.Get "config/log4j.properties" | nindent 4 }} diff --git a/addons/hbase/values.yaml b/addons/hbase/values.yaml index 58c85ce454..d9d8f184e8 100644 --- a/addons/hbase/values.yaml +++ b/addons/hbase/values.yaml @@ -19,6 +19,12 @@ hbasestandalone: tag: "v2.5.6-1.0.0" pullPolicy: IfNotPresent +images: + jmxExporter: + registry: docker.io + repository: apecloud/jmx-exporter + tag: 0.18.0-debian-11-r20 + runtime: hbaseHome: /opt/hbase-2.5.6 hbaseConfDir: /hbase/conf @@ -64,6 +70,14 @@ extra: terminationPolicy: Delete clusterDomain: cluster.local +exporter: + securityContext: + runAsNonRoot: true + runAsUser: 1001 + +jmxExporter: + port: 5556 + securityContext: runAsUser: 10000 runAsGroup: 1000 From 31edb49c94b09f958bd9c806eaedae7f3ecdd5f9 Mon Sep 17 00:00:00 2001 From: zhangbaojun Date: Fri, 10 Jul 2026 15:27:43 +0800 Subject: [PATCH 18/18] feat(hbase): use bundled java lz4 codec for compression sanity check --- addons/hbase/config/hbase-site-cluster.tpl | 7 ++++++- addons/hbase/config/hbase-site-standalone.tpl | 5 +++++ addons/hbase/config/hdfs-common-site.tpl | 2 +- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/addons/hbase/config/hbase-site-cluster.tpl b/addons/hbase/config/hbase-site-cluster.tpl index 80dc5b1a17..a61443e4db 100644 --- a/addons/hbase/config/hbase-site-cluster.tpl +++ b/addons/hbase/config/hbase-site-cluster.tpl @@ -282,8 +282,13 @@ true + + hbase.io.compress.lz4.codec + org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec + + hbase.splitlog.manager.timeout {{ .HBASE_SPLITLOG_MANAGER_TIMEOUT }} - \ No newline at end of file + diff --git a/addons/hbase/config/hbase-site-standalone.tpl b/addons/hbase/config/hbase-site-standalone.tpl index 0a59c11fef..e853614f6a 100644 --- a/addons/hbase/config/hbase-site-standalone.tpl +++ b/addons/hbase/config/hbase-site-standalone.tpl @@ -126,6 +126,11 @@ {{ .HBASE_REPLICATION_ENABLED }} + + hbase.io.compress.lz4.codec + org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec + + hbase.security.authentication {{ .HBASE_SECURITY_AUTHENTICATION }} diff --git a/addons/hbase/config/hdfs-common-site.tpl b/addons/hbase/config/hdfs-common-site.tpl index 389d7de245..a84043543b 100644 --- a/addons/hbase/config/hdfs-common-site.tpl +++ b/addons/hbase/config/hdfs-common-site.tpl @@ -13,7 +13,7 @@ io.compression.codecs - org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec + org.apache.hadoop.io.compress.GzipCodec,org.apache.hadoop.io.compress.DefaultCodec,org.apache.hadoop.io.compress.BZip2Codec,org.apache.hadoop.io.compress.SnappyCodec,org.apache.hadoop.hbase.io.compress.lz4.Lz4Codec