1{ config, lib, options, pkgs, ... }:
2
3with lib;
4
5let
6 top = config.services.kubernetes;
7 otop = options.services.kubernetes;
8 cfg = top.controllerManager;
9in
10{
11 imports = [
12 (mkRenamedOptionModule [ "services" "kubernetes" "controllerManager" "address" ] ["services" "kubernetes" "controllerManager" "bindAddress"])
13 (mkRemovedOptionModule [ "services" "kubernetes" "controllerManager" "insecurePort" ] "")
14 ];
15
16 ###### interface
17 options.services.kubernetes.controllerManager = with lib.types; {
18
19 allocateNodeCIDRs = mkOption {
20 description = lib.mdDoc "Whether to automatically allocate CIDR ranges for cluster nodes.";
21 default = true;
22 type = bool;
23 };
24
25 bindAddress = mkOption {
26 description = lib.mdDoc "Kubernetes controller manager listening address.";
27 default = "127.0.0.1";
28 type = str;
29 };
30
31 clusterCidr = mkOption {
32 description = lib.mdDoc "Kubernetes CIDR Range for Pods in cluster.";
33 default = top.clusterCidr;
34 defaultText = literalExpression "config.${otop.clusterCidr}";
35 type = str;
36 };
37
38 enable = mkEnableOption (lib.mdDoc "Kubernetes controller manager");
39
40 extraOpts = mkOption {
41 description = lib.mdDoc "Kubernetes controller manager extra command line options.";
42 default = "";
43 type = separatedString " ";
44 };
45
46 featureGates = mkOption {
47 description = lib.mdDoc "List set of feature gates";
48 default = top.featureGates;
49 defaultText = literalExpression "config.${otop.featureGates}";
50 type = listOf str;
51 };
52
53 kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes controller manager";
54
55 leaderElect = mkOption {
56 description = lib.mdDoc "Whether to start leader election before executing main loop.";
57 type = bool;
58 default = true;
59 };
60
61 rootCaFile = mkOption {
62 description = lib.mdDoc ''
63 Kubernetes controller manager certificate authority file included in
64 service account's token secret.
65 '';
66 default = top.caFile;
67 defaultText = literalExpression "config.${otop.caFile}";
68 type = nullOr path;
69 };
70
71 securePort = mkOption {
72 description = lib.mdDoc "Kubernetes controller manager secure listening port.";
73 default = 10252;
74 type = int;
75 };
76
77 serviceAccountKeyFile = mkOption {
78 description = lib.mdDoc ''
79 Kubernetes controller manager PEM-encoded private RSA key file used to
80 sign service account tokens
81 '';
82 default = null;
83 type = nullOr path;
84 };
85
86 tlsCertFile = mkOption {
87 description = lib.mdDoc "Kubernetes controller-manager certificate file.";
88 default = null;
89 type = nullOr path;
90 };
91
92 tlsKeyFile = mkOption {
93 description = lib.mdDoc "Kubernetes controller-manager private key file.";
94 default = null;
95 type = nullOr path;
96 };
97
98 verbosity = mkOption {
99 description = lib.mdDoc ''
100 Optional glog verbosity level for logging statements. See
101 <https://github.com/kubernetes/community/blob/master/contributors/devel/logging.md>
102 '';
103 default = null;
104 type = nullOr int;
105 };
106
107 };
108
109 ###### implementation
110 config = mkIf cfg.enable {
111 systemd.services.kube-controller-manager = {
112 description = "Kubernetes Controller Manager Service";
113 wantedBy = [ "kubernetes.target" ];
114 after = [ "kube-apiserver.service" ];
115 serviceConfig = {
116 RestartSec = "30s";
117 Restart = "on-failure";
118 Slice = "kubernetes.slice";
119 ExecStart = ''${top.package}/bin/kube-controller-manager \
120 --allocate-node-cidrs=${boolToString cfg.allocateNodeCIDRs} \
121 --bind-address=${cfg.bindAddress} \
122 ${optionalString (cfg.clusterCidr!=null)
123 "--cluster-cidr=${cfg.clusterCidr}"} \
124 ${optionalString (cfg.featureGates != [])
125 "--feature-gates=${concatMapStringsSep "," (feature: "${feature}=true") cfg.featureGates}"} \
126 --kubeconfig=${top.lib.mkKubeConfig "kube-controller-manager" cfg.kubeconfig} \
127 --leader-elect=${boolToString cfg.leaderElect} \
128 ${optionalString (cfg.rootCaFile!=null)
129 "--root-ca-file=${cfg.rootCaFile}"} \
130 --secure-port=${toString cfg.securePort} \
131 ${optionalString (cfg.serviceAccountKeyFile!=null)
132 "--service-account-private-key-file=${cfg.serviceAccountKeyFile}"} \
133 ${optionalString (cfg.tlsCertFile!=null)
134 "--tls-cert-file=${cfg.tlsCertFile}"} \
135 ${optionalString (cfg.tlsKeyFile!=null)
136 "--tls-private-key-file=${cfg.tlsKeyFile}"} \
137 ${optionalString (elem "RBAC" top.apiserver.authorizationMode)
138 "--use-service-account-credentials"} \
139 ${optionalString (cfg.verbosity != null) "--v=${toString cfg.verbosity}"} \
140 ${cfg.extraOpts}
141 '';
142 WorkingDirectory = top.dataDir;
143 User = "kubernetes";
144 Group = "kubernetes";
145 };
146 unitConfig = {
147 StartLimitIntervalSec = 0;
148 };
149 path = top.path;
150 };
151
152 services.kubernetes.pki.certs = with top.lib; {
153 controllerManager = mkCert {
154 name = "kube-controller-manager";
155 CN = "kube-controller-manager";
156 action = "systemctl restart kube-controller-manager.service";
157 };
158 controllerManagerClient = mkCert {
159 name = "kube-controller-manager-client";
160 CN = "system:kube-controller-manager";
161 action = "systemctl restart kube-controller-manager.service";
162 };
163 };
164
165 services.kubernetes.controllerManager.kubeconfig.server = mkDefault top.apiserverAddress;
166 };
167
168 meta.buildDocsInSandbox = false;
169}