Вопрос или проблема
У меня есть развертывание для Kubernetes, написанное на Terraform. Эти скрипты работали ранее, но после некоторых ошибок с серверами их пришлось перезапустить, и мне пришлось снова развертывать всю инфраструктуру.
У меня есть Stateful set, который работает совершенно нормально, вот файл для этого Stateful set:
resource "kubernetes_service" "cassandra" {
metadata {
name = "cassandra"
namespace = "production"
labels = {
app = "cassandra"
}
}
spec {
selector = {
app = "cassandra"
}
port {
name = "cassandra-internal"
port = 7000
target_port = 7000
}
cluster_ip = "None"
}
}
resource "kubernetes_stateful_set" "cassandra" {
metadata {
name = "cassandra"
namespace = "production"
}
spec {
service_name = "cassandra"
selector {
match_labels = {
app = "cassandra"
}
}
replicas = 24
# replicas = 0
update_strategy {
type = "RollingUpdate"
}
pod_management_policy = "OrderedReady"
volume_claim_template {
metadata {
name = "cassandra-data"
}
spec {
access_modes = ["ReadWriteOnce"]
storage_class_name = "cassandra-storage"
resources {
requests = {
storage = "800Gi"
}
}
}
}
template {
metadata {
labels = {
app = "cassandra"
}
}
spec {
container {
image = "[REDACTED]cassandra:4.1.5"
name = "cassandra"
image_pull_policy = "Always"
env {
name = "CASSANDRA_SEEDS"
value = "cassandra-0.cassandra.production.svc.cluster.local"
}
volume_mount {
name = "cassandra-data"
mount_path = "/var/lib/cassandra"
}
resources {
limits = {
memory = "20Gi"
cpu = "6"
}
}
}
}
}
}
}
Вот развертывание, которое я пытаюсь развернуть в продакшене:
resource "kubernetes_deployment" "kairosdb" {
depends_on = [
kubernetes_stateful_set.cassandra
]
metadata {
name = "kairosdb"
namespace = "production"
}
spec {
# replicas = 4
replicas = 1
selector {
match_labels = {
app = "kairosdb"
}
}
template {
metadata {
labels = {
app = "kairosdb"
}
}
spec {
container {
image = "[REDACTED]/kairosdb-ingest:1.3.0"
name = "kairosdb"
image_pull_policy = "Always"
port {
name = "http"
container_port = 8080
}
port {
name = "telnet"
container_port = 4242
}
env {
name = "JAVA_OPTS"
value = " -Djava.net.preferIPv4Stack=true "
}
env {
name = "CASSANDRA_HOST_LIST"
value = "cassandra-0.cassandra.production.svc.cluster.local,cassandra-1.cassandra.production.svc.cluster.local,cassandra-2.cassandra.production.svc.cluster.local,cassandra-3.cassandra.production.svc.cluster.local,cassandra-4.cassandra.production.svc.cluster.local,cassandra-5.cassandra.production.svc.cluster.local"
}
}
affinity {
node_affinity {
required_during_scheduling_ignored_during_execution {
node_selector_term {
match_expressions {
key = "service"
operator = "NotIn"
values = ["aux"]
}
match_expressions {
key = "environment"
operator = "In"
values = ["production"]
}
}
}
}
}
}
}
}
}
Но Pod моего развертывания не запускается. При проверке описания пода показывается следующее:
kubectl --namespace production describe pod kairosdb-7dffc4d7c7-tm8kp
Name: kairosdb-7dffc4d7c7-tm8kp
Namespace: production
Priority: 0
Service Account: default
Node: <none>
Labels: app=kairosdb
pod-template-hash=7dffc4d7c7
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Controlled By: ReplicaSet/kairosdb-7dffc4d7c7
Containers:
kairosdb:
Image: [REDACTED]/kairosdb-ingest:1.3.0
Ports: 8080/TCP, 4242/TCP
Host Ports: 0/TCP, 0/TCP
Environment:
JAVA_OPTS: -Djava.net.preferIPv4Stack=true
CASSANDRA_HOST_LIST: cassandra-0.cassandra.production.svc.cluster.local,cassandra-1.cassandra.production.svc.cluster.local,cassandra-2.cassandra.production.svc.cluster.local,cassandra-3.cassandra.production.svc.cluster.local,cassandra-4.cassandra.production.svc.cluster.local,cassandra-5.cassandra.production.svc.cluster.local
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-h5zhl (ro)
Conditions:
Type Status
PodScheduled False
Volumes:
kube-api-access-h5zhl:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 104s default-scheduler 0/9 nodes are available: 3 node(s) had untolerated taint {node-role.kubernetes.io/controlplane: true}, 6 node(s) didn't match Pod's node affinity/selector. preemption: 0/9 nodes are available: 9 Preemption is not helpful for scheduling.
Я не знаю, почему возникает эта проблема.
Я пытался избавиться от блока “affinity”, но проблема в том, что Pod разворачивается на сервере, который мы используем для вспомогательных служб, и идея состоит в том, чтобы развернуть Pod на серверах, которые соответствуют аффинности.
Настаиваю, что развертывание работало нормально до перезапуска серверов, так что проблема может быть связана с этим.
В чем может быть проблема? Любая помощь будет очень ценна.
Ответ или решение
Проблема с развертыванием в Kubernetes: Система не может найти подходящий узел
Ваша проблема, с которой вы столкнулись при развертывании приложения в Kubernetes, указывает на то, что pod не удается запустить из-за несоответствия с заданными требованиями по привязанности к узлам. Давайте внимательно разберемся с вашей конфигурацией и возможными причинами.
Контекст и Объяснение Проблемы
Как следует из приведенного вами лога и информации о развертывании, pod kairosdb
не смог быть запущен, так как Kubernetes не нашел подходящего узла. Статус сообщения от Планировщика Kubernetes:
0/9 nodes are available: 3 node(s) had untolerated taint {node-role.kubernetes.io/controlplane: true}, 6 node(s) didn't match Pod's node affinity/selector.
Давайте разберем это сообщение:
-
Untolerated taint: Три узла имеют метку (taint), которую ваш pod не может игнорировать. В данном случае указанный taint связан с ролями узлов управления (control plane), что означает, что pod не может быть развернут на этих узлах.
-
Не соответствие требованиям по привязанности к узлам: Шесть узлов не соответствуют критериям по привязанности, указанным в вашем развертывании. В вашем YAML указан блок
affinity
, который описывает требования по узлам, где pod может быть развернут.
Анализ Конфигурации
Ваше определение развертывания содержит следующие параметры в affinity
:
affinity {
node_affinity {
required_during_scheduling_ignored_during_execution {
node_selector_term {
match_expressions {
key = "service"
operator = "NotIn"
values = ["aux"]
}
match_expressions {
key = "environment"
operator = "In"
values = ["production"]
}
}
}
}
}
Это означает, что ваш pod может быть развернут только на узлах, где:
- Метка
service
не должна быть равнаaux
. - Метка
environment
должна быть равнаproduction
.
Возможные Решения
-
Проверка Меток Узлов: Необходимо убедиться, что среди доступных узлов действительно есть узлы, соответствующие указанным меткам. Используйте команду для вывода меток узлов:
kubectl get nodes --show-labels
Посмотрите, какие метки установлены на узлах и соответствуют ли они требованиям вашего развертывания.
-
Настройка Тональных Меток: Если ваши узлы не имеют необходимых меток, можно добавить их с помощью следующей команды:
kubectl label nodes <имя_узла> service=<значение> kubectl label nodes <имя_узла> environment=production
-
Анализ Tainks: Если ваше приложение не критично к узлам управления, и вы хотите временно игнорировать taint, можно добавить toleration в ваш YAML:
tolerations { key = "node-role.kubernetes.io/controlplane" operator = "Exists" effect = "NoSchedule" }
Однако этот подход может повлиять на производительность и стабильность вашего развертывания, поэтому используйте его с осторожностью.
- Удаление Требования по Привязанности (Если это допустимо): Если вы хотите сразу развернуть pod, можно временно убрать блок
affinity
, что позволит Kubernetes разместить его на любом доступном узле. Однако у вас может возникнуть проблема с размерами ресурсов или управлением нагрузкой в будущем.
Заключение
Проблема, с которой вы столкнулись, связана с несоответствием текущих узлов требованиям, заданным для развертывания pod. Проведите аудит меток узлов и taints с помощью приведенных выше команд и корректируйте конфигурацию, основываясь на результатах.
Если у вас остаются вопросы или необходима помощь в доработке конфигурации, не стесняйтесь задавать их.