in iotdb-operator/internal/controller/confignode_controller.go [122:227]
func (r *ConfigNodeReconciler) constructStateFulSetForConfigNode(configNode *iotdbv1.ConfigNode) *appsv1.StatefulSet {
labels := map[string]string{"app": ConfigNodeName}
replicas := int32(configNode.Spec.Replicas)
envVars := make([]corev1.EnvVar, 3)
envNum := 0
if configNode.Spec.Envs != nil {
envNum = len(configNode.Spec.Envs)
envVars = make([]corev1.EnvVar, len(configNode.Spec.Envs)+3)
i := 0
for key, value := range configNode.Spec.Envs {
if key == "cn_internal_port" {
value = "10710"
} else if key == "cn_consensus_port" {
value = "10720"
} else if key == "cn_metric_prometheus_reporter_port" {
value = "9091"
}
envVars[i] = corev1.EnvVar{Name: key, Value: value}
i++
}
}
envVars[envNum] = corev1.EnvVar{
Name: "POD_NAME",
ValueFrom: &corev1.EnvVarSource{
FieldRef: &corev1.ObjectFieldSelector{
FieldPath: "metadata.name",
},
},
}
val1 := ConfigNodeName + "-0." + ConfigNodeName + "-headless." + configNode.Namespace + ".svc.cluster.local:10710"
val2 := "$(POD_NAME)." + ConfigNodeName + "-headless." + configNode.Namespace + ".svc.cluster.local"
envVars[envNum+1] = corev1.EnvVar{Name: "cn_seed_config_node", Value: val1}
envVars[envNum+2] = corev1.EnvVar{Name: "cn_internal_address", Value: val2}
pvcTemplate := *r.constructPVCForConfigNode(configNode)
pvcName := pvcTemplate.Name
statefulset := &appsv1.StatefulSet{
ObjectMeta: metav1.ObjectMeta{
Name: ConfigNodeName,
Namespace: configNode.Namespace,
Labels: labels,
},
Spec: appsv1.StatefulSetSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: labels,
},
ServiceName: ConfigNodeName + "-headless",
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: labels,
},
Spec: corev1.PodSpec{
Affinity: &corev1.Affinity{
PodAntiAffinity: &corev1.PodAntiAffinity{
RequiredDuringSchedulingIgnoredDuringExecution: []corev1.PodAffinityTerm{
{
LabelSelector: &metav1.LabelSelector{
MatchLabels: labels,
},
TopologyKey: "kubernetes.io/hostname",
},
},
},
},
Containers: []corev1.Container{
{
Name: ConfigNodeName,
Image: configNode.Spec.Image,
ImagePullPolicy: corev1.PullIfNotPresent,
Ports: []corev1.ContainerPort{
{Name: "internal", ContainerPort: 10710},
{Name: "consensus", ContainerPort: 10720},
},
Resources: corev1.ResourceRequirements{
Limits: corev1.ResourceList{
corev1.ResourceCPU: *configNode.Spec.Resources.Limits.Cpu(),
corev1.ResourceMemory: *configNode.Spec.Resources.Limits.Memory(),
},
Requests: corev1.ResourceList{
corev1.ResourceCPU: *configNode.Spec.Resources.Limits.Cpu(),
corev1.ResourceMemory: *configNode.Spec.Resources.Limits.Memory(),
},
},
Env: envVars,
VolumeMounts: []corev1.VolumeMount{
{Name: pvcName, MountPath: "/iotdb/data", SubPath: "data"},
{Name: pvcName, MountPath: "/iotdb/logs", SubPath: "logs"},
{Name: pvcName, MountPath: "/iotdb/ext", SubPath: "ext"},
{Name: pvcName, MountPath: "/iotdb/.env", SubPath: ".env"},
{Name: pvcName, MountPath: "/iotdb/activation", SubPath: "activation"},
},
},
},
},
},
VolumeClaimTemplates: []corev1.PersistentVolumeClaim{pvcTemplate},
},
}
err := SetControllerReference(configNode, statefulset, r.Scheme)
if err != nil {
return nil
}
return statefulset
}