Службы Kubernetes истекают из-за тайм-аута при доступе к модулям на разных рабочих узлах

Службы Kubernetes истекают из-за тайм-аута при доступе к модулям на разных рабочих узлах

Я пытаюсь запустить пару рабочих процессов Kubernetes на экземплярах EC2 и сталкиваюсь с проблемой, когда служба, по-видимому, «не видит» все модули, которые она должна видеть.

Моя точная среда — это пара AWS Snowballs, Red и Blue, а мой кластер выглядит как control, worker-red, и worker-blue[1]. Я развертываю фиктивный сервер Python, который ждет GET на порту 8080 и отвечает локальным именем хоста. Я настроил его с достаточным количеством реплик, чтобы и и worker-redимели worker-blueпо крайней мере по одному pod каждый. Наконец, я создал службу, спецификация которой выглядит как

spec:
    type: NodePort
    selector:
        app: hello-server
    ports:
        - port: 8080
          targetPort: 8080
          nodePort: 30080

Теперь я могу проверить, что мои модули работают.

kubectl get pods -o wide
NAME                                      READY   STATUS    RESTARTS   AGE   IP              NODE          NOMINATED NODE   READINESS GATES
hello-world-deployment-587468bdb7-hf4dq   1/1     Running   0          27m   192.168.1.116   worker.red    <none>           <none>
hello-world-deployment-587468bdb7-mclhm   1/1     Running   0          27m   192.168.1.126   worker.blue   <none>           <none>

Теперь я могу попробовать их завить.

curl worker-red:30080
greetings from hello-world-deployment-587468bdb7-hf4dq
curl worker-blue:30080
greetings from hello-world-deployment-587468bdb7-mclhm

Вот что происходит примерно в половине случаев. В другой половине случаев curl завершается с ошибкой тайм-аута. А именно — curling worker-red даст ответ ТОЛЬКО от hf4dq, а curling worker-blue даст ответ ТОЛЬКО от mclhm. Если я оцеплю и осушу worker-blue так, чтобы оба моих pod'а работали на worker-red, тайм-аута никогда не будет, и оба pod'а ответят.

Похоже, что служба NodePort не достигает подов, которые не находятся на хосте, который я закручиваю. Насколько я понимаю, это не то, как службы должны работать. Что я упускаю?

[1] Если я настрою так, что у меня будет два рабочих процесса, оба на Red, возникнет та же проблема, которую я описываю, но это мой основной вариант использования, поэтому я сосредоточусь на нем.

решение1

Трудно однозначно сказать, в чем может быть проблема, но есть несколько шагов, которые вы можете предпринять для ее устранения:

  1. Отладочные модули, особенно проверьте, нет ли чего-то подозрительного в журналах:
  • kubectl logs ${POD_NAME} ${CONTAINER_NAME}

  • kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}

  1. Отладочные службы, например, проверив:
  • Существует ли данная услуга?

  • Работает ли сервис по DNS-имени?

  • Работает ли сервис по IP?

  • Правильно ли определена Услуга?

  • Есть ли у Сервиса конечные точки?

  • Работает ли kube-proxy?

Выполнение этих шагов поможет вам найти причину вашей проблемы, а также лучше понять механизмы, лежащие в основе услуг.

решение2

Вы используете NodePortслужбу типов, и в этом случае то, что вы наблюдаете, вполне ожидаемо.

Ваша служба сопоставляет 2 pod, которые запущены на двух разных узлах. Поскольку служба имеет тип NodePort, существует внутренняя ассоциация pod вашей службы и узла, на котором она запущена. Если вы закрутите worker-redконечную точку, выТОЛЬКОполучить ответ от worker-redpod, это потому, что другой pod привязан к другой конечной точке worker-blue:<node-port>и недоступен из worker-redконечной точки. Да, это тот же сервис, но он поддерживается 2 конечными точками, каждая из которых имеет разные имена хостов.

Вот так в принципе и NodePortработают службы.

Когда вы объединяете их на одном узле, оба pod'а доступны с одного и того же имени хоста узла, поэтому скручивание их обоих будет работать. С этого момента обе конечные точки сопоставляются с разными портами, ното же имя хоста.

Как способ углубить ваше понимание этого. Вы можете попробовать изменить тип вашей службы на LoadBalancer. И вы заметите, что вы сможете достичь обоих модулей, используя одно и то же имя хоста, независимо от того, где они запланированы. И это имя хоста/IP-адрес будет адресом , который LoadBalancerбудут иметь все модули в службе.

Надеюсь, это прояснит ваше недоумение!

Связанный контент