#python #mongodb #flask #kubernetes #minikube
Вопрос:
У меня есть приложение flask с базой данных mongodb, которое я пытаюсь развернуть на мини-кубе.
Я упаковал оба приложения и определил, что они работают без оркестровки.
Я обязательно запускаю mongodb перед колбой.
Однако при запуске в kubernetes я получаю следующую ошибку. журналы kubectl flaskweb-развертывание-7f6775bc8f-7q72j
Traceback (most recent call last): File "run.py", line 1, in lt;modulegt; from app import web_app, socketio File "/code/app/__init__.py", line 18, in lt;modulegt; from .main import main as main_blueprint File "/code/app/main/__init__.py", line 5, in lt;modulegt; from . import routes, events File "/code/app/main/routes.py", line 8, in lt;modulegt; from .models import eInstance, eMessage File "/code/app/main/models.py", line 24, in lt;modulegt; if eInstance.objects().first() is None: File "/usr/local/lib/python3.8/dist-packages/mongoengine/queryset/manager.py", line 38, in __get__ queryset = queryset_class(owner, owner._get_collection()) File "/usr/local/lib/python3.8/dist-packages/mongoengine/document.py", line 223, in _get_collection if cls._meta.get("auto_create_index", True) and db.client.is_primary: File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 1088, in is_primary return self._server_property('is_writable') File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 889, in _server_property server = self._topology.select_server( File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 244, in select_server return random.choice(self.select_servers(selector, File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 202, in select_servers server_descriptions = self._select_servers_loop( File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 218, in _select_servers_loop raise ServerSelectionTimeoutError( pymongo.errors.ServerSelectionTimeoutError: 10.97.8.16:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: lt;TopologyDescription id: 6187e39295442839a2d95a49, topology_type: Single, servers: [lt;ServerDescription ('10.97.8.16', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('10.97.8.16:27017: [Errno 111] Connection refused')gt;]gt;
Я просмотрел все сообщения, которые я могу найти, относящиеся к этой проблеме, но не могу сопоставить ни одну из этих проблем с моей реализацией.
Dockerfiles mongodb
FROM ubuntu:18.04 RUN apt update; apt install -y gnupg2 RUN apt install -y software-properties-common # Installation RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 9DA31620334BD75D9DCB49F368818C72E52529D4 RUN add-apt-repository 'deb [arch=amd64] https://repo.mongodb.org/apt/ubuntu bionic/mongodb-org/4.0 multiverse' RUN apt-get update amp;amp; apt install -y mongodb-org RUN mkdir /data RUN mkdir /data/db # Start db #RUN mongod --bind_ip=0.0.0.0 amp; EXPOSE 27017 # Set entrypoint ENTRYPOINT ["usr/bin/mongod", "--bind_ip=0.0.0.0"]
колба питона
FROM ubuntu:latest RUN apt update; apt install -y gnupg2 WORKDIR /code COPY . /code/ RUN apt install -y python3-pip RUN pip3 install -r requirements.txt ENV PYTHONPATH /code EXPOSE 8080 ENTRYPOINT [ "python3" ] CMD [ "run.py" ]
yaml files for deployment and service
apiVersion: apps/v1 kind: Deployment metadata: name: mongodb-deployment labels: app: mongodb spec: replicas: 1 selector: matchLabels: app: mongodb template: metadata: labels: app: mongodb spec: containers: - name: mongodb image: mongodb:v1 imagePullPolicy: Never ports: - containerPort: 27017 volumes: - name: mongo-persistent-storage mountPath: /data/db volumes: - name: mongo-persistent-storage
serviceDB.yaml
apiVersion: v1 kind: Service metadata: labels: name: mongodb-service name: mongodb-service spec: ports: - port: 27017 targetPort: 27017 selector: app: mongodb
webserver-deploy.yaml
apiVersion: apps/v1 kind: Deployment metadata: name: flaskweb-deployment spec: replicas: 3 selector: matchLabels: app: flaskweb template: metadata: labels: app: flaskweb spec: containers: - name: flaskweb image: flaskweb:v1 ports: - containerPort: 8080
serviceWEB.yaml
apiVersion: v1 kind: Service metadata: name: flaskweb-service spec: selector: app: flaskweb type: NodePort ports: - protocol: "TCP" port: 8080 targetPort: 8080 nodePort: 30100
kubectl get pods
NAME READY STATUS RESTARTS AGE flaskweb-deployment-7f6775bc8f-7q72j 0/1 Error 1 (40s ago) 74s flaskweb-deployment-7f6775bc8f-lpwlz 0/1 Error 1 (40s ago) 74s flaskweb-deployment-7f6775bc8f-pvnjz 0/1 Error 1 (40s ago) 74s mongodb-deployment-867998dcff-786tv 1/1 Running 0 6m29s NAME READY STATUS RESTARTS AGE flaskweb-deployment-7f6775bc8f-7q72j 0/1 CrashLoopBackOff 9 (94s ago) 27m flaskweb-deployment-7f6775bc8f-lpwlz 0/1 CrashLoopBackOff 9 (85s ago) 27m flaskweb-deployment-7f6775bc8f-pvnjz 0/1 CrashLoopBackOff 9 (111s ago) 27m mongodb-deployment-867998dcff-786tv 1/1 Running 0 33m
kubectl get services
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE flaskweb-service NodePort 10.105.225.55 lt;nonegt; 8080:30100/TCP 2s kubernetes ClusterIP 10.96.0.1 lt;nonegt; 443/TCP 23h mongodb-service ClusterIP 10.97.8.16 lt;nonegt; 27017/TCP 24m
mongodb settings in config.py
MONGODB_SETTINGS = {'db': 'mongodb', 'host': '10.97.8.16', 'port': 27017}
kubectl describe pod flaskweb-deployment-7f6775bc8f-7q72j
Name: flaskweb-deployment-7f6775bc8f-7q72j Namespace: default Priority: 0 Node: minikube/192.168.49.2 Start Time: Sun, 07 Nov 2021 14:31:31 0000 Labels: app=flaskweb pod-template-hash=7f6775bc8f Annotations: lt;nonegt; Status: Running IP: 172.17.0.6 IPs: IP: 172.17.0.6 Controlled By: ReplicaSet/flaskweb-deployment-7f6775bc8f Containers: flaskweb: Container ID: docker://93d1a5c0dfb69feadb8b1c252a3ad4635342e5117c2814f838e651cf0e9f13d9 Image: flaskweb:v1 Image ID: docker://sha256:eaf719a9964b4de784f2a56951e9d058e41f7201a7db25d26a5100539841e25b Port: 8080/TCP Host Port: 0/TCP State: Waiting Reason: CrashLoopBackOff Last State: Terminated Reason: Error Exit Code: 1 Started: Sun, 07 Nov 2021 14:57:17 0000 Finished: Sun, 07 Nov 2021 14:57:49 0000 Ready: False Restart Count: 9 Environment: lt;nonegt; Mounts: /var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-hchq9 (ro) Conditions: Type Status Initialized True Ready False ContainersReady False PodScheduled True Volumes: kube-api-access-hchq9: Type: Projected (a volume that contains injected data from multiple sources) TokenExpirationSeconds: 3607 ConfigMapName: kube-root-ca.crt ConfigMapOptional: lt;nilgt; DownwardAPI: true QoS Class: BestEffort Node-Selectors: lt;nonegt; Tolerations: node.kubernetes.io/not-ready:NoExecute op=Exists for 300s node.kubernetes.io/unreachable:NoExecute op=Exists for 300s Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Scheduled 29m default-scheduler Successfully assigned default/flaskweb-deployment-7f6775bc8f-7q72j to minikube Normal Created 25m (x5 over 29m) kubelet Created container flaskweb Normal Started 25m (x5 over 29m) kubelet Started container flaskweb Normal Pulled 9m3s (x9 over 29m) kubelet Container image "flaskweb:v1" already present on machine Warning BackOff 3m58s (x94 over 27m) kubelet Back-off restarting failed container
Edit: I matched the selector using app instead of name in the service yaml.
Still getting the following errors:
Traceback (most recent call last): File "run.py", line 1, in lt;modulegt; from app import web_app, socketio File "/code/app/__init__.py", line 18, in lt;modulegt; from .main import main as main_blueprint File "/code/app/main/__init__.py", line 5, in lt;modulegt; from . import routes, events File "/code/app/main/routes.py", line 8, in lt;modulegt; from .models import eInstance, eMessage File "/code/app/main/models.py", line 24, in lt;modulegt; if eInstance.objects().first() is None: File "/usr/local/lib/python3.8/dist-packages/mongoengine/queryset/manager.py", line 38, in __get__ queryset = queryset_class(owner, owner._get_collection()) File "/usr/local/lib/python3.8/dist-packages/mongoengine/document.py", line 223, in _get_collection if cls._meta.get("auto_create_index", True) and db.client.is_primary: File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 1088, in is_primary return self._server_property('is_writable') File "/usr/local/lib/python3.8/dist-packages/pymongo/mongo_client.py", line 889, in _server_property server = self._topology.select_server( File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 244, in select_server return random.choice(self.select_servers(selector, File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 202, in select_servers server_descriptions = self._select_servers_loop( File "/usr/local/lib/python3.8/dist-packages/pymongo/topology.py", line 218, in _select_servers_loop raise ServerSelectionTimeoutError( pymongo.errors.ServerSelectionTimeoutError: 10.97.8.16:27017: timed out, Timeout: 30s, Topology Description: lt;TopologyDescription id: 61880d44d1e4d98ec7db8557, topology_type: Single, servers: [lt;ServerDescription ('10.97.8.16', 27017) server_type: Unknown, rtt: None, error=NetworkTimeout('10.97.8.16:27017: timed out')gt;]gt;
ОКОНЧАТЕЛЬНОЕ РЕДАКТИРОВАНИЕ: В системе заканчивались ресурсы. помогла обрезка докерской системы.
Ответ №1:
Проблема здесь связана с настройкой вашей службы для mongodb.
~$ kubectl explain service.spec.selector KIND: Service VERSION: v1 FIELD: selector lt;map[string]stringgt; DESCRIPTION: Route service traffic to pods with label keys and values matching this selector. If empty or not present, the service is assumed to have an external process managing its endpoints, which Kubernetes will not modify. Only applies to types ClusterIP, NodePort, and LoadBalancer. Ignored if type is ExternalName. More info: https://kubernetes.io/docs/concepts/services-networking/service/
как вы можете видеть из вышесказанного, селектор использует ключи и значения меток модулей, чтобы узнать, какие модули следует обслуживать.
Если вы выполните команду
~$ kubectl get endpoints mongodb-service
вы должны видеть, что за вашим сервисом нет конечных точек. Причина в том, что ваш сервис неправильно выбирает модули. В настоящее время у вас есть этот селектор:
selector: name: mongodb
но ваши капсулы помечены по-другому:
labels: app: mongodb
Просто изменив значение name
на app
в манифесте для службы mongodb, следует решить эту проблему.
Еще одна вещь, на которую я хотел обратить ваше внимание, заключается в том, что вы используете статически установленный ip-адрес службы в конфигурации mongodb в flask.
MONGODB_SETTINGS = {'db': 'mongodb', 'host': '10.97.8.16', 'port': 27017}
это не очень хороший подход. Лучшим способом сделать это было бы использовать имя службы и позволить kubedns позаботиться о разрешении имени.
Комментарии:
1. Спасибо, я исправил ошибку селектора. Однако я все еще получаю ту же ошибку в журналах колб.
2. @Ozixic попробуйте войти в модуль flask и посмотрите, сможете ли вы получить доступ к сервису mongodb вручную. Видите ли вы конечные точки, стоящие за сервисом сейчас?
3. Я могу получить доступ к сервису mongodb вручную