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"
2019-01-08 02:14:42 +00:00
"net"
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-11 22:54:47 +00:00
"github.com/docker/docker/api/types"
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"
2019-05-28 18:51:53 +00:00
"github.com/rancher/rke/metadata"
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"
2019-07-18 20:42:01 +00:00
v3 "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"
2019-04-30 10:28:10 +00:00
2019-06-24 20:16:37 +00:00
// MaxEtcdOldEnvVersion The versions are maxed out for minor versions because -rancher1 suffix will cause semver to think its older, example: v1.15.0 > v1.15.0-rancher1
MaxEtcdOldEnvVersion = "v3.2.99"
MaxK8s115Version = "v1.15"
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 ]
2019-06-17 20:52:15 +00:00
clusterPlan . Nodes = append ( clusterPlan . Nodes , BuildRKEConfigNodePlan ( ctx , myCluster , host , hostsInfoMap [ host . Address ] , nil ) )
2018-02-13 00:47:56 +00:00
}
return clusterPlan , nil
}
2019-06-17 20:52:15 +00:00
func BuildRKEConfigNodePlan ( ctx context . Context , myCluster * Cluster , host * hosts . Host , hostDockerInfo types . Info , svcOptions * v3 . KubernetesServicesOptions ) 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 ( )
2019-06-17 20:52:15 +00:00
processes [ services . KubeletContainerName ] = myCluster . BuildKubeletProcess ( host , prefixPath , svcOptions )
processes [ services . KubeproxyContainerName ] = myCluster . BuildKubeProxyProcess ( host , prefixPath , svcOptions )
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 {
2019-06-17 20:52:15 +00:00
processes [ services . KubeAPIContainerName ] = myCluster . BuildKubeAPIProcess ( host , prefixPath , svcOptions )
processes [ services . KubeControllerContainerName ] = myCluster . BuildKubeControllerProcess ( prefixPath , svcOptions )
processes [ services . SchedulerContainerName ] = myCluster . BuildSchedulerProcess ( prefixPath , svcOptions )
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
}
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) BuildKubeAPIProcess ( host * hosts . Host , prefixPath string , svcOptions * v3 . KubernetesServicesOptions ) v3 . Process {
2018-02-14 20:58:35 +00:00
// check if external etcd is used
2019-05-31 16:39:56 +00:00
etcdConnectionString := services . GetEtcdConnString ( c . EtcdHosts , host . InternalAddress )
2018-02-14 20:58:35 +00:00
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-05-28 18:51:53 +00:00
2018-03-14 23:37:04 +00:00
CommandArgs := map [ string ] string {
2019-07-24 20:25:14 +00:00
"client-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
"cloud-provider" : c . CloudProvider . Name ,
"etcd-cafile" : etcdCAClientCert ,
"etcd-certfile" : etcdClientCert ,
"etcd-keyfile" : etcdClientKey ,
"etcd-prefix" : etcdPathPrefix ,
"etcd-servers" : etcdConnectionString ,
"kubelet-client-certificate" : pki . GetCertPath ( pki . KubeAPICertName ) ,
"kubelet-client-key" : pki . GetKeyPath ( pki . KubeAPICertName ) ,
"kubelet-certificate-authority" : pki . GetCertPath ( pki . CACertName ) ,
"proxy-client-cert-file" : pki . GetCertPath ( pki . APIProxyClientCertName ) ,
"proxy-client-key-file" : pki . GetKeyPath ( pki . APIProxyClientCertName ) ,
"requestheader-allowed-names" : pki . APIProxyClientCertName ,
"requestheader-client-ca-file" : pki . GetCertPath ( pki . RequestHeaderCACertName ) ,
"service-account-key-file" : pki . GetKeyPath ( pki . ServiceAccountTokenKeyName ) ,
"service-cluster-ip-range" : c . Services . KubeAPI . ServiceClusterIPRange ,
"service-node-port-range" : c . Services . KubeAPI . ServiceNodePortRange ,
"tls-cert-file" : pki . GetCertPath ( pki . KubeAPICertName ) ,
"tls-private-key-file" : pki . GetKeyPath ( pki . KubeAPICertName ) ,
2018-03-14 23:37:04 +00:00
}
2019-02-11 23:21:29 +00:00
if len ( c . CloudProvider . Name ) > 0 {
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
}
2019-06-17 20:52:15 +00:00
var serviceOptions v3 . KubernetesServicesOptions
if svcOptions == nil {
// check if our version has specific options for this component
serviceOptions = c . GetKubernetesServicesOptions ( )
} else {
serviceOptions = * svcOptions
}
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
2019-02-26 23:14:01 +00:00
if util . GetTagMajorVersion ( c . Version ) == "v1.8" {
2018-06-12 21:02:05 +00:00
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
2019-01-08 02:14:42 +00:00
if len ( host . InternalAddress ) > 0 && net . ParseIP ( host . InternalAddress ) != nil {
CommandArgs [ "advertise-address" ] = host . InternalAddress
}
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 {
2019-05-28 18:51:53 +00:00
if c . Services . KubeAPI . AlwaysPullImages {
CommandArgs [ optionName ] = CommandArgs [ optionName ] + ",PodSecurityPolicy,AlwaysPullImages"
} else {
CommandArgs [ optionName ] = CommandArgs [ optionName ] + ",PodSecurityPolicy"
}
2018-08-29 21:42:12 +00:00
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
}
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) BuildKubeControllerProcess ( prefixPath string , svcOptions * v3 . KubernetesServicesOptions ) 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
"cloud-provider" : c . CloudProvider . Name ,
"cluster-cidr" : c . ClusterCIDR ,
"kubeconfig" : pki . GetConfigPath ( pki . KubeControllerCertName ) ,
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 ,
}
// 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
}
2019-02-11 23:21:29 +00:00
if len ( c . CloudProvider . Name ) > 0 {
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
}
2019-06-17 20:52:15 +00:00
var serviceOptions v3 . KubernetesServicesOptions
if svcOptions == nil {
// check if our version has specific options for this component
serviceOptions = c . GetKubernetesServicesOptions ( )
} else {
serviceOptions = * svcOptions
}
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
}
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) BuildKubeletProcess ( host * hosts . Host , prefixPath string , svcOptions * v3 . KubernetesServicesOptions ) 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-05-28 18:51:53 +00:00
"client-ca-file" : pki . GetCertPath ( pki . CACertName ) ,
"cloud-provider" : c . CloudProvider . Name ,
"cluster-dns" : c . ClusterDNSServer ,
"cluster-domain" : c . ClusterDomain ,
"fail-swap-on" : strconv . FormatBool ( c . Services . Kubelet . FailSwapOn ) ,
"hostname-override" : host . HostnameOverride ,
"kubeconfig" : pki . GetConfigPath ( pki . KubeNodeCertName ) ,
2019-07-24 20:25:14 +00:00
"tls-cert-file" : pki . GetCertPath ( pki . GetCrtNameForAddress ( host . InternalAddress , pki . KubeletCertName ) ) ,
"tls-private-key-file" : pki . GetCertPath ( fmt . Sprintf ( "%s-key" , pki . GetCrtNameForAddress ( host . InternalAddress , pki . KubeletCertName ) ) ) ,
2019-05-28 18:51:53 +00:00
"pod-infra-container-image" : c . Services . Kubelet . InfraContainerImage ,
"root-dir" : path . Join ( prefixPath , "/var/lib/kubelet" ) ,
2018-02-13 00:47:56 +00:00
}
2019-07-18 20:42:01 +00:00
if c . DinD {
CommandArgs [ "healthz-bind-address" ] = "0.0.0.0"
}
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
}
2019-02-11 23:21:29 +00:00
if len ( c . CloudProvider . Name ) > 0 {
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 ) ) )
}
2019-06-17 20:52:15 +00:00
var serviceOptions v3 . KubernetesServicesOptions
if svcOptions == nil {
// check if our version has specific options for this component
serviceOptions = c . GetKubernetesServicesOptions ( )
} else {
serviceOptions = * svcOptions
2019-06-24 20:16:37 +00:00
}
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 {
2019-07-18 20:42:01 +00:00
URL : services . GetHealthCheckURL ( false , services . KubeletPort ) ,
2018-02-13 00:47:56 +00:00
}
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
}
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) BuildKubeProxyProcess ( host * hosts . Host , prefixPath string , svcOptions * v3 . KubernetesServicesOptions ) 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 {
2019-05-28 18:51:53 +00:00
"cluster-cidr" : c . ClusterCIDR ,
"hostname-override" : host . HostnameOverride ,
"kubeconfig" : pki . GetConfigPath ( pki . KubeProxyCertName ) ,
2019-01-07 19:52:57 +00:00
}
2019-05-28 18:51:53 +00:00
2019-06-17 20:52:15 +00:00
var serviceOptions v3 . KubernetesServicesOptions
if svcOptions == nil {
// check if our version has specific options for this component
serviceOptions = c . GetKubernetesServicesOptions ( )
} else {
serviceOptions = * svcOptions
}
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
}
}
2019-05-28 18:51:53 +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-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" ) ) ,
2019-04-10 17:59:58 +00:00
"/run:/run" ,
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
}
}
2019-06-17 20:52:15 +00:00
func ( c * Cluster ) BuildSchedulerProcess ( prefixPath string , svcOptions * v3 . KubernetesServicesOptions ) 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 {
2019-05-28 18:51:53 +00:00
"kubeconfig" : pki . GetConfigPath ( pki . KubeSchedulerCertName ) ,
2018-03-14 23:37:04 +00:00
}
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"
}
2019-06-17 20:52:15 +00:00
var serviceOptions v3 . KubernetesServicesOptions
if svcOptions == nil {
// check if our version has specific options for this component
serviceOptions = c . GetKubernetesServicesOptions ( )
} else {
serviceOptions = * svcOptions
}
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 {
2019-07-24 20:25:14 +00:00
nodeName := pki . GetCrtNameForAddress ( host . InternalAddress , pki . EtcdCertName )
2018-02-13 00:47:56 +00:00
initCluster := ""
2019-03-08 21:02:44 +00:00
architecture := "amd64"
2018-02-13 00:47:56 +00:00
if len ( etcdHosts ) == 0 {
initCluster = services . GetEtcdInitialCluster ( c . EtcdHosts )
2019-02-28 07:54:35 +00:00
if len ( c . EtcdHosts ) > 0 {
architecture = c . EtcdHosts [ 0 ] . DockerInfo . Architecture
}
2018-02-13 00:47:56 +00:00
} else {
initCluster = services . GetEtcdInitialCluster ( etcdHosts )
2019-02-28 07:54:35 +00:00
architecture = etcdHosts [ 0 ] . DockerInfo . Architecture
2018-02-13 00:47:56 +00:00
}
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 )
2019-04-30 10:28:10 +00:00
// Determine etcd version for correct etcdctl environment variables
etcdTag , err := util . GetImageTagFromImage ( c . Services . Etcd . Image )
if err != nil {
logrus . Warn ( err )
}
etcdSemVer , err := util . StrToSemVer ( etcdTag )
if err != nil {
logrus . Warn ( err )
}
2019-06-24 20:16:37 +00:00
maxEtcdOldEnvSemVer , err := util . StrToSemVer ( MaxEtcdOldEnvVersion )
2019-04-30 10:28:10 +00:00
if err != nil {
logrus . Warn ( err )
}
// Configure default etcdctl environment variables
2018-05-02 11:47:53 +00:00
Env := [ ] string { }
Env = append ( Env , "ETCDCTL_API=3" )
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 ) ) )
2019-03-09 02:36:21 +00:00
2019-04-30 10:28:10 +00:00
// Apply old configuration to avoid replacing etcd container
2019-06-24 20:16:37 +00:00
if etcdSemVer . LessThan ( * maxEtcdOldEnvSemVer ) {
logrus . Debugf ( "Version [%s] is less than version [%s]" , etcdSemVer , maxEtcdOldEnvSemVer )
2019-04-30 10:28:10 +00:00
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_ENDPOINT=https://%s:2379" , listenAddress ) )
} else {
2019-06-24 20:16:37 +00:00
logrus . Debugf ( "Version [%s] is equal or higher than version [%s]" , etcdSemVer , maxEtcdOldEnvSemVer )
2019-04-30 10:28:10 +00:00
// Point etcdctl to localhost in case we have listen all (0.0.0.0) configured
if listenAddress == "0.0.0.0" {
Env = append ( Env , "ETCDCTL_ENDPOINTS=https://127.0.0.1:2379" )
// If internal address is configured, set endpoint to that address as well
} else {
Env = append ( Env , fmt . Sprintf ( "ETCDCTL_ENDPOINTS=https://%s:2379" , listenAddress ) )
}
}
2019-03-09 02:36:21 +00:00
if architecture == "aarch64" {
architecture = "arm64"
}
2019-03-08 21:02:44 +00:00
Env = append ( Env , fmt . Sprintf ( "ETCD_UNSUPPORTED_ARCH=%s" , architecture ) )
2019-02-28 07:54:35 +00:00
2018-06-07 09:38:39 +00:00
Env = append ( Env , c . Services . Etcd . ExtraEnv ... )
2019-07-24 19:58:50 +00:00
var user string
if c . Services . Etcd . UID != 0 && c . Services . Etcd . GID != 0 {
user = fmt . Sprintf ( "%d:%d" , c . Services . Etcd . UID , c . Services . Etcd . UID )
}
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 ,
2019-07-24 19:58:50 +00:00
User : user ,
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 {
2019-07-19 19:03:40 +00:00
if serviceOptions , ok := metadata . K8sVersionToServiceOptions [ c . Version ] ; ok {
return serviceOptions
}
2019-02-26 23:14:01 +00:00
clusterMajorVersion := util . GetTagMajorVersion ( c . Version )
2019-04-30 10:28:10 +00:00
k8sImageTag , err := util . GetImageTagFromImage ( c . SystemImages . Kubernetes )
if err != nil {
logrus . Warn ( err )
}
2018-04-18 06:52:55 +00:00
2019-02-26 23:14:01 +00:00
k8sImageMajorVersion := util . GetTagMajorVersion ( k8sImageTag )
2018-04-18 03:16:57 +00:00
2018-04-18 06:52:55 +00:00
if clusterMajorVersion != k8sImageMajorVersion && k8sImageMajorVersion != "" {
2018-04-18 03:16:57 +00:00
clusterMajorVersion = k8sImageMajorVersion
}
2019-05-28 18:51:53 +00:00
serviceOptions , ok := metadata . K8sVersionToServiceOptions [ clusterMajorVersion ]
2018-04-17 23:08:21 +00:00
if ok {
return serviceOptions
}
return v3 . KubernetesServicesOptions { }
}
2018-04-18 03:16:57 +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 ]
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
}