Description
A StatefulSet references a headless Service through spec.service_name to provide stable network names for its pods. Configure cluster_ip = "None" on a Service in the same namespace, with a selector matching the actual pod labels.
Referring to an ordinary Service or an incorrect selector can prevent the expected per-pod DNS names and peer discovery from working.
Potential impact
- Peers may be unreachable through stable pod DNS names.
- Unreliable discovery during restarts or scaling can complicate recovery of stateful applications.
Remediation
- Point the StatefulSet’s
service_nameto a headless Service in the same namespace and set the Service’scluster_ipto"None". - Verify the Service selector against actual pod labels, ports and DNS responses. Create the Service separately.
Examples
These excerpts show the Service association only; the required pod template, Service ports and other settings are omitted. The before excerpt omits cluster_ip for ordinary ClusterIP allocation, while the after excerpt selects a headless Service.
Before
hcl
resource "kubernetes_service" "example" {
metadata {
name = "prometheus"
namespace = "monitoring"
}
spec {
selector = {
app = "prometheus"
}
}
}
resource "kubernetes_stateful_set" "example" {
metadata {
name = "prometheus"
namespace = "monitoring"
}
spec {
service_name = "prometheus"
selector {
match_labels = {
app = "prometheus"
}
}
}
}
After
hcl
resource "kubernetes_service" "example" {
metadata {
name = "prometheus"
namespace = "monitoring"
}
spec {
cluster_ip = "None"
selector = {
app = "prometheus"
}
}
}
resource "kubernetes_stateful_set" "example" {
metadata {
name = "prometheus"
namespace = "monitoring"
}
spec {
service_name = "prometheus"
selector {
match_labels = {
app = "prometheus"
}
}
}
}
Explanation:
- Before: The StatefulSet references an ordinary ClusterIP Service, not a headless Service.
- After: cluster_ip is set to None. The omitted pod template must also carry labels matching the selector.