Skip to content

Commit

Permalink
automatically set kubelet args for CAPD
Browse files Browse the repository at this point in the history
  • Loading branch information
fabriziopandini committed Jun 26, 2023
1 parent 6073e52 commit 8b15bc0
Show file tree
Hide file tree
Showing 27 changed files with 461 additions and 135 deletions.
23 changes: 22 additions & 1 deletion bootstrap/kubeadm/types/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,26 @@ func UnmarshalClusterStatus(yaml string) (*bootstrapv1.ClusterStatus, error) {
return obj, nil
}

// UnmarshalInitConfiguration tries to translate a Kubeadm API yaml back to the InitConfiguration type.
// NOTE: The yaml could be any of the known formats for the kubeadm InitConfiguration type.
func UnmarshalInitConfiguration(yaml string) (*bootstrapv1.InitConfiguration, error) {
obj := &bootstrapv1.InitConfiguration{}
if err := unmarshalFromVersions(yaml, initConfigurationVersionTypeMap, obj); err != nil {
return nil, err
}
return obj, nil
}

// UnmarshalJoinConfiguration tries to translate a Kubeadm API yaml back to the JoinConfiguration type.
// NOTE: The yaml could be any of the known formats for the kubeadm JoinConfiguration type.
func UnmarshalJoinConfiguration(yaml string) (*bootstrapv1.JoinConfiguration, error) {
obj := &bootstrapv1.JoinConfiguration{}
if err := unmarshalFromVersions(yaml, joinConfigurationVersionTypeMap, obj); err != nil {
return nil, err
}
return obj, nil
}

func unmarshalFromVersions(yaml string, kubeadmAPIVersions map[schema.GroupVersion]conversion.Convertible, capiObj conversion.Hub) error {
// For each know kubeadm API version
for gv, obj := range kubeadmAPIVersions {
Expand All @@ -192,7 +212,8 @@ func unmarshalFromVersions(yaml string, kubeadmAPIVersions map[schema.GroupVersi
return errors.Wrapf(err, "failed to build scheme for kubeadm types conversions")
}

if _, _, err := codecs.UniversalDeserializer().Decode([]byte(yaml), &gvk, kubeadmObj); err == nil {
_, _, err = codecs.UniversalDeserializer().Decode([]byte(yaml), &gvk, kubeadmObj)
if err == nil {
// If conversion worked, then converts the kubeadmObj (spoke) back to the Cluster API ClusterConfiguration type (hub).
if err := kubeadmObj.(conversion.Convertible).ConvertTo(capiObj); err != nil {
return errors.Wrapf(err, "failed to convert kubeadm types to Cluster API types")
Expand Down
118 changes: 118 additions & 0 deletions bootstrap/kubeadm/types/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -555,3 +555,121 @@ func TestUnmarshalClusterStatus(t *testing.T) {
})
}
}

func TestUnmarshalInitConfiguration(t *testing.T) {
type args struct {
yaml string
}
tests := []struct {
name string
args args
want *bootstrapv1.InitConfiguration
wantErr bool
}{
{
name: "Parses a v1beta1 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
"kind: InitConfiguration\n" +
"localAPIEndpoint: {}\n" +
"nodeRegistration: {}\n",
},
want: &bootstrapv1.InitConfiguration{},
wantErr: false,
},
{
name: "Parses a v1beta2 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
"kind: InitConfiguration\n" +
"localAPIEndpoint: {}\n" +
"nodeRegistration: {}\n",
},
want: &bootstrapv1.InitConfiguration{},
wantErr: false,
},
{
name: "Parses a v1beta3 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
"kind: InitConfiguration\n" +
"localAPIEndpoint: {}\n" +
"nodeRegistration: {}\n",
},
want: &bootstrapv1.InitConfiguration{},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

got, err := UnmarshalInitConfiguration(tt.args.yaml)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
})
}
}

func TestUnmarshalJoinConfiguration(t *testing.T) {
type args struct {
yaml string
}
tests := []struct {
name string
args args
want *bootstrapv1.JoinConfiguration
wantErr bool
}{
{
name: "Parses a v1beta1 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta1\n" + "" +
"caCertPath: \"\"\n" +
"discovery: {}\n" +
"kind: JoinConfiguration\n",
},
want: &bootstrapv1.JoinConfiguration{},
wantErr: false,
},
{
name: "Parses a v1beta2 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta2\n" + "" +
"caCertPath: \"\"\n" +
"discovery: {}\n" +
"kind: JoinConfiguration\n",
},
want: &bootstrapv1.JoinConfiguration{},
wantErr: false,
},
{
name: "Parses a v1beta3 kubeadm configuration",
args: args{
yaml: "apiVersion: kubeadm.k8s.io/v1beta3\n" + "" +
"caCertPath: \"\"\n" +
"discovery: {}\n" +
"kind: JoinConfiguration\n",
},
want: &bootstrapv1.JoinConfiguration{},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
g := NewWithT(t)

got, err := UnmarshalJoinConfiguration(tt.args.yaml)
if tt.wantErr {
g.Expect(err).To(HaveOccurred())
return
}
g.Expect(err).ToNot(HaveOccurred())
g.Expect(got).To(Equal(tt.want), cmp.Diff(tt.want, got))
})
}
}
18 changes: 3 additions & 15 deletions docs/book/src/clusterctl/commands/alpha-topology-plan.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,17 +132,9 @@ spec:
apiServer:
certSANs: [ localhost, 127.0.0.1 ]
initConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
cgroup-driver: cgroupfs
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
joinConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
cgroup-driver: cgroupfs
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta1
kind: DockerMachineTemplate
Expand Down Expand Up @@ -174,10 +166,7 @@ spec:
template:
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
cgroup-driver: cgroupfs
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
```
</details>
Expand Down Expand Up @@ -485,4 +474,3 @@ If only one cluster is affected or if a Cluster is in the input it defaults as t
Namespace used for objects with missing namespaces in the input.

If not provided, the namespace defined in kubeconfig is used. If a kubeconfig is not available the value `default` is used.

13 changes: 4 additions & 9 deletions docs/book/src/tasks/bootstrap/kubeadm-bootstrap.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@ metadata:
name: my-control-plane1-config
spec:
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
clusterConfiguration:
controllerManager:
extraArgs:
Expand Down Expand Up @@ -119,8 +117,7 @@ metadata:
spec:
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
clusterConfiguration:
controllerManager:
extraArgs:
Expand All @@ -136,8 +133,7 @@ metadata:
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
controlPlane: {}
```

Expand All @@ -150,8 +146,7 @@ metadata:
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
```

### Bootstrap Orchestration
Expand Down
12 changes: 12 additions & 0 deletions docs/book/src/tasks/experimental-features/ignition.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,18 @@ This initial implementation uses Ignition **v2** and was tested with **Flatcar C

</aside>

<aside class="note warning">

<h1>Note</h1>

If using ignition with CAPD you should take care of setting `kubeletExtraArgs` for the `kindest/node` image in use,
because default CAPD templates do not include anymore those settings since when the cloud-init shim for CAPD is automatically taking care of this.
An example of how to set `kubeletExtraArgs` for the `kindest/node` can be found under `cluster-api/test/e2e/data/infrastructure-docker/main/cluster-template-ignition`.

Hopefully, this will be automated for Ignition too in a future release.

</aside>

This guide explains how to deploy an AWS workload cluster using Ignition.

## Prerequisites
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,7 @@ spec:
# host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied.
certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal]
initConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
joinConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
version: "${KUBERNETES_VERSION}"
6 changes: 1 addition & 5 deletions test/e2e/data/infrastructure-docker/main/bases/md.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,7 @@ spec:
template:
spec:
joinConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
---
# MachineDeployment object
apiVersion: cluster.x-k8s.io/v1beta1
Expand Down
5 changes: 1 addition & 4 deletions test/e2e/data/infrastructure-docker/main/bases/mp.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,4 @@ metadata:
name: "${CLUSTER_NAME}-mp-0-config"
spec:
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ metadata:
spec:
kubeadmConfigSpec:
format: ignition
initConfiguration:
nodeRegistration:
# We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
joinConfiguration:
nodeRegistration:
# We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
---
apiVersion: bootstrap.cluster.x-k8s.io/v1beta1
kind: KubeadmConfigTemplate
Expand All @@ -24,3 +38,10 @@ spec:
contents:
inline: Howdy!
mode: 0644
joinConfiguration:
nodeRegistration:
# We have to set the criSocket to containerd as kubeadm defaults to docker runtime if both containerd and docker sockets are found
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
Original file line number Diff line number Diff line change
Expand Up @@ -45,17 +45,9 @@ spec:
apiServer:
certSANs: [localhost, 127.0.0.1]
initConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
joinConfiguration:
nodeRegistration:
criSocket: unix:///var/run/containerd/containerd.sock
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
---
# cp0 Machine
apiVersion: cluster.x-k8s.io/v1beta1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,9 @@ spec:
# host.docker.internal is required by kubetest when running on MacOS because of the way ports are proxied.
certSANs: [localhost, 127.0.0.1, 0.0.0.0, host.docker.internal]
initConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
joinConfiguration:
nodeRegistration:
kubeletExtraArgs:
eviction-hard: 'nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%'
fail-swap-on: "false"
nodeRegistration: {} # node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
files:
- path: /wait-signal.sh
content: |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,9 @@ metadata:
name: "${CLUSTER_NAME}-mp-0-config-cgroupfs"
spec:
joinConfiguration:
# node registration parameters are automatically injected by CAPD according to the kindest/node image in use.
nodeRegistration:
kubeletExtraArgs:
# We have to pin the cgroupDriver to cgroupfs as kubeadm >=1.21 defaults to systemd
# kind will implement systemd support in: https://github.com/kubernetes-sigs/kind/issues/1726
cgroup-driver: cgroupfs
eviction-hard: nodefs.available<0%,nodefs.inodesFree<0%,imagefs.available<0%
fail-swap-on: "false"
Loading

0 comments on commit 8b15bc0

Please sign in to comment.