Я пытаюсь развернуть сервер федеративного обучения с помощью 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
Развертывание Kubernetes для сервера Flower на Python завершается сбоем: «Порт в адресе сервера уже используется» ⇐ Python
-
- Похожие темы
- Ответы
- Просмотры
- Последнее сообщение
-
-
Как динамически найти доступный порт в Spring Boot, когда настроенный порт уже используется?
Anonymous » » в форуме JAVA - 0 Ответы
- 9 Просмотры
-
Последнее сообщение Anonymous
-