Skip to content

Commit 1948118

Browse files
twexlernyodas
authored andcommitted
patch from PR# 133654
datadog:patch
1 parent e287a78 commit 1948118

File tree

3 files changed

+117
-3
lines changed

3 files changed

+117
-3
lines changed

pkg/kubelet/kubelet.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -918,6 +918,13 @@ func NewMainKubelet(ctx context.Context,
918918
}
919919
return cert, nil
920920
}
921+
922+
// GetCertificate is only preferred over the certificate files by
923+
// Golang TLS if the ClientHelloInfo.ServerName is set, which it is
924+
// not when connecting to a host by IP address. Clear the files to
925+
// force the use of GetCertificate.
926+
kubeDeps.TLSOptions.CertFile = ""
927+
kubeDeps.TLSOptions.KeyFile = ""
921928
}
922929
}
923930

pkg/kubelet/server/server.go

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,9 +192,6 @@ func ListenAndServeKubeletServer(
192192

193193
if tlsOptions != nil {
194194
s.TLSConfig = tlsOptions.Config
195-
// Passing empty strings as the cert and key files means no
196-
// cert/keys are specified and GetCertificate in the TLSConfig
197-
// should be called instead.
198195
if err := s.ListenAndServeTLS(tlsOptions.CertFile, tlsOptions.KeyFile); err != nil {
199196
klog.ErrorS(err, "Failed to listen and serve")
200197
os.Exit(1)

test/e2e_node/kubelet_tls_test.go

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
Copyright 2025 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package e2enode
18+
19+
import (
20+
"context"
21+
"crypto/tls"
22+
"crypto/x509"
23+
"fmt"
24+
"net"
25+
"os"
26+
"path/filepath"
27+
28+
"github.com/onsi/ginkgo/v2"
29+
"github.com/onsi/gomega"
30+
"k8s.io/client-go/util/cert"
31+
"k8s.io/kubernetes/pkg/cluster/ports"
32+
kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
33+
"k8s.io/kubernetes/test/e2e/framework"
34+
)
35+
36+
func createCertAndKeyFiles(certDir string) (string, string, error) {
37+
cert, key, err := cert.GenerateSelfSignedCertKey(
38+
"localhost",
39+
[]net.IP{{127, 0, 0, 1}},
40+
[]string{"localhost"},
41+
)
42+
if err != nil {
43+
return "", "", nil
44+
}
45+
46+
certPath := filepath.Join(certDir, "kubelet.cert")
47+
keyPath := filepath.Join(certDir, "kubelet.key")
48+
if err = os.WriteFile(certPath, cert, os.FileMode(0644)); err != nil {
49+
return "", "", err
50+
}
51+
52+
if err = os.WriteFile(keyPath, key, os.FileMode(0600)); err != nil {
53+
return "", "", err
54+
}
55+
56+
return certPath, keyPath, nil
57+
}
58+
59+
func getCert(addr string) (*x509.Certificate, error) {
60+
conn, err := tls.Dial("tcp", addr, &tls.Config{InsecureSkipVerify: true})
61+
if err != nil {
62+
return nil, err
63+
}
64+
defer func() { _ = conn.Close() }()
65+
66+
return conn.ConnectionState().PeerCertificates[0], nil
67+
}
68+
69+
var _ = SIGDescribe("KubletTLS", framework.WithSerial(), framework.WithNodeConformance(), func() {
70+
f := framework.NewDefaultFramework("kubelet-tls-test")
71+
72+
ginkgo.Context("certificate reload", func() {
73+
var tempDir string
74+
75+
t := ginkgo.GinkgoT()
76+
ginkgo.BeforeEach(func(ctx context.Context) {
77+
tempDir = t.TempDir()
78+
cfg, err := getCurrentKubeletConfig(ctx)
79+
framework.ExpectNoError(err)
80+
ginkgo.DeferCleanup(func(ctx context.Context, cfg *kubeletconfig.KubeletConfiguration) {
81+
updateKubeletConfig(ctx, f, cfg, true)
82+
}, cfg.DeepCopy())
83+
84+
certPath, keyPath, err := createCertAndKeyFiles(tempDir)
85+
framework.ExpectNoError(err)
86+
87+
cfg.TLSCertFile = certPath
88+
cfg.TLSPrivateKeyFile = keyPath
89+
updateKubeletConfig(ctx, f, cfg, true)
90+
})
91+
92+
ginkgo.It("should reload certificates from disk", func(ctx context.Context) {
93+
addr := fmt.Sprintf("127.0.0.1:%d", ports.KubeletPort)
94+
oldCert, err := getCert(addr)
95+
framework.ExpectNoError(err)
96+
97+
_, _, err = createCertAndKeyFiles(tempDir)
98+
framework.ExpectNoError(err)
99+
100+
gomega.Eventually(ctx, func(ctx context.Context) (bool, error) {
101+
newCert, err := getCert(addr)
102+
if err != nil {
103+
return true, err
104+
}
105+
106+
return newCert.Equal(oldCert), nil
107+
}).Should(gomega.BeFalseBecause("new certificate should be loaded"))
108+
})
109+
})
110+
})

0 commit comments

Comments
 (0)