diff --git a/pkg/cluster/internal/create/actions/config/config.go b/pkg/cluster/internal/create/actions/config/config.go index a5ab77b200..b6f1e4dd17 100644 --- a/pkg/cluster/internal/create/actions/config/config.go +++ b/pkg/cluster/internal/create/actions/config/config.go @@ -78,7 +78,7 @@ func (a *Action) Execute(ctx *actions.ActionContext) error { KubeProxyMode: string(ctx.Config.Networking.KubeProxyMode), ServiceSubnet: ctx.Config.Networking.ServiceSubnet, ControlPlane: true, - IPv6: ctx.Config.Networking.IPFamily == config.IPv6Family, + IPFamily: ctx.Config.Networking.IPFamily, FeatureGates: ctx.Config.FeatureGates, RuntimeConfig: ctx.Config.RuntimeConfig, RootlessProvider: providerInfo.Rootless, diff --git a/pkg/cluster/internal/kubeadm/config.go b/pkg/cluster/internal/kubeadm/config.go index 80c22586b5..b49501e97d 100644 --- a/pkg/cluster/internal/kubeadm/config.go +++ b/pkg/cluster/internal/kubeadm/config.go @@ -25,6 +25,7 @@ import ( "k8s.io/apimachinery/pkg/util/version" "sigs.k8s.io/kind/pkg/errors" + "sigs.k8s.io/kind/pkg/internal/apis/config" ) // ConfigData is supplied to the kubeadm config template, with values populated @@ -67,8 +68,8 @@ type ConfigData struct { // Kubernetes API Server RuntimeConfig RuntimeConfig map[string]string - // IPv4 values take precedence over IPv6 by default, if true set IPv6 default values - IPv6 bool + // IPFamily of the cluster, it can be IPv4, IPv6 or DualStack + IPFamily config.ClusterIPFamily // Labels are the labels, in the format "key1=val1,key2=val2", with which the respective node will be labeled NodeLabels string @@ -96,6 +97,10 @@ type DerivedConfigData struct { FeatureGatesString string // RuntimeConfigString is of the form `Foo=true,Baz=false` RuntimeConfigString string + // KubeadmFeatureGates contains Kubeadm only feature gates + KubeadmFeatureGates map[string]bool + // IPv4 values take precedence over IPv6 by default, if true set IPv6 default values + IPv6 bool } // Derive automatically derives DockerStableTag if not specified @@ -107,6 +112,9 @@ func (c *ConfigData) Derive() { c.DockerStableTag = strings.Replace(c.KubernetesVersion, "+", "_", -1) } + // get the IP addresses family for defaulting components + c.IPv6 = c.IPFamily == config.IPv6Family + // get sorted list of FeatureGate keys featureGateKeys := make([]string, 0, len(c.FeatureGates)) for k := range c.FeatureGates { @@ -281,6 +289,10 @@ metadata: name: config kubernetesVersion: {{.KubernetesVersion}} clusterName: "{{.ClusterName}}" +{{ if .KubeadmFeatureGates}}featureGates: +{{ range $key, $value := .KubeadmFeatureGates }} + "{{ $key }}": {{ $value }} +{{end}}{{end}} controlPlaneEndpoint: "{{ .ControlPlaneEndpoint }}" # on docker for mac we have to expose the api server via port forward, # so we need to ensure the cert is valid for localhost so we can talk @@ -439,6 +451,17 @@ func Config(data ConfigData) (config string, err error) { // derive any automatic fields if not supplied data.Derive() + // Kubeadm has its own feature-gate for dual stack + // we need to enable it for Kubernetes version 1.20 only + // dual-stack is only supported in 1.20+ + // TODO: remove this when 1.20 is EOL or we no longer support + // dual-stack for 1.20 in KIND + if ver.LessThan(version.MustParseSemantic("v1.21.0")) && + ver.AtLeast(version.MustParseSemantic("v1.20.0")) { + data.KubeadmFeatureGates = make(map[string]bool) + data.KubeadmFeatureGates["IPv6DualStack"] = true + } + // execute the template var buff bytes.Buffer err = t.Execute(&buff, data) diff --git a/site/content/docs/user/configuration.md b/site/content/docs/user/configuration.md index 6a1fe87dfb..67d4663ae1 100644 --- a/site/content/docs/user/configuration.md +++ b/site/content/docs/user/configuration.md @@ -102,22 +102,52 @@ Multiple details of the cluster's networking can be customized under the #### IP Family -KIND has limited support for IPv6 (and soon dual-stack!) clusters, you can switch -from the default of IPv4 by setting: +KIND has support for IPv4, IPv6 and dual-stack clusters, you can switch from the default of IPv4 by setting: +##### IPv6 clusters +You can run IPv6 single-stack clusters using `kind`, if the host that runs the docker containers support IPv6. +Most operating systems / distros have IPv6 enabled by default, but you can check on Linux with the following command: + +```sh +sudo sysctl net.ipv6.conf.all.disable_ipv6 +``` + +You should see: + +```sh +net.ipv6.conf.all.disable_ipv6 = 0 +``` + +If you are using Docker on Windows or Mac, you will need to use an IPv4 port +forward for the API Server from the host because IPv6 port forwards don't work +on these platforms, you can do this with the following config: {{< codeFromInline lang="yaml" >}} kind: Cluster apiVersion: kind.x-k8s.io/v1alpha4 networking: ipFamily: ipv6 + apiServerAddress: 127.0.0.1 {{< /codeFromInline >}} -NOTE: you may need to [reconfigure your docker daemon](https://docs.docker.com/config/daemon/ipv6/) -to enable ipv6 in order to use this. +On Linux all you need is: -IPv6 does not work on docker for mac because port forwarding ipv6 -is not yet supported in docker for mac. +{{< codeFromInline lang="yaml" >}} +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: + ipFamily: ipv6 +{{< /codeFromInline >}} + +##### Dual Stack clusters +You can run dual stack clusters using `kind` 0.11+, on kubernetes versions 1.20+. + +{{< codeFromInline lang="yaml" >}} +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: + ipFamily: dual +{{< /codeFromInline >}} #### API Server diff --git a/site/content/docs/user/quick-start.md b/site/content/docs/user/quick-start.md index 8f96601a78..70244ab1b1 100644 --- a/site/content/docs/user/quick-start.md +++ b/site/content/docs/user/quick-start.md @@ -334,58 +334,6 @@ featureGates: FeatureGateName: true {{< /codeFromInline >}} -#### IPv6 clusters -You can run IPv6 single-stack clusters using `kind`, if the host that runs the docker containers support IPv6. -Most operating systems / distros have IPv6 enabled by default, but you can check on Linux with the following command: - -```sh -sudo sysctl net.ipv6.conf.all.disable_ipv6 -``` - -You should see: - -```sh -net.ipv6.conf.all.disable_ipv6 = 0 -``` - -If you are using Docker on Windows or Mac, you will need to use an IPv4 port -forward for the API Server from the host because IPv6 port forwards don't work -on these platforms, you can do this with the following config: - -```yaml -# an ipv6 cluster -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -networking: - ipFamily: ipv6 - apiServerAddress: 127.0.0.1 -``` - -On Linux all you need is: -```yaml -# an ipv6 cluster -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -networking: - ipFamily: ipv6 -``` - -#### Dual Stack clusters -You can run dual stack clusters using `kind`, on kubernetes versions +1.21 -but first you need to [enable ipv6 in your docker daemon][docker enable ipv6]. - -```yaml -# a dual-stack cluster -kind: Cluster -apiVersion: kind.x-k8s.io/v1alpha4 -networking: - ipFamily: dual -nodes: -- role: control-plane -- role: worker -- role: worker -``` - ### Configure kind to use a proxy If you are running kind in an environment that requires a proxy, you may need to configure kind to use it.