at 23.11-pre 4.7 kB view raw
1{ config, lib, pkgs, ... }: 2 3with lib; 4 5let 6 top = config.services.kubernetes; 7 cfg = top.addonManager; 8 9 isRBACEnabled = elem "RBAC" top.apiserver.authorizationMode; 10 11 addons = pkgs.runCommand "kubernetes-addons" { } '' 12 mkdir -p $out 13 # since we are mounting the addons to the addon manager, they need to be copied 14 ${concatMapStringsSep ";" (a: "cp -v ${a}/* $out/") (mapAttrsToList (name: addon: 15 pkgs.writeTextDir "${name}.json" (builtins.toJSON addon) 16 ) (cfg.addons))} 17 ''; 18in 19{ 20 ###### interface 21 options.services.kubernetes.addonManager = with lib.types; { 22 23 bootstrapAddons = mkOption { 24 description = lib.mdDoc '' 25 Bootstrap addons are like regular addons, but they are applied with cluster-admin rights. 26 They are applied at addon-manager startup only. 27 ''; 28 default = { }; 29 type = attrsOf attrs; 30 example = literalExpression '' 31 { 32 "my-service" = { 33 "apiVersion" = "v1"; 34 "kind" = "Service"; 35 "metadata" = { 36 "name" = "my-service"; 37 "namespace" = "default"; 38 }; 39 "spec" = { ... }; 40 }; 41 } 42 ''; 43 }; 44 45 addons = mkOption { 46 description = lib.mdDoc "Kubernetes addons (any kind of Kubernetes resource can be an addon)."; 47 default = { }; 48 type = attrsOf (either attrs (listOf attrs)); 49 example = literalExpression '' 50 { 51 "my-service" = { 52 "apiVersion" = "v1"; 53 "kind" = "Service"; 54 "metadata" = { 55 "name" = "my-service"; 56 "namespace" = "default"; 57 }; 58 "spec" = { ... }; 59 }; 60 } 61 // import <nixpkgs/nixos/modules/services/cluster/kubernetes/dns.nix> { cfg = config.services.kubernetes; }; 62 ''; 63 }; 64 65 enable = mkEnableOption (lib.mdDoc "Kubernetes addon manager"); 66 }; 67 68 ###### implementation 69 config = mkIf cfg.enable { 70 environment.etc."kubernetes/addons".source = "${addons}/"; 71 72 systemd.services.kube-addon-manager = { 73 description = "Kubernetes addon manager"; 74 wantedBy = [ "kubernetes.target" ]; 75 after = [ "kube-apiserver.service" ]; 76 environment.ADDON_PATH = "/etc/kubernetes/addons/"; 77 path = [ pkgs.gawk ]; 78 serviceConfig = { 79 Slice = "kubernetes.slice"; 80 ExecStart = "${top.package}/bin/kube-addons"; 81 WorkingDirectory = top.dataDir; 82 User = "kubernetes"; 83 Group = "kubernetes"; 84 Restart = "on-failure"; 85 RestartSec = 10; 86 }; 87 unitConfig = { 88 StartLimitIntervalSec = 0; 89 }; 90 }; 91 92 services.kubernetes.addonManager.bootstrapAddons = mkIf isRBACEnabled 93 (let 94 name = "system:kube-addon-manager"; 95 namespace = "kube-system"; 96 in 97 { 98 99 kube-addon-manager-r = { 100 apiVersion = "rbac.authorization.k8s.io/v1"; 101 kind = "Role"; 102 metadata = { 103 inherit name namespace; 104 }; 105 rules = [{ 106 apiGroups = ["*"]; 107 resources = ["*"]; 108 verbs = ["*"]; 109 }]; 110 }; 111 112 kube-addon-manager-rb = { 113 apiVersion = "rbac.authorization.k8s.io/v1"; 114 kind = "RoleBinding"; 115 metadata = { 116 inherit name namespace; 117 }; 118 roleRef = { 119 apiGroup = "rbac.authorization.k8s.io"; 120 kind = "Role"; 121 inherit name; 122 }; 123 subjects = [{ 124 apiGroup = "rbac.authorization.k8s.io"; 125 kind = "User"; 126 inherit name; 127 }]; 128 }; 129 130 kube-addon-manager-cluster-lister-cr = { 131 apiVersion = "rbac.authorization.k8s.io/v1"; 132 kind = "ClusterRole"; 133 metadata = { 134 name = "${name}:cluster-lister"; 135 }; 136 rules = [{ 137 apiGroups = ["*"]; 138 resources = ["*"]; 139 verbs = ["list"]; 140 }]; 141 }; 142 143 kube-addon-manager-cluster-lister-crb = { 144 apiVersion = "rbac.authorization.k8s.io/v1"; 145 kind = "ClusterRoleBinding"; 146 metadata = { 147 name = "${name}:cluster-lister"; 148 }; 149 roleRef = { 150 apiGroup = "rbac.authorization.k8s.io"; 151 kind = "ClusterRole"; 152 name = "${name}:cluster-lister"; 153 }; 154 subjects = [{ 155 kind = "User"; 156 inherit name; 157 }]; 158 }; 159 }); 160 161 services.kubernetes.pki.certs = { 162 addonManager = top.lib.mkCert { 163 name = "kube-addon-manager"; 164 CN = "system:kube-addon-manager"; 165 action = "systemctl restart kube-addon-manager.service"; 166 }; 167 }; 168 }; 169 170 meta.buildDocsInSandbox = false; 171}