wip: helm chart deploys to namespace with resource limits and requests, trying to fix connection refused to api error
This commit is contained in:
parent
8e857bc72a
commit
460c8b59e1
13
examples/monitoring_with_tenant/Cargo.toml
Normal file
13
examples/monitoring_with_tenant/Cargo.toml
Normal file
@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "example-monitoring-with-tenant"
|
||||
edition = "2024"
|
||||
version.workspace = true
|
||||
readme.workspace = true
|
||||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
cidr.workspace = true
|
||||
harmony = { version = "0.1.0", path = "../../harmony" }
|
||||
harmony_cli = { version = "0.1.0", path = "../../harmony_cli" }
|
||||
tokio.workspace = true
|
||||
url.workspace = true
|
63
examples/monitoring_with_tenant/src/main.rs
Normal file
63
examples/monitoring_with_tenant/src/main.rs
Normal file
@ -0,0 +1,63 @@
|
||||
use cidr::Ipv4Cidr;
|
||||
use harmony::{
|
||||
data::Id,
|
||||
inventory::Inventory,
|
||||
maestro::Maestro,
|
||||
modules::{
|
||||
monitoring::{
|
||||
alert_channel::discord_alert_channel::DiscordWebhook,
|
||||
alert_rule::prometheus_alert_rule::AlertManagerRuleGroup,
|
||||
kube_prometheus::helm_prometheus_alert_score::HelmPrometheusAlertingScore,
|
||||
},
|
||||
prometheus::alerts::k8s::pvc::high_pvc_fill_rate_over_two_days,
|
||||
tenant::TenantScore,
|
||||
},
|
||||
topology::{
|
||||
K8sAnywhereTopology, Url,
|
||||
tenant::{InternetEgressPolicy, ResourceLimits, TenantConfig, TenantNetworkPolicy},
|
||||
},
|
||||
};
|
||||
use std::net::Ipv4Addr;
|
||||
use std::str::FromStr;
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() {
|
||||
let tenant = TenantScore {
|
||||
config: TenantConfig {
|
||||
id: Id::from_string("1234".to_string()),
|
||||
name: "test-tenant".to_string(),
|
||||
resource_limits: ResourceLimits {
|
||||
cpu_request_cores: 4.0,
|
||||
cpu_limit_cores: 4.0,
|
||||
memory_request_gb: 4.0,
|
||||
memory_limit_gb: 4.0,
|
||||
storage_total_gb: 10.0,
|
||||
},
|
||||
network_policy: TenantNetworkPolicy::default(),
|
||||
},
|
||||
};
|
||||
|
||||
let discord_receiver = DiscordWebhook {
|
||||
name: "test-discord".to_string(),
|
||||
url: Url::Url(url::Url::parse("https://discord.doesnt.exist.com").unwrap()),
|
||||
};
|
||||
|
||||
let high_pvc_fill_rate_over_two_days_alert = high_pvc_fill_rate_over_two_days();
|
||||
|
||||
let additional_rules =
|
||||
AlertManagerRuleGroup::new("pvc-alerts", vec![high_pvc_fill_rate_over_two_days_alert]);
|
||||
|
||||
let alerting_score = HelmPrometheusAlertingScore {
|
||||
receivers: vec![Box::new(discord_receiver)],
|
||||
rules: vec![Box::new(additional_rules)],
|
||||
};
|
||||
let mut maestro = Maestro::<K8sAnywhereTopology>::initialize(
|
||||
Inventory::autoload(),
|
||||
K8sAnywhereTopology::from_env(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
maestro.register_all(vec![Box::new(tenant), Box::new(alerting_score)]);
|
||||
harmony_cli::init(maestro, None).await.unwrap();
|
||||
}
|
@ -185,13 +185,18 @@ impl K8sAnywhereTopology {
|
||||
self.tenant_manager
|
||||
.get_or_try_init(async || -> Result<K8sTenantManager, String> {
|
||||
let k8s_client = self.k8s_client().await?;
|
||||
Ok(K8sTenantManager::new(k8s_client, TenantConfig::default()))
|
||||
Ok(K8sTenantManager::new(k8s_client))
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
async fn store_tenant_config(&self, config: TenantConfig) {
|
||||
self.tenant_manager_config
|
||||
.get_or_init(|| async { config })
|
||||
.await;
|
||||
}
|
||||
|
||||
fn get_k8s_tenant_manager(&self) -> Result<&K8sTenantManager, ExecutorError> {
|
||||
match self.tenant_manager.get() {
|
||||
@ -271,6 +276,7 @@ impl HelmCommand for K8sAnywhereTopology {}
|
||||
#[async_trait]
|
||||
impl TenantManager for K8sAnywhereTopology {
|
||||
async fn provision_tenant(&self, config: &TenantConfig) -> Result<(), ExecutorError> {
|
||||
self.store_tenant_config(config.clone()).await;
|
||||
self.get_k8s_tenant_manager()?
|
||||
.provision_tenant(config)
|
||||
.await
|
||||
|
@ -25,7 +25,6 @@ use super::{TenantConfig, TenantManager};
|
||||
#[derive(new)]
|
||||
pub struct K8sTenantManager {
|
||||
k8s_client: Arc<K8sClient>,
|
||||
k8s_tenant_config: TenantConfig,
|
||||
}
|
||||
|
||||
impl K8sTenantManager {
|
||||
@ -326,6 +325,6 @@ impl TenantManager for K8sTenantManager {
|
||||
Ok(())
|
||||
}
|
||||
fn get_tenant_config(&self) -> Option<TenantConfig> {
|
||||
Some(self.k8s_tenant_config.clone())
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
use serde::Serialize;
|
||||
|
||||
use crate::modules::monitoring::
|
||||
kube_prometheus::types::{AlertManagerAdditionalPromRules, AlertManagerChannelConfig}
|
||||
;
|
||||
use crate::modules::monitoring::kube_prometheus::types::{
|
||||
AlertManagerAdditionalPromRules, AlertManagerChannelConfig,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct KubePrometheusConfig {
|
||||
|
@ -12,7 +12,8 @@ use crate::modules::{
|
||||
helm::chart::HelmChartScore,
|
||||
monitoring::kube_prometheus::types::{
|
||||
AlertGroup, AlertManager, AlertManagerAdditionalPromRules, AlertManagerConfig,
|
||||
AlertManagerRoute, AlertManagerValues,
|
||||
AlertManagerRoute, AlertManagerSpec, AlertManagerValues, Cpu, CpuUnit, Limits, Memory,
|
||||
MemoryUnit, Requests, Resources,
|
||||
},
|
||||
};
|
||||
|
||||
@ -36,8 +37,53 @@ pub fn kube_prometheus_helm_chart_score(
|
||||
let node_exporter = config.node_exporter.to_string();
|
||||
let prometheus_operator = config.prometheus_operator.to_string();
|
||||
let prometheus = config.prometheus.to_string();
|
||||
let resource_limit = Resources {
|
||||
limits: Limits {
|
||||
memory: Memory {
|
||||
value: 100,
|
||||
unit: MemoryUnit::Mi,
|
||||
},
|
||||
cpu: Cpu {
|
||||
value: 100,
|
||||
unit: CpuUnit::Milli,
|
||||
},
|
||||
},
|
||||
requests: Requests {
|
||||
memory: Memory {
|
||||
value: 100,
|
||||
unit: MemoryUnit::Mi,
|
||||
},
|
||||
cpu: Cpu {
|
||||
value: 100,
|
||||
unit: CpuUnit::Milli,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
fn indent_lines(s: &str, spaces: usize) -> String {
|
||||
let pad = " ".repeat(spaces);
|
||||
s.lines()
|
||||
.map(|line| format!("{pad}{line}"))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
|
||||
fn resource_block(resource: &Resources, indent_level: usize) -> String {
|
||||
let yaml = serde_yaml::to_string(resource).unwrap();
|
||||
format!(
|
||||
"{}resources:\n{}",
|
||||
" ".repeat(indent_level),
|
||||
indent_lines(&yaml, indent_level + 2)
|
||||
)
|
||||
}
|
||||
let resource_section = resource_block(&resource_limit, 2);
|
||||
|
||||
let mut values = format!(
|
||||
r#"
|
||||
prometheus:
|
||||
enabled: {prometheus}
|
||||
prometheusSpec:
|
||||
{resource_section}
|
||||
defaultRules:
|
||||
create: {default_rules}
|
||||
rules:
|
||||
@ -77,32 +123,59 @@ defaultRules:
|
||||
windows: true
|
||||
windowsMonitoring:
|
||||
enabled: {windows_monitoring}
|
||||
{resource_section}
|
||||
grafana:
|
||||
enabled: {grafana}
|
||||
{resource_section}
|
||||
kubernetesServiceMonitors:
|
||||
enabled: {kubernetes_service_monitors}
|
||||
{resource_section}
|
||||
kubeApiServer:
|
||||
enabled: {kubernetes_api_server}
|
||||
{resource_section}
|
||||
kubelet:
|
||||
enabled: {kubelet}
|
||||
{resource_section}
|
||||
kubeControllerManager:
|
||||
enabled: {kube_controller_manager}
|
||||
{resource_section}
|
||||
coreDns:
|
||||
enabled: {core_dns}
|
||||
{resource_section}
|
||||
kubeEtcd:
|
||||
enabled: {kube_etcd}
|
||||
{resource_section}
|
||||
kubeScheduler:
|
||||
enabled: {kube_scheduler}
|
||||
{resource_section}
|
||||
kubeProxy:
|
||||
enabled: {kube_proxy}
|
||||
{resource_section}
|
||||
kubeStateMetrics:
|
||||
enabled: {kube_state_metrics}
|
||||
{resource_section}
|
||||
nodeExporter:
|
||||
enabled: {node_exporter}
|
||||
{resource_section}
|
||||
prometheusOperator:
|
||||
enabled: {prometheus_operator}
|
||||
prometheus:
|
||||
enabled: {prometheus}
|
||||
admissionWebhooks:
|
||||
deployment:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 10m
|
||||
memory: 100Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 100Mi
|
||||
patch:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 10m
|
||||
memory: 100Mi
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 100Mi
|
||||
"#,
|
||||
);
|
||||
|
||||
@ -145,6 +218,30 @@ prometheus:
|
||||
alertmanager: AlertManager {
|
||||
enabled: config.alert_manager,
|
||||
config: alert_manager_channel_config,
|
||||
alertManagerSpec: AlertManagerSpec {
|
||||
resources: Resources {
|
||||
limits: Limits {
|
||||
memory: Memory {
|
||||
value: 100,
|
||||
unit: MemoryUnit::Mi,
|
||||
},
|
||||
cpu: Cpu {
|
||||
value: 100,
|
||||
unit: CpuUnit::Milli,
|
||||
},
|
||||
},
|
||||
requests: Requests {
|
||||
memory: Memory {
|
||||
value: 100,
|
||||
unit: MemoryUnit::Mi,
|
||||
},
|
||||
cpu: Cpu {
|
||||
value: 100,
|
||||
unit: CpuUnit::Milli,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -184,7 +281,6 @@ prometheus:
|
||||
values.push_str(&alert_manager_additional_rules_yaml);
|
||||
debug!("full values.yaml: \n {:#}", values);
|
||||
|
||||
|
||||
HelmChartScore {
|
||||
namespace: Some(NonBlankString::from_str(&config.namespace.clone().unwrap()).unwrap()),
|
||||
release_name: NonBlankString::from_str("kube-prometheus").unwrap(),
|
||||
|
@ -21,7 +21,7 @@ pub struct HelmPrometheusAlertingScore {
|
||||
impl<T: Topology + HelmCommand + TenantManager> Score<T> for HelmPrometheusAlertingScore {
|
||||
fn create_interpret(&self) -> Box<dyn crate::interpret::Interpret<T>> {
|
||||
Box::new(AlertingInterpret {
|
||||
sender: Prometheus::new() ,
|
||||
sender: Prometheus::new(),
|
||||
receivers: self.receivers.clone(),
|
||||
rules: self.rules.clone(),
|
||||
})
|
||||
|
@ -63,8 +63,11 @@ impl Prometheus {
|
||||
}
|
||||
|
||||
pub fn configure_with_topology<T: TenantManager>(&self, topology: &T) {
|
||||
let ns = topology.get_tenant_config().map(|cfg| cfg.name.clone())
|
||||
.unwrap_or_else(|| "monitoring".to_string());
|
||||
let ns = topology
|
||||
.get_tenant_config()
|
||||
.map(|cfg| cfg.name.clone())
|
||||
.unwrap_or_else(|| "monitoring".to_string());
|
||||
debug!("NS: {}", ns);
|
||||
self.config.lock().unwrap().namespace = Some(ns);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ pub struct AlertManagerValues {
|
||||
pub struct AlertManager {
|
||||
pub enabled: bool,
|
||||
pub config: AlertManagerConfig,
|
||||
pub alertManagerSpec: AlertManagerSpec,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
@ -43,6 +44,58 @@ pub struct AlertManagerChannelConfig {
|
||||
pub channel_receiver: Value,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct AlertManagerSpec {
|
||||
pub(crate) resources: Resources,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Resources {
|
||||
pub limits: Limits,
|
||||
pub requests: Requests,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Limits {
|
||||
pub memory: Memory,
|
||||
pub cpu: Cpu,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Requests {
|
||||
pub memory: Memory,
|
||||
pub cpu: Cpu,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Memory {
|
||||
pub value: u64,
|
||||
pub unit: MemoryUnit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct Cpu {
|
||||
pub value: u64,
|
||||
pub unit: CpuUnit,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum MemoryUnit {
|
||||
Ki,
|
||||
Mi,
|
||||
Gi,
|
||||
Ti,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum CpuUnit {
|
||||
// 1 = 1 core, m = millicore
|
||||
Core,
|
||||
Milli,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize)]
|
||||
pub struct AlertManagerAdditionalPromRules {
|
||||
#[serde(flatten)]
|
||||
|
Loading…
Reference in New Issue
Block a user