cluster: deploy calico and metrics service
diff --git a/cluster/kube/lib/metrics.libsonnet b/cluster/kube/lib/metrics.libsonnet
new file mode 100644
index 0000000..e11f5ef
--- /dev/null
+++ b/cluster/kube/lib/metrics.libsonnet
@@ -0,0 +1,142 @@
+# Deploy a per-cluster Metrics Server setup.
+
+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,
+ },
+ },
+ },
+}