@@ -17,9 +17,12 @@ use stackable_hdfs_crd::{
17
17
constants:: {
18
18
DATANODE_ROOT_DATA_DIR_PREFIX , DEFAULT_DATA_NODE_METRICS_PORT ,
19
19
DEFAULT_JOURNAL_NODE_METRICS_PORT , DEFAULT_NAME_NODE_METRICS_PORT ,
20
- JVM_SECURITY_PROPERTIES_FILE , LISTENER_VOLUME_DIR , LISTENER_VOLUME_NAME , LOG4J_PROPERTIES ,
21
- NAMENODE_ROOT_DATA_DIR , SERVICE_PORT_NAME_IPC , SERVICE_PORT_NAME_RPC ,
22
- STACKABLE_ROOT_DATA_DIR ,
20
+ JVM_SECURITY_PROPERTIES_FILE , LISTENER_VOLUME_DIR , LISTENER_VOLUME_NAME ,
21
+ LIVENESS_PROBE_FAILURE_THRESHOLD , LIVENESS_PROBE_INITIAL_DELAY_SECONDS ,
22
+ LIVENESS_PROBE_PERIOD_SECONDS , LOG4J_PROPERTIES , NAMENODE_ROOT_DATA_DIR ,
23
+ READINESS_PROBE_FAILURE_THRESHOLD , READINESS_PROBE_INITIAL_DELAY_SECONDS ,
24
+ READINESS_PROBE_PERIOD_SECONDS , SERVICE_PORT_NAME_HTTP , SERVICE_PORT_NAME_HTTPS ,
25
+ SERVICE_PORT_NAME_IPC , SERVICE_PORT_NAME_RPC , STACKABLE_ROOT_DATA_DIR ,
23
26
} ,
24
27
storage:: DataNodeStorageConfig ,
25
28
AnyNodeConfig , DataNodeContainer , HdfsCluster , HdfsPodRef , HdfsRole , NameNodeContainer ,
@@ -35,8 +38,9 @@ use stackable_operator::{
35
38
k8s_openapi:: {
36
39
api:: core:: v1:: {
37
40
ConfigMapKeySelector , ConfigMapVolumeSource , Container , ContainerPort ,
38
- EmptyDirVolumeSource , EnvVar , EnvVarSource , ObjectFieldSelector , PersistentVolumeClaim ,
39
- Probe , ResourceRequirements , TCPSocketAction , Volume , VolumeMount ,
41
+ EmptyDirVolumeSource , EnvVar , EnvVarSource , HTTPGetAction , ObjectFieldSelector ,
42
+ PersistentVolumeClaim , Probe , ResourceRequirements , TCPSocketAction , Volume ,
43
+ VolumeMount ,
40
44
} ,
41
45
apimachinery:: pkg:: util:: intstr:: IntOrString ,
42
46
} ,
@@ -114,8 +118,21 @@ pub enum ContainerConfig {
114
118
container_name : String ,
115
119
/// Volume mounts for config and logging.
116
120
volume_mounts : ContainerVolumeDirs ,
117
- /// Readiness and liveness probe service port name.
118
- tcp_socket_action_port_name : & ' static str ,
121
+ /// Port name of the IPC/RPC port, used for the readiness probe.
122
+ ipc_port_name : & ' static str ,
123
+ /// Port name of the web UI HTTP port, used for the liveness probe.
124
+ web_ui_http_port_name : & ' static str ,
125
+ /// Port name of the web UI HTTPS port, used for the liveness probe.
126
+ web_ui_https_port_name : & ' static str ,
127
+ /// Path of the web UI URL; The path defaults to / in Kubernetes
128
+ /// and the kubelet follows redirects. The default would work if
129
+ /// the location header is set properly but that is not the case
130
+ /// for the DataNode. On a TLS-enabled DataNode, calling
131
+ /// https://127.0.0.1:9865/ redirects to the non-TLS URL
132
+ /// http://127.0.0.1:9865/index.html which causes the liveness
133
+ /// probe to fail. So it is best to not rely on the location
134
+ /// header but instead provide the resolved path directly.
135
+ web_ui_path : & ' static str ,
119
136
/// The JMX Exporter metrics port.
120
137
metrics_port : u16 ,
121
138
} ,
@@ -390,11 +407,23 @@ impl ContainerConfig {
390
407
cb. resources ( resources) ;
391
408
}
392
409
393
- if let Some ( probe) = self . tcp_socket_action_probe ( 10 , 10 ) {
394
- cb. readiness_probe ( probe. clone ( ) ) ;
410
+ if let Some ( probe) = self . web_ui_port_probe (
411
+ hdfs,
412
+ LIVENESS_PROBE_PERIOD_SECONDS ,
413
+ LIVENESS_PROBE_INITIAL_DELAY_SECONDS ,
414
+ LIVENESS_PROBE_FAILURE_THRESHOLD ,
415
+ ) {
395
416
cb. liveness_probe ( probe) ;
396
417
}
397
418
419
+ if let Some ( probe) = self . ipc_port_probe (
420
+ READINESS_PROBE_PERIOD_SECONDS ,
421
+ READINESS_PROBE_INITIAL_DELAY_SECONDS ,
422
+ READINESS_PROBE_FAILURE_THRESHOLD ,
423
+ ) {
424
+ cb. readiness_probe ( probe. clone ( ) ) ;
425
+ }
426
+
398
427
Ok ( cb. build ( ) )
399
428
}
400
429
@@ -788,24 +817,64 @@ wait_for_termination $!
788
817
}
789
818
}
790
819
791
- /// Creates a probe for [`stackable_operator::k8s_openapi::api::core::v1::TCPSocketAction`]
792
- /// for liveness or readiness probes
793
- fn tcp_socket_action_probe (
820
+ /// Creates a probe for the web UI port
821
+ fn web_ui_port_probe (
794
822
& self ,
823
+ hdfs : & HdfsCluster ,
795
824
period_seconds : i32 ,
796
825
initial_delay_seconds : i32 ,
826
+ failure_threshold : i32 ,
797
827
) -> Option < Probe > {
798
828
match self {
799
829
ContainerConfig :: Hdfs {
800
- tcp_socket_action_port_name,
830
+ web_ui_http_port_name,
831
+ web_ui_https_port_name,
832
+ web_ui_path,
801
833
..
802
- } => Some ( Probe {
834
+ } => {
835
+ let http_get_action = if hdfs. has_https_enabled ( ) {
836
+ HTTPGetAction {
837
+ port : IntOrString :: String ( web_ui_https_port_name. to_string ( ) ) ,
838
+ scheme : Some ( "HTTPS" . into ( ) ) ,
839
+ path : Some ( web_ui_path. to_string ( ) ) ,
840
+ ..HTTPGetAction :: default ( )
841
+ }
842
+ } else {
843
+ HTTPGetAction {
844
+ port : IntOrString :: String ( web_ui_http_port_name. to_string ( ) ) ,
845
+ scheme : Some ( "HTTP" . into ( ) ) ,
846
+ path : Some ( web_ui_path. to_string ( ) ) ,
847
+ ..HTTPGetAction :: default ( )
848
+ }
849
+ } ;
850
+ Some ( Probe {
851
+ http_get : Some ( http_get_action) ,
852
+ period_seconds : Some ( period_seconds) ,
853
+ initial_delay_seconds : Some ( initial_delay_seconds) ,
854
+ failure_threshold : Some ( failure_threshold) ,
855
+ ..Probe :: default ( )
856
+ } )
857
+ }
858
+ _ => None ,
859
+ }
860
+ }
861
+
862
+ /// Creates a probe for the IPC/RPC port
863
+ fn ipc_port_probe (
864
+ & self ,
865
+ period_seconds : i32 ,
866
+ initial_delay_seconds : i32 ,
867
+ failure_threshold : i32 ,
868
+ ) -> Option < Probe > {
869
+ match self {
870
+ ContainerConfig :: Hdfs { ipc_port_name, .. } => Some ( Probe {
803
871
tcp_socket : Some ( TCPSocketAction {
804
- port : IntOrString :: String ( String :: from ( * tcp_socket_action_port_name ) ) ,
872
+ port : IntOrString :: String ( ipc_port_name . to_string ( ) ) ,
805
873
..TCPSocketAction :: default ( )
806
874
} ) ,
807
875
period_seconds : Some ( period_seconds) ,
808
876
initial_delay_seconds : Some ( initial_delay_seconds) ,
877
+ failure_threshold : Some ( failure_threshold) ,
809
878
..Probe :: default ( )
810
879
} ) ,
811
880
_ => None ,
@@ -1177,21 +1246,30 @@ impl From<HdfsRole> for ContainerConfig {
1177
1246
role : role. clone ( ) ,
1178
1247
container_name : role. to_string ( ) ,
1179
1248
volume_mounts : ContainerVolumeDirs :: from ( role) ,
1180
- tcp_socket_action_port_name : SERVICE_PORT_NAME_RPC ,
1249
+ ipc_port_name : SERVICE_PORT_NAME_RPC ,
1250
+ web_ui_http_port_name : SERVICE_PORT_NAME_HTTP ,
1251
+ web_ui_https_port_name : SERVICE_PORT_NAME_HTTPS ,
1252
+ web_ui_path : "/dfshealth.html" ,
1181
1253
metrics_port : DEFAULT_NAME_NODE_METRICS_PORT ,
1182
1254
} ,
1183
1255
HdfsRole :: DataNode => Self :: Hdfs {
1184
1256
role : role. clone ( ) ,
1185
1257
container_name : role. to_string ( ) ,
1186
1258
volume_mounts : ContainerVolumeDirs :: from ( role) ,
1187
- tcp_socket_action_port_name : SERVICE_PORT_NAME_IPC ,
1259
+ ipc_port_name : SERVICE_PORT_NAME_IPC ,
1260
+ web_ui_http_port_name : SERVICE_PORT_NAME_HTTP ,
1261
+ web_ui_https_port_name : SERVICE_PORT_NAME_HTTPS ,
1262
+ web_ui_path : "/datanode.html" ,
1188
1263
metrics_port : DEFAULT_DATA_NODE_METRICS_PORT ,
1189
1264
} ,
1190
1265
HdfsRole :: JournalNode => Self :: Hdfs {
1191
1266
role : role. clone ( ) ,
1192
1267
container_name : role. to_string ( ) ,
1193
1268
volume_mounts : ContainerVolumeDirs :: from ( role) ,
1194
- tcp_socket_action_port_name : SERVICE_PORT_NAME_RPC ,
1269
+ ipc_port_name : SERVICE_PORT_NAME_RPC ,
1270
+ web_ui_http_port_name : SERVICE_PORT_NAME_HTTP ,
1271
+ web_ui_https_port_name : SERVICE_PORT_NAME_HTTPS ,
1272
+ web_ui_path : "/journalnode.html" ,
1195
1273
metrics_port : DEFAULT_JOURNAL_NODE_METRICS_PORT ,
1196
1274
} ,
1197
1275
}
0 commit comments