2018-02-13 00:47:56 +00:00
package cluster
import (
"context"
2018-06-13 02:10:48 +00:00
"crypto/md5"
2018-02-13 00:47:56 +00:00
"fmt"
2018-04-11 22:54:47 +00:00
"path"
2018-02-13 00:47:56 +00:00
"strconv"
2018-02-14 20:58:35 +00:00
"strings"
2018-02-13 00:47:56 +00:00
2018-03-29 20:58:46 +00:00
b64 "encoding/base64"
2018-04-18 03:16:57 +00:00
ref "github.com/docker/distribution/reference"
2018-04-11 22:54:47 +00:00
"github.com/docker/docker/api/types"
2018-06-06 17:11:47 +00:00
"github.com/rancher/rke/cloudprovider/aws"
2018-04-03 20:18:51 +00:00
"github.com/rancher/rke/docker"
2018-02-13 00:47:56 +00:00
"github.com/rancher/rke/hosts"
2018-04-03 19:27:04 +00:00
"github.com/rancher/rke/k8s"
2018-02-13 00:47:56 +00:00
"github.com/rancher/rke/pki"
"github.com/rancher/rke/services"
2018-10-04 08:54:04 +00:00
"github.com/rancher/rke/util"
2018-02-13 00:47:56 +00:00
"github.com/rancher/types/apis/management.cattle.io/v3"
2018-08-09 15:03:28 +00:00
"github.com/sirupsen/logrus"
2018-02-13 00:47:56 +00:00
)
2018-02-14 20:58:35 +00:00
const (
2018-05-03 20:07:41 +00:00
EtcdPathPrefix = "/registry"
ContainerNameLabel = "io.rancher.rke.container.name"
2018-06-13 02:10:48 +00:00
CloudConfigSumEnv = "RKE_CLOUD_CONFIG_CHECKSUM"
2018-08-03 22:01:58 +00:00
2018-08-05 01:10:48 +00:00
DefaultToolsEntrypoint = "/opt/rke-tools/entrypoint.sh"
DefaultToolsEntrypointVersion = "0.1.13"
LegacyToolsEntrypoint = "/opt/rke/entrypoint.sh"
2018-08-29 00:23:41 +00:00
KubeletDockerConfigEnv = "RKE_KUBELET_DOCKER_CONFIG"
KubeletDockerConfigFileEnv = "RKE_KUBELET_DOCKER_FILE"
KubeletDockerConfigPath = "/var/lib/kubelet/config.json"
2018-02-14 20:58:35 +00:00
)
2018-08-29 21:42:12 +00:00
var admissionControlOptionNames = [ ] string { "enable-admission-plugins" , "admission-control" }
2018-04-11 22:54:47 +00:00
func GeneratePlan ( ctx context . Context , rkeConfig * v3 . RancherKubernetesEngineConfig , hostsInfoMap map [ string ] types . Info ) ( v3 . RKEPlan , error ) {
2018-02-13 00:47:56 +00:00
clusterPlan := v3 . RKEPlan { }
2018-11-07 23:54:08 +00:00
myCluster , err := InitClusterObject ( ctx , rkeConfig , ExternalFlags { } )
2018-04-19 15:54:15 +00:00
if err != nil {
return clusterPlan , err
}
2018-02-13 00:47:56 +00:00
// rkeConfig.Nodes are already unique. But they don't have role flags. So I will use the parsed cluster.Hosts to make use of the role flags.
uniqHosts := hosts . GetUniqueHostList ( myCluster . EtcdHosts , myCluster . ControlPlaneHosts , myCluster . WorkerHosts )
for _ , host := range uniqHosts {
2018-04-25 22:02:40 +00:00
host . DockerInfo = hostsInfoMap [ host . Address ]
2018-04-11 22:54:47 +00:00
clusterPlan . Nodes = append ( clusterPlan . Nodes , BuildRKEConfigNodePlan ( ctx , myCluster , host , hostsInfoMap [ host . Address ] ) )
2018-02-13 00:47:56 +00:00
}
return clusterPlan , nil
}
2018-04-11 22:54:47 +00:00
func BuildRKEConfigNodePlan ( ctx context . Context , myCluster * Cluster , host * hosts . Host , hostDockerInfo types . Info ) v3 . RKEConfigNodePlan {
2018-06-25 22:50:45 +00:00
prefixPath := hosts . GetPrefixPath ( hostDockerInfo . OperatingSystem , myCluster . PrefixPath )
2018-02-24 13:08:46 +00:00
processes := map [ string ] v3 . Process { }
2018-02-13 00:47:56 +00:00
portChecks := [ ] v3 . PortCheck { }
// Everybody gets a sidecar and a kubelet..
2018-02-24 13:08:46 +00:00
processes [ services . SidekickContainerName ] = myCluster . BuildSidecarProcess ( )
2018-04-11 22:54:47 +00:00
processes [ services . KubeletContainerName ] = myCluster . BuildKubeletProcess ( host , prefixPath )
2018-06-19 18:33:18 +00:00
processes [ services . KubeproxyContainerName ] = myCluster . BuildKubeProxyProcess ( host , prefixPath )
2018-02-13 00:47:56 +00:00
portChecks = append ( portChecks , BuildPortChecksFromPortList ( host , WorkerPortList , ProtocolTCP ) ... )
// Do we need an nginxProxy for this one ?
2018-04-14 17:18:51 +00:00
if ! host . IsControl {
2018-02-24 13:08:46 +00:00
processes [ services . NginxProxyContainerName ] = myCluster . BuildProxyProcess ( )
2018-02-13 00:47:56 +00:00
}
if host . IsControl {
2018-04-11 22:54:47 +00:00
processes [ services . KubeAPIContainerName ] = myCluster . BuildKubeAPIProcess ( prefixPath )
processes [ services . KubeControllerContainerName ] = myCluster . BuildKubeControllerProcess ( prefixPath )
processes [ services . SchedulerContainerName ] = myCluster . BuildSchedulerProcess ( prefixPath )
2018-02-13 00:47:56 +00:00
portChecks = append ( portChecks , BuildPortChecksFromPortList ( host , ControlPlanePortList , ProtocolTCP ) ... )
}
if host . IsEtcd {
2018-04-14 18:38:07 +00:00
processes [ services . EtcdContainerName ] = myCluster . BuildEtcdProcess ( host , myCluster . EtcdReadyHosts , prefixPath )
2018-02-13 00:47:56 +00:00
portChecks = append ( portChecks , BuildPortChecksFromPortList ( host , EtcdPortList , ProtocolTCP ) ... )
}
2018-03-29 20:58:46 +00:00
cloudConfig := v3 . File {
2018-12-28 16:41:37 +00:00
Name : cloudConfigFileName ,
2018-03-29 20:58:46 +00:00
Contents : b64 . StdEncoding . EncodeToString ( [ ] byte ( myCluster . CloudConfigFile ) ) ,
}
2018-02-13 00:47:56 +00:00
return v3 . RKEConfigNodePlan {
Address : host . Address ,
Processes : processes ,
PortChecks : portChecks ,
2018-03-29 20:58:46 +00:00
Files : [ ] v3 . File { cloudConfig } ,
2018-04-03 19:27:04 +00:00
Annotations : map [ string ] string {
k8s . ExternalAddressAnnotation : host . Address ,
k8s . InternalAddressAnnotation : host . InternalAddress ,
} ,
2018-04-04 10:02:11 +00:00
Labels : host . ToAddLabels ,
2018-02-13 00:47:56 +00:00
}
}
2018-04-11 22:54:47 +00:00
func ( c * Cluster ) BuildKubeAPIProcess ( prefixPath string ) v3 . Process {
2018-02-14 20:58:35 +00:00
// check if external etcd is used
etcdConnectionString := services . GetEtcdConnString ( c . EtcdHosts )
etcdPathPrefix := EtcdPathPrefix
etcdClientCert := pki . GetCertPath ( pki . KubeNodeCertName )
etcdClientKey := pki . GetKeyPath ( pki . KubeNodeCertName )
etcdCAClientCert := pki . GetCertPath ( pki . CACertName )
2018-06-12 21:02:05 +00:00
2018-02-14 20:58:35 +00:00
if len ( c . Services . Etcd . ExternalURLs ) > 0 {
etcdConnectionString = strings . Join ( c . Services . Etcd . ExternalURLs , "," )
etcdPathPrefix = c . Services . Etcd . Path
etcdClientCert = pki . GetCertPath ( pki . EtcdClientCertName )
etcdClientKey = pki . GetKeyPath ( pki . EtcdClientCertName )
etcdCAClientCert = pki . GetCertPath ( pki . EtcdClientCACertName )
}
2018-02-13 00:47:56 +00:00
Command := [ ] string {
2018-08-03 22:01:58 +00:00
c . getRKEToolsEntryPoint ( ) ,
2018-02-13 00:47:56 +00:00
"kube-apiserver" ,
}
2019-01-07 19:52:57 +00:00
baseEnabledAdmissionPlugins := [ ] string {
"DefaultStorageClass" ,
"DefaultTolerationSeconds" ,
"LimitRanger" ,
"NamespaceLifecycle" ,
"NodeRestriction" ,
"PersistentVolumeLabel" ,
"ResourceQuota" ,
"ServiceAccount" ,
}
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
2018-07-17 18:19:08 +00:00
"allow-privileged" : "true" ,
2019-01-07 19:52:57 +00:00
"anonymous-auth" : "false" ,
"bind-address" : "0.0.0.0" ,
2018-07-17 18:19:08 +00:00
"client-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
2019-01-07 19:52:57 +00:00
"cloud-provider" : c . CloudProvider . Name ,
2018-07-17 18:19:08 +00:00
"etcd-cafile" : etcdCAClientCert ,
"etcd-certfile" : etcdClientCert ,
"etcd-keyfile" : etcdClientKey ,
"etcd-prefix" : etcdPathPrefix ,
2019-01-07 19:52:57 +00:00
"etcd-servers" : etcdConnectionString ,
"insecure-port" : "0" ,
"kubelet-client-certificate" : pki . GetCertPath ( pki . KubeAPICertName ) ,
"kubelet-client-key" : pki . GetKeyPath ( pki . KubeAPICertName ) ,
"kubelet-preferred-address-types" : "InternalIP,ExternalIP,Hostname" ,
"profiling" : "false" ,
2018-07-17 18:19:08 +00:00
"proxy-client-cert-file" : pki . GetCertPath ( pki . APIProxyClientCertName ) ,
2019-01-07 19:52:57 +00:00
"proxy-client-key-file" : pki . GetKeyPath ( pki . APIProxyClientCertName ) ,
"requestheader-allowed-names" : pki . APIProxyClientCertName ,
"requestheader-client-ca-file" : pki . GetCertPath ( pki . RequestHeaderCACertName ) ,
2018-07-17 18:19:08 +00:00
"requestheader-extra-headers-prefix" : "X-Remote-Extra-" ,
"requestheader-group-headers" : "X-Remote-Group" ,
"requestheader-username-headers" : "X-Remote-User" ,
2019-01-07 19:52:57 +00:00
"repair-malformed-updates" : "false" ,
"secure-port" : "6443" ,
"service-account-key-file" : pki . GetKeyPath ( pki . ServiceAccountTokenKeyName ) ,
"service-account-lookup" : "true" ,
"service-cluster-ip-range" : c . Services . KubeAPI . ServiceClusterIPRange ,
"service-node-port-range" : c . Services . KubeAPI . ServiceNodePortRange ,
"storage-backend" : "etcd3" ,
"tls-cert-file" : pki . GetCertPath ( pki . KubeAPICertName ) ,
"tls-private-key-file" : pki . GetKeyPath ( pki . KubeAPICertName ) ,
2018-03-14 23:37:04 +00:00
}
2018-06-06 17:11:47 +00:00
if len ( c . CloudProvider . Name ) > 0 && c . CloudProvider . Name != aws . AWSCloudProviderName {
2018-12-28 16:41:37 +00:00
CommandArgs [ "cloud-config" ] = cloudConfigFileName
}
if c . Authentication . Webhook != nil {
CommandArgs [ "authentication-token-webhook-config-file" ] = authnWebhookFileName
CommandArgs [ "authentication-token-webhook-cache-ttl" ] = c . Authentication . Webhook . CacheTimeout
2018-03-28 19:46:28 +00:00
}
2018-06-13 02:10:48 +00:00
if len ( c . CloudProvider . Name ) > 0 {
c . Services . KubeAPI . ExtraEnv = append (
c . Services . KubeAPI . ExtraEnv ,
2018-12-06 23:35:11 +00:00
fmt . Sprintf ( "%s=%s" , CloudConfigSumEnv , getCloudConfigChecksum ( c . CloudConfigFile ) ) )
2018-06-13 02:10:48 +00:00
}
2018-04-11 17:28:26 +00:00
// check if our version has specific options for this component
2018-04-18 03:16:57 +00:00
serviceOptions := c . GetKubernetesServicesOptions ( )
2018-04-17 23:08:21 +00:00
if serviceOptions . KubeAPI != nil {
2018-04-11 17:28:26 +00:00
for k , v := range serviceOptions . KubeAPI {
2018-10-01 21:12:53 +00:00
// if the value is empty, we remove that option
if len ( v ) == 0 {
delete ( CommandArgs , k )
continue
}
2018-04-11 17:28:26 +00:00
CommandArgs [ k ] = v
}
}
2018-06-12 21:02:05 +00:00
// check api server count for k8s v1.8
if getTagMajorVersion ( c . Version ) == "v1.8" {
CommandArgs [ "apiserver-count" ] = strconv . Itoa ( len ( c . ControlPlaneHosts ) )
}
2018-04-11 17:28:26 +00:00
2018-02-13 00:47:56 +00:00
if c . Authorization . Mode == services . RBACAuthorizationMode {
2018-03-14 23:37:04 +00:00
CommandArgs [ "authorization-mode" ] = "Node,RBAC"
2018-02-13 00:47:56 +00:00
}
2019-01-07 19:52:57 +00:00
// PodSecurityPolicy
if c . Services . KubeAPI . PodSecurityPolicy {
CommandArgs [ "runtime-config" ] = "extensions/v1beta1/podsecuritypolicy=true"
baseEnabledAdmissionPlugins = append ( baseEnabledAdmissionPlugins , "PodSecurityPolicy" )
}
2019-01-07 20:51:41 +00:00
// AlwaysPullImages
if c . Services . KubeAPI . AlwaysPullImages {
baseEnabledAdmissionPlugins = append ( baseEnabledAdmissionPlugins , "AlwaysPullImages" )
}
2019-01-07 19:52:57 +00:00
// Admission control plugins
// Resolution order:
// k8s_defaults.go K8sVersionServiceOptions
// enabledAdmissionPlugins
// cluster.yml extra_args overwrites it all
for _ , optionName := range admissionControlOptionNames {
if _ , ok := CommandArgs [ optionName ] ; ok {
enabledAdmissionPlugins := strings . Split ( CommandArgs [ optionName ] , "," )
enabledAdmissionPlugins = append ( enabledAdmissionPlugins , baseEnabledAdmissionPlugins ... )
// Join unique slice as arg
CommandArgs [ optionName ] = strings . Join ( util . UniqueStringSlice ( enabledAdmissionPlugins ) , "," )
break
}
}
2018-02-13 00:47:56 +00:00
if c . Services . KubeAPI . PodSecurityPolicy {
2018-03-14 23:37:04 +00:00
CommandArgs [ "runtime-config" ] = "extensions/v1beta1/podsecuritypolicy=true"
2018-08-29 21:42:12 +00:00
for _ , optionName := range admissionControlOptionNames {
if _ , ok := CommandArgs [ optionName ] ; ok {
CommandArgs [ optionName ] = CommandArgs [ optionName ] + ",PodSecurityPolicy"
break
}
}
2018-02-13 00:47:56 +00:00
}
VolumesFrom := [ ] string {
services . SidekickContainerName ,
}
Binds := [ ] string {
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-02-13 00:47:56 +00:00
}
2018-03-14 23:37:04 +00:00
// Override args if they exist, add additional args
2018-02-13 00:47:56 +00:00
for arg , value := range c . Services . KubeAPI . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . KubeAPI . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
Command = append ( Command , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . KubeAPI . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
URL : services . GetHealthCheckURL ( true , services . KubeAPIPort ) ,
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . KubeAPI . Image , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . KubeAPIContainerName ,
Command : Command ,
VolumesFrom : VolumesFrom ,
2018-07-19 20:41:56 +00:00
Binds : getUniqStringList ( Binds ) ,
2018-06-13 02:10:48 +00:00
Env : getUniqStringList ( c . Services . KubeAPI . ExtraEnv ) ,
2018-04-03 20:18:51 +00:00
NetworkMode : "host" ,
RestartPolicy : "always" ,
Image : c . Services . KubeAPI . Image ,
HealthCheck : healthCheck ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . KubeAPIContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
2018-04-11 22:54:47 +00:00
func ( c * Cluster ) BuildKubeControllerProcess ( prefixPath string ) v3 . Process {
2018-03-14 23:37:04 +00:00
Command := [ ] string {
2018-08-03 22:01:58 +00:00
c . getRKEToolsEntryPoint ( ) ,
2018-02-13 00:47:56 +00:00
"kube-controller-manager" ,
}
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
2019-01-07 19:52:57 +00:00
"address" : "127.0.0.1" ,
2018-11-07 23:54:08 +00:00
"allow-untagged-cloud" : "true" ,
2019-01-07 19:52:57 +00:00
"allocate-node-cidrs" : "true" ,
"cloud-provider" : c . CloudProvider . Name ,
"cluster-cidr" : c . ClusterCIDR ,
2018-11-07 23:54:08 +00:00
"configure-cloud-routes" : "false" ,
"enable-hostpath-provisioner" : "false" ,
2019-01-07 19:52:57 +00:00
"kubeconfig" : pki . GetConfigPath ( pki . KubeControllerCertName ) ,
"leader-elect" : "true" ,
2018-11-07 23:54:08 +00:00
"node-monitor-grace-period" : "40s" ,
"pod-eviction-timeout" : "5m0s" ,
2019-01-07 19:52:57 +00:00
"profiling" : "false" ,
2018-03-14 23:37:04 +00:00
"root-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
2019-01-07 19:52:57 +00:00
"service-account-private-key-file" : pki . GetKeyPath ( pki . ServiceAccountTokenKeyName ) ,
"service-cluster-ip-range" : c . Services . KubeController . ServiceClusterIPRange ,
"terminated-pod-gc-threshold" : "1000" ,
"v" : "2" ,
}
// Best security practice is to listen on localhost, but DinD uses private container network instead of Host.
if c . DinD {
CommandArgs [ "address" ] = "0.0.0.0"
2018-03-14 23:37:04 +00:00
}
2018-06-06 17:11:47 +00:00
if len ( c . CloudProvider . Name ) > 0 && c . CloudProvider . Name != aws . AWSCloudProviderName {
2018-12-28 16:41:37 +00:00
CommandArgs [ "cloud-config" ] = cloudConfigFileName
2018-03-28 19:46:28 +00:00
}
2018-06-13 02:10:48 +00:00
if len ( c . CloudProvider . Name ) > 0 {
c . Services . KubeController . ExtraEnv = append (
c . Services . KubeController . ExtraEnv ,
2018-12-06 23:35:11 +00:00
fmt . Sprintf ( "%s=%s" , CloudConfigSumEnv , getCloudConfigChecksum ( c . CloudConfigFile ) ) )
2018-06-13 02:10:48 +00:00
}
2018-04-11 17:28:26 +00:00
// check if our version has specific options for this component
2018-04-18 03:16:57 +00:00
serviceOptions := c . GetKubernetesServicesOptions ( )
2018-04-17 23:08:21 +00:00
if serviceOptions . KubeController != nil {
2018-04-11 17:28:26 +00:00
for k , v := range serviceOptions . KubeController {
2018-10-01 21:12:53 +00:00
// if the value is empty, we remove that option
if len ( v ) == 0 {
delete ( CommandArgs , k )
continue
}
2018-04-11 17:28:26 +00:00
CommandArgs [ k ] = v
}
}
2018-02-13 00:47:56 +00:00
args := [ ] string { }
if c . Authorization . Mode == services . RBACAuthorizationMode {
args = append ( args , "--use-service-account-credentials=true" )
}
VolumesFrom := [ ] string {
services . SidekickContainerName ,
}
Binds := [ ] string {
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-02-13 00:47:56 +00:00
}
for arg , value := range c . Services . KubeController . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . KubeController . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
Command = append ( Command , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . KubeController . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
URL : services . GetHealthCheckURL ( false , services . KubeControllerPort ) ,
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . KubeController . Image , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . KubeControllerContainerName ,
Command : Command ,
Args : args ,
VolumesFrom : VolumesFrom ,
2018-07-19 20:41:56 +00:00
Binds : getUniqStringList ( Binds ) ,
2018-06-13 02:10:48 +00:00
Env : getUniqStringList ( c . Services . KubeController . ExtraEnv ) ,
2018-04-03 20:18:51 +00:00
NetworkMode : "host" ,
RestartPolicy : "always" ,
Image : c . Services . KubeController . Image ,
HealthCheck : healthCheck ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . KubeControllerContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
2018-04-11 22:54:47 +00:00
func ( c * Cluster ) BuildKubeletProcess ( host * hosts . Host , prefixPath string ) v3 . Process {
2018-02-13 00:47:56 +00:00
2018-03-14 23:37:04 +00:00
Command := [ ] string {
2018-08-03 22:01:58 +00:00
c . getRKEToolsEntryPoint ( ) ,
2018-02-13 00:47:56 +00:00
"kubelet" ,
2018-03-14 23:37:04 +00:00
}
CommandArgs := map [ string ] string {
2019-01-07 19:52:57 +00:00
"address" : "0.0.0.0" ,
"allow-privileged" : "true" ,
"anonymous-auth" : "false" ,
"authentication-token-webhook" : "true" ,
"cgroups-per-qos" : "True" ,
"client-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
"cloud-provider" : c . CloudProvider . Name ,
"cluster-dns" : c . ClusterDNSServer ,
"cluster-domain" : c . ClusterDomain ,
"cni-bin-dir" : "/opt/cni/bin" ,
"cni-conf-dir" : "/etc/cni/net.d" ,
"enforce-node-allocatable" : "" ,
"event-qps" : "0" ,
"fail-swap-on" : strconv . FormatBool ( c . Services . Kubelet . FailSwapOn ) ,
"hostname-override" : host . HostnameOverride ,
"kubeconfig" : pki . GetConfigPath ( pki . KubeNodeCertName ) ,
"make-iptables-util-chains" : "true" ,
"network-plugin" : "cni" ,
"pod-infra-container-image" : c . Services . Kubelet . InfraContainerImage ,
"read-only-port" : "0" ,
"resolv-conf" : "/etc/resolv.conf" ,
"root-dir" : path . Join ( prefixPath , "/var/lib/kubelet" ) ,
"streaming-connection-idle-timeout" : "30m" ,
"volume-plugin-dir" : "/var/lib/kubelet/volumeplugins" ,
"v" : "2" ,
2018-02-13 00:47:56 +00:00
}
2018-06-22 06:35:52 +00:00
if host . IsControl && ! host . IsWorker {
CommandArgs [ "register-with-taints" ] = unschedulableControlTaint
}
2018-03-26 22:53:28 +00:00
if host . Address != host . InternalAddress {
CommandArgs [ "node-ip" ] = host . InternalAddress
}
2018-06-06 17:11:47 +00:00
if len ( c . CloudProvider . Name ) > 0 && c . CloudProvider . Name != aws . AWSCloudProviderName {
2018-12-28 16:41:37 +00:00
CommandArgs [ "cloud-config" ] = cloudConfigFileName
2018-03-28 19:46:28 +00:00
}
2018-06-13 02:10:48 +00:00
if len ( c . CloudProvider . Name ) > 0 {
c . Services . Kubelet . ExtraEnv = append (
c . Services . Kubelet . ExtraEnv ,
2018-12-06 23:35:11 +00:00
fmt . Sprintf ( "%s=%s" , CloudConfigSumEnv , getCloudConfigChecksum ( c . CloudConfigFile ) ) )
2018-06-13 02:10:48 +00:00
}
2018-08-29 00:23:41 +00:00
if len ( c . PrivateRegistriesMap ) > 0 {
2019-01-07 19:52:57 +00:00
kubeletDockerConfig , _ := docker . GetKubeletDockerConfig ( c . PrivateRegistriesMap )
2018-08-29 00:23:41 +00:00
c . Services . Kubelet . ExtraEnv = append (
c . Services . Kubelet . ExtraEnv ,
fmt . Sprintf ( "%s=%s" , KubeletDockerConfigEnv ,
2019-01-07 19:52:57 +00:00
b64 . StdEncoding . EncodeToString ( [ ] byte ( kubeletDockerConfig ) ) ) )
2018-08-29 00:23:41 +00:00
c . Services . Kubelet . ExtraEnv = append (
c . Services . Kubelet . ExtraEnv ,
fmt . Sprintf ( "%s=%s" , KubeletDockerConfigFileEnv , path . Join ( prefixPath , KubeletDockerConfigPath ) ) )
}
2018-04-11 17:28:26 +00:00
// check if our version has specific options for this component
2018-04-18 03:16:57 +00:00
serviceOptions := c . GetKubernetesServicesOptions ( )
2018-04-17 23:08:21 +00:00
if serviceOptions . Kubelet != nil {
2018-04-11 17:28:26 +00:00
for k , v := range serviceOptions . Kubelet {
2018-10-01 21:12:53 +00:00
// if the value is empty, we remove that option
if len ( v ) == 0 {
delete ( CommandArgs , k )
continue
}
2018-04-11 17:28:26 +00:00
CommandArgs [ k ] = v
}
}
2018-02-13 00:47:56 +00:00
VolumesFrom := [ ] string {
services . SidekickContainerName ,
}
Binds := [ ] string {
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-04-24 20:43:50 +00:00
"/etc/cni:/etc/cni:rw,z" ,
"/opt/cni:/opt/cni:rw,z" ,
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/var/lib/cni:z" , path . Join ( prefixPath , "/var/lib/cni" ) ) ,
2018-04-26 03:10:53 +00:00
"/var/lib/calico:/var/lib/calico:z" ,
2018-02-13 00:47:56 +00:00
"/etc/resolv.conf:/etc/resolv.conf" ,
2018-03-05 08:42:49 +00:00
"/sys:/sys:rprivate" ,
2018-04-10 16:49:38 +00:00
host . DockerInfo . DockerRootDir + ":" + host . DockerInfo . DockerRootDir + ":rw,rslave,z" ,
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:%s:shared,z" , path . Join ( prefixPath , "/var/lib/kubelet" ) , path . Join ( prefixPath , "/var/lib/kubelet" ) ) ,
2018-04-18 20:53:14 +00:00
"/var/lib/rancher:/var/lib/rancher:shared,z" ,
2018-03-05 08:42:49 +00:00
"/var/run:/var/run:rw,rprivate" ,
"/run:/run:rprivate" ,
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/ceph" , path . Join ( prefixPath , "/etc/ceph" ) ) ,
2018-03-30 18:00:19 +00:00
"/dev:/host/dev:rprivate" ,
2018-06-25 18:40:51 +00:00
"/var/log/containers:/var/log/containers:z" ,
"/var/log/pods:/var/log/pods:z" ,
2018-04-24 08:43:06 +00:00
"/usr:/host/usr:ro" ,
"/etc:/host/etc:ro" ,
2018-02-13 00:47:56 +00:00
}
2018-08-01 18:10:58 +00:00
// Special case to simplify using flex volumes
if path . Join ( prefixPath , "/var/lib/kubelet" ) != "/var/lib/kubelet" {
Binds = append ( Binds , "/var/lib/kubelet/volumeplugins:/var/lib/kubelet/volumeplugins:shared,z" )
}
2018-02-13 00:47:56 +00:00
for arg , value := range c . Services . Kubelet . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . Kubelet . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
Command = append ( Command , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . Kubelet . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
URL : services . GetHealthCheckURL ( true , services . KubeletPort ) ,
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . Kubelet . Image , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . KubeletContainerName ,
Command : Command ,
VolumesFrom : VolumesFrom ,
2018-07-19 20:41:56 +00:00
Binds : getUniqStringList ( Binds ) ,
2018-06-13 02:10:48 +00:00
Env : getUniqStringList ( c . Services . Kubelet . ExtraEnv ) ,
2018-04-03 20:18:51 +00:00
NetworkMode : "host" ,
RestartPolicy : "always" ,
Image : c . Services . Kubelet . Image ,
PidMode : "host" ,
Privileged : true ,
HealthCheck : healthCheck ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . KubeletContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
2018-06-19 18:33:18 +00:00
func ( c * Cluster ) BuildKubeProxyProcess ( host * hosts . Host , prefixPath string ) v3 . Process {
2018-03-14 23:37:04 +00:00
Command := [ ] string {
2018-08-03 22:01:58 +00:00
c . getRKEToolsEntryPoint ( ) ,
2018-02-13 00:47:56 +00:00
"kube-proxy" ,
}
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
2018-11-07 23:54:08 +00:00
"cluster-cidr" : c . ClusterCIDR ,
"v" : "2" ,
2019-01-07 19:52:57 +00:00
"healthz-bind-address" : "127.0.0.1" ,
2018-06-19 18:33:18 +00:00
"hostname-override" : host . HostnameOverride ,
2018-03-14 23:37:04 +00:00
"kubeconfig" : pki . GetConfigPath ( pki . KubeProxyCertName ) ,
}
2019-01-07 19:52:57 +00:00
// Best security practice is to listen on localhost, but DinD uses private container network instead of Host.
if c . DinD {
CommandArgs [ "healthz-bind-address" ] = "0.0.0.0"
}
2018-04-11 17:28:26 +00:00
// check if our version has specific options for this component
2018-04-18 03:16:57 +00:00
serviceOptions := c . GetKubernetesServicesOptions ( )
2018-04-17 23:08:21 +00:00
if serviceOptions . Kubeproxy != nil {
2018-04-11 17:28:26 +00:00
for k , v := range serviceOptions . Kubeproxy {
2018-10-01 21:12:53 +00:00
// if the value is empty, we remove that option
if len ( v ) == 0 {
delete ( CommandArgs , k )
continue
}
2018-04-11 17:28:26 +00:00
CommandArgs [ k ] = v
}
}
2018-02-13 00:47:56 +00:00
VolumesFrom := [ ] string {
services . SidekickContainerName ,
}
Binds := [ ] string {
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-02-13 00:47:56 +00:00
}
for arg , value := range c . Services . Kubeproxy . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . Kubeproxy . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
Command = append ( Command , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . Kubeproxy . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
URL : services . GetHealthCheckURL ( false , services . KubeproxyPort ) ,
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . Kubeproxy . Image , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-11-07 23:54:08 +00:00
Name : services . KubeproxyContainerName ,
Command : Command ,
VolumesFrom : VolumesFrom ,
Binds : getUniqStringList ( Binds ) ,
Env : c . Services . Kubeproxy . ExtraEnv ,
NetworkMode : "host" ,
RestartPolicy : "always" ,
PidMode : "host" ,
Privileged : true ,
HealthCheck : healthCheck ,
Image : c . Services . Kubeproxy . Image ,
2018-04-03 20:18:51 +00:00
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . KubeproxyContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
func ( c * Cluster ) BuildProxyProcess ( ) v3 . Process {
nginxProxyEnv := ""
for i , host := range c . ControlPlaneHosts {
nginxProxyEnv += fmt . Sprintf ( "%s" , host . InternalAddress )
if i < ( len ( c . ControlPlaneHosts ) - 1 ) {
nginxProxyEnv += ","
}
}
Env := [ ] string { fmt . Sprintf ( "%s=%s" , services . NginxProxyEnvName , nginxProxyEnv ) }
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . SystemImages . NginxProxy , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-22 20:55:34 +00:00
Name : services . NginxProxyContainerName ,
Env : Env ,
// we do this to force container update when CP hosts change.
2018-11-07 23:54:08 +00:00
Args : Env ,
Command : [ ] string { "nginx-proxy" } ,
NetworkMode : "host" ,
RestartPolicy : "always" ,
HealthCheck : v3 . HealthCheck { } ,
Image : c . SystemImages . NginxProxy ,
2018-04-03 20:18:51 +00:00
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . NginxProxyContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
2018-04-11 22:54:47 +00:00
func ( c * Cluster ) BuildSchedulerProcess ( prefixPath string ) v3 . Process {
2018-03-14 23:37:04 +00:00
Command := [ ] string {
2018-08-03 22:01:58 +00:00
c . getRKEToolsEntryPoint ( ) ,
2018-02-13 00:47:56 +00:00
"kube-scheduler" ,
}
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
"leader-elect" : "true" ,
"v" : "2" ,
2019-01-07 19:52:57 +00:00
"address" : "127.0.0.1" ,
"profiling" : "false" ,
2018-03-14 23:37:04 +00:00
"kubeconfig" : pki . GetConfigPath ( pki . KubeSchedulerCertName ) ,
}
2019-01-07 19:52:57 +00:00
// Best security practice is to listen on localhost, but DinD uses private container network instead of Host.
if c . DinD {
CommandArgs [ "address" ] = "0.0.0.0"
}
2018-04-11 17:28:26 +00:00
// check if our version has specific options for this component
2018-04-18 03:16:57 +00:00
serviceOptions := c . GetKubernetesServicesOptions ( )
2018-04-17 23:08:21 +00:00
if serviceOptions . Scheduler != nil {
2018-04-11 17:28:26 +00:00
for k , v := range serviceOptions . Scheduler {
2018-10-01 21:12:53 +00:00
// if the value is empty, we remove that option
if len ( v ) == 0 {
delete ( CommandArgs , k )
continue
}
2018-04-11 17:28:26 +00:00
CommandArgs [ k ] = v
}
}
2018-02-13 00:47:56 +00:00
VolumesFrom := [ ] string {
services . SidekickContainerName ,
}
Binds := [ ] string {
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-02-13 00:47:56 +00:00
}
for arg , value := range c . Services . Scheduler . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . Scheduler . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
Command = append ( Command , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . Scheduler . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
URL : services . GetHealthCheckURL ( false , services . SchedulerPort ) ,
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . Scheduler . Image , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . SchedulerContainerName ,
Command : Command ,
2018-07-19 20:41:56 +00:00
Binds : getUniqStringList ( Binds ) ,
2018-06-07 09:38:39 +00:00
Env : c . Services . Scheduler . ExtraEnv ,
2018-04-03 20:18:51 +00:00
VolumesFrom : VolumesFrom ,
NetworkMode : "host" ,
RestartPolicy : "always" ,
Image : c . Services . Scheduler . Image ,
HealthCheck : healthCheck ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . SchedulerContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
func ( c * Cluster ) BuildSidecarProcess ( ) v3 . Process {
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . SystemImages . KubernetesServicesSidecar , c . PrivateRegistriesMap )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . SidekickContainerName ,
NetworkMode : "none" ,
Image : c . SystemImages . KubernetesServicesSidecar ,
HealthCheck : v3 . HealthCheck { } ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . SidekickContainerName ,
} ,
2019-01-21 20:05:59 +00:00
Command : [ ] string { "/bin/bash" } ,
2018-02-13 00:47:56 +00:00
}
}
2018-04-11 22:54:47 +00:00
func ( c * Cluster ) BuildEtcdProcess ( host * hosts . Host , etcdHosts [ ] * hosts . Host , prefixPath string ) v3 . Process {
2018-02-13 00:47:56 +00:00
nodeName := pki . GetEtcdCrtName ( host . InternalAddress )
initCluster := ""
if len ( etcdHosts ) == 0 {
initCluster = services . GetEtcdInitialCluster ( c . EtcdHosts )
} else {
initCluster = services . GetEtcdInitialCluster ( etcdHosts )
}
clusterState := "new"
if host . ExistingEtcdCluster {
clusterState = "existing"
}
2018-03-14 23:37:04 +00:00
args := [ ] string {
"/usr/local/bin/etcd" ,
2018-02-13 00:47:56 +00:00
"--peer-client-cert-auth" ,
"--client-cert-auth" ,
2018-03-14 23:37:04 +00:00
}
2018-04-20 04:07:44 +00:00
// If InternalAddress is not explicitly set, it's set to the same value as Address. This is all good until we deploy on a host with a DNATed public address like AWS, in that case we can't bind to that address so we fall back to 0.0.0.0
listenAddress := host . InternalAddress
if host . Address == host . InternalAddress {
listenAddress = "0.0.0.0"
}
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
"name" : "etcd-" + host . HostnameOverride ,
2018-05-15 21:06:05 +00:00
"data-dir" : services . EtcdDataDir ,
2018-03-14 23:37:04 +00:00
"advertise-client-urls" : "https://" + host . InternalAddress + ":2379,https://" + host . InternalAddress + ":4001" ,
2018-04-20 04:07:44 +00:00
"listen-client-urls" : "https://" + listenAddress + ":2379" ,
2018-03-14 23:37:04 +00:00
"initial-advertise-peer-urls" : "https://" + host . InternalAddress + ":2380" ,
2018-04-20 04:07:44 +00:00
"listen-peer-urls" : "https://" + listenAddress + ":2380" ,
2018-03-14 23:37:04 +00:00
"initial-cluster-token" : "etcd-cluster-1" ,
"initial-cluster" : initCluster ,
"initial-cluster-state" : clusterState ,
"trusted-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
"peer-trusted-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
"cert-file" : pki . GetCertPath ( nodeName ) ,
"key-file" : pki . GetKeyPath ( nodeName ) ,
"peer-cert-file" : pki . GetCertPath ( nodeName ) ,
"peer-key-file" : pki . GetKeyPath ( nodeName ) ,
2018-02-13 00:47:56 +00:00
}
Binds := [ ] string {
2018-05-15 21:06:05 +00:00
fmt . Sprintf ( "%s:%s:z" , path . Join ( prefixPath , "/var/lib/etcd" ) , services . EtcdDataDir ) ,
2018-04-11 22:54:47 +00:00
fmt . Sprintf ( "%s:/etc/kubernetes:z" , path . Join ( prefixPath , "/etc/kubernetes" ) ) ,
2018-02-13 00:47:56 +00:00
}
2018-03-16 03:20:42 +00:00
2018-02-13 00:47:56 +00:00
for arg , value := range c . Services . Etcd . ExtraArgs {
2018-03-14 23:37:04 +00:00
if _ , ok := c . Services . Etcd . ExtraArgs [ arg ] ; ok {
CommandArgs [ arg ] = value
}
}
for arg , value := range CommandArgs {
2018-02-13 00:47:56 +00:00
cmd := fmt . Sprintf ( "--%s=%s" , arg , value )
args = append ( args , cmd )
}
2018-03-16 03:20:42 +00:00
Binds = append ( Binds , c . Services . Etcd . ExtraBinds ... )
2018-02-13 00:47:56 +00:00
healthCheck := v3 . HealthCheck {
2018-04-20 20:17:45 +00:00
URL : fmt . Sprintf ( "https://%s:2379/health" , host . InternalAddress ) ,
2018-02-13 00:47:56 +00:00
}
2018-04-03 20:18:51 +00:00
registryAuthConfig , _ , _ := docker . GetImageRegistryConfig ( c . Services . Etcd . Image , c . PrivateRegistriesMap )
2018-05-02 11:47:53 +00:00
Env := [ ] string { }
Env = append ( Env , "ETCDCTL_API=3" )
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_ENDPOINT=https://%s:2379" , listenAddress ) )
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_CACERT=%s" , pki . GetCertPath ( pki . CACertName ) ) )
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_CERT=%s" , pki . GetCertPath ( nodeName ) ) )
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_KEY=%s" , pki . GetKeyPath ( nodeName ) ) )
2018-06-07 09:38:39 +00:00
Env = append ( Env , c . Services . Etcd . ExtraEnv ... )
2018-02-13 00:47:56 +00:00
return v3 . Process {
2018-04-03 20:18:51 +00:00
Name : services . EtcdContainerName ,
Args : args ,
2018-07-19 20:41:56 +00:00
Binds : getUniqStringList ( Binds ) ,
2018-05-02 11:47:53 +00:00
Env : Env ,
2018-04-03 20:18:51 +00:00
NetworkMode : "host" ,
RestartPolicy : "always" ,
Image : c . Services . Etcd . Image ,
HealthCheck : healthCheck ,
ImageRegistryAuthConfig : registryAuthConfig ,
2018-05-03 20:07:41 +00:00
Labels : map [ string ] string {
ContainerNameLabel : services . EtcdContainerName ,
} ,
2018-02-13 00:47:56 +00:00
}
}
func BuildPortChecksFromPortList ( host * hosts . Host , portList [ ] string , proto string ) [ ] v3 . PortCheck {
portChecks := [ ] v3 . PortCheck { }
for _ , port := range portList {
intPort , _ := strconv . Atoi ( port )
portChecks = append ( portChecks , v3 . PortCheck {
Address : host . Address ,
Port : intPort ,
Protocol : proto ,
} )
}
return portChecks
}
2018-04-11 22:54:47 +00:00
2018-04-18 03:16:57 +00:00
func ( c * Cluster ) GetKubernetesServicesOptions ( ) v3 . KubernetesServicesOptions {
clusterMajorVersion := getTagMajorVersion ( c . Version )
NamedkK8sImage , _ := ref . ParseNormalizedNamed ( c . SystemImages . Kubernetes )
2018-04-18 06:52:55 +00:00
2018-04-18 03:16:57 +00:00
k8sImageTag := NamedkK8sImage . ( ref . Tagged ) . Tag ( )
k8sImageMajorVersion := getTagMajorVersion ( k8sImageTag )
2018-04-18 06:52:55 +00:00
if clusterMajorVersion != k8sImageMajorVersion && k8sImageMajorVersion != "" {
2018-04-18 03:16:57 +00:00
clusterMajorVersion = k8sImageMajorVersion
}
serviceOptions , ok := v3 . K8sVersionServiceOptions [ clusterMajorVersion ]
2018-04-17 23:08:21 +00:00
if ok {
return serviceOptions
}
return v3 . KubernetesServicesOptions { }
}
2018-04-18 03:16:57 +00:00
func getTagMajorVersion ( tag string ) string {
splitTag := strings . Split ( tag , "." )
2018-04-18 06:52:55 +00:00
if len ( splitTag ) < 2 {
return ""
}
2018-04-18 03:16:57 +00:00
return strings . Join ( splitTag [ : 2 ] , "." )
}
2018-06-13 02:10:48 +00:00
2018-12-06 23:35:11 +00:00
func getCloudConfigChecksum ( config string ) string {
configByteSum := md5 . Sum ( [ ] byte ( config ) )
2018-06-13 02:10:48 +00:00
return fmt . Sprintf ( "%x" , configByteSum )
}
func getUniqStringList ( l [ ] string ) [ ] string {
m := map [ string ] bool { }
ul := [ ] string { }
for _ , k := range l {
if _ , ok := m [ k ] ; ! ok {
m [ k ] = true
ul = append ( ul , k )
}
}
return ul
}
2018-08-03 22:01:58 +00:00
func ( c * Cluster ) getRKEToolsEntryPoint ( ) string {
v := strings . Split ( c . SystemImages . KubernetesServicesSidecar , ":" )
2018-08-09 15:03:28 +00:00
last := v [ len ( v ) - 1 ]
logrus . Debugf ( "Extracted version [%s] from image [%s]" , last , c . SystemImages . KubernetesServicesSidecar )
2018-10-04 08:54:04 +00:00
sv , err := util . StrToSemVer ( last )
2018-08-09 15:03:28 +00:00
if err != nil {
2018-08-05 01:10:48 +00:00
return DefaultToolsEntrypoint
2018-08-03 22:01:58 +00:00
}
2018-10-04 08:54:04 +00:00
svdefault , err := util . StrToSemVer ( DefaultToolsEntrypointVersion )
2018-08-09 15:03:28 +00:00
if err != nil {
return DefaultToolsEntrypoint
}
if sv . LessThan ( * svdefault ) {
2018-08-05 01:10:48 +00:00
return LegacyToolsEntrypoint
2018-08-03 22:01:58 +00:00
}
2018-08-05 01:10:48 +00:00
return DefaultToolsEntrypoint
2018-08-03 22:01:58 +00:00
}