mirror of https://github.com/kubernetes/kops.git
Merge pull request #3898 from rdrgmnzs/additional_cidr
Automatic merge from submit-queue. Add additionalNetworkCIDRs to support VPCs with multiple CIDRs in AWS Add additionalNetworkCIDRs to support VPCs with multiple CIDRs in AWS. @justinsb I cannot find anywhere that does a check on an existing VPC to see if the networkCIDR matches what is on the VPC defined, I was looking for that so I can add a similar check for this. Am I missing something or is there really no check like that?
This commit is contained in:
commit
7bd0a6a703
|
|
@ -63,6 +63,36 @@ probably remove that tag to indicate that the resources are not owned by that cl
|
|||
deleting the cluster won't try to delete the VPC. (Deleting the VPC won't succeed anyway, because it's in use,
|
||||
but it's better to avoid the later confusion!)
|
||||
|
||||
|
||||
### VPC with multiple CIDRs
|
||||
|
||||
AWS now allows you to add more CIDRs to a VPC, the param `AdditionalNetworkCIDRs` allows you to specify any additional CIDRs added to the VPC.
|
||||
|
||||
```
|
||||
metadata:
|
||||
creationTimestamp: "2016-06-27T14:23:34Z"
|
||||
name: ${CLUSTER_NAME}
|
||||
spec:
|
||||
cloudProvider: aws
|
||||
networkCIDR: 10.1.0.0/16
|
||||
additionalNetworkCIDRs:
|
||||
- 10.2.0.0/16
|
||||
networkID: vpc-00aa5577
|
||||
subnets:
|
||||
- cidr: 10.1.0.0/19
|
||||
name: us-east-1b
|
||||
type: Public
|
||||
zone: us-east-1b
|
||||
id: subnet-1234567
|
||||
- cidr: 10.2.0.0/19
|
||||
name: us-east-1b
|
||||
type: Public
|
||||
zone: us-east-1b
|
||||
id: subnet-1234568
|
||||
```
|
||||
|
||||
|
||||
|
||||
## Advanced Options for Creating Clusters in Existing VPCs
|
||||
|
||||
### Shared Subnets
|
||||
|
|
|
|||
|
|
@ -68,6 +68,10 @@ type ClusterSpec struct {
|
|||
// This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to the VPC CIDR. It is not required on GCE.
|
||||
NetworkCIDR string `json:"networkCIDR,omitempty"`
|
||||
// AdditionalNetworkCIDRs is a list of aditional CIDR used for the AWS VPC
|
||||
// or otherwise allocated to k8s. This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to any aditional CIDRs added to a VPC.
|
||||
AdditionalNetworkCIDRs []string `json:"additionalNetworkCIDRs,omitempty"`
|
||||
// NetworkID is an identifier of a network, if we want to reuse/share an existing network (e.g. an AWS VPC)
|
||||
NetworkID string `json:"networkID,omitempty"`
|
||||
// Topology defines the type of network topology to use on the cluster - default public
|
||||
|
|
|
|||
|
|
@ -67,6 +67,10 @@ type ClusterSpec struct {
|
|||
// This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to the VPC CIDR. It is not required on GCE.
|
||||
NetworkCIDR string `json:"networkCIDR,omitempty"`
|
||||
// AdditionalNetworkCIDRs is a list of aditional CIDR used for the AWS VPC
|
||||
// or otherwise allocated to k8s. This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to any aditional CIDRs added to a VPC.
|
||||
AdditionalNetworkCIDRs []string `json:"additionalNetworkCIDRs,omitempty"`
|
||||
// NetworkID is an identifier of a network, if we want to reuse/share an existing network (e.g. an AWS VPC)
|
||||
NetworkID string `json:"networkID,omitempty"`
|
||||
// Topology defines the type of network topology to use on the cluster - default public
|
||||
|
|
|
|||
|
|
@ -590,6 +590,7 @@ func autoConvert_v1alpha1_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
|
|||
out.MasterPublicName = in.MasterPublicName
|
||||
out.MasterInternalName = in.MasterInternalName
|
||||
out.NetworkCIDR = in.NetworkCIDR
|
||||
out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs
|
||||
out.NetworkID = in.NetworkID
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
|
|
@ -825,6 +826,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha1_ClusterSpec(in *kops.ClusterSpec,
|
|||
out.MasterPublicName = in.MasterPublicName
|
||||
out.MasterInternalName = in.MasterInternalName
|
||||
out.NetworkCIDR = in.NetworkCIDR
|
||||
out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs
|
||||
out.NetworkID = in.NetworkID
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
|
|
|
|||
|
|
@ -753,6 +753,11 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
}
|
||||
}
|
||||
}
|
||||
if in.AdditionalNetworkCIDRs != nil {
|
||||
in, out := &in.AdditionalNetworkCIDRs, &out.AdditionalNetworkCIDRs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
if *in == nil {
|
||||
|
|
|
|||
|
|
@ -65,6 +65,10 @@ type ClusterSpec struct {
|
|||
// This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to the VPC CIDR. It is not required on GCE.
|
||||
NetworkCIDR string `json:"networkCIDR,omitempty"`
|
||||
// AdditionalNetworkCIDRs is a list of aditional CIDR used for the AWS VPC
|
||||
// or otherwise allocated to k8s. This is a real CIDR, not the internal k8s network
|
||||
// On AWS, it maps to any aditional CIDRs added to a VPC.
|
||||
AdditionalNetworkCIDRs []string `json:"additionalNetworkCIDRs,omitempty"`
|
||||
// NetworkID is an identifier of a network, if we want to reuse/share an existing network (e.g. an AWS VPC)
|
||||
NetworkID string `json:"networkID,omitempty"`
|
||||
// Topology defines the type of network topology to use on the cluster - default public
|
||||
|
|
|
|||
|
|
@ -636,6 +636,7 @@ func autoConvert_v1alpha2_ClusterSpec_To_kops_ClusterSpec(in *ClusterSpec, out *
|
|||
out.MasterPublicName = in.MasterPublicName
|
||||
out.MasterInternalName = in.MasterInternalName
|
||||
out.NetworkCIDR = in.NetworkCIDR
|
||||
out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs
|
||||
out.NetworkID = in.NetworkID
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
|
|
@ -887,6 +888,7 @@ func autoConvert_kops_ClusterSpec_To_v1alpha2_ClusterSpec(in *kops.ClusterSpec,
|
|||
out.MasterPublicName = in.MasterPublicName
|
||||
out.MasterInternalName = in.MasterInternalName
|
||||
out.NetworkCIDR = in.NetworkCIDR
|
||||
out.AdditionalNetworkCIDRs = in.AdditionalNetworkCIDRs
|
||||
out.NetworkID = in.NetworkID
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
|
|
|
|||
|
|
@ -762,6 +762,11 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
*out = make([]ClusterSubnetSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.AdditionalNetworkCIDRs != nil {
|
||||
in, out := &in.AdditionalNetworkCIDRs, &out.AdditionalNetworkCIDRs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
if *in == nil {
|
||||
|
|
|
|||
|
|
@ -157,6 +157,20 @@ func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
|
|||
}
|
||||
}
|
||||
|
||||
// Check AdditionalNetworkCIDRs
|
||||
var additionalNetworkCIDRs []*net.IPNet
|
||||
{
|
||||
if len(c.Spec.AdditionalNetworkCIDRs) > 0 {
|
||||
for _, AdditionalNetworkCIDR := range c.Spec.AdditionalNetworkCIDRs {
|
||||
_, IPNetAdditionalNetworkCIDR, err := net.ParseCIDR(AdditionalNetworkCIDR)
|
||||
if err != nil {
|
||||
return field.Invalid(fieldSpec.Child("AdditionalNetworkCIDRs"), AdditionalNetworkCIDR, fmt.Sprintf("Cluster had an invalid AdditionalNetworkCIDRs"))
|
||||
}
|
||||
additionalNetworkCIDRs = append(additionalNetworkCIDRs, IPNetAdditionalNetworkCIDR)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check NonMasqueradeCIDR
|
||||
var nonMasqueradeCIDR *net.IPNet
|
||||
{
|
||||
|
|
@ -326,7 +340,7 @@ func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
|
|||
return field.Invalid(fieldSubnet.Child("CIDR"), s.CIDR, "Subnet had an invalid CIDR")
|
||||
}
|
||||
|
||||
if networkCIDR != nil && !isSubnet(networkCIDR, subnetCIDR) {
|
||||
if networkCIDR != nil && !validateSubnetCIDR(networkCIDR, additionalNetworkCIDRs, subnetCIDR) {
|
||||
return field.Invalid(fieldSubnet.Child("CIDR"), s.CIDR, fmt.Sprintf("Subnet %q had a CIDR %q that was not a subnet of the NetworkCIDR %q", s.Name, s.CIDR, c.Spec.NetworkCIDR))
|
||||
}
|
||||
}
|
||||
|
|
@ -482,6 +496,21 @@ func ValidateCluster(c *kops.Cluster, strict bool) *field.Error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// validateSubnetCIDR is responsible for validating subnets are part of the CIRDs assigned to the cluster.
|
||||
func validateSubnetCIDR(networkCIDR *net.IPNet, additionalNetworkCIDRs []*net.IPNet, subnetCIDR *net.IPNet) bool {
|
||||
if isSubnet(networkCIDR, subnetCIDR) {
|
||||
return true
|
||||
}
|
||||
|
||||
for _, additionalNetworkCIDR := range additionalNetworkCIDRs {
|
||||
if isSubnet(additionalNetworkCIDR, subnetCIDR) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// validateEtcdClusterSpec is responsible for validating the etcd cluster spec
|
||||
func validateEtcdClusterSpec(spec *kops.EtcdClusterSpec, fieldPath *field.Path) *field.Error {
|
||||
if spec.Name == "" {
|
||||
|
|
|
|||
|
|
@ -71,6 +71,11 @@ func validateClusterSpec(spec *kops.ClusterSpec, fieldPath *field.Path) field.Er
|
|||
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("nodePortAccess").Index(i))...)
|
||||
}
|
||||
|
||||
// AdditionalNetworkCIDRs
|
||||
for i, cidr := range spec.AdditionalNetworkCIDRs {
|
||||
allErrs = append(allErrs, validateCIDR(cidr, fieldPath.Child("additionalNetworkCIDRs").Index(i))...)
|
||||
}
|
||||
|
||||
for i := range spec.Hooks {
|
||||
allErrs = append(allErrs, validateHookSpec(&spec.Hooks[i], fieldPath.Child("hooks").Index(i))...)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -907,6 +907,11 @@ func (in *ClusterSpec) DeepCopyInto(out *ClusterSpec) {
|
|||
*out = make([]ClusterSubnetSpec, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.AdditionalNetworkCIDRs != nil {
|
||||
in, out := &in.AdditionalNetworkCIDRs, &out.AdditionalNetworkCIDRs
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Topology != nil {
|
||||
in, out := &in.Topology, &out.Topology
|
||||
if *in == nil {
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ type VPC struct {
|
|||
|
||||
ID *string
|
||||
CIDR *string
|
||||
AdditionalCIDR *[]string
|
||||
EnableDNSHostnames *bool
|
||||
EnableDNSSupport *bool
|
||||
|
||||
|
|
@ -75,10 +76,11 @@ func (e *VPC) Find(c *fi.Context) (*VPC, error) {
|
|||
}
|
||||
vpc := response.Vpcs[0]
|
||||
actual := &VPC{
|
||||
ID: vpc.VpcId,
|
||||
CIDR: vpc.CidrBlock,
|
||||
Name: findNameTag(vpc.Tags),
|
||||
Tags: intersectTags(vpc.Tags, e.Tags),
|
||||
ID: vpc.VpcId,
|
||||
CIDR: vpc.CidrBlock,
|
||||
AdditionalCIDR: getAdditionalCIDR(vpc.CidrBlock, vpc.CidrBlockAssociationSet),
|
||||
Name: findNameTag(vpc.Tags),
|
||||
Tags: intersectTags(vpc.Tags, e.Tags),
|
||||
}
|
||||
|
||||
glog.V(4).Infof("found matching VPC %v", actual)
|
||||
|
|
@ -273,3 +275,15 @@ func (e *VPC) CloudformationLink() *cloudformation.Literal {
|
|||
|
||||
return cloudformation.Ref("AWS::EC2::VPC", *e.Name)
|
||||
}
|
||||
|
||||
func getAdditionalCIDR(CIDR *string, additionalCIDRSet []*ec2.VpcCidrBlockAssociation) *[]string {
|
||||
var additionalCIDRs []string
|
||||
|
||||
for _, CIDRSet := range additionalCIDRSet {
|
||||
if *CIDRSet.CidrBlock != *CIDR {
|
||||
additionalCIDRs = append(additionalCIDRs, *CIDRSet.CidrBlock)
|
||||
}
|
||||
}
|
||||
|
||||
return &additionalCIDRs
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue