Change:
return command } <ins> // calcNodeCidrSize determines the size of the subnets used on each node, based // on the pod subnet provided.  For IPv4, we assume that the pod subnet will // be /16 and use /24. If the pod subnet cannot be parsed, the IPv4 value will // be used (/24). // // For IPv6, the algorithm will do two three. First, the node CIDR will be set // to a multiple of 8, using the available bits for easier readability by user. // Second, the number of nodes will be 512 to 64K to attempt to maximize the // number of nodes (see NOTE below). Third, pod networks of /113 and larger will // be rejected, as the amount of bits available is too small. // // A special case is when the pod network size is /112, where /120 will be used, // only allowing 256 nodes and 256 pods. // // If the pod network size is /113 or larger, the node CIDR will be set to the same // size and this will be rejected later in validation. // // NOTE: Currently, the pod network must be /66 or larger. It is not reflected here, // but a smaller value will fail later validation. // // NOTE: Currently, the design allows a maximum of 64K nodes. This algorithm splits // the available bits to maximize the number used for nodes, but still have the node // CIDR be a multiple of eight. // func calcNodeCidrSize(podSubnet string) string { maskSize := "24" if ip, podCidr, err := net.ParseCIDR(podSubnet); err == nil { if ip.To4() == nil { var nodeCidrSize int podNetSize, totalBits := podCidr.Mask.Size() switch { case podNetSize == 112: // Special case, allows 256 nodes, 256 pods/node nodeCidrSize = 120 case podNetSize < 112: // Use multiple of 8 for node CIDR, with 512 to 64K nodes nodeCidrSize = totalBits - ((totalBits-podNetSize-1)/8-1)*8 default: // Not enough bits, will fail later, when validate nodeCidrSize = podNetSize } maskSize = strconv.Itoa(nodeCidrSize) } } return maskSize } </ins> // getControllerManagerCommand builds the right controller manager command from the given config object and version func getControllerManagerCommand(cfg *kubeadmapi.MasterConfiguration, k8sVersion *version.Version) []string { defaultArguments := map[string]string{

Discussion:
<!-- This form is for bug reports and feature requests ONLY! If you're looking for help check and the . --Is this a BUG REPORT or FEATURE REQUEST?: /kind bug What happened: For IPv6, the node CIDR size is hard coded to /64. This causes an error bringing up the kube-controller, as the size must be for a smaller subnet (larger value) that what is used for the pod subnet, which is specified for some CNI plugins (e.g. Calico). In addition, this is a catch-22, as the pod subnet prefix cannot be for a larger network (smaller value) than /66, so we cannot set it to /63, for example. What you expected to happen: The node CIDR size should be computed, based on the pod subnet specified, so that it can meet the requirements. How to reproduce it (as minimally and precisely as possible): Bring up a cluster using KubeAdm, specifying IPv6 and choose any pod subnet prefix desired. Anything else we need to know?: Note, there is a second requirement, that the difference between pod subnet size and node CIDR size be 16 or less (issue ). I'll be submitting a proposed PR to address this. Environment: Kubernetes version (use ): latest on master, using 1.9.2 in my case Cloud provider or hardware configuration: bare metal, single node OS (e.g. from /etc/os-release): Ubuntu 16.04 Kernel (e.g. ): Linux bxb-c2-77 4.4.0-109-generic -Ubuntu SMP Tue Jan 9 19:52:39 UTC 2018 x8664 x8664 x86_64 GNU/Linux Install tools: kubeadm Others: /area ipv6 /sig network
/assign pmichali