我有以下 python 3.12.4 代码,它使用 dockerhub 图像“mongo:4.4.7”在通过 docker 容器本地部署的 mongoDB 中插入 JSON
myClient = pymongo.MongoClient("mongodb://%s:%s@%s" % (MONGO_USERNAME, MONGO_PASSWORD, MONGO_URL), timeoutMS=20000)
myDB = myClient[MONGO_CLIENT_NAME]
myCollection = myDB[MONGO_CLOLLECTION_NAME]
the_json = '{"id": "json1","thestr": "exampleStr","theint": 11,"thedate": "2024-10-15T11:59:59.953Z"}'
myRecord = json.loads(the_json)
# replace str date with python' datetime object
myRecord["thedate"] = datetime.strptime(myRecord["thedate"], "%Y-%m-%dT%H:%M:%S.%fZ")
insertionResult = myCollection.insert_one(myRecord)
startDate = datetime(2024, 9, 24, 7, 51, 5, 953123)
mySearch = myCollection.find({"thedate": {"$gt": startDate}})
以上代码正确返回记录。
当对 kubernetes 集群中相同的 dockerhub 镜像和相同的 python 库使用完全相同的 python 代码时,问题就开始了。在这种情况下,不会返回任何记录。奇怪的是,在这样的集群部署中,当我执行“mySearch = myCollection.find()”时,它会获取数据库中的所有记录,因此不存在连接问题...
我尝试了几种日期类型来执行搜索,例如:
startDate = datetime(2023, 10, 1, 10, 00, 23, 953123, pytz.UTC)
startDate = datetime.now(tz=pytz.utc)- timedelta(days=7)
startDate = datetime(2024, 9, 24, 7, 51, 5, 953123)
startDate = datetime.now() - timedelta(days=7)
以防万一,所有集装箱的日期:
MY PC DATE: lun 21 oct 2024 18:27:08 CEST+0200
DATE MONGODB RUN IN DOCKERS LOCALLY: Mon Oct 21 16:26:43 UTC 2024 +0000
DATE MONGODB RUN IN KUBERNETES: Mon Oct 21 16:29:24 UTC 2024 +0000
DATE PYTHON CODE KUBERNETES: Mon Oct 21 16:30:44 UTC 2024 +0000
数据库内的示例记录是:
{ "_id" : ObjectId("671740d94d474abb29c7357c"), "id" : "json1", "thestr" : "exampleFile", "theint" : 11, "thedate" : ISODate("2024-06-15T11:59:59.111Z")
如您所见,日期是用 ISOdate 存储的,这对我来说似乎是正确的。当我使用 Mongo CLI 执行以下检查时,数据库中存储的日期的数据类型似乎也很好:
> date_obj = db["collection-name"].findOne({ thestr: 'exampleFile' }).thedate
ISODate("2024-10-15T11:59:59.111Z")
> date_obj.toString()
Tue Oct 15 2024 11:59:59 GMT+0000 (UTC)
遵循部署和配置映射 YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: pythonclient
namespace: pythonclient
spec:
replicas: 1
selector:
matchLabels:
app: pythonclient
template:
metadata:
labels:
app: pythonclient
spec:
containers:
- name: pythonclient
image: python:latest
command:
- /bin/sh
- -c
- |-
cd /usr/app/src
pip install -r requirements.txt
python3 pythonclient.py
ports:
- containerPort: 8001
volumeMounts:
- mountPath: /usr/app/src
name: config
volumes:
- name: config
configMap:
name: pythonclient-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pythonclient-config
namespace: pythonclient
data:
pythonclient.py: |
##here goes the python code that save/reads from the mongoDB##
requirements.txt: |
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
blinker==1.8.2
certifi==2024.8.30
cffi==1.17.1
click==8.1.7
dnspython==2.6.1
Flask==3.0.3
flask-swagger-ui==4.11.1
itsdangerous==2.2.0
Jinja2==3.1.4
joblib==1.4.2
MarkupSafe==2.1.5
minio==7.2.9
paho-mqtt==2.1.0
pycparser==2.22
pycryptodome==3.21.0
pymongo==4.10.1
python-crontab==3.2.0
python-dateutil==2.9.0.post0
pytz==2024.2
six==1.16.0
typing_extensions==4.12.2
urllib3==2.2.3
Werkzeug==3.0.3
关于可能发生的事情有任何线索吗?为什么它在本地工作但在 kubernetes 中不起作用? 预先感谢!
同时,在您提供更多信息的同时,让我发布一个片段,展示如何让 Python 客户端从 MongoDB 数据库插入和读取记录,该数据库都部署在 Kubernetes 集群中。
请注意,mongo URL 是
mongo-service.pythonclient.svc.cluster.local:27017"
。 mongo-service
是 Kubernetes 中用于连接到稳定端点的 mongo 数据库实例的 Service
资源的名称。
你可以
kubectl apply -f <THE FILE BELOW>
:
---
apiVersion: v1
kind: Service
metadata:
name: mongo-service
namespace: pythonclient
spec:
selector:
app: mongo
ports:
- protocol: TCP
port: 27017
targetPort: 27017
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: mongo
namespace: pythonclient
spec:
serviceName: mongo-service
replicas: 1
selector:
matchLabels:
app: mongo
template:
metadata:
labels:
app: mongo
spec:
containers:
- name: mongo
image: mongo:4.4.7
env:
- name: MONGO_INITDB_ROOT_USERNAME
value: root
- name: MONGO_INITDB_ROOT_PASSWORD
value: foo
ports:
- containerPort: 27017
---
apiVersion: batch/v1
kind: Job
metadata:
name: pythonclient
namespace: pythonclient
spec:
template:
spec:
restartPolicy: Never
containers:
- name: pythonclient
image: python:latest
command:
- /bin/sh
- -c
- |-
cd /usr/app/src
pip install -r requirements.txt
python3 pythonclient.py
ports:
- containerPort: 8001
volumeMounts:
- mountPath: /usr/app/src
name: config
volumes:
- name: config
configMap:
name: pythonclient-config
---
apiVersion: v1
kind: ConfigMap
metadata:
name: pythonclient-config
namespace: pythonclient
data:
pythonclient.py: |
#!/usr/bin/env python3
##here goes the python code that save/reads from the mongoDB##
import pymongo
import json
from datetime import datetime
# docker run --rm -p 27017:27017 -e MONGO_INITDB_ROOT_USERNAME=root -e MONGO_INITDB_ROOT_PASSWORD=foo mongo:4.4.7
MONGO_USERNAME = "root"
MONGO_PASSWORD = "foo"
MONGO_URL = "mongo-service.pythonclient.svc.cluster.local:27017"
MONGO_CLIENT_NAME = "my-client"
MONGO_COLLECTION_NAME = "my-collection"
myClient = pymongo.MongoClient("mongodb://%s:%s@%s" % (MONGO_USERNAME, MONGO_PASSWORD, MONGO_URL), timeoutMS=1000)
myClient = pymongo.MongoClient("mongodb://%s:%s@%s" % (MONGO_USERNAME, MONGO_PASSWORD, MONGO_URL), timeoutMS=1000)
myDB = myClient[MONGO_CLIENT_NAME]
myCollection = myDB[MONGO_COLLECTION_NAME]
the_json = '{"id": "json1","thestr": "exampleStr","theint": 11,"thedate": "2024-10-15T11:59:59.953Z"}'
myRecord = json.loads(the_json)
myRecord["thedate"] = datetime.strptime(myRecord["thedate"], "%Y-%m-%dT%H:%M:%S.%fZ")
insertionResult = myCollection.insert_one(myRecord)
startDate = datetime(2024, 9, 24, 7, 51, 5, 953123)
documents = myCollection.find({"thedate": {"$gt": startDate}})
print()
print('===> showing documents:')
for doc in documents:
print(doc)
print('done')
requirements.txt: |
argon2-cffi==23.1.0
argon2-cffi-bindings==21.2.0
blinker==1.8.2
certifi==2024.8.30
cffi==1.17.1
click==8.1.7
dnspython==2.6.1
Flask==3.0.3
flask-swagger-ui==4.11.1
itsdangerous==2.2.0
Jinja2==3.1.4
joblib==1.4.2
MarkupSafe==2.1.5
minio==7.2.9
paho-mqtt==2.1.0
pycparser==2.22
pycryptodome==3.21.0
pymongo==4.10.1
python-crontab==3.2.0
python-dateutil==2.9.0.post0
pytz==2024.2
six==1.16.0
typing_extensions==4.12.2
urllib3==2.2.3
Werkzeug==3.0.3
您应该会从
kubectl logs -n pythonclient <THE JOB POD NAME>
看到以下内容。
===> showing documents:
{'_id': ObjectId('6717bf86e93e55221ffc8ae9'), 'id': 'json1', 'thestr': 'exampleStr', 'theint': 11, 'thedate': datetime.datetime(2024, 10, 15, 11, 59, 59, 953000)}
done