Skip to content

Commit 6a2fe32

Browse files
authored
feat: properly support kube-vip upgrades (#1062)
**What problem does this PR solve?**: See https://docs.google.com/document/d/1RolIuLXf5qD5l2lya0ZtY-ZcGkh07ctiRiG8jjXMthU/edit?usp=sharing with additional details. We ran into an issue where upgrading CAREN causes an unwanted rollout of all control plane Nodes. This happens when CAREN is shipped with a new kube-vip version and the difference in the static Pod spec changes the `file` contents in KCP and forces new Nodes to be created. We do not want this behavior and only want this rollout to happen at controlled times. In a recent change we introduced a mechanism of making backend changes by using versioned handlers. 7bc9094 This change follows a similar pattern. A new handler is introduced that will instead of reading the kube-vip template from a global ConfigMap will read it directly from the KCPTemplate associated with the ClusterClass. We can then continue to change the kube-vip version (or any other spec changes there) and downstream projects will just pick up whatever changes through a new ClusterClass. Another important goal with this approach was to not require consumers of CAREN to maintain some reference to the "correct" kube-vip template. We want to keep upgrades as simple as possible by only changing the Kubernetes version, and let CAREN handle its own business logic. **Alternative Considered Solutions** 1. Add a ConfigMap ref of the static Pod template to the API. This would require the clients to keep track of and update another field on upgrades. We want to keep the upgrade changes as simple as possible and leave this kind of implementation detail to CAREN. 2. Add logic to only apply new changes when upgrading. This approach was considered for a previous scenario, but we decided against it due to complexity and instead introduced versioned ClusterClass and templates. **Which issue(s) this PR fixes**: Fixes # **How Has This Been Tested?**: <!-- Please describe the tests that you ran to verify your changes. Provide output from the tests and any manual steps needed to replicate the tests. --> Tested locally by creating a cluster with the new and old handlers. **Special notes for your reviewer**: <!-- Use this to provide any additional information to the reviewers. This may include: - Best way to review the PR. - Where the author wants the most review attention on. - etc. --> This PR introduces a "v3" version of the handlers with the modified kube-vip handler, and preserves the previous behavior from v2.
1 parent 8a0b84a commit 6a2fe32

File tree

60 files changed

+1805
-4030
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

60 files changed

+1805
-4030
lines changed

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ repos:
153153
name: License headers - YAML and Makefiles
154154
stages: [pre-commit]
155155
files: (^Makefile|\.(ya?ml|mk))$
156-
exclude: ^(internal/test|pkg/handlers/.+/embedded|examples|charts/cluster-api-runtime-extensions-nutanix/(defaultclusterclasses|addons))/.+\.ya?ml|docs/static/helm/index\.yaml|charts/cluster-api-runtime-extensions-nutanix/templates/helm-config.yaml$
156+
exclude: ^(internal/test|pkg/handlers/.+/embedded|examples|charts/cluster-api-runtime-extensions-nutanix/(defaultclusterclasses|addons))/.+\.ya?ml|docs/static/helm/index\.yaml|charts/cluster-api-runtime-extensions-nutanix/templates/helm-config.yaml|hack/examples/files/kube-vip.yaml$
157157
args:
158158
- --license-filepath
159159
- hack/license-header.txt

charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/aws-cluster-class.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ spec:
2323
patches:
2424
- external:
2525
discoverVariablesExtension: awsclusterconfigvars-dv.cluster-api-runtime-extensions-nutanix
26-
generateExtension: awsclusterv2configpatch-gp.cluster-api-runtime-extensions-nutanix
26+
generateExtension: awsclusterv3configpatch-gp.cluster-api-runtime-extensions-nutanix
2727
name: cluster-config
2828
- external:
2929
discoverVariablesExtension: awsworkerconfigvars-dv.cluster-api-runtime-extensions-nutanix

charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/docker-cluster-class.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ spec:
3131
patches:
3232
- external:
3333
discoverVariablesExtension: dockerclusterconfigvars-dv.cluster-api-runtime-extensions-nutanix
34-
generateExtension: dockerclusterv2configpatch-gp.cluster-api-runtime-extensions-nutanix
34+
generateExtension: dockerclusterv3configpatch-gp.cluster-api-runtime-extensions-nutanix
3535
name: cluster-config
3636
- external:
3737
discoverVariablesExtension: dockerworkerconfigvars-dv.cluster-api-runtime-extensions-nutanix

charts/cluster-api-runtime-extensions-nutanix/defaultclusterclasses/nutanix-cluster-class.yaml

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ spec:
6767
patches:
6868
- external:
6969
discoverVariablesExtension: nutanixclusterconfigvars-dv.cluster-api-runtime-extensions-nutanix
70-
generateExtension: nutanixclusterv2configpatch-gp.cluster-api-runtime-extensions-nutanix
70+
generateExtension: nutanixclusterv3configpatch-gp.cluster-api-runtime-extensions-nutanix
7171
name: cluster-config
7272
- external:
7373
discoverVariablesExtension: nutanixworkerconfigvars-dv.cluster-api-runtime-extensions-nutanix
@@ -132,7 +132,69 @@ spec:
132132
scheduler:
133133
extraArgs:
134134
tls-cipher-suites: TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256,TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
135-
files: []
135+
files:
136+
- content: |-
137+
apiVersion: v1
138+
kind: Pod
139+
metadata:
140+
name: kube-vip
141+
namespace: kube-system
142+
spec:
143+
containers:
144+
- args:
145+
- manager
146+
env:
147+
- name: vip_arp
148+
value: "true"
149+
- name: port
150+
value: '{{ .Port }}'
151+
- name: vip_nodename
152+
valueFrom:
153+
fieldRef:
154+
fieldPath: spec.nodeName
155+
- name: vip_cidr
156+
value: "32"
157+
- name: dns_mode
158+
value: first
159+
- name: cp_enable
160+
value: "true"
161+
- name: cp_namespace
162+
value: kube-system
163+
- name: vip_leaderelection
164+
value: "true"
165+
- name: vip_leasename
166+
value: plndr-cp-lock
167+
- name: vip_leaseduration
168+
value: "15"
169+
- name: vip_renewdeadline
170+
value: "10"
171+
- name: vip_retryperiod
172+
value: "2"
173+
- name: address
174+
value: '{{ .Address }}'
175+
- name: prometheus_server
176+
image: ghcr.io/kube-vip/kube-vip:v0.8.9
177+
imagePullPolicy: IfNotPresent
178+
name: kube-vip
179+
resources: {}
180+
securityContext:
181+
capabilities:
182+
add:
183+
- NET_ADMIN
184+
- NET_RAW
185+
volumeMounts:
186+
- mountPath: /etc/kubernetes/admin.conf
187+
name: kubeconfig
188+
hostAliases:
189+
- hostnames:
190+
- kubernetes
191+
ip: 127.0.0.1
192+
hostNetwork: true
193+
volumes:
194+
- hostPath:
195+
path: /etc/kubernetes/admin.conf
196+
name: kubeconfig
197+
path: /etc/kubernetes/manifests/kube-vip.yaml
136198
initConfiguration:
137199
nodeRegistration:
138200
kubeletExtraArgs:

common/pkg/testutils/capitest/request/items.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,19 @@ func NewKubeadmConfigTemplateRequest(
8383
)
8484
}
8585

86-
func NewKubeadmControlPlaneTemplateRequest(
86+
type KubeadmControlPlaneTemplateRequestItemBuilder struct {
87+
files []bootstrapv1.File
88+
}
89+
90+
func (b *KubeadmControlPlaneTemplateRequestItemBuilder) WithFiles(
91+
files ...bootstrapv1.File,
92+
) *KubeadmControlPlaneTemplateRequestItemBuilder {
93+
b.files = files
94+
return b
95+
}
96+
97+
func (b *KubeadmControlPlaneTemplateRequestItemBuilder) NewRequest(
8798
uid types.UID,
88-
name string,
8999
) runtimehooksv1.GeneratePatchesRequestItem {
90100
return NewRequestItem(
91101
&controlplanev1.KubeadmControlPlaneTemplate{
@@ -94,7 +104,7 @@ func NewKubeadmControlPlaneTemplateRequest(
94104
Kind: "KubeadmControlPlaneTemplate",
95105
},
96106
ObjectMeta: metav1.ObjectMeta{
97-
Name: name,
107+
Name: kubeadmControlPlaneTemplateRequestObjectName,
98108
Namespace: Namespace,
99109
},
100110
Spec: controlplanev1.KubeadmControlPlaneTemplateSpec{
@@ -107,6 +117,7 @@ func NewKubeadmControlPlaneTemplateRequest(
107117
JoinConfiguration: &bootstrapv1.JoinConfiguration{
108118
NodeRegistration: bootstrapv1.NodeRegistrationOptions{},
109119
},
120+
Files: b.files,
110121
},
111122
},
112123
},
@@ -126,7 +137,8 @@ func NewKubeadmControlPlaneTemplateRequest(
126137
func NewKubeadmControlPlaneTemplateRequestItem(
127138
uid types.UID,
128139
) runtimehooksv1.GeneratePatchesRequestItem {
129-
return NewKubeadmControlPlaneTemplateRequest(uid, kubeadmControlPlaneTemplateRequestObjectName)
140+
builder := &KubeadmControlPlaneTemplateRequestItemBuilder{}
141+
return builder.NewRequest(uid)
130142
}
131143

132144
func NewCPDockerMachineTemplateRequestItem(

hack/addons/update-kube-vip-manifests.sh

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@ if [ -z "${KUBE_VIP_VERSION:-}" ]; then
1313
exit 1
1414
fi
1515

16-
ASSETS_DIR="$(mktemp -d -p "${TMPDIR:-/tmp}")"
17-
readonly ASSETS_DIR
18-
trap_add "rm -rf ${ASSETS_DIR}" EXIT
19-
16+
readonly ASSETS_DIR="hack/examples/files"
2017
readonly FILE_NAME="kube-vip.yaml"
2118

2219
# shellcheck disable=SC2016 # Single quotes are required for the gojq expression.
@@ -33,23 +30,9 @@ docker container run --rm ghcr.io/kube-vip/kube-vip:"${KUBE_VIP_VERSION}" \
3330
gojq --yaml-input --yaml-output \
3431
'del(.metadata.creationTimestamp, .status) |
3532
.spec.containers[].imagePullPolicy |= "IfNotPresent" |
36-
(.spec.containers[0].env[] | select(.name == "port").value) |= "{{ `{{ .Port }}` }}" |
37-
(.spec.containers[0].env[] | select(.name == "address").value) |= "{{ `{{ .Address }}` }}"
33+
(.spec.containers[0].env[] | select(.name == "port").value) |= "{{ .Port }}" |
34+
(.spec.containers[0].env[] | select(.name == "address").value) |= "{{ .Address }}"
3835
' >"${ASSETS_DIR}/${FILE_NAME}"
3936

40-
kubectl create configmap "{{ .Values.hooks.virtualIP.kubeVip.defaultTemplateConfigMap.name }}" --dry-run=client --output yaml \
41-
--from-file "${ASSETS_DIR}/${FILE_NAME}" \
42-
>"${ASSETS_DIR}/kube-vip-configmap.yaml"
43-
44-
# add warning not to edit file directly
45-
cat <<EOF >"${GIT_REPO_ROOT}/charts/cluster-api-runtime-extensions-nutanix/templates/virtual-ip/kube-vip/manifests/kube-vip-configmap.yaml"
46-
$(cat "${GIT_REPO_ROOT}/hack/license-header.yaml.txt")
47-
48-
#=================================================================
49-
# DO NOT EDIT THIS FILE
50-
# IT HAS BEEN GENERATED BY /hack/addons/update-kube-vip-manifests.sh
51-
#=================================================================
52-
{{- if .Values.hooks.virtualIP.kubeVip.defaultTemplateConfigMap.create }}
53-
$(cat "${ASSETS_DIR}/kube-vip-configmap.yaml")
54-
{{- end -}}
55-
EOF
37+
# add 8 spaces to each line so that the kustomize template can be properly indented
38+
sed -i -e 's/^/ /' "${ASSETS_DIR}/${FILE_NAME}"

hack/examples/bases/nutanix/clusterclass/kustomization.yaml.tmpl

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,23 @@ patches:
4646
- op: "remove"
4747
path: "/spec/template/spec/kubeadmConfigSpec/clusterConfiguration/apiServer/certSANs"
4848

49-
# Delete the kube-vip file.
50-
# Will be templated and added back in the handler if enabled.
49+
# Template the kube-vip file.
50+
# The handler will set the variables if needed, or remove it.
5151
- target:
5252
kind: KubeadmControlPlaneTemplate
5353
patch: |-
5454
- op: test
5555
path: /spec/template/spec/kubeadmConfigSpec/files/0/path
5656
value: "/etc/kubernetes/manifests/kube-vip.yaml"
5757
- op: "remove"
58-
path: "/spec/template/spec/kubeadmConfigSpec/files/0"
58+
path: "/spec/template/spec/kubeadmConfigSpec/files/0/owner"
59+
- op: "replace"
60+
path: "/spec/template/spec/kubeadmConfigSpec/files/0/path"
61+
value: "/etc/kubernetes/manifests/kube-vip.yaml"
62+
- op: "replace"
63+
path: "/spec/template/spec/kubeadmConfigSpec/files/0/content"
64+
value: |
65+
${KUBE_VIP_CONTENT}
5966

6067
# Delete the kube-vip related pre and postKubeadmCommands.
6168
# Will be added back in the handler if enabled.

hack/examples/files/kube-vip.yaml

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
apiVersion: v1
2+
kind: Pod
3+
metadata:
4+
name: kube-vip
5+
namespace: kube-system
6+
spec:
7+
containers:
8+
- args:
9+
- manager
10+
env:
11+
- name: vip_arp
12+
value: "true"
13+
- name: port
14+
value: '{{ .Port }}'
15+
- name: vip_nodename
16+
valueFrom:
17+
fieldRef:
18+
fieldPath: spec.nodeName
19+
- name: vip_cidr
20+
value: "32"
21+
- name: dns_mode
22+
value: first
23+
- name: cp_enable
24+
value: "true"
25+
- name: cp_namespace
26+
value: kube-system
27+
- name: vip_leaderelection
28+
value: "true"
29+
- name: vip_leasename
30+
value: plndr-cp-lock
31+
- name: vip_leaseduration
32+
value: "15"
33+
- name: vip_renewdeadline
34+
value: "10"
35+
- name: vip_retryperiod
36+
value: "2"
37+
- name: address
38+
value: '{{ .Address }}'
39+
- name: prometheus_server
40+
image: ghcr.io/kube-vip/kube-vip:v0.8.9
41+
imagePullPolicy: IfNotPresent
42+
name: kube-vip
43+
resources: {}
44+
securityContext:
45+
capabilities:
46+
add:
47+
- NET_ADMIN
48+
- NET_RAW
49+
volumeMounts:
50+
- mountPath: /etc/kubernetes/admin.conf
51+
name: kubeconfig
52+
hostAliases:
53+
- hostnames:
54+
- kubernetes
55+
ip: 127.0.0.1
56+
hostNetwork: true
57+
volumes:
58+
- hostPath:
59+
path: /etc/kubernetes/admin.conf
60+
name: kubeconfig

hack/examples/overlays/clusterclasses/aws/kustomization.yaml.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ patches:
1919
value:
2020
- name: "cluster-config"
2121
external:
22-
generateExtension: "awsclusterv2configpatch-gp.cluster-api-runtime-extensions-nutanix"
22+
generateExtension: "awsclusterv3configpatch-gp.cluster-api-runtime-extensions-nutanix"
2323
discoverVariablesExtension: "awsclusterconfigvars-dv.cluster-api-runtime-extensions-nutanix"
2424
- name: "worker-config"
2525
external:

hack/examples/overlays/clusterclasses/docker/kustomization.yaml.tmpl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ patches:
1919
value:
2020
- name: "cluster-config"
2121
external:
22-
generateExtension: "dockerclusterv2configpatch-gp.cluster-api-runtime-extensions-nutanix"
22+
generateExtension: "dockerclusterv3configpatch-gp.cluster-api-runtime-extensions-nutanix"
2323
discoverVariablesExtension: "dockerclusterconfigvars-dv.cluster-api-runtime-extensions-nutanix"
2424
- name: "worker-config"
2525
external:

0 commit comments

Comments
 (0)