global: # zone: cluster.local (use only if your DNS server doesn't live in the same zone as kubecost) prometheus: enabled: true # If false, Prometheus will not be installed -- only actively supported on paid Kubecost plans fqdn: http://cost-analyzer-prometheus-server.default.svc #example fqdn. Ignored if enabled: true # insecureSkipVerify : false # If true, kubecost will not check the TLS cert of prometheus # queryServiceBasicAuthSecretName: dbsecret # kubectl create secret generic dbsecret -n kubecost --from-file=USERNAME --from-file=PASSWORD # queryServiceBearerTokenSecretName: dbsecret # kubectl create secret generic mcdbsecret -n kubecost --from-file=TOKEN # Durable storage option, product key required thanos: enabled: false # queryService: http://thanos-query-frontend-http.kubecost:{{ .Values.thanos.queryFrontend.http.port }} # an address of the thanos query-frontend endpoint, if different from installed thanos # queryServiceBasicAuthSecretName: mcdbsecret # kubectl create secret generic mcdbsecret -n kubecost --from-file=USERNAME --from-file=PASSWORD <---enter basic auth credentials like that # queryServiceBearerTokenSecretName mcdbsecret # kubectl create secret generic mcdbsecret -n kubecost --from-file=TOKEN # queryOffset: 3h # The offset to apply to all thanos queries in order to achieve syncronization on all cluster block stores grafana: enabled: true # If false, Grafana will not be installed domainName: cost-analyzer-grafana.default.svc #example grafana domain Ignored if enabled: true scheme: "http" # http or https, for the domain name above. proxy: true # If true, the kubecost frontend will route to your grafana through its service endpoint notifications: # Kubecost alerting configuration # Ref: http://docs.kubecost.com/alerts alertConfigs: enabled: false # the example values below are never read unless enabled is set to true frontendUrl: http://localhost:9090 # optional, used for linkbacks slackWebhookUrl: https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXXXXXXXX # optional, used for Slack alerts globalAlertEmails: - recipient@example.com - additionalRecipient@example.com alerts: # Daily namespace budget alert on namespace `kubecost` - type: budget # supported: budget, recurringUpdate threshold: 50 # optional, required for budget alerts window: daily # or 1d aggregation: namespace filter: kubecost ownerContact: # optional, overrides globalAlertEmails default - owner@example.com - owner2@example.com # Daily cluster budget alert (clusterCosts alert) on cluster `cluster-one` - type: budget threshold: 200.8 # optional, required for budget alerts window: daily # or 1d aggregation: cluster filter: cluster-one # Recurring weekly update (weeklyUpdate alert) - type: recurringUpdate window: weekly # or 7d aggregation: namespace filter: '*' # Recurring weekly namespace update on kubecost namespace - type: recurringUpdate window: weekly # or 7d aggregation: namespace filter: kubecost ownerContact: # ownerContact(s) should be the same for the same namespace, otherwise the last namespace alert overwrites - owner@example.com - owner2@example.com alertmanager: # Supply an alertmanager FQDN to receive notifications from the app. enabled: false # If true, allow kubecost to write to your alertmanager fqdn: http://cost-analyzer-prometheus-server.default.svc #example fqdn. Ignored if prometheus.enabled: true podAnnotations: {} # iam.amazonaws.com/role: role-arn pricingCsv: enabled: false location: provider: "AWS" region: "us-east-1" URI: s3://kc-csv-test/pricing_schema.csv # a valid file URI csvAccessCredentials: pricing-schema-access-secret saml: # enterprise key required to use enabled: false secretName: "kubecost-authzero" #metadataSecretName: "kubecost-authzero-metadata" # One of metadataSecretName or idpMetadataURL must be set. defaults to metadataURL if set idpMetadataURL: "https://dev-elu2z98r.auth0.com/samlp/metadata/c6nY4M37rBP0qSO1IYIqBPPyIPxLS8v2" appRootURL: "http://localhost:9090" # sample URL # audienceURI: "http://localhost:9090" # by convention, the same as the appRootURL, but any string uniquely identifying kubecost to your samp IDP. Optional if you follow the convention rbac: enabled: false groups: - name: admin enabled: false # if admin is disabled, all SAML users will be able to make configuration changes to the kubecost frontend assertionName: "http://schemas.auth0.com/userType" # a SAML Assertion, one of whose elements has a value that matches on of the values in assertionValues assertionValues: - "admin" - "superusers" - name: readonly enabled: false # if readonly is disabled, all users authorized on SAML will default to readonly assertionName: "http://schemas.auth0.com/userType" assertionvalues: - "readonly" # imagePullSecrets: # - name: "image-pull-secret" kubecostChecks: enabled: true image: "quay.io/kubecost1/checks" resources: requests: cpu: "20m" memory: "100Mi" limits: cpu: "100m" memory: "200Mi" kubecostFrontend: image: "gcr.io/kubecost1/frontend" imagePullPolicy: Always resources: requests: cpu: "10m" memory: "55Mi" #limits: # cpu: "100m" # memory: "256Mi" kubecost: image: "gcr.io/kubecost1/server" resources: requests: cpu: "100m" memory: "55Mi" #limits: # cpu: "100m" # memory: "256Mi" kubecostModel: image: "gcr.io/kubecost1/cost-model" imagePullPolicy: Always warmCache: true warmSavingsCache: true etl: true # The total number of days the ETL storage will build etlStoreDurationDays: 120 maxQueryConcurrency: 5 # utcOffset represents a timezone in hours and minutes east (+) or west (-) # of UTC, itself, which is defined as +00:00. # See the tz database of timezones to look up your local UTC offset: # https://en.wikipedia.org/wiki/List_of_tz_database_time_zones utcOffset: "+00:00" resources: requests: cpu: "200m" memory: "55Mi" #limits: # cpu: "800m" # memory: "256Mi" ingress: enabled: false annotations: kubernetes.io/ingress.class: nginx # kubernetes.io/tls-acme: "true" paths: ["/"] # There's no need to route specifically to the pods-- we have an nginx deployed that handles routing hosts: - cost-analyzer.local tls: [] # - secretName: cost-analyzer-tls # hosts: # - cost-analyzer.local nodeSelector: {} tolerations: [] # - key: "key" # operator: "Equal|Exists" # value: "value" # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" affinity: {} # If true, creates a PriorityClass to be used by the cost-analyzer pod priority: enabled: false # value: 1000000 # If true, enable creation of NetworkPolicy resources. networkPolicy: enabled: false podSecurityPolicy: enabled: false # Define persistence volume for cost-analyzer persistentVolume: size: 0.2Gi dbSize: 32.0Gi enabled: true # Note that setting this to false means configurations will be wiped out on pod restart. # storageClass: "-" # # existingClaim: kubecost-cost-analyzer # a claim in the same namespace as kubecost service: type: ClusterIP port: 9090 targetPort: 9090 # nodePort: labels: {} annotations: {} # enabling long-term durable storage with Postgres requires an enterprise license remoteWrite: postgres: enabled: false initImage: "gcr.io/kubecost1/sql-init" initImagePullPolicy: Always installLocal: true remotePostgresAddress: "" # ignored if installing locally persistentVolume: size: 200Gi auth: password: admin # change me prometheus: extraScrapeConfigs: | - job_name: kubecost honor_labels: true scrape_interval: 1m scrape_timeout: 10s metrics_path: /metrics scheme: http dns_sd_configs: - names: - {{ template "cost-analyzer.serviceName" . }} type: 'A' port: 9003 - job_name: kubecost-networking kubernetes_sd_configs: - role: pod relabel_configs: # Scrape only the the targets matching the following metadata - source_labels: [__meta_kubernetes_pod_label_app] action: keep regex: {{ template "cost-analyzer.networkCostsName" . }} server: # If clusterIDConfigmap is defined, instead use user-generated configmap with key CLUSTER_ID # to use as unique cluster ID in kubecost cost-analyzer deployment. # This overrides the cluster_id set in prometheus.server.global.external_labels. # NOTE: This does not affect the external_labels set in prometheus config. # clusterIDConfigmap: cluster-id-configmap resources: {} # limits: # cpu: 500m # memory: 512Mi # requests: # cpu: 500m # memory: 512Mi global: scrape_interval: 1m scrape_timeout: 10s evaluation_interval: 1m external_labels: cluster_id: cluster-one # Each cluster should have a unique ID persistentVolume: size: 32Gi enabled: true extraArgs: query.max-concurrency: 1 query.max-samples: 100000000 tolerations: [] # - key: "key" # operator: "Equal|Exists" # value: "value" # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" alertmanager: # enabled: false persistentVolume: enabled: true nodeExporter: enabled: true pushgateway: enabled: false persistentVolume: enabled: true serverFiles: # prometheus.yml: # Sample block -- enable if using an in cluster durable store. # remote_write: # - url: "http://pgprometheus-adapter:9201/write" # write_relabel_configs: # - source_labels: [__name__] # regex: 'container_.*_allocation|container_.*_allocation_bytes|.*_hourly_cost|kube_pod_container_resource_requests_memory_bytes|container_memory_working_set_bytes|kube_pod_container_resource_requests_cpu_cores|kube_pod_container_resource_requests|pod_pvc_allocation|kube_namespace_labels|kube_pod_labels' # action: keep # queue_config: # max_samples_per_send: 1000 #remote_read: # - url: "http://pgprometheus-adapter:9201/read" rules: groups: - name: CPU rules: - expr: sum(rate(container_cpu_usage_seconds_total{container_name!=""}[5m])) record: cluster:cpu_usage:rate5m - expr: rate(container_cpu_usage_seconds_total{container_name!=""}[5m]) record: cluster:cpu_usage_nosum:rate5m - expr: avg(irate(container_cpu_usage_seconds_total{container_name!="POD", container_name!=""}[5m])) by (container_name,pod_name,namespace) record: kubecost_container_cpu_usage_irate - expr: sum(container_memory_working_set_bytes{container_name!="POD",container_name!=""}) by (container_name,pod_name,namespace) record: kubecost_container_memory_working_set_bytes - expr: sum(container_memory_working_set_bytes{container_name!="POD",container_name!=""}) record: kubecost_cluster_memory_working_set_bytes - name: Savings rules: - expr: sum(avg(kube_pod_owner{owner_kind!="DaemonSet"}) by (pod) * sum(container_cpu_allocation) by (pod)) record: kubecost_savings_cpu_allocation labels: daemonset: "false" - expr: sum(avg(kube_pod_owner{owner_kind="DaemonSet"}) by (pod) * sum(container_cpu_allocation) by (pod)) / sum(kube_node_info) record: kubecost_savings_cpu_allocation labels: daemonset: "true" - expr: sum(avg(kube_pod_owner{owner_kind!="DaemonSet"}) by (pod) * sum(container_memory_allocation_bytes) by (pod)) record: kubecost_savings_memory_allocation_bytes labels: daemonset: "false" - expr: sum(avg(kube_pod_owner{owner_kind="DaemonSet"}) by (pod) * sum(container_memory_allocation_bytes) by (pod)) / sum(kube_node_info) record: kubecost_savings_memory_allocation_bytes labels: daemonset: "true" - expr: label_replace(sum(kube_pod_status_phase{phase="Running",namespace!="kube-system"} > 0) by (pod, namespace), "pod_name", "$1", "pod", "(.+)") record: kubecost_savings_running_pods - expr: sum(rate(container_cpu_usage_seconds_total{container_name!="",container_name!="POD",instance!=""}[5m])) by (namespace, pod_name, container_name, instance) record: kubecost_savings_container_cpu_usage_seconds - expr: sum(container_memory_working_set_bytes{container_name!="",container_name!="POD",instance!=""}) by (namespace, pod_name, container_name, instance) record: kubecost_savings_container_memory_usage_bytes - expr: avg(sum(kube_pod_container_resource_requests_cpu_cores{namespace!="kube-system"}) by (pod, namespace, instance)) by (pod, namespace) record: kubecost_savings_pod_requests_cpu_cores - expr: avg(sum(kube_pod_container_resource_requests_memory_bytes{namespace!="kube-system"}) by (pod, namespace, instance)) by (pod, namespace) record: kubecost_savings_pod_requests_memory_bytes networkCosts: enabled: false podSecurityPolicy: enabled: false image: gcr.io/kubecost1/kubecost-network-costs:v13.7 imagePullPolicy: Always # Traffic Logging will enable logging the top 5 destinations for each source # every 30 minutes. trafficLogging: true # Port will set both the containerPort and hostPort to this value. # These must be identical due to network-costs being run on hostNetwork port: 3001 resources: {} #requests: # cpu: "50m" # memory: "20Mi" config: # Configuration for traffic destinations, including specific classification # for IPs and CIDR blocks. This configuration will act as an override to the # automatic classification provided by network-costs. destinations: # In Zone contains a list of address/range that will be # classified as in zone. in-zone: # Loopback - "127.0.0.1" # IPv4 Link Local Address Space - "169.254.0.0/16" # Private Address Ranges in RFC-1918 - "10.0.0.0/8" - "172.16.0.0/12" - "192.168.0.0/16" # In Region contains a list of address/range that will be # classified as in region. This is synonymous with cross # zone traffic, where the regions between source and destinations # are the same, but the zone is different. in-region: [] # Cross Region contains a list of address/range that will be # classified as non-internet egress from one region to another. cross-region: [] # Direct Classification specifically maps an ip address or range # to a region (required) and/or zone (optional). This classification # takes priority over in-zone, in-region, and cross-region configurations. direct-classification: [] # - region: "us-east1" # zone: "us-east1-c" # ips: # - "10.0.0.0/24" ## Node tolerations for server scheduling to nodes with taints ## Ref: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/ ## tolerations: [] # - key: "key" # operator: "Equal|Exists" # value: "value" # effect: "NoSchedule|PreferNoSchedule|NoExecute(1.6 only)" ## PriorityClassName ## Ref: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/#priorityclass priorityClassName: [] ## PodMonitor ## Allows scraping of network metrics from a dedicated prometheus operator setup podMonitor: enabled: false additionalLabels: {} # Kubecost Deployment Configuration # Used for HA mode in Business & Enterprise tier kubecostDeployment: replicas: 1 # Kubecost Cluster Controller for Right Sizing and Cluster Turndown clusterController: enabled: false image: gcr.io/kubecost1/cluster-controller:v0.0.2 imagePullPolicy: Always reporting: # Kubecost bug report feature: Logs access/collection limited to .Release.Namespace # Ref: http://docs.kubecost.com/bug-report logCollection: true productAnalytics: true errorReporting: true valuesReporting: true serviceMonitor: enabled: false additionalLabels: {} prometheusRule: enabled: false additionalLabels: {} supportNFS: true initChownDataImage: "busybox" # Supports a fully qualified Docker image eg: registry.hub.docker.com/library/busybox:latest. initChownData: resources: {} #requests: # cpu: "50m" # memory: "20Mi" grafana: # namespace_datasources: kubecost # override the default namespace here # namespace_dashboards: kubecost # override the default namespace here sidecar: dashboards: enabled: true # label that the configmaps with dashboards are marked with label: grafana_dashboard datasources: # dataSourceFilename: foo.yml # If you need to change the name of the datasource file enabled: true defaultDatasourceEnabled: false dataSourceName: default-kubecost # label that the configmaps with datasources are marked with label: kubecost_grafana_datasource # For grafana to be accessible, add the path to root_url. For example, if you run kubecost at www.foo.com:9090/kubecost # set root_url to "%(protocol)s://%(domain)s:%(http_port)s/kubecost/grafana". No change is necessary here if kubecost runs at a root URL grafana.ini: server: root_url: "%(protocol)s://%(domain)s:%(http_port)s/grafana" serviceAccount: create: true # Set this to false if you're bringing your own service account. annotations: {} # name: kc-test # These configs can also be set from the Settings page in the Kubecost product UI # Values in this block override config changes in the Settings UI on pod restart # # kubecostProductConfigs: # An optional list of cluster definitions that can be added for frontend access. The local # cluster is *always* included by default, so this list is for non-local clusters. # Ref: https://github.com/kubecost/docs/blob/master/multi-cluster.md # clusters: # - name: "Cluster A" # address: http://cluster-a.kubecost.com:9090 # # Optional authentication credentials - only basic auth is currently supported. # auth: # type: basic # # Secret name should be a secret formatted based on: https://github.com/kubecost/docs/blob/master/ingress-examples.md # secretName: cluster-a-auth # # Or pass auth directly as base64 encoded user:pass # data: YWRtaW46YWRtaW4= # # Or user and pass directly # user: admin # pass: admin # - name: "Cluster B" # address: http://cluster-b.kubecost.com:9090 # defaultModelPricing: # default monthly resource prices, used predominately for on-prem clusters # CPU: 28.0 # spotCPU: 4.86 # RAM: 3.09 # spotRAM: 0.65 # GPU: 693.50 # spotGPU: 225.0 # storage: 0.04 # zoneNetworkEgress: 0.01 # regionNetworkEgress: 0.01 # internetNetworkEgress: 0.12 # enabled: true # # The cluster profile represents a predefined set of parameters to use when calculating savings. # # Possible values are: [ development, production, high-availability ] # clusterProfile: production # customPricesEnabled: false # This makes the default view custom prices-- generally used for on-premises clusters # spotLabel: lifecycle # spotLabelValue: Ec2Spot # gpuLabel: gpu # gpuLabelValue: true # awsServiceKeyName: ACCESSKEYID # awsServiceKeyPassword: fakepassword # Only use if your values.yaml are stored encrypted. Otherwise provide an existing secret via serviceKeySecretName # awsSpotDataRegion: us-east-1 # awsSpotDataBucket: spot-data-feed-s3-bucket # awsSpotDataPrefix: dev # athenaProjectID: "530337586277" # The AWS AccountID where the Athena CUR is. Generally your masterpayer account # athenaBucketName: "s3://aws-athena-query-results-530337586277-us-east-1" # athenaRegion: us-east-1 # athenaDatabase: athenacurcfn_athena_test1 # athenaTable: "athena_test1" # masterPayerARN: "" # projectID: "123456789" # Also known as AccountID on AWS -- the current account/project that this instance of Kubecost is deployed on. # gcpSecretName: gcp-secret # Name of a secret representing the gcp service key # bigQueryBillingDataDataset: billing_data.gcp_billing_export_v1_01AC9F_74CF1D_5565A2 # labelMappingConfigs: # names of k8s labels used to designate different allocation concepts # enabled: true # owner_label: "owner" # team_label: "team" # department_label: "dept" # product_label: "product" # environment_label: "env" # namespace_external_label: "kubernetes_namespace" # external labels are used to map external cloud costs to kubernetes concepts # cluster_external_label: "kubernetes_cluster" # controller_external_label: "kubernetes_controller" # product_external_label: "kubernetes_label_app" # service_external_label: "kubernetes_service" # deployment_external_label: "kubernetes_deployment" # team_external_label: "kubernetes_label_team" # environment_external_label: "kubernetes_label_env" # department_external_label: "kubernetes_label_department" # statefulset_external_label: "kubernetes_statefulset" # daemonset_external_label: "kubernetes_daemonset" # pod_external_label: "kubernetes_pod" # grafanaURL: "" # clusterName: "" # used for display in Kubecost UI # currencyCode: "USD" # offical support for USD, CAD, EUR, and CHF # azureBillingRegion: US # Represents 2-letter region code, e.g. West Europe = NL, Canada = CA. ref: https://en.wikipedia.org/wiki/List_of_ISO_3166_country_codes # azureSubscriptionID: 0bd50fdf-c923-4e1e-850c-196dd3dcc5d3 # azureClientID: f2ef6f7d-71fb-47c8-b766-8d63a19db017 # azureTenantID: 72faf3ff-7a3f-4597-b0d9-7b0b201bb23a # azureClientPassword: fake key # Only use if your values.yaml are stored encrypted. Otherwise provide an existing secret via serviceKeySecretName # discount: "" # percentage discount applied to compute # negotiatedDiscount: "" # custom negotiated cloud provider discount # defaultIdle: false # serviceKeySecretName: "" # Use an existing AWS or Azure secret with format as in aws-service-key-secret.yaml or azure-service-key-secret.yaml. Leave blank if using createServiceKeySecret # createServiceKeySecret: true # Creates a secret representing your cloud service key based on data in values.yaml. If you are storing unencrypted values, add a secret manually # sharedNamespaces: "" # namespaces with shared workloads, example value: "kube-system\,ingress-nginx\,kubecost\,monitoring" # productKey: # apply business or enterprise product license # key: "" # enabled: false # secretname: productkeysecret # create a secret out of a file named productkey.json of format { "key": "kc-b1325234" }