Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cmd/kops/create_cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,9 +316,9 @@ func NewCmdCreateCluster(f *util.Factory, out io.Writer) *cobra.Command {
})
cmd.Flags().BoolVar(&options.DisableSubnetTags, "disable-subnet-tags", options.DisableSubnetTags, "Disable automatic subnet tagging")

cmd.Flags().StringSliceVar(&options.EtcdClusters, "etcd-clusters", options.EtcdClusters, "Names of the etcd clusters: main, events")
cmd.Flags().StringSliceVar(&options.EtcdClusters, "etcd-clusters", options.EtcdClusters, "Names of the etcd clusters: main, events, leases")
cmd.RegisterFlagCompletionFunc("etcd-clusters", func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
return []string{"main", "events"}, cobra.ShellCompDirectiveNoFileComp
return []string{"main", "events", "leases"}, cobra.ShellCompDirectiveNoFileComp
})

cmd.Flags().BoolVar(&encryptEtcdStorage, "encrypt-etcd-storage", false, "Generate key in AWS KMS and use it for encrypt etcd volumes")
Expand Down
12 changes: 12 additions & 0 deletions cmd/kops/integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1418,6 +1418,18 @@ func (i *integrationTest) setupCluster(t *testing.T, ctx context.Context, inputY
secondaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBALE1vJwNk3HlXVk6JfFlK9oWkdHAp4cN9y4xSK12g+2dpUyUxMYN\nYAy4JWYUcUBaiEhjKd6YR6CZmRnXlLsASt8CAwEAAQJABeku812Yj3IBHRrNbTHc\ntpeOIZr1e5HBru7B59dOKzzKrI2SozD+wKmhi2r+8yPkdU1nq4DE1Pboc1BmPh9C\n0QIhAMiAQ+yZRuThl8qOCZ+D9Frmml102DIf5d1NjGGQD84FAiEA4kMJCM194VPV\n2W7QsLH+szbwRHXg1dOlR9WQHJ8rZpMCIF/F7SwyV0vzerdVu8EHngxhxPDJZJAk\n7n8UkO71iqclAiEAypza9z4E7oWDZ507Vi9edJ/K0pN4jiJjzIrq7SZ/1+8CID2K\nAMbqYsKhlMt8zM+hSUg+u8wcWs8CVBb4ozQY2Xyb\n-----END RSA PRIVATE KEY-----",
secondaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBeDCCASKgAwIBAgIMFo+bQ+EuVthBfuZvMA0GCSqGSIb3DQEBCwUAMB0xGzAZ\nBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjAeFw0yMTA3MDUyMDExNDZaFw0zMTA3\nMDUyMDExNDZaMB0xGzAZBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjBcMA0GCSqG\nSIb3DQEBAQUAA0sAMEgCQQCxNbycDZNx5V1ZOiXxZSvaFpHRwKeHDfcuMUitdoPt\nnaVMlMTGDWAMuCVmFHFAWohIYynemEegmZkZ15S7AErfAgMBAAGjQjBAMA4GA1Ud\nDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTAjQ8T4HclPIsC\nqipEfUIcLP6jqTANBgkqhkiG9w0BAQsFAANBAJdZ17TN3HlWrH7HQgfR12UBwz8K\nG9DurDznVaBVUYaHY8Sg5AvAXeb+yIF2JMmRR+bK+/G1QYY2D3/P31Ic2Oo=\n-----END CERTIFICATE-----",
})
storeKeyset(t, ctx, keyStore, "etcd-manager-ca-leases", &testingKeyset{
primaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBAMW5A2xmJgkkoaURt6/pc0zhbo8rq7kX4zoWJmUV+MNVLXecut3V\nHPfLI3PRhlGDB3ftJNapf2uPLRoZyujeoycCAwEAAQJBALIOHMEfdB1DubW3MN3f\ns4+Ga1PPFgPHOT9z9vuNP8pWcRWGACXdln4T/VM5LQYrwTQ/i9EMZycl3ISbTUfy\nEPECIQD5RWUR1dF4S2VGFtxhttbZbP6m3Nk/eiOmT3wPv4TJDQIhAMsPY9YgTmfV\nuZwykVu/UopdjVY/vFAiFYwA2Km8b2gDAiB9jdiUnTA++SrvnMAwb5nUNjQl9ANx\nF6IxOMPyYrMNWQIhALb2wANRCrSeq+ak3bqockwALXi4ZwphG78RiCewhUVXAiA+\n4yljHjbbEGQje8VuxmA3ITMeCwAkIqjXY1Z5DUTnDA==\n-----END RSA PRIVATE KEY-----",
primaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBfDCCASagAwIBAgIMFo+bKjm1c3jfv6hIMA0GCSqGSIb3DQEBCwUAMB8xHTAb\nBgNVBAMTFGV0Y2QtbWFuYWdlci1jYS1tYWluMB4XDTIxMDcwNTIwMDk1NloXDTMx\nMDcwNTIwMDk1NlowHzEdMBsGA1UEAxMUZXRjZC1tYW5hZ2VyLWNhLW1haW4wXDAN\nBgkqhkiG9w0BAQEFAANLADBIAkEAxbkDbGYmCSShpRG3r+lzTOFujyuruRfjOhYm\nZRX4w1Utd5y63dUc98sjc9GGUYMHd+0k1ql/a48tGhnK6N6jJwIDAQABo0IwQDAO\nBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUWZLkbBFx\nGAgPU4i62c52unSo7RswDQYJKoZIhvcNAQELBQADQQAj6Pgd0va/8FtkyMlnohLu\nGf4v8RJO6zk3Y6jJ4+cwWziipFM1ielMzSOZfFcCZgH3m5Io40is4hPSqyq2TOA6\n-----END CERTIFICATE-----",
secondaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBAMN9483Hf4qLDdOG9Fl2w7ewdHN7Cd2mn3Biz7xt8UQfTeW2K/fq\nmQKt5swBZMbHJ+I9XHuW9fxikwxAApZmYHUCAwEAAQJAOOGfcBe1L52oRz0ESie5\naPBJ4fQR+dFqoOvPYBdpVRV4h8PcLGhH7H0RO0pJf9ni0MxWDMn2R8Nw6/I7zSgr\n/QIhAN432G6YOItNGj0wrNBgZerFIOVdnHe+higgAhJOtNFbAiEA4TXsL5ALyAYI\nVDS66EbriI15z5XxiauBk0zAbqun7m8CIQDUK+Ichn7GkpGRBx6ZvtDQvfNQzHaO\n5nzVZupTbI68rQIgLzkNU1PTBJgvOujroDTuwm1X820vfnyV6PsZBpu71MUCIAPQ\nTjwL4gGtCZtHXHqAUS9vgf4sQ40oBqNb3NhshheB\n-----END RSA PRIVATE KEY-----",
secondaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBfDCCASagAwIBAgIMFo+bQ+Eg8Si30gr4MA0GCSqGSIb3DQEBCwUAMB8xHTAb\nBgNVBAMTFGV0Y2QtbWFuYWdlci1jYS1tYWluMB4XDTIxMDcwNTIwMTE0NloXDTMx\nMDcwNTIwMTE0NlowHzEdMBsGA1UEAxMUZXRjZC1tYW5hZ2VyLWNhLW1haW4wXDAN\nBgkqhkiG9w0BAQEFAANLADBIAkEAw33jzcd/iosN04b0WXbDt7B0c3sJ3aafcGLP\nvG3xRB9N5bYr9+qZAq3mzAFkxscn4j1ce5b1/GKTDEAClmZgdQIDAQABo0IwQDAO\nBgNVHQ8BAf8EBAMCAQYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUE/h+3gDP\nDvKwHRyiYlXM8voZ1wowDQYJKoZIhvcNAQELBQADQQBXuimeEoAOu5HN4hG7NqL9\nt40K3ZRhRZv3JQWnRVJCBDjg1rD0GQJR/n+DoWvbeijI5C9pNjr2pWSIYR1eYCvd\n-----END CERTIFICATE-----",
})
storeKeyset(t, ctx, keyStore, "etcd-peers-ca-leases", &testingKeyset{
primaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBOwIBAAJBALJFpdanCA3og1CrCz2n8G88SUm/ZGej11VMWGVCoMBpQld7swGa\nI7g0lxbvoSjN4GHnO1Hf/g0TUUzbHxOKxLcCAwEAAQJBAI418S1i4ZH2wYpAaB8v\nMSYLOYuTGk1y7fwlgv6EQCg8esJcMCeDsqT5V5sUicT6jT5m3KdpKA4v4kpZJzHo\nr8ECIQDRtEmpTSmTQ1FAVPu34j6ZU0W5zT8RMaoUFPCXPJ/M9QIhANmg7bTqNNBY\nd7TUxmgm2NW5GDn0yyg1WqoIL4wOJz97AiBvrCad9e1x8qNOMvNpVR4o4GN9MoOn\nUF9WGmCU6T/gEQIgdhnEBdK3eH0Z8TMqvKigMVNyFzmF6jsSCYXJr7qah/MCIQCy\npxPa6cKMC0n9t61B+1f7O2yCvwllormxaFYVm9J4xw==\n-----END RSA PRIVATE KEY-----",
primaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBeDCCASKgAwIBAgIMFo+bKjmuLDDLcDHsMA0GCSqGSIb3DQEBCwUAMB0xGzAZ\nBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjAeFw0yMTA3MDUyMDA5NTZaFw0zMTA3\nMDUyMDA5NTZaMB0xGzAZBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjBcMA0GCSqG\nSIb3DQEBAQUAA0sAMEgCQQCyRaXWpwgN6INQqws9p/BvPElJv2Rno9dVTFhlQqDA\naUJXe7MBmiO4NJcW76EozeBh5ztR3/4NE1FM2x8TisS3AgMBAAGjQjBAMA4GA1Ud\nDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBQtE1d49uSvpURf\nOQ25Vlu6liY20DANBgkqhkiG9w0BAQsFAANBAAgLVaetJZcfOA3OIMMvQbz2Ydrt\nuWF9BKkIad8jrcIrm3IkOtR8bKGmDIIaRKuG/ZUOL6NMe2fky3AAfKwleL4=\n-----END CERTIFICATE-----",
secondaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBOgIBAAJBALE1vJwNk3HlXVk6JfFlK9oWkdHAp4cN9y4xSK12g+2dpUyUxMYN\nYAy4JWYUcUBaiEhjKd6YR6CZmRnXlLsASt8CAwEAAQJABeku812Yj3IBHRrNbTHc\ntpeOIZr1e5HBru7B59dOKzzKrI2SozD+wKmhi2r+8yPkdU1nq4DE1Pboc1BmPh9C\n0QIhAMiAQ+yZRuThl8qOCZ+D9Frmml102DIf5d1NjGGQD84FAiEA4kMJCM194VPV\n2W7QsLH+szbwRHXg1dOlR9WQHJ8rZpMCIF/F7SwyV0vzerdVu8EHngxhxPDJZJAk\n7n8UkO71iqclAiEAypza9z4E7oWDZ507Vi9edJ/K0pN4jiJjzIrq7SZ/1+8CID2K\nAMbqYsKhlMt8zM+hSUg+u8wcWs8CVBb4ozQY2Xyb\n-----END RSA PRIVATE KEY-----",
secondaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBeDCCASKgAwIBAgIMFo+bQ+EuVthBfuZvMA0GCSqGSIb3DQEBCwUAMB0xGzAZ\nBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjAeFw0yMTA3MDUyMDExNDZaFw0zMTA3\nMDUyMDExNDZaMB0xGzAZBgNVBAMTEmV0Y2QtcGVlcnMtY2EtbWFpbjBcMA0GCSqG\nSIb3DQEBAQUAA0sAMEgCQQCxNbycDZNx5V1ZOiXxZSvaFpHRwKeHDfcuMUitdoPt\nnaVMlMTGDWAMuCVmFHFAWohIYynemEegmZkZ15S7AErfAgMBAAGjQjBAMA4GA1Ud\nDwEB/wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTAjQ8T4HclPIsC\nqipEfUIcLP6jqTANBgkqhkiG9w0BAQsFAANBAJdZ17TN3HlWrH7HQgfR12UBwz8K\nG9DurDznVaBVUYaHY8Sg5AvAXeb+yIF2JMmRR+bK+/G1QYY2D3/P31Ic2Oo=\n-----END CERTIFICATE-----",
})
storeKeyset(t, ctx, keyStore, "service-account", &testingKeyset{
primaryKey: "-----BEGIN RSA PRIVATE KEY-----\nMIIBPQIBAAJBANiW3hfHTcKnxCig+uWhpVbOfH1pANKmXVSysPKgE80QSU4tZ6m4\n9pAEeIMsvwvDMaLsb2v6JvXe0qvCmueU+/sCAwEAAQJBAKt/gmpHqP3qA3u8RA5R\n2W6L360Z2Mnza1FmkI/9StCCkJGjuE5yDhxU4JcVnFyX/nMxm2ockEEQDqRSu7Oo\nxTECIQD2QsUsgFL4FnXWzTclySJ6ajE4Cte3gSDOIvyMNMireQIhAOEnsV8UaSI+\nZyL7NMLzMPLCgtsrPnlamr8gdrEHf9ITAiEAxCCLbpTI/4LL2QZZrINTLVGT34Fr\nKl/yI5pjrrp/M2kCIQDfOktQyRuzJ8t5kzWsUxCkntS+FxHJn1rtQ3Jp8dV4oQIh\nAOyiVWDyLZJvg7Y24Ycmp86BZjM9Wk/BfWpBXKnl9iDY\n-----END RSA PRIVATE KEY-----",
primaryCertificate: "-----BEGIN CERTIFICATE-----\nMIIBZzCCARGgAwIBAgIBAjANBgkqhkiG9w0BAQsFADAaMRgwFgYDVQQDEw9zZXJ2\naWNlLWFjY291bnQwHhcNMjEwNTAyMjAzMDA2WhcNMzEwNTAyMjAzMDA2WjAaMRgw\nFgYDVQQDEw9zZXJ2aWNlLWFjY291bnQwXDANBgkqhkiG9w0BAQEFAANLADBIAkEA\n2JbeF8dNwqfEKKD65aGlVs58fWkA0qZdVLKw8qATzRBJTi1nqbj2kAR4gyy/C8Mx\nouxva/om9d7Sq8Ka55T7+wIDAQABo0IwQDAOBgNVHQ8BAf8EBAMCAQYwDwYDVR0T\nAQH/BAUwAwEB/zAdBgNVHQ4EFgQUI5beFHueAGyT1pQ6UTOdbMfj3gQwDQYJKoZI\nhvcNAQELBQADQQBwPLO+Np8o6k3aNBGKE4JTCOs06X72OXNivkWWWP/9XGz6x4DI\nHPU65kbUn/pWXBUVVlpsKsdmWA2Bu8pd/vD+\n-----END CERTIFICATE-----\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/cli/kops_create_cluster.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 32 additions & 0 deletions docs/cluster_spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,38 @@ etcdClusters:

The etcd version used by kOps follows the recommended etcd version for the given kubernetes version. It is possible to override this by adding the `version` key to each of the etcd clusters.

### The `leases` etcd shard for megaclusters

kOps supports configuring an optional `leases` etcd shard. This shard is specifically designed for megaclusters to isolate the massive volume of high-frequency write traffic generated by node heartbeats. By redirecting this traffic to a dedicated `leases` shard, it prevents the primary etcd database from being overwhelmed, ensuring overall control plane stability.

```yaml
etcdClusters:
- etcdMembers:
- instanceGroup: master0-az0
name: a-1
- instanceGroup: master1-az0
name: a-2
- instanceGroup: master0-az1
name: b-1
name: main
- etcdMembers:
- instanceGroup: master0-az0
name: a-1
- instanceGroup: master1-az0
name: a-2
- instanceGroup: master0-az1
name: b-1
name: events
- etcdMembers:
- instanceGroup: master0-az0
name: a-1
- instanceGroup: master1-az0
name: a-2
- instanceGroup: master0-az1
name: b-1
name: leases
```

By default, the Volumes created for the etcd clusters are `gp3` and 20GB each. The volume size, type (`gp2`, `gp3`, `io1`, `io2`), iops( for `io1`, `io2`, `gp3`) and throughput (`gp3`) can be configured via their parameters.

As of kOps 1.12.0 it is also possible to modify the requests for your etcd cluster members using the `cpuRequest` and `memoryRequest` parameters.
Expand Down
4 changes: 2 additions & 2 deletions k8s/crds/kops.k8s.io_clusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1444,8 +1444,8 @@ spec:
pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$
x-kubernetes-int-or-string: true
name:
description: Name is the name of the etcd cluster (main, events
etc)
description: Name is the name of the etcd cluster (main, events,
leases etc)
type: string
provider:
description: |-
Expand Down
2 changes: 1 addition & 1 deletion nodeup/pkg/model/etcd_manager_tls.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (b *EtcdManagerTLSBuilder) Build(ctx *fi.NodeupModelBuilderContext) error {
keys["etcd-clients-ca"] = "etcd-clients-ca-" + etcdClusterName

// Because API server can only have a single client certificate for etcd, we need to share a client CA
if etcdClusterName == "main" || etcdClusterName == "events" {
if etcdClusterName == "main" || etcdClusterName == "events" || etcdClusterName == "leases" {
keys["etcd-clients-ca"] = "etcd-clients-ca"
}

Expand Down
3 changes: 3 additions & 0 deletions nodeup/pkg/model/kube_apiserver.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,9 @@ func (b *KubeAPIServerBuilder) buildPod(ctx context.Context, kubeAPIServer *kops
if strings.HasPrefix(kubeAPIServer.EtcdServersOverrides[i], "/events") {
kubeAPIServer.EtcdServersOverrides[i] = strings.ReplaceAll(kubeAPIServer.EtcdServersOverrides[i], "127.0.0.1", eventsEtcdDNSName)
}
if strings.HasPrefix(kubeAPIServer.EtcdServersOverrides[i], "/registry/leases") {
kubeAPIServer.EtcdServersOverrides[i] = strings.ReplaceAll(kubeAPIServer.EtcdServersOverrides[i], "127.0.0.1", "leases.etcd.internal."+clusterName)
}
}
}

Expand Down
1 change: 1 addition & 0 deletions nodeup/pkg/model/logrotate.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ func (b *LogrotateBuilder) Build(c *fi.NodeupModelBuilderContext) error {
b.addLogRotate(c, "kubelet", "/var/log/kubelet.log", logRotateOptions{})
b.addLogRotate(c, "etcd", "/var/log/etcd.log", logRotateOptions{})
b.addLogRotate(c, "etcd-events", "/var/log/etcd-events.log", logRotateOptions{})
b.addLogRotate(c, "etcd-leases", "/var/log/etcd-leases.log", logRotateOptions{})
if b.NodeupConfig.UseCiliumEtcd {
b.addLogRotate(c, "etcd-cilium", "/var/log/etcd-cilium.log", logRotateOptions{})
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/kops/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,7 @@ const (

// EtcdClusterSpec is the etcd cluster specification
type EtcdClusterSpec struct {
// Name is the name of the etcd cluster (main, events etc)
// Name is the name of the etcd cluster (main, events, leases etc)
Name string `json:"name,omitempty"`
// Provider is the provider used to run etcd: Manager, Legacy.
// Defaults to Manager.
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/kops/status.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ type ClusterStatus struct {

// EtcdClusterStatus represents the status of etcd: because etcd only allows limited reconfiguration, we have to block changes once etcd has been initialized.
type EtcdClusterStatus struct {
// Name is the name of the etcd cluster (main, events etc)
// Name is the name of the etcd cluster (main, events, leases etc)
Name string `json:"name,omitempty"`
// EtcdMember stores the configurations for each member of the cluster (including the data volume)
Members []*EtcdMemberStatus `json:"etcdMembers,omitempty"`
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/kops/v1alpha2/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -648,7 +648,7 @@ const (

// EtcdClusterSpec is the etcd cluster specification
type EtcdClusterSpec struct {
// Name is the name of the etcd cluster (main, events etc)
// Name is the name of the etcd cluster (main, events, leases etc)
Name string `json:"name,omitempty"`
// Provider is the provider used to run etcd: Manager, Legacy.
// Defaults to Manager.
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/kops/v1alpha3/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -623,7 +623,7 @@ type ExternalDNSConfig struct {

// EtcdClusterSpec is the etcd cluster specification
type EtcdClusterSpec struct {
// Name is the name of the etcd cluster (main, events etc)
// Name is the name of the etcd cluster (main, events, leases etc)
Name string `json:"name,omitempty"`
Provider string `json:"-"`
// Members stores the configurations for each member of the cluster (including the data volume)
Expand Down
2 changes: 1 addition & 1 deletion pkg/apis/kops/validation/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,7 @@ func validateExternalPolicies(role string, policies []string, fldPath *field.Pat
func validateEtcdClusterSpec(spec kops.EtcdClusterSpec, c *kops.Cluster, fieldPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{}

allErrs = append(allErrs, IsValidValue(fieldPath.Child("name"), &spec.Name, []string{"cilium", "main", "events"})...)
allErrs = append(allErrs, IsValidValue(fieldPath.Child("name"), &spec.Name, []string{"cilium", "main", "events", "leases"})...)

if spec.Provider != "" {
allErrs = append(allErrs, IsValidValue(fieldPath.Child("provider"), &spec.Provider, []kops.EtcdProviderType{kops.EtcdProviderTypeManager})...)
Expand Down
1 change: 1 addition & 0 deletions pkg/dump/dumper.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ func NewLogDumper(bastionAddress string, sshConfig *ssh.ClientConfig, keyRing ag
"etcd",
"etcd-events",
"etcd-cilium",
"etcd-leases",
"glbc",
"cluster-autoscaler",
"kube-addon-manager",
Expand Down
2 changes: 2 additions & 0 deletions pkg/model/awsmodel/autoscalinggroup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,10 @@ func TestAPIServerAdditionalSecurityGroupsWithNLB(t *testing.T) {
"apiserver-aggregator-ca",
"etcd-clients-ca",
"etcd-manager-ca-events",
"etcd-manager-ca-leases",
"etcd-manager-ca-main",
"etcd-peers-ca-events",
"etcd-peers-ca-leases",
"etcd-peers-ca-main",
"service-account",
} {
Expand Down
60 changes: 40 additions & 20 deletions pkg/model/awsmodel/firewall.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,14 @@ func (b *FirewallModelBuilder) applyNodeToMasterBlockSpecificPorts(c *fi.Cloudup
tcpBlocked[wellknownports.EtcdMainPeerPort] = true
tcpBlocked[wellknownports.EtcdEventsPeerPort] = true

for _, c := range b.Cluster.Spec.EtcdClusters {
if c.Name == "leases" {
tcpBlocked[wellknownports.EtcdLeasesClientPort] = true
tcpBlocked[wellknownports.EtcdLeasesPeerPort] = true
break
}
}

udpRanges := []portRange{{From: 1, To: 65535}}
protocols := []Protocol{}

Expand Down Expand Up @@ -307,27 +315,39 @@ func (b *AWSModelContext) GetSecurityGroups(role kops.InstanceGroupRole) ([]Secu
name := b.SecurityGroupName(role)
switch role {
case kops.InstanceGroupRoleControlPlane:
removeExtraRules := []string{
"port=22", // SSH
"port=443", // k8s api
"port=" + strconv.Itoa(wellknownports.EtcdMainPeerPort), // etcd main peer
"port=" + strconv.Itoa(wellknownports.EtcdEventsPeerPort), // etcd events peer
"port=3988", // kops-controller
"port=" + strconv.Itoa(wellknownports.EtcdMainClientPort), // etcd main
"port=" + strconv.Itoa(wellknownports.EtcdEventsClientPort), // etcd events
"port=4789", // VXLAN
"port=179", // Calico
"port=8443", // k8s api secondary listener
"port=3:4", // ICMP
"port=-1", // ICMPv6

// TODO: UDP vs TCP vs ICMP vs ICMPv6
// TODO: Protocol 4 for calico
}

for _, c := range b.Cluster.Spec.EtcdClusters {
if c.Name == "leases" {
removeExtraRules = append(removeExtraRules,
"port="+strconv.Itoa(wellknownports.EtcdLeasesPeerPort), // etcd leases peer
"port="+strconv.Itoa(wellknownports.EtcdLeasesClientPort), // etcd leases
)
break
}
}

baseGroup = &awstasks.SecurityGroup{
Name: fi.PtrTo(name),
VPC: b.LinkToVPC(),
Description: fi.PtrTo("Security group for masters"),
RemoveExtraRules: []string{
"port=22", // SSH
"port=443", // k8s api
"port=" + strconv.Itoa(wellknownports.EtcdMainPeerPort), // etcd main peer
"port=" + strconv.Itoa(wellknownports.EtcdEventsPeerPort), // etcd events peer
"port=3988", // kops-controller
"port=" + strconv.Itoa(wellknownports.EtcdMainClientPort), // etcd main
"port=" + strconv.Itoa(wellknownports.EtcdEventsClientPort), // etcd events
"port=4789", // VXLAN
"port=179", // Calico
"port=8443", // k8s api secondary listener
"port=3:4", // ICMP
"port=-1", // ICMPv6

// TODO: UDP vs TCP vs ICMP vs ICMPv6
// TODO: Protocol 4 for calico
},
Name: fi.PtrTo(name),
VPC: b.LinkToVPC(),
Description: fi.PtrTo("Security group for masters"),
RemoveExtraRules: removeExtraRules,
}
baseGroup.Tags = b.CloudTags(name, false)
case kops.InstanceGroupRoleNode:
Expand Down
9 changes: 8 additions & 1 deletion pkg/model/azuremodel/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,13 @@ func (b *NetworkModelBuilder) Build(c *fi.CloudupModelBuilderContext) error {
DestinationApplicationSecurityGroupNames: []*string{fi.PtrTo(b.NameForApplicationSecurityGroupNodes())},
DestinationPortRange: fi.PtrTo("*"),
})
etcdPeerMax := wellknownports.EtcdEventsPeerPort
for _, c := range b.Cluster.Spec.EtcdClusters {
if c.Name == "leases" {
etcdPeerMax = wellknownports.EtcdLeasesPeerPort
break
}
}
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
Name: fi.PtrTo("DenyNodesToEtcdManager"),
Priority: fi.PtrTo[int32](1003),
Expand All @@ -185,7 +192,7 @@ func (b *NetworkModelBuilder) Build(c *fi.CloudupModelBuilderContext) error {
SourceApplicationSecurityGroupNames: []*string{fi.PtrTo(b.NameForApplicationSecurityGroupNodes())},
SourcePortRange: fi.PtrTo("*"),
DestinationApplicationSecurityGroupNames: []*string{fi.PtrTo(b.NameForApplicationSecurityGroupControlPlane())},
DestinationPortRange: fi.PtrTo(strconv.Itoa(wellknownports.EtcdMainPeerPort) + "-" + strconv.Itoa(wellknownports.EtcdEventsPeerPort)),
DestinationPortRange: fi.PtrTo(strconv.Itoa(wellknownports.EtcdMainPeerPort) + "-" + strconv.Itoa(etcdPeerMax)),
})
nsgTask.SecurityRules = append(nsgTask.SecurityRules, &azuretasks.NetworkSecurityRule{
Name: fi.PtrTo("DenyNodesToEtcd"),
Expand Down
Loading