| # 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, |
| }, |
| }, |
| }, |
| } |