gpt4 book ai didi

python-3.x - 在 Kubernetes cron 作业中运行的应用程序未连接到同一 Kubernetes 集群中的数据库

转载 作者:行者123 更新时间:2023-12-04 02:28:33 24 4
gpt4 key购买 nike

我有一个运行 PostgreSQL 数据库的 Kubernetes 集群、一个 Grafana 仪表板和一个在 Kubernetes 中每小时运行一次的 Python 单次运行应用程序(构建为 Docker 镜像)CronJob (见下面的 list )。此外,这一切都是使用 ArgoCD 和 Istio side-car 注入(inject)进行部署的。

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

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

database.yaml 的内容:

---
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 的内容:

---
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 的内容:

---
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 仪表盘的数据源设置:

    Connection settings used by Grafana data source

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

    Connection settings used by cron job

  2. 考虑到 Istio 可能会导致此问题,我尝试为 CronJob 禁用 Istio side-car 注入(inject)资源(通过将此注释添加到 metadata.annotations 部分:sidecar.istio.io/inject: false )但注释实际上从未出现在 Argo 日志中,并且在 CronJob 时没有观察到任何变化。正在运行。

  3. 我试过了 kubectl exec进入CronJob正在运行 Python 脚本以进行更多调试但实际上从未能够调试的容器,因为一旦发生连接错误容器就会退出。

就是说,在这方面我已经用头撞墙够久了。谁能发现我可能遗漏的东西并指出正确的方向,好吗?

最佳答案

我认为问题在于您的 pod 在 istio sidecar 准备就绪之前尝试连接到数据库。因此无法建立连接。

Istio 运行一个初始化容器来配置 pod 路由表,因此所有流量都通过 sidecar 进行路由。因此,如果 sidecar 没有运行,而另一个 pod 尝试连接到数据库,则无法建立连接。

有两种解决方案。

首先,您的作业可能会等待 30 秒,然后再使用一些 sleep 命令调用 main.py

或者,您可以启用 holdApplicationUntilProxyStarts。通过这个主容器,直到 sidecar 运行时才会启动。

关于python-3.x - 在 Kubernetes cron 作业中运行的应用程序未连接到同一 Kubernetes 集群中的数据库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65707362/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com