-
-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathstatefulset.rs
More file actions
136 lines (116 loc) · 5.25 KB
/
Copy pathstatefulset.rs
File metadata and controls
136 lines (116 loc) · 5.25 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
//! Builds the rolegroup [`StatefulSet`] for an HDFS role group.
use snafu::{ResultExt, Snafu};
use stackable_operator::{
builder::pod::{PodBuilder, security::PodSecurityContextBuilder},
k8s_openapi::{
DeepMerge,
api::apps::v1::{StatefulSet, StatefulSetSpec},
apimachinery::pkg::apis::meta::v1::LabelSelector,
},
kube::api::ObjectMeta,
kvp::{LabelError, Labels},
utils::cluster_info::KubernetesClusterInfo,
v2::types::operator::RoleGroupName,
};
use crate::{
controller::{
ValidatedCluster, ValidatedRoleGroupConfig,
build::{
self,
container::{self, ContainerConfig},
graceful_shutdown::{self, add_graceful_shutdown_config},
},
},
crd::HdfsNodeRole,
};
#[derive(Snafu, Debug)]
pub enum Error {
#[snafu(display("failed to build roleGroup selector labels"))]
RoleGroupSelectorLabels { source: LabelError },
#[snafu(display("failed to create container and volume configuration"))]
FailedToCreateContainerAndVolumeConfiguration { source: container::Error },
#[snafu(display("failed to configure graceful shutdown"))]
GracefulShutdown { source: graceful_shutdown::Error },
#[snafu(display("failed to build role-group volume claim templates from config"))]
BuildRoleGroupVolumeClaimTemplates { source: container::Error },
}
pub(crate) fn build_rolegroup_statefulset(
validated: &ValidatedCluster,
cluster_info: &KubernetesClusterInfo,
role: &HdfsNodeRole,
role_group_name: &RoleGroupName,
rolegroup_config: &ValidatedRoleGroupConfig,
service_account_name: &str,
) -> Result<StatefulSet, Error> {
tracing::info!("Setting up StatefulSet for role {role} role group {role_group_name}");
let image = &validated.image;
let merged_config = &rolegroup_config.config;
// PodBuilder for StatefulSet Pod template.
let mut pb = PodBuilder::new();
let rolegroup_selector_labels: Labels =
build::rolegroup_selector_labels(validated, role, role_group_name)
.context(RoleGroupSelectorLabelsSnafu)?;
let pb_metadata = ObjectMeta {
labels: Some(rolegroup_selector_labels.clone().into()),
..ObjectMeta::default()
};
pb.metadata(pb_metadata)
.image_pull_secrets_from_product_image(image)
.affinity(&merged_config.affinity)
.service_account_name(service_account_name)
.security_context(PodSecurityContextBuilder::new().fs_group(1000).build());
// Adds all containers and volumes to the pod builder
// We must use the selector labels ("rolegroup_selector_labels") and not the recommended labels
// for the ephemeral listener volumes created by this function.
// This is because the recommended set contains a "managed-by" label. This label triggers
// the cluster resources to "manage" listeners which is wrong and leads to errors.
// The listeners are managed by the listener-operator.
ContainerConfig::add_containers_and_volumes(
&mut pb,
validated,
cluster_info,
role,
role_group_name,
rolegroup_config,
&rolegroup_selector_labels,
)
.context(FailedToCreateContainerAndVolumeConfigurationSnafu)?;
add_graceful_shutdown_config(merged_config, &mut pb).context(GracefulShutdownSnafu)?;
// The `podOverrides` were already merged (role <- role group) during validation
// by the local-`framework` `with_validated_config`.
let mut pod_template = pb.build_template();
pod_template.merge_from(rolegroup_config.pod_overrides.clone());
// The same comment regarding labels is valid here as it is for the ContainerConfig::add_containers_and_volumes() call above.
let pvcs = ContainerConfig::volume_claim_templates(merged_config, &rolegroup_selector_labels)
.context(BuildRoleGroupVolumeClaimTemplatesSnafu)?;
let statefulset_spec = StatefulSetSpec {
pod_management_policy: Some("OrderedReady".to_string()),
replicas: rolegroup_config.replicas.map(i32::from),
selector: LabelSelector {
match_labels: Some(rolegroup_selector_labels.into()),
..LabelSelector::default()
},
// Must match the headless Service name so the StatefulSet's pods get stable DNS names.
// See the TODO in `build::resource::service::rolegroup_headless_service` about the
// un-suffixed name.
service_name: Some(
validated
.resource_names(role, role_group_name)
.qualified_role_group_name()
.to_string(),
),
template: pod_template,
volume_claim_templates: Some(pvcs),
..StatefulSetSpec::default()
};
// TODO: The restart-controller is currently not enabled via the label RESTART_CONTROLLER_ENABLED_LABEL.
// This is due to problems that might appear when restarting pods during the initial formatting of namenodes.
// See: https://github.com/stackabletech/hdfs-operator/issues/750 (disable restart-controller)
// https://github.com/stackabletech/issues/issues/816 (enable restart-controller)
let metadata = build::rolegroup_metadata(validated, role, role_group_name);
Ok(StatefulSet {
metadata: metadata.build(),
spec: Some(statefulset_spec),
status: None,
})
}