kube-prometheus/jsonnet: Use jsonnet-bundler
This commit is contained in:
1 parent
992bcdccc1
commit
edf21e4382
141 files changed
+11503
-7217
No files matched your search
@@ -0,0 +1,2 @@
|
||||
jsonnetfile.lock.json
|
||||
vendor/
|
||||
@@ -0,0 +1,97 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
local alertmanagerConfig = "\nglobal:\n resolve_timeout: 5m\nroute:\n group_by: ['job']\n group_wait: 30s\n group_interval: 5m\n repeat_interval: 12h\n receiver: 'null'\n routes:\n - match:\n alertname: DeadMansSwitch\n receiver: 'null'\nreceivers:\n- name: 'null'\n";
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
alertmanager: 'v0.14.0',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
alertmanager: 'quay.io/prometheus/alertmanager',
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
config: alertmanagerConfig,
|
||||
replicas: 3,
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager+:: {
|
||||
secret:
|
||||
local secret = k.core.v1.secret;
|
||||
|
||||
secret.new('alertmanager-main', { 'alertmanager.yaml': std.base64($._config.alertmanager.config) }) +
|
||||
secret.mixin.metadata.withNamespace($._config.namespace),
|
||||
|
||||
serviceAccount:
|
||||
local serviceAccount = k.core.v1.serviceAccount;
|
||||
|
||||
serviceAccount.new('alertmanager-main') +
|
||||
serviceAccount.mixin.metadata.withNamespace($._config.namespace),
|
||||
|
||||
service:
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
local alertmanagerPort = servicePort.newNamed('web', 9093, 'web');
|
||||
|
||||
service.new('alertmanager-main', { app: 'alertmanager', alertmanager: 'main' }, alertmanagerPort) +
|
||||
service.mixin.metadata.withNamespace($._config.namespace) +
|
||||
service.mixin.metadata.withLabels({ alertmanager: 'main' }),
|
||||
|
||||
serviceMonitor:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'alertmanager',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'alertmanager',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
alertmanager: 'main',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'monitoring',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'web',
|
||||
interval: '30s',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
alertmanager:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'Alertmanager',
|
||||
metadata: {
|
||||
name: 'main',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
alertmanager: 'main',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
replicas: $._config.alertmanager.replicas,
|
||||
version: $._config.versions.alertmanager,
|
||||
baseImage: $._config.imageRepos.alertmanager,
|
||||
nodeSelector: { 'beta.kubernetes.io/os': 'linux' },
|
||||
serviceAccountName: 'alertmanager-main',
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"dependencies": [
|
||||
{
|
||||
"name": "ksonnet",
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/ksonnet/ksonnet-lib",
|
||||
"subdir": ""
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
},
|
||||
{
|
||||
"name": "kubernetes-mixin",
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/kubernetes-monitoring/kubernetes-mixin",
|
||||
"subdir": ""
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
},
|
||||
{
|
||||
"name": "grafana",
|
||||
"source": {
|
||||
"git": {
|
||||
"remote": "https://github.com/brancz/kubernetes-grafana",
|
||||
"subdir": "grafana"
|
||||
}
|
||||
},
|
||||
"version": "master"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
{
|
||||
prometheus+:: {
|
||||
kubeControllerManagerPrometheusDiscoveryService:
|
||||
service.new('kube-controller-manager-prometheus-discovery', { 'k8s-app': 'kube-controller-manager' }, servicePort.newNamed('http-metrics', 10252, 10252)) +
|
||||
service.mixin.metadata.withNamespace('kube-system') +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-controller-manager' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
kubeSchedulerPrometheusDiscoveryService:
|
||||
service.new('kube-scheduler-prometheus-discovery', { 'k8s-app': 'kube-scheduler' }, servicePort.newNamed('http-metrics', 10251, 10251)) +
|
||||
service.mixin.metadata.withNamespace('kube-system') +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-scheduler' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
kubeDnsPrometheusDiscoveryService:
|
||||
service.new('kube-dns-prometheus-discovery', { 'k8s-app': 'kube-dns' }, [servicePort.newNamed('http-metrics-skydns', 10055, 10055), servicePort.newNamed('http-metrics-dnsmasq', 10054, 10054)]) +
|
||||
service.mixin.metadata.withNamespace('kube-system') +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-dns' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
local kp = (import 'kube-prometheus/kube-prometheus.libsonnet');
|
||||
|
||||
{ ['0prometheus-operator-' + name]: kp.prometheusOperator[name] for name in std.objectFields(kp.prometheusOperator) } +
|
||||
{ ['node-exporter-' + name]: kp.nodeExporter[name] for name in std.objectFields(kp.nodeExporter) } +
|
||||
{ ['kube-state-metrics-' + name]: kp.kubeStateMetrics[name] for name in std.objectFields(kp.kubeStateMetrics) } +
|
||||
{ ['alertmanager-' + name]: kp.alertmanager[name] for name in std.objectFields(kp.alertmanager) } +
|
||||
{ ['prometheus-' + name]: kp.prometheus[name] for name in std.objectFields(kp.prometheus) } +
|
||||
{ ['grafana-' + name]: kp.grafana[name] for name in std.objectFields(kp.grafana) }
|
||||
@@ -0,0 +1,18 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
{
|
||||
prometheus+: {
|
||||
kubeControllerManagerPrometheusDiscoveryService:
|
||||
service.new('kube-controller-manager-prometheus-discovery', { component: 'kube-controller-manager' }, servicePort.newNamed('http-metrics', 10252, 10252)) +
|
||||
service.mixin.metadata.withNamespace('kube-system') +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-controller-manager' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
kubeSchedulerPrometheusDiscoveryService:
|
||||
service.new('kube-scheduler-prometheus-discovery', { component: 'kube-scheduler' }, servicePort.newNamed('http-metrics', 10251, 10251)) +
|
||||
service.mixin.metadata.withNamespace('kube-system') +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-scheduler' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
{
|
||||
prometheus+: {
|
||||
service+:
|
||||
service.mixin.spec.withPorts(servicePort.newNamed('web', 9090, 'web') + servicePort.withNodePort(30900)) +
|
||||
service.mixin.spec.withType('NodePort'),
|
||||
},
|
||||
alertmanager+: {
|
||||
service+:
|
||||
service.mixin.spec.withPorts(servicePort.newNamed('web', 9093, 'web') + servicePort.withNodePort(30903)) +
|
||||
service.mixin.spec.withType('NodePort'),
|
||||
},
|
||||
grafana+: {
|
||||
service+:
|
||||
service.mixin.spec.withPorts(servicePort.newNamed('http', 3000, 'http') + servicePort.withNodePort(30902)) +
|
||||
service.mixin.spec.withType('NodePort'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
(import 'grafana/grafana.libsonnet') +
|
||||
(import 'kube-state-metrics/kube-state-metrics.libsonnet') +
|
||||
(import 'node-exporter/node-exporter.libsonnet') +
|
||||
(import 'alertmanager/alertmanager.libsonnet') +
|
||||
(import 'prometheus-operator/prometheus-operator.libsonnet') +
|
||||
(import 'prometheus/prometheus.libsonnet') +
|
||||
(import 'kubernetes-mixin/mixin.libsonnet') +
|
||||
{
|
||||
_config+:: {
|
||||
kubeStateMetricsSelector: 'job="kube-state-metrics"',
|
||||
cadvisorSelector: 'job="kubelet"',
|
||||
nodeExporterSelector: 'job="node-exporter"',
|
||||
kubeletSelector: 'job="kubelet"',
|
||||
notKubeDnsSelector: 'job!="kube-dns"',
|
||||
|
||||
prometheus+:: {
|
||||
rules: $.prometheusRules + $.prometheusAlerts,
|
||||
},
|
||||
|
||||
grafana+:: {
|
||||
dashboards: $.grafanaDashboards,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,286 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
kubeStateMetrics: 'v1.3.0',
|
||||
kubeRbacProxy: 'v0.3.0',
|
||||
addonResizer: '1.0',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
kubeStateMetrics: 'quay.io/coreos/kube-state-metrics',
|
||||
kubeRbacProxy: 'quay.io/coreos/kube-rbac-proxy',
|
||||
addonResizer: 'quay.io/coreos/addon-resizer',
|
||||
},
|
||||
},
|
||||
|
||||
kubeStateMetrics+:: {
|
||||
clusterRoleBinding:
|
||||
local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
|
||||
|
||||
clusterRoleBinding.new() +
|
||||
clusterRoleBinding.mixin.metadata.withName('kube-state-metrics') +
|
||||
clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
clusterRoleBinding.mixin.roleRef.withName('kube-state-metrics') +
|
||||
clusterRoleBinding.mixin.roleRef.mixinInstance({ kind: 'ClusterRole' }) +
|
||||
clusterRoleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'kube-state-metrics', namespace: $._config.namespace }]),
|
||||
|
||||
clusterRole:
|
||||
local clusterRole = k.rbac.v1.clusterRole;
|
||||
local policyRule = clusterRole.rulesType;
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'configmaps',
|
||||
'secrets',
|
||||
'nodes',
|
||||
'pods',
|
||||
'services',
|
||||
'resourcequotas',
|
||||
'replicationcontrollers',
|
||||
'limitranges',
|
||||
'persistentvolumeclaims',
|
||||
'persistentvolumes',
|
||||
'namespaces',
|
||||
'endpoints',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local extensionsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['extensions']) +
|
||||
policyRule.withResources([
|
||||
'daemonsets',
|
||||
'deployments',
|
||||
'replicasets',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local appsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['apps']) +
|
||||
policyRule.withResources([
|
||||
'statefulsets',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local batchRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['batch']) +
|
||||
policyRule.withResources([
|
||||
'cronjobs',
|
||||
'jobs',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local autoscalingRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['autoscaling']) +
|
||||
policyRule.withResources([
|
||||
'horizontalpodautoscalers',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local authenticationRole = policyRule.new() +
|
||||
policyRule.withApiGroups(['authentication.k8s.io']) +
|
||||
policyRule.withResources([
|
||||
'tokenreviews',
|
||||
]) +
|
||||
policyRule.withVerbs(['create']);
|
||||
|
||||
local authorizationRole = policyRule.new() +
|
||||
policyRule.withApiGroups(['authorization.k8s.io']) +
|
||||
policyRule.withResources([
|
||||
'subjectaccessreviews',
|
||||
]) +
|
||||
policyRule.withVerbs(['create']);
|
||||
|
||||
local rules = [coreRule, extensionsRule, appsRule, batchRule, autoscalingRule, authenticationRole, authorizationRole];
|
||||
|
||||
clusterRole.new() +
|
||||
clusterRole.mixin.metadata.withName('kube-state-metrics') +
|
||||
clusterRole.withRules(rules),
|
||||
deployment:
|
||||
local deployment = k.apps.v1beta2.deployment;
|
||||
local container = k.apps.v1beta2.deployment.mixin.spec.template.spec.containersType;
|
||||
local volume = k.apps.v1beta2.deployment.mixin.spec.template.spec.volumesType;
|
||||
local containerPort = container.portsType;
|
||||
local containerVolumeMount = container.volumeMountsType;
|
||||
local podSelector = deployment.mixin.spec.template.spec.selectorType;
|
||||
|
||||
local podLabels = { app: 'kube-state-metrics' };
|
||||
|
||||
local proxyClusterMetrics =
|
||||
container.new('kube-rbac-proxy-main', $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy) +
|
||||
container.withArgs([
|
||||
'--secure-listen-address=:8443',
|
||||
'--upstream=http://127.0.0.1:8081/',
|
||||
]) +
|
||||
container.withPorts(containerPort.newNamed('https-main', 8443)) +
|
||||
container.mixin.resources.withRequests({ cpu: '10m', memory: '20Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '20m', memory: '40Mi' });
|
||||
|
||||
local proxySelfMetrics =
|
||||
container.new('kube-rbac-proxy-self', $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy) +
|
||||
container.withArgs([
|
||||
'--secure-listen-address=:9443',
|
||||
'--upstream=http://127.0.0.1:8082/',
|
||||
]) +
|
||||
container.withPorts(containerPort.newNamed('https-self', 9443)) +
|
||||
container.mixin.resources.withRequests({ cpu: '10m', memory: '20Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '20m', memory: '40Mi' });
|
||||
|
||||
local kubeStateMetrics =
|
||||
container.new('kube-state-metrics', $._config.imageRepos.kubeStateMetrics + ':' + $._config.versions.kubeStateMetrics) +
|
||||
container.withArgs([
|
||||
'--host=127.0.0.1',
|
||||
'--port=8081',
|
||||
'--telemetry-host=127.0.0.1',
|
||||
'--telemetry-port=8082',
|
||||
]) +
|
||||
container.mixin.resources.withRequests({ cpu: '102m', memory: '180Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '102m', memory: '180Mi' });
|
||||
|
||||
local addonResizer =
|
||||
container.new('addon-resizer', $._config.imageRepos.addonResizer + ':' + $._config.versions.addonResizer) +
|
||||
container.withCommand([
|
||||
'/pod_nanny',
|
||||
'--container=kube-state-metrics',
|
||||
'--cpu=100m',
|
||||
'--extra-cpu=2m',
|
||||
'--memory=150Mi',
|
||||
'--extra-memory=30Mi',
|
||||
'--threshold=5',
|
||||
'--deployment=kube-state-metrics',
|
||||
]) +
|
||||
container.withEnv([
|
||||
{
|
||||
name: 'MY_POD_NAME',
|
||||
valueFrom: {
|
||||
fieldRef: { apiVersion: 'v1', fieldPath: 'metadata.name' },
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'MY_POD_NAMESPACE',
|
||||
valueFrom: {
|
||||
fieldRef: { apiVersion: 'v1', fieldPath: 'metadata.namespace' },
|
||||
},
|
||||
},
|
||||
]) +
|
||||
container.mixin.resources.withRequests({ cpu: '10m', memory: '30Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '10m', memory: '30Mi' });
|
||||
|
||||
local c = [proxyClusterMetrics, proxySelfMetrics, kubeStateMetrics, addonResizer];
|
||||
|
||||
deployment.new('kube-state-metrics', 1, c, podLabels) +
|
||||
deployment.mixin.metadata.withNamespace($._config.namespace) +
|
||||
deployment.mixin.metadata.withLabels(podLabels) +
|
||||
deployment.mixin.spec.selector.withMatchLabels(podLabels) +
|
||||
deployment.mixin.spec.template.spec.withNodeSelector({ 'beta.kubernetes.io/os': 'linux' }) +
|
||||
deployment.mixin.spec.template.spec.securityContext.withRunAsNonRoot(true) +
|
||||
deployment.mixin.spec.template.spec.securityContext.withRunAsUser(65534) +
|
||||
deployment.mixin.spec.template.spec.withServiceAccountName('kube-state-metrics'),
|
||||
|
||||
roleBinding:
|
||||
local roleBinding = k.rbac.v1.roleBinding;
|
||||
|
||||
roleBinding.new() +
|
||||
roleBinding.mixin.metadata.withName('kube-state-metrics') +
|
||||
roleBinding.mixin.metadata.withNamespace($._config.namespace) +
|
||||
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
roleBinding.mixin.roleRef.withName('kube-state-metrics') +
|
||||
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
|
||||
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'kube-state-metrics' }]),
|
||||
|
||||
role:
|
||||
local role = k.rbac.v1.role;
|
||||
local policyRule = role.rulesType;
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'pods',
|
||||
]) +
|
||||
policyRule.withVerbs(['get']);
|
||||
|
||||
local extensionsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['extensions']) +
|
||||
policyRule.withResources([
|
||||
'deployments',
|
||||
]) +
|
||||
policyRule.withVerbs(['get', 'update']) +
|
||||
policyRule.withResourceNames(['kube-state-metrics']);
|
||||
|
||||
local rules = [coreRule, extensionsRule];
|
||||
|
||||
role.new() +
|
||||
role.mixin.metadata.withName('kube-state-metrics') +
|
||||
role.mixin.metadata.withNamespace($._config.namespace) +
|
||||
role.withRules(rules),
|
||||
|
||||
serviceAccount:
|
||||
local serviceAccount = k.core.v1.serviceAccount;
|
||||
|
||||
serviceAccount.new('kube-state-metrics') +
|
||||
serviceAccount.mixin.metadata.withNamespace($._config.namespace),
|
||||
|
||||
service:
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
local ksmServicePortMain = servicePort.newNamed('https-main', 8443, 'https-main');
|
||||
local ksmServicePortSelf = servicePort.newNamed('https-self', 9443, 'https-self');
|
||||
|
||||
service.new('kube-state-metrics', $.kubeStateMetrics.deployment.spec.selector.matchLabels, [ksmServicePortMain, ksmServicePortSelf]) +
|
||||
service.mixin.metadata.withNamespace($._config.namespace) +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'kube-state-metrics' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
|
||||
serviceMonitor:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-state-metrics',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'kube-state-metrics',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'kube-state-metrics',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'monitoring',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https-main',
|
||||
scheme: 'https',
|
||||
interval: '30s',
|
||||
honorLabels: true,
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
port: 'https-self',
|
||||
scheme: 'https',
|
||||
interval: '30s',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
nodeExporter: 'v0.15.2',
|
||||
kubeRbacProxy: 'v0.3.0',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
nodeExporter: 'quay.io/prometheus/node-exporter',
|
||||
kubeRbacProxy: 'quay.io/coreos/kube-rbac-proxy',
|
||||
},
|
||||
},
|
||||
|
||||
nodeExporter+:: {
|
||||
clusterRoleBinding:
|
||||
local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
|
||||
|
||||
clusterRoleBinding.new() +
|
||||
clusterRoleBinding.mixin.metadata.withName('node-exporter') +
|
||||
clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
clusterRoleBinding.mixin.roleRef.withName('node-exporter') +
|
||||
clusterRoleBinding.mixin.roleRef.mixinInstance({ kind: 'ClusterRole' }) +
|
||||
clusterRoleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'node-exporter', namespace: $._config.namespace }]),
|
||||
|
||||
clusterRole:
|
||||
local clusterRole = k.rbac.v1.clusterRole;
|
||||
local policyRule = clusterRole.rulesType;
|
||||
|
||||
local authenticationRole = policyRule.new() +
|
||||
policyRule.withApiGroups(['authentication.k8s.io']) +
|
||||
policyRule.withResources([
|
||||
'tokenreviews',
|
||||
]) +
|
||||
policyRule.withVerbs(['create']);
|
||||
|
||||
local authorizationRole = policyRule.new() +
|
||||
policyRule.withApiGroups(['authorization.k8s.io']) +
|
||||
policyRule.withResources([
|
||||
'subjectaccessreviews',
|
||||
]) +
|
||||
policyRule.withVerbs(['create']);
|
||||
|
||||
local rules = [authenticationRole, authorizationRole];
|
||||
|
||||
clusterRole.new() +
|
||||
clusterRole.mixin.metadata.withName('node-exporter') +
|
||||
clusterRole.withRules(rules),
|
||||
|
||||
daemonset:
|
||||
local daemonset = k.apps.v1beta2.daemonSet;
|
||||
local container = daemonset.mixin.spec.template.spec.containersType;
|
||||
local volume = daemonset.mixin.spec.template.spec.volumesType;
|
||||
local containerPort = container.portsType;
|
||||
local containerVolumeMount = container.volumeMountsType;
|
||||
local podSelector = daemonset.mixin.spec.template.spec.selectorType;
|
||||
local toleration = daemonset.mixin.spec.template.spec.tolerationsType;
|
||||
|
||||
local podLabels = { app: 'node-exporter' };
|
||||
|
||||
local masterToleration = toleration.new() +
|
||||
toleration.withEffect('NoSchedule') +
|
||||
toleration.withKey('node-role.kubernetes.io/master');
|
||||
|
||||
local procVolumeName = 'proc';
|
||||
local procVolume = volume.fromHostPath(procVolumeName, '/proc');
|
||||
local procVolumeMount = containerVolumeMount.new(procVolumeName, '/host/proc');
|
||||
|
||||
local sysVolumeName = 'sys';
|
||||
local sysVolume = volume.fromHostPath(sysVolumeName, '/sys');
|
||||
local sysVolumeMount = containerVolumeMount.new(sysVolumeName, '/host/sys');
|
||||
|
||||
local nodeExporter =
|
||||
container.new('node-exporter', $._config.imageRepos.nodeExporter + ':' + $._config.versions.nodeExporter) +
|
||||
container.withArgs([
|
||||
'--web.listen-address=127.0.0.1:9101',
|
||||
'--path.procfs=/host/proc',
|
||||
'--path.sysfs=/host/sys',
|
||||
]) +
|
||||
container.withVolumeMounts([procVolumeMount, sysVolumeMount]) +
|
||||
container.mixin.resources.withRequests({ cpu: '102m', memory: '180Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '102m', memory: '180Mi' });
|
||||
|
||||
local proxy =
|
||||
container.new('kube-rbac-proxy', $._config.imageRepos.kubeRbacProxy + ':' + $._config.versions.kubeRbacProxy) +
|
||||
container.withArgs([
|
||||
'--secure-listen-address=:9100',
|
||||
'--upstream=http://127.0.0.1:9101/',
|
||||
]) +
|
||||
container.withPorts(containerPort.newNamed('https', 9100)) +
|
||||
container.mixin.resources.withRequests({ cpu: '10m', memory: '20Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '20m', memory: '40Mi' });
|
||||
|
||||
local c = [nodeExporter, proxy];
|
||||
|
||||
daemonset.new() +
|
||||
daemonset.mixin.metadata.withName('node-exporter') +
|
||||
daemonset.mixin.metadata.withNamespace($._config.namespace) +
|
||||
daemonset.mixin.metadata.withLabels(podLabels) +
|
||||
daemonset.mixin.spec.selector.withMatchLabels(podLabels) +
|
||||
daemonset.mixin.spec.template.metadata.withLabels(podLabels) +
|
||||
daemonset.mixin.spec.template.spec.withTolerations([masterToleration]) +
|
||||
daemonset.mixin.spec.template.spec.withNodeSelector({ 'beta.kubernetes.io/os': 'linux' }) +
|
||||
daemonset.mixin.spec.template.spec.withContainers(c) +
|
||||
daemonset.mixin.spec.template.spec.withVolumes([procVolume, sysVolume]) +
|
||||
daemonset.mixin.spec.template.spec.securityContext.withRunAsNonRoot(true) +
|
||||
daemonset.mixin.spec.template.spec.securityContext.withRunAsUser(65534) +
|
||||
daemonset.mixin.spec.template.spec.withServiceAccountName('node-exporter'),
|
||||
|
||||
serviceAccount:
|
||||
local serviceAccount = k.core.v1.serviceAccount;
|
||||
|
||||
serviceAccount.new('node-exporter') +
|
||||
serviceAccount.mixin.metadata.withNamespace($._config.namespace),
|
||||
|
||||
serviceMonitor:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'node-exporter',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'node-exporter',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'node-exporter',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'monitoring',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https',
|
||||
scheme: 'https',
|
||||
interval: '30s',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
|
||||
service:
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
local nodeExporterPort = servicePort.newNamed('https', 9100, 'https');
|
||||
|
||||
service.new('node-exporter', $.nodeExporter.daemonset.spec.selector.matchLabels, nodeExporterPort) +
|
||||
service.mixin.metadata.withNamespace($._config.namespace) +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'node-exporter' }) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"CustomResourceDefinition","metadata":{"creationTimestamp":null,"name":"alertmanagers.monitoring.coreos.com"},"spec":{"group":"monitoring.coreos.com","names":{"kind":"Alertmanager","plural":"alertmanagers"},"scope":"Namespaced","validation":{"openAPIV3Schema":{"description":"Describes an Alertmanager cluster.","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds","type":"string"},"spec":{"description":"Specification of the desired behavior of the Alertmanager cluster. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status","properties":{"affinity":{"description":"Affinity is a group of affinity scheduling rules.","properties":{"nodeAffinity":{"description":"Node affinity is a group of node affinity scheduling rules.","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"description":"The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding \"weight\" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.","items":{"description":"An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).","properties":{"preference":{"description":"A null or empty node selector term matches no objects.","properties":{"matchExpressions":{"description":"Required. A list of node selector requirements. The requirements are ANDed.","items":{"description":"A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.","properties":{"key":{"description":"The label key that the selector applies to.","type":"string"},"operator":{"description":"Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.","type":"string"},"values":{"description":"An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.","items":{"type":"string"},"type":"array"}},"required":["key","operator"]},"type":"array"}},"required":["matchExpressions"]},"weight":{"description":"Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.","format":"int32","type":"integer"}},"required":["weight","preference"]},"type":"array"},"requiredDuringSchedulingIgnoredDuringExecution":{"description":"A node selector represents the union of the results of one or more label queries over a set of nodes; that is, it represents the OR of the selectors represented by the node selector terms.","properties":{"nodeSelectorTerms":{"description":"Required. A list of node selector terms. The terms are ORed.","items":{"description":"A null or empty node selector term matches no objects.","properties":{"matchExpressions":{"description":"Required. A list of node selector requirements. The requirements are ANDed.","items":{"description":"A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.","properties":{"key":{"description":"The label key that the selector applies to.","type":"string"},"operator":{"description":"Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.","type":"string"},"values":{"description":"An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.","items":{"type":"string"Line truncated
|
||||
@@ -0,0 +1 @@
|
||||
{"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"CustomResourceDefinition","metadata":{"creationTimestamp":null,"name":"prometheuses.monitoring.coreos.com"},"spec":{"group":"monitoring.coreos.com","names":{"kind":"Prometheus","plural":"prometheuses"},"scope":"Namespaced","validation":{"openAPIV3Schema":{"description":"Prometheus defines a Prometheus deployment.","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds","type":"string"},"spec":{"description":"Specification of the desired behavior of the Prometheus cluster. More info: https://github.com/kubernetes/community/blob/master/contributors/devel/api-conventions.md#spec-and-status","properties":{"additionalScrapeConfigs":{"description":"SecretKeySelector selects a key of a Secret.","properties":{"key":{"description":"The key of the secret to select from. Must be a valid secret key.","type":"string"},"name":{"description":"Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names","type":"string"},"optional":{"description":"Specify whether the Secret or it's key must be defined","type":"boolean"}},"required":["key"]},"affinity":{"description":"Affinity is a group of affinity scheduling rules.","properties":{"nodeAffinity":{"description":"Node affinity is a group of node affinity scheduling rules.","properties":{"preferredDuringSchedulingIgnoredDuringExecution":{"description":"The scheduler will prefer to schedule pods to nodes that satisfy the affinity expressions specified by this field, but it may choose a node that violates one or more of the expressions. The node that is most preferred is the one with the greatest sum of weights, i.e. for each node that meets all of the scheduling requirements (resource request, requiredDuringScheduling affinity expressions, etc.), compute a sum by iterating through the elements of this field and adding \"weight\" to the sum if the node matches the corresponding matchExpressions; the node(s) with the highest sum are the most preferred.","items":{"description":"An empty preferred scheduling term matches all objects with implicit weight 0 (i.e. it's a no-op). A null preferred scheduling term matches no objects (i.e. is also a no-op).","properties":{"preference":{"description":"A null or empty node selector term matches no objects.","properties":{"matchExpressions":{"description":"Required. A list of node selector requirements. The requirements are ANDed.","items":{"description":"A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.","properties":{"key":{"description":"The label key that the selector applies to.","type":"string"},"operator":{"description":"Represents a key's relationship to a set of values. Valid operators are In, NotIn, Exists, DoesNotExist. Gt, and Lt.","type":"string"},"values":{"description":"An array of string values. If the operator is In or NotIn, the values array must be non-empty. If the operator is Exists or DoesNotExist, the values array must be empty. If the operator is Gt or Lt, the values array must have a single element, which will be interpreted as an integer. This array is replaced during a strategic merge patch.","items":{"type":"string"},"type":"array"}},"required":["key","operator"]},"type":"array"}},"required":["matchExpressions"]},"weight":{"description":"Weight associated with matching the corresponding nodeSelectorTerm, in the range 1-100.","format":"int32","type":"integer"}},"required":["weight","preference"]},"type":"array"},"requiredDuringSchedulingIgnoredDuringExecution":{"description":"A node selector represents the union of the results of one or more label queries over a set of nodes; that is, it represents the OR of the selectors represented by the node selector terms.","properties":{"nodeSelectorTerms":{"description":"Required. A list of node selector terms. The terms are ORed.","items":{"description":"A null or empty node selector term matches no objects.","properties":{"matchExpressions":{"description":"Required. A list of node selector requirements. The requirements are ANDed.","items":{"description":"A node selector requirement is a selector that contains values, a key, and an operator that relates the key and values.","properties":{"key":{"description":"The label key that the selector applies to.","type":"string"},"operator":{"description":"Represents a key's relationship to a sLine truncated
|
||||
@@ -0,0 +1,152 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
prometheusOperator: 'v0.19.0',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
prometheusOperator: 'quay.io/coreos/prometheus-operator',
|
||||
},
|
||||
},
|
||||
|
||||
prometheusOperator+:: {
|
||||
// Prefixing with 0 to ensure these manifests are listed and therefore created first.
|
||||
'0alertmanagerCustomResourceDefinition': import 'alertmanager-crd.libsonnet',
|
||||
'0prometheusCustomResourceDefinition': import 'prometheus-crd.libsonnet',
|
||||
'0servicemonitorCustomResourceDefinition': import 'servicemonitor-crd.libsonnet',
|
||||
|
||||
clusterRoleBinding:
|
||||
local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
|
||||
|
||||
clusterRoleBinding.new() +
|
||||
clusterRoleBinding.mixin.metadata.withName('prometheus-operator') +
|
||||
clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
clusterRoleBinding.mixin.roleRef.withName('prometheus-operator') +
|
||||
clusterRoleBinding.mixin.roleRef.mixinInstance({ kind: 'ClusterRole' }) +
|
||||
clusterRoleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-operator', namespace: $._config.namespace }]),
|
||||
|
||||
clusterRole:
|
||||
local clusterRole = k.rbac.v1.clusterRole;
|
||||
local policyRule = clusterRole.rulesType;
|
||||
|
||||
local extensionsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['extensions']) +
|
||||
policyRule.withResources([
|
||||
'thirdpartyresources',
|
||||
]) +
|
||||
policyRule.withVerbs(['*']);
|
||||
|
||||
local apiExtensionsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['apiextensions.k8s.io']) +
|
||||
policyRule.withResources([
|
||||
'customresourcedefinitions',
|
||||
]) +
|
||||
policyRule.withVerbs(['*']);
|
||||
|
||||
local monitoringRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['monitoring.coreos.com']) +
|
||||
policyRule.withResources([
|
||||
'alertmanagers',
|
||||
'prometheuses',
|
||||
'prometheuses/finalizers',
|
||||
'alertmanagers/finalizers',
|
||||
'servicemonitors',
|
||||
]) +
|
||||
policyRule.withVerbs(['*']);
|
||||
|
||||
local appsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['apps']) +
|
||||
policyRule.withResources([
|
||||
'statefulsets',
|
||||
]) +
|
||||
policyRule.withVerbs(['*']);
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'configmaps',
|
||||
'secrets',
|
||||
]) +
|
||||
policyRule.withVerbs(['*']);
|
||||
|
||||
local podRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'pods',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'delete']);
|
||||
|
||||
local routingRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'services',
|
||||
'endpoints',
|
||||
]) +
|
||||
policyRule.withVerbs(['get', 'create', 'update']);
|
||||
|
||||
local nodeRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'nodes',
|
||||
]) +
|
||||
policyRule.withVerbs(['list', 'watch']);
|
||||
|
||||
local namespaceRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'namespaces',
|
||||
]) +
|
||||
policyRule.withVerbs(['list']);
|
||||
|
||||
local rules = [extensionsRule, apiExtensionsRule, monitoringRule, appsRule, coreRule, podRule, routingRule, nodeRule, namespaceRule];
|
||||
|
||||
clusterRole.new() +
|
||||
clusterRole.mixin.metadata.withName('prometheus-operator') +
|
||||
clusterRole.withRules(rules),
|
||||
|
||||
deployment:
|
||||
local deployment = k.apps.v1beta2.deployment;
|
||||
local container = k.apps.v1beta2.deployment.mixin.spec.template.spec.containersType;
|
||||
local containerPort = container.portsType;
|
||||
|
||||
local targetPort = 8080;
|
||||
local podLabels = { 'k8s-app': 'prometheus-operator' };
|
||||
|
||||
local operatorContainer =
|
||||
container.new('prometheus-operator', $._config.imageRepos.prometheusOperator + ':' + $._config.versions.prometheusOperator) +
|
||||
container.withPorts(containerPort.newNamed('http', targetPort)) +
|
||||
container.withArgs(['--kubelet-service=kube-system/kubelet', '--config-reloader-image=quay.io/coreos/configmap-reload:v0.0.1']) +
|
||||
container.mixin.resources.withRequests({ cpu: '100m', memory: '50Mi' }) +
|
||||
container.mixin.resources.withLimits({ cpu: '200m', memory: '100Mi' });
|
||||
|
||||
deployment.new('prometheus-operator', 1, operatorContainer, podLabels) +
|
||||
deployment.mixin.metadata.withNamespace($._config.namespace) +
|
||||
deployment.mixin.metadata.withLabels(podLabels) +
|
||||
deployment.mixin.spec.selector.withMatchLabels(podLabels) +
|
||||
deployment.mixin.spec.template.spec.withNodeSelector({ 'beta.kubernetes.io/os': 'linux' }) +
|
||||
deployment.mixin.spec.template.spec.securityContext.withRunAsNonRoot(true) +
|
||||
deployment.mixin.spec.template.spec.securityContext.withRunAsUser(65534) +
|
||||
deployment.mixin.spec.template.spec.withServiceAccountName('prometheus-operator'),
|
||||
|
||||
serviceAccount:
|
||||
local serviceAccount = k.core.v1.serviceAccount;
|
||||
|
||||
serviceAccount.new('prometheus-operator') +
|
||||
serviceAccount.mixin.metadata.withNamespace($._config.namespace),
|
||||
|
||||
service:
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
local poServicePort = servicePort.newNamed('http', 8080, 'http');
|
||||
|
||||
service.new('prometheus-operator', $.prometheusOperator.deployment.spec.selector.matchLabels, [poServicePort]) +
|
||||
service.mixin.metadata.withLabels({ 'k8s-app': 'prometheus-operator' }) +
|
||||
service.mixin.metadata.withNamespace($._config.namespace) +
|
||||
service.mixin.spec.withClusterIp('None'),
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
{"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"CustomResourceDefinition","metadata":{"creationTimestamp":null,"name":"servicemonitors.monitoring.coreos.com"},"spec":{"group":"monitoring.coreos.com","names":{"kind":"ServiceMonitor","plural":"servicemonitors"},"scope":"Namespaced","validation":{"openAPIV3Schema":{"description":"ServiceMonitor defines monitoring for a set of services.","properties":{"apiVersion":{"description":"APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#resources","type":"string"},"kind":{"description":"Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#types-kinds","type":"string"},"spec":{"description":"ServiceMonitorSpec contains specification parameters for a ServiceMonitor.","properties":{"endpoints":{"description":"A list of endpoints allowed as part of this ServiceMonitor.","items":{"description":"Endpoint defines a scrapeable endpoint serving Prometheus metrics.","properties":{"basicAuth":{"description":"BasicAuth allow an endpoint to authenticate over basic authentication More info: https://prometheus.io/docs/operating/configuration/#endpoints","properties":{"password":{"description":"SecretKeySelector selects a key of a Secret.","properties":{"key":{"description":"The key of the secret to select from. Must be a valid secret key.","type":"string"},"name":{"description":"Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names","type":"string"},"optional":{"description":"Specify whether the Secret or it's key must be defined","type":"boolean"}},"required":["key"]},"username":{"description":"SecretKeySelector selects a key of a Secret.","properties":{"key":{"description":"The key of the secret to select from. Must be a valid secret key.","type":"string"},"name":{"description":"Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names","type":"string"},"optional":{"description":"Specify whether the Secret or it's key must be defined","type":"boolean"}},"required":["key"]}}},"bearerTokenFile":{"description":"File to read bearer token for scraping targets.","type":"string"},"honorLabels":{"description":"HonorLabels chooses the metric's labels on collisions with target labels.","type":"boolean"},"interval":{"description":"Interval at which metrics should be scraped","type":"string"},"metricRelabelings":{"description":"MetricRelabelConfigs to apply to samples before ingestion.","items":{"description":"RelabelConfig allows dynamic rewriting of the label set, being applied to samples before ingestion. It defines `\u003cmetric_relabel_configs\u003e`-section of Prometheus configuration. More info: https://prometheus.io/docs/prometheus/latest/configuration/configuration/#metric_relabel_configs","properties":{"action":{"description":"Action to perform based on regex matching. Default is 'replace'","type":"string"},"modulus":{"description":"Modulus to take of the hash of the source label values.","format":"int64","type":"integer"},"regex":{"description":"Regular expression against which the extracted value is matched. defailt is '(.*)'","type":"string"},"replacement":{"description":"Replacement value against which a regex replace is performed if the regular expression matches. Regex capture groups are available. Default is '$1'","type":"string"},"separator":{"description":"Separator placed between concatenated source label values. default is ';'.","type":"string"},"sourceLabels":{"description":"The source labels select values from existing labels. Their content is concatenated using the configured separator and matched against the configured regular expression for the replace, keep, and drop actions.","items":{"type":"string"},"type":"array"},"targetLabel":{"description":"Label to which the resulting value is written in a replace action. It is mandatory for replace actions. Regex capture groups are available.","type":"string"}}},"type":"array"},"params":{"description":"Optional HTTP URL parameters","type":"object"},"path":{"description":"HTTP path to scrape for metrics.","type":"string"},"port":{"description":"Name of the service port this endpoint refers to. Mutually exclusive with targetPort.","type":"string"},"scheme":{"description":"HTTP scheme to use for scraping.","type":"string"},"scrapeTimeout":{"description":"Timeout after which the scrape is ended","type":"string"},"targetPort":{},"tlsConfig":{"description":"TLSConfig specifies TLS configuration parameters.","properties":{"caFile":{"description":"The CA cert to use for the targets.","type":"string"},Line truncated
|
||||
@@ -0,0 +1,454 @@
|
||||
local k = import 'ksonnet/ksonnet.beta.3/k.libsonnet';
|
||||
|
||||
{
|
||||
_config+:: {
|
||||
namespace: 'default',
|
||||
|
||||
versions+:: {
|
||||
prometheus: 'v2.2.1',
|
||||
},
|
||||
|
||||
imageRepos+:: {
|
||||
prometheus: 'quay.io/prometheus/prometheus',
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
replicas: 2,
|
||||
rules: {},
|
||||
},
|
||||
},
|
||||
|
||||
prometheus+:: {
|
||||
serviceAccount:
|
||||
local serviceAccount = k.core.v1.serviceAccount;
|
||||
|
||||
serviceAccount.new('prometheus-k8s') +
|
||||
serviceAccount.mixin.metadata.withNamespace($._config.namespace),
|
||||
service:
|
||||
local service = k.core.v1.service;
|
||||
local servicePort = k.core.v1.service.mixin.spec.portsType;
|
||||
|
||||
local prometheusPort = servicePort.newNamed('web', 9090, 'web');
|
||||
|
||||
service.new('prometheus-k8s', { app: 'prometheus', prometheus: 'k8s' }, prometheusPort) +
|
||||
service.mixin.metadata.withNamespace($._config.namespace) +
|
||||
service.mixin.metadata.withLabels({ prometheus: 'k8s' }),
|
||||
rules:
|
||||
local configMap = k.core.v1.configMap;
|
||||
|
||||
configMap.new('prometheus-k8s-rules', { 'all.rules.yaml': std.manifestYamlDoc($._config.prometheus.rules) }) +
|
||||
configMap.mixin.metadata.withLabels({ role: 'alert-rules', prometheus: 'k8s' }) +
|
||||
configMap.mixin.metadata.withNamespace($._config.namespace),
|
||||
roleBindingDefault:
|
||||
local roleBinding = k.rbac.v1.roleBinding;
|
||||
|
||||
roleBinding.new() +
|
||||
roleBinding.mixin.metadata.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.metadata.withNamespace('default') +
|
||||
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
roleBinding.mixin.roleRef.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
|
||||
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-k8s', namespace: $._config.namespace }]),
|
||||
clusterRole:
|
||||
local clusterRole = k.rbac.v1.clusterRole;
|
||||
local policyRule = clusterRole.rulesType;
|
||||
|
||||
local nodeMetricsRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources(['nodes/metrics']) +
|
||||
policyRule.withVerbs(['get']);
|
||||
|
||||
local metricsRule = policyRule.new() +
|
||||
policyRule.withNonResourceUrls('/metrics') +
|
||||
policyRule.withVerbs(['get']);
|
||||
|
||||
local rules = [nodeMetricsRule, metricsRule];
|
||||
|
||||
clusterRole.new() +
|
||||
clusterRole.mixin.metadata.withName('prometheus-k8s') +
|
||||
clusterRole.withRules(rules),
|
||||
roleConfig:
|
||||
local role = k.rbac.v1.role;
|
||||
local policyRule = role.rulesType;
|
||||
|
||||
local configmapRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'configmaps',
|
||||
]) +
|
||||
policyRule.withVerbs(['get']);
|
||||
|
||||
role.new() +
|
||||
role.mixin.metadata.withName('prometheus-k8s-config') +
|
||||
role.mixin.metadata.withNamespace($._config.namespace) +
|
||||
role.withRules(configmapRule),
|
||||
roleBindingConfig:
|
||||
local roleBinding = k.rbac.v1.roleBinding;
|
||||
|
||||
roleBinding.new() +
|
||||
roleBinding.mixin.metadata.withName('prometheus-k8s-config') +
|
||||
roleBinding.mixin.metadata.withNamespace($._config.namespace) +
|
||||
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
roleBinding.mixin.roleRef.withName('prometheus-k8s-config') +
|
||||
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
|
||||
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-k8s', namespace: $._config.namespace }]),
|
||||
roleBindingNamespace:
|
||||
local roleBinding = k.rbac.v1.roleBinding;
|
||||
|
||||
roleBinding.new() +
|
||||
roleBinding.mixin.metadata.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.metadata.withNamespace($._config.namespace) +
|
||||
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
roleBinding.mixin.roleRef.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
|
||||
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-k8s', namespace: $._config.namespace }]),
|
||||
clusterRoleBinding:
|
||||
local clusterRoleBinding = k.rbac.v1.clusterRoleBinding;
|
||||
|
||||
clusterRoleBinding.new() +
|
||||
clusterRoleBinding.mixin.metadata.withName('prometheus-k8s') +
|
||||
clusterRoleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
clusterRoleBinding.mixin.roleRef.withName('prometheus-k8s') +
|
||||
clusterRoleBinding.mixin.roleRef.mixinInstance({ kind: 'ClusterRole' }) +
|
||||
clusterRoleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-k8s', namespace: $._config.namespace }]),
|
||||
roleKubeSystem:
|
||||
local role = k.rbac.v1.role;
|
||||
local policyRule = role.rulesType;
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'nodes',
|
||||
'services',
|
||||
'endpoints',
|
||||
'pods',
|
||||
]) +
|
||||
policyRule.withVerbs(['get', 'list', 'watch']);
|
||||
|
||||
role.new() +
|
||||
role.mixin.metadata.withName('prometheus-k8s') +
|
||||
role.mixin.metadata.withNamespace('kube-system') +
|
||||
role.withRules(coreRule),
|
||||
roleDefault:
|
||||
local role = k.rbac.v1.role;
|
||||
local policyRule = role.rulesType;
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'nodes',
|
||||
'services',
|
||||
'endpoints',
|
||||
'pods',
|
||||
]) +
|
||||
policyRule.withVerbs(['get', 'list', 'watch']);
|
||||
|
||||
role.new() +
|
||||
role.mixin.metadata.withName('prometheus-k8s') +
|
||||
role.mixin.metadata.withNamespace('default') +
|
||||
role.withRules(coreRule),
|
||||
roleBindingKubeSystem:
|
||||
local roleBinding = k.rbac.v1.roleBinding;
|
||||
|
||||
roleBinding.new() +
|
||||
roleBinding.mixin.metadata.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.metadata.withNamespace('kube-system') +
|
||||
roleBinding.mixin.roleRef.withApiGroup('rbac.authorization.k8s.io') +
|
||||
roleBinding.mixin.roleRef.withName('prometheus-k8s') +
|
||||
roleBinding.mixin.roleRef.mixinInstance({ kind: 'Role' }) +
|
||||
roleBinding.withSubjects([{ kind: 'ServiceAccount', name: 'prometheus-k8s', namespace: $._config.namespace }]),
|
||||
roleNamespace:
|
||||
local role = k.rbac.v1.role;
|
||||
local policyRule = role.rulesType;
|
||||
|
||||
local coreRule = policyRule.new() +
|
||||
policyRule.withApiGroups(['']) +
|
||||
policyRule.withResources([
|
||||
'nodes',
|
||||
'services',
|
||||
'endpoints',
|
||||
'pods',
|
||||
]) +
|
||||
policyRule.withVerbs(['get', 'list', 'watch']);
|
||||
|
||||
role.new() +
|
||||
role.mixin.metadata.withName('prometheus-k8s') +
|
||||
role.mixin.metadata.withNamespace($._config.namespace) +
|
||||
role.withRules(coreRule),
|
||||
prometheus:
|
||||
local container = k.core.v1.pod.mixin.spec.containersType;
|
||||
local resourceRequirements = container.mixin.resourcesType;
|
||||
local selector = k.apps.v1beta2.deployment.mixin.spec.selectorType;
|
||||
|
||||
local resources = resourceRequirements.new() +
|
||||
resourceRequirements.withRequests({ memory: '400Mi' });
|
||||
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'Prometheus',
|
||||
metadata: {
|
||||
name: 'k8s',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
prometheus: 'k8s',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
replicas: $._config.prometheus.replicas,
|
||||
version: $._config.versions.prometheus,
|
||||
baseImage: $._config.imageRepos.prometheus,
|
||||
serviceAccountName: 'prometheus-k8s',
|
||||
serviceMonitorSelector: selector.withMatchExpressions({ key: 'k8s-app', operator: 'Exists' }),
|
||||
nodeSelector: { 'beta.kubernetes.io/os': 'linux' },
|
||||
ruleSelector: selector.withMatchLabels({
|
||||
role: 'alert-rules',
|
||||
prometheus: 'k8s',
|
||||
}),
|
||||
resources: resources,
|
||||
alerting: {
|
||||
alertmanagers: [
|
||||
{
|
||||
namespace: $._config.namespace,
|
||||
name: 'alertmanager-main',
|
||||
port: 'web',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitorPrometheus:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'prometheus',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'prometheus',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
selector: {
|
||||
matchLabels: {
|
||||
prometheus: 'k8s',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'monitoring',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'web',
|
||||
interval: '30s',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
serviceMonitorPrometheusOperator:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'prometheus-operator',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'prometheus-operator',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
endpoints: [
|
||||
{
|
||||
port: 'http',
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'prometheus-operator',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitorKubeScheduler:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-scheduler',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'kube-scheduler',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'http-metrics',
|
||||
interval: '30s',
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'kube-scheduler',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitorKubelet:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kubelet',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'kubelet',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https-metrics',
|
||||
scheme: 'https',
|
||||
interval: '30s',
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
},
|
||||
{
|
||||
port: 'https-metrics',
|
||||
scheme: 'https',
|
||||
path: '/metrics/cadvisor',
|
||||
interval: '30s',
|
||||
honorLabels: true,
|
||||
tlsConfig: {
|
||||
insecureSkipVerify: true,
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'kubelet',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitorKubeControllerManager:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-controller-manager',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'kube-controller-manager',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
endpoints: [
|
||||
{
|
||||
port: 'http-metrics',
|
||||
interval: '30s',
|
||||
},
|
||||
],
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'kube-controller-manager',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
serviceMonitorApiserver:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'kube-apiserver',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'apiserver',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'component',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
component: 'apiserver',
|
||||
provider: 'kubernetes',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'default',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'https',
|
||||
interval: '30s',
|
||||
scheme: 'https',
|
||||
tlsConfig: {
|
||||
caFile: '/var/run/secrets/kubernetes.io/serviceaccount/ca.crt',
|
||||
serverName: 'kubernetes',
|
||||
},
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
serviceMonitorCoreDNS:
|
||||
{
|
||||
apiVersion: 'monitoring.coreos.com/v1',
|
||||
kind: 'ServiceMonitor',
|
||||
metadata: {
|
||||
name: 'coredns',
|
||||
namespace: $._config.namespace,
|
||||
labels: {
|
||||
'k8s-app': 'coredns',
|
||||
},
|
||||
},
|
||||
spec: {
|
||||
jobLabel: 'k8s-app',
|
||||
selector: {
|
||||
matchLabels: {
|
||||
'k8s-app': 'coredns',
|
||||
component: 'metrics',
|
||||
},
|
||||
},
|
||||
namespaceSelector: {
|
||||
matchNames: [
|
||||
'kube-system',
|
||||
],
|
||||
},
|
||||
endpoints: [
|
||||
{
|
||||
port: 'http-metrics',
|
||||
interval: '15s',
|
||||
bearerTokenFile: '/var/run/secrets/kubernetes.io/serviceaccount/token',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
Reference in new issue
Block a user