Puppet Class: k8s::kubelet

Defined in:
modules/k8s/manifests/kubelet.pp

Overview

SPDX-License-Identifier: Apache-2.0

Class that sets up and configures kubelet

Parameters:

  • version (K8s::KubernetesVersion)
  • kubeconfig (String)
  • cni (Boolean)
  • kubelet_cert (Hash[String, Stdlib::Unixpath])
  • pod_infra_container_image (String)
  • cluster_domain (Stdlib::Fqdn) (defaults to: 'cluster.local')
  • cni_bin_dir (Stdlib::Unixpath) (defaults to: '/opt/cni/bin')
  • cni_conf_dir (Stdlib::Unixpath) (defaults to: '/etc/cni/net.d')
  • v_log_level (Integer) (defaults to: 0)
  • ipv6dualstack (Boolean) (defaults to: false)
  • listen_address (Optional[Stdlib::IP::Address]) (defaults to: undef)
  • docker_kubernetes_user_password (Optional[String]) (defaults to: undef)
  • cluster_dns (Optional[Array[Stdlib::IP::Address,1]]) (defaults to: undef)
  • node_labels (Optional[Array[String]]) (defaults to: [])
  • node_taints (Optional[Array[K8s::Core::V1Taint]]) (defaults to: [])
  • extra_params (Optional[Array[String]]) (defaults to: undef)
  • system_reserved (Optional[K8s::ReservedResource]) (defaults to: undef)


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
# File 'modules/k8s/manifests/kubelet.pp', line 3

class k8s::kubelet (
    K8s::KubernetesVersion $version,
    String $kubeconfig,
    Boolean $cni,
    Hash[String, Stdlib::Unixpath] $kubelet_cert,
    String $pod_infra_container_image,
    Stdlib::Fqdn $cluster_domain = 'cluster.local',
    Stdlib::Unixpath $cni_bin_dir = '/opt/cni/bin',
    Stdlib::Unixpath $cni_conf_dir = '/etc/cni/net.d',
    Integer $v_log_level = 0,
    Boolean $ipv6dualstack = false,
    Optional[Stdlib::IP::Address] $listen_address = undef,
    Optional[String] $docker_kubernetes_user_password = undef,
    Optional[Array[Stdlib::IP::Address,1]] $cluster_dns = undef,
    Optional[Array[String]] $node_labels = [],
    Optional[Array[K8s::Core::V1Taint]] $node_taints = [],
    Optional[Array[String]] $extra_params = undef,
    Optional[K8s::ReservedResource] $system_reserved = undef,
) {
    k8s::package { 'kubelet':
        package => 'node',
        version => $version,
    }
    # apparmor is needed for PodSecurityPolicy to be able to enforce profiles
    ensure_packages('apparmor')
    # socat is needed on k8s nodes for kubectl proxying to work
    ensure_packages('socat')

    # With k8s 1.23 we have aggregation layer support and can enable authentication/authorization
    # of requests against kubelet. Webhook mode uses the SubjectAccessReview API to determine authorization.
    $authentication = {
        anonymous => { enabled => false },
        webhook => { enabled => true },
        x509 => { clientCAFile => $kubelet_cert['chain'] },
    }
    $authorization = { mode => 'Webhook' }

    # Create the KubeletConfiguration YAML
    $config_yaml = {
        apiVersion         => 'kubelet.config.k8s.io/v1beta1',
        kind               => 'KubeletConfiguration',
        address            => $listen_address,
        tlsPrivateKeyFile  => $kubelet_cert['key'],
        tlsCertFile        => $kubelet_cert['cert'],
        clusterDomain      => $cluster_domain,
        clusterDNS         => $cluster_dns,
        # FIXME: Do we really need anonymous read only access to kubelets enabled?
        #
        # When kubelet is run without --config, --read-only-port defaults to 10255 (e.g. is enabled).
        # Using --config the default changes to 0 (e.g. disabled).
        # 10255 is used by prometheus to scrape kubelet and cadvisor metrics.
        readOnlyPort       => 10255,
        authentication     => $authentication,
        authorization      => $authorization,
        registerWithTaints => $node_taints,
        # Use systemd cgroup driver
        cgroupDriver       => 'systemd',
        # evictionHard is set to kubelet defaults apart from memory.available (which defaults to 100M)
        evictionHard       => {
            'imagefs.available' => '15%',
            'memory.available'  => '300M',
            'nodefs.available'  => '10%',
            'nodefs.inodesFree' => '5%',
        },
    }
    $config_file = '/etc/kubernetes/kubelet-config.yaml'
    file { $config_file:
        ensure  => file,
        owner   => 'kube',
        group   => 'kube',
        mode    => '0400',
        # FIXME: Warning: Calling function empty() with Numeric value is deprecated.
        content => $config_yaml.filter |$k, $v| { $v =~ NotUndef and !$v.empty }.to_yaml,
        notify  => Service['kubelet'],
        require => K8s::Package['kubelet'],
    }

    file { '/etc/default/kubelet':
        ensure  => file,
        owner   => 'root',
        group   => 'root',
        mode    => '0644',
        content => template('k8s/kubelet.default.erb'),
        notify  => Service['kubelet'],
    }

    file { [
        '/var/run/kubernetes',
        '/var/lib/kubelet',
    ]:
        ensure => directory,
        owner  => 'root',
        group  => 'root',
        mode   => '0700',
    }

    if $docker_kubernetes_user_password {
        # TODO: pass the docker registry to this class as a variable.
        docker::credentials { '/var/lib/kubelet/config.json':
            owner             => 'root',
            group             => 'root',
            registry          => 'docker-registry.discovery.wmnet',
            registry_username => 'kubernetes',
            registry_password => $docker_kubernetes_user_password,
        }
    }

    service { 'kubelet':
        ensure    => running,
        enable    => true,
        subscribe => [
            File[$kubeconfig],
        ],
    }
}