2017-12-05 01:29:29 +00:00
package cluster
2018-02-01 21:28:31 +00:00
import (
"context"
2019-10-30 20:04:16 +00:00
"encoding/json"
2020-03-13 06:55:41 +00:00
"errors"
2018-08-31 21:41:24 +00:00
"fmt"
2018-11-13 20:30:40 +00:00
"strings"
2018-02-01 21:28:31 +00:00
2020-03-13 06:55:41 +00:00
"github.com/blang/semver"
2018-11-07 23:54:08 +00:00
"github.com/rancher/rke/cloudprovider"
2018-11-02 05:53:29 +00:00
"github.com/rancher/rke/docker"
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"
2019-10-30 20:04:16 +00:00
"github.com/rancher/rke/metadata"
2018-02-01 21:28:31 +00:00
"github.com/rancher/rke/services"
2018-12-28 16:41:37 +00:00
"github.com/rancher/rke/templates"
2020-07-11 16:24:19 +00:00
v3 "github.com/rancher/rke/types"
2019-06-12 21:09:29 +00:00
"github.com/rancher/rke/util"
"github.com/sirupsen/logrus"
2019-11-20 00:42:59 +00:00
appsv1 "k8s.io/api/apps/v1"
2019-10-30 20:04:16 +00:00
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
2019-11-20 00:42:59 +00:00
"k8s.io/apimachinery/pkg/util/intstr"
2019-10-30 20:04:16 +00:00
apiserverv1alpha1 "k8s.io/apiserver/pkg/apis/apiserver/v1alpha1"
auditv1 "k8s.io/apiserver/pkg/apis/audit/v1"
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-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-12-28 16:41:37 +00:00
DefaultAuthnWebhookFile = templates . AuthnWebhook
DefaultAuthnCacheTimeout = "5s"
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-12-13 08:46:47 +00:00
DefaultIngressController = "nginx"
DefaultEtcdBackupCreationPeriod = "12h"
DefaultEtcdBackupRetentionPeriod = "72h"
DefaultEtcdSnapshot = true
DefaultMonitoringProvider = "metrics-server"
DefaultEtcdBackupConfigIntervalHours = 12
DefaultEtcdBackupConfigRetention = 6
2019-06-12 21:09:29 +00:00
DefaultDNSProvider = "kube-dns"
K8sVersionCoreDNS = "1.14.0"
2018-09-24 23:24:45 +00:00
DefaultEtcdHeartbeatIntervalName = "heartbeat-interval"
DefaultEtcdHeartbeatIntervalValue = "500"
DefaultEtcdElectionTimeoutName = "election-timeout"
DefaultEtcdElectionTimeoutValue = "5000"
2019-04-13 14:43:34 +00:00
DefaultFlannelBackendVxLan = "vxlan"
DefaultFlannelBackendVxLanPort = "8472"
DefaultFlannelBackendVxLanVNI = "1"
2019-10-30 20:04:16 +00:00
2020-02-21 18:52:18 +00:00
DefaultCalicoFlexVolPluginDirectory = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds"
DefaultCanalFlexVolPluginDirectory = "/usr/libexec/kubernetes/kubelet-plugins/volume/exec/nodeagent~uds"
2019-10-30 20:04:16 +00:00
KubeAPIArgAdmissionControlConfigFile = "admission-control-config-file"
DefaultKubeAPIArgAdmissionControlConfigFileValue = "/etc/kubernetes/admission.yaml"
EventRateLimitPluginName = "EventRateLimit"
KubeAPIArgAuditLogPath = "audit-log-path"
KubeAPIArgAuditLogMaxAge = "audit-log-maxage"
KubeAPIArgAuditLogMaxBackup = "audit-log-maxbackup"
KubeAPIArgAuditLogMaxSize = "audit-log-maxsize"
KubeAPIArgAuditLogFormat = "audit-log-format"
KubeAPIArgAuditPolicyFile = "audit-policy-file"
DefaultKubeAPIArgAuditLogPathValue = "/var/log/kube-audit/audit-log.json"
2019-11-21 21:56:48 +00:00
DefaultKubeAPIArgAuditPolicyFileValue = "/etc/kubernetes/audit-policy.yaml"
2020-02-04 19:27:52 +00:00
2020-02-26 21:33:22 +00:00
DefaultMaxUnavailableWorker = "10%"
DefaultMaxUnavailableControlplane = "1"
DefaultNodeDrainTimeout = 120
DefaultNodeDrainGracePeriod = - 1
2017-12-05 01:29:29 +00:00
)
2019-11-20 00:42:59 +00:00
var (
2020-05-20 18:30:46 +00:00
DefaultNodeDrainIgnoreDaemonsets = true
2019-11-20 00:42:59 +00:00
DefaultDaemonSetMaxUnavailable = intstr . FromInt ( 1 )
DefaultDeploymentUpdateStrategyParams = intstr . FromString ( "25%" )
2020-03-26 21:39:24 +00:00
DefaultDaemonSetUpdateStrategy = v3 . DaemonSetUpdateStrategy {
Strategy : appsv1 . RollingUpdateDaemonSetStrategyType ,
2019-11-20 00:42:59 +00:00
RollingUpdate : & appsv1 . RollingUpdateDaemonSet { MaxUnavailable : & DefaultDaemonSetMaxUnavailable } ,
}
2020-03-26 21:39:24 +00:00
DefaultDeploymentUpdateStrategy = v3 . DeploymentStrategy {
Strategy : appsv1 . RollingUpdateDeploymentStrategyType ,
2019-11-20 00:42:59 +00:00
RollingUpdate : & appsv1 . RollingUpdateDeployment {
MaxUnavailable : & DefaultDeploymentUpdateStrategyParams ,
MaxSurge : & DefaultDeploymentUpdateStrategyParams ,
} ,
}
DefaultClusterProportionalAutoscalerLinearParams = v3 . LinearAutoscalerParams { CoresPerReplica : 128 , NodesPerReplica : 4 , Min : 1 , PreventSinglePointFailure : true }
DefaultMonitoringAddonReplicas = int32 ( 1 )
)
2018-11-07 23:54:08 +00:00
type ExternalFlags struct {
2019-01-02 23:02:34 +00:00
CertificateDir string
2018-11-07 23:54:08 +00:00
ClusterFilePath string
2019-01-07 19:52:57 +00:00
DinD bool
2019-01-02 23:02:34 +00:00
ConfigDir string
CustomCerts bool
2018-11-07 23:54:08 +00:00
DisablePortCheck bool
2019-01-02 23:02:34 +00:00
GenerateCSR bool
2018-11-07 23:54:08 +00:00
Local bool
UpdateOnly bool
}
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
2019-04-23 21:42:10 +00:00
func ( c * Cluster ) setClusterDefaults ( ctx context . Context , flags ExternalFlags ) error {
2018-02-01 21:28:31 +00:00
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
2018-11-13 20:30:40 +00:00
c . Nodes [ i ] . HostnameOverride = strings . ToLower ( c . Nodes [ i ] . HostnameOverride )
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 {
2019-05-28 18:51:53 +00:00
c . Version = metadata . DefaultK8sVersion
2018-04-18 03:16:57 +00:00
}
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-11-02 05:53:29 +00:00
//set docker private registry URL
for _ , pr := range c . PrivateRegistries {
if pr . URL == "" {
pr . URL = docker . DockerRegistryURL
}
c . PrivateRegistriesMap [ pr . URL ] = pr
}
2018-07-22 09:36:21 +00:00
2019-01-24 19:20:22 +00:00
err := c . setClusterImageDefaults ( )
if err != nil {
return err
}
2018-07-22 09:36:21 +00:00
2019-04-23 21:42:10 +00:00
if c . RancherKubernetesEngineConfig . RotateCertificates != nil ||
flags . CustomCerts {
c . ForceDeployCerts = true
}
2019-06-12 21:09:29 +00:00
err = c . setClusterDNSDefaults ( )
if err != nil {
return err
}
2018-02-01 21:28:31 +00:00
c . setClusterServicesDefaults ( )
c . setClusterNetworkDefaults ( )
2018-12-28 16:41:37 +00:00
c . setClusterAuthnDefaults ( )
2020-02-04 19:27:52 +00:00
c . setNodeUpgradeStrategy ( )
2019-11-20 00:42:59 +00:00
c . setAddonsDefaults ( )
2019-01-24 19:20:22 +00:00
return nil
2018-02-01 21:28:31 +00:00
}
2020-02-04 19:27:52 +00:00
func ( c * Cluster ) setNodeUpgradeStrategy ( ) {
if c . UpgradeStrategy == nil {
2020-02-26 21:33:22 +00:00
logrus . Debugf ( "No input provided for maxUnavailableWorker, setting it to default value of %v percent" , strings . TrimRight ( DefaultMaxUnavailableWorker , "%" ) )
logrus . Debugf ( "No input provided for maxUnavailableControlplane, setting it to default value of %v" , DefaultMaxUnavailableControlplane )
2020-02-04 19:27:52 +00:00
c . UpgradeStrategy = & v3 . NodeUpgradeStrategy {
2020-02-26 21:33:22 +00:00
MaxUnavailableWorker : DefaultMaxUnavailableWorker ,
MaxUnavailableControlplane : DefaultMaxUnavailableControlplane ,
2020-02-04 19:27:52 +00:00
}
return
}
2020-02-26 21:33:22 +00:00
setDefaultIfEmpty ( & c . UpgradeStrategy . MaxUnavailableWorker , DefaultMaxUnavailableWorker )
setDefaultIfEmpty ( & c . UpgradeStrategy . MaxUnavailableControlplane , DefaultMaxUnavailableControlplane )
2020-02-04 19:27:52 +00:00
if ! c . UpgradeStrategy . Drain {
return
}
if c . UpgradeStrategy . DrainInput == nil {
c . UpgradeStrategy . DrainInput = & v3 . NodeDrainInput {
2020-05-20 18:30:46 +00:00
IgnoreDaemonSets : & DefaultNodeDrainIgnoreDaemonsets ,
2020-02-04 19:27:52 +00:00
// default to 120 seems to work better for controlplane nodes
Timeout : DefaultNodeDrainTimeout ,
//Period of time in seconds given to each pod to terminate gracefully.
// If negative, the default value specified in the pod will be used
GracePeriod : DefaultNodeDrainGracePeriod ,
}
}
}
2018-02-01 21:28:31 +00:00
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-11-01 22:33:30 +00:00
// enable etcd snapshots by default
2018-11-07 00:08:38 +00:00
if c . Services . Etcd . Snapshot == nil {
defaultSnapshot := DefaultEtcdSnapshot
c . Services . Etcd . Snapshot = & defaultSnapshot
}
2018-11-01 22:33:30 +00:00
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-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-12-13 08:46:47 +00:00
2019-03-18 17:22:00 +00:00
if c . Services . Etcd . BackupConfig != nil &&
( c . Services . Etcd . BackupConfig . Enabled == nil ||
( c . Services . Etcd . BackupConfig . Enabled != nil && * c . Services . Etcd . BackupConfig . Enabled ) ) {
2018-12-13 08:46:47 +00:00
if c . Services . Etcd . BackupConfig . IntervalHours == 0 {
c . Services . Etcd . BackupConfig . IntervalHours = DefaultEtcdBackupConfigIntervalHours
}
if c . Services . Etcd . BackupConfig . Retention == 0 {
c . Services . Etcd . BackupConfig . Retention = DefaultEtcdBackupConfigRetention
}
}
2019-10-30 20:04:16 +00:00
if _ , ok := c . Services . KubeAPI . ExtraArgs [ KubeAPIArgAdmissionControlConfigFile ] ; ! ok {
if c . Services . KubeAPI . EventRateLimit != nil &&
c . Services . KubeAPI . EventRateLimit . Enabled &&
c . Services . KubeAPI . EventRateLimit . Configuration == nil {
c . Services . KubeAPI . EventRateLimit . Configuration = newDefaultEventRateLimitConfig ( )
}
}
2020-03-13 06:55:41 +00:00
enableKubeAPIAuditLog , err := checkVersionNeedsKubeAPIAuditLog ( c . Version )
if err != nil {
logrus . Warnf ( "Can not determine if cluster version [%s] needs to have kube-api audit log enabled: %v" , c . Version , err )
}
if enableKubeAPIAuditLog {
logrus . Debugf ( "Enabling kube-api audit log for cluster version [%s]" , c . Version )
if c . Services . KubeAPI . AuditLog == nil {
c . Services . KubeAPI . AuditLog = & v3 . AuditLog { Enabled : true }
}
}
2019-10-30 20:04:16 +00:00
if c . Services . KubeAPI . AuditLog != nil &&
c . Services . KubeAPI . AuditLog . Enabled {
if c . Services . KubeAPI . AuditLog . Configuration == nil {
alc := newDefaultAuditLogConfig ( )
c . Services . KubeAPI . AuditLog . Configuration = alc
} else {
if c . Services . KubeAPI . AuditLog . Configuration . Policy == nil {
c . Services . KubeAPI . AuditLog . Configuration . Policy = newDefaultAuditPolicy ( )
}
}
}
}
func newDefaultAuditPolicy ( ) * auditv1 . Policy {
p := & auditv1 . Policy {
TypeMeta : v1 . TypeMeta {
Kind : "Policy" ,
APIVersion : auditv1 . SchemeGroupVersion . String ( ) ,
} ,
Rules : [ ] auditv1 . PolicyRule {
{
Level : "Metadata" ,
} ,
} ,
OmitStages : nil ,
}
return p
}
func newDefaultAuditLogConfig ( ) * v3 . AuditLogConfig {
p := newDefaultAuditPolicy ( )
c := & v3 . AuditLogConfig {
2019-11-21 21:56:48 +00:00
MaxAge : 30 ,
MaxBackup : 10 ,
2019-10-30 20:04:16 +00:00
MaxSize : 100 ,
Path : DefaultKubeAPIArgAuditLogPathValue ,
Format : "json" ,
Policy : p ,
}
return c
}
2020-01-23 22:52:30 +00:00
func getEventRateLimitPluginFromConfig ( c * v3 . Configuration ) ( apiserverv1alpha1 . AdmissionPluginConfiguration , error ) {
2019-10-30 20:04:16 +00:00
plugin := apiserverv1alpha1 . AdmissionPluginConfiguration {
Name : EventRateLimitPluginName ,
Configuration : & runtime . Unknown {
ContentType : "application/json" ,
} ,
}
cBytes , err := json . Marshal ( c )
if err != nil {
return plugin , fmt . Errorf ( "error marshalling eventratelimit config: %v" , err )
}
plugin . Configuration . Raw = cBytes
return plugin , nil
}
2020-01-23 22:52:30 +00:00
func newDefaultEventRateLimitConfig ( ) * v3 . Configuration {
return & v3 . Configuration {
2019-10-30 20:04:16 +00:00
TypeMeta : v1 . TypeMeta {
Kind : "Configuration" ,
2020-01-31 03:14:34 +00:00
APIVersion : "eventratelimit.admission.k8s.io/v1alpha1" ,
2019-10-30 20:04:16 +00:00
} ,
2020-01-23 22:52:30 +00:00
Limits : [ ] v3 . Limit {
2019-10-30 20:04:16 +00:00
{
2020-01-23 22:52:30 +00:00
Type : v3 . ServerLimitType ,
2019-10-30 20:04:16 +00:00
QPS : 5000 ,
Burst : 20000 ,
} ,
} ,
}
}
func newDefaultEventRateLimitPlugin ( ) ( apiserverv1alpha1 . AdmissionPluginConfiguration , error ) {
plugin := apiserverv1alpha1 . AdmissionPluginConfiguration {
Name : EventRateLimitPluginName ,
Configuration : & runtime . Unknown {
ContentType : "application/json" ,
} ,
}
c := newDefaultEventRateLimitConfig ( )
cBytes , err := json . Marshal ( c )
if err != nil {
return plugin , fmt . Errorf ( "error marshalling eventratelimit config: %v" , err )
}
plugin . Configuration . Raw = cBytes
return plugin , nil
}
func newDefaultAdmissionConfiguration ( ) ( * apiserverv1alpha1 . AdmissionConfiguration , error ) {
var admissionConfiguration * apiserverv1alpha1 . AdmissionConfiguration
admissionConfiguration = & apiserverv1alpha1 . AdmissionConfiguration {
TypeMeta : v1 . TypeMeta {
Kind : "AdmissionConfiguration" ,
APIVersion : apiserverv1alpha1 . SchemeGroupVersion . String ( ) ,
} ,
}
return admissionConfiguration , nil
2018-02-01 21:28:31 +00:00
}
2019-01-24 19:20:22 +00:00
func ( c * Cluster ) setClusterImageDefaults ( ) error {
2018-08-31 21:41:24 +00:00
var privRegURL string
2019-01-24 19:20:22 +00:00
2019-05-28 18:51:53 +00:00
imageDefaults , ok := metadata . K8sVersionToRKESystemImages [ c . Version ]
2019-03-01 18:09:45 +00:00
if ! ok {
return nil
2018-02-26 16:27:32 +00:00
}
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 ) ,
2018-07-22 09:36:21 +00:00
& c . SystemImages . CoreDNS : d ( imageDefaults . CoreDNS , privRegURL ) ,
& c . SystemImages . CoreDNSAutoscaler : d ( imageDefaults . CoreDNSAutoscaler , privRegURL ) ,
2018-08-31 21:41:24 +00:00
& 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 ) ,
2019-07-11 20:59:03 +00:00
& c . SystemImages . CalicoControllers : d ( imageDefaults . CalicoControllers , privRegURL ) ,
2019-08-23 16:43:56 +00:00
& c . SystemImages . CalicoFlexVol : d ( imageDefaults . CalicoFlexVol , privRegURL ) ,
2018-08-31 21:41:24 +00:00
& c . SystemImages . CanalNode : d ( imageDefaults . CanalNode , privRegURL ) ,
& c . SystemImages . CanalCNI : d ( imageDefaults . CanalCNI , privRegURL ) ,
& c . SystemImages . CanalFlannel : d ( imageDefaults . CanalFlannel , privRegURL ) ,
2019-08-23 16:43:56 +00:00
& c . SystemImages . CanalFlexVol : d ( imageDefaults . CanalFlexVol , privRegURL ) ,
2018-08-31 21:41:24 +00:00
& 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 ) ,
2020-03-03 11:05:59 +00:00
& c . SystemImages . Nodelocal : d ( imageDefaults . Nodelocal , privRegURL ) ,
2019-07-05 04:23:48 +00:00
// this's a stopgap, we could drop this after https://github.com/kubernetes/kubernetes/pull/75618 merged
& c . SystemImages . WindowsPodInfraContainer : d ( imageDefaults . WindowsPodInfraContainer , 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 )
}
2019-01-24 19:20:22 +00:00
return nil
2018-02-01 21:28:31 +00:00
}
2018-02-05 15:50:39 +00:00
2019-06-12 21:09:29 +00:00
func ( c * Cluster ) setClusterDNSDefaults ( ) error {
if c . DNS != nil && len ( c . DNS . Provider ) != 0 {
return nil
}
clusterSemVer , err := util . StrToSemVer ( c . Version )
if err != nil {
return err
}
logrus . Debugf ( "No DNS provider configured, setting default based on cluster version [%s]" , clusterSemVer )
K8sVersionCoreDNSSemVer , err := util . StrToSemVer ( K8sVersionCoreDNS )
if err != nil {
return err
}
// Default DNS provider for cluster version 1.14.0 and higher is coredns
ClusterDNSProvider := CoreDNSProvider
// If cluster version is less than 1.14.0 (K8sVersionCoreDNSSemVer), use kube-dns
if clusterSemVer . LessThan ( * K8sVersionCoreDNSSemVer ) {
logrus . Debugf ( "Cluster version [%s] is less than version [%s], using DNS provider [%s]" , clusterSemVer , K8sVersionCoreDNSSemVer , DefaultDNSProvider )
ClusterDNSProvider = DefaultDNSProvider
}
2020-03-13 06:56:11 +00:00
if c . DNS == nil {
c . DNS = & v3 . DNSConfig { }
}
2019-06-12 21:09:29 +00:00
c . DNS . Provider = ClusterDNSProvider
logrus . Debugf ( "DNS provider set to [%s]" , ClusterDNSProvider )
return nil
}
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 {
2020-02-21 18:52:18 +00:00
CalicoCloudProvider : DefaultNetworkCloudProvider ,
CalicoFlexVolPluginDirectory : DefaultCalicoFlexVolPluginDirectory ,
2018-02-05 15:50:39 +00:00
}
2018-05-30 08:30:12 +00:00
case FlannelNetworkPlugin :
networkPluginConfigDefaultsMap = map [ string ] string {
2019-04-13 14:43:34 +00:00
FlannelBackendType : DefaultFlannelBackendVxLan ,
FlannelBackendPort : DefaultFlannelBackendVxLanPort ,
FlannelBackendVxLanNetworkIdentify : DefaultFlannelBackendVxLanVNI ,
2018-05-30 08:30:12 +00:00
}
case CanalNetworkPlugin :
networkPluginConfigDefaultsMap = map [ string ] string {
2019-04-13 14:43:34 +00:00
CanalFlannelBackendType : DefaultFlannelBackendVxLan ,
CanalFlannelBackendPort : DefaultFlannelBackendVxLanPort ,
CanalFlannelBackendVxLanNetworkIdentify : DefaultFlannelBackendVxLanVNI ,
2020-02-21 18:52:18 +00:00
CanalFlexVolPluginDirectory : DefaultCanalFlexVolPluginDirectory ,
2018-05-30 08:30:12 +00:00
}
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-07-18 04:29:48 +00:00
if c . Network . WeaveNetworkProvider != nil {
networkPluginConfigDefaultsMap [ WeavePassword ] = c . Network . WeaveNetworkProvider . Password
}
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
2018-12-28 16:41:37 +00:00
func ( c * Cluster ) setClusterAuthnDefaults ( ) {
setDefaultIfEmpty ( & c . Authentication . Strategy , DefaultAuthStrategy )
for _ , strategy := range strings . Split ( c . Authentication . Strategy , "|" ) {
strategy = strings . ToLower ( strings . TrimSpace ( strategy ) )
c . AuthnStrategies [ strategy ] = true
}
if c . AuthnStrategies [ AuthnWebhookProvider ] && c . Authentication . Webhook == nil {
c . Authentication . Webhook = & v3 . AuthWebhookConfig { }
}
if c . Authentication . Webhook != nil {
webhookConfigDefaultsMap := map [ * string ] string {
& c . Authentication . Webhook . ConfigFile : DefaultAuthnWebhookFile ,
& c . Authentication . Webhook . CacheTimeout : DefaultAuthnCacheTimeout ,
}
for k , v := range webhookConfigDefaultsMap {
setDefaultIfEmpty ( 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 )
}
2018-11-07 23:54:08 +00:00
func ( c * Cluster ) setCloudProvider ( ) error {
p , err := cloudprovider . InitCloudProvider ( c . CloudProvider )
if err != nil {
return fmt . Errorf ( "Failed to initialize cloud provider: %v" , err )
}
if p != nil {
c . CloudConfigFile , err = p . GenerateCloudConfigFile ( )
if err != nil {
return fmt . Errorf ( "Failed to parse cloud config file: %v" , err )
}
c . CloudProvider . Name = p . GetName ( )
if c . CloudProvider . Name == "" {
return fmt . Errorf ( "Name of the cloud provider is not defined for custom provider" )
}
}
return nil
}
2018-11-12 23:24:59 +00:00
func GetExternalFlags ( local , updateOnly , disablePortCheck bool , configDir , clusterFilePath string ) ExternalFlags {
2018-11-07 23:54:08 +00:00
return ExternalFlags {
Local : local ,
UpdateOnly : updateOnly ,
DisablePortCheck : disablePortCheck ,
ConfigDir : configDir ,
ClusterFilePath : clusterFilePath ,
}
}
2019-11-20 00:42:59 +00:00
func ( c * Cluster ) setAddonsDefaults ( ) {
c . Ingress . UpdateStrategy = setDaemonsetAddonDefaults ( c . Ingress . UpdateStrategy )
c . Network . UpdateStrategy = setDaemonsetAddonDefaults ( c . Network . UpdateStrategy )
2020-03-07 20:11:41 +00:00
c . DNS . UpdateStrategy = setDNSDeploymentAddonDefaults ( c . DNS . UpdateStrategy , c . DNS . Provider )
2019-11-20 00:42:59 +00:00
if c . DNS . LinearAutoscalerParams == nil {
c . DNS . LinearAutoscalerParams = & DefaultClusterProportionalAutoscalerLinearParams
}
c . Monitoring . UpdateStrategy = setDeploymentAddonDefaults ( c . Monitoring . UpdateStrategy )
if c . Monitoring . Replicas == nil {
c . Monitoring . Replicas = & DefaultMonitoringAddonReplicas
}
}
2020-03-26 21:39:24 +00:00
func setDaemonsetAddonDefaults ( updateStrategy * v3 . DaemonSetUpdateStrategy ) * v3 . DaemonSetUpdateStrategy {
if updateStrategy != nil && updateStrategy . Strategy != appsv1 . RollingUpdateDaemonSetStrategyType {
2019-11-20 00:42:59 +00:00
return updateStrategy
}
if updateStrategy == nil || updateStrategy . RollingUpdate == nil || updateStrategy . RollingUpdate . MaxUnavailable == nil {
return & DefaultDaemonSetUpdateStrategy
}
return updateStrategy
}
2020-03-26 21:39:24 +00:00
func setDeploymentAddonDefaults ( updateStrategy * v3 . DeploymentStrategy ) * v3 . DeploymentStrategy {
if updateStrategy != nil && updateStrategy . Strategy != appsv1 . RollingUpdateDeploymentStrategyType {
2019-11-20 00:42:59 +00:00
return updateStrategy
}
if updateStrategy == nil || updateStrategy . RollingUpdate == nil {
return & DefaultDeploymentUpdateStrategy
}
if updateStrategy . RollingUpdate . MaxUnavailable == nil {
updateStrategy . RollingUpdate . MaxUnavailable = & DefaultDeploymentUpdateStrategyParams
}
if updateStrategy . RollingUpdate . MaxSurge == nil {
updateStrategy . RollingUpdate . MaxSurge = & DefaultDeploymentUpdateStrategyParams
}
return updateStrategy
}
2020-03-07 20:11:41 +00:00
2020-03-26 21:39:24 +00:00
func setDNSDeploymentAddonDefaults ( updateStrategy * v3 . DeploymentStrategy , dnsProvider string ) * v3 . DeploymentStrategy {
2020-03-07 20:11:41 +00:00
var (
coreDNSMaxUnavailable , coreDNSMaxSurge = intstr . FromInt ( 1 ) , intstr . FromInt ( 0 )
kubeDNSMaxSurge , kubeDNSMaxUnavailable = intstr . FromString ( "10%" ) , intstr . FromInt ( 0 )
)
2020-03-26 21:39:24 +00:00
if updateStrategy != nil && updateStrategy . Strategy != appsv1 . RollingUpdateDeploymentStrategyType {
2020-03-07 20:11:41 +00:00
return updateStrategy
}
switch dnsProvider {
case CoreDNSProvider :
if updateStrategy == nil || updateStrategy . RollingUpdate == nil {
2020-03-26 21:39:24 +00:00
return & v3 . DeploymentStrategy {
Strategy : appsv1 . RollingUpdateDeploymentStrategyType ,
2020-03-07 20:11:41 +00:00
RollingUpdate : & appsv1 . RollingUpdateDeployment {
MaxUnavailable : & coreDNSMaxUnavailable ,
MaxSurge : & coreDNSMaxSurge ,
} ,
}
}
if updateStrategy . RollingUpdate . MaxUnavailable == nil {
updateStrategy . RollingUpdate . MaxUnavailable = & coreDNSMaxUnavailable
}
case KubeDNSProvider :
if updateStrategy == nil || updateStrategy . RollingUpdate == nil {
2020-03-26 21:39:24 +00:00
return & v3 . DeploymentStrategy {
Strategy : appsv1 . RollingUpdateDeploymentStrategyType ,
2020-03-07 20:11:41 +00:00
RollingUpdate : & appsv1 . RollingUpdateDeployment {
MaxUnavailable : & kubeDNSMaxUnavailable ,
MaxSurge : & kubeDNSMaxSurge ,
} ,
}
}
if updateStrategy . RollingUpdate . MaxSurge == nil {
updateStrategy . RollingUpdate . MaxSurge = & kubeDNSMaxSurge
}
}
return updateStrategy
}
2020-03-13 06:55:41 +00:00
func checkVersionNeedsKubeAPIAuditLog ( k8sVersion string ) ( bool , error ) {
toMatch , err := semver . Make ( k8sVersion [ 1 : ] )
if err != nil {
return false , fmt . Errorf ( "Cluster version [%s] can not be parsed as semver" , k8sVersion [ 1 : ] )
}
logrus . Debugf ( "Checking if cluster version [%s] needs to have kube-api audit log enabled" , k8sVersion [ 1 : ] )
// kube-api audit log needs to be enabled for k8s 1.15.11 and up, k8s 1.16.8 and up, k8s 1.17.4 and up
clusterKubeAPIAuditLogRange , err := semver . ParseRange ( ">=1.15.11-rancher0 <=1.15.99 || >=1.16.8-rancher0 <=1.16.99 || >=1.17.4-rancher0" )
if err != nil {
return false , errors . New ( "Failed to parse semver range for checking to enable kube-api audit log" )
}
if clusterKubeAPIAuditLogRange ( toMatch ) {
logrus . Debugf ( "Cluster version [%s] needs to have kube-api audit log enabled" , k8sVersion [ 1 : ] )
return true , nil
}
logrus . Debugf ( "Cluster version [%s] does not need to have kube-api audit log enabled" , k8sVersion [ 1 : ] )
return false , nil
}