Я пытаюсь запустить пару рабочих процессов 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
Трудно однозначно сказать, в чем может быть проблема, но есть несколько шагов, которые вы можете предпринять для ее устранения:
- Отладочные модули, особенно проверьте, нет ли чего-то подозрительного в журналах:
kubectl logs ${POD_NAME} ${CONTAINER_NAME}
kubectl logs --previous ${POD_NAME} ${CONTAINER_NAME}
- Отладочные службы, например, проверив:
Существует ли данная услуга?
Работает ли сервис по DNS-имени?
Работает ли сервис по IP?
Правильно ли определена Услуга?
Есть ли у Сервиса конечные точки?
Работает ли kube-proxy?
Выполнение этих шагов поможет вам найти причину вашей проблемы, а также лучше понять механизмы, лежащие в основе услуг.
решение2
Вы используете NodePort
службу типов, и в этом случае то, что вы наблюдаете, вполне ожидаемо.
Ваша служба сопоставляет 2 pod, которые запущены на двух разных узлах. Поскольку служба имеет тип NodePort
, существует внутренняя ассоциация pod вашей службы и узла, на котором она запущена. Если вы закрутите worker-red
конечную точку, выТОЛЬКОполучить ответ от worker-red
pod, это потому, что другой pod привязан к другой конечной точке worker-blue:<node-port>
и недоступен из worker-red
конечной точки. Да, это тот же сервис, но он поддерживается 2 конечными точками, каждая из которых имеет разные имена хостов.
Вот так в принципе и NodePort
работают службы.
Когда вы объединяете их на одном узле, оба pod'а доступны с одного и того же имени хоста узла, поэтому скручивание их обоих будет работать. С этого момента обе конечные точки сопоставляются с разными портами, ното же имя хоста.
Как способ углубить ваше понимание этого. Вы можете попробовать изменить тип вашей службы на LoadBalancer
. И вы заметите, что вы сможете достичь обоих модулей, используя одно и то же имя хоста, независимо от того, где они запланированы. И это имя хоста/IP-адрес будет адресом , который LoadBalancer
будут иметь все модули в службе.
Надеюсь, это прояснит ваше недоумение!