简体   繁体   English

无法从 fastapi api 访问 redis 当它们在同一个集群、同一个 pod 中时,通过 docker 桌面使用单节点集群

[英]Cant access redis from fastapi api when they are in a same cluster, same pod, using a single node cluster via docker desktop

2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/uvicorn/protocols/http/h11_impl.py", line 407, in run_asgi
2023-01-07 21:05:14     result = await app(  # type: ignore[func-returns-value]
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/uvicorn/middleware/proxy_headers.py", line 78, in __call__
2023-01-07 21:05:14     return await self.app(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/fastapi/applications.py", line 270, in __call__
2023-01-07 21:05:14     await super().__call__(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/applications.py", line 124, in __call__
2023-01-07 21:05:14     await self.middleware_stack(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 184, in __call__
2023-01-07 21:05:14     raise exc
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/errors.py", line 162, in __call__
2023-01-07 21:05:14     await self.app(scope, receive, _send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 79, in __call__
2023-01-07 21:05:14     raise exc
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/middleware/exceptions.py", line 68, in __call__
2023-01-07 21:05:14     await self.app(scope, receive, sender)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 21, in __call__
2023-01-07 21:05:14     raise e
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/fastapi/middleware/asyncexitstack.py", line 18, in __call__
2023-01-07 21:05:14     await self.app(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 706, in __call__
2023-01-07 21:05:14     await route.handle(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 276, in handle
2023-01-07 21:05:14     await self.app(scope, receive, send)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/starlette/routing.py", line 66, in app
2023-01-07 21:05:14     response = await func(request)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 235, in app
2023-01-07 21:05:14     raw_response = await run_endpoint_function(
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/fastapi/routing.py", line 161, in run_endpoint_function
2023-01-07 21:05:14     return await dependant.call(**values)
2023-01-07 21:05:14   File "/app/./main.py", line 49, in login
2023-01-07 21:05:14     stored_password = await redis_client.hget(name=user.username, key="password")
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/aioredis/client.py", line 1082, in execute_command
2023-01-07 21:05:14     conn = self.connection or await pool.get_connection(command_name, **options)
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/aioredis/connection.py", line 1416, in get_connection
2023-01-07 21:05:14     await connection.connect()
2023-01-07 21:05:14   File "/usr/local/lib/python3.10/site-packages/aioredis/connection.py", line 698, in connect
2023-01-07 21:05:14     raise ConnectionError(self._error_message(e))
2023-01-07 21:05:14 aioredis.exceptions.ConnectionError: Error 111 connecting to redis:6379. 111.

deployment.yaml file deployment.yaml 文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: auth-service
spec:
  replicas: 1
  selector:
    matchLabels:
      app: auth-service
  template:
    metadata:
      labels:
        app: auth-service
    spec:
      containers:
      - name: auth-service
        image: localhost:5000/auth-service:latest
        ports:
        - containerPort: 8000
        resources:
          limits:
            cpu: "1"
            memory: "1Gi"
          requests:
            cpu: "0.5"
            memory: "500Mi"
        envFrom:
          - secretRef:
              name: auth-service-fastapi-secrets
      - name: redis
        image: redis:alpine
        ports:
        - containerPort: 6379
        resources:
          limits:
            cpu: "1"
            memory: "1Gi"
          requests:
            cpu: "0.5"
            memory: "500Mi"
---
apiVersion: v1
kind: Service
metadata:
  name: auth-service
spec:
  type: NodePort
  selector:
    app: auth-service
  ports:
  - port: 8000
    targetPort: 8000
    nodePort: 30080
---
apiVersion: v1
kind: Service
metadata:
  name: redis
spec:
  selector:
    app: redis
  ports:
  - port: 6379
    targetPort: 6379

my docker-compose did work: docker-compose.yml:我的 docker-compose 确实有效:docker-compose.yml:

version: "3"
services:
  auth-service:
    build: .
    ports:
      - "8000:8000"
    environment:
      REDIS_HOST: redis
      REDIS_PORT: 6379
    env_file: fastapi.env
    depends_on:
      - redis
  redis:
    image: "redis:alpine"
    volumes:
      - redis_data:/data

volumes:
  redis_data:

fastapi code: fastapi代码:

import os
import bcrypt
import jwt
import aioredis

from datetime import datetime
from fastapi import FastAPI, HTTPException, Cookie, Depends, Response
from pydantic import BaseModel, EmailStr


app = FastAPI()

# user model


class User(BaseModel):
    username: str
    password: str

# env variables
SECRET_KEY = os.environ["JWT_SECRET"]

# redis connection
redis_client = aioredis.from_url(
    "redis://redis:6379", encoding="utf-8", decode_responses=True)

So I am not sure what the problem is.所以我不确定是什么问题。

I have tried talking to chatGPT, didn't quite worked for me, also, I tried using the cluster ip of redis in the fastapi code instead of the name "redis":我试过与 chatGPT 交谈,但对我来说不太有效,而且,我尝试在 fastapi 代码中使用 redis 的集群 ip 而不是名称“redis”:

aioredis.from_url( "redis://redis:6379", encoding="utf-8", decode_responses=True)

still not working: ConnectionRefusedError: [Errno 111] Connect call failed ('10.107.169.72', 6379)仍然无法正常工作: ConnectionRefusedError: [Errno 111] Connect call failed ('10.107.169.72', 6379)

saw some similar question on stackoverflow, but still confused after reading it.在stackoverflow上看到了一些类似的问题,但看完后仍然一头雾水。

When your application code connects to redis:6379 , in Kube.netes, it connects to the Service named redis in the same namespace.当您的应用程序代码连接到redis:6379时,在 Kube.netes 中,它连接到同一命名空间中名为redis的服务。 In the setup you've shown, that forwards requests to Pods with a label app: redis .在您展示的设置中,将请求转发到具有 label app: redis There aren't any of those Pods, though, which results in your error.但是,这些 Pod 中没有任何一个会导致您的错误。

You should also be able to see this comparing kubectl describe service auth-service and kubectl describe service redis .您还应该能够看到这个比较kubectl describe service auth-servicekubectl describe service redis The redis service should end with a line like redis服务应以类似

Endpoints:                <none>

which is usually a sign that the Service's selector: doesn't match the Pods' labels: .这通常表明服务的selector:与 Pod 的labels:不匹配。

In your case, the right answer is to split the Deployment into two, with only one container each.在您的情况下,正确的答案是将 Deployment 一分为二,每个只有一个容器。 Especially:尤其:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis
  ...
spec:
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
        - name: redis
          image: redis:alpine

This has a couple of other technical advantages.这还有其他一些技术优势。 If you rebuild your application and change the image: tag in your main Deployment, the restart won't also restart Redis, so you'll keep your cache.如果您重建应用程序并更改image:主 Deployment 中的标记,则重新启动不会同时重新启动 Redis,因此您将保留缓存。 If you set the main application to have multiple replicas: , they'll all share the same single Redis in the other Deployment.如果您将主应用程序设置为具有多个replicas: ,它们将在另一个 Deployment 中共享同一个 Redis。

(If you want to set up your Redis to also persist its data to disk, use a StatefulSet rather than a Deployment. This is a more complicated setup, and comes with requirements like an additional Service. If you're fine with your Redis occasionally losing its state than a Deployment is fine.) (如果你想设置你的 Redis 也将其数据保存到磁盘,请使用StatefulSet而不是 Deployment。这是一个更复杂的设置,并且带有附加服务等要求。如果你偶尔使用 Redis失去它的 state 比部署更好。)

According to this answer , you can access other containers in the same pod on localhost , so in your case localhost:6379 .根据这个答案,您可以访问localhost上同一 pod 中的其他容器,因此在您的情况下为localhost:6379

I would also consider why you're running both your application and redis on the same pod.我还会考虑为什么您在同一个 pod 上同时运行您的应用程序和 redis。 The whole point of using kube.netes is to be able to scale your application, and having several containers in the same pod makes it impossible to scale your app without also scaling redis, and vice versa.使用 kube.netes 的全部意义在于能够扩展您的应用程序,并且在同一个 pod 中拥有多个容器使得在不扩展 redis 的情况下无法扩展您的应用程序,反之亦然。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 集群,来自Python的节点 - Cluster, Node from Python 从 pydoop 访问 hdfs 集群 - Access hdfs cluster from pydoop 从 Spark 容器无法访问 docker 集群中的 Minio - Minio in docker cluster is not reachable from spark container Azure Kubernetes 上的 Redis 分片集群 - Redis sharded cluster on Azure Kubernetes 当hadoop和python在不同的docker容器中时,如何从Hadoop集群中/从Hadoop集群中读取/写入文件? - How to read/write files with python3 from/in hadoop cluster when hadoop and python are in different docker containers? 使用 python api 从 GCP 管理 Kubernetes 集群 - Managing Kubernetes cluster from GCP with python api 有没有办法同时将多个图像发送到 API fastapi - is there a way to send multiple images to an API at the same time fastapi Python Redis:无法从本地计算机或服务器连接到 AWS Redis 集群 - Python Redis: Not able to connect to AWS Redis cluster from local machine or server 如何从Kubernetes集群中的Airflow工作程序在另一个命名空间中的另一个窗格中运行命令 - How to run a command in another pod in another namespace from an Airflow worker in a Kubernetes cluster Python代码在桌面上运行,但不在群集上运行:UnicodeEncodeError - Python Code runs on desktop but not on cluster: UnicodeEncodeError
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM