1{
2 pkgs ? import <nixpkgs> {},
3 internalDomain ? "cloud.yourdomain.net",
4 externalDomain ? "myawesomecluster.cluster.yourdomain.net",
5 serviceClusterIp ? "10.0.0.1",
6 kubelets
7}:
8let
9 runWithCFSSL = name: cmd:
10 builtins.fromJSON (builtins.readFile (
11 pkgs.runCommand "${name}-cfss.json" {
12 buildInputs = [ pkgs.cfssl ];
13 } "cfssl ${cmd} > $out"
14 ));
15
16 writeCFSSL = content:
17 pkgs.runCommand content.name {
18 buildInputs = [ pkgs.cfssl ];
19 } ''
20 mkdir -p $out
21 cd $out
22 cat ${writeFile content} | cfssljson -bare ${content.name}
23 '';
24
25 noCSR = content: pkgs.lib.filterAttrs (n: v: n != "csr") content;
26 noKey = content: pkgs.lib.filterAttrs (n: v: n != "key") content;
27
28 writeFile = content: pkgs.writeText "content" (
29 if pkgs.lib.isAttrs content then builtins.toJSON content
30 else toString content
31 );
32
33 createServingCertKey = { ca, cn, hosts? [], size ? 2048, name ? cn }:
34 noCSR (
35 (runWithCFSSL name "gencert -ca=${writeFile ca.cert} -ca-key=${writeFile ca.key} -profile=server -config=${writeFile ca.config} ${writeFile {
36 CN = cn;
37 hosts = hosts;
38 key = { algo = "rsa"; inherit size; };
39 }}") // { inherit name; }
40 );
41
42 createClientCertKey = { ca, cn, groups ? [], size ? 2048, name ? cn }:
43 noCSR (
44 (runWithCFSSL name "gencert -ca=${writeFile ca.cert} -ca-key=${writeFile ca.key} -profile=client -config=${writeFile ca.config} ${writeFile {
45 CN = cn;
46 names = map (group: {O = group;}) groups;
47 hosts = [""];
48 key = { algo = "rsa"; inherit size; };
49 }}") // { inherit name; }
50 );
51
52 createSigningCertKey = { C ? "xx", ST ? "x", L ? "x", O ? "x", OU ? "x", CN ? "ca", emailAddress ? "x", expiry ? "43800h", size ? 2048, name ? CN }:
53 (noCSR (runWithCFSSL CN "genkey -initca ${writeFile {
54 key = { algo = "rsa"; inherit size; };
55 names = [{ inherit C ST L O OU CN emailAddress; }];
56 }}")) // {
57 inherit name;
58 config.signing = {
59 default.expiry = expiry;
60 profiles = {
61 server = {
62 inherit expiry;
63 usages = [
64 "signing"
65 "key encipherment"
66 "server auth"
67 ];
68 };
69 client = {
70 inherit expiry;
71 usages = [
72 "signing"
73 "key encipherment"
74 "client auth"
75 ];
76 };
77 peer = {
78 inherit expiry;
79 usages = [
80 "signing"
81 "key encipherment"
82 "server auth"
83 "client auth"
84 ];
85 };
86 };
87 };
88 };
89
90 ca = createSigningCertKey {};
91
92 kube-apiserver = createServingCertKey {
93 inherit ca;
94 cn = "kube-apiserver";
95 hosts = ["kubernetes.default" "kubernetes.default.svc" "localhost" "api.${externalDomain}" serviceClusterIp];
96 };
97
98 kubelet = createServingCertKey {
99 inherit ca;
100 cn = "kubelet";
101 hosts = ["*.${externalDomain}"];
102 };
103
104 service-accounts = createServingCertKey {
105 inherit ca;
106 cn = "kube-service-accounts";
107 };
108
109 etcd = createServingCertKey {
110 inherit ca;
111 cn = "etcd";
112 hosts = ["etcd.${externalDomain}"];
113 };
114
115 etcd-client = createClientCertKey {
116 inherit ca;
117 cn = "etcd-client";
118 };
119
120 kubelet-client = createClientCertKey {
121 inherit ca;
122 cn = "kubelet-client";
123 groups = ["system:masters"];
124 };
125
126 apiserver-client = {
127 kubelet = hostname: createClientCertKey {
128 inherit ca;
129 name = "apiserver-client-kubelet-${hostname}";
130 cn = "system:node:${hostname}.${externalDomain}";
131 groups = ["system:nodes"];
132 };
133
134 kube-proxy = createClientCertKey {
135 inherit ca;
136 name = "apiserver-client-kube-proxy";
137 cn = "system:kube-proxy";
138 groups = ["system:kube-proxy" "system:nodes"];
139 };
140
141 kube-controller-manager = createClientCertKey {
142 inherit ca;
143 name = "apiserver-client-kube-controller-manager";
144 cn = "system:kube-controller-manager";
145 groups = ["system:masters"];
146 };
147
148 kube-scheduler = createClientCertKey {
149 inherit ca;
150 name = "apiserver-client-kube-scheduler";
151 cn = "system:kube-scheduler";
152 groups = ["system:kube-scheduler"];
153 };
154
155 admin = createClientCertKey {
156 inherit ca;
157 cn = "admin";
158 groups = ["system:masters"];
159 };
160 };
161in {
162 master = pkgs.buildEnv {
163 name = "master-keys";
164 paths = [
165 (writeCFSSL (noKey ca))
166 (writeCFSSL kube-apiserver)
167 (writeCFSSL kubelet-client)
168 (writeCFSSL apiserver-client.kube-controller-manager)
169 (writeCFSSL apiserver-client.kube-scheduler)
170 (writeCFSSL service-accounts)
171 (writeCFSSL etcd)
172 ];
173 };
174
175 worker = pkgs.buildEnv {
176 name = "worker-keys";
177 paths = [
178 (writeCFSSL (noKey ca))
179 (writeCFSSL kubelet)
180 (writeCFSSL apiserver-client.kube-proxy)
181 (writeCFSSL etcd-client)
182 ] ++ map (hostname: writeCFSSL (apiserver-client.kubelet hostname)) kubelets;
183 };
184
185 admin = writeCFSSL apiserver-client.admin;
186}