Skip to content

Commit

Permalink
fix: update in-cluster kubeconfig validity to match other certs
Browse files Browse the repository at this point in the history
Talos generates in-cluster kubeconfig for the kube-scheduler and
kube-controller-manager to authenticate to kube-apiserver. Bug was that
validity of that kubeconfig was set to 24h by mistake. Fix that by
bumping validity to default for other Kubernetes certs (1 year).

Add a certificate refresh at 50% of the validity.

Fix bugs with copying secret resources which was leading to updates not
being propagated correctly.

Signed-off-by: Andrey Smirnov <smirnov.andrey@gmail.com>
  • Loading branch information
smira authored and talos-bot committed Mar 1, 2021
1 parent c2f7a4b commit 31e56e6
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
19 changes: 14 additions & 5 deletions internal/app/machined/pkg/controllers/secrets/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ import (
"github.com/talos-systems/talos/pkg/resources/v1alpha1"
)

// KubernetesCertificateValidityDuration is the validity duration for the certificates created with this controller.
//
// Controller automatically refreshes certs at 50% of CertificateValidityDuration.
const KubernetesCertificateValidityDuration = constants.KubernetesDefaultCertificateValidityDuration

// KubernetesController manages secrets.Kubernetes based on configuration.
type KubernetesController struct{}

Expand Down Expand Up @@ -66,11 +71,15 @@ func (ctrl *KubernetesController) Run(ctx context.Context, r controller.Runtime,
return fmt.Errorf("error setting up dependencies: %w", err)
}

refreshTicker := time.NewTicker(KubernetesCertificateValidityDuration / 2)
defer refreshTicker.Stop()

for {
select {
case <-ctx.Done():
return nil
case <-r.EventCh():
case <-refreshTicker.C:
}

k8sRootRes, err := r.Get(ctx, resource.NewMetadata(secrets.NamespaceName, secrets.RootType, secrets.RootKubernetesID, resource.VersionUndefined))
Expand Down Expand Up @@ -149,7 +158,7 @@ func (ctrl *KubernetesController) updateSecrets(k8sRoot *secrets.RootKubernetesS
x509.DNSNames(altNames.DNSNames),
x509.CommonName("kube-apiserver"),
x509.Organization("kube-master"),
x509.NotAfter(time.Now().Add(constants.KubernetesDefaultCertificateValidityDuration)),
x509.NotAfter(time.Now().Add(KubernetesCertificateValidityDuration)),
)
if err != nil {
return fmt.Errorf("failed to generate api-server cert: %w", err)
Expand All @@ -160,7 +169,7 @@ func (ctrl *KubernetesController) updateSecrets(k8sRoot *secrets.RootKubernetesS
apiServerKubeletClient, err := x509.NewKeyPair(ca,
x509.CommonName(constants.KubernetesAdminCertCommonName),
x509.Organization(constants.KubernetesAdminCertOrganization),
x509.NotAfter(time.Now().Add(constants.KubernetesDefaultCertificateValidityDuration)),
x509.NotAfter(time.Now().Add(KubernetesCertificateValidityDuration)),
)
if err != nil {
return fmt.Errorf("failed to generate api-server cert: %w", err)
Expand All @@ -175,7 +184,7 @@ func (ctrl *KubernetesController) updateSecrets(k8sRoot *secrets.RootKubernetesS

frontProxy, err := x509.NewKeyPair(aggregatorCA,
x509.CommonName("front-proxy-client"),
x509.NotAfter(time.Now().Add(constants.KubernetesDefaultCertificateValidityDuration)),
x509.NotAfter(time.Now().Add(KubernetesCertificateValidityDuration)),
)
if err != nil {
return fmt.Errorf("failed to generate aggregator cert: %w", err)
Expand Down Expand Up @@ -256,6 +265,6 @@ func (adapter *generateAdminAdapter) AdminKubeconfig() config.AdminKubeconfig {
}

func (adapter *generateAdminAdapter) CertLifetime() time.Duration {
// this certificate is not delivered to the user, it's used only internally by Talos
return x509.DefaultCertificateValidityDuration
// this certificate is not delivered to the user, it's used only internally by control plane components
return KubernetesCertificateValidityDuration
}
3 changes: 2 additions & 1 deletion internal/integration/api/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"github.com/talos-systems/talos/internal/integration/base"
"github.com/talos-systems/talos/pkg/machinery/api/machine"
"github.com/talos-systems/talos/pkg/machinery/client"
machinetype "github.com/talos-systems/talos/pkg/machinery/config/types/v1alpha1/machine"
)

// EventsSuite verifies Events API.
Expand All @@ -36,7 +37,7 @@ func (suite *EventsSuite) SetupTest() {
// make sure API calls have timeout
suite.ctx, suite.ctxCancel = context.WithTimeout(context.Background(), 30*time.Second)

suite.nodeCtx = client.WithNodes(suite.ctx, suite.RandomDiscoveredNode())
suite.nodeCtx = client.WithNodes(suite.ctx, suite.RandomDiscoveredNode(machinetype.TypeJoin))
}

// TearDownTest ...
Expand Down
8 changes: 5 additions & 3 deletions pkg/resources/secrets/etcd.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const EtcdID = resource.ID("etcd")
// Etcd contains etcd generated secrets.
type Etcd struct {
md resource.Metadata
spec interface{}
spec *EtcdCertsSpec
}

// EtcdCertsSpec describes etcd certs secrets.
Expand Down Expand Up @@ -57,9 +57,11 @@ func (r *Etcd) String() string {

// DeepCopy implements resource.Resource.
func (r *Etcd) DeepCopy() resource.Resource {
specCopy := *r.spec

return &Etcd{
md: r.md,
spec: r.spec,
spec: &specCopy,
}
}

Expand All @@ -74,5 +76,5 @@ func (r *Etcd) ResourceDefinition() core.ResourceDefinitionSpec {

// Certs returns .spec.
func (r *Etcd) Certs() *EtcdCertsSpec {
return r.spec.(*EtcdCertsSpec)
return r.spec
}
8 changes: 5 additions & 3 deletions pkg/resources/secrets/kubernetes.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ const KubernetesID = resource.ID("k8s-certs")
// Kubernetes contains K8s generated secrets.
type Kubernetes struct {
md resource.Metadata
spec interface{}
spec *KubernetesCertsSpec
}

// KubernetesCertsSpec describes generated Kubernetes certificates.
Expand Down Expand Up @@ -61,9 +61,11 @@ func (r *Kubernetes) String() string {

// DeepCopy implements resource.Resource.
func (r *Kubernetes) DeepCopy() resource.Resource {
specCopy := *r.spec

return &Kubernetes{
md: r.md,
spec: r.spec,
spec: &specCopy,
}
}

Expand All @@ -78,5 +80,5 @@ func (r *Kubernetes) ResourceDefinition() core.ResourceDefinitionSpec {

// Certs returns .spec.
func (r *Kubernetes) Certs() *KubernetesCertsSpec {
return r.spec.(*KubernetesCertsSpec)
return r.spec
}
15 changes: 14 additions & 1 deletion pkg/resources/secrets/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,9 +86,22 @@ func (r *Root) String() string {

// DeepCopy implements resource.Resource.
func (r *Root) DeepCopy() resource.Resource {
var specCopy interface{}

switch v := r.spec.(type) {
case *RootEtcdSpec:
vv := *v
specCopy = &vv
case *RootKubernetesSpec:
vv := *v
specCopy = &vv
default:
panic("unexpected spec type")
}

return &Root{
md: r.md,
spec: r.spec,
spec: specCopy,
}
}

Expand Down

0 comments on commit 31e56e6

Please sign in to comment.