skip to Main Content

I am trying to play around with k8s in order to create a website for introducing longitude and latitude and get a reply from a Weather API using nginx ingress.
This is my main.py:

 #!/usr/bin/env python
import os
import json
import redis
from flask import Flask, request
from weather import get_weather_data

app = Flask(__name__)
redis_conn = redis.from_url(os.getenv("REDIS_URL", "redis://localhost:6379"))

@app.route("/")
def index():
    return "Usage: http://<hostname>[:<prt>]/api/<url>"

@app.route("/api/")
def api():
    latitude = request.args.get("latitude")
    longitude = request.args.get("longitude")

    weather_data = get_weather_data(latitude, longitude)
    
    jsonlinks = redis_conn.get(latitude + "," + longitude)

    if jsonlinks is None:
        jsonlinks = json.dumps(weather_data)
        redis_conn.set(latitude + "," + longitude, jsonlinks)

    response = app.response_class(
        status=200,
        mimetype="application/json",
        response=jsonlinks
    )

    return response


if __name__ == "__main__":
    app.run(host="0.0.0.0")

And this is my weather.py:

import http.client
import os

def get_weather_data(latitude, longitude):
    conn = http.client.HTTPSConnection("weatherapi-com.p.rapidapi.com")

    headers = {
        'X-RapidAPI-Key': "random API key",
        'X-RapidAPI-Host': "weatherapi-com.p.rapidapi.com"
    }

    query = f"/current.json?q={latitude},{longitude}"
    conn.request("GET", query, headers=headers)

    res = conn.getresponse()
    data = res.read()

    return data.decode("utf-8")

After setting up the deployments and services when trying to use

curl "localhost/api?latitude=52&longitude=5"

This is the reply that I get

<!doctype html>
<html lang=en>
<title>Redirecting...</title>
<h1>Redirecting...</h1>
<p>You should be redirected automatically to the target URL: <a href="http://localhost/api/?latitude=52&amp;longitude=5">http://localhost/api/?latitude=52&amp;longitude=5</a>. If not, click the link.

What can I do so that I can get the proper response when calling to the IP instead of getting a redirect that ends in a 500 error.

*Edit : also added ingress .yaml file

# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  creationTimestamp: "2023-07-14T09:08:54Z"
  generation: 3
  name: weather
  namespace: weather
  resourceVersion: "53494"
  uid: e2536964-ae58-428b-afc3-65eaebdf56e8
spec:
  ingressClassName: nginx
  rules:
  - host: localhost
    http:
      paths:
      - backend:
          service:
            name: api
            port:
              number: 6000
        path: /api
        pathType: Prefix
status:
  loadBalancer:
    ingress:
    - hostname: localhost

And also the detailed error log from docker dekstop:

10.1.0.37 - - [14/Jul/2023 11:36:27] "GET /api?latitude=52&longitude=5 HTTP/1.1" 308 -
2023-07-14 13:36:27 [2023-07-14 11:36:27,872] ERROR in app: Exception on /api/ [GET]
2023-07-14 13:36:27 Traceback (most recent call last):
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 707, in connect
2023-07-14 13:36:27     sock = self.retry.call_with_retry(
2023-07-14 13:36:27            ^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/retry.py", line 46, in call_with_retry
2023-07-14 13:36:27     return do()
2023-07-14 13:36:27            ^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 708, in <lambda>
2023-07-14 13:36:27     lambda: self._connect(), lambda error: self.disconnect(error)
2023-07-14 13:36:27             ^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 974, in _connect
2023-07-14 13:36:27     for res in socket.getaddrinfo(
2023-07-14 13:36:27                ^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/socket.py", line 962, in getaddrinfo
2023-07-14 13:36:27     for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
2023-07-14 13:36:27                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27 socket.gaierror: [Errno -2] Name or service not known
2023-07-14 13:36:27 
2023-07-14 13:36:27 During handling of the above exception, another exception occurred:
2023-07-14 13:36:27 
2023-07-14 13:36:27 Traceback (most recent call last):
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 2190, in wsgi_app
2023-07-14 13:36:27     response = self.full_dispatch_request()
2023-07-14 13:36:27                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 1486, in full_dispatch_request
2023-07-14 13:36:27     rv = self.handle_user_exception(e)
2023-07-14 13:36:27          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 1484, in full_dispatch_request
2023-07-14 13:36:27     rv = self.dispatch_request()
2023-07-14 13:36:27          ^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/flask/app.py", line 1469, in dispatch_request
2023-07-14 13:36:27     return self.ensure_sync(self.view_functions[rule.endpoint])(**view_args)
2023-07-14 13:36:27            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/app/./main.py", line 22, in api
2023-07-14 13:36:27     jsonlinks = redis_conn.get(latitude + "," + longitude)
2023-07-14 13:36:27                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/commands/core.py", line 1816, in get
2023-07-14 13:36:27     return self.execute_command("GET", name)
2023-07-14 13:36:27            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/client.py", line 1266, in execute_command
2023-07-14 13:36:27     conn = self.connection or pool.get_connection(command_name, **options)
2023-07-14 13:36:27                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 1461, in get_connection
2023-07-14 13:36:27     connection.connect()
2023-07-14 13:36:27   File "/usr/local/lib/python3.11/site-packages/redis/connection.py", line 713, in connect
2023-07-14 13:36:27     raise ConnectionError(self._error_message(e))
2023-07-14 13:36:27 redis.exceptions.ConnectionError: Error -2 connecting to redis:6379. Name or service not known.
2023-07-14 13:36:27 10.1.0.37 - - [14/Jul/2023 11:36:27] "GET /api/?latitude=52&longitude=5 HTTP/1.1" 500 -

2

Answers


  1. Chosen as BEST ANSWER

    Managed to fix the issue by creating a redis service.

    apiVersion: v1
    kind: Service
    metadata:
      name: redis
    spec:
      selector:
        io.kompose.service: redis
      ports:
        - protocol: TCP
          port: 6379
          targetPort: 6379
    

  2. First of all, curl doesn’t follow redirects by default. Try this:

    curl -L "localhost/api?latitude=52&longitude=5"
    

    Second, you trying to connect to redis instance redis:6379 and getting error:

    redis.exceptions.ConnectionError: Error -2 connecting to redis:6379. Name or service not known.
    

    Are you sure that you have running redis instance? If yes, try to connect to the instance from machine/container where your main.py serves requests, with redis-cli or via REST API.

    Bear in mind that everything inside kubernetes cluster have it’s own dns name.
    Let’s say your main.py runs inside pod with name server-0 and redis runs on pod with name redis-0. Then to connect from server-0 to redis-0, you should use url "redis://redis-0:6379"

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search