#node.js #reactjs #docker #nginx #kubernetes
Вопрос:
Я новичок в Kubernetes и пытаюсь развернуть приложение React в своем кластере. Вот основная информация:
- Рабочий стол Docker, одноузловой кластер Kubernetes
- Интерфейс разработки React, открывающий порт 3000
- Серверная часть Node.js/Express, открывающая порт 8080
- Контроллер входа NGINX, обслуживающий мой интерфейс React на «локальном хосте:3000» и маршрутизирующий мои запросы API выборки (fetch(«локальный хост:3000/api/…», ПАРАМЕТРЫ)) на серверную часть (которая работает)
У меня возникла проблема при открытии приложения React. Контроллер входа правильно направляет в приложение, но 3 пакета (bundle.js, main.chink.js, третий, который я не помню) не загружены. Я получаю следующую ошибку:
GET http://localhost/static/js/main.chunk.js net::ERR_ABORTED 404 (Not Found) ingress (one example)
Я понимаю, почему происходит эта ошибка. Контроллер входа правильно направляет трафик, но загружает только index.html файл. В этом файле есть вызовы 3 сценариев (ссылающихся на пакеты), которые не загружены. Я понимаю ошибку, файлы не отправляются в браузер, поэтому index.html файл не может их загрузить, но не знаю, как это исправить.
У кого-нибудь есть какие-нибудь предложения? де, а затем вытащил из Докер-хаба. Кто-нибудь знает, каким может быть возможное решение? Например, исправляет ли это развертывание сборки/ папки (встроенное приложение React с использованием «npm run build»)? Должен ли я использовать nginx внутри своего файла Dockerfile для создания контейнера?
Вход.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
#labels:
#name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /
pathType: Exact
backend:
service:
name: titanicfrontendservice
port:
number: 3000
- path: /api
pathType: Exact
backend:
service:
name: titanicbackendservice
port:
number: 8080
Ingress controller deployment yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
replicas: 1
selector:
matchLabels:
app: nginx-ingress
template:
metadata:
labels:
app: nginx-ingress
#annotations:
#prometheus.io/scrape: "true"
#prometheus.io/port: "9113"
spec:
serviceAccountName: nginx-ingress
containers:
- image: nginx/nginx-ingress:1.10.0
imagePullPolicy: IfNotPresent
name: nginx-ingress
ports:
- name: http
containerPort: 80
- name: https
containerPort: 443
- name: readiness-port
containerPort: 8081
#- name: prometheus
#containerPort: 9113
readinessProbe:
httpGet:
path: /nginx-ready
port: readiness-port
periodSeconds: 1
securityContext:
allowPrivilegeEscalation: true
runAsUser: 101 #nginx
capabilities:
drop:
- ALL
add:
- NET_BIND_SERVICE
env:
- name: POD_NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
args:
- -nginx-configmaps=$(POD_NAMESPACE)/nginx-config
- -default-server-tls-secret=$(POD_NAMESPACE)/default-server-secret
#- -v=3 # Enables extensive logging. Useful for troubleshooting.
- -report-ingress-status
- -external-service=nginx-ingress
#- -enable-prometheus-metrics
#- -global-configuration=$(POD_NAMESPACE)/nginx-configuration
Служба контроллера входа yaml
apiVersion: v1
kind: Service
metadata:
name: nginx-ingress
namespace: nginx-ingress
spec:
externalTrafficPolicy: Local
type: LoadBalancer
ports:
- port: 3000
targetPort: 80
protocol: TCP
name: http
- port: 443
targetPort: 443
protocol: TCP
name: https
selector:
app: nginx-ingress
Комментарии:
1. Здравствуйте, вы уверены, что ваш
nginx-ingress-controller
прослушивает порт 3000? По умолчанию это 80/443. Кроме того, пожалуйста, включитеYAML
манифест вашегоIngress
ресурса,Service
иDeployments
. Кроме того, вы пытались открыть и подключиться к своемуfrontend
on aNodePort
, чтобы опуститьIngress
контроллер?2. @DawidKruk Да, я поменял порты на входном контроллере .yaml, мне не очень нравилось использовать порт 80 (я сохранил 443, хотя и не часто его использую). Я отредактирую вопрос, чтобы включить запрошенные вами yamls. Я уже пробовал открывать интерфейс напрямую с помощью балансировщика нагрузки. Однако я не мог понять, как правильно направлять ПОЧТУ и ПОЛУЧАТЬ запросы. Более конкретно, как я уже спрашивал в StackOverflow, я не могу выбрать подходящий URL-адрес для включения в API выборки.
Ответ №1:
TL;DR
Переключитесь pathType
на оба /api
и /
путь к Prefix
.
Я включил некоторые пояснения с фиксированным Ingress
ресурсом ниже.
Для целей воспроизведения я использовал titanic
декларации, которые вы предоставили в другом вопросе:
Проблема с вашей конфигурацией связана с: pathType
.
Используя ваш Ingress
ресурс pathType: Exact
, вы показали мне пустую страницу.
Изменение вашего Ingress
ресурса с pathType: Prefix
помощью решенной проблемы.
Боковое примечание!
Появилось сообщение: «Вы бы пережили крушение «Титаника»?».
Точная Ingress
конфигурация должна быть следующей:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /
pathType: Prefix # <-- IMPORTANT
backend:
service:
name: titanicfrontendservice
port:
number: 3000
- path: /api
pathType: Prefix # <-- IMPORTANT
backend:
service:
name: titanicbackendservice
port:
number: 8080
Почему я думаю, что это произошло?
Ссылаясь на официальную документацию:
Типы путей
Каждый путь на входе должен иметь соответствующий тип пути. Пути, которые не содержат явного типа пути, не пройдут проверку. Существует три поддерживаемых типа путей:
ImplementationSpecific
: При этом типе пути соответствие зависит от класса входа. Реализации могут рассматривать это как отдельный тип пути или рассматривать его идентично типам префиксов или точных путей.Exact
: Точно соответствует пути URL-адреса и с учетом регистра.Prefix
: Совпадения на основе префикса пути URL, разделенного на /. Сопоставление чувствительно к регистру и выполняется по элементам пути. Элемент пути ссылается на список меток в пути, разделенном разделителем/. Запрос соответствует пути p, если каждый p является префиксом p по элементам пути запроса.— Kubernetes.io: Документы: Концепции: Службы сети: Вход: Типы путей (есть несколько примеров того, как обрабатывается сопоставление путей)
Ingress controller
вынужден сопоставлять только /
путь, оставляя остальные зависимости (кроме index.html
) на других путях, таких как /super.jpg
и /folder/awesome.jpg
ошибка с 404
кодом.
Боковое примечание!
Вы можете проверить это поведение, создав nginx
Pod
и поместив в него файлы примеров. После примененияIngress
ресурса с/
иpathType: Exact
вы не сможете запросить его черезIngress
контроллер, но вы можете получить доступ к ним в кластере.
Я призываю вас проверить дополнительные ресурсы:
Комментарии:
1. @DavidKruk Большое спасибо! Я уже однажды пытался протестировать исправление, но, похоже, у меня было что-то еще неправильно настроено. Я хочу задать вам один вопрос: у вас есть аккаунт в Твиттере или что-нибудь в этом роде? Вы просто были невероятно вежливы и предупредительны, что я хочу следить за вами для любых будущих обновлений, которые у вас есть, или чего-то в этом роде.
2. @Stroboscopio рад, что вам удалось найти решение. К сожалению, у меня нет аккаунта в твиттере (я подумываю об этом). Не стесняйтесь просматривать ответы в моем профиле, и, возможно, мы еще встретимся на StackOverflow.
Ответ №2:
Проблема с вашим входом.yaml заключается в том, что маршрут для вашего пользовательского интерфейса должен быть /* и располагаться под внутренней маршрутизацией. Кроме того, проверьте свою маршрутизацию на наличие API
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: titanic-ingress
#labels:
#name: titanic-ingress
spec:
ingressClassName: nginx
rules:
- host: localhost
http:
paths:
- path: /api/*
pathType: Exact
backend:
service:
name: titanicbackendservice
port:
number: 8080
- path: /*
pathType: Exact
backend:
service:
name: titanicfrontendservice
port:
number: 3000