From 2c4096943edd24ea1ba10ccf51f7dc81ce58852f Mon Sep 17 00:00:00 2001 From: Shachar Sharon Date: Wed, 24 Jul 2024 12:30:31 +0300 Subject: [PATCH] cephadm: run smbmetrics as side-car container When samba metrics-exporter image is provided and it is not an empty string, run the smbmetrics as side-car container along-side main samba-server. This metrics-exporter uses 'smbstatus' to convert SMB stats into standard Prometheus metrics (via port 9922 by default). This commit defines ContainerCommon as base of SambaContainerCommon and SMBMetricsContainer. It defines the basic APIs of smb containers with empty defaults. It also allows passing explicit image URL to samba's sidecar containers. If no alternative image is provided (which is the typical case), use the one provided by context or default one. Signed-off-by: Shachar Sharon --- src/cephadm/cephadmlib/daemons/smb.py | 78 ++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 14 deletions(-) diff --git a/src/cephadm/cephadmlib/daemons/smb.py b/src/cephadm/cephadmlib/daemons/smb.py index 0aecd418b1b..ae9acbc9c45 100644 --- a/src/cephadm/cephadmlib/daemons/smb.py +++ b/src/cephadm/cephadmlib/daemons/smb.py @@ -81,6 +81,8 @@ class Config: smb_port: int ceph_config_entity: str vhostname: str + metrics_image: str + metrics_port: int # clustering related values rank: int rank_generation: int @@ -103,6 +105,8 @@ class Config: smb_port: int = 0, ceph_config_entity: str = 'client.admin', vhostname: str = '', + metrics_image: str = '', + metrics_port: int = 0, rank: int = -1, rank_generation: int = -1, cluster_meta_uri: str = '', @@ -122,6 +126,8 @@ class Config: self.smb_port = smb_port self.ceph_config_entity = ceph_config_entity self.vhostname = vhostname + self.metrics_image = metrics_image + self.metrics_port = metrics_port self.rank = rank self.rank_generation = rank_generation self.cluster_meta_uri = cluster_meta_uri @@ -155,15 +161,34 @@ def _container_dns_args(cfg: Config) -> List[str]: return cargs -class SambaContainerCommon: - def __init__( - self, - cfg: Config, - ) -> None: +class ContainerCommon: + def __init__(self, cfg: Config, image: str = '') -> None: self.cfg = cfg + self.image = image def name(self) -> str: - raise NotImplementedError('samba container name') + raise NotImplementedError('container name') + + def envs(self) -> Dict[str, str]: + return {} + + def envs_list(self) -> List[str]: + return [] + + def args(self) -> List[str]: + return [] + + def container_args(self) -> List[str]: + return [] + + def container_image(self) -> str: + return self.image + + +class SambaContainerCommon(ContainerCommon): + def __init__(self, cfg: Config, image: str = '') -> None: + self.cfg = cfg + self.image = image def envs(self) -> Dict[str, str]: environ = { @@ -196,9 +221,6 @@ class SambaContainerCommon: args.append(f'--debug-delay={self.cfg.debug_delay}') return args - def container_args(self) -> List[str]: - return [] - class SambaNetworkedInitContainer(SambaContainerCommon): """SambaContainerCommon subclass that enables additional networking @@ -233,6 +255,9 @@ class SMBDContainer(SambaContainerCommon): cargs = [] if self.cfg.smb_port: cargs.append(f'--publish={self.cfg.smb_port}:{self.cfg.smb_port}') + if self.cfg.metrics_port: + metrics_port = self.cfg.metrics_port + cargs.append(f'--publish={metrics_port}:{metrics_port}') cargs.extend(_container_dns_args(self.cfg)) return cargs @@ -284,6 +309,17 @@ class ConfigWatchContainer(SambaContainerCommon): return super().args() + ['update-config', '--watch'] +class SMBMetricsContainer(ContainerCommon): + def name(self) -> str: + return 'smbmetrics' + + def args(self) -> List[str]: + args = [] + if self.cfg.metrics_port > 0: + args.append(f'--port={self.cfg.metrics_port}') + return args + + class CTDBMigrateInitContainer(SambaContainerCommon): def name(self) -> str: return 'ctdbMigrate' @@ -358,13 +394,13 @@ class CTDBNodeMonitorContainer(SambaContainerCommon): class ContainerLayout: init_containers: List[SambaContainerCommon] primary: SambaContainerCommon - supplemental: List[SambaContainerCommon] + supplemental: List[ContainerCommon] def __init__( self, init_containers: List[SambaContainerCommon], primary: SambaContainerCommon, - supplemental: List[SambaContainerCommon], + supplemental: List[ContainerCommon], ) -> None: self.init_containers = init_containers self.primary = primary @@ -393,6 +429,7 @@ class SMB(ContainerDaemonForm): self._cached_layout: Optional[ContainerLayout] = None self._rank_info = context_getters.fetch_rank_info(ctx) self.smb_port = 445 + self.metrics_port = 9922 self._network_mapper = _NetworkMapper(ctx) logger.debug('Created SMB ContainerDaemonForm instance') @@ -431,6 +468,8 @@ class SMB(ContainerDaemonForm): files = data_utils.dict_get(configs, 'files', {}) ceph_config_entity = configs.get('config_auth_entity', '') vhostname = configs.get('virtual_hostname', '') + metrics_image = configs.get('metrics_image', '') + metrics_port = int(configs.get('metrics_port', '0')) cluster_meta_uri = configs.get('cluster_meta_uri', '') cluster_lock_uri = configs.get('cluster_lock_uri', '') cluster_public_addrs = configs.get('cluster_public_addrs', []) @@ -470,6 +509,8 @@ class SMB(ContainerDaemonForm): smb_port=self.smb_port, ceph_config_entity=ceph_config_entity, vhostname=vhostname, + metrics_image=metrics_image, + metrics_port=metrics_port, cluster_meta_uri=cluster_meta_uri, cluster_lock_uri=cluster_lock_uri, cluster_public_addrs=_public_addrs, @@ -517,7 +558,7 @@ class SMB(ContainerDaemonForm): if self._cached_layout: return self._cached_layout init_ctrs: List[SambaContainerCommon] = [] - ctrs: List[SambaContainerCommon] = [] + ctrs: List[ContainerCommon] = [] init_ctrs.append(ConfigInitContainer(self._cfg)) ctrs.append(ConfigWatchContainer(self._cfg)) @@ -526,6 +567,11 @@ class SMB(ContainerDaemonForm): init_ctrs.append(MustJoinContainer(self._cfg)) ctrs.append(WinbindContainer(self._cfg)) + metrics_image = self._cfg.metrics_image.strip() + metrics_port = self._cfg.metrics_port + if metrics_image and metrics_port > 0: + ctrs.append(SMBMetricsContainer(self._cfg, metrics_image)) + if self._cfg.clustered: init_ctrs += [ CTDBMigrateInitContainer(self._cfg), @@ -564,7 +610,7 @@ class SMB(ContainerDaemonForm): ) def _to_sidecar_container( - self, ctx: CephadmContext, smb_ctr: SambaContainerCommon + self, ctx: CephadmContext, smb_ctr: ContainerCommon ) -> SidecarContainer: volume_mounts: Dict[str, str] = {} container_args: List[str] = smb_ctr.container_args() @@ -587,10 +633,11 @@ class SMB(ContainerDaemonForm): identity = DaemonSubIdentity.from_parent( self.identity, smb_ctr.name() ) + img = smb_ctr.container_image() or ctx.image or self.default_image return SidecarContainer( ctx, entrypoint='', - image=ctx.image or self.default_image, + image=img, identity=identity, container_args=container_args, args=smb_ctr.args(), @@ -673,6 +720,9 @@ class SMB(ContainerDaemonForm): ) -> None: if not any(ep.port == self.smb_port for ep in endpoints): endpoints.append(EndPoint('0.0.0.0', self.smb_port)) + if self.metrics_port > 0: + if not any(ep.port == self.metrics_port for ep in endpoints): + endpoints.append(EndPoint('0.0.0.0', self.metrics_port)) def prepare_data_dir(self, data_dir: str, uid: int, gid: int) -> None: self.validate() -- 2.47.3