summary refs log tree commit diff
path: root/nixos/modules/services/cluster/kubernetes
diff options
context:
space:
mode:
authorJohan Thomsen <jth@dbc.dk>2019-02-12 16:48:23 +0100
committerFranz Pletz <fpletz@fnordicwalking.de>2019-02-20 21:08:56 +0100
commit466beb02143f99815eef90ef8a69c91cd898a998 (patch)
tree019499759ad73754e40833ea2698ad26aeb485a7 /nixos/modules/services/cluster/kubernetes
parent1f49c2160a074b6cb36389a05fd3395cee432d64 (diff)
downloadnixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar.gz
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar.bz2
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar.lz
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar.xz
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.tar.zst
nixpkgs-466beb02143f99815eef90ef8a69c91cd898a998.zip
nixos/kubernetes: let flannel use kubernetes as storage backend
+ isolate etcd on the master node by letting it listen only on loopback
+ enabling kubelet on master and taint master with NoSchedule

The reason for the latter is that flannel requires all nodes to be "registered"
in the cluster in order to setup the cluster network. This means that the
kubelet is needed even at nodes on which we don't plan to schedule anything.
Diffstat (limited to 'nixos/modules/services/cluster/kubernetes')
-rw-r--r--nixos/modules/services/cluster/kubernetes/apiserver.nix1
-rw-r--r--nixos/modules/services/cluster/kubernetes/default.nix10
-rw-r--r--nixos/modules/services/cluster/kubernetes/flannel.nix52
-rw-r--r--nixos/modules/services/cluster/kubernetes/pki.nix23
4 files changed, 78 insertions, 8 deletions
diff --git a/nixos/modules/services/cluster/kubernetes/apiserver.nix b/nixos/modules/services/cluster/kubernetes/apiserver.nix
index 465d74d83c8..81e45b417de 100644
--- a/nixos/modules/services/cluster/kubernetes/apiserver.nix
+++ b/nixos/modules/services/cluster/kubernetes/apiserver.nix
@@ -411,6 +411,7 @@ in
           name = "etcd";
           CN = top.masterAddress;
           hosts = [
+                    "etcd.local"
                     "etcd.${top.addons.dns.clusterDomain}"
                     top.masterAddress
                     cfg.advertiseAddress
diff --git a/nixos/modules/services/cluster/kubernetes/default.nix b/nixos/modules/services/cluster/kubernetes/default.nix
index a5a59f4a5fc..375e33e91b5 100644
--- a/nixos/modules/services/cluster/kubernetes/default.nix
+++ b/nixos/modules/services/cluster/kubernetes/default.nix
@@ -189,6 +189,16 @@ in {
       services.kubernetes.addonManager.enable = mkDefault true;
       services.kubernetes.proxy.enable = mkDefault true;
       services.etcd.enable = true; # Cannot mkDefault because of flannel default options
+      services.kubernetes.kubelet = {
+        enable = mkDefault true;
+        taints = mkIf (!(elem "node" cfg.roles)) {
+          master = {
+            key = "node-role.kubernetes.io/master";
+            value = "true";
+            effect = "NoSchedule";
+          };
+        };
+      };
     })
 
 
diff --git a/nixos/modules/services/cluster/kubernetes/flannel.nix b/nixos/modules/services/cluster/kubernetes/flannel.nix
index 38dc1e2b47d..fb70e6513d3 100644
--- a/nixos/modules/services/cluster/kubernetes/flannel.nix
+++ b/nixos/modules/services/cluster/kubernetes/flannel.nix
@@ -6,6 +6,9 @@ let
   top = config.services.kubernetes;
   cfg = top.flannel;
 
+  # we want flannel to use kubernetes itself as configuration backend, not direct etcd
+  storageBackend = "kubernetes";
+
   # needed for flannel to pass options to docker
   mkDockerOpts = pkgs.runCommand "mk-docker-opts" {
     buildInputs = [ pkgs.makeWrapper ];
@@ -29,6 +32,8 @@ in
 
       enable = mkDefault true;
       network = mkDefault top.clusterCidr;
+      inherit storageBackend;
+      nodeName = config.services.kubernetes.kubelet.hostname;
     };
 
     services.kubernetes.kubelet = {
@@ -69,11 +74,52 @@ in
     };
 
     services.kubernetes.pki.certs = {
-      flannelEtcdClient = top.lib.mkCert {
-        name = "flannel-etcd-client";
-        CN = "flannel-etcd-client";
+      flannelClient = top.lib.mkCert {
+        name = "flannel-client";
+        CN = "flannel-client";
         action = "systemctl restart flannel.service";
       };
     };
+
+    # give flannel som kubernetes rbac permissions if applicable
+    services.kubernetes.addonManager.bootstrapAddons = mkIf ((storageBackend == "kubernetes") && (elem "RBAC" top.apiserver.authorizationMode)) {
+
+      flannel-cr = {
+        apiVersion = "rbac.authorization.k8s.io/v1beta1";
+        kind = "ClusterRole";
+        metadata = { name = "flannel"; };
+        rules = [{
+          apiGroups = [ "" ];
+          resources = [ "pods" ];
+          verbs = [ "get" ];
+        }
+        {
+          apiGroups = [ "" ];
+          resources = [ "nodes" ];
+          verbs = [ "list" "watch" ];
+        }
+        {
+          apiGroups = [ "" ];
+          resources = [ "nodes/status" ];
+          verbs = [ "patch" ];
+        }];
+      };
+
+      flannel-crb = {
+        apiVersion = "rbac.authorization.k8s.io/v1beta1";
+        kind = "ClusterRoleBinding";
+        metadata = { name = "flannel"; };
+        roleRef = {
+          apiGroup = "rbac.authorization.k8s.io";
+          kind = "ClusterRole";
+          name = "flannel";
+        };
+        subjects = [{
+          kind = "User";
+          name = "flannel-client";
+        }];
+      };
+
+    };
   };
 }
diff --git a/nixos/modules/services/cluster/kubernetes/pki.nix b/nixos/modules/services/cluster/kubernetes/pki.nix
index 4587373d519..38deca23a99 100644
--- a/nixos/modules/services/cluster/kubernetes/pki.nix
+++ b/nixos/modules/services/cluster/kubernetes/pki.nix
@@ -305,7 +305,7 @@ in
         ''}
 
         ${optionalString top.flannel.enable ''
-          while [ ! -f ${cfg.certs.flannelEtcdClient.cert} ]; do sleep 1; done
+          while [ ! -f ${cfg.certs.flannelClient.cert} ]; do sleep 1; done
           echo "Restarting flannel..." >&1
           systemctl restart flannel
         ''}
@@ -313,22 +313,35 @@ in
         echo "Node joined succesfully"
       '')];
 
+      # isolate etcd on loopback at the master node
+      # easyCerts doesn't support multimaster clusters anyway atm.
       services.etcd = with cfg.certs.etcd; {
+        listenClientUrls = ["https://127.0.0.1:2379"];
+        listenPeerUrls = ["https://127.0.0.1:2380"];
+        advertiseClientUrls = ["https://etcd.local:2379"];
+        initialCluster = ["${top.masterAddress}=https://etcd.local:2380"];
+        initialAdvertisePeerUrls = ["https://etcd.local:2380"];
         certFile = mkDefault cert;
         keyFile = mkDefault key;
         trustedCaFile = mkDefault caCert;
       };
+      networking.extraHosts = mkIf (config.services.etcd.enable) ''
+        127.0.0.1 etcd.${top.addons.dns.clusterDomain} etcd.local
+      '';
 
-      services.flannel.etcd = with cfg.certs.flannelEtcdClient; {
-        certFile = mkDefault cert;
-        keyFile = mkDefault key;
-        caFile = mkDefault caCert;
+      services.flannel = with cfg.certs.flannelClient; {
+        kubeconfig = top.lib.mkKubeConfig "flannel" {
+          server = top.apiserverAddress;
+          certFile = cert;
+          keyFile = key;
+        };
       };
 
       services.kubernetes = {
 
         apiserver = mkIf top.apiserver.enable (with cfg.certs.apiServer; {
           etcd = with cfg.certs.apiserverEtcdClient; {
+            servers = ["https://etcd.local:2379"];
             certFile = mkDefault cert;
             keyFile = mkDefault key;
             caFile = mkDefault caCert;