# Deploy a per-cluster Metrics Server setup. # These are Kubernetes metrics, not Prometheus/whatever. local kube = import "../../../kube/kube.libsonnet"; { Environment: { local env = self, local cfg = env.cfg, cfg:: { image: "k8s.gcr.io/metrics-server-amd64:v0.3.1", namespace: "kube-system", }, sa: kube.ServiceAccount("metrics-server") { metadata+: { namespace: cfg.namespace, }, }, # Cluster Role and Binding for the metrics server to allow reading node state. crServer: kube.ClusterRole("system:metrics-server") { rules: [ { apiGroups: [""], resources: ["pods", "nodes", "nodes/stats"], verbs: ["get", "list", "watch"] }, ], }, crbServer: kube.ClusterRoleBinding("system:metrics-server") { roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "ClusterRole", name: env.crServer.metadata.name, }, subjects: [ { kind: "ServiceAccount", name: env.sa.metadata.name, namespace: env.sa.metadata.namespace, }, ], }, # Let the metrics server act as an auth delegator. crbAuthDelegator: kube.ClusterRoleBinding("metrics-server:system:auth-delegator") { roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "ClusterRole", name: "system:auth-delegator", }, subjects: [ { kind: "ServiceAccount", name: env.sa.metadata.name, namespace: env.sa.metadata.namespace, }, ], }, # Let the metrics server access the apiserver extensions configmap. rbAPIExtensionsMap: kube.RoleBinding("metrics-server-auth-reader") { metadata+: { namespace: cfg.namespace, }, roleRef: { apiGroup: "rbac.authorization.k8s.io", kind: "Role", name: "extension-apiserver-authentication-reader", }, subjects: [ { kind: "ServiceAccount", name: env.sa.metadata.name, namespace: env.sa.metadata.namespace, }, ], }, deployment: kube.Deployment("metrics-server") { metadata+: { namespace: cfg.namespace, labels+: { "k8s-app": "metrics-server", }, }, spec+: { template+: { spec+: { serviceAccountName: env.sa.metadata.name, volumes_: { tmp: { emptyDir: {}, }, }, containers_: { coredns: kube.Container("metrics-server") { local container = self, image: cfg.image, imagePullPolicy: "IfNotPresent", # TODO(q3k): define resource limits ports_: { https: { containerPort: 443, protocol: "TCP", }, }, volumeMounts_: { tmp: { mountPath: "/tmp", }, }, }, }, }, }, }, }, svc: kube.Service("metrics-server") { local svc = self, metadata+: { namespace: cfg.namespace, }, target_pod: env.deployment.spec.template, }, api: kube._Object("apiregistration.k8s.io/v1beta1", "APIService", "v1beta1.metrics.k8s.io") { spec+: { service: { name: env.svc.metadata.name, namespace: env.svc.metadata.namespace, }, group: "metrics.k8s.io", version: "v1beta1", insecureSkipTLSVerify: true, groupPriorityMinimum: 100, versionPriority: 100, }, }, }, }