2018-02-13 00:47:56 +00:00
|
|
|
package cluster
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"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-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"
|
2018-02-13 00:47:56 +00:00
|
|
|
"github.com/rancher/rke/pki"
|
|
|
|
"github.com/rancher/rke/services"
|
|
|
|
"github.com/rancher/types/apis/management.cattle.io/v3"
|
|
|
|
)
|
|
|
|
|
2018-02-14 20:58:35 +00:00
|
|
|
const (
|
|
|
|
EtcdPathPrefix = "/registry"
|
2018-04-11 22:54:47 +00:00
|
|
|
B2DOS = "Boot2Docker"
|
|
|
|
B2DPrefixPath = "/mnt/sda1/rke"
|
|
|
|
ROS = "RancherOS"
|
|
|
|
ROSPrefixPath = "/opt/rke"
|
2018-02-14 20:58:35 +00:00
|
|
|
)
|
|
|
|
|
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-02-20 11:51:57 +00:00
|
|
|
myCluster, _ := ParseCluster(ctx, rkeConfig, "", "", nil, nil, nil)
|
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-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 {
|
|
|
|
prefixPath := myCluster.getPrefixPath(hostDockerInfo.OperatingSystem)
|
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)
|
|
|
|
processes[services.KubeproxyContainerName] = myCluster.BuildKubeProxyProcess(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{
|
|
|
|
Name: CloudConfigPath,
|
|
|
|
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)
|
|
|
|
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{
|
|
|
|
"/opt/rke/entrypoint.sh",
|
|
|
|
"kube-apiserver",
|
|
|
|
}
|
2018-03-14 23:37:04 +00:00
|
|
|
|
|
|
|
CommandArgs := map[string]string{
|
|
|
|
"insecure-bind-address": "127.0.0.1",
|
|
|
|
"bind-address": "0.0.0.0",
|
|
|
|
"insecure-port": "0",
|
|
|
|
"secure-port": "6443",
|
2018-03-23 18:14:11 +00:00
|
|
|
"cloud-provider": c.CloudProvider.Name,
|
2018-03-30 22:43:34 +00:00
|
|
|
"allow-privileged": "true",
|
2018-03-14 23:37:04 +00:00
|
|
|
"kubelet-preferred-address-types": "InternalIP,ExternalIP,Hostname",
|
|
|
|
"service-cluster-ip-range": c.Services.KubeAPI.ServiceClusterIPRange,
|
|
|
|
"admission-control": "ServiceAccount,NamespaceLifecycle,LimitRanger,PersistentVolumeLabel,DefaultStorageClass,ResourceQuota,DefaultTolerationSeconds",
|
|
|
|
"storage-backend": "etcd3",
|
|
|
|
"client-ca-file": pki.GetCertPath(pki.CACertName),
|
|
|
|
"tls-cert-file": pki.GetCertPath(pki.KubeAPICertName),
|
|
|
|
"tls-private-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
|
|
|
"kubelet-client-certificate": pki.GetCertPath(pki.KubeAPICertName),
|
|
|
|
"kubelet-client-key": pki.GetKeyPath(pki.KubeAPICertName),
|
|
|
|
"service-account-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
|
|
|
}
|
2018-03-28 19:46:28 +00:00
|
|
|
if len(c.CloudProvider.Name) > 0 {
|
|
|
|
CommandArgs["cloud-config"] = CloudConfigPath
|
|
|
|
}
|
2018-04-11 17:28:26 +00:00
|
|
|
// check if our version has specific options for this component
|
2018-04-17 23:08:21 +00:00
|
|
|
serviceOptions := GetKubernetesServicesOptions(c.Version)
|
|
|
|
if serviceOptions.KubeAPI != nil {
|
2018-04-11 17:28:26 +00:00
|
|
|
for k, v := range serviceOptions.KubeAPI {
|
|
|
|
CommandArgs[k] = v
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-14 20:58:35 +00:00
|
|
|
args := []string{
|
|
|
|
"--etcd-cafile=" + etcdCAClientCert,
|
|
|
|
"--etcd-certfile=" + etcdClientCert,
|
|
|
|
"--etcd-keyfile=" + etcdClientKey,
|
|
|
|
"--etcd-servers=" + etcdConnectionString,
|
|
|
|
"--etcd-prefix=" + etcdPathPrefix,
|
|
|
|
}
|
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
|
|
|
}
|
|
|
|
if c.Services.KubeAPI.PodSecurityPolicy {
|
2018-03-14 23:37:04 +00:00
|
|
|
CommandArgs["runtime-config"] = "extensions/v1beta1/podsecuritypolicy=true"
|
|
|
|
CommandArgs["admission-control"] = CommandArgs["admission-control"] + ",PodSecurityPolicy"
|
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,
|
|
|
|
Args: args,
|
|
|
|
VolumesFrom: VolumesFrom,
|
|
|
|
Binds: Binds,
|
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
Image: c.Services.KubeAPI.Image,
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
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{
|
|
|
|
"/opt/rke/entrypoint.sh",
|
2018-02-13 00:47:56 +00:00
|
|
|
"kube-controller-manager",
|
|
|
|
}
|
2018-03-14 23:37:04 +00:00
|
|
|
|
|
|
|
CommandArgs := map[string]string{
|
|
|
|
"address": "0.0.0.0",
|
2018-03-23 18:14:11 +00:00
|
|
|
"cloud-provider": c.CloudProvider.Name,
|
2018-03-23 20:15:30 +00:00
|
|
|
"allow-untagged-cloud": "true",
|
2018-03-23 18:14:11 +00:00
|
|
|
"configure-cloud-routes": "false",
|
2018-03-14 23:37:04 +00:00
|
|
|
"leader-elect": "true",
|
|
|
|
"kubeconfig": pki.GetConfigPath(pki.KubeControllerCertName),
|
|
|
|
"enable-hostpath-provisioner": "false",
|
|
|
|
"node-monitor-grace-period": "40s",
|
|
|
|
"pod-eviction-timeout": "5m0s",
|
|
|
|
"v": "2",
|
|
|
|
"allocate-node-cidrs": "true",
|
|
|
|
"cluster-cidr": c.ClusterCIDR,
|
|
|
|
"service-cluster-ip-range": c.Services.KubeController.ServiceClusterIPRange,
|
|
|
|
"service-account-private-key-file": pki.GetKeyPath(pki.KubeAPICertName),
|
|
|
|
"root-ca-file": pki.GetCertPath(pki.CACertName),
|
|
|
|
}
|
2018-03-28 19:46:28 +00:00
|
|
|
if len(c.CloudProvider.Name) > 0 {
|
|
|
|
CommandArgs["cloud-config"] = CloudConfigPath
|
|
|
|
}
|
2018-04-11 17:28:26 +00:00
|
|
|
|
|
|
|
// check if our version has specific options for this component
|
2018-04-17 23:08:21 +00:00
|
|
|
serviceOptions := GetKubernetesServicesOptions(c.Version)
|
|
|
|
if serviceOptions.KubeController != nil {
|
2018-04-11 17:28:26 +00:00
|
|
|
for k, v := range serviceOptions.KubeController {
|
|
|
|
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,
|
|
|
|
Binds: Binds,
|
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
Image: c.Services.KubeController.Image,
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
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{
|
|
|
|
"/opt/rke/entrypoint.sh",
|
2018-02-13 00:47:56 +00:00
|
|
|
"kubelet",
|
2018-03-14 23:37:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
CommandArgs := map[string]string{
|
|
|
|
"v": "2",
|
|
|
|
"address": "0.0.0.0",
|
|
|
|
"cadvisor-port": "0",
|
|
|
|
"read-only-port": "0",
|
|
|
|
"cluster-domain": c.ClusterDomain,
|
|
|
|
"pod-infra-container-image": c.Services.Kubelet.InfraContainerImage,
|
|
|
|
"cgroups-per-qos": "True",
|
|
|
|
"enforce-node-allocatable": "",
|
|
|
|
"hostname-override": host.HostnameOverride,
|
|
|
|
"cluster-dns": c.ClusterDNSServer,
|
|
|
|
"network-plugin": "cni",
|
|
|
|
"cni-conf-dir": "/etc/cni/net.d",
|
|
|
|
"cni-bin-dir": "/opt/cni/bin",
|
|
|
|
"resolv-conf": "/etc/resolv.conf",
|
|
|
|
"allow-privileged": "true",
|
2018-03-23 18:14:11 +00:00
|
|
|
"cloud-provider": c.CloudProvider.Name,
|
2018-03-14 23:37:04 +00:00
|
|
|
"kubeconfig": pki.GetConfigPath(pki.KubeNodeCertName),
|
|
|
|
"client-ca-file": pki.GetCertPath(pki.CACertName),
|
|
|
|
"anonymous-auth": "false",
|
|
|
|
"volume-plugin-dir": "/var/lib/kubelet/volumeplugins",
|
|
|
|
"fail-swap-on": strconv.FormatBool(c.Services.Kubelet.FailSwapOn),
|
2018-04-11 22:54:47 +00:00
|
|
|
"root-dir": path.Join(prefixPath, "/var/lib/kubelet"),
|
2018-02-13 00:47:56 +00:00
|
|
|
}
|
2018-03-26 22:53:28 +00:00
|
|
|
if host.Address != host.InternalAddress {
|
|
|
|
CommandArgs["node-ip"] = host.InternalAddress
|
|
|
|
}
|
2018-03-28 19:46:28 +00:00
|
|
|
if len(c.CloudProvider.Name) > 0 {
|
|
|
|
CommandArgs["cloud-config"] = CloudConfigPath
|
|
|
|
}
|
2018-04-11 17:28:26 +00:00
|
|
|
|
|
|
|
// check if our version has specific options for this component
|
2018-04-17 23:08:21 +00:00
|
|
|
serviceOptions := GetKubernetesServicesOptions(c.Version)
|
|
|
|
if serviceOptions.Kubelet != nil {
|
2018-04-11 17:28:26 +00:00
|
|
|
for k, v := range serviceOptions.Kubelet {
|
|
|
|
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 18:30:15 +00:00
|
|
|
"/etc/cni:/etc/cni:ro,z",
|
|
|
|
"/opt/cni:/opt/cni:ro,z",
|
2018-04-11 22:54:47 +00:00
|
|
|
fmt.Sprintf("%s:/var/lib/cni:z", path.Join(prefixPath, "/var/lib/cni")),
|
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-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-04-11 22:54:47 +00:00
|
|
|
fmt.Sprintf("%s:/var/log/containers:z", path.Join(prefixPath, "/var/log/containers")),
|
|
|
|
fmt.Sprintf("%s:/var/log/pods:z", path.Join(prefixPath, "/var/log/pods")),
|
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,
|
|
|
|
Binds: Binds,
|
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
Image: c.Services.Kubelet.Image,
|
|
|
|
PidMode: "host",
|
|
|
|
Privileged: true,
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
2018-02-13 00:47:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-04-11 22:54:47 +00:00
|
|
|
func (c *Cluster) BuildKubeProxyProcess(prefixPath string) v3.Process {
|
2018-03-14 23:37:04 +00:00
|
|
|
Command := []string{
|
|
|
|
"/opt/rke/entrypoint.sh",
|
2018-02-13 00:47:56 +00:00
|
|
|
"kube-proxy",
|
|
|
|
}
|
2018-03-14 23:37:04 +00:00
|
|
|
|
|
|
|
CommandArgs := map[string]string{
|
|
|
|
"v": "2",
|
|
|
|
"healthz-bind-address": "0.0.0.0",
|
|
|
|
"kubeconfig": pki.GetConfigPath(pki.KubeProxyCertName),
|
|
|
|
}
|
|
|
|
|
2018-04-11 17:28:26 +00:00
|
|
|
// check if our version has specific options for this component
|
2018-04-17 23:08:21 +00:00
|
|
|
serviceOptions := GetKubernetesServicesOptions(c.Version)
|
|
|
|
if serviceOptions.Kubeproxy != nil {
|
2018-04-11 17:28:26 +00:00
|
|
|
for k, v := range serviceOptions.Kubeproxy {
|
|
|
|
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-02-24 13:08:46 +00:00
|
|
|
Name: services.KubeproxyContainerName,
|
2018-02-13 00:47:56 +00:00
|
|
|
Command: Command,
|
|
|
|
VolumesFrom: VolumesFrom,
|
|
|
|
Binds: Binds,
|
|
|
|
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-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-02-24 13:08:46 +00:00
|
|
|
Name: services.NginxProxyContainerName,
|
2018-02-13 00:47:56 +00:00
|
|
|
Env: Env,
|
2018-02-15 03:25:36 +00:00
|
|
|
Args: Env,
|
2018-02-13 00:47:56 +00:00
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
HealthCheck: v3.HealthCheck{},
|
|
|
|
Image: c.SystemImages.NginxProxy,
|
2018-04-03 20:18:51 +00:00
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
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{
|
|
|
|
"/opt/rke/entrypoint.sh",
|
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",
|
|
|
|
"address": "0.0.0.0",
|
|
|
|
"kubeconfig": pki.GetConfigPath(pki.KubeSchedulerCertName),
|
|
|
|
}
|
|
|
|
|
2018-04-11 17:28:26 +00:00
|
|
|
// check if our version has specific options for this component
|
2018-04-17 23:08:21 +00:00
|
|
|
serviceOptions := GetKubernetesServicesOptions(c.Version)
|
|
|
|
if serviceOptions.Scheduler != nil {
|
2018-04-11 17:28:26 +00:00
|
|
|
for k, v := range serviceOptions.Scheduler {
|
|
|
|
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,
|
|
|
|
Binds: Binds,
|
|
|
|
VolumesFrom: VolumesFrom,
|
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
Image: c.Services.Scheduler.Image,
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
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-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
|
|
|
}
|
|
|
|
|
|
|
|
CommandArgs := map[string]string{
|
|
|
|
"name": "etcd-" + host.HostnameOverride,
|
|
|
|
"data-dir": "/var/lib/rancher/etcd",
|
|
|
|
"advertise-client-urls": "https://" + host.InternalAddress + ":2379,https://" + host.InternalAddress + ":4001",
|
|
|
|
"listen-client-urls": "https://0.0.0.0:2379",
|
|
|
|
"initial-advertise-peer-urls": "https://" + host.InternalAddress + ":2380",
|
|
|
|
"listen-peer-urls": "https://0.0.0.0:2380",
|
|
|
|
"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-04-11 22:54:47 +00:00
|
|
|
fmt.Sprintf("%s:/var/lib/rancher/etcd:z", path.Join(prefixPath, "/var/lib/etcd")),
|
|
|
|
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{
|
|
|
|
URL: services.EtcdHealthCheckURL,
|
|
|
|
}
|
2018-04-03 20:18:51 +00:00
|
|
|
registryAuthConfig, _, _ := docker.GetImageRegistryConfig(c.Services.Etcd.Image, c.PrivateRegistriesMap)
|
|
|
|
|
2018-02-13 00:47:56 +00:00
|
|
|
return v3.Process{
|
2018-04-03 20:18:51 +00:00
|
|
|
Name: services.EtcdContainerName,
|
|
|
|
Args: args,
|
|
|
|
Binds: Binds,
|
|
|
|
NetworkMode: "host",
|
|
|
|
RestartPolicy: "always",
|
|
|
|
Image: c.Services.Etcd.Image,
|
|
|
|
HealthCheck: healthCheck,
|
|
|
|
ImageRegistryAuthConfig: registryAuthConfig,
|
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
|
|
|
|
|
|
|
func (c *Cluster) getPrefixPath(osType string) string {
|
|
|
|
var prefixPath string
|
|
|
|
if strings.Contains(osType, B2DOS) {
|
|
|
|
prefixPath = B2DPrefixPath
|
|
|
|
} else if strings.Contains(osType, ROS) {
|
|
|
|
prefixPath = ROSPrefixPath
|
|
|
|
} else {
|
|
|
|
prefixPath = c.PrefixPath
|
|
|
|
}
|
|
|
|
return prefixPath
|
|
|
|
}
|
2018-04-17 23:08:21 +00:00
|
|
|
|
|
|
|
func GetKubernetesServicesOptions(version string) v3.KubernetesServicesOptions {
|
|
|
|
splitVersion := strings.Split(version, ".")
|
|
|
|
majorVersion := strings.Join(splitVersion[:2], ".")
|
|
|
|
serviceOptions, ok := v3.K8sVersionServiceOptions[majorVersion]
|
|
|
|
if ok {
|
|
|
|
return serviceOptions
|
|
|
|
}
|
|
|
|
return v3.KubernetesServicesOptions{}
|
|
|
|
}
|