Ошибка Kubernetes 502 Bad Gateway: сбой подключения() (111: соединение отклонено) при подключении к восходящему каналу

Прежде всего, я новичок в Nginx, Docker и Kubernetes, поэтому, возможно, я допустил очевидную ошибку, но после целой недели поиска и проб я столкнулся с той же ошибкой. Кроме того, я видел и другие подобные вопросы, но, к сожалению, предложенные решения не решили мою проблему.

Когда я обращаюсь к своему URL-адресу, я получаю сообщение 502 Bad Gateway (nginx), и когда я регистрирую свой контейнер nginx из своего модуля, он возвращает следующее:

[error] 7#7: *102 connect() failed (111: Connection refused) while connecting to upstream, client: <ip_address>, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9000/", host: <host_name>

В моем проекте используется Next JS 14. Я использую 3 модуля, и каждый модуль имеет два контейнера: my-project-nextjs и my-project-nginx (контейнер по умолчанию).

Что касается Docker, я пробовал разные конфигурации. Мое приложение находится в монорепозитории с использованием Turbo, поэтому я следую этой документации, чтобы создать свой Dockerfile:

FROM node:20.9.0-alpine AS base

FROM base AS builder
RUN apk update
RUN apk add --no-cache libc6-compat

WORKDIR /app

RUN yarn global add turbo
COPY . .

RUN turbo prune @monorepo/my-project --docker

FROM base AS installer
RUN apk update
RUN apk add --no-cache libc6-compat
WORKDIR /app

COPY --from=builder /app/out/json/ .
RUN yarn install

COPY --from=builder /app/out/full/ .
COPY --from=builder /app/tsconfig.json ./tsconfig.json
RUN yarn turbo run build --filter=@monorepo/my-project

FROM base AS runner
WORKDIR /app

ENV NODE_ENV production

RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
USER nextjs

COPY --from=installer --chown=nextjs:nodejs /app/apps/my-project/.next/standalone ./
COPY --from=installer --chown=nextjs:nodejs /app/apps/my-project/.next/static ./apps/my-project/.next/static
COPY --from=installer --chown=nextjs:nodejs /app/apps/my-project/public ./apps/my-project/public

EXPOSE 9000

ENV PORT 9000

CMD node apps/my-project/server.js

Для Dockerfile nginx я попробовал debian:strech-line и nginx:stable-alpine: результат тот же, ошибка 502. Вот версия Debian:

FROM debian:stretch-slim

ENV DEBIAN_FRONTEND = "noninteractive" \
    TERM = "xterm"
RUN echo "deb http://archive.debian.org/debian stretch main contrib non-free" > /etc/apt/sources.list
RUN apt-get update && apt-get upgrade -y &&\
    apt-get install -y nginx-light

RUN echo "Acquire::http {No-Cache=True;};" > /etc/apt/apt.conf.d/no-cache &&\
    apt-get -q update && \
    apt-get -qy dist-upgrade && \
    apt-get install -qy \
      nginx-light \
      nano \
    && \
    apt-get -y autoremove && \
    apt-get -y clean && \
    rm -rf /var/lib/apt/lists/*

COPY .docker/nginx/nginx.conf /etc/nginx/nginx.conf

RUN rm -v /etc/nginx/sites-enabled/default

ADD .docker/nginx/sites-enabled /etc/nginx/sites-enabled
ADD .docker/nginx/conf.d /etc/nginx/conf.d

COPY . /app
WORKDIR /app

CMD ["nginx"]

Конфигурация моего приложения, я полагаю, очень проста:

server {
    listen 80;
    server_name _;

    root /app/apps/my-project/.next;

    location / {
        proxy_pass http://localhost:9000;
    }

    location /nginx-health {
        access_log off;
        return 200 "OK\n";
    }
}

Когда я проверяю состояние своих модулей, они все работают. Мой контейнер my-project-nextjs возвращает этот журнал:

  ▲ Next.js 14.2.3
  - Local:        http://<pod_name>:9000
  - Network:      http://<ip_address>:9000

 ✓ Starting...
 ✓ Ready in 161ms

Поэтому я полагаю, что мой образ Next JS Docker правильный.

Мой контейнер my-project-nginx возвращает этот журнал (после того, как я попытался перейти на свой сайт по его URL-адресу):

[error] 7#7: *102 connect() failed (111: Connection refused) while connecting to upstream, client: <ip_address>, server: _, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:9000/", host: <host_name>

Судя по другим решениям SO, я думал, что проблема связана с ПОРТОМ или proxy_pass. ПОРТ мне кажется хорошим, поэтому я не знаю, что можно попробовать. Для proxy_pass я попытался заменить свое текущее значение (proxy_pass http://localhost:9000;) на http://127.0.0.1:9000, http://0.0.0.0:9000 или создать восходящий поток (но, если я прав, это когда контейнеры находятся в разных модулях).

Есть ли у вас идеи, почему я получаю сообщение об ошибке 502?

РЕДАКТИРОВАТЬ и РЕШЕНИЕ:

Вот мой код развертывания:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-project-deployment
  labels:
    app: my-project
  namespace: beta
spec:
  replicas: 2
  selector:
    matchLabels:
      name: my-project
  template:
    metadata:
      labels:
        name: my-project
    spec:
      containers:
        - name: my-project-nginx
          image: <my_image>
          imagePullPolicy: Always
          ports:
          - containerPort: 80
          env:
          - name: PORT
            value: "80"
          resources:
              limits:
                memory: 768Mi
              requests:
                memory: 256Mi
          readinessProbe:
            tcpSocket:
              port: 80 
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 80
            initialDelaySeconds: 15
            periodSeconds: 20
            successThreshold: 1
            failureThreshold: 3
        - name: my-project-nextjs
          image: <my_image>
          imagePullPolicy: Always
          ports:
          - containerPort: 9000
          env:
          - name: PORT
            value: "9000"
          - name: DD_AGENT_HOST
            valueFrom:
              fieldRef:
                fieldPath: status.hostIP
          - name: DD_SERVICE_NAME
            value: "my-project-beta"
          resources:
              limits:
                memory: 1Gi
              requests:
                memory: 512Mi
          readinessProbe:
            tcpSocket:
              port: 9000
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            tcpSocket:
              port: 9000
            initialDelaySeconds: 15
            periodSeconds: 20
            successThreshold: 1
            failureThreshold: 3
      dnsPolicy: ClusterFirst
      imagePullSecrets:
      - name: <name>

---
apiVersion: v1
kind: Service
metadata:
  name: my-project
  namespace: beta
  labels:
    name: my-project
spec:
  type: ClusterIP
  ports:
    - name: nginx-container
      port: 80
      targetPort: 80 
    - name: nextjs-container
      port: 9000
      targetPort: 9000
  selector:
    name: my-project

Мне удалось заставить эту штуку работать, открыв порт 9000. Я изменил proxy_pass на имя своей службы my-project и добавил эту часть, чтобы решить мою проблему:

- name: nextjs-container
      port: 9000
      targetPort: 9000

Вам нужно подключиться к <pod_name>:9000, а не localhost:9000

Kevin Kopf 26.08.2024 19:00

@KevinKopf Спасибо за ответ. Я попытался установить my-project:9000, но у модуля теперь статус «CrashLoopBackOff», а журнал: nginx: [emerg] host not found in upstream my-project in /etc/nginx/sites-enabled/my-project.conf:79 (то есть proxy_pass http://my-project:9000;). Я не знаю, правильный ли это подход, потому что имя моего модуля динамическое (например, my-project-54546f8d5c-2bvnh).

PeacefulBee 26.08.2024 22:34

В вашем случае слишком много неизвестных переменных. Как вы реализуете проект? Как выглядит конфигурация развертывания? Не имеет ли смысл использовать входной контроллер?

Kevin Kopf 27.08.2024 08:38

Извините за отсутствие информации, сначала не знала, чем поделиться. Я добавил свою конфигурацию развертывания. Мне также удалось решить мою проблему (я добавил решение в свой пост), благодаря вам и @RahulK. Спасибо за вашу помощь и ваше время :) Если вы считаете, что мне все еще нужно добавить информацию, которая может помочь другим людям, сообщите мне, и я обновлю свой пост.

PeacefulBee 27.08.2024 12:32
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
0
4
53
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В конфигурации вместо localhost используйте имя службы Kubernetes, которое предоставляет контейнер my-project-nextjs. Обновите его, как показано ниже

 location / {
        proxy_pass http://<service_name>:9000;
    }

Сервис должен быть примерно таким, как показано ниже.

apiVersion: v1
kind: Service
metadata:
  name: my-project-nextjs-service
spec:
  selector:
    app: my-project-nextjs
  ports:
    - protocol: TCP
      port: 9000
      targetPort: 9000

Также убедитесь, что существует служба Kubernetes, которая предоставляет контейнер my-project-nextjs. И с помощью приведенной ниже команды проверьте, доступен ли сервис Kubernetes из контейнера my-project-nginx.

kubectl exec -it <nginx-pod-name> -- curl http://<service_name>:9000

Спасибо, с service_name работает! Мне также пришлось открыть порт 9000 в своем Service.

PeacefulBee 27.08.2024 12:33

Другие вопросы по теме