mirror of
https://github.com/lingble/talos.git
synced 2025-12-03 22:33:50 +00:00
feat: add CNI, and pod and service CIDR to configurator
This adds more methods to the Cluster interface that allows for more granular control of the cluster network settings. Signed-off-by: Andrew Rynhard <andrew@andrewrynhard.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import (
|
||||
"github.com/talos-systems/talos/internal/app/machined/pkg/system/runner/goroutine"
|
||||
"github.com/talos-systems/talos/pkg/config"
|
||||
"github.com/talos-systems/talos/pkg/constants"
|
||||
tnet "github.com/talos-systems/talos/pkg/net"
|
||||
)
|
||||
|
||||
// Bootkube implements the Service interface. It serves as the concrete type with
|
||||
@@ -125,11 +126,11 @@ func generateAssets(config config.Configurator) (err error) {
|
||||
}
|
||||
apiServers = append(apiServers, u)
|
||||
|
||||
_, podCIDR, err := net.ParseCIDR("10.2.0.0/16")
|
||||
_, podCIDR, err := net.ParseCIDR(config.Cluster().Network().PodCIDR())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, serviceCIDR, err := net.ParseCIDR("10.3.0.0/24")
|
||||
_, serviceCIDR, err := net.ParseCIDR(config.Cluster().Network().ServiceCIDR())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -154,6 +155,16 @@ func generateAssets(config config.Configurator) (err error) {
|
||||
return errors.Wrap(err, "failed to parse Kubernetes key")
|
||||
}
|
||||
|
||||
apiServiceIP, err := tnet.NthIPInNetwork(serviceCIDR, 1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
dnsServiceIP, err := tnet.NthIPInNetwork(serviceCIDR, 10)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conf := asset.Config{
|
||||
CACert: k8sCA,
|
||||
CAPrivKey: k8sKey,
|
||||
@@ -163,11 +174,11 @@ func generateAssets(config config.Configurator) (err error) {
|
||||
EtcdServers: []*url.URL{etcdServer},
|
||||
EtcdUseTLS: true,
|
||||
APIServers: apiServers,
|
||||
APIServiceIP: net.ParseIP("10.3.0.1"),
|
||||
DNSServiceIP: net.ParseIP("10.3.0.10"),
|
||||
APIServiceIP: apiServiceIP,
|
||||
DNSServiceIP: dnsServiceIP,
|
||||
PodCIDR: podCIDR,
|
||||
ServiceCIDR: serviceCIDR,
|
||||
NetworkProvider: "flannel",
|
||||
NetworkProvider: config.Cluster().Network().CNI(),
|
||||
AltNames: altNames,
|
||||
Images: asset.DefaultImages,
|
||||
BootstrapSecretsSubdir: "/assets/tls",
|
||||
|
||||
@@ -20,6 +20,15 @@ type Cluster interface {
|
||||
AESCBCEncryptionSecret() string
|
||||
Config(machine.Type) (string, error)
|
||||
Etcd() Etcd
|
||||
Network() Network
|
||||
}
|
||||
|
||||
// Network defines the requirements for a config that pertains to cluster
|
||||
// network options.
|
||||
type Network interface {
|
||||
CNI() string
|
||||
PodCIDR() string
|
||||
ServiceCIDR() string
|
||||
}
|
||||
|
||||
// Etcd defines the requirements for a config that pertains to etcd related
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
|
||||
"github.com/talos-systems/talos/pkg/config/cluster"
|
||||
"github.com/talos-systems/talos/pkg/config/machine"
|
||||
"github.com/talos-systems/talos/pkg/constants"
|
||||
"github.com/talos-systems/talos/pkg/crypto/x509"
|
||||
)
|
||||
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
type ClusterConfig struct {
|
||||
ControlPlane *ControlPlaneConfig `yaml:"controlPlane"`
|
||||
ClusterName string `yaml:"clusterName,omitempty"`
|
||||
Network *ClusterNetworkConfig `yaml:"network,omitempty"`
|
||||
ClusterNetwork *ClusterNetworkConfig `yaml:"network,omitempty"`
|
||||
BootstrapToken string `yaml:"token,omitempty"`
|
||||
CertificateKey string `yaml:"certificateKey"`
|
||||
ClusterAESCBCEncryptionSecret string `yaml:"aescbcEncryptionSecret"`
|
||||
@@ -67,6 +68,7 @@ type EtcdConfig struct {
|
||||
|
||||
// ClusterNetworkConfig represents kube networking config vals
|
||||
type ClusterNetworkConfig struct {
|
||||
CNI string `yaml:"cni"`
|
||||
DNSDomain string `yaml:"dnsDomain"`
|
||||
PodSubnet []string `yaml:"podSubnets"`
|
||||
ServiceSubnet []string `yaml:"serviceSubnets"`
|
||||
@@ -139,3 +141,35 @@ func (c *ClusterConfig) Secret() string {
|
||||
}
|
||||
return parts[1]
|
||||
}
|
||||
|
||||
// Network implements the Configurator interface.
|
||||
func (c *ClusterConfig) Network() cluster.Network {
|
||||
return c
|
||||
}
|
||||
|
||||
// CNI implements the Configurator interface.
|
||||
func (c *ClusterConfig) CNI() string {
|
||||
if c.ClusterNetwork.CNI == "" {
|
||||
return constants.DefaultCNI
|
||||
}
|
||||
|
||||
return c.ClusterNetwork.CNI
|
||||
}
|
||||
|
||||
// PodCIDR implements the Configurator interface.
|
||||
func (c *ClusterConfig) PodCIDR() string {
|
||||
if len(c.ClusterNetwork.PodSubnet) == 0 {
|
||||
return constants.DefaultPodCIDR
|
||||
}
|
||||
|
||||
return c.ClusterNetwork.PodSubnet[0]
|
||||
}
|
||||
|
||||
// ServiceCIDR implements the Configurator interface.
|
||||
func (c *ClusterConfig) ServiceCIDR() string {
|
||||
if len(c.ClusterNetwork.ServiceSubnet) == 0 {
|
||||
return constants.DefaultServiceCIDR
|
||||
}
|
||||
|
||||
return c.ClusterNetwork.ServiceSubnet[0]
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ func initUd(in *Input) (string, error) {
|
||||
EtcdConfig: &v1alpha1.EtcdConfig{
|
||||
RootCA: in.Certs.Etcd,
|
||||
},
|
||||
Network: &v1alpha1.ClusterNetworkConfig{
|
||||
ClusterNetwork: &v1alpha1.ClusterNetworkConfig{
|
||||
DNSDomain: in.ServiceDomain,
|
||||
PodSubnet: in.PodNet,
|
||||
ServiceSubnet: in.ServiceNet,
|
||||
|
||||
@@ -233,6 +233,15 @@ const (
|
||||
|
||||
// DefaultLogPath is the default path to the log storage directory.
|
||||
DefaultLogPath = SystemRunPath + "/log"
|
||||
|
||||
// DefaultCNI is the default CNI.
|
||||
DefaultCNI = "flannel"
|
||||
|
||||
// DefaultPodCIDR is the default pod CIDR block.
|
||||
DefaultPodCIDR = "10.244.0.0/16"
|
||||
|
||||
// DefaultServiceCIDR is the default service CIDR block.
|
||||
DefaultServiceCIDR = "10.96.0.0/12"
|
||||
)
|
||||
|
||||
// See https://linux.die.net/man/3/klogctl
|
||||
|
||||
@@ -6,6 +6,8 @@ package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
// IPAddrs finds and returns a list of non-loopback IPv4 addresses of the
|
||||
@@ -40,3 +42,24 @@ func FormatAddress(addr string) string {
|
||||
}
|
||||
return addr
|
||||
}
|
||||
|
||||
// NthIPInNetwork takes an IPNet and returns the nth IP in it.
|
||||
func NthIPInNetwork(network *net.IPNet, n int) (net.IP, error) {
|
||||
ip := network.IP
|
||||
dst := make([]byte, len(ip))
|
||||
copy(dst, ip)
|
||||
for i := 0; i < n; i++ {
|
||||
for j := len(dst) - 1; j >= 0; j-- {
|
||||
dst[j]++
|
||||
if dst[j] > 0 {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if network.Contains(dst) {
|
||||
return dst, nil
|
||||
}
|
||||
|
||||
return nil, errors.New("network does not contain enough IPs")
|
||||
}
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"gotest.tools/assert"
|
||||
@@ -23,3 +25,73 @@ func TestFormatAddress(t *testing.T) {
|
||||
assert.Equal(t, FormatAddress("192.168.1.1"), "192.168.1.1")
|
||||
assert.Equal(t, FormatAddress("alpha.beta.gamma.com"), "alpha.beta.gamma.com")
|
||||
}
|
||||
|
||||
// nolint: scopelint
|
||||
func TestNthIPInNetwork(t *testing.T) {
|
||||
type args struct {
|
||||
network *net.IPNet
|
||||
n int
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want net.IP
|
||||
}{
|
||||
{
|
||||
name: "increment IPv4 by 1",
|
||||
args: args{
|
||||
network: &net.IPNet{
|
||||
IP: net.IP{10, 96, 0, 0},
|
||||
Mask: net.IPMask{255, 255, 255, 0},
|
||||
},
|
||||
n: 1,
|
||||
},
|
||||
want: net.IP{10, 96, 0, 1},
|
||||
},
|
||||
{
|
||||
name: "increment IPv4 by 10",
|
||||
args: args{
|
||||
network: &net.IPNet{
|
||||
IP: net.IP{10, 96, 0, 0},
|
||||
Mask: net.IPMask{255, 255, 255, 0},
|
||||
},
|
||||
n: 10,
|
||||
},
|
||||
want: net.IP{10, 96, 0, 10},
|
||||
},
|
||||
{
|
||||
name: "increment IPv6 by 1",
|
||||
args: args{
|
||||
network: &net.IPNet{
|
||||
IP: net.ParseIP("2001:db8:a0b:12f0::1"),
|
||||
Mask: net.IPMask{255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
n: 1,
|
||||
},
|
||||
want: net.ParseIP("2001:db8:a0b:12f0::2"),
|
||||
},
|
||||
{
|
||||
name: "increment IPv6 by 10",
|
||||
args: args{
|
||||
network: &net.IPNet{
|
||||
IP: net.ParseIP("2001:db8:a0b:12f0::1"),
|
||||
Mask: net.IPMask{255, 255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
|
||||
},
|
||||
n: 10,
|
||||
},
|
||||
want: net.ParseIP("2001:db8:a0b:12f0::b"),
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := NthIPInNetwork(tt.args.network, tt.args.n)
|
||||
if err != nil {
|
||||
t.Errorf("%v", err)
|
||||
}
|
||||
|
||||
if !reflect.DeepEqual(got, tt.want) {
|
||||
t.Errorf("NthFromIP() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user