Развертывание Kubernetes для сервера Flower на Python завершается сбоем: «Порт в адресе сервера уже используется»Python

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Развертывание Kubernetes для сервера Flower на Python завершается сбоем: «Порт в адресе сервера уже используется»

Сообщение Anonymous »

Я пытаюсь развернуть сервер федеративного обучения с помощью Flower (flwr) в кластере Kubernetes с помощью специального образа Docker (fl-server:latest). Сервер должен работать на определенном порту и хосте. Моя цель — убедиться, что сервер найдет доступный порт, прежде чем начать, чтобы избежать конфликтов с другими службами.
Я реализовал класс Python для создания как развертывания, так и соответствующего сервиса с помощью Kubernetes. API. Ниже приведен код для создания развертывания и службы:
from kubernetes import client, config
from uuid import uuid4

class DeploymentFL:

def __init__(self):
pass

def create_deployment_object(self, model_name: str, port_k8s: str, port_flower: str, model_uuid: str, host: str = "192.168.49.2") -> client.V1Deployment:
"""
Create a Kubernetes deployment object for a Federated Learning server.

Args:
model_name (str): The name of the model to be used.
port_k8s (str): The port number for the Kubernetes service.
port_flower (str): The port number for the Flower server.
model_uuid (str): The uuid of the model to identify it.
host (str): The host address of the server.

Return:
client.V1Deployment: The deployment object for the Kubernetes API.
"""
try:
sanitized_model_name = f"{model_name.lower().replace('_', '-')}"
name_container = f"fl-server-{sanitized_model_name}-{model_uuid}"

# Define the container with environment variables and health checks
container = client.V1Container(
name=name_container,
image="fl-server:latest",
image_pull_policy="Never",
ports=[
client.V1ContainerPort(container_port=int(port_k8s)),
],
env=[
client.V1EnvVar(name="FL_HOST", value=host),
client.V1EnvVar(name="FL_PORT", value=str(port_k8s)),
],
volume_mounts=[client.V1VolumeMount(
name='model-storage',
mount_path='/mnt/data'
)],
liveness_probe=client.V1Probe(
_exec=client.V1ExecAction(command=["/bin/sh", "-c", f"nc -zv {host} {port_k8s}"]),
initial_delay_seconds=60,
period_seconds=10,
timeout_seconds=5,
failure_threshold=3,
),
readiness_probe=client.V1Probe(
_exec=client.V1ExecAction(command=["/bin/sh", "-c", f"nc -zv {host} {port_k8s}"]),
initial_delay_seconds=30,
period_seconds=10,
timeout_seconds=5,
failure_threshold=3,
)
)

# Define the Pod template
template = client.V1PodTemplateSpec(
metadata=client.V1ObjectMeta(labels={"app": name_container}),
spec=client.V1PodSpec(containers=[container], volumes=[client.V1Volume(
name='model-storage',
persistent_volume_claim=client.V1PersistentVolumeClaimVolumeSource(claim_name='model-pvc')
)])
)

# Define the Deployment specification
spec = client.V1DeploymentSpec(
replicas=1,
template=template,
selector={'matchLabels': {'app': name_container}}
)

name_deployment = f"{name_container}-deployment"
deployment = client.V1Deployment(
metadata=client.V1ObjectMeta(name=name_deployment),
spec=spec
)

return deployment
except Exception as e:
print(f"Error at create deployment object: {e}")

def create_service_object(self, model_name: str, port: int, model_uuid: str) -> client.V1Service:
"""
Create a Kubernetes service object for a Federated Learning server.

Args:
model_name (str): The name of the model to be used.
port (int): The port number for the server.
model_uuid (str): The uuid of the model to identify it.

Return:
client.V1Service: The service object for the Kubernetes API.
"""
try:
sanitized_model_name = model_name.lower().replace("_", "-")
service_name = f"fl-server-{sanitized_model_name}-{model_uuid}-service"
service = client.V1Service(
metadata=client.V1ObjectMeta(name=service_name),
spec=client.V1ServiceSpec(
selector={"app": f"fl-server-{sanitized_model_name}-{model_uuid}"},
ports=[client.V1ServicePort(port=port, target_port=port)],
type="NodePort"
)
)
return service, service_name
except Exception as e:
print(f"Error at create service object: {e}")

ниже приведен скрипт Python, который генерирует изображение fl-сервера:
import flwr as fl
import tensorflow as tf
import os
import socket

def is_port_in_use(host, port):
"""Check if a port is in use."""
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
return s.connect_ex((host, port)) == 0

def run_server(host: str, port: int):
"""
Start a Federated Learning server with the given model.

Args:
host (str): The host address for the server.
port (int): The port number for the server.

Return:
None
"""
try:
# Define the Federated Learning strategy
strategy = fl.server.strategy.FedAvg(
fraction_fit=0.1,
fraction_evaluate=0.1,
min_fit_clients=2,
min_evaluate_clients=2,
min_available_clients=2,
)

# Start the Flower server
fl.server.start_server(
server_address=f"{host}:{port}",
config=fl.server.ServerConfig(num_rounds=3),
strategy=strategy,
)
except Exception as e:
print(f"Error starting fl server: {e}")

if __name__ == "__main__":
# Read environment variables
host = os.getenv("FL_HOST", "192.168.49.2")
port = int(os.getenv("FL_PORT", "30878"))

# Find an available port
original_port = port
while is_port_in_use(host, port):
print(f"Port {port} is already in use. Trying another port...")
port += 1

print(f"Starting Flower server on {host}:{port} (initially tried {original_port})")
run_server(host, port)

Я ожидал, что сервер запустится на первом доступном порту. Если указанный порт используется, сценарий должен найти следующий доступный порт и использовать его для запуска сервера.
Несмотря на то, что сценарий предназначен для проверки доступности порта, я продолжаю получать следующая ошибка в журналах при развертывании в Kubernetes:
INFO : Starting Flower server, config: num_rounds=3, no round_timeout
Starting Flower server on 192.168.49.2:30099 (initially tried 30099)
Port in server address 192.168.49.2:30099 is already in use.

Чтобы попытаться решить проблему, я проверил правильность работы логики проверки портов, запустив скрипт локально.
Я убедился, что при развертывании Kubernetes используется последняя версия Docker. image (fl-server:latest).
Я проверил, что селектор служб соответствует меткам модуля.
Я проверил, что никакие другие службы не используют порт, используя ss и netstat внутри контейнера.
Вот мой Dockerfile, использованный для создания образа:
FROM python:3.10

# Install dependencies
COPY requirements.txt .
RUN pip install -r requirements.txt

# Copy the application code
COPY fl_server.py /app/fl_server.py
WORKDIR /app

# Run the server
CMD ["python", "fl_server.py"]


Подробнее здесь: https://stackoverflow.com/questions/790 ... server-add
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»