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&longitude=5">http://localhost/api/?latitude=52&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
Managed to fix the issue by creating a redis service.
First of all, curl doesn’t follow redirects by default. Try this:
Second, you trying to connect to redis instance redis:6379 and getting error:
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"