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

Ste*_*jic 1 django postgresql docker kubernetes

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

我已经成功地为我的 Django 应用程序和 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
Run Code Online (Sandbox Code Playgroud)

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

在成功对 Django 应用程序和 PostgreSQL 进行 dockerizing 后,我尝试配置YMLKubernetes 所需的部署/服务文件,但我在这样做时遇到了麻烦。例如:

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
Run Code Online (Sandbox Code Playgroud)

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

另一个问题在于 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
Run Code Online (Sandbox Code Playgroud)

我不明白是什么volumeMountsvolumes是的,如果我连正确指定它们。

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

apiVersion: v1
kind: Secret
metadata:
  name: postgres-credentials
type: Opaque
data:
  user: stefan_radonjic
  passowrd: cepajecar995
Run Code Online (Sandbox Code Playgroud)

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

apiVersion: v1
kind: Service
metadata:
  name: postgres-service
spec:
  selector:
    app: postgres-container
  ports:
    - protocol: TCP
      port: 5432
      targetPort: 5432
Run Code Online (Sandbox Code Playgroud)

我的 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
Run Code Online (Sandbox Code Playgroud)

还有我的 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
Run Code Online (Sandbox Code Playgroud)

最后但并非最不重要的是,我的 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
Run Code Online (Sandbox Code Playgroud)

除了上面我已经问过的问题,我还想问我这样做对吗?如果没有,我能做些什么来解决这个问题。

Con*_*nst 5

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

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

    # setting name of first container within pod to web
    spec:
      containers:
        - name: web
    
    Run Code Online (Sandbox Code Playgroud)
  • 容器的镜像必须在一些可用的 docker 容器注册表中。从托管自己的 docker 注册表到使用公开可用的注册表,有多种选择。在任何情况下,您都必须能够将构建阶段推送到该 docker 容器注册表(无论是亚马逊 ECR、Docker、Gitlab、自托管...),并从 kubernetes 中从该注册表中提取(安全设置、提取机密)等等...)。在您的 docker-compose 文件中,您使用了两个容器。对于 db,您使用公共 postgres 映像,对于 web,您使用 build 命令,并且映像仅存储到该主机上的本地 docker 注册表(您必须将其推送到公共存储库,以便 k8s 能够在部署期间从中提取)。

我不明白volumeMounts 和volumes 是做什么用的,如果我什至正确指定了它们。

  • 简而言之,卷用于将卷附加到容器。根据您的用例和确定的架构,有多种卷的方法,但总而言之,它们归结为短暂的、恒定的和持久的。临时将在容器终止或重新启动时丢失,常量(例如来自 configMaps)用于将配置文件传递给容器,而持久对于有状态应用程序(数据库等)最有趣。您可以通过多种方式指定卷,所有卷都必须具有名称(由 volumeMount 引用)以及直接卷规范或卷声明规范(建议后者用于持久卷,因为您可以从这种方式的自动配置中受益)。
  • VolumeMounts 用于定义容器文件系统预定义卷应挂载的位置。它们引用要按名称挂载的卷,通过 mountPath 在容器文件系统上提供挂载点,并且在某些情况下可以具有特定文件的子路径。
  • 在您的示例中,您将持久卷声明获得的卷绑定到 postgres (/var/lib/postgresql/data) 的数据路径。尽管您使用了未指定的存储类,但有趣的部分是您的 Persistent 卷被定义为主机上的 localpath。这意味着在每个节点上你启动了这个数据库 pod,你最终会将该 pod 的 db 容器的 /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 本地文件夹(空),你最终得到空数据库。如果您使用主机' s 本地文件系统为了持久性,您需要将此类 pod 与节点(或更好的具有关联性)选择器联系起来。出于性能原因,建议运行本地文件系统的数据库卷,但软管 pod 失去了轻松重新调度的能力。另一种方法是拥有一些可以独立于节点(例如 Amazon EBS)安装的真正持久的卷,并且它们需要不同的 PVC(或要使用的配置器)。

除了上面我已经问过的问题,我还想问我这样做对吗?如果没有,我能做些什么来解决这个问题。

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