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

r1zhe5dt  于 2023-01-08  发布在  Redis
关注(0)|答案(2)|浏览(152)
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.

部署.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

我的 Docker 组合确实起作用了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代码:

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)

所以我不知道问题出在哪里。
我试过与chatGPT对话,但效果不太好,另外,我试过在fastapi代码中使用redis的集群IP,而不是名称“redis”:
第一个月
仍然不工作:ConnectionRefusedError: [Errno 111] Connect call failed ('10.107.169.72', 6379)
在stackoverflow上看到一些类似的问题,但阅读完后仍然感到困惑。

zpqajqem

zpqajqem1#

当您的应用程序代码连接到redis:6379时,在Kubernetes中,它会连接到相同名称空间中名为redis的服务。在您所展示的设置中,它会将请求转发到标签为app: redis的Pod。但是,这些Pod中没有任何一个,这导致了您的错误。
比较kubectl describe service auth-servicekubectl describe service redis时,您也应该能够看到这一点。

Endpoints:                <none>

这通常表示服务的selector:与Pod的labels:不匹配。
在您的情况下,正确的答案是将部署拆分为两个,每个部署只有一个容器。

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

这样做还有很多其他的技术优势:如果你重新构建你的应用,并在你的主部署中修改了image:标签,那么重启不会同时重启Redis,所以你可以保留缓存;如果你设置主应用有多个replicas:,那么它们在其他部署中将共享同一个Redis。
(If如果你想设置你的Redis也将数据保存到磁盘,那么使用StatefulSet而不是Deployment。这是一个更复杂的设置,并且需要额外的服务。如果你对Redis偶尔丢失状态没有意见,那么Deployment就更好了。

6ojccjat

6ojccjat2#

根据this answer,您可以访问localhost上同一pod中的其他容器,因此在您的情况下是localhost:6379
我也会考虑为什么你要在同一个pod上运行你的应用程序和redis,使用kubernetes的全部意义就是能够扩展你的应用程序,而在同一个pod中有几个容器使得不扩展redis就不可能扩展你的应用程序,反之亦然。

相关问题