blob: df82effc46a0a279ab85fcb8cc264482c4409c27 [file] [log] [blame]
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +01001{ config, pkgs, lib, ... }:
2
Serge Bazanskifbe234b2020-10-03 00:13:28 +02003with (( import ../defs-cluster-k0.nix ) config.networking.hostName);
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +01004let
5 # Pin for k8s packages. This is so that upagrading the system will not upgrade the k8s control or data planes.
6 k8spkgs = import (fetchGit {
Serge Bazanskie77f7712020-10-10 22:39:50 +02007 # Now at 1.16.5
8 name = "nixos-unstable-2020-01-22";
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +01009 url = https://github.com/nixos/nixpkgs-channels/;
Serge Bazanskie77f7712020-10-10 22:39:50 +020010 rev = "a96ed5d70427bdc2fbb9e805784e1b9621157a98";
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010011 }) {};
12 # Pin for kubelet
13 k8spkgsKubelet = import (fetchGit {
Serge Bazanskie77f7712020-10-10 22:39:50 +020014 # Now at 1.16.5
15 name = "nixos-unstable-2020-01-22";
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010016 url = https://github.com/nixos/nixpkgs-channels/;
Serge Bazanskie77f7712020-10-10 22:39:50 +020017 rev = "a96ed5d70427bdc2fbb9e805784e1b9621157a98";
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010018 }) {};
19
20in rec {
21 # Disable kubelet service and bring in our own override.
22 # Also nuke flannel from the orbit.
23 disabledModules = [
24 "services/cluster/kubernetes/kubelet.nix"
25 "services/cluster/kubernetes/flannel.nix"
26 ];
27
28 imports =
29 [
Serge Bazanskifbe234b2020-10-03 00:13:28 +020030 ./kubelet.nix
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010031 ];
32
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010033 networking.firewall.enable = false;
34
35 # Point k8s apiserver address at ourselves, as every machine runs an apiserver with this cert name.
36 networking.extraHosts = ''
37 127.0.0.1 ${k8sapi}
38 '';
39
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +010040 services.etcd = rec {
41 enable = true;
42 name = fqdn;
43 listenClientUrls = ["https://0.0.0.0:2379"];
44 advertiseClientUrls = ["https://${fqdn}:2379"];
45 listenPeerUrls = ["https://0.0.0.0:2380"];
46 initialAdvertisePeerUrls = ["https://${fqdn}:2380"];
47 initialCluster = (map (n: "${n.fqdn}=https://${n.fqdn}:2380") machines);
48 initialClusterState = "existing";
49
50 clientCertAuth = true;
51 trustedCaFile = pki.etcd.server.ca;
52 certFile = pki.etcd.server.cert;
53 keyFile = pki.etcd.server.key;
54
55 peerClientCertAuth = true;
56 peerTrustedCaFile = pki.etcdPeer.ca;
57 peerCertFile = pki.etcdPeer.cert;
58 peerKeyFile = pki.etcdPeer.key;
59
60 extraConf = {
61 PEER_CLIENT_CERT_AUTH = "true";
62 };
63 };
64
65 services.kubernetes = {
66 # Pin to specific k8s package.
67 package = k8spkgs.kubernetes;
68 roles = []; # We do not use any nixpkgs predefined roles for k8s. Instead,
69 # we enable k8s components manually.
70
71 caFile = pki.kube.apiserver.ca;
72 clusterCidr = "10.10.16.0/20";
73
74 path = [ pkgs.e2fsprogs ]; # kubelet wants to mkfs.ext4 when mounting pvcs
75
76 addons.dns.enable = false;
77
78 apiserver = rec {
79 enable = true;
80 insecurePort = ports.k8sAPIServerPlain;
81 securePort = ports.k8sAPIServerSecure;
82 advertiseAddress = "${machine.ipAddr}";
83
84 etcd = {
85 # https://github.com/kubernetes/kubernetes/issues/72102
86 servers = (map (n: "https://${n.fqdn}:2379") ( [ machine ] ));
87 caFile = pki.etcd.kube.ca;
88 keyFile = pki.etcd.kube.key;
89 certFile = pki.etcd.kube.cert;
90 };
91
92 tlsCertFile = pki.kube.apiserver.cert;
93 tlsKeyFile = pki.kube.apiserver.key;
94
95 clientCaFile = pki.kube.apiserver.ca;
96
97 kubeletHttps = true;
98 kubeletClientCaFile = pki.kube.apiserver.ca;
99 kubeletClientCertFile = pki.kube.apiserver.cert;
100 kubeletClientKeyFile = pki.kube.apiserver.key;
101
102 serviceAccountKeyFile = pki.kube.serviceaccounts.key;
103
104 allowPrivileged = true;
105 serviceClusterIpRange = "10.10.12.0/24";
106 runtimeConfig = "api/all,authentication.k8s.io/v1beta1";
107 authorizationMode = ["Node" "RBAC"];
108 enableAdmissionPlugins = ["NamespaceLifecycle" "NodeRestriction" "LimitRanger" "ServiceAccount" "DefaultStorageClass" "ResourceQuota" "PodSecurityPolicy"];
109 extraOpts = ''
110 --apiserver-count=5 \
111 --proxy-client-cert-file=${pki.kubeFront.apiserver.cert} \
112 --proxy-client-key-file=${pki.kubeFront.apiserver.key} \
113 --requestheader-allowed-names= \
114 --requestheader-client-ca-file=${pki.kubeFront.apiserver.ca} \
115 --requestheader-extra-headers-prefix=X-Remote-Extra- \
116 --requestheader-group-headers=X-Remote-Group \
117 --requestheader-username-headers=X-Remote-User \
118 -v=5
119 '';
120 };
121
Serge Bazanski12573892020-10-10 14:55:08 +0200122 controllerManager = let
123 top = config.services.kubernetes;
124 kubeconfig = top.lib.mkKubeConfig "controller-manager" pki.kube.controllermanager.config;
125 in {
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +0100126 enable = true;
127 bindAddress = "0.0.0.0";
128 insecurePort = ports.k8sControllerManagerPlain;
129 leaderElect = true;
130 serviceAccountKeyFile = pki.kube.serviceaccounts.key;
131 rootCaFile = pki.kube.ca;
132 extraOpts = ''
133 --service-cluster-ip-range=10.10.12.0/24 \
134 --use-service-account-credentials=true \
135 --secure-port=${toString ports.k8sControllerManagerSecure}\
Serge Bazanski12573892020-10-10 14:55:08 +0200136 --authentication-kubeconfig=${kubeconfig}\
137 --authorization-kubeconfig=${kubeconfig}\
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +0100138 '';
139 kubeconfig = pki.kube.controllermanager.config;
140 };
141
Serge Bazanski12573892020-10-10 14:55:08 +0200142 scheduler = let
143 top = config.services.kubernetes;
144 kubeconfig = top.lib.mkKubeConfig "scheduler" pki.kube.controllermanager.config;
145 in {
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +0100146 enable = true;
147 address = "0.0.0.0";
Serge Bazanski12573892020-10-10 14:55:08 +0200148 port = ports.k8sSchedulerPlain;
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +0100149 leaderElect = true;
150 kubeconfig = pki.kube.scheduler.config;
Serge Bazanski12573892020-10-10 14:55:08 +0200151 extraOpts = ''
152 --secure-port=${toString ports.k8sSchedulerSecure}\
153 --authentication-kubeconfig=${kubeconfig}\
154 --authorization-kubeconfig=${kubeconfig}\
155 '';
Sergiusz Bazanskic78cc132020-02-02 22:31:53 +0100156 };
157
158 proxy = {
159 enable = true;
160 kubeconfig = pki.kube.proxy.config;
161 extraOpts = ''
162 --hostname-override=${fqdn}\
163 --proxy-mode=iptables
164 '';
165 };
166
167 kubelet = {
168 enable = true;
169 unschedulable = false;
170 hostname = fqdn;
171 tlsCertFile = pki.kube.kubelet.cert;
172 tlsKeyFile = pki.kube.kubelet.key;
173 clientCaFile = pki.kube.kubelet.ca;
174 nodeIp = machine.ipAddr;
175 networkPlugin = "cni";
176 clusterDns = "10.10.12.254";
177 kubeconfig = pki.kube.kubelet.config;
178 extraOpts = ''
179 --read-only-port=0
180 '';
181 package = k8spkgsKubelet.kubernetes;
182 };
183
184 };
185
186 # https://github.com/NixOS/nixpkgs/issues/60687
187 systemd.services.kube-control-plane-online = {
188 preStart = pkgs.lib.mkForce "";
189 };
190 # this seems to depend on flannel
191 # TODO(q3k): file issue
192 systemd.services.kubelet-online = {
193 script = pkgs.lib.mkForce "sleep 1";
194 };
195}