使用PostgreSQL将Django应用程序部署到Kubernetes Google Cloud集群

时间:2018-05-02 23:57:43

标签: django postgresql docker kubernetes

我在尝试将我的Django应用程序和PostgreSQL数据库部署到我已配置的Kubernetes Google Cloud群集时遇到了麻烦。

我已经为我的Django Application和PostgreSQL数据库成功创建了Docker容器。这是我的docker-compose.yml文件的样子:

version: '3'

services:
  db:
    image: postgres
    environment:
      - POSTGRES_USER=stefan_radonjic
      - POSTGRES_PASSWORD=cepajecar995
      - POSTGRES_DB=agent_technologies_db
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000 --settings=agents.config.docker-settings
    volumes: 
      - .:/agent-technologies
    ports: 
      - "8000:8000"
    links:
      - db
    depends_on:
      - db

我已经构建了图像,并尝试了sudo docker-compose up命令,应用程序运行正常。

成功将Django Application和PostgreSQL对接后,我尝试配置Kubernetes所需的部署/服务YML文件,但我遇到了麻烦。例如:

deployment-definition.yml - 用于部署Django应用程序的文件:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: agent-technologies-deployment
      labels:
        app: agent-technologies
        tier: backend
    spec:
      template:
        metadata:
          name: agent-technologies-pod
          labels:
            app: agent-technologies
            tier: backend
        spec:
          containers:
            - name: 
              image:
              ports:
                - containerPort: 8000
        replicas:
        selector:
          matchLabels:
            tier: backend

在容器的词典列表中,我知道我的容器名称应该是web,但我不确定该容器的图像位于何处,所以我不知道应该指定什么作为容器图像。< / p>

另一个问题在于postgres / deployment-definition.yml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: postgres
spec:
  replicas: 1
  selector:
    matchLabels:
      app: postgres-container
  template:
    metadata:
      labels:
        app: postgres-container
        tier: backend
    spec:
      containers:
        - name: postgres-container
          image: postgres:9.6.6
          env:
            - name: POSTGRES_USER
              valueFrom:
                secretKeyRef:
                  name: postgres-credentials
                  key: user

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

            - name: POSTGRES_DB
              value: agent_technologies_db
          ports:
            - containerPort: 5432
          volumeMounts:
            - name: postgres-volume-mount
              mountPath: /var/lib/postgresql/data

      volumes:
        - name: postgres-volume-mount
          persistentVolumeClaim:
            claimName: postgres-pvc

我不明白volumeMountsvolumes的用途,以及我是否正确指定了它们。

这是我的secret-definition.yml文件:

apiVersion: v1
kind: Secret
metadata:
  name: postgres-credentials
type: Opaque
data:
  user: stefan_radonjic
  passowrd: cepajecar995

我的postgres / service-definition.yml文件:

apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres-container
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432

我的postgres / volume-definition.yml文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /data/postgres-pv

我的postgres / volume-claim-definitono.yml文件:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: postgres-pv
  labels:
    type: local
spec:
  capacity:
    storage: 2Gi
  storageClassName: standard
  accessModes:
    - ReadWriteMany
  hostPath:
    path: /data/postgres-pv

最后但并非最不重要的是,我的service-definition.yml文件 - 用于Django应用程序

apiVersion: v1
kind: Service
metadata:
  name: agent-technologies-service
spec:
  selector:
    app: agent-technologies
  ports:
    - protocol: TCP
      port: 8000
      targetPort: 8000
  type: NodePort

除了上面已经提到的问题,我还想问我做得对吗?如果没有,我该怎么做才能解决这个问题。

1 个答案:

答案 0 :(得分:4)

  

在容器的词典列表中,我知道我的容器名称应该是web,但我不确定该容器的图像位于何处,所以我不知道应该指定什么作为容器图像。

  • 容器的名称是pod的本地名称(您可以有多个容器共享同一个pod)。容器名称(在您的情况下为Web)适用于部署时提供的文件:

    # setting name of first container within pod to web
    spec:
      containers:
        - name: web
    
  • 容器的图片必须位于某个可用的docker容器注册表中。从托管自己的docker注册表到使用公共可用的注册表注册表有多种选择。在任何情况下,你必须能够将你的构建阶段推送到该docker容器注册表(无论是amazon ECR,Docker,Gitlab,自托管......),并从kubernetes中提取该注册表(安全设置,提取秘密)等等...)。在您的docker-compose文件中,您使用两个容器。对于db,您使用公共postgres映像,对于Web,您使用build命令和映像仅存储到该主机上的本地docker注册表(您必须将其推送到公共存储库以便k8s能够在部署期间从中提取)。 / LI>
  

我不明白volumeMounts和卷的用途,以及我是否正确指定它们。

  • 简而言之,卷用于将卷附加到容器。根据您的使用案例和决定的体系结构,有几种卷的方法,但总而言之,它们归结为短暂的,持续的和持久的。在容器终止或重启时会出现短暂的错误,常量(例如来自configMaps)用于将配置文件传递给容器,而持久性对于有状态应用程序(数据库等)最有意义。您可以通过多种方式指定卷,所有卷都必须具有名称(由volumeMount引用)以及直接卷规范或卷声明规范(后者建议持久卷,因为您可以通过这种方式从自动配置中受益)。 LI>
  • VolumeMounts用于定义容器文件系统预定义卷的安装位置。它们引用要按名称挂载的卷,通过mountPath在容器文件系统上提供挂载点,并且在某些情况下可以包含指向特定文件的子路径。
  • 在您的示例中,您将持久卷声明获得的卷绑定到postgres的数据路径(/ var / lib / postgresql / data)。虽然您使用了未指定的存储类,但有趣的是,您的Persistent卷在主机上定义为localpath。这意味着在每个节点上启动了此数据库窗格,您最终会将该窗格的数据库容器的/ var / lib / postgresql / data指向该特定节点上的/ data / postgres-pv。这将打开您以下问题:假设您有3个节点(A,B和C)并且您的数据库pod在A上启动,使用A的/ data / postgres-pv文件夹作为自己的/ var / lib / postrgresql / data。然后你重新启动它,它被终止并重新安排到节点B.突然之间,它使用B的/ data / postgres-pv本地文件夹(空),你最终得到空数据库。如果您使用主机的本地文件系统来保持持久性,则需要将这些pod与节点(或更好的亲和力)选择器联系起来。出于性能原因,建议运行本地文件系统的数据库卷,但软管包无法轻松重新安排。另一种方法是拥有一些可以独立于节点(例如Amazon EBS)安装的真正持久卷,它们需要不同的PVC(或使用配置器)。
  

除了上面已经提到的问题,我还想问我做得对吗?如果没有,我该怎么做才能解决这个问题。

  • 如上所述,定义存储类并将数据库pod锁定到特定节点或应用某种动态配置,以便卷跟随pod在点头上的位置。
  • 相反的偏好:不要将所有内容放在默认命名空间中,使用单独的命名空间来处理k8s清单,以后更难移动所有内容,更难以意外删除错误的内容......
  • 个人偏好:数据库是有状态应用程序,因此建议使用statefulset而不是部署。
  • 当您从docker-compose文件开始并希望转换为kubernetes清单时,有一些工具可以帮助您,值得检查。
  • 关于kubernetes的文档有点过时但非常好,你可以对卷和volumeClaims进行一些很好的阅读,还有活跃的松弛通道。
  • 哦,在这里发布文件时模拟用户/传递,我们现在知道cepa ...
  • 最后,你做得很好!