【问题标题】:How to serve the static content in nginx + django + kubernetes?如何在 nginx + django + kubernetes 中提供静态内容?
【发布时间】:2020-09-09 04:23:37
【问题描述】:

我有一个运行 django 应用程序部署的 minikube。直到今天,我们使用的是 django 启动的服务器。现在,我添加了另一个 Nginx 容器,以便我们可以部署 django 应用程序,因为我读到 django 并不是真正用于生产。在阅读了一些文档和博客之后,我配置了 deployment.yaml 文件,它现在运行得非常好。 问题是没有提供静态内容。这实际上是因为静态内容位于 django 容器中,而不是 Nginx 容器中。 (如果他们可以分享数量,请澄清这个疑问或误解)什么是最好的方式,以便我可以提供我的静态内容? 这是我的部署文件的规范:

spec:
            containers:
                - name: user-django-app
                  image: my-django-app:latest
                  ports:
                    - containerPort: 8000
                  env:
                    - name: POSTGRES_HOST
                      value: mysql-service
                    - name: POSTGRES_USER
                      value: admin
                    - name: POSTGRES_PASSWORD
                      value: admin
                    - name: POSTGRES_PORT
                      value: "8001"
                    - name: POSTGRES_DB
                      value: userdb
                - name: user-nginx
                  image: nginx
                  volumeMounts:
                    - name: nginx-config
                      mountPath: /etc/nginx/nginx.conf 
                      subPath: nginx.conf
            volumes:
              - name: nginx-config
                configMap:
                  name: nginx-config

我相信

server {
    location /static {
        alias /var/www/djangoapp/static;
    }
}

需要更改。但是我不知道我应该写什么?另外,如何在部署完成后立即运行python manage.py migratepython manage.py collectstatic

请提供资源/文档/博客,这将帮助我做到这一点。谢谢! 谢谢。

@willrof 回答后,这是我当前的 YAML 文件。

apiVersion: apps/v1
kind: Deployment
metadata:
    name: user-deployment
    labels: 
        app: web
spec:
    replicas: 1
    selector:
        matchLabels:
            app: web
            micro-service: user
    template:
        metadata:
            name: user
            labels:
                app: web
                micro-service: user
        spec:
            containers:
                - name: user-django-app
                  image: docker.io/dev1911/drone_plus_plus_user:latest
                  ports:
                    - containerPort: 8000
                  env:
                    - name: POSTGRES_HOST
                      value: mysql-service
                    - name: POSTGRES_USER
                      value: admin
                    - name: POSTGRES_PASSWORD
                      value: admin
                    - name: POSTGRES_PORT
                      value: "8001"
                    - name: POSTGRES_DB
                      value: userdb
                  volumeMounts:
                    - name: shared
                      mountPath: /shared
                  command: ["/bin/sh", "-c"]
                  args: ["apt-get install nano"]
                - name: user-nginx
                  image: nginx
                  volumeMounts:
                    - name: nginx-config
                      mountPath: /etc/nginx/nginx.conf 
                      subPath: nginx.conf
                    - name: shared
                      mountPath: /var/www/user/static
            volumes:
              - name: nginx-config
                configMap:
                  name: nginx-config
              - name: shared
                emptyDir: {}

而 nginx-config 文件是

worker_processes  auto;

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
  worker_connections  4096;  ## Default: 1024
}

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;
    log_format ltsv 'domain:$host\t'
                    'host:$remote_addr\t'
                    'user:$remote_user\t'
                    'time:$time_local\t'
                    'method:$request_method\t'
                    'path:$request_uri\t'
                    'protocol:$server_protocol\t'
                    'status:$status\t'
                    'size:$body_bytes_sent\t'
                    'referer:$http_referer\t'
                    'agent:$http_user_agent\t'
                    'response_time:$request_time\t'
                    'cookie:$http_cookie\t'
                    'set_cookie:$sent_http_set_cookie\t'
                    'upstream_addr:$upstream_addr\t'
                    'upstream_cache_status:$upstream_cache_status\t'
                    'upstream_response_time:$upstream_response_time';
    access_log  /var/log/nginx/access.log  ltsv;
    sendfile        on;
    tcp_nopush     on;
    server_names_hash_bucket_size 128; # this seems to be required for some vhosts
    keepalive_timeout  65;
    gzip  on;

    server {
        listen 80;
        server_name  example.com
            ;
        location / {
            proxy_pass http://127.0.0.1:8000;
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        }
        location /static {
            alias /var/www/user/static;
        }
    }
#    include /etc/nginx/conf.d/*.conf;
}

这个配置不是我写的,但我发现了这个并编辑了我的使用。

【问题讨论】:

  • 可以参考thisthis
  • 谢谢你,@hdhruna 我希望这能解决我的问题。
  • 检查提供的链接后,如果您仍然遇到问题,请使用您的新发现和问题更新您的问题,您可以在评论中提及我,我也可以为您查找。
  • @willrof 当然,谢谢。我尚未对此进行测试,但已经浏览了链接。我一定会寻求帮助的。非常感谢。
  • @willrof 我做了提到的两个链接中的建议。创建共享卷有效。但我必须手动将我的静态文件夹的内容从应用程序复制到共享目录。我怎样才能自动化呢?带有 args 的命令 bin/sh 不起作用。添加这些行时部署失败。请帮忙。

标签: django nginx kubernetes minikube


【解决方案1】:

我们在 cmets 聊天后,您告诉我您在使用 cmd 和 args 时遇到了困难。

这是一个名为two-containers.yaml的示例:

apiVersion: v1
kind: Pod
metadata:
  name: two-containers
spec:
  restartPolicy: Never

  containers:
  - name: python
    image: python
    volumeMounts:
    - name: shared-data
      mountPath: /pod-data
    command: ["/bin/sh"]
    args: ["-c", "apt-get update && apt-get install -y curl && mkdir /curl-folder && cp /usr/bin/curl /curl-folder && cp -r /curl-folder /pod-data/"]

  - name: user-nginx
    image: nginx
    volumeMounts:
      - name: shared-data
        mountPath: /tmp/pod-data

  volumes:
  - name: shared-data
    emptyDir: {}

python 将启动,运行apt-get update 然后运行apt-get install -y curl 然后mkdir /curl-folder 然后将usr/bin/curl 复制到/curl-folder 然后将文件夹/curl-folder 复制到/pod-data 共享安装卷。

一些观察:

  • 容器映像必须具有command 中提到的二进制文件(如 python 中的/bin/sh)。
  • 尝试使用 && 在 args 字段中连续链接命令,这样更容易测试和部署。

复制:

$ kubectl apply -f two-container-volume.yaml 
pod/two-containers created

$ kubectl get pods -w
NAME             READY   STATUS    RESTARTS   AGE
two-containers   2/2     Running   0          7s
two-containers   1/2     NotReady  0          30s

$ kubectl describe pod two-containers
...
Containers:
  python:
    Container ID:  docker://911462e67d7afab9bca6cdaea154f9229c80632efbfc631ddc76c3d431333193
    Image:         python
    Command:
      /bin/sh
    Args:
      -c
      apt-get update && apt-get install -y curl && mkdir /curl-folder && cp /usr/bin/curl /curl-folder && cp -r /curl-folder /pod-data/
    State:          Terminated
      Reason:       Completed
      Exit Code:    0

  user-nginx:
    State:          Running
  • python 容器正确执行并完成,现在让我们检查一下 nginx 容器内的文件记录。
$ kubectl exec -it two-containers -c user-nginx -- /bin/bash
root@two-containers:/# cd /tmp/pod-data/curl-folder/     
root@two-containers:/tmp/pod-data/curl-folder# ls
curl

如果您需要进一步的帮助,请在尝试运行时使用 command+args 发布 yaml,我们可以帮助您解决语法问题。

【讨论】:

  • 非常感谢。这让我几乎清楚。您在这里使用的是 debian 映像。我正在使用我自己的图像,它是使用 python 3.7 图像构建的。这就是我的部署失败的原因吗?另外,如果有人遇到同样的问题并需要帮助,我会标记这个正确答案。
  • 刚刚用bashsh 测试了hub.docker.com/_/python 默认python 图像,它的工作原理相同。 (我只是将图像从 debian 更改为 python)。我将用 python 图像更改我的答案供您比较。在您尝试运行时在此处发布 yaml,以便我们检查!
  • 我在问题中添加了 yaml 文件。
【解决方案2】:

如果是 django 应用,请考虑使用 whitenoise http://whitenoise.evans.io/en/stable/ 从 minikube 或 kubernetes 提供静态内容。

这是一个直截了当的建议,但在有人提到它之前我不得不搜索很多。

【讨论】:

    猜你喜欢
    • 2020-09-20
    • 2014-07-30
    • 1970-01-01
    • 1970-01-01
    • 2011-03-24
    • 2013-04-15
    • 2014-07-09
    • 2019-02-13
    • 2019-01-23
    相关资源
    最近更新 更多