diff --git a/REFERENCE.md b/REFERENCE.md index 766d1f7..df70809 100644 --- a/REFERENCE.md +++ b/REFERENCE.md @@ -32,6 +32,7 @@ Uses the cni-plugins bridge binary to create a bridge interface to connect the c * [`k8s::server::resources::kube_proxy`](#k8s--server--resources--kube_proxy): Generates and deploys the default kube-proxy service for Kubernetes * [`k8s::server::scheduler`](#k8s--server--scheduler): Installs and configures a Kubernetes scheduler * [`k8s::server::tls`](#k8s--server--tls): Generates the necessary Kubernetes certificates for a server +* [`k8s::server::wait_online`](#k8s--server--wait_online): Creates a dummy exec to allow deferring applies until the Kubernetes API server has started ### Defined types @@ -2925,6 +2926,10 @@ Data type: `Stdlib::Unixpath` Default value: `$k8s::server::aggregator_ca_cert` +### `k8s::server::wait_online` + +Creates a dummy exec to allow deferring applies until the Kubernetes API server has started + ## Defined types ### `k8s::binary` diff --git a/lib/puppet/type/kubectl_apply.rb b/lib/puppet/type/kubectl_apply.rb index 028af3f..6a9fc15 100644 --- a/lib/puppet/type/kubectl_apply.rb +++ b/lib/puppet/type/kubectl_apply.rb @@ -148,7 +148,10 @@ def retrieve [self[:kubeconfig]] end autorequire(:service) do - ['k8s-apiserver'] + ['kube-apiserver'] + end + autorequire(:exec) do + ['k8s apiserver wait online'] end autorequire(:file) do [ diff --git a/manifests/node/kubelet.pp b/manifests/node/kubelet.pp index 4afca90..6945dcb 100644 --- a/manifests/node/kubelet.pp +++ b/manifests/node/kubelet.pp @@ -181,6 +181,7 @@ sysctl { default: ensure => $ensure, + silent => true, value => '1'; 'net.bridge.bridge-nf-call-iptables': diff --git a/manifests/server.pp b/manifests/server.pp index 394cb9b..a4edead 100644 --- a/manifests/server.pp +++ b/manifests/server.pp @@ -71,6 +71,7 @@ } if $manage_components { include k8s::server::apiserver + include k8s::server::wait_online # XXX Think of a better way to do this if $master == 'https://kubernetes:6443' { diff --git a/manifests/server/apiserver.pp b/manifests/server/apiserver.pp index ab72ace..4523cfa 100644 --- a/manifests/server/apiserver.pp +++ b/manifests/server/apiserver.pp @@ -250,6 +250,7 @@ }, }), } + # TODO: Create a dummy kube-apiserver service that just requires kubelet } else { $_sysconfig_path = pick($k8s::sysconfig_path, '/etc/sysconfig') file { "${_sysconfig_path}/kube-apiserver": @@ -280,13 +281,14 @@ ], notify => Service['kube-apiserver'], } - service { 'kube-apiserver': + Service <| title == 'etcd' |> + -> service { 'kube-apiserver': ensure => stdlib::ensure($ensure, 'service'), enable => true, subscribe => K8s::Binary['kube-apiserver'], } - Service['kube-apiserver'] -> Kubectl_apply<| |> ['kube-apiserver', 'front-proxy-client', 'apiserver-kubelet-client'].each |$cert| { + ['kube-apiserver', 'front-proxy-client', 'apiserver-kubelet-client'].each |$cert| { if defined(K8s::Server::Tls::Cert[$cert]) { K8s::Server::Tls::Cert[$cert] ~> Service['kube-apiserver'] } diff --git a/manifests/server/wait_online.pp b/manifests/server/wait_online.pp new file mode 100644 index 0000000..4cd2d1c --- /dev/null +++ b/manifests/server/wait_online.pp @@ -0,0 +1,16 @@ +# @summary Creates a dummy exec to allow deferring applies until the Kubernetes API server has started +class k8s::server::wait_online { + # Wait up to 30 seconds for kube-apiserver to start + exec { 'k8s apiserver wait online': + command => 'kubectl --kubeconfig /root/.kube/config version', + path => $facts['path'], + refreshonly => true, + tries => 15, + try_sleep => 2, + } + + # Require possibly managed components before checking online state + Kubeconfig <| title == '/root/.kube/config' |> -> Exec['k8s apiserver wait online'] + K8s::Binary <| title == 'kubectl' |> -> Exec['k8s apiserver wait online'] + Service <| title == 'kube-apiserver' |> ~> Exec['k8s apiserver wait online'] +} diff --git a/spec/classes/server/wait_online_spec.rb b/spec/classes/server/wait_online_spec.rb new file mode 100644 index 0000000..5e6be7c --- /dev/null +++ b/spec/classes/server/wait_online_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'k8s::server::wait_online' do + let(:pre_condition) do + <<~PUPPET + function assert_private() {} + + include ::k8s + class { '::k8s::server': + manage_etcd => false, + manage_certs => true, + manage_components => false, + manage_resources => false, + node_on_server => false, + } + class { '::k8s::server::apiserver': + etcd_servers => [], + } + PUPPET + end + + on_supported_os.each do |os, os_facts| + context "on #{os}" do + let(:facts) { os_facts } + + it { is_expected.to compile } + + it do + is_expected.to contain_exec('k8s apiserver wait online'). + that_requires('Kubeconfig[/root/.kube/config]'). + that_requires('K8s::Binary[kubectl]'). + that_requires('Service[kube-apiserver]') + end + end + end +end