at 18.09-beta 11 kB view raw
1{ config, pkgs, lib, ... }: 2 3with lib; 4 5let 6 cfg = config.services.kubernetes.addons.dashboard; 7in { 8 options.services.kubernetes.addons.dashboard = { 9 enable = mkEnableOption "kubernetes dashboard addon"; 10 11 rbac = mkOption { 12 description = "Role-based access control (RBAC) options"; 13 default = {}; 14 type = types.submodule { 15 options = { 16 enable = mkOption { 17 description = "Whether to enable role based access control is enabled for kubernetes dashboard"; 18 type = types.bool; 19 default = elem "RBAC" config.services.kubernetes.apiserver.authorizationMode; 20 }; 21 22 clusterAdmin = mkOption { 23 description = "Whether to assign cluster admin rights to the kubernetes dashboard"; 24 type = types.bool; 25 default = false; 26 }; 27 }; 28 }; 29 }; 30 31 version = mkOption { 32 description = "Which version of the kubernetes dashboard to deploy"; 33 type = types.str; 34 default = "v1.8.3"; 35 }; 36 37 image = mkOption { 38 description = "Docker image to seed for the kubernetes dashboard container."; 39 type = types.attrs; 40 default = { 41 imageName = "k8s.gcr.io/kubernetes-dashboard-amd64"; 42 imageDigest = "sha256:dc4026c1b595435ef5527ca598e1e9c4343076926d7d62b365c44831395adbd0"; 43 finalImageTag = cfg.version; 44 sha256 = "18ajcg0q1vignfjk2sm4xj4wzphfz8wah69ps8dklqfvv0164mc8"; 45 }; 46 }; 47 }; 48 49 config = mkIf cfg.enable { 50 services.kubernetes.kubelet.seedDockerImages = [(pkgs.dockerTools.pullImage cfg.image)]; 51 52 services.kubernetes.addonManager.addons = { 53 kubernetes-dashboard-deployment = { 54 kind = "Deployment"; 55 apiVersion = "apps/v1"; 56 metadata = { 57 labels = { 58 k8s-addon = "kubernetes-dashboard.addons.k8s.io"; 59 k8s-app = "kubernetes-dashboard"; 60 version = cfg.version; 61 "kubernetes.io/cluster-service" = "true"; 62 "addonmanager.kubernetes.io/mode" = "Reconcile"; 63 }; 64 name = "kubernetes-dashboard"; 65 namespace = "kube-system"; 66 }; 67 spec = { 68 replicas = 1; 69 revisionHistoryLimit = 10; 70 selector.matchLabels."k8s-app" = "kubernetes-dashboard"; 71 template = { 72 metadata = { 73 labels = { 74 k8s-addon = "kubernetes-dashboard.addons.k8s.io"; 75 k8s-app = "kubernetes-dashboard"; 76 version = cfg.version; 77 "kubernetes.io/cluster-service" = "true"; 78 }; 79 annotations = { 80 "scheduler.alpha.kubernetes.io/critical-pod" = ""; 81 }; 82 }; 83 spec = { 84 priorityClassName = "system-cluster-critical"; 85 containers = [{ 86 name = "kubernetes-dashboard"; 87 image = with cfg.image; "${imageName}:${finalImageTag}"; 88 ports = [{ 89 containerPort = 8443; 90 protocol = "TCP"; 91 }]; 92 resources = { 93 limits = { 94 cpu = "100m"; 95 memory = "300Mi"; 96 }; 97 requests = { 98 cpu = "100m"; 99 memory = "100Mi"; 100 }; 101 }; 102 args = ["--auto-generate-certificates"]; 103 volumeMounts = [{ 104 name = "tmp-volume"; 105 mountPath = "/tmp"; 106 } { 107 name = "kubernetes-dashboard-certs"; 108 mountPath = "/certs"; 109 }]; 110 livenessProbe = { 111 httpGet = { 112 scheme = "HTTPS"; 113 path = "/"; 114 port = 8443; 115 }; 116 initialDelaySeconds = 30; 117 timeoutSeconds = 30; 118 }; 119 }]; 120 volumes = [{ 121 name = "kubernetes-dashboard-certs"; 122 secret = { 123 secretName = "kubernetes-dashboard-certs"; 124 }; 125 } { 126 name = "tmp-volume"; 127 emptyDir = {}; 128 }]; 129 serviceAccountName = "kubernetes-dashboard"; 130 tolerations = [{ 131 key = "node-role.kubernetes.io/master"; 132 effect = "NoSchedule"; 133 } { 134 key = "CriticalAddonsOnly"; 135 operator = "Exists"; 136 }]; 137 }; 138 }; 139 }; 140 }; 141 142 kubernetes-dashboard-svc = { 143 apiVersion = "v1"; 144 kind = "Service"; 145 metadata = { 146 labels = { 147 k8s-addon = "kubernetes-dashboard.addons.k8s.io"; 148 k8s-app = "kubernetes-dashboard"; 149 "kubernetes.io/cluster-service" = "true"; 150 "kubernetes.io/name" = "KubeDashboard"; 151 "addonmanager.kubernetes.io/mode" = "Reconcile"; 152 }; 153 name = "kubernetes-dashboard"; 154 namespace = "kube-system"; 155 }; 156 spec = { 157 ports = [{ 158 port = 443; 159 targetPort = 8443; 160 }]; 161 selector.k8s-app = "kubernetes-dashboard"; 162 }; 163 }; 164 165 kubernetes-dashboard-sa = { 166 apiVersion = "v1"; 167 kind = "ServiceAccount"; 168 metadata = { 169 labels = { 170 k8s-app = "kubernetes-dashboard"; 171 k8s-addon = "kubernetes-dashboard.addons.k8s.io"; 172 "addonmanager.kubernetes.io/mode" = "Reconcile"; 173 }; 174 name = "kubernetes-dashboard"; 175 namespace = "kube-system"; 176 }; 177 }; 178 kubernetes-dashboard-sec-certs = { 179 apiVersion = "v1"; 180 kind = "Secret"; 181 metadata = { 182 labels = { 183 k8s-app = "kubernetes-dashboard"; 184 # Allows editing resource and makes sure it is created first. 185 "addonmanager.kubernetes.io/mode" = "EnsureExists"; 186 }; 187 name = "kubernetes-dashboard-certs"; 188 namespace = "kube-system"; 189 }; 190 type = "Opaque"; 191 }; 192 kubernetes-dashboard-sec-kholder = { 193 apiVersion = "v1"; 194 kind = "Secret"; 195 metadata = { 196 labels = { 197 k8s-app = "kubernetes-dashboard"; 198 # Allows editing resource and makes sure it is created first. 199 "addonmanager.kubernetes.io/mode" = "EnsureExists"; 200 }; 201 name = "kubernetes-dashboard-key-holder"; 202 namespace = "kube-system"; 203 }; 204 type = "Opaque"; 205 }; 206 kubernetes-dashboard-cm = { 207 apiVersion = "v1"; 208 kind = "ConfigMap"; 209 metadata = { 210 labels = { 211 k8s-app = "kubernetes-dashboard"; 212 # Allows editing resource and makes sure it is created first. 213 "addonmanager.kubernetes.io/mode" = "EnsureExists"; 214 }; 215 name = "kubernetes-dashboard-settings"; 216 namespace = "kube-system"; 217 }; 218 }; 219 } // (optionalAttrs cfg.rbac.enable 220 (let 221 subjects = [{ 222 kind = "ServiceAccount"; 223 name = "kubernetes-dashboard"; 224 namespace = "kube-system"; 225 }]; 226 labels = { 227 k8s-app = "kubernetes-dashboard"; 228 k8s-addon = "kubernetes-dashboard.addons.k8s.io"; 229 "addonmanager.kubernetes.io/mode" = "Reconcile"; 230 }; 231 in 232 (if cfg.rbac.clusterAdmin then { 233 kubernetes-dashboard-crb = { 234 apiVersion = "rbac.authorization.k8s.io/v1"; 235 kind = "ClusterRoleBinding"; 236 metadata = { 237 name = "kubernetes-dashboard"; 238 inherit labels; 239 }; 240 roleRef = { 241 apiGroup = "rbac.authorization.k8s.io"; 242 kind = "ClusterRole"; 243 name = "cluster-admin"; 244 }; 245 inherit subjects; 246 }; 247 } 248 else 249 { 250 # Upstream role- and rolebinding as per: 251 # https://raw.githubusercontent.com/kubernetes/dashboard/master/src/deploy/alternative/kubernetes-dashboard.yaml 252 kubernetes-dashboard-role = { 253 apiVersion = "rbac.authorization.k8s.io/v1"; 254 kind = "Role"; 255 metadata = { 256 name = "kubernetes-dashboard-minimal"; 257 namespace = "kube-system"; 258 inherit labels; 259 }; 260 rules = [ 261 # Allow Dashboard to create 'kubernetes-dashboard-key-holder' secret. 262 { 263 apiGroups = [""]; 264 resources = ["secrets"]; 265 verbs = ["create"]; 266 } 267 # Allow Dashboard to create 'kubernetes-dashboard-settings' config map. 268 { 269 apiGroups = [""]; 270 resources = ["configmaps"]; 271 verbs = ["create"]; 272 } 273 # Allow Dashboard to get, update and delete Dashboard exclusive secrets. 274 { 275 apiGroups = [""]; 276 resources = ["secrets"]; 277 resourceNames = ["kubernetes-dashboard-key-holder"]; 278 verbs = ["get" "update" "delete"]; 279 } 280 # Allow Dashboard to get and update 'kubernetes-dashboard-settings' config map. 281 { 282 apiGroups = [""]; 283 resources = ["configmaps"]; 284 resourceNames = ["kubernetes-dashboard-settings"]; 285 verbs = ["get" "update"]; 286 } 287 # Allow Dashboard to get metrics from heapster. 288 { 289 apiGroups = [""]; 290 resources = ["services"]; 291 resourceNames = ["heapster"]; 292 verbs = ["proxy"]; 293 } 294 { 295 apiGroups = [""]; 296 resources = ["services/proxy"]; 297 resourceNames = ["heapster" "http:heapster:" "https:heapster:"]; 298 verbs = ["get"]; 299 } 300 ]; 301 }; 302 303 kubernetes-dashboard-rb = { 304 apiVersion = "rbac.authorization.k8s.io/v1"; 305 kind = "RoleBinding"; 306 metadata = { 307 name = "kubernetes-dashboard-minimal"; 308 namespace = "kube-system"; 309 inherit labels; 310 }; 311 roleRef = { 312 apiGroup = "rbac.authorization.k8s.io"; 313 kind = "Role"; 314 name = "kubernetes-dashboard-minimal"; 315 }; 316 inherit subjects; 317 }; 318 }) 319 )); 320 }; 321}