about summary refs log tree commit diff
path: root/nixos/modules/services/cluster/kubernetes/dns.nix
blob: 939f58fc41b78c1d5a0db079d25c539337c98a3e (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
{ config, pkgs, lib, ... }:

with lib;

let
  version = "1.14.4";

  k8s-dns-kube-dns = pkgs.dockerTools.pullImage {
    imageName = "gcr.io/google_containers/k8s-dns-kube-dns-amd64";
    finalImageTag = version;
    sha256 = "0q97xfqrigrfjl2a9cxl5in619py0zv44gch09jm8gqjkxl80imp";
    imageDigest = "sha256:40790881bbe9ef4ae4ff7fe8b892498eecb7fe6dcc22661402f271e03f7de344";
  };

  k8s-dns-dnsmasq-nanny = pkgs.dockerTools.pullImage {
    imageName = "gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64";
    finalImageTag = version;
    sha256 = "051w5ca4qb88mwva4hbnh9xzlsvv7k1mbk3wz50lmig2mqrqqx6c";
    imageDigest = "sha256:aeeb994acbc505eabc7415187cd9edb38cbb5364dc1c2fc748154576464b3dc2";
  };

  k8s-dns-sidecar = pkgs.dockerTools.pullImage {
    imageName = "gcr.io/google_containers/k8s-dns-sidecar-amd64";
    finalImageTag = version;
    sha256 = "1z0d129bcm8i2cqq36x5jhnrv9hirj8c6kjrmdav8vgf7py78vsm";
    imageDigest = "sha256:97074c951046e37d3cbb98b82ae85ed15704a290cce66a8314e7f846404edde9";
  };

  cfg = config.services.kubernetes.addons.dns;
in {
  options.services.kubernetes.addons.dns = {
    enable = mkEnableOption "kubernetes dns addon";

    clusterIp = mkOption {
      description = "Dns addon clusterIP";

      # this default is also what kubernetes users
      default = (
        concatStringsSep "." (
          take 3 (splitString "." config.services.kubernetes.apiserver.serviceClusterIpRange
        ))
      ) + ".254";
      type = types.str;
    };

    clusterDomain = mkOption {
      description = "Dns cluster domain";
      default = "cluster.local";
      type = types.str;
    };
  };

  config = mkIf cfg.enable {
    services.kubernetes.kubelet.seedDockerImages = [
      k8s-dns-kube-dns
      k8s-dns-dnsmasq-nanny
      k8s-dns-sidecar
    ];

    services.kubernetes.addonManager.addons = {
      kubedns-deployment = {
        apiVersion = "apps/v1beta1";
        kind = "Deployment";
        metadata = {
          labels = {
            "addonmanager.kubernetes.io/mode" = "Reconcile";
            "k8s-app" = "kube-dns";
            "kubernetes.io/cluster-service" = "true";
          };
          name = "kube-dns";
          namespace = "kube-system";
        };
        spec = {
          selector.matchLabels."k8s-app" = "kube-dns";
          strategy = {
            rollingUpdate = {
              maxSurge = "10%";
              maxUnavailable = 0;
            };
          };
          template = {
            metadata = {
              annotations."scheduler.alpha.kubernetes.io/critical-pod" = "";
              labels.k8s-app = "kube-dns";
            };
            spec = {
              containers = [
                {
                  name = "kubedns";
                  args = [
                    "--domain=${cfg.clusterDomain}"
                    "--dns-port=10053"
                    "--config-dir=/kube-dns-config"
                    "--v=2"
                  ];
                  env = [
                    {
                      name = "PROMETHEUS_PORT";
                      value = "10055";
                    }
                  ];
                  image = "gcr.io/google_containers/k8s-dns-kube-dns-amd64:${version}";
                  livenessProbe = {
                    failureThreshold = 5;
                    httpGet = {
                      path = "/healthcheck/kubedns";
                      port = 10054;
                      scheme = "HTTP";
                    };
                    initialDelaySeconds = 60;
                    successThreshold = 1;
                    timeoutSeconds = 5;
                  };
                  ports = [
                    {
                      containerPort = 10053;
                      name = "dns-local";
                      protocol = "UDP";
                    }
                    {
                      containerPort = 10053;
                      name = "dns-tcp-local";
                      protocol = "TCP";
                    }
                    {
                      containerPort = 10055;
                      name = "metrics";
                      protocol = "TCP";
                    }
                  ];
                  readinessProbe = {
                    httpGet = {
                      path = "/readiness";
                      port = 8081;
                      scheme = "HTTP";
                    };
                    initialDelaySeconds = 3;
                    timeoutSeconds = 5;
                  };
                  resources = {
                    limits.memory = "170Mi";
                    requests = {
                      cpu = "100m";
                      memory = "70Mi";
                    };
                  };
                  volumeMounts = [
                    {
                      mountPath = "/kube-dns-config";
                      name = "kube-dns-config";
                    }
                  ];
                }
                {
                  args = [
                    "-v=2"
                    "-logtostderr"
                    "-configDir=/etc/k8s/dns/dnsmasq-nanny"
                    "-restartDnsmasq=true"
                    "--"
                    "-k"
                    "--cache-size=1000"
                    "--log-facility=-"
                    "--server=/${cfg.clusterDomain}/127.0.0.1#10053"
                    "--server=/in-addr.arpa/127.0.0.1#10053"
                    "--server=/ip6.arpa/127.0.0.1#10053"
                  ];
                  image = "gcr.io/google_containers/k8s-dns-dnsmasq-nanny-amd64:${version}";
                  livenessProbe = {
                    failureThreshold = 5;
                    httpGet = {
                      path = "/healthcheck/dnsmasq";
                      port = 10054;
                      scheme = "HTTP";
                    };
                    initialDelaySeconds = 60;
                    successThreshold = 1;
                    timeoutSeconds = 5;
                  };
                  name = "dnsmasq";
                  ports = [
                    {
                      containerPort = 53;
                      name = "dns";
                      protocol = "UDP";
                    }
                    {
                      containerPort = 53;
                      name = "dns-tcp";
                      protocol = "TCP";
                    }
                  ];
                  resources = {
                    requests = {
                      cpu = "150m";
                      memory = "20Mi";
                    };
                  };
                  volumeMounts = [
                    {
                      mountPath = "/etc/k8s/dns/dnsmasq-nanny";
                      name = "kube-dns-config";
                    }
                  ];
                }
                {
                  name = "sidecar";
                  image = "gcr.io/google_containers/k8s-dns-sidecar-amd64:${version}";
                  args = [
                    "--v=2"
                    "--logtostderr"
                    "--probe=kubedns,127.0.0.1:10053,kubernetes.default.svc.${cfg.clusterDomain},5,A"
                    "--probe=dnsmasq,127.0.0.1:53,kubernetes.default.svc.${cfg.clusterDomain},5,A"
                  ];
                  livenessProbe = {
                    failureThreshold = 5;
                    httpGet = {
                      path = "/metrics";
                      port = 10054;
                      scheme = "HTTP";
                    };
                    initialDelaySeconds = 60;
                    successThreshold = 1;
                    timeoutSeconds = 5;
                  };
                  ports = [
                    {
                      containerPort = 10054;
                      name = "metrics";
                      protocol = "TCP";
                    }
                  ];
                  resources = {
                    requests = {
                      cpu = "10m";
                      memory = "20Mi";
                    };
                  };
                }
              ];
              dnsPolicy = "Default";
              serviceAccountName = "kube-dns";
              tolerations = [
                {
                  key = "CriticalAddonsOnly";
                  operator = "Exists";
                }
              ];
              volumes = [
                {
                  configMap = {
                    name = "kube-dns";
                    optional = true;
                  };
                  name = "kube-dns-config";
                }
              ];
            };
          };
        };
      };

      kubedns-svc = {
        apiVersion = "v1";
        kind = "Service";
        metadata = {
          labels = {
            "addonmanager.kubernetes.io/mode" = "Reconcile";
            "k8s-app" = "kube-dns";
            "kubernetes.io/cluster-service" = "true";
            "kubernetes.io/name" = "KubeDNS";
          };
          name = "kube-dns";
          namespace  = "kube-system";
        };
        spec = {
          clusterIP = cfg.clusterIp;
          ports = [
            {name = "dns"; port = 53; protocol = "UDP";}
            {name = "dns-tcp"; port = 53; protocol = "TCP";}
          ];
          selector.k8s-app = "kube-dns";
        };
      };

      kubedns-sa = {
        apiVersion = "v1";
        kind = "ServiceAccount";
        metadata = {
          name = "kube-dns";
          namespace = "kube-system";
          labels = {
            "kubernetes.io/cluster-service" = "true";
            "addonmanager.kubernetes.io/mode" = "Reconcile";
          };
        };
      };

      kubedns-cm = {
        apiVersion = "v1";
        kind = "ConfigMap";
        metadata = {
          name = "kube-dns";
          namespace = "kube-system";
          labels = {
            "addonmanager.kubernetes.io/mode" = "EnsureExists";
          };
        };
      };
    };

    services.kubernetes.kubelet.clusterDns = mkDefault cfg.clusterIp;
  };
}