【问题标题】:Kubernetes + Django / PostgreSQL - How do I specify HOST of my PostgreSQL Database when I deploy it to Kubernetes ClusterKubernetes + Django / PostgreSQL - 当我将 PostgreSQL 数据库部署到 Kubernetes 集群时,如何指定它的主机
【发布时间】:2018-05-24 17:58:29
【问题描述】:

我在配置我的 Dockerized Django + PostgreSQL DB 应用程序以在我使用谷歌云平台创建的 Kubernetes 集群上工作时遇到很多问题。

当我将 Docker Hub 中的 PostgreSQL 映像和我的 Django Web 应用程序的映像部署到 Kubernetes 集群时,如何从我的 settings.py 文件中指定 DATABASES.default.HOST?

这就是我希望我的应用程序如何工作。当我在本地运行应用程序时,我想使用 SQLITE DB,为此我在我的 settings.py 文件中进行了以下更改:

if(os.getenv('DB')==None):
    print('Development - Using "SQLITE3" Database')
    DATABASES = {
        'default':{
            'ENGINE': 'django.db.backends.sqlite3',
            'NAME': os.path.join(BASE_DIR,'db.sqlite3'),
        }
    }
else:
    print('Production - Using "POSTGRESQL" Database')
    DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.postgresql_psycopg2',
            'NAME': 'agent_technologies_db',
            'USER': 'stefan_radonjic',
            'PASSWORD': 'cepajecar995',
            'HOST': ,  #???
            'PORT': ,  #???
            }
    }

主要思想是,当我将应用程序部署到 Kubernetes 集群时,在 Kubernetes Pod 对象内部,一个 Docker 容器(我的 Dockerized Django 应用程序)将运行。创建容器时,我还创建了环境变量 DB 并将其设置为 True。因此,当我部署应用程序时,我使用 PostgreSQL 数据库。

注意:如果有人对我应该如何将本地开发与生产开发分开有任何其他建议,请发表评论。

这是我的 Dockerfile 的样子:

FROM python:3.6

ENV PYTHONUNBUFFERED 1
RUN mkdir /agent-technologies
WORKDIR /agent-technologies
COPY . /agent-technologies 
RUN pip install -r requirements.txt

EXPOSE 8000

这是我的 docker-compose 文件的样子:

version: '3'
services:
  web:
    build: .
    command: python src/manage.py runserver --settings=agents.config.settings
    volumes: 
      - .:/agent-technologies
    ports: 
      - "8000:8000"
    environment:
      - DB=true

在本地运行应用程序时,它工作得非常好。但是当我尝试将它部署到 Kubernetes 集群时,运行我的应用程序容器的 Pod 对象在无限循环中崩溃,因为我不知道在生产环境中运行应用程序时如何指定 DATABASES.default.HOST。当然,在 docker-compose 文件 (command: python src/manage.py runserver --settings=agents.config.settings) 中指定的命令可能会产生异常并导致 Pod 无限循环崩溃。

注意:我已经为 Kubernetes 创建了所有必要的配置文件(部署定义/服务/秘密/卷文件)。这是我的github链接:https://github.com/StefanCepa/agent-technologies-bachelor

任何帮助将不胜感激!提前谢谢大家!

【问题讨论】:

    标签: django postgresql docker kubernetes


    【解决方案1】:

    您必须为您的 postgres pod 创建一个 service(集群 ip)以使其“可访问”。当你创建一个服务时,你可以通过<service name>.default:<port>access它。但是,将 postgres(或任何 db)作为简单的 pod 运行是危险的(一旦您或 k8s 重新创建 pod 或对其进行扩展,您将丢失数据)。您可以使用service 或使用statefulSets 正确安装它。

    获得地址后,您可以将其放入env variable 并从您的settings.py 中访问它

    编辑: 将其放入您的部署 yaml (example):

    env:
    - name: POSTGRES_HOST
      value: "postgres-service.default"
    - name: POSTGRES_PORT
      value: "5432"
    - name: DB
      value: "DB"
    

    在你的 settings.py 中

    'USER': 'stefan_radonjic',
    'PASSWORD': 'cepajecar995',
    'HOST': os.getenv('POSTGRES_HOST'),
    'PORT': os.getenv('POSTGRES_PORT'),
    

    【讨论】:

    • 我在问题中提供了我的 github 链接。我已经创建了一个服务,并将我的 PostgreSQL 数据存储在集群中每个节点的 PD 上。我需要的是当我的应用在集群中运行时如何指定 DATABASE.defaul.HOST 的信息。
    • 添加了一些 sn-ps。试试这个,让我知道它是否有效。
    • 非常感谢您的帮助!请您解释一下环境变量 DB 和 POSTGRES_HOST 环境变量的意义。我的意思是,当我指定“postgres-service.default”时,这是否意味着环境变量将在“default”命名空间中查找 postgres-service 对象?再次非常感谢您!
    • 是的 - 它会在默认命名空间中查找 postgres,如果您有多个数据库副本,服务也会进行负载平衡。实际上有很多方法可以“输入”(或访问)它 - 但这很简单。
    • 我明白了。而环境变量DB是postgres contianer的名字还是?
    【解决方案2】:

    以下是我的发现:

    1. postgres 实例依赖于持久卷。我看到了持久卷声明的代码,但没有看到持久卷本身。所以我必须先创建它。
    apiVersion: v1
    kind: PersistentVolume
    metadata:
      labels:
        type: local
      name: task-pv-volume
    spec:
      accessModes:
      - ReadWriteMany
      capacity:
        storage: 1Gi
      hostPath:
        path: /tmp/data
      persistentVolumeReclaimPolicy: Retain
    
    1. agent-technologies-bachelor/agents/config/kubernetes/postgres/secrets-definition.yml 中有一个类型的术语密码。
    data:
      user: c3RlZmFuX3JhZG9uamlj #stefan_radonjic
      passowrd: sdfsdfsd #cepajecar995
    

    因此,postgres 实例无法启动。我通过运行命令 kubectl describe pods 查看事件发现了这一点

    1. Docker 映像中没有执行应用程序的命令。结果,如果我在 cepa995/agents_web 上运行您的 docker 映像,它只会退出并且不会运行任何应用程序。这就是 django 应用程序没有运行的原因。为了解决这个问题,我修改了 Dockerfile 以在末尾添加 CMD 指令。我看到你把它放在 docker-compose 中来构建图像,但是这个命令必须在 Dockerfile 本身中。 Dockerfile 现在看起来像这样:
    FROM python:3.6
    ENV PYTHONUNBUFFERED 1
    RUN mkdir /agent-technologies
    WORKDIR /agent-technologies
    COPY . /agent-technologies
    RUN pip install -r src/requirements.txt
    EXPOSE 8000
    CMD python src/manage.py runserver 0.0.0.0:8000 --settings=agents.config.settings
    

    【讨论】:

    • 非常感谢您的帮助!对此,我真的非常感激!请你告诉我几件事。首先,您是在 Minikube 还是 Google Cloud Kubernetes 集群上运行我的应用程序?我之所以问是因为,我在文档中读到 VolumeClaim 也可以充当卷,并且由于在 Google Cloud 集群上我已经在集群节点上有 PD,我认为我不需要 PersistentVolume 对象。其次,我到底需要 docker-compose 文件吗?或者我只是构建我的 Dockefile,在我的 repo 上发布图像,就是这样?再次感谢您的所有帮助!
    • 我在 play-with-k8s.com 上试过这个。我必须创建一个单独的 PV。那时你可能不需要那个。您不需要 docker-compose 文件。如果您已成功构建映像并推送到您的存储库。但要确保它也有 CMD 指令。
    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 2020-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-17
    相关资源
    最近更新 更多