diff --git a/docs/docs/concepts/backends.md b/docs/docs/concepts/backends.md index 06d33149e..341585a66 100644 --- a/docs/docs/concepts/backends.md +++ b/docs/docs/concepts/backends.md @@ -1049,18 +1049,18 @@ In case of a self-managed cluster, also specify the IP address of any node in th - type: kubernetes kubeconfig: filename: ~/.kube/config - networking: - ssh_host: localhost # The external IP address of any node - ssh_port: 32000 # Any port accessible outside of the cluster + proxy_jump: + hostname: localhost # The external IP address of any node + port: 32000 # Any port accessible outside of the cluster ``` - The port specified to `ssh_port` must be accessible outside of the cluster. + The port specified to `port` must be accessible outside of the cluster. ??? info "Kind" If you are using [Kind](https://kind.sigs.k8s.io/), make sure to make - to set up `ssh_port` via `extraPortMappings` for proxying SSH traffic: + to set up `port` via `extraPortMappings` for proxying SSH traffic: ```yaml kind: Cluster @@ -1068,8 +1068,8 @@ In case of a self-managed cluster, also specify the IP address of any node in th nodes: - role: control-plane extraPortMappings: - - containerPort: 32000 # Must be same as `ssh_port` - hostPort: 32000 # Must be same as `ssh_port` + - containerPort: 32000 # Must be same as `port` + hostPort: 32000 # Must be same as `port` ``` Go ahead and create the cluster like this: @@ -1092,13 +1092,13 @@ In case of a self-managed cluster, also specify the IP address of any node in th - type: kubernetes kubeconfig: filename: ~/.kube/config - networking: - ssh_port: 32000 # Any port accessible outside of the cluster + proxy_jump: + port: 32000 # Any port accessible outside of the cluster ``` - The port specified to `ssh_port` must be accessible outside of the cluster. + The port specified to `port` must be accessible outside of the cluster. ??? info "EKS" For example, if you are using EKS, make sure to add it via an ingress rule diff --git a/docs/docs/reference/server/config.yml.md b/docs/docs/reference/server/config.yml.md index 25f649ddf..c9660a819 100644 --- a/docs/docs/reference/server/config.yml.md +++ b/docs/docs/reference/server/config.yml.md @@ -293,9 +293,9 @@ to configure [backends](../../concepts/backends.md) and other [server-level sett cat my-service-account-file.json | jq -c | jq -R ``` -###### `projects[n].backends[type=kubernetes].networking` { #kubernetes-networking data-toc-label="networking" } +###### `projects[n].backends[type=kubernetes].proxy_jump` { #kubernetes-proxy_jump data-toc-label="proxy_jump" } -#SCHEMA# dstack._internal.core.backends.kubernetes.models.KubernetesNetworkingConfig +#SCHEMA# dstack._internal.core.backends.kubernetes.models.KubernetesProxyJumpConfig overrides: show_root_heading: false diff --git a/src/dstack/_internal/core/backends/kubernetes/compute.py b/src/dstack/_internal/core/backends/kubernetes/compute.py index 96dbbc50b..3cf9d93c8 100644 --- a/src/dstack/_internal/core/backends/kubernetes/compute.py +++ b/src/dstack/_internal/core/backends/kubernetes/compute.py @@ -20,7 +20,7 @@ from dstack._internal.core.backends.base.offers import filter_offers_by_requirements from dstack._internal.core.backends.kubernetes.models import ( KubernetesConfig, - KubernetesNetworkingConfig, + KubernetesProxyJumpConfig, ) from dstack._internal.core.backends.kubernetes.utils import ( call_api_method, @@ -69,10 +69,10 @@ class KubernetesCompute( def __init__(self, config: KubernetesConfig): super().__init__() self.config = config.copy() - networking_config = self.config.networking - if networking_config is None: - networking_config = KubernetesNetworkingConfig() - self.networking_config = networking_config + proxy_jump = self.config.proxy_jump + if proxy_jump is None: + proxy_jump = KubernetesProxyJumpConfig() + self.proxy_jump = proxy_jump self.api = get_api_from_config_data(config.kubeconfig.data) def get_offers_by_requirements( @@ -143,7 +143,7 @@ def run_job( # as an ssh proxy jump to connect to all other services in Kubernetes. # Setup jump pod in a separate thread to avoid long-running run_job. # In case the thread fails, the job will be failed and resubmitted. - jump_pod_hostname = self.networking_config.ssh_host + jump_pod_hostname = self.proxy_jump.hostname if jump_pod_hostname is None: jump_pod_hostname = get_cluster_public_ip(self.api) if jump_pod_hostname is None: @@ -156,7 +156,7 @@ def run_job( namespace=self.config.namespace, project_name=run.project_name, ssh_public_keys=[project_ssh_public_key.strip(), run.run_spec.ssh_key_pub.strip()], - jump_pod_port=self.networking_config.ssh_port, + jump_pod_port=self.proxy_jump.port, ) if not created: threading.Thread( @@ -820,11 +820,11 @@ def _run_ssh_command(hostname: str, port: int, ssh_private_key: str, command: st def _get_jump_pod_name(project_name: str) -> str: - return f"{project_name}-ssh-jump-pod" + return f"dstack-{project_name}-ssh-jump-pod" def _get_jump_pod_service_name(project_name: str) -> str: - return f"{project_name}-ssh-jump-pod-service" + return f"dstack-{project_name}-ssh-jump-pod-service" def _get_pod_service_name(pod_name: str) -> str: diff --git a/src/dstack/_internal/core/backends/kubernetes/models.py b/src/dstack/_internal/core/backends/kubernetes/models.py index a4f05cab1..09e505f0a 100644 --- a/src/dstack/_internal/core/backends/kubernetes/models.py +++ b/src/dstack/_internal/core/backends/kubernetes/models.py @@ -8,11 +8,11 @@ DEFAULT_NAMESPACE = "default" -class KubernetesNetworkingConfig(CoreModel): - ssh_host: Annotated[ - Optional[str], Field(description="The external IP address of any node") +class KubernetesProxyJumpConfig(CoreModel): + hostname: Annotated[ + Optional[str], Field(description="The external IP address or hostname of any node") ] = None - ssh_port: Annotated[ + port: Annotated[ Optional[int], Field(description="Any port accessible outside of the cluster") ] = None @@ -24,8 +24,8 @@ class KubeconfigConfig(CoreModel): class KubernetesBackendConfig(CoreModel): type: Annotated[Literal["kubernetes"], Field(description="The type of backend")] = "kubernetes" - networking: Annotated[ - Optional[KubernetesNetworkingConfig], Field(description="The networking configuration") + proxy_jump: Annotated[ + Optional[KubernetesProxyJumpConfig], Field(description="The SSH proxy jump configuration") ] = None namespace: Annotated[ str, Field(description="The namespace for resources managed by `dstack`") diff --git a/src/tests/_internal/core/backends/kubernetes/test_configurator.py b/src/tests/_internal/core/backends/kubernetes/test_configurator.py index dfef80cfd..3605b82fc 100644 --- a/src/tests/_internal/core/backends/kubernetes/test_configurator.py +++ b/src/tests/_internal/core/backends/kubernetes/test_configurator.py @@ -8,7 +8,7 @@ from dstack._internal.core.backends.kubernetes.models import ( KubeconfigConfig, KubernetesBackendConfigWithCreds, - KubernetesNetworkingConfig, + KubernetesProxyJumpConfig, ) from dstack._internal.core.errors import BackendInvalidCredentialsError @@ -17,7 +17,7 @@ class TestKubernetesConfigurator: def test_validate_config_valid(self): config = KubernetesBackendConfigWithCreds( kubeconfig=KubeconfigConfig(data="valid", filename="-"), - networking=KubernetesNetworkingConfig(ssh_host=None, ssh_port=None), + proxy_jump=KubernetesProxyJumpConfig(hostname=None, port=None), ) with patch( "dstack._internal.core.backends.kubernetes.utils.get_api_from_config_data" @@ -30,7 +30,7 @@ def test_validate_config_valid(self): def test_validate_config_invalid_config(self): config = KubernetesBackendConfigWithCreds( kubeconfig=KubeconfigConfig(data="invalid", filename="-"), - networking=KubernetesNetworkingConfig(ssh_host=None, ssh_port=None), + proxy_jump=KubernetesProxyJumpConfig(hostname=None, port=None), ) with ( patch(