Skip to content

Commit ba78454

Browse files
authored
Merge pull request #213 from Vacant2333/fix-replace-attach-script
fix: replace the attach-script's runtime configurations
2 parents 7aaeb79 + a411981 commit ba78454

File tree

1 file changed

+30
-26
lines changed

1 file changed

+30
-26
lines changed

pkg/providers/ack/ack.go

Lines changed: 30 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
"errors"
2525
"fmt"
2626
"net/http"
27+
"regexp"
2728
"sort"
2829
"strings"
2930
"sync"
@@ -106,21 +107,23 @@ func (p *DefaultProvider) GetClusterCNI(_ context.Context) (string, error) {
106107
return p.clusterCNI, nil
107108
}
108109

109-
// Get the ID of the target nodepool id when DescribeClusterAttachScriptsRequest.
110-
// If there is no default nodepool, select the nodepool with the most HealthyNodes.
110+
// We need to manually retrieve the runtime configuration of the nodepool, with the default node pool prioritized.
111+
// If there is no default node pool, we will choose the runtime configuration of the node pool with the most HealthyNodes.
112+
// In some cases, the DescribeClusterAttachScripts interface may return the Docker runtime in clusters running version 1.24,
113+
// even though Docker runtime only supports clusters of version 1.22 and below.
111114
//
112115
//nolint:gocyclo
113-
func (p *DefaultProvider) getTargetNodePoolID(ctx context.Context) (*string, error) {
116+
func (p *DefaultProvider) getClusterAttachRuntimeConfiguration(ctx context.Context) (string, string, error) {
114117
resp, err := p.ackClient.DescribeClusterNodePools(tea.String(p.clusterID), &ackclient.DescribeClusterNodePoolsRequest{})
115118
if err != nil {
116119
log.FromContext(ctx).Error(err, "Failed to describe cluster nodepools")
117-
return nil, err
120+
return "", "", err
118121
}
119122
if resp == nil || resp.Body == nil || resp.Body.Nodepools == nil {
120-
return nil, fmt.Errorf("empty describe cluster nodepools response")
123+
return "", "", fmt.Errorf("empty describe cluster nodepools response")
121124
}
122125
if len(resp.Body.Nodepools) == 0 {
123-
return nil, fmt.Errorf("no nodepool found")
126+
return "", "", fmt.Errorf("no nodepool found")
124127
}
125128

126129
nodepools := resp.Body.Nodepools
@@ -145,10 +148,12 @@ func (p *DefaultProvider) getTargetNodePoolID(ctx context.Context) (*string, err
145148
})
146149

147150
targetNodepool := nodepools[0]
148-
if targetNodepool.NodepoolInfo == nil {
149-
return nil, fmt.Errorf("target describe cluster nodepool is empty")
151+
if targetNodepool.KubernetesConfig == nil || targetNodepool.KubernetesConfig.Runtime == nil ||
152+
targetNodepool.KubernetesConfig.RuntimeVersion == nil {
153+
return "", "", fmt.Errorf("target describe cluster nodepool is empty")
150154
}
151-
return targetNodepool.NodepoolInfo.NodepoolId, nil
155+
return tea.StringValue(targetNodepool.KubernetesConfig.Runtime),
156+
tea.StringValue(targetNodepool.KubernetesConfig.RuntimeVersion), nil
152157
}
153158

154159
func (p *DefaultProvider) GetNodeRegisterScript(ctx context.Context,
@@ -161,34 +166,34 @@ func (p *DefaultProvider) GetNodeRegisterScript(ctx context.Context,
161166
return p.resolveUserData(cachedScript.(string), labels, nodeClaim, kubeletCfg, userData), nil
162167
}
163168

164-
nodepoolID, err := p.getTargetNodePoolID(ctx)
165-
if err != nil {
166-
// Don't return here, we can process when there is no default cluster id.
167-
// We need to try to obtain a usable nodepool ID in order to get the cluster attach scripts.
168-
// One known scenario is on an ACK cluster with version 1.24, where the user deleted the default nodepool and
169-
// created a nodepool with a containerd runtime. The DescribeClusterAttachScriptsRequest api will use the
170-
// CRI configuration of the deleted default nodepool, which might be using the Docker runtime.
171-
// This could result in nodes failing to register to the new cluster.
172-
log.FromContext(ctx).Error(err, "Failed to get default nodepool id")
173-
}
174169
reqPara := &ackclient.DescribeClusterAttachScriptsRequest{
175170
KeepInstanceName: tea.Bool(true),
176-
NodepoolId: nodepoolID,
177171
}
178172
resp, err := p.ackClient.DescribeClusterAttachScripts(tea.String(p.clusterID), reqPara)
179173
if err != nil {
180174
log.FromContext(ctx).Error(err, "Failed to get node registration script")
181175
return "", err
182176
}
183-
s := tea.StringValue(resp.Body)
184-
if s == "" {
177+
respStr := tea.StringValue(resp.Body)
178+
if respStr == "" {
185179
err := errors.New("empty node registration script")
186180
log.FromContext(ctx).Error(err, "")
187181
return "", err
188182
}
183+
respStr = strings.ReplaceAll(respStr, "\r\n", "")
184+
185+
runtime, runtimeVersion, err := p.getClusterAttachRuntimeConfiguration(ctx)
186+
if err != nil {
187+
// If error happen, we do nothing here
188+
log.FromContext(ctx).Error(err, "Failed to get cluster attach runtime configuration")
189+
} else {
190+
// Replace the runtime and runtime-version parameter
191+
respStr = regexp.MustCompile(`\s+--runtime\s+\S+\s+--runtime-version\s+\S+`).ReplaceAllString(
192+
respStr, fmt.Sprintf(" --runtime %s --runtime-version %s", runtime, runtimeVersion))
193+
}
189194

190-
p.cache.SetDefault(p.clusterID, s)
191-
return p.resolveUserData(s, labels, nodeClaim, kubeletCfg, userData), nil
195+
p.cache.SetDefault(p.clusterID, respStr)
196+
return p.resolveUserData(respStr, labels, nodeClaim, kubeletCfg, userData), nil
192197
}
193198

194199
func (p *DefaultProvider) resolveUserData(respStr string, labels map[string]string, nodeClaim *karpv1.NodeClaim,
@@ -207,8 +212,7 @@ func (p *DefaultProvider) resolveUserData(respStr string, labels map[string]stri
207212
}
208213

209214
// Clean up the input string
210-
cleanupStr := strings.ReplaceAll(respStr, "\r\n", "")
211-
script.WriteString(cleanupStr + " ")
215+
script.WriteString(respStr + " ")
212216
// Add labels
213217
script.WriteString(fmt.Sprintf("--labels %s ", p.formatLabels(labels)))
214218
// Add kubelet config

0 commit comments

Comments
 (0)