From 2a3213b3add1fbe7d11e866aeac6f50d853f891f Mon Sep 17 00:00:00 2001 From: Adam King Date: Mon, 31 Mar 2025 19:24:28 -0400 Subject: [PATCH] mgr/cephadm: add only_bind_port_on_networks support for rgw This means with a spec like ``` service_type: rgw service_id: foo service_name: rgw.foo placement: hosts: - vm-00 networks: - 192.168.122.0/24 spec: only_bind_port_on_networks: true ``` cephadm will search for an IP address within 192.168.122.0/24 and have the RGW daemon only bind on that IP rather than on all networks. What RGW binds to is controlled by the "rgw_frontends" setting for the rgw daemon, so what cephadm write there is all that is modified by this commit. Signed-off-by: Adam King --- .../mgr/cephadm/services/cephadmservice.py | 31 ++++++++++++++----- .../ceph/deployment/service_spec.py | 3 ++ 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/pybind/mgr/cephadm/services/cephadmservice.py b/src/pybind/mgr/cephadm/services/cephadmservice.py index 072e80ac68407..8fae845401f46 100644 --- a/src/pybind/mgr/cephadm/services/cephadmservice.py +++ b/src/pybind/mgr/cephadm/services/cephadmservice.py @@ -1135,11 +1135,26 @@ class RgwService(CephService): if extra_ssl_cert_provided and spec.generate_cert: raise OrchestratorError("Cannot provide ssl_certificate in combination with generate_cert") + # pick ip RGW should bind to + ip_to_bind_to = '' + if spec.only_bind_port_on_networks and spec.networks: + assert daemon_spec.host is not None + ip_to_bind_to = self.mgr.get_first_matching_network_ip(daemon_spec.host, spec) or '' + if ip_to_bind_to: + daemon_spec.port_ips = {str(port): ip_to_bind_to} + else: + logger.warning( + f'Failed to find ip in {spec.networks} for host {daemon_spec.host}. ' + f'{daemon_spec.name()} will bind to all IPs' + ) + elif daemon_spec.ip: + ip_to_bind_to = daemon_spec.ip + if ftype == 'beast': if spec.ssl: - if daemon_spec.ip: + if ip_to_bind_to: args.append( - f"ssl_endpoint={build_url(host=daemon_spec.ip, port=port).lstrip('/')}") + f"ssl_endpoint={build_url(host=ip_to_bind_to, port=port).lstrip('/')}") else: args.append(f"ssl_port={port}") if spec.generate_cert: @@ -1147,15 +1162,15 @@ class RgwService(CephService): elif not extra_ssl_cert_provided: args.append(f"ssl_certificate=config://rgw/cert/{spec.service_name()}") else: - if daemon_spec.ip: - args.append(f"endpoint={build_url(host=daemon_spec.ip, port=port).lstrip('/')}") + if ip_to_bind_to: + args.append(f"endpoint={build_url(host=ip_to_bind_to, port=port).lstrip('/')}") else: args.append(f"port={port}") elif ftype == 'civetweb': if spec.ssl: - if daemon_spec.ip: + if ip_to_bind_to: # note the 's' suffix on port - args.append(f"port={build_url(host=daemon_spec.ip, port=port).lstrip('/')}s") + args.append(f"port={build_url(host=ip_to_bind_to, port=port).lstrip('/')}s") else: args.append(f"port={port}s") # note the 's' suffix on port if spec.generate_cert: @@ -1163,8 +1178,8 @@ class RgwService(CephService): elif not extra_ssl_cert_provided: args.append(f"ssl_certificate=config://rgw/cert/{spec.service_name()}") else: - if daemon_spec.ip: - args.append(f"port={build_url(host=daemon_spec.ip, port=port).lstrip('/')}") + if ip_to_bind_to: + args.append(f"port={build_url(host=ip_to_bind_to, port=port).lstrip('/')}") else: args.append(f"port={port}") else: diff --git a/src/python-common/ceph/deployment/service_spec.py b/src/python-common/ceph/deployment/service_spec.py index 93ea0511de1f2..2c9967b7fd7a0 100644 --- a/src/python-common/ceph/deployment/service_spec.py +++ b/src/python-common/ceph/deployment/service_spec.py @@ -1224,6 +1224,7 @@ class RGWSpec(ServiceSpec): extra_container_args: Optional[GeneralArgList] = None, extra_entrypoint_args: Optional[GeneralArgList] = None, custom_configs: Optional[List[CustomConfig]] = None, + only_bind_port_on_networks: bool = False, rgw_realm_token: Optional[str] = None, update_endpoints: Optional[bool] = False, zone_endpoints: Optional[str] = None, # comma separated endpoints list @@ -1276,6 +1277,8 @@ class RGWSpec(ServiceSpec): self.update_endpoints = update_endpoints self.zone_endpoints = zone_endpoints self.zonegroup_hostnames = zonegroup_hostnames + #: Whether to limit ip we bind to to what's specified in "networks" parameter + self.only_bind_port_on_networks = only_bind_port_on_networks #: To track op metrics by user config value rgw_user_counters_cache must be set to true self.rgw_user_counters_cache = rgw_user_counters_cache -- 2.39.5