From 82a3aacf421f61cf1b58f1e3e46bc996cafa78a2 Mon Sep 17 00:00:00 2001 From: Adam King Date: Fri, 11 Aug 2023 14:00:31 -0400 Subject: [PATCH] mgr/cephadm: only check haproxy frontend_port conflicts on VIP If we know what IP the frontend_port will be binding to, we can pass that down through the port_ips mapping so cephadm will only check if that port on that specific VIP if in use. This allows multiple haproxy daemons to be bound to the same port on different VIPs on the same host. Note that you still must use a different monitor port for the two different ingress services as that port is bound to on the actual IP of the host. Only the frontend port can be the same for haproxies on the same host as long as the VIP is different. Fixes: https://tracker.ceph.com/issues/57614 Signed-off-by: Adam King (cherry picked from commit 640af155986ac85d12367f43ac45b682a9fa9415) Conflicts: src/pybind/mgr/cephadm/tests/test_services.py --- src/pybind/mgr/cephadm/services/ingress.py | 8 +++- src/pybind/mgr/cephadm/tests/test_services.py | 38 +++++++++++++++++++ 2 files changed, 44 insertions(+), 2 deletions(-) diff --git a/src/pybind/mgr/cephadm/services/ingress.py b/src/pybind/mgr/cephadm/services/ingress.py index 95cff4bad19..720a0bf305c 100644 --- a/src/pybind/mgr/cephadm/services/ingress.py +++ b/src/pybind/mgr/cephadm/services/ingress.py @@ -169,6 +169,10 @@ class IngressService(CephService): if spec.enable_haproxy_protocol: server_opts.append("send-proxy-v2") logger.debug("enabled default server opts: %r", server_opts) + ip = '*' if spec.virtual_ips_list else str(spec.virtual_ip).split('/')[0] or daemon_spec.ip or '*' + frontend_port = daemon_spec.ports[0] if daemon_spec.ports else spec.frontend_port + if ip != '*' and frontend_port: + daemon_spec.port_ips = {str(frontend_port): ip} haproxy_conf = self.mgr.template.render( 'services/ingress/haproxy.cfg.j2', { @@ -178,8 +182,8 @@ class IngressService(CephService): 'servers': servers, 'user': spec.monitor_user or 'admin', 'password': password, - 'ip': "*" if spec.virtual_ips_list else str(spec.virtual_ip).split('/')[0] or daemon_spec.ip or '*', - 'frontend_port': daemon_spec.ports[0] if daemon_spec.ports else spec.frontend_port, + 'ip': ip, + 'frontend_port': frontend_port, 'monitor_port': daemon_spec.ports[1] if daemon_spec.ports else spec.monitor_port, 'local_host_ip': host_ip, 'default_server_opts': server_opts, diff --git a/src/pybind/mgr/cephadm/tests/test_services.py b/src/pybind/mgr/cephadm/tests/test_services.py index e2c6fed9c73..3350f2951b9 100644 --- a/src/pybind/mgr/cephadm/tests/test_services.py +++ b/src/pybind/mgr/cephadm/tests/test_services.py @@ -2023,6 +2023,44 @@ class TestIngressService: assert haproxy_generated_conf[0] == haproxy_expected_conf + @patch("cephadm.serve.CephadmServe._run_cephadm") + def test_haproxy_port_ips(self, _run_cephadm, cephadm_module: CephadmOrchestrator): + _run_cephadm.side_effect = async_side_effect(('{}', '', 0)) + + with with_host(cephadm_module, 'test', addr='1.2.3.7'): + cephadm_module.cache.update_host_networks('test', { + '1.2.3.0/24': { + 'if0': ['1.2.3.4/32'] + } + }) + + # Check the ingress with multiple VIPs + s = RGWSpec(service_id="foo", placement=PlacementSpec(count=1), + rgw_frontend_type='beast') + + ip = '1.2.3.100' + frontend_port = 8089 + + ispec = IngressSpec(service_type='ingress', + service_id='test', + backend_service='rgw.foo', + frontend_port=frontend_port, + monitor_port=8999, + monitor_user='admin', + monitor_password='12345', + keepalived_password='12345', + virtual_ip=f"{ip}/24") + with with_service(cephadm_module, s) as _, with_service(cephadm_module, ispec) as _: + # generate the haproxy conf based on the specified spec + haproxy_daemon_spec = cephadm_module.cephadm_services['ingress'].prepare_create( + CephadmDaemonDeploySpec( + host='test', + daemon_type='haproxy', + daemon_id='ingress', + service_name=ispec.service_name())) + + assert haproxy_daemon_spec.port_ips == {str(frontend_port): ip} + @patch("cephadm.serve.CephadmServe._run_cephadm") @patch("cephadm.services.nfs.NFSService.fence_old_ranks", MagicMock()) @patch("cephadm.services.nfs.NFSService.run_grace_tool", MagicMock()) -- 2.39.5