cluster-api: kubeadm-control-plane provider panics during api conversion because of missing `Patches` type in `v1alpha4`

What steps did you take and what happened: We upgraded CAPI from 0.4.x to 1.1.x and now we do get errors when updating KubeadmControlPlane objects because the kubeadm-bootstrap-controlle panics during conversion from apiVersion v1alpha4 to v1beta1 when doing a server-side apply:

2022/02/15 14:07:48 http: panic serving 192.168.250.0:9972: runtime error: invalid memory address or nil pointer dereference
goroutine 5601 [running]:
net/http.(*conn).serve.func1()
	net/http/server.go:1801 +0xb9
panic({0x1864c60, 0x2bbef10})
	runtime/panic.go:1047 +0x266
sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha4.(*KubeadmControlPlane).ConvertTo(0xc005567800, {0x1d077c8, 0xc005567800})
	sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1alpha4/conversion.go:43 +0xd8
sigs.k8s.io/controller-runtime/pkg/webhook/conversion.(*Webhook).convertObject(0xc000754f20, {0x1cf8650, 0xc005567200}, {0x1cf86f0, 0xc005567800})
	sigs.k8s.io/controller-runtime@v0.11.0/pkg/webhook/conversion/conversion.go:144 +0x506
sigs.k8s.io/controller-runtime/pkg/webhook/conversion.(*Webhook).handleConvertRequest(0xc000754f20, 0xc0014778c0)
	sigs.k8s.io/controller-runtime@v0.11.0/pkg/webhook/conversion/conversion.go:107 +0x24b
sigs.k8s.io/controller-runtime/pkg/webhook/conversion.(*Webhook).ServeHTTP(0x1cdb0e0, {0x7f32bb9db468, 0xc001e6d770}, 0xc000e37100)
	sigs.k8s.io/controller-runtime@v0.11.0/pkg/webhook/conversion/conversion.go:74 +0xeb
github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerInFlight.func1({0x7f32bb9db468, 0xc001e6d770}, 0xc001e6d770)
	github.com/prometheus/client_golang@v1.11.0/prometheus/promhttp/instrument_server.go:40 +0xd4
net/http.HandlerFunc.ServeHTTP(0x1d072e8, {0x7f32bb9db468, 0xc001e6d770}, 0x40ce34)
	net/http/server.go:2046 +0x2f
github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerCounter.func1({0x1d072e8, 0xc001323500}, 0xc000e37100)
	github.com/prometheus/client_golang@v1.11.0/prometheus/promhttp/instrument_server.go:101 +0x92
net/http.HandlerFunc.ServeHTTP(0xc000449280, {0x1d072e8, 0xc001323500}, 0xe0)
	net/http/server.go:2046 +0x2f
github.com/prometheus/client_golang/prometheus/promhttp.InstrumentHandlerDuration.func2({0x1d072e8, 0xc001323500}, 0xc000e37100)
	github.com/prometheus/client_golang@v1.11.0/prometheus/promhttp/instrument_server.go:76 +0xa2
net/http.HandlerFunc.ServeHTTP(0xc07b0acd28f2ad6f, {0x1d072e8, 0xc001323500}, 0xc001323500)
	net/http/server.go:2046 +0x2f
net/http.(*ServeMux).ServeHTTP(0xc0020969ce, {0x1d072e8, 0xc001323500}, 0xc000e37100)
	net/http/server.go:2424 +0x149
net/http.serverHandler.ServeHTTP({0x1cf76d8}, {0x1d072e8, 0xc001323500}, 0xc000e37100)
	net/http/server.go:2878 +0x43b
net/http.(*conn).serve(0xc003ad2460, {0x1d0e638, 0xc000260750})
	net/http/server.go:1929 +0xb08
created by net/http.(*Server).Serve
	net/http/server.go:3033 +0x4e8

The Patches type is not available in the v1alpha3 and v1alpha4 type definitions but seems to still be referenced in the conversion process which leads to the nil pointer dereference:

https://github.com/kubernetes-sigs/cluster-api/blob/82ab810646f11ec7c96a1543697264deaa3884ec/controlplane/kubeadm/api/v1alpha4/conversion.go#L43

What did you expect to happen: When updating the KubeadmControlPlane object with server-side apply, conversion between API versions should not reference undefined types.

Anything else you would like to add: [Miscellaneous information that will assist in solving the issue.]

Environment:

  • Cluster-api version: 1.1.1
  • Kubernetes version: (use kubectl version): 1.21.9

/kind bug /area bootstrap /area api

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Comments: 16 (10 by maintainers)

Most upvoted comments

@sbueringer Your fix did the trick. It’s working fine now in our environment. Thanks a lot!

@marratj almost forgot. You should probably checkout release-1.1 and cherry-pick my commit on top. Otherwise you’ll get other changes from main which would be bad.

Let me try to build it on my side from your PR branch, never built any of the CAPI components myself yet.

We started out with v1alpha4 and now use v1beta1. Both have the same issue, just tried both again, no matter which one I set as apiVersion in the manifest.

When you say they are both set, I assume they are not set to empty object {} but they have “sub-fields” set?

Exactly. They are currently looking like this:

            "initConfiguration": {
                "nodeRegistration": {
                    "criSocket": "/var/run/containerd/containerd.sock",
                    "kubeletExtraArgs": {
                        "cloud-provider": "external"
                    },
                    "name": "{{ ds.meta_data.instance_id }}"
                }
            },
            "joinConfiguration": {
                "nodeRegistration": {
                    "criSocket": "/var/run/containerd/containerd.sock",
                    "kubeletExtraArgs": {
                        "cloud-provider": "external"
                    },
                    "name": "{{ ds.meta_data.instance_id }}"
                }
            }