2017-12-05 01:29:29 +00:00
|
|
|
package cluster
|
|
|
|
|
2018-02-01 21:28:31 +00:00
|
|
|
import (
|
|
|
|
"context"
|
2018-08-31 21:41:24 +00:00
|
|
|
"fmt"
|
2018-02-01 21:28:31 +00:00
|
|
|
|
2018-05-07 21:51:09 +00:00
|
|
|
"github.com/rancher/rke/k8s"
|
2018-02-01 21:28:31 +00:00
|
|
|
"github.com/rancher/rke/log"
|
|
|
|
"github.com/rancher/rke/services"
|
2018-02-26 16:27:32 +00:00
|
|
|
"github.com/rancher/types/apis/management.cattle.io/v3"
|
2018-02-01 21:28:31 +00:00
|
|
|
)
|
|
|
|
|
2017-12-05 01:29:29 +00:00
|
|
|
const (
|
2018-03-29 19:51:35 +00:00
|
|
|
DefaultServiceClusterIPRange = "10.43.0.0/16"
|
2018-06-06 21:23:20 +00:00
|
|
|
DefaultNodePortRange = "30000-32767"
|
2018-03-29 19:51:35 +00:00
|
|
|
DefaultClusterCIDR = "10.42.0.0/16"
|
|
|
|
DefaultClusterDNSService = "10.43.0.10"
|
2017-12-05 01:29:29 +00:00
|
|
|
DefaultClusterDomain = "cluster.local"
|
2018-03-14 00:18:07 +00:00
|
|
|
DefaultClusterName = "local"
|
2017-12-05 01:29:29 +00:00
|
|
|
DefaultClusterSSHKeyPath = "~/.ssh/id_rsa"
|
|
|
|
|
2018-04-21 01:44:21 +00:00
|
|
|
DefaultK8sVersion = v3.DefaultK8s
|
2018-02-26 16:27:32 +00:00
|
|
|
|
2018-01-19 18:42:42 +00:00
|
|
|
DefaultSSHPort = "22"
|
2017-12-14 21:56:19 +00:00
|
|
|
DefaultDockerSockPath = "/var/run/docker.sock"
|
|
|
|
|
2017-12-14 21:56:19 +00:00
|
|
|
DefaultAuthStrategy = "x509"
|
2017-12-16 09:48:42 +00:00
|
|
|
DefaultAuthorizationMode = "rbac"
|
2017-12-05 01:29:29 +00:00
|
|
|
|
2018-04-05 11:09:22 +00:00
|
|
|
DefaultNetworkPlugin = "canal"
|
2017-12-07 18:07:23 +00:00
|
|
|
DefaultNetworkCloudProvider = "none"
|
2017-12-05 01:29:29 +00:00
|
|
|
|
2018-05-09 17:39:19 +00:00
|
|
|
DefaultIngressController = "nginx"
|
|
|
|
DefaultEtcdBackupCreationPeriod = "5m0s"
|
|
|
|
DefaultEtcdBackupRetentionPeriod = "24h"
|
2018-07-17 18:19:08 +00:00
|
|
|
DefaultMonitoringProvider = "metrics-server"
|
2018-09-24 23:24:45 +00:00
|
|
|
|
|
|
|
DefaultEtcdHeartbeatIntervalName = "heartbeat-interval"
|
|
|
|
DefaultEtcdHeartbeatIntervalValue = "500"
|
|
|
|
DefaultEtcdElectionTimeoutName = "election-timeout"
|
|
|
|
DefaultEtcdElectionTimeoutValue = "5000"
|
2017-12-05 01:29:29 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func setDefaultIfEmptyMapValue(configMap map[string]string, key string, value string) {
|
|
|
|
if _, ok := configMap[key]; !ok {
|
|
|
|
configMap[key] = value
|
|
|
|
}
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
|
2017-12-05 01:29:29 +00:00
|
|
|
func setDefaultIfEmpty(varName *string, defaultValue string) {
|
|
|
|
if len(*varName) == 0 {
|
|
|
|
*varName = defaultValue
|
|
|
|
}
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
|
|
|
|
func (c *Cluster) setClusterDefaults(ctx context.Context) {
|
|
|
|
if len(c.SSHKeyPath) == 0 {
|
|
|
|
c.SSHKeyPath = DefaultClusterSSHKeyPath
|
|
|
|
}
|
2018-04-11 22:54:47 +00:00
|
|
|
// Default Path prefix
|
|
|
|
if len(c.PrefixPath) == 0 {
|
|
|
|
c.PrefixPath = "/"
|
|
|
|
}
|
2018-05-08 22:30:50 +00:00
|
|
|
// Set bastion/jump host defaults
|
|
|
|
if len(c.BastionHost.Address) > 0 {
|
|
|
|
if len(c.BastionHost.Port) == 0 {
|
|
|
|
c.BastionHost.Port = DefaultSSHPort
|
|
|
|
}
|
|
|
|
if len(c.BastionHost.SSHKeyPath) == 0 {
|
|
|
|
c.BastionHost.SSHKeyPath = c.SSHKeyPath
|
|
|
|
}
|
|
|
|
c.BastionHost.SSHAgentAuth = c.SSHAgentAuth
|
|
|
|
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
for i, host := range c.Nodes {
|
|
|
|
if len(host.InternalAddress) == 0 {
|
|
|
|
c.Nodes[i].InternalAddress = c.Nodes[i].Address
|
|
|
|
}
|
|
|
|
if len(host.HostnameOverride) == 0 {
|
|
|
|
// This is a temporary modification
|
|
|
|
c.Nodes[i].HostnameOverride = c.Nodes[i].Address
|
|
|
|
}
|
|
|
|
if len(host.SSHKeyPath) == 0 {
|
|
|
|
c.Nodes[i].SSHKeyPath = c.SSHKeyPath
|
|
|
|
}
|
2018-01-19 18:42:42 +00:00
|
|
|
if len(host.Port) == 0 {
|
|
|
|
c.Nodes[i].Port = DefaultSSHPort
|
|
|
|
}
|
2018-03-06 00:52:43 +00:00
|
|
|
|
|
|
|
// For now, you can set at the global level only.
|
|
|
|
c.Nodes[i].SSHAgentAuth = c.SSHAgentAuth
|
2018-02-01 21:28:31 +00:00
|
|
|
}
|
2018-03-06 00:52:43 +00:00
|
|
|
|
2018-02-01 21:28:31 +00:00
|
|
|
if len(c.Authorization.Mode) == 0 {
|
|
|
|
c.Authorization.Mode = DefaultAuthorizationMode
|
|
|
|
}
|
|
|
|
if c.Services.KubeAPI.PodSecurityPolicy && c.Authorization.Mode != services.RBACAuthorizationMode {
|
|
|
|
log.Warnf(ctx, "PodSecurityPolicy can't be enabled with RBAC support disabled")
|
|
|
|
c.Services.KubeAPI.PodSecurityPolicy = false
|
|
|
|
}
|
2018-02-07 00:30:25 +00:00
|
|
|
if len(c.Ingress.Provider) == 0 {
|
|
|
|
c.Ingress.Provider = DefaultIngressController
|
2018-02-01 21:28:31 +00:00
|
|
|
}
|
2018-03-14 00:18:07 +00:00
|
|
|
if len(c.ClusterName) == 0 {
|
|
|
|
c.ClusterName = DefaultClusterName
|
|
|
|
}
|
2018-04-18 03:16:57 +00:00
|
|
|
if len(c.Version) == 0 {
|
|
|
|
c.Version = DefaultK8sVersion
|
|
|
|
}
|
2018-05-07 21:51:09 +00:00
|
|
|
if c.AddonJobTimeout == 0 {
|
|
|
|
c.AddonJobTimeout = k8s.DefaultTimeout
|
|
|
|
}
|
2018-07-17 18:19:08 +00:00
|
|
|
if len(c.Monitoring.Provider) == 0 {
|
|
|
|
c.Monitoring.Provider = DefaultMonitoringProvider
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
c.setClusterImageDefaults()
|
|
|
|
c.setClusterServicesDefaults()
|
|
|
|
c.setClusterNetworkDefaults()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Cluster) setClusterServicesDefaults() {
|
2018-05-10 21:45:15 +00:00
|
|
|
// We don't accept per service images anymore.
|
|
|
|
c.Services.KubeAPI.Image = c.SystemImages.Kubernetes
|
|
|
|
c.Services.Scheduler.Image = c.SystemImages.Kubernetes
|
|
|
|
c.Services.KubeController.Image = c.SystemImages.Kubernetes
|
|
|
|
c.Services.Kubelet.Image = c.SystemImages.Kubernetes
|
|
|
|
c.Services.Kubeproxy.Image = c.SystemImages.Kubernetes
|
|
|
|
c.Services.Etcd.Image = c.SystemImages.Etcd
|
|
|
|
|
2018-02-01 21:28:31 +00:00
|
|
|
serviceConfigDefaultsMap := map[*string]string{
|
|
|
|
&c.Services.KubeAPI.ServiceClusterIPRange: DefaultServiceClusterIPRange,
|
2018-06-06 21:23:20 +00:00
|
|
|
&c.Services.KubeAPI.ServiceNodePortRange: DefaultNodePortRange,
|
2018-02-01 21:28:31 +00:00
|
|
|
&c.Services.KubeController.ServiceClusterIPRange: DefaultServiceClusterIPRange,
|
|
|
|
&c.Services.KubeController.ClusterCIDR: DefaultClusterCIDR,
|
|
|
|
&c.Services.Kubelet.ClusterDNSServer: DefaultClusterDNSService,
|
|
|
|
&c.Services.Kubelet.ClusterDomain: DefaultClusterDomain,
|
2018-02-05 15:50:39 +00:00
|
|
|
&c.Services.Kubelet.InfraContainerImage: c.SystemImages.PodInfraContainer,
|
2018-02-01 21:28:31 +00:00
|
|
|
&c.Authentication.Strategy: DefaultAuthStrategy,
|
2018-05-09 17:39:19 +00:00
|
|
|
&c.Services.Etcd.Creation: DefaultEtcdBackupCreationPeriod,
|
|
|
|
&c.Services.Etcd.Retention: DefaultEtcdBackupRetentionPeriod,
|
2018-02-01 21:28:31 +00:00
|
|
|
}
|
|
|
|
for k, v := range serviceConfigDefaultsMap {
|
|
|
|
setDefaultIfEmpty(k, v)
|
|
|
|
}
|
2018-09-24 23:24:45 +00:00
|
|
|
// Add etcd timeouts
|
|
|
|
if c.Services.Etcd.ExtraArgs == nil {
|
|
|
|
c.Services.Etcd.ExtraArgs = make(map[string]string)
|
|
|
|
}
|
|
|
|
if _, ok := c.Services.Etcd.ExtraArgs[DefaultEtcdElectionTimeoutName]; !ok {
|
|
|
|
c.Services.Etcd.ExtraArgs[DefaultEtcdElectionTimeoutName] = DefaultEtcdElectionTimeoutValue
|
|
|
|
}
|
|
|
|
if _, ok := c.Services.Etcd.ExtraArgs[DefaultEtcdHeartbeatIntervalName]; !ok {
|
|
|
|
c.Services.Etcd.ExtraArgs[DefaultEtcdHeartbeatIntervalName] = DefaultEtcdHeartbeatIntervalValue
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *Cluster) setClusterImageDefaults() {
|
2018-08-31 21:41:24 +00:00
|
|
|
var privRegURL string
|
2018-02-26 16:27:32 +00:00
|
|
|
imageDefaults, ok := v3.K8sVersionToRKESystemImages[c.Version]
|
|
|
|
if !ok {
|
|
|
|
imageDefaults = v3.K8sVersionToRKESystemImages[DefaultK8sVersion]
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
|
2018-08-31 21:41:24 +00:00
|
|
|
for _, privReg := range c.PrivateRegistries {
|
|
|
|
if privReg.IsDefault {
|
|
|
|
privRegURL = privReg.URL
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
2018-02-01 21:28:31 +00:00
|
|
|
systemImagesDefaultsMap := map[*string]string{
|
2018-08-31 21:41:24 +00:00
|
|
|
&c.SystemImages.Alpine: d(imageDefaults.Alpine, privRegURL),
|
|
|
|
&c.SystemImages.NginxProxy: d(imageDefaults.NginxProxy, privRegURL),
|
|
|
|
&c.SystemImages.CertDownloader: d(imageDefaults.CertDownloader, privRegURL),
|
|
|
|
&c.SystemImages.KubeDNS: d(imageDefaults.KubeDNS, privRegURL),
|
|
|
|
&c.SystemImages.KubeDNSSidecar: d(imageDefaults.KubeDNSSidecar, privRegURL),
|
|
|
|
&c.SystemImages.DNSmasq: d(imageDefaults.DNSmasq, privRegURL),
|
|
|
|
&c.SystemImages.KubeDNSAutoscaler: d(imageDefaults.KubeDNSAutoscaler, privRegURL),
|
|
|
|
&c.SystemImages.KubernetesServicesSidecar: d(imageDefaults.KubernetesServicesSidecar, privRegURL),
|
|
|
|
&c.SystemImages.Etcd: d(imageDefaults.Etcd, privRegURL),
|
|
|
|
&c.SystemImages.Kubernetes: d(imageDefaults.Kubernetes, privRegURL),
|
|
|
|
&c.SystemImages.PodInfraContainer: d(imageDefaults.PodInfraContainer, privRegURL),
|
|
|
|
&c.SystemImages.Flannel: d(imageDefaults.Flannel, privRegURL),
|
|
|
|
&c.SystemImages.FlannelCNI: d(imageDefaults.FlannelCNI, privRegURL),
|
|
|
|
&c.SystemImages.CalicoNode: d(imageDefaults.CalicoNode, privRegURL),
|
|
|
|
&c.SystemImages.CalicoCNI: d(imageDefaults.CalicoCNI, privRegURL),
|
|
|
|
&c.SystemImages.CalicoCtl: d(imageDefaults.CalicoCtl, privRegURL),
|
|
|
|
&c.SystemImages.CanalNode: d(imageDefaults.CanalNode, privRegURL),
|
|
|
|
&c.SystemImages.CanalCNI: d(imageDefaults.CanalCNI, privRegURL),
|
|
|
|
&c.SystemImages.CanalFlannel: d(imageDefaults.CanalFlannel, privRegURL),
|
|
|
|
&c.SystemImages.WeaveNode: d(imageDefaults.WeaveNode, privRegURL),
|
|
|
|
&c.SystemImages.WeaveCNI: d(imageDefaults.WeaveCNI, privRegURL),
|
|
|
|
&c.SystemImages.Ingress: d(imageDefaults.Ingress, privRegURL),
|
|
|
|
&c.SystemImages.IngressBackend: d(imageDefaults.IngressBackend, privRegURL),
|
|
|
|
&c.SystemImages.MetricsServer: d(imageDefaults.MetricsServer, privRegURL),
|
2018-02-01 21:28:31 +00:00
|
|
|
}
|
2018-02-26 16:27:32 +00:00
|
|
|
|
2018-02-01 21:28:31 +00:00
|
|
|
for k, v := range systemImagesDefaultsMap {
|
|
|
|
setDefaultIfEmpty(k, v)
|
|
|
|
}
|
|
|
|
}
|
2018-02-05 15:50:39 +00:00
|
|
|
|
|
|
|
func (c *Cluster) setClusterNetworkDefaults() {
|
|
|
|
setDefaultIfEmpty(&c.Network.Plugin, DefaultNetworkPlugin)
|
|
|
|
|
|
|
|
if c.Network.Options == nil {
|
|
|
|
// don't break if the user didn't define options
|
|
|
|
c.Network.Options = make(map[string]string)
|
|
|
|
}
|
|
|
|
networkPluginConfigDefaultsMap := make(map[string]string)
|
2018-05-08 23:53:19 +00:00
|
|
|
// This is still needed because RKE doesn't use c.Network.*NetworkProvider, that's a rancher type
|
2018-02-05 15:50:39 +00:00
|
|
|
switch c.Network.Plugin {
|
|
|
|
case CalicoNetworkPlugin:
|
|
|
|
networkPluginConfigDefaultsMap = map[string]string{
|
|
|
|
CalicoCloudProvider: DefaultNetworkCloudProvider,
|
|
|
|
}
|
2018-05-30 08:30:12 +00:00
|
|
|
case FlannelNetworkPlugin:
|
|
|
|
networkPluginConfigDefaultsMap = map[string]string{
|
|
|
|
FlannelBackendType: "vxlan",
|
|
|
|
}
|
|
|
|
case CanalNetworkPlugin:
|
|
|
|
networkPluginConfigDefaultsMap = map[string]string{
|
|
|
|
CanalFlannelBackendType: "vxlan",
|
|
|
|
}
|
2018-02-05 15:50:39 +00:00
|
|
|
}
|
2018-04-02 21:28:40 +00:00
|
|
|
if c.Network.CalicoNetworkProvider != nil {
|
2018-05-08 23:53:19 +00:00
|
|
|
setDefaultIfEmpty(&c.Network.CalicoNetworkProvider.CloudProvider, DefaultNetworkCloudProvider)
|
2018-04-02 21:28:40 +00:00
|
|
|
networkPluginConfigDefaultsMap[CalicoCloudProvider] = c.Network.CalicoNetworkProvider.CloudProvider
|
2018-03-29 20:58:46 +00:00
|
|
|
}
|
2018-04-02 21:28:40 +00:00
|
|
|
if c.Network.FlannelNetworkProvider != nil {
|
|
|
|
networkPluginConfigDefaultsMap[FlannelIface] = c.Network.FlannelNetworkProvider.Iface
|
2018-05-30 08:30:12 +00:00
|
|
|
|
2018-03-29 20:58:46 +00:00
|
|
|
}
|
2018-04-26 03:10:53 +00:00
|
|
|
if c.Network.CanalNetworkProvider != nil {
|
|
|
|
networkPluginConfigDefaultsMap[CanalIface] = c.Network.CanalNetworkProvider.Iface
|
|
|
|
}
|
2018-02-05 15:50:39 +00:00
|
|
|
for k, v := range networkPluginConfigDefaultsMap {
|
|
|
|
setDefaultIfEmptyMapValue(c.Network.Options, k, v)
|
|
|
|
}
|
|
|
|
}
|
2018-08-31 21:41:24 +00:00
|
|
|
|
|
|
|
func d(image, defaultRegistryURL string) string {
|
|
|
|
if len(defaultRegistryURL) == 0 {
|
|
|
|
return image
|
|
|
|
}
|
|
|
|
return fmt.Sprintf("%s/%s", defaultRegistryURL, image)
|
|
|
|
}
|