1{
2 config,
3 lib,
4 options,
5 pkgs,
6 ...
7}:
8
9with lib;
10
11let
12 top = config.services.kubernetes;
13 otop = options.services.kubernetes;
14 cfg = top.proxy;
15in
16{
17 imports = [
18 (mkRenamedOptionModule
19 [ "services" "kubernetes" "proxy" "address" ]
20 [ "services" "kubernetes" "proxy" "bindAddress" ]
21 )
22 ];
23
24 ###### interface
25 options.services.kubernetes.proxy = with lib.types; {
26
27 bindAddress = mkOption {
28 description = "Kubernetes proxy listening address.";
29 default = "0.0.0.0";
30 type = str;
31 };
32
33 enable = mkEnableOption "Kubernetes proxy";
34
35 extraOpts = mkOption {
36 description = "Kubernetes proxy extra command line options.";
37 default = "";
38 type = separatedString " ";
39 };
40
41 featureGates = mkOption {
42 description = "Attribute set of feature gates.";
43 default = top.featureGates;
44 defaultText = literalExpression "config.${otop.featureGates}";
45 type = attrsOf bool;
46 };
47
48 hostname = mkOption {
49 description = "Kubernetes proxy hostname override.";
50 default = config.networking.hostName;
51 defaultText = literalExpression "config.networking.hostName";
52 type = str;
53 };
54
55 kubeconfig = top.lib.mkKubeConfigOptions "Kubernetes proxy";
56
57 verbosity = mkOption {
58 description = ''
59 Optional glog verbosity level for logging statements. See
60 <https://github.com/kubernetes/community/blob/master/contributors/devel/logging.md>
61 '';
62 default = null;
63 type = nullOr int;
64 };
65
66 };
67
68 ###### implementation
69 config = mkIf cfg.enable {
70 systemd.services.kube-proxy = {
71 description = "Kubernetes Proxy Service";
72 wantedBy = [ "kubernetes.target" ];
73 after = [ "kube-apiserver.service" ];
74 path = with pkgs; [
75 iptables
76 conntrack-tools
77 ];
78 serviceConfig = {
79 Slice = "kubernetes.slice";
80 ExecStart = ''
81 ${top.package}/bin/kube-proxy \
82 --bind-address=${cfg.bindAddress} \
83 ${optionalString (top.clusterCidr != null) "--cluster-cidr=${top.clusterCidr}"} \
84 ${
85 optionalString (cfg.featureGates != { })
86 "--feature-gates=${
87 concatStringsSep "," (
88 builtins.attrValues (mapAttrs (n: v: "${n}=${trivial.boolToString v}") cfg.featureGates)
89 )
90 }"
91 } \
92 --hostname-override=${cfg.hostname} \
93 --kubeconfig=${top.lib.mkKubeConfig "kube-proxy" cfg.kubeconfig} \
94 ${optionalString (cfg.verbosity != null) "--v=${toString cfg.verbosity}"} \
95 ${cfg.extraOpts}
96 '';
97 WorkingDirectory = top.dataDir;
98 Restart = "on-failure";
99 RestartSec = 5;
100 };
101 unitConfig = {
102 StartLimitIntervalSec = 0;
103 };
104 };
105
106 services.kubernetes.proxy.hostname = with config.networking; mkDefault hostName;
107
108 services.kubernetes.pki.certs = {
109 kubeProxyClient = top.lib.mkCert {
110 name = "kube-proxy-client";
111 CN = "system:kube-proxy";
112 action = "systemctl restart kube-proxy.service";
113 };
114 };
115
116 services.kubernetes.proxy.kubeconfig.server = mkDefault top.apiserverAddress;
117 };
118
119 meta.buildDocsInSandbox = false;
120}