@@ -20,6 +20,8 @@ import (
20
20
"context"
21
21
"crypto/x509"
22
22
"fmt"
23
+ "os"
24
+ "path"
23
25
"path/filepath"
24
26
"strings"
25
27
"time"
@@ -34,12 +36,15 @@ import (
34
36
"k8s.io/client-go/tools/clientcmd"
35
37
certutil "k8s.io/client-go/util/cert"
36
38
"k8s.io/klog/v2"
39
+ kubeletconfig "k8s.io/kubelet/config/v1beta1"
40
+ "sigs.k8s.io/yaml"
37
41
38
42
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
39
43
kubeadmscheme "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/scheme"
40
44
kubeadmapiv1 "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1beta4"
41
45
"k8s.io/kubernetes/cmd/kubeadm/app/componentconfigs"
42
46
"k8s.io/kubernetes/cmd/kubeadm/app/constants"
47
+ "k8s.io/kubernetes/cmd/kubeadm/app/features"
43
48
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
44
49
"k8s.io/kubernetes/cmd/kubeadm/app/util/config/strict"
45
50
"k8s.io/kubernetes/cmd/kubeadm/app/util/output"
@@ -111,7 +116,7 @@ func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Inte
111
116
if ! newControlPlane {
112
117
// gets the nodeRegistration for the current from the node object
113
118
kubeconfigFile := filepath .Join (kubeconfigDir , constants .KubeletKubeConfigFileName )
114
- if err := GetNodeRegistration (kubeconfigFile , client , & initcfg .NodeRegistration ); err != nil {
119
+ if err := GetNodeRegistration (kubeconfigFile , client , & initcfg .NodeRegistration , & initcfg . ClusterConfiguration ); err != nil {
115
120
return nil , errors .Wrap (err , "failed to get node registration" )
116
121
}
117
122
// gets the APIEndpoint for the current node
@@ -123,7 +128,7 @@ func getInitConfigurationFromCluster(kubeconfigDir string, client clientset.Inte
123
128
}
124
129
125
130
// GetNodeRegistration returns the nodeRegistration for the current node
126
- func GetNodeRegistration (kubeconfigFile string , client clientset.Interface , nodeRegistration * kubeadmapi.NodeRegistrationOptions ) error {
131
+ func GetNodeRegistration (kubeconfigFile string , client clientset.Interface , nodeRegistration * kubeadmapi.NodeRegistrationOptions , clusterCfg * kubeadmapi. ClusterConfiguration ) error {
127
132
// gets the name of the current node
128
133
nodeName , err := getNodeNameFromKubeletConfig (kubeconfigFile )
129
134
if err != nil {
@@ -136,9 +141,30 @@ func GetNodeRegistration(kubeconfigFile string, client clientset.Interface, node
136
141
return errors .Wrap (err , "failed to get corresponding node" )
137
142
}
138
143
139
- criSocket , ok := node .ObjectMeta .Annotations [constants .AnnotationKubeadmCRISocket ]
140
- if ! ok {
141
- return errors .Errorf ("node %s doesn't have %s annotation" , nodeName , constants .AnnotationKubeadmCRISocket )
144
+ var (
145
+ criSocket string
146
+ ok bool
147
+ missingAnnotationError = errors .Errorf ("node %s doesn't have %s annotation" , nodeName , constants .AnnotationKubeadmCRISocket )
148
+ )
149
+ if features .Enabled (clusterCfg .FeatureGates , features .NodeLocalCRISocket ) {
150
+ _ , err = os .Stat (filepath .Join (constants .KubeletRunDirectory , constants .KubeletInstanceConfigurationFileName ))
151
+ if os .IsNotExist (err ) {
152
+ criSocket , ok = node .ObjectMeta .Annotations [constants .AnnotationKubeadmCRISocket ]
153
+ if ! ok {
154
+ return missingAnnotationError
155
+ }
156
+ } else {
157
+ kubeletConfig , err := readKubeletConfig (constants .KubeletRunDirectory , constants .KubeletInstanceConfigurationFileName )
158
+ if err != nil {
159
+ return errors .Wrapf (err , "node %q does not have a kubelet instance configuration" , nodeName )
160
+ }
161
+ criSocket = kubeletConfig .ContainerRuntimeEndpoint
162
+ }
163
+ } else {
164
+ criSocket , ok = node .ObjectMeta .Annotations [constants .AnnotationKubeadmCRISocket ]
165
+ if ! ok {
166
+ return missingAnnotationError
167
+ }
142
168
}
143
169
144
170
// returns the nodeRegistration attributes
@@ -253,3 +279,20 @@ func getRawAPIEndpointFromPodAnnotationWithoutRetry(ctx context.Context, client
253
279
}
254
280
return "" , errors .Errorf ("API server pod for node name %q hasn't got a %q annotation, cannot retrieve API endpoint" , nodeName , constants .KubeAPIServerAdvertiseAddressEndpointAnnotationKey )
255
281
}
282
+
283
+ // readKubeletConfig reads a KubeletConfiguration from the specified file.
284
+ func readKubeletConfig (kubeletDir , fileName string ) (* kubeletconfig.KubeletConfiguration , error ) {
285
+ kubeletFile := path .Join (kubeletDir , fileName )
286
+
287
+ data , err := os .ReadFile (kubeletFile )
288
+ if err != nil {
289
+ return nil , errors .Wrapf (err , "could not read kubelet configuration file %q" , kubeletFile )
290
+ }
291
+
292
+ var config kubeletconfig.KubeletConfiguration
293
+ if err := yaml .Unmarshal (data , & config ); err != nil {
294
+ return nil , errors .Wrapf (err , "could not parse kubelet configuration file %q" , kubeletFile )
295
+ }
296
+
297
+ return & config , nil
298
+ }
0 commit comments