diff --git a/jsonnet/kube-prometheus/kube-prometheus.libsonnet b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
index 0267fda24f02a585947efc3a5b67bb3760c9b493..0183b28625917c6c0e139b2d69e79d69d9dec04a 100644
--- a/jsonnet/kube-prometheus/kube-prometheus.libsonnet
+++ b/jsonnet/kube-prometheus/kube-prometheus.libsonnet
@@ -1,14 +1,12 @@
 local kubeRbacProxyContainer = import './kube-rbac-proxy/containerMixin.libsonnet';
 
-local nodeExporter = import './node-exporter/node-exporter.libsonnet';
 local alertmanager = import './alertmanager/alertmanager.libsonnet';
-
-local prometheusAdapter = import './prometheus-adapter/prometheus-adapter.libsonnet';
-
 local blackboxExporter = import './blackbox-exporter/blackbox-exporter.libsonnet';
+local kubeStateMetrics = import './kube-state-metrics/kube-state-metrics.libsonnet';
+local nodeExporter = import './node-exporter/node-exporter.libsonnet';
+local prometheusAdapter = import './prometheus-adapter/prometheus-adapter.libsonnet';
 
 (import 'github.com/brancz/kubernetes-grafana/grafana/grafana.libsonnet') +
-(import './kube-state-metrics/kube-state-metrics.libsonnet') +
 (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics-mixin/mixin.libsonnet') +
 (import 'github.com/prometheus/node_exporter/docs/node-mixin/mixin.libsonnet') +
 (import 'github.com/prometheus/alertmanager/doc/alertmanager-mixin/mixin.libsonnet') +
@@ -20,28 +18,33 @@ local blackboxExporter = import './blackbox-exporter/blackbox-exporter.libsonnet
 (import './alerts/alerts.libsonnet') +
 (import './rules/rules.libsonnet') +
 {
-  nodeExporter: nodeExporter({
-    namespace: $._config.namespace,
-    version: '1.0.1',
-    image: 'quay.io/prometheus/node-exporter:v1.0.1',
-  }),
   alertmanager: alertmanager({
     name: 'main',
     namespace: $._config.namespace,
     version: '0.21.0',
     image: 'quay.io/prometheus/alertmanager:v0.21.0',
   }),
+  blackboxExporter: blackboxExporter({
+    namespace: $._config.namespace,
+    version: '0.18.0',
+    image: 'quay.io/prometheus/blackbox-exporter:v0.18.0',
+  }),
+  kubeStateMetrics: kubeStateMetrics({
+    namespace: $._config.namespace,
+    version: '1.9.7',
+    image: 'quay.io/coreos/kube-state-metrics:v1.9.7',
+  }),
+  nodeExporter: nodeExporter({
+    namespace: $._config.namespace,
+    version: '1.0.1',
+    image: 'quay.io/prometheus/node-exporter:v1.0.1',
+  }),
   prometheusAdapter: prometheusAdapter({
     namespace: $._config.namespace,
     version: '0.8.2',
     image: 'directxman12/k8s-prometheus-adapter:v0.8.2',
     prometheusURL: 'http://prometheus-' + $._config.prometheus.name + '.' + $._config.namespace + '.svc.cluster.local:9090/',
   }),
-  blackboxExporter: blackboxExporter({
-    namespace: $._config.namespace,
-    version: '0.18.0',
-    image: 'quay.io/prometheus/blackbox-exporter:v0.18.0',
-  }),
   kubePrometheus+:: {
     namespace: {
       apiVersion: 'v1',
@@ -217,10 +220,6 @@ local blackboxExporter = import './blackbox-exporter/blackbox-exporter.libsonnet
         requests: { cpu: '10m', memory: '20Mi' },
         limits: { cpu: '20m', memory: '40Mi' },
       },
-      'kube-state-metrics': {
-        requests: { cpu: '100m', memory: '150Mi' },
-        limits: { cpu: '100m', memory: '150Mi' },
-      },
     },
     prometheus+:: { rules: $.prometheusRules + $.prometheusAlerts },
     grafana+:: {
diff --git a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet b/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
index 62cad10bb3a45f7ae54debc794b1fb4a5b1b0ff4..8b602f7ed78469281ab0080b354507d72fcb4375 100644
--- a/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
+++ b/jsonnet/kube-prometheus/kube-state-metrics/kube-state-metrics.libsonnet
@@ -1,138 +1,133 @@
-local kubeRbacProxyContainer = import '../kube-rbac-proxy/containerMixin.libsonnet';
-local ksm = import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics/kube-state-metrics.libsonnet';
+local krp = (import '../kube-rbac-proxy/container.libsonnet');
 
-{
-  _config+:: {
-    versions+:: {
-      kubeStateMetrics: '1.9.7',
-    },
-    imageRepos+:: {
-      kubeStateMetrics: 'quay.io/coreos/kube-state-metrics',
-    },
-    kubeStateMetrics+:: {
-      scrapeInterval: '30s',
-      scrapeTimeout: '30s',
-      labels: {
-        'app.kubernetes.io/name': 'kube-state-metrics',
-        'app.kubernetes.io/version': $._config.versions.kubeStateMetrics,
-        'app.kubernetes.io/component': 'exporter',
-        'app.kubernetes.io/part-of': 'kube-prometheus',
-      },
-      selectorLabels: {
-        [labelName]: $._config.kubeStateMetrics.labels[labelName]
-        for labelName in std.objectFields($._config.kubeStateMetrics.labels)
-        if !std.setMember(labelName, ['app.kubernetes.io/version'])
-      },
+local defaults = {
+  local defaults = self,
+  namespace: error 'must provide namespace',
+  version: error 'must provide version',
+  image: error 'must provide version',
+  resources: {
+    requests: { cpu: '10m', memory: '190Mi' },
+    limits: { cpu: '100m', memory: '250Mi' },
+  },
+
+  scrapeInterval: '30s',
+  scrapeTimeout: '30s',
+  commonLabels:: {
+    'app.kubernetes.io/name': 'kube-state-metrics',
+    'app.kubernetes.io/version': defaults.version,
+    'app.kubernetes.io/component': 'exporter',
+    'app.kubernetes.io/part-of': 'kube-prometheus',
+  },
+  selectorLabels:: {
+    [labelName]: defaults.commonLabels[labelName]
+    for labelName in std.objectFields(defaults.commonLabels)
+    if !std.setMember(labelName, ['app.kubernetes.io/version'])
+  },
+};
+
+function(params) (import 'github.com/kubernetes/kube-state-metrics/jsonnet/kube-state-metrics/kube-state-metrics.libsonnet') {
+  local ksm = self,
+  config:: defaults + params,
+  // Safety check
+  assert std.isObject(ksm.config.resources),
+
+  name:: 'kube-state-metrics',
+  namespace:: ksm.config.namespace,
+  version:: ksm.config.version,
+  image:: ksm.config.image,
+  commonLabels:: ksm.config.commonLabels,
+  podLabels:: ksm.config.selectorLabels,
+
+  service+: {
+    spec+: {
+      ports: [
+        {
+          name: 'https-main',
+          port: 8443,
+          targetPort: 'https-main',
+        },
+        {
+          name: 'https-self',
+          port: 9443,
+          targetPort: 'https-self',
+        },
+      ],
     },
   },
-  kubeStateMetrics+::
-    ksm {
-      local version = self.version,
-      name:: 'kube-state-metrics',
-      namespace:: $._config.namespace,
-      version:: $._config.versions.kubeStateMetrics,
-      image:: $._config.imageRepos.kubeStateMetrics + ':v' + $._config.versions.kubeStateMetrics,
-      commonLabels:: $._config.kubeStateMetrics.labels,
-      podLabels:: $._config.kubeStateMetrics.selectorLabels,
-      service+: {
+
+  local kubeRbacProxyMain = krp({
+    name: 'kube-rbac-proxy-main',
+    upstream: 'http://127.0.0.1:8081/',
+    secureListenAddress: ':8443',
+    ports: [
+      { name: 'https-main', containerPort: 8443,  },
+    ],
+  }),
+
+  local kubeRbacProxySelf = krp({
+    name: 'kube-rbac-proxy-self',
+    upstream: 'http://127.0.0.1:8082/',
+    secureListenAddress: ':9443',
+    ports: [
+      { name: 'https-self', containerPort: 9443,  },
+    ],
+  }),
+
+  deployment+: {
+    spec+: {
+      template+: {
         spec+: {
-          ports: [
-            {
-              name: 'https-main',
-              port: 8443,
-              targetPort: 'https-main',
-            },
-            {
-              name: 'https-self',
-              port: 9443,
-              targetPort: 'https-self',
-            },
-          ],
+          containers: std.map(function(c) c {
+            ports:: null,
+            livenessProbe:: null,
+            readinessProbe:: null,
+            args: ['--host=127.0.0.1', '--port=8081', '--telemetry-host=127.0.0.1', '--telemetry-port=8082'],
+            resources: ksm.config.resources,
+          }, super.containers) + [kubeRbacProxyMain, kubeRbacProxySelf],
         },
       },
-      deployment+: {
-        spec+: {
-          template+: {
-            spec+: {
-              containers: std.map(function(c) c {
-                ports:: null,
-                livenessProbe:: null,
-                readinessProbe:: null,
-                args: ['--host=127.0.0.1', '--port=8081', '--telemetry-host=127.0.0.1', '--telemetry-port=8082'],
-              }, super.containers),
-            },
-          },
-        },
+    },
+  },
+  serviceMonitor:
+    {
+      apiVersion: 'monitoring.coreos.com/v1',
+      kind: 'ServiceMonitor',
+      metadata: {
+        name: ksm.name,
+        namespace: ksm.config.namespace,
+        labels: ksm.config.commonLabels,
       },
-      serviceMonitor:
-        {
-          apiVersion: 'monitoring.coreos.com/v1',
-          kind: 'ServiceMonitor',
-          metadata: {
-            name: 'kube-state-metrics',
-            namespace: $._config.namespace,
-            labels: $._config.kubeStateMetrics.labels,
-          },
-          spec: {
-            jobLabel: 'app.kubernetes.io/name',
-            selector: { matchLabels: $._config.kubeStateMetrics.selectorLabels },
-            endpoints: [
-              {
-                port: 'https-main',
-                scheme: 'https',
-                interval: $._config.kubeStateMetrics.scrapeInterval,
-                scrapeTimeout: $._config.kubeStateMetrics.scrapeTimeout,
-                honorLabels: true,
-                bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
-                relabelings: [
-                  {
-                    regex: '(pod|service|endpoint|namespace)',
-                    action: 'labeldrop',
-                  },
-                ],
-                tlsConfig: {
-                  insecureSkipVerify: true,
-                },
-              },
+      spec: {
+        jobLabel: 'app.kubernetes.io/name',
+        selector: { matchLabels: ksm.config.selectorLabels },
+        endpoints: [
+          {
+            port: 'https-main',
+            scheme: 'https',
+            interval: ksm.config.scrapeInterval,
+            scrapeTimeout: ksm.config.scrapeTimeout,
+            honorLabels: true,
+            bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
+            relabelings: [
               {
-                port: 'https-self',
-                scheme: 'https',
-                interval: $._config.kubeStateMetrics.scrapeInterval,
-                bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
-                tlsConfig: {
-                  insecureSkipVerify: true,
-                },
+                regex: '(pod|service|endpoint|namespace)',
+                action: 'labeldrop',
               },
             ],
+            tlsConfig: {
+              insecureSkipVerify: true,
+            },
           },
-        },
-    } +
-    (kubeRbacProxyContainer {
-       config+:: {
-         kubeRbacProxy: {
-           local cfg = self,
-           image: $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy,
-           name: 'kube-rbac-proxy-main',
-           securePortName: 'https-main',
-           securePort: 8443,
-           secureListenAddress: ':%d' % self.securePort,
-           upstream: 'http://127.0.0.1:8081/',
-           tlsCipherSuites: $._config.tlsCipherSuites,
-         },
-       },
-     }).deploymentMixin +
-    (kubeRbacProxyContainer {
-       config+:: {
-         kubeRbacProxy: {
-           local cfg = self,
-           image: $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy,
-           name: 'kube-rbac-proxy-self',
-           securePortName: 'https-self',
-           securePort: 9443,
-           secureListenAddress: ':%d' % self.securePort,
-           upstream: 'http://127.0.0.1:8082/',
-           tlsCipherSuites: $._config.tlsCipherSuites,
-         },
-       },
-     }).deploymentMixin,
+          {
+            port: 'https-self',
+            scheme: 'https',
+            interval: ksm.config.scrapeInterval,
+            bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
+            tlsConfig: {
+              insecureSkipVerify: true,
+            },
+          },
+        ],
+      },
+    },
 }
diff --git a/manifests/kube-state-metrics-deployment.yaml b/manifests/kube-state-metrics-deployment.yaml
index ab50e622f6b4690c4a0cb83f568e58fc3e70a56e..8c36bc6257381b90e7cc61ac0611983d037d8f26 100644
--- a/manifests/kube-state-metrics-deployment.yaml
+++ b/manifests/kube-state-metrics-deployment.yaml
@@ -31,6 +31,13 @@ spec:
         - --telemetry-port=8082
         image: quay.io/coreos/kube-state-metrics:v1.9.7
         name: kube-state-metrics
+        resources:
+          limits:
+            cpu: 100m
+            memory: 250Mi
+          requests:
+            cpu: 10m
+            memory: 190Mi
       - args:
         - --logtostderr
         - --secure-listen-address=:8443
@@ -41,6 +48,13 @@ spec:
         ports:
         - containerPort: 8443
           name: https-main
+        resources:
+          limits:
+            cpu: 20m
+            memory: 40Mi
+          requests:
+            cpu: 10m
+            memory: 20Mi
         securityContext:
           runAsGroup: 65532
           runAsNonRoot: true
@@ -55,6 +69,13 @@ spec:
         ports:
         - containerPort: 9443
           name: https-self
+        resources:
+          limits:
+            cpu: 20m
+            memory: 40Mi
+          requests:
+            cpu: 10m
+            memory: 20Mi
         securityContext:
           runAsGroup: 65532
           runAsNonRoot: true