Плохой запрос (400): Django / Nginx / Gunicorn / Kubernetes

У меня есть проект Django, запущенный на Kubernetes с Redis, Postgres, Celery, Flower и Nginx. Я развертываю его с помощью Minikube и Kubectl на моем localhost. Все выглядит хорошо; журналы стручков выглядят нормально, но когда я пытаюсь проложить туннель к службе Nginx, она возвращает Bad Request (400). Журналы, файлы проекта, dockerfile и различные YAML-файлы прилагаются.

Django pod logs:

Operations to perform:
  Apply all migrations: admin, auth, contenttypes, sessions, website
Running migrations:
  No migrations to apply.

138 static files copied to '/app/staticfiles'.
[2024-05-11 15:21:33 +0000] [9] [INFO] Starting gunicorn 22.0.0
[2024-05-11 15:21:33 +0000] [9] [INFO] Listening at: http://0.0.0.0:8000 (9)
[2024-05-11 15:21:33 +0000] [9] [INFO] Using worker: sync
[2024-05-11 15:21:33 +0000] [10] [INFO] Booting worker with pid: 10

Журналы подкачки Nginx:

Nginx pod logs:
/docker-entrypoint.sh: /docker-entrypoint.d/ is not empty, will attempt to perform configuration
/docker-entrypoint.sh: Looking for shell scripts in /docker-entrypoint.d/
/docker-entrypoint.sh: Launching /docker-entrypoint.d/10-listen-on-ipv6-by-default.sh
10-listen-on-ipv6-by-default.sh: info: can not modify /etc/nginx/conf.d/default.conf (read-only file system?)
/docker-entrypoint.sh: Sourcing /docker-entrypoint.d/15-local-resolvers.envsh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/20-envsubst-on-templates.sh
/docker-entrypoint.sh: Launching /docker-entrypoint.d/30-tune-worker-processes.sh
/docker-entrypoint.sh: Configuration complete; ready for start up
2024/05/14 19:15:32 [notice] 1#1: using the "epoll" event method
2024/05/14 19:15:32 [notice] 1#1: nginx/1.25.5
2024/05/14 19:15:32 [notice] 1#1: built by gcc 12.2.0 (Debian 12.2.0-14) 
2024/05/14 19:15:32 [notice] 1#1: OS: Linux 6.6.16-linuxkit
2024/05/14 19:15:32 [notice] 1#1: getrlimit(RLIMIT_NOFILE): 1048576:1048576
2024/05/14 19:15:32 [notice] 1#1: start worker processes
2024/05/14 19:15:32 [notice] 1#1: start worker process 20
2024/05/14 19:15:32 [notice] 1#1: start worker process 21
2024/05/14 19:15:32 [notice] 1#1: start worker process 22
2024/05/14 19:15:32 [notice] 1#1: start worker process 23
2024/05/14 19:15:32 [notice] 1#1: start worker process 24
2024/05/14 19:15:32 [notice] 1#1: start worker process 25
2024/05/14 19:15:32 [notice] 1#1: start worker process 26
2024/05/14 19:15:32 [notice] 1#1: start worker process 27
10.244.0.1 - - [14/May/2024:19:15:43 +0000] "GET / HTTP/1.1" 400 154 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"
10.244.0.1 - - [14/May/2024:19:15:43 +0000] "GET /favicon.ico HTTP/1.1" 400 154 "http://127.0.0.1:58187/" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36" "-"

Project setting.py:

Проект urls.py:

from django.contrib import admin
from django.urls import path, include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path("admin/", admin.site.urls),
    path("", include("website.urls")),
]

if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Проект wsgi.py:

import os
from django.core.wsgi import get_wsgi_application

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "premier_league_predictions.settings")
application = get_wsgi_application()

Dockerfile:

FROM python:3.11.8-slim
ENV PYTHONUNBUFFERED 1
ENV PYTHONDONTWRITEBYTECODE 1
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
EXPOSE 8000

Django deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: django
spec:
  replicas: 1
  selector:
    matchLabels:
      app: django
  template:
    metadata:
      labels:
        app: django
    spec:
      containers:
        - name: django
          image: ***/***:latest
          command: ["/bin/sh", "-c"]
          args:
            - >
              python manage.py migrate &&
              python manage.py collectstatic --no-input &&
              gunicorn premier_league_predictions.wsgi:application --bind 0.0.0.0:8000
          ports:
            - containerPort: 8000
          env:
            - name: DEBUG
              valueFrom:
                configMapKeyRef:
                  name: django-cm
                  key: debug

            - name: SECRET_KEY
              valueFrom:
                secretKeyRef:
                  name: django-credentials
                  key: key

            - name: DB_NAME
              valueFrom:
                configMapKeyRef:
                  name: postgres-cm
                  key: name

            - name: DB_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: user

            - name: DB_PASSWORD
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: password

            - name: DB_HOST
              valueFrom:
                configMapKeyRef:
                  name: django-cm
                  key: db_host

            - name: DB_PORT
              valueFrom:
                configMapKeyRef:
                  name: django-cm
                  key: db_port

            - name: REDIS_HOST
              valueFrom:
                configMapKeyRef:
                  name: django-cm
                  key: redis_host

            - name: REDIS_PORT
              valueFrom:
                configMapKeyRef:
                  name: django-cm
                  key: redis_port
          volumeMounts:
            - name: django-staticfiles
              mountPath: /data/staticfiles
            - name: django-media
              mountPath: /data/media
      imagePullSecrets:
        - name: dockerhub-credentials
      volumes:
        - name: django-staticfiles
          persistentVolumeClaim:
            claimName: django-staticfiles-pvc
        - name: django-media
          persistentVolumeClaim:
            claimName: django-media-pvc

Django pv.yaml:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: django-staticfiles-pv
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 1Gi
  hostPath:
    path: /data/django-staticfiles-pv

---

apiVersion: v1
kind: PersistentVolume
metadata:
  name: django-media-pv
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  capacity:
    storage: 1Gi
  hostPath:
    path: /data/django-media-pv

Django pvc.yaml:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: django-staticfiles-pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeName: django-staticfiles-pv

---

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: django-media-pvc
spec:
  storageClassName: manual
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  volumeName: django-media-pv

Django service.yaml:

kind: Service
apiVersion: v1
metadata:
  name: django-service
spec:
  selector:
    app: django
  ports:
    - port: 8000
      targetPort: 8000

Nginx deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80
          volumeMounts:
            - name: nginx-config
              mountPath: /etc/nginx/conf.d
            - name: django-staticfiles
              mountPath: "/data/staticfiles"
            - name: django-media
              mountPath: "/data/media"
      volumes:
        - name: nginx-config
          configMap:
            name: nginx-cm
        - name: django-staticfiles
          persistentVolumeClaim:
            claimName: django-staticfiles-pvc
        - name: django-media
          persistentVolumeClaim:
            claimName: django-media-pvc

Nginx config-map.yaml:

apiVersion: v1
kind: ConfigMap
metadata:
  name: nginx-cm
data:
  default.conf: |
    server {
        listen 80;
        server_name _;

        location / {
            proxy_pass http://django-service:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Forwarded-Host $server_name;
            proxy_set_header X-Real-IP $remote_addr;
        }
    }

Nginx service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
  selector:
    app: nginx

Я был бы очень благодарен за помощь в получении доступа к приложению с помощью URL. Я много чего перепробовал, но чувствую, что мне не хватает знаний

Спасибо!

Вернуться на верх