Skip to content

Commit 0664d80

Browse files
authored
chore: remove 2.4 support (including JMX exporter) (#672)
* chore: remove code supporting HBase 2.4 * add metrics integration test * update changelog * remove unused function parameter * fix region server metric * review feedback
1 parent 2d97646 commit 0664d80

File tree

10 files changed

+106
-151
lines changed

10 files changed

+106
-151
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@
3737
- test: ZooKeeper 3.9.2 removed ([#654]).
3838
- test: Remove HDFS `3.3.4`, `3.3.6`, and `3.4.0` ([#655]).
3939
- test: HBase 2.4.18 removed ([#659]):
40+
- Remove operator support for HBase 2.4 including the JMX exporter ([#672]).
4041

4142
[#640]: https://github.com/stackabletech/hbase-operator/pull/640
4243
[#645]: https://github.com/stackabletech/hbase-operator/pull/645
@@ -49,6 +50,7 @@
4950
[#659]: https://github.com/stackabletech/hbase-operator/pull/659
5051
[#660]: https://github.com/stackabletech/hbase-operator/pull/660
5152
[#661]: https://github.com/stackabletech/hbase-operator/pull/661
53+
[#672]: https://github.com/stackabletech/hbase-operator/pull/672
5254

5355
## [25.3.0] - 2025-03-21
5456

docs/modules/hbase/pages/usage-guide/monitoring.adoc

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,3 @@ Starting with HBase 2.6 the URL for Prometheus metrics has changed.
88
This is because HBase offers now a built-in endpoint for this purpose.
99
This endpoint is available from the UI service.
1010
For example, in the case of the master service, the URL is `http://<master-service>:16010/prometheus`.
11-
The old URL `http://<master-service>:9100` is still available for HBase 2.4.

rust/operator-binary/src/config/jvm.rs

Lines changed: 9 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ use stackable_operator::{
55
};
66

77
use crate::crd::{
8-
AnyServiceConfig, CONFIG_DIR_NAME, HbaseRole, JVM_SECURITY_PROPERTIES_FILE, METRICS_PORT,
9-
v1alpha1,
8+
AnyServiceConfig, CONFIG_DIR_NAME, HbaseRole, JVM_SECURITY_PROPERTIES_FILE, v1alpha1,
109
};
1110

1211
const JAVA_HEAP_FACTOR: f32 = 0.8;
@@ -53,18 +52,11 @@ pub fn construct_role_specific_non_heap_jvm_args(
5352
hbase: &v1alpha1::HbaseCluster,
5453
hbase_role: &HbaseRole,
5554
role_group: &str,
56-
product_version: &str,
5755
) -> Result<String, Error> {
5856
let mut jvm_args = vec![format!(
5957
"-Djava.security.properties={CONFIG_DIR_NAME}/{JVM_SECURITY_PROPERTIES_FILE}"
6058
)];
6159

62-
// Starting with HBase 2.6 the JVM exporter is not needed anymore
63-
if product_version.starts_with("2.4") || product_version.starts_with("2.5") {
64-
jvm_args.push(
65-
format!("-javaagent:/stackable/jmx/jmx_prometheus_javaagent.jar={METRICS_PORT}:/stackable/jmx/{hbase_role}.yaml")
66-
);
67-
}
6860
if hbase.has_kerberos_enabled() {
6961
jvm_args.push("-Djava.security.krb5.conf=/stackable/kerberos/krb5.conf".to_owned());
7062
}
@@ -168,17 +160,11 @@ mod tests {
168160
default:
169161
replicas: 1
170162
"#;
171-
let (hbase, hbase_role, merged_config, role_group, product_version) =
172-
construct_boilerplate(input);
163+
let (hbase, hbase_role, merged_config, role_group) = construct_boilerplate(input);
173164

174165
let global_jvm_args = construct_global_jvm_args(false);
175-
let role_specific_non_heap_jvm_args = construct_role_specific_non_heap_jvm_args(
176-
&hbase,
177-
&hbase_role,
178-
&role_group,
179-
&product_version,
180-
)
181-
.unwrap();
166+
let role_specific_non_heap_jvm_args =
167+
construct_role_specific_non_heap_jvm_args(&hbase, &hbase_role, &role_group).unwrap();
182168
let hbase_heapsize_env = construct_hbase_heapsize_env(&merged_config).unwrap();
183169

184170
assert_eq!(global_jvm_args, "");
@@ -230,17 +216,11 @@ mod tests {
230216
- -Xmx40000m # This has no effect!
231217
- -Dhttps.proxyPort=1234
232218
"#;
233-
let (hbase, hbase_role, merged_config, role_group, product_version) =
234-
construct_boilerplate(input);
219+
let (hbase, hbase_role, merged_config, role_group) = construct_boilerplate(input);
235220

236221
let global_jvm_args = construct_global_jvm_args(hbase.has_kerberos_enabled());
237-
let role_specific_non_heap_jvm_args = construct_role_specific_non_heap_jvm_args(
238-
&hbase,
239-
&hbase_role,
240-
&role_group,
241-
&product_version,
242-
)
243-
.unwrap();
222+
let role_specific_non_heap_jvm_args =
223+
construct_role_specific_non_heap_jvm_args(&hbase, &hbase_role, &role_group).unwrap();
244224
let hbase_heapsize_env = construct_hbase_heapsize_env(&merged_config).unwrap();
245225

246226
assert_eq!(
@@ -260,28 +240,15 @@ mod tests {
260240

261241
fn construct_boilerplate(
262242
hbase_cluster: &str,
263-
) -> (
264-
v1alpha1::HbaseCluster,
265-
HbaseRole,
266-
AnyServiceConfig,
267-
String,
268-
String,
269-
) {
243+
) -> (v1alpha1::HbaseCluster, HbaseRole, AnyServiceConfig, String) {
270244
let hbase: v1alpha1::HbaseCluster =
271245
serde_yaml::from_str(hbase_cluster).expect("illegal test input");
272246

273247
let hbase_role = HbaseRole::RegionServer;
274248
let merged_config = hbase
275249
.merged_config(&hbase_role, "default", "my-hdfs")
276250
.unwrap();
277-
let product_version = hbase.spec.image.product_version().to_owned();
278251

279-
(
280-
hbase,
281-
hbase_role,
282-
merged_config,
283-
"default".to_owned(),
284-
product_version,
285-
)
252+
(hbase, hbase_role, merged_config, "default".to_owned())
286253
}
287254
}

rust/operator-binary/src/crd/mod.rs

Lines changed: 4 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,6 @@ pub const HBASE_UI_PORT_NAME_HTTP: &str = "ui-http";
6666
pub const HBASE_UI_PORT_NAME_HTTPS: &str = "ui-https";
6767
pub const HBASE_REST_PORT_NAME_HTTP: &str = "rest-http";
6868
pub const HBASE_REST_PORT_NAME_HTTPS: &str = "rest-https";
69-
pub const METRICS_PORT_NAME: &str = "metrics";
7069

7170
pub const HBASE_MASTER_PORT: u16 = 16000;
7271
// HBase always uses 16010, regardless of http or https. On 2024-01-17 we decided in Arch-meeting that we want to stick
@@ -77,9 +76,6 @@ pub const HBASE_REGIONSERVER_PORT: u16 = 16020;
7776
pub const HBASE_REGIONSERVER_UI_PORT: u16 = 16030;
7877
pub const HBASE_REST_PORT: u16 = 8080;
7978
pub const HBASE_REST_UI_PORT: u16 = 8085;
80-
// This port is only used by Hbase prior to version 2.6 with a third-party JMX exporter.
81-
// Newer versions use the same port as the UI because Hbase provides it's own metrics API
82-
pub const METRICS_PORT: u16 = 9100;
8379

8480
const DEFAULT_REGION_MOVER_TIMEOUT: Duration = Duration::from_minutes_unchecked(59);
8581
const DEFAULT_REGION_MOVER_DELTA_TO_SHUTDOWN: Duration = Duration::from_minutes_unchecked(1);
@@ -494,11 +490,10 @@ impl v1alpha1::HbaseCluster {
494490
}
495491

496492
/// Returns required port name and port number tuples depending on the role.
497-
/// Hbase versions 2.4.* will have three ports for each role
498493
/// Hbase versions 2.6.* will have two ports for each role. The metrics are available over the
499494
/// UI port.
500-
pub fn ports(&self, role: &HbaseRole, hbase_version: &str) -> Vec<(String, u16)> {
501-
let result_without_metric_port: Vec<(String, u16)> = match role {
495+
pub fn ports(&self, role: &HbaseRole) -> Vec<(String, u16)> {
496+
match role {
502497
HbaseRole::Master => vec![
503498
("master".to_string(), HBASE_MASTER_PORT),
504499
(self.ui_port_name(), HBASE_MASTER_UI_PORT),
@@ -519,14 +514,6 @@ impl v1alpha1::HbaseCluster {
519514
),
520515
(self.ui_port_name(), HBASE_REST_UI_PORT),
521516
],
522-
};
523-
if hbase_version.starts_with(r"2.4") {
524-
result_without_metric_port
525-
.into_iter()
526-
.chain(vec![(METRICS_PORT_NAME.to_string(), METRICS_PORT)])
527-
.collect()
528-
} else {
529-
result_without_metric_port
530517
}
531518
}
532519

@@ -956,7 +943,7 @@ impl Configuration for HbaseConfigFragment {
956943
HBASE_ENV_SH => {
957944
// The contents of this file cannot be built entirely here because we don't have
958945
// access to the clusterConfig or product version.
959-
// These are needed to set up Kerberos and JMX exporter settings.
946+
// These are needed to set up Kerberos.
960947
// To avoid fragmentation of the code needed to build this file, we moved the
961948
// implementation to the hbase_controller::build_hbase_env_sh() function.
962949
}
@@ -1107,7 +1094,7 @@ impl Configuration for RegionServerConfigFragment {
11071094
HBASE_ENV_SH => {
11081095
// The contents of this file cannot be built entirely here because we don't have
11091096
// access to the clusterConfig or product version.
1110-
// These are needed to set up Kerberos and JMX exporter settings.
1097+
// These are needed to set up Kerberos.
11111098
// To avoid fragmentation of the code needed to build this file, we moved the
11121099
// implementation to the hbase_controller::build_hbase_env_sh() function.
11131100
}

rust/operator-binary/src/hbase_controller.rs

Lines changed: 11 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -336,8 +336,6 @@ pub async fn reconcile_hbase(
336336

337337
let client = &ctx.client;
338338

339-
validate_cr(hbase)?;
340-
341339
let resolved_product_image = hbase
342340
.spec
343341
.image
@@ -515,7 +513,7 @@ pub fn build_region_server_role_service(
515513
.server_role_service_name()
516514
.context(GlobalServiceNameNotFoundSnafu)?;
517515
let ports = hbase
518-
.ports(&role, &resolved_product_image.product_version)
516+
.ports(&role)
519517
.into_iter()
520518
.map(|(name, value)| ServicePort {
521519
name: Some(name),
@@ -601,13 +599,8 @@ fn build_rolegroup_config_map(
601599
);
602600
}
603601
PropertyNameKind::File(file_name) if file_name == HBASE_ENV_SH => {
604-
let mut hbase_env_config = build_hbase_env_sh(
605-
hbase,
606-
merged_config,
607-
&hbase_role,
608-
&rolegroup.role_group,
609-
&resolved_product_image.product_version,
610-
)?;
602+
let mut hbase_env_config =
603+
build_hbase_env_sh(hbase, merged_config, &hbase_role, &rolegroup.role_group)?;
611604

612605
// configOverride come last
613606
hbase_env_config.extend(config.clone());
@@ -691,15 +684,11 @@ fn build_rolegroup_config_map(
691684
builder.add_data(SSL_CLIENT_XML, ssl_client_xml);
692685
}
693686

694-
extend_role_group_config_map(
695-
rolegroup,
696-
merged_config.logging(),
697-
&mut builder,
698-
&resolved_product_image.product_version,
699-
)
700-
.context(InvalidLoggingConfigSnafu {
701-
cm_name: rolegroup.object_name(),
702-
})?;
687+
extend_role_group_config_map(rolegroup, merged_config.logging(), &mut builder).context(
688+
InvalidLoggingConfigSnafu {
689+
cm_name: rolegroup.object_name(),
690+
},
691+
)?;
703692

704693
builder.build().map_err(|e| Error::BuildRoleGroupConfig {
705694
source: e,
@@ -717,7 +706,7 @@ fn build_rolegroup_service(
717706
resolved_product_image: &ResolvedProductImage,
718707
) -> Result<Service> {
719708
let ports = hbase
720-
.ports(hbase_role, &resolved_product_image.product_version)
709+
.ports(hbase_role)
721710
.into_iter()
722711
.map(|(name, value)| ServicePort {
723712
name: Some(name),
@@ -783,7 +772,7 @@ fn build_rolegroup_statefulset(
783772
let hbase_version = &resolved_product_image.app_version_label;
784773

785774
let ports = hbase
786-
.ports(hbase_role, &resolved_product_image.product_version)
775+
.ports(hbase_role)
787776
.into_iter()
788777
.map(|(name, value)| ContainerPort {
789778
name: Some(name),
@@ -1099,7 +1088,6 @@ fn build_hbase_env_sh(
10991088
merged_config: &AnyServiceConfig,
11001089
hbase_role: &HbaseRole,
11011090
role_group: &str,
1102-
product_version: &str,
11031091
) -> Result<BTreeMap<String, String>, Error> {
11041092
let mut result = BTreeMap::new();
11051093

@@ -1114,7 +1102,7 @@ fn build_hbase_env_sh(
11141102
construct_global_jvm_args(hbase.has_kerberos_enabled()),
11151103
);
11161104
let role_specific_non_heap_jvm_args =
1117-
construct_role_specific_non_heap_jvm_args(hbase, hbase_role, role_group, product_version)
1105+
construct_role_specific_non_heap_jvm_args(hbase, hbase_role, role_group)
11181106
.context(ConstructJvmArgumentSnafu)?;
11191107
match hbase_role {
11201108
HbaseRole::Master => {
@@ -1140,24 +1128,6 @@ fn build_hbase_env_sh(
11401128
Ok(result)
11411129
}
11421130

1143-
/// Ensures that no authorization is configured for HBase versions that do not support it.
1144-
/// In the future, such validations should be moved to the CRD CEL rules which are much more flexible
1145-
/// and have to added benefit that invalid CRs are rejected by the API server.
1146-
/// A requirement for this is that the minimum supported Kubernetes version is 1.29.
1147-
fn validate_cr(hbase: &v1alpha1::HbaseCluster) -> Result<()> {
1148-
tracing::info!("Begin CR validation");
1149-
1150-
let hbase_version = hbase.spec.image.product_version();
1151-
let authorization = hbase.spec.cluster_config.authorization.is_some();
1152-
1153-
if hbase_version.starts_with("2.4") && authorization {
1154-
tracing::error!("Invalid custom resource");
1155-
return Err(Error::AuthorizationNotSupported);
1156-
}
1157-
tracing::info!("End CR validation");
1158-
Ok(())
1159-
}
1160-
11611131
/// Build the domain name of an HBase service pod.
11621132
/// The hbase-entrypoint.sh script uses this to build the fully qualified name of a pod
11631133
/// by appending it to the `HOSTNAME` environment variable.

rust/operator-binary/src/product_logging.rs

Lines changed: 12 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,7 @@ pub enum Error {
4343
type Result<T, E = Error> = std::result::Result<T, E>;
4444

4545
const CONSOLE_CONVERSION_PATTERN: &str = "%d{ISO8601} %-5p [%t] %c{2}: %.1000m%n";
46-
const HBASE_LOG4J_FILE: &str = "hbase.log4j.xml";
4746
const HBASE_LOG4J2_FILE: &str = "hbase.log4j2.xml";
48-
pub const LOG4J_CONFIG_FILE: &str = "log4j.properties";
4947
pub const LOG4J2_CONFIG_FILE: &str = "log4j2.properties";
5048
pub const STACKABLE_LOG_DIR: &str = "/stackable/log";
5149
pub static CONTAINERDEBUG_LOG_DIRECTORY: std::sync::LazyLock<String> =
@@ -56,16 +54,12 @@ pub fn extend_role_group_config_map(
5654
rolegroup: &RoleGroupRef<v1alpha1::HbaseCluster>,
5755
logging: &Logging<Container>,
5856
cm_builder: &mut ConfigMapBuilder,
59-
hbase_version: &str,
6057
) -> Result<()> {
6158
if let Some(ContainerLogConfig {
6259
choice: Some(ContainerLogConfigChoice::Automatic(log_config)),
6360
}) = logging.containers.get(&Container::Hbase)
6461
{
65-
cm_builder.add_data(
66-
log4j_properties_file_name(hbase_version),
67-
log4j_config(hbase_version, log_config),
68-
);
62+
cm_builder.add_data(LOG4J2_CONFIG_FILE, log4j_config(log_config));
6963
}
7064

7165
let vector_log_config = if let Some(ContainerLogConfig {
@@ -87,41 +81,15 @@ pub fn extend_role_group_config_map(
8781
Ok(())
8882
}
8983

90-
pub fn log4j_properties_file_name(hbase_version: &str) -> &'static str {
91-
if needs_log4j2(hbase_version) {
92-
LOG4J2_CONFIG_FILE
93-
} else {
94-
LOG4J_CONFIG_FILE
95-
}
96-
}
97-
98-
fn log4j_config(hbase_version: &str, log_config: &AutomaticContainerLogConfig) -> String {
99-
if needs_log4j2(hbase_version) {
100-
product_logging::framework::create_log4j2_config(
101-
&format!("{STACKABLE_LOG_DIR}/hbase"),
102-
HBASE_LOG4J2_FILE,
103-
MAX_HBASE_LOG_FILES_SIZE
104-
.scale_to(BinaryMultiple::Mebi)
105-
.floor()
106-
.value as u32,
107-
CONSOLE_CONVERSION_PATTERN,
108-
log_config,
109-
)
110-
} else {
111-
product_logging::framework::create_log4j_config(
112-
&format!("{STACKABLE_LOG_DIR}/hbase"),
113-
HBASE_LOG4J_FILE,
114-
MAX_HBASE_LOG_FILES_SIZE
115-
.scale_to(BinaryMultiple::Mebi)
116-
.floor()
117-
.value as u32,
118-
CONSOLE_CONVERSION_PATTERN,
119-
log_config,
120-
)
121-
}
122-
}
123-
124-
// HBase 2.6 moved from log4j to log4j2
125-
fn needs_log4j2(hbase_version: &str) -> bool {
126-
!hbase_version.starts_with(r"2.4")
84+
fn log4j_config(log_config: &AutomaticContainerLogConfig) -> String {
85+
product_logging::framework::create_log4j2_config(
86+
&format!("{STACKABLE_LOG_DIR}/hbase"),
87+
HBASE_LOG4J2_FILE,
88+
MAX_HBASE_LOG_FILES_SIZE
89+
.scale_to(BinaryMultiple::Mebi)
90+
.floor()
91+
.value as u32,
92+
CONSOLE_CONVERSION_PATTERN,
93+
log_config,
94+
)
12795
}

tests/templates/kuttl/opa/30-install-hbase.yaml.j2

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,6 @@ commands:
2828
appender.console.name = STDOUT
2929
appender.console.layout.type = PatternLayout
3030
appender.console.layout.pattern = [%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n
31-
log4j.properties: |
32-
# Used by HBase 2.4
33-
log4j.rootLogger=INFO, FILE
34-
log4j.appender.FILE=org.apache.log4j.FileAppender
35-
log4j.appender.FILE.File=/stackable/log/hbase/hbase.log4j.xml
36-
log4j.appender.FILE.layout=org.apache.log4j.xml.XMLLayout
3731
---
3832
apiVersion: hbase.stackable.tech/v1alpha1
3933
kind: HbaseCluster

0 commit comments

Comments
 (0)