¿Qué o cómo mejorar? Python, React, Postgresql

Yekale7

Buenas!

Vengo a pedir consejo sobre el proyecto montado de seguimiento de stock de productos: https://www.mediavida.com/foro/hard-soft/bot-buscador-avisos-stock-nvidia-rtx-amd-rx-ps5-xbox-664425

Actualmente, tengo montado lo siguiente:

  • Scripts para detección de stock: Python
  • Base de datos: Postgresql (Hay dos bases de datos con replicación)
  • Flask + Jinja + HTML para la web (Flask se interconecta con la DB)
  • Docker (en concreto docker-compose) para la monitorización de todo: Telegraf + InfluxDB (recibe la info de los scripts) + Grafana
  • Squid Proxys en varios VPS

Cambios:

Migración de la web a: Flask + Nextjs

Dudas

No sé si la web es recomendable meterla en un container de docker (soy novato de docker, se lanzar container, ver logs, red, etc... pero no me peleado en exceso con ello)
Lo mismo con la base de datos porque todo está a pelo en el Linux.
Me haría falta una GUI o herramienta para la gestión de los procesos de linux (ejecución de scripts de python), actualmente ejecutados por medio de systemd. ¿Existe? Quizás no he sabido buscar, pero no he encontrado nada útil...

Cualquier idea u opinión es bienvenida.

wdaoajw

Por comodidad, todo metido en containers. Tanto el front como las bbdd

1 1 respuesta
JuAn4k4

Todo containers, cambias docker compose por kubernetes, metes Prometheus y quitas la ponzoña de grafana/influxdb y ya tienes un buen roadmap para aprender

5 3 respuestas
Gigi_men

#3 Ponzoña Grafana/Influx? Un poco violenta esa forma de referirse al actual estandar de la industria, no? Por no decir que has comparado el uso de Prometheus con el de Grafana cuando no tienen nada que ver una cosa con la otra. Yo metería Prometheus para scraping, sobretodo si terminas montando alguna de las versiones de K8s y así podrás utilizar las anotaciones que corresponda. Grafana para la visualización de los datos y InfluxDB para el histórico de métricas. Si quieres logs, mete también Loki. Este stack se integra muy bien.

Desconozco si el proyecto es productivo 100% o si es mas para aprender, pero a poco que vaya a ser algo funcional de verdad, te dejases de bases de datos en containers. Para las aplicaciones, sin duda.

De nuevo, si es para un stack de pruebas, compose está medio bien, pero te recomendaría pasarte a K3s o algo similar para ir pasándote al estandar de la industria. Bajo ningún concepto montes un Kubernetes Vanilla a no ser que sea para aprender.

Y para la gestión de procesos,te diría que un Airflow montado también en containers. Es sencillo y muy versátil.

1 2 respuestas
Yekale7

#3 #4 Investigaré sobre kubernetes. Sobre K8s K3s no tengo ni idea, algún vídeo recomendable o web poor donde empezar?

Entiendo que la idea de #3, pero no entiendo como implementar Prometheus con la idea de #4. ¿A qué te refieres con scraping ? Quitar postgresql??

Es un entorno productivo porque todo está funcionando 24x7, aunque parar impacta a 4 usuarios del foro...

También, voy a buscar sobre Loki y Airflow

Edit: estoy leyendo sobre kubernetes y me gusta, lo veo una mejora increíble.

3 respuestas
JuAn4k4

#4 A ver que Grafana y tal está bien pero se queda muy corto y a mi como usuario me parece bastante tercermundista, Prometheus no lo he usado ya que siempre he estado en Datadog y Newrelic, pero vamos he usado tanto InfluxDB como Grafana y me parecen ambos bastante mediocres como apps.

2 respuestas
wdaoajw

#6 Prometheus es el standard fuera de lo Enterprise y grafana tres cuartos de lo mismo. No hay alternativas mejores gratis.

Por otro lado, #5 si te quieres montar un cluster de kubernetes para aprender adelante, pero para levantar 4 contenedores me quedaba con compose

Gigi_men

#6 estás comparando una herramienta de pago y cara ($$$) como Datadog, con como he dicho, el estandar de monitorización de la industria que es Grafana. En que te basas para decir que es tercermundista? Tienes plugins para aburrir, tienes themes para aburrir, tienes comunidad para aburrir y todo está en desarrollo constante tanto por la comunidad, como por la propia empresa Grafana que se ha convertido en una de las maás potentes del sector. Datadog está muy bien para empezar o si necesitas algo cómodo y te da un poco igual la parte económica, ya que únicamente instalando el Agente ya tienes métricas y logs disponibles. Pero es muy MUY peligroso si no controlas el número de métricas ingestadas. Con New Relic pasa exactamente lo mismo, cómodo por necesitar un agente y a correr.

Respecto a IngluxDB es una TSDB, así que tampoco hay que intentar tratarlo como lo que no es. Para cosas discretas está muy bien y si necesitas algo más completo y eficiente te puedes pasar al stack de M3 o Victoria Metrics. Pero vamos, que para lo que necesita el OP con el InflixDB le sobra de calle. No creo que vaya a necesitar insertar millones de datos por segundo.

#5 Basicamente, Prometheus es un scraper. Tus aplicaciones lo que deberían hacer es publicar las métricas que quieran en un endpoint, ya sean a través del framework que corresponda o mediante algún agente de statsD por ejemplo. Y el Prometheus lo que hará será atacar a todos esos hosts al endpoint que le hayas indicado recogiendo esas métricas y enviandolas al InflixDB (o cualquier otro destino de datos que quieras. Puedes enviarlo directamente a Grafana, pero el historico de datos que podrás almacenar será menor). A partir de ahí, el Grafana tendrá configurado el InfluxDB como origen de datos y cuando le solicites una muestra, le hará la consulta correspondiente.

Para la parte de Kubernetes, importante lo que te he comentado. Si puedes evitar meterte en la parte de administración del Kubernetes en si, hazlo (a no ser que lo que quieras sea aprender eso en concreto). Pillate algún servicio gestionado o alguna versión lite como Minikube, K3s, K0s...

Dejo por aquí cosas interesantes:
Explicación del stack que comentaba - https://medium.com/swlh/monitoring-with-grafana-prometheus-and-influxdb-an-airport-webcams-example-508c04b226b6

Charla de un proyecto en el que participé precisamente para quitar Datadog por optimización de costes - https://www.youtube.com/watch?v=1eDZYiRDF3I&list=PLQ1vMvN4ZpX9tSYkX0xzP8eV_D3DtB79l&index=10

1 respuesta
wdaoajw

#8 Prometheus además de hacer scrape ya es en sí una TSDB donde almacenar las métricas, y si lo necesitas puedes ampliar sus capacidades con Thanos

1 1 respuesta
Gigi_men

#9 Correcto. No conocía esta parte ya que no la trabajé y únicamente utilizabamos su caché. Desconozco cuanto de eficiente es como TSDB.

https://prometheus.io/docs/prometheus/latest/storage/

1 respuesta
wdaoajw

#10 más que decente, de hecho es el standard de monitorización ahora mismo, sin soluciones enterprise. Y si necesitas almacenar cantidades ingentes de métricas, añades Thanos, de forma que el Prometheus almacena 7d de métricas y otros 2 meses en un S3 y a la hora de hacer el fetch de métricas para visualizarlas en grafana tienes ambas disponibles sin necesidad de utilizar un almacenamiento caro

1
D

Coincido con que Prometheus me parece mejor que influxdb/grafana aunque solo lo he probado, en la empresa tiraron por Datadog

#5 k8s es el orquestrador de contenedores que usa la mayoría. Al principio puede saturar de lo potente que es pero una vez que tienes los conceptos claros, no es tan difícil

Resumen de lo que es k8s:

Aquí te haces un intensivo de 5h

3 1 respuesta
Kaledros

Ya que hablamos de métricas, ¿alguien ha probado OpenTelemetry? Hace un tiempo me tumbaron en un proceso porque era requisito, lo estoy mirando a la vez que Prometheus y aunque entiendo las diferencias me gustaría leer de alguien que lo use.

1 respuesta
JuAn4k4

#13 Pues ya les vale tirarte por eso, madre mía.

A ver que está bien y ha sido el estándar, ahora lo es Prometheus. Por poder se puede usar para mil historias, a mi personalmente no me gusta mucho, pero está bien de funcionalidad

1 respuesta
Yekale7

Los Kubernetes lo veo bastante bien para tener montado la monitorización de todos los servidores e incluso, hacer uso de la conectividad entre pods. Además, de montar un pequeño clúster con una DB. La verdad que me ha molado bastante y le veo mucha utilidad y potencial.

He visto algún vídeo aunque aún me quedan los de #12 y me están matando el exponer los servicios por ingress. No consigo llevar al maldito servicio que expone el pod que al final es un dashboard....

Kaledros

#14 Fue una cosa rara. Acabé haciendo dos entrevistas técnicas porque a la media hora de la primera me di cuenta de que me estaban entrevistando para un puesto full stack y no para el de backend que yo eché CV (me preguntaban sobre manejo del DOM y esas cosas). Se lo dije, la cortamos y a la semana siguiente tuve la de backend. Me preguntaron mucho sobre telemetría y me dijeron que era imprescindible manejarse con OpenTelemetry como si la hubieras inventado. Y como no había oído hablar de ella pensaba que tenía un (otro) hueco gordo en mi formación y llevo una semana con el tema. "Es que es un estándar", "todos los proyectos de microservicios deberían implementarlo", etc.

Yekale7

https://docs.oracle.com/en-us/iaas/Content/ContEng/Tasks/contengsettingupingresscontroller.htm

Mi problema es el load balancer. Los de oracle hacen un tutorial sin probrarlo o que me he perdido? "Creating the Service Account, and the Ingress Controller"

Y crean dos Load Balancers, pero para ellos es solo 1 ¿? Creo que el servicio que han definido debería actual el creado por el anterior, pero no han definido correctamente el nombre del servicio.

Luego en su panel:

...

1 respuesta
wdaoajw

#17 Por eso mismo te dije que para montar 4 containers Kubernetes es un overkill de cuidado.

Primero, para montar un servicio como LoadBalancer, debes tener el cluster configurado en algun cloud publico de cara a poder usar SUS servicios de LoadBalancer, de lo contrario, unicamente puedes exponer hacia afuera el servicio con uno de tipo NodePort.

Por otro lado, un objeto Ingress se registra en un IngressController, y debes tener definidos ambos. El servicio NodePort expondra el deployment del IngressController y este hara de reverseProxy dentro del cluster.

2 2 respuestas
Yekale7

#18 El tema de kubernetes que me viene perfecto para tener un cluster con storage compartido, y otro cluster sin compartir storage etc... Lo veo bien porque ya se está dimensionando mucho el proyecto.

y sí claro, ahora mismo está el clúster está en oracle. El tema que con el yaml de github se crea mal el load balancer, porque no es capaz de hablar con todos los nodos.Con el yaml que pasa oracle, todo ok, pero claro tengo 2 load balancer ya tengo el lío con los pods etc...., no están definidos los end points en el segundo servicio...

El tema que quiero exponer Grafana. Este tiene un clúster IP, que es el que se debería conectar con el ingress defiendo el servicio y se hace el reverse proxy con el controlador como comentas teóricamente...

Voy a empezar de cero, pero no hay manera... Esto ya sería lo único que me faltaría para exponer los malditos servicios...

wdaoajw

Si quieres exponer Grafana, entonces el flujo del trafico es el siguiente:

Servicio LoadBalancer -> IngressController -> Ingress -> Grafana SVC -> Grafana Pod

Para el ingressController, puedes utilizar este por ejemplo: https://kubernetes.github.io/ingress-nginx/

En cuanto al storage, en un mismo cluster puedes tener diferentes tipos de Storage, y defines como usarlos o no en los propios yaml de config

1 1 respuesta
Yekale7

#20 Vale, perfecto. La situación actual es la siguiente:

El ejemplo que has pasado, ejecuto el yaml: https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v1.1.1/deploy/static/provider/cloud/deploy.yaml

Deploy:

# Source: ingress-nginx/templates/controller-service.yaml
apiVersion: v1
kind: Service
metadata:
  annotations:
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
  name: ingress-nginx-controller
  namespace: ingress-nginx
spec:
  type: LoadBalancer
  externalTrafficPolicy: Local
  ipFamilyPolicy: SingleStack
  ipFamilies:
    - IPv4
  ports:
    - name: http
      port: 80
      protocol: TCP
      targetPort: http
      appProtocol: http
    - name: https
      port: 443
      protocol: TCP
      targetPort: https
      appProtocol: https
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller

Oracle generic:

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx
  namespace: ingress-nginx
  labels:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/part-of: ingress-nginx
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

Voy a reemplazar el código de Oracle a deploy porque hay algo que no termine de cuadrarle a la nube de Oracle. Por si este hilo sirvierá, también cambio el nombre del yaml oracle de 'ingress-nginx' a 'ingress-nginx-controller'

Edit: Todo OK ahora:

Edit 2:
Tengo el siguiente error:

Error from server (InternalError): error when creating ".\grafana-ingress.yaml": Internal error occurred: failed calling webhook "validate.nginx.ingress.kubernetes.io": Post "https://ingress-nginx-controller-admission.ingress-nginx.svc:443/networking/v1/ingresses?timeout=10s": EOF

grafana-ingress.yaml

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kube-prometheus-stack-1643570798-grafana
                port:
                  number: 80

En los nodos hay kubernetes: v1.21.5
Estoy buscando info porque tiene pinta de ser algún problema de la api v1 o v1beta definida en el nginx...

edit 3:
kubectl delete -A ValidatingWebhookConfiguration ingress-nginx-admission

Un poco drástica la solución que veo, pero como estoy probando pues me sirve...

Yekale7

Doble post:

Tuve que volver a editar el archivo deploy.yaml

kind: Service
apiVersion: v1
metadata:
  name: ingress-nginx-controller
  namespace: ingress-nginx
  labels:
    helm.sh/chart: ingress-nginx-4.0.15
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/version: 1.1.1
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/component: controller
spec:
  type: LoadBalancer
  selector:
    app.kubernetes.io/name: ingress-nginx
    app.kubernetes.io/instance: ingress-nginx
    app.kubernetes.io/component: controller
  ports:
    - name: http
      port: 80
      targetPort: http
    - name: https
      port: 443
      targetPort: https

Y ahora si llego perfectamente al NGINX y he creado el ingress, pero tengo una respuesta maravillosa: 502 Bad Gateway
Según el pod de NGINX:

2022/01/31 12:27:20 [error] 67#67: *4374 connect() failed (113: Host is unreachable) while connecting to upstream, client: 10.244.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://10.244.0.2:3000/", host: "150.X.Y.X"

2022/01/31 12:27:23 [error] 67#67: *4374 connect() failed (113: Host is unreachable) while connecting to upstream, client: 10.244.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://10.244.0.2:3000/", host: "150.X.Y.X"

10.244.0.1 - - [31/Jan/2022:12:27:26 +0000] "GET / HTTP/1.1" 502 150 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:96.0) Gecko/20100101 Firefox/96.0" 367 9.220 [monitoring-kube-prometheus-stack-1643570798-grafana-80] [] 10.244.0.2:3000, 10.244.0.2:3000, 10.244.0.2:3000 0, 0, 0 3.076, 3.072, 3.072 502, 502, 502 2570ebc4f6340a984bffa5e07f089653

2022/01/31 12:27:26 [error] 67#67: *4374 connect() failed (113: Host is unreachable) while connecting to upstream, client: 10.244.0.1, server: _, request: "GET / HTTP/1.1", upstream: "http://10.244.0.2:3000/", host: "150.X.Y.X"

Entiendo que el nombre: monitoring-kube-prometheus-stack-1643570798-grafana-80 lo forma nginx siguiendo algunas reglas y es normal.

Grafana Service IP: 10.96.65.70
Pod IP: 10.244.0.2
Node: 10.0.10.205

No entiendo porque no es capaz de llegar al host y utiliza la Pod IP ...

wdaoajw

Te falta definir el host en el ingress

1 respuesta
Yekale7

#23 ¿Es obligatorio? Voy a probar

1 respuesta
wdaoajw

#24 puedes definir un wildcard ( * )

1 respuesta
Yekale7

#25 Nada, imposible

1 respuesta
wdaoajw

#26 comparte el yaml del ingress y del svc de grafana

1 respuesta
Yekale7

#27

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: grafana-ingress
  namespace: monitoring
  annotations:
    kubernetes.io/ingress.class: "nginx"
spec:
  rules:
    - host: "*.svc.local"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: kube-prometheus-stack-1643570798-grafana
                port:
                  number: 80
apiVersion: v1
kind: Service
metadata:
  name: kube-prometheus-stack-1643570798-grafana
  namespace: monitoring
  uid: 5372d8d5-2688-4bfc-918b-b24908df84e4
  resourceVersion: '26142'
  creationTimestamp: '2022-01-30T19:27:03Z'
  labels:
    app.kubernetes.io/instance: kube-prometheus-stack-1643570798
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: grafana
    app.kubernetes.io/version: 8.3.4
    helm.sh/chart: grafana-6.21.0
  annotations:
    meta.helm.sh/release-name: kube-prometheus-stack-1643570798
    meta.helm.sh/release-namespace: monitoring
  managedFields:
    - manager: helm
      operation: Update
      apiVersion: v1
      time: '2022-01-30T19:27:02Z'
      fieldsType: FieldsV1
      fieldsV1:
        f:metadata:
          f:annotations:
            .: {}
            f:meta.helm.sh/release-name: {}
            f:meta.helm.sh/release-namespace: {}
          f:labels:
            .: {}
            f:app.kubernetes.io/instance: {}
            f:app.kubernetes.io/managed-by: {}
            f:app.kubernetes.io/name: {}
            f:app.kubernetes.io/version: {}
            f:helm.sh/chart: {}
        f:spec:
          f:ports:
            .: {}
            k:{"port":80,"protocol":"TCP"}:
              .: {}
              f:name: {}
              f:port: {}
              f:protocol: {}
              f:targetPort: {}
          f:selector:
            .: {}
            f:app.kubernetes.io/instance: {}
            f:app.kubernetes.io/name: {}
          f:sessionAffinity: {}
          f:type: {}
  selfLink: >-
    /api/v1/namespaces/monitoring/services/kube-prometheus-stack-1643570798-grafana
status:
  loadBalancer: {}
spec:
  ports:
    - name: http-web
      protocol: TCP
      port: 80
      targetPort: 3000
  selector:
    app.kubernetes.io/instance: kube-prometheus-stack-1643570798
    app.kubernetes.io/name: grafana
  clusterIP: 10.96.65.70
  clusterIPs:
    - 10.96.65.70
  type: ClusterIP
  sessionAffinity: None
  ipFamilies:
    - IPv4
  ipFamilyPolicy: SingleStack
1 respuesta
wdaoajw

#28 cambia el hostname por "*" únicamente, tal y como lo tienes ahora está esperando requests con la cabecera Host: algo.svc.local

1 respuesta
Yekale7

#29 No deja poner únicamente "*"

Cluster IP - service grafana

bash-5.1$ curl -k -v http://10.96.65.70:80
*   Trying 10.96.65.70:80...
* connect to 10.96.65.70 port 80 failed: Host is unreachable
* Failed to connect to 10.96.65.70 port 80 after 3075 ms: Host is unreachable
* Closing connection 0
curl: (7) Failed to connect to 10.96.65.70 port 80 after 3075 ms: Host is unreachable

Pod IP

bash-5.1$ curl -k -v http://10.244.0.2:3000
*   Trying 10.244.0.2:3000...
* connect to 10.244.0.2 port 3000 failed: Host is unreachable
* Failed to connect to 10.244.0.2 port 3000 after 3078 ms: Host is unreachable
* Closing connection 0
curl: (7) Failed to connect to 10.244.0.2 port 3000 after 3078 ms: Host is unreachable

Estos comandos desde dentro del POD NGINX.
La regla de ingress sin el "host" añadido:

PS C:\Users\X> kubectl get ingress -n monitoring
NAME              CLASS    HOSTS   ADDRESS           PORTS   AGE
grafana-ingress   <none>   *       X.Y.Z.H                  80      109m


PS C:\Users\X> kubectl apply -f .\grafana-ingress.yaml
ingress.networking.k8s.io/grafana-ingress unchanged
PS C:\Users\X>
PS C:\Users\X>
PS C:\Users\X> kubectl get ingress -n monitoring
NAME              CLASS    HOSTS   ADDRESS           PORTS   AGE
grafana-ingress   <none>   *       X.Y.Z.H                 80      109m
PS C:\Users\X> kubectl get ingress -n monitoring -o wide
NAME              CLASS    HOSTS   ADDRESS           PORTS   AGE
grafana-ingress   <none>   *       X.Y.Z.H                 80      110m
PS C:\Users\X> kubectl describe ingress grafana-ingress -n monitoring
Name:             grafana-ingress
Labels:           <none>
Namespace:        monitoring
Address:          X.Y.Z.H   
Default backend: default-http-backend:80 (<error: endpoints "default-http-backend" not found>) Rules: Host Path Backends ---- ---- -------- * / kube-prometheus-stack-1643570798-grafana:80 (10.244.0.2:3000) Annotations: kubernetes.io/ingress.class: nginx Events: Type Reason Age From Message ---- ------ ---- ---- ------- Normal Sync 38m (x7 over 111m) nginx-ingress-controller Scheduled for sync

El nginx se llega sin problema. Es la comunicación entre el pod de nginx y grafana...
Diría que es la comunicación entre pods de distintos namespaces