mirror of https://github.com/kubernetes/kops.git
parent
aa190b8c3f
commit
302f23463e
|
@ -36,6 +36,7 @@ type CreateClusterCmd struct {
|
|||
VPCID string
|
||||
NetworkCIDR string
|
||||
DNSZone string
|
||||
AdminAccess string
|
||||
}
|
||||
|
||||
var createCluster CreateClusterCmd
|
||||
|
@ -93,6 +94,7 @@ func init() {
|
|||
|
||||
cmd.Flags().StringVar(&createCluster.DNSZone, "dns-zone", "", "DNS hosted zone to use (defaults to last two components of cluster name)")
|
||||
cmd.Flags().StringVar(&createCluster.OutDir, "out", "", "Path to write any local output")
|
||||
cmd.Flags().StringVar(&createCluster.AdminAccess, "admin-access", "", "Restrict access to admin endpoints (SSH, HTTPS) to this CIDR. If not set, access will not be restricted by IP.")
|
||||
}
|
||||
|
||||
var EtcdClusters = []string{"main", "events"}
|
||||
|
@ -332,6 +334,10 @@ func (c *CreateClusterCmd) Run() error {
|
|||
c.SSHPublicKey = utils.ExpandPath(c.SSHPublicKey)
|
||||
}
|
||||
|
||||
if c.AdminAccess != "" {
|
||||
cluster.Spec.AdminAccess = []string{c.AdminAccess}
|
||||
}
|
||||
|
||||
err = cluster.PerformAssignments()
|
||||
if err != nil {
|
||||
return fmt.Errorf("error populating configuration: %v", err)
|
||||
|
|
|
@ -1,8 +1,24 @@
|
|||
# Detailed description of arguments
|
||||
|
||||
## admin-access
|
||||
|
||||
`admin-access` controls the CIDR which can access the admin endpoints (SSH to each node, HTTPS to the master).
|
||||
|
||||
It maps to `Cluster.Spec.AdminAccess`
|
||||
|
||||
If not specified, no IP level restrictions will apply (though there are still restrictions, for example you need
|
||||
a permitted SSH key to access the SSH service!).
|
||||
|
||||
Currently this can only be a single CIDR.
|
||||
|
||||
Examples:
|
||||
|
||||
`--admin-access=18.0.0.0/8` to restrict to IPs in the 18.0.0.0/8 CIDR
|
||||
|
||||
|
||||
## dns-zone
|
||||
|
||||
dns-zone controls the Route53 hosted zone in which DNS records will be created. It can either by the name
|
||||
`dns-zone` controls the Route53 hosted zone in which DNS records will be created. It can either by the name
|
||||
of the hosted zone (`example.com`), or it can be the ID of the hosted zone (`Z1GABCD1ABC2DEF`)
|
||||
|
||||
Suppose you're creating a cluster named "dev.kubernetes.example.com`:
|
||||
|
@ -17,3 +33,7 @@ If you don't specify a dns-zone, kops will list all your hosted zones, and choos
|
|||
is a a suffix of your cluster name. So for `dev.kubernetes.example.com`, if you have `kubernetes.example.com`,
|
||||
`example.com` and `somethingelse.example.com`, it would choose `kubernetes.example.com`. `example.com` matches
|
||||
but is shorter; `somethingelse.example.com` is not a suffix-match.
|
||||
|
||||
Examples:
|
||||
|
||||
`--dns-zone=example.com` to use the hosted zone with a name of example.com
|
||||
|
|
|
@ -35,7 +35,7 @@ securityGroupRule/egress-api-lb:
|
|||
# HTTPS to the master ELB is allowed (for API access)
|
||||
securityGroupRule/https-external-to-api:
|
||||
securityGroup: securityGroup/api.{{ ClusterName }}
|
||||
cidr: 0.0.0.0/0
|
||||
cidr: {{ AdminCIDR }}
|
||||
protocol: tcp
|
||||
fromPort: 443
|
||||
toPort: 443
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
# HTTPS to the master is allowed (for API access)
|
||||
securityGroupRule/https-external-to-master:
|
||||
securityGroup: securityGroup/masters.{{ ClusterName }}
|
||||
cidr: 0.0.0.0/0
|
||||
cidr: {{ AdminCIDR }}
|
||||
protocol: tcp
|
||||
fromPort: 443
|
||||
toPort: 443
|
||||
|
|
|
@ -24,10 +24,10 @@ securityGroupRule/master-egress:
|
|||
egress: true
|
||||
cidr: 0.0.0.0/0
|
||||
|
||||
# SSH is open to the world
|
||||
# SSH is open to AdminCIDR
|
||||
securityGroupRule/ssh-external-to-master:
|
||||
securityGroup: securityGroup/masters.{{ ClusterName }}
|
||||
cidr: 0.0.0.0/0
|
||||
cidr: {{ AdminCIDR }}
|
||||
protocol: tcp
|
||||
fromPort: 22
|
||||
toPort: 22
|
||||
|
|
|
@ -27,7 +27,7 @@ securityGroupRule/node-egress:
|
|||
# SSH is open to the world
|
||||
securityGroupRule/ssh-external-to-node:
|
||||
securityGroup: securityGroup/nodes.{{ ClusterName }}
|
||||
cidr: 0.0.0.0/0
|
||||
cidr: {{ AdminCIDR }}
|
||||
protocol: tcp
|
||||
fromPort: 22
|
||||
toPort: 22
|
||||
|
|
|
@ -6,9 +6,9 @@ persistentDisk/kubernetes-master-{{ ClusterName }}:
|
|||
volumeType: {{ or .MasterVolumeType "pd-ssd" }}
|
||||
|
||||
# Open master HTTPS
|
||||
firewallRule/kubernetes-master-https-{{ ClusterName }}:
|
||||
firewallRule/kubernetes-master-https-{{ ClusterName }}-{{ AdminCIDR }}:
|
||||
network: network/default
|
||||
sourceRanges: 0.0.0.0/0
|
||||
sourceRanges: {{ AdminCIDR }}
|
||||
targetTags: {{ .MasterTag }}
|
||||
allowed: tcp:443
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@ firewallRule/{{ $networkName }}-default-internal:
|
|||
- icmp
|
||||
|
||||
# SSH is open to the world
|
||||
firewallRule/{{ $networkName }}-default-ssh:
|
||||
firewallRule/{{ $networkName }}-default-ssh-{{ AdminCIDR }}:
|
||||
network: network/default
|
||||
sourceRanges: 0.0.0.0/0
|
||||
sourceRanges: {{ AdminCIDR }}
|
||||
allowed: tcp:22
|
||||
|
||||
|
|
|
@ -90,6 +90,10 @@ type ClusterSpec struct {
|
|||
// It cannot overlap ServiceClusterIPRange
|
||||
NonMasqueradeCIDR string `json:"nonMasqueradeCIDR,omitempty"`
|
||||
|
||||
// AdminAccess determines the permitted access to the admin endpoints (SSH & master HTTPS)
|
||||
// Currently only a single CIDR is supported (though a richer grammar could be added in future)
|
||||
AdminAccess []string `json:"adminAccess,omitempty"`
|
||||
|
||||
//NetworkProvider string `json:",omitempty"`
|
||||
//
|
||||
//HairpinMode string `json:",omitempty"`
|
||||
|
@ -273,6 +277,17 @@ func (c *Cluster) PerformAssignments() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// FillDefaults populates default values.
|
||||
// This is different from PerformAssignments, because these values are changeable, and thus we don't need to
|
||||
// store them (i.e. we don't need to 'lock them')
|
||||
func (c *Cluster) FillDefaults() error {
|
||||
if len(c.Spec.AdminAccess) == 0 {
|
||||
c.Spec.AdminAccess = append(c.Spec.AdminAccess, "0.0.0.0/0")
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (z *ClusterZoneSpec) performAssignments(c *Cluster) error {
|
||||
if z.CIDR == "" {
|
||||
cidr, err := z.assignCIDR(c)
|
||||
|
|
|
@ -178,6 +178,17 @@ func (c *Cluster) Validate(strict bool) error {
|
|||
}
|
||||
}
|
||||
|
||||
if strict && len(c.Spec.AdminAccess) == 0 {
|
||||
return fmt.Errorf("AdminAccess not configured")
|
||||
}
|
||||
|
||||
for _, adminAccess := range c.Spec.AdminAccess {
|
||||
_, _, err := net.ParseCIDR(adminAccess)
|
||||
if err != nil {
|
||||
return fmt.Errorf("AdminAccess rule %q could not be parsed (invalid CIDR)", adminAccess)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
|
@ -147,6 +147,11 @@ func (c *CreateClusterCmd) Run() error {
|
|||
return err
|
||||
}
|
||||
|
||||
err = cluster.FillDefaults()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Check that instance groups are defined in valid zones
|
||||
{
|
||||
clusterZones := make(map[string]*api.ClusterZoneSpec)
|
||||
|
|
|
@ -51,6 +51,7 @@ func (tf *TemplateFunctions) AddTo(dest template.FuncMap) {
|
|||
dest["EtcdClusterMemberTags"] = tf.EtcdClusterMemberTags
|
||||
dest["SharedVPC"] = tf.SharedVPC
|
||||
dest["WellKnownServiceIP"] = tf.WellKnownServiceIP
|
||||
dest["AdminCIDR"] = tf.AdminCIDR
|
||||
}
|
||||
|
||||
func (tf *TemplateFunctions) EtcdClusterMemberTags(etcd *api.EtcdClusterSpec, m *api.EtcdMemberSpec) map[string]string {
|
||||
|
@ -77,3 +78,14 @@ func (tf *TemplateFunctions) EtcdClusterMemberTags(etcd *api.EtcdClusterSpec, m
|
|||
func (tf *TemplateFunctions) SharedVPC() bool {
|
||||
return tf.cluster.Spec.NetworkID != ""
|
||||
}
|
||||
|
||||
// AdminCIDR returns the single CIDR that is allowed access to the admin ports of the cluster (22, 443 on master)
|
||||
func (tf *TemplateFunctions) AdminCIDR() (string, error) {
|
||||
if len(tf.cluster.Spec.AdminAccess) == 0 {
|
||||
return "0.0.0.0/0", nil
|
||||
}
|
||||
if len(tf.cluster.Spec.AdminAccess) == 1 {
|
||||
return tf.cluster.Spec.AdminAccess[0], nil
|
||||
}
|
||||
return "", fmt.Errorf("Multiple AdminAccess rules are not (currently) supported")
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue