首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >运行在Kubernetes cron作业中的应用程序不连接到同一个Kubernetes集群中的数据库。

运行在Kubernetes cron作业中的应用程序不连接到同一个Kubernetes集群中的数据库。
EN

Stack Overflow用户
提问于 2021-01-13 17:59:50
回答 1查看 1.4K关注 0票数 3

我有一个Kubernetes集群,运行一个PostgreSQL数据库、一个Grafana仪表板和一个Python单运行应用程序(构建为一个Docker映像),该应用程序在Kubernetes CronJob中每小时运行一次(参见下面的清单)。此外,这都是部署使用ArgoCD与Istio侧汽车注入.

我遇到的问题(如标题所示)是,我的Python应用程序无法连接到集群中的数据库。这对我来说很奇怪,因为仪表板实际上可以连接到数据库,所以我不确定Python应用程序有什么不同。

以下是我的清单(更改了一些内容以删除可识别的信息):

database.yaml含量

代码语言:javascript
复制
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: database
  name: database
spec:
  replicas: 1
  selector:
    matchLabels:
      app: database
  strategy: {}
  template:
    metadata:
      labels:
        app: database
    spec:
      containers:
      - image: postgres:12.5
        imagePullPolicy: ""
        name: database
        ports:
        - containerPort: 5432
        env:
          - name: POSTGRES_DB
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_DB
          - name: POSTGRES_USER
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_USER
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_PASSWORD
        resources: {}
        readinessProbe:
          initialDelaySeconds: 30
          tcpSocket:
            port: 5432
      restartPolicy: Always
      serviceAccountName: ""
      volumes: null
status: {}
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: database
  name: database
spec:
  ports:
  - name: "5432"
    port: 5432
    targetPort: 5432
  selector:
    app: database
status:
  loadBalancer: {}

dashboard.yaml含量

代码语言:javascript
复制
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: dashboard
  name: dashboard
spec:
  replicas: 1
  selector:
    matchLabels:
      app: dashboard
  strategy: {}
  template:
    metadata:
      labels:
        app: dashboard
    spec:
      containers:
      - image: grafana:7.3.3
        imagePullPolicy: ""
        name: dashboard
        ports:
          - containerPort: 3000
        resources: {}
        env:
          - name: POSTGRES_DB
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_DB
          - name: POSTGRES_USER
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_USER
          - name: POSTGRES_PASSWORD
            valueFrom:
              secretKeyRef:
                name: postgres-secret
                key: POSTGRES_PASSWORD
        volumeMounts:
          - name: grafana-datasource
            mountPath: /etc/grafana/provisioning/datasources
        readinessProbe:
          initialDelaySeconds: 30
          httpGet:
            path: /
            port: 3000
      restartPolicy: Always
      serviceAccountName: ""
      volumes:
        - name: grafana-datasource
          configMap:
            defaultMode: 420
            name: grafana-datasource
        - name: grafana-dashboard-provision
status: {}
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: dashboard
  name: dashboard
spec:
  ports:
  - name: "3000"
    port: 3000
    targetPort: 3000
  selector:
    app: dashboard
status:
  loadBalancer: {}

cronjob.yaml含量

代码语言:javascript
复制
---
apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: python
spec:
  concurrencyPolicy: Replace
  # TODO: Go back to hourly when finished testing/troubleshooting
  # schedule: "@hourly"
  schedule: "*/15 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - image: python-tool:1.0.5
            imagePullPolicy: ""
            name: python
            args: []
            command:
              - /bin/sh
              - -c
              - >-
                echo "$(POSTGRES_USER)" > creds/db.creds;
                echo "$(POSTGRES_PASSWORD)" >> creds/db.creds;
                echo "$(SERVICE1_TOKEN)" > creds/service1.creds;
                echo "$(SERVICE2_TOKEN)" > creds/service2.creds;
                echo "$(SERVICE3_TOKEN)" > creds/service3.creds;
                python3 -u main.py;
                echo "Job finished with exit code $?";
            env:
              - name: POSTGRES_DB
                valueFrom:
                  secretKeyRef:
                    name: postgres-secret
                    key: POSTGRES_DB
              - name: POSTGRES_USER
                valueFrom:
                  secretKeyRef:
                    name: postgres-secret
                    key: POSTGRES_USER
              - name: POSTGRES_PASSWORD
                valueFrom:
                  secretKeyRef:
                    name: postgres-secret
                    key: POSTGRES_PASSWORD
              - name: SERVICE1_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: api-tokens-secret
                    key: SERVICE1_TOKEN
              - name: SERVICE2_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: api-tokens-secret
                    key: SERVICE2_TOKEN
              - name: SERVICE3_TOKEN
                valueFrom:
                  secretKeyRef:
                    name: api-tokens-secret
                    key: SERVICE3_TOKEN
          restartPolicy: OnFailure
          serviceAccountName: ""
status: {}

现在,正如我所提到的,Istio也是这张图片的一部分,所以我为仪表板提供了一个虚拟服务,因为它应该可以在集群之外访问,但仅此而已。

所有这些都已经消失了,下面是我为解决这个问题所做的努力,我自己:

  1. 确认CronJob使用正确的连接设置(即主机、数据库名、用户名和密码)连接到数据库。

为此,我在CronJob部署中添加了echo语句,显示用户名和密码(我知道,我知道),它们是预期值。我还知道这些是数据库的正确连接设置,因为我逐字使用这些设置将仪表板连接到数据库,从而获得了成功的连接。

Grafana仪表板的数据源设置:

来自Python应用程序的错误消息(如容器的ArgoCD日志所示):

  1. 认为Istio可能是造成这个问题的原因,我尝试禁用Istio侧汽车注入对CronJob资源(通过将这个注释添加到metadata.annotations部分:sidecar.istio.io/inject: false),但是注释从未实际出现在Argo日志中,并且在CronJob运行时没有观察到任何更改。

  1. I尝试在运行kubectl exec脚本的CronJob容器中进行更多的调试,但实际上无法调试,因为一旦发生连接错误,容器就会退出。

尽管如此,我的头撞在墙上已经够久了。有人能找出我可能错过的东西并指出正确的方向吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-01-13 18:45:58

我认为问题在于,在istio准备好之前,您的吊舱试图连接到数据库。这样就无法建立起联系。

Istio运行一个init容器,该容器配置pods路由表,因此所有流量都通过侧目录路由。因此,如果侧卡没有运行,而另一个吊舱试图连接到db,则无法建立连接。

有两种解决办法。

首先,您的工作可以等待30秒(如30秒),然后使用一些睡眠命令调用main.py

或者,您可以启用holdApplicationUntilProxyStarts。通过这个主容器将不会启动,直到侧车运行。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65707362

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档