1
0
mirror of https://github.com/rancher/rke.git synced 2025-06-04 04:59:40 +00:00
rke/cluster/hosts.go

183 lines
5.8 KiB
Go
Raw Normal View History

package cluster
import (
"fmt"
"strings"
"context"
2018-03-31 10:54:12 +00:00
"github.com/docker/docker/api/types"
"github.com/rancher/rke/hosts"
"github.com/rancher/rke/log"
"github.com/rancher/rke/pki"
"github.com/rancher/rke/services"
"github.com/rancher/rke/util"
2018-02-21 23:13:08 +00:00
"github.com/rancher/types/apis/management.cattle.io/v3"
2017-11-13 21:28:38 +00:00
"github.com/sirupsen/logrus"
2018-02-01 16:25:19 +00:00
"golang.org/x/sync/errgroup"
2017-11-21 20:26:26 +00:00
)
const (
2018-03-23 18:14:11 +00:00
etcdRoleLabel = "node-role.kubernetes.io/etcd"
controlplaneRoleLabel = "node-role.kubernetes.io/controlplane"
workerRoleLabel = "node-role.kubernetes.io/worker"
)
func (c *Cluster) TunnelHosts(ctx context.Context, flags ExternalFlags) error {
if flags.Local {
if err := c.ControlPlaneHosts[0].TunnelUpLocal(ctx, c.Version); err != nil {
return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err)
}
return nil
}
2018-02-21 23:13:08 +00:00
c.InactiveHosts = make([]*hosts.Host, 0)
uniqueHosts := hosts.GetUniqueHostList(c.EtcdHosts, c.ControlPlaneHosts, c.WorkerHosts)
2018-10-16 19:51:57 +00:00
var errgrp errgroup.Group
for _, uniqueHost := range uniqueHosts {
runHost := uniqueHost
errgrp.Go(func() error {
if err := runHost.TunnelUp(ctx, c.DockerDialerFactory, c.PrefixPath, c.Version); err != nil {
// Unsupported Docker version is NOT a connectivity problem that we can recover! So we bail out on it
if strings.Contains(err.Error(), "Unsupported Docker version found") {
return err
}
log.Warnf(ctx, "Failed to set up SSH tunneling for host [%s]: %v", runHost.Address, err)
c.InactiveHosts = append(c.InactiveHosts, runHost)
}
2018-10-16 19:51:57 +00:00
return nil
})
}
if err := errgrp.Wait(); err != nil {
return err
}
2018-02-21 23:13:08 +00:00
for _, host := range c.InactiveHosts {
log.Warnf(ctx, "Removing host [%s] from node lists", host.Address)
c.EtcdHosts = removeFromHosts(host, c.EtcdHosts)
c.ControlPlaneHosts = removeFromHosts(host, c.ControlPlaneHosts)
c.WorkerHosts = removeFromHosts(host, c.WorkerHosts)
c.RancherKubernetesEngineConfig.Nodes = removeFromRKENodes(host.RKEConfigNode, c.RancherKubernetesEngineConfig.Nodes)
}
2018-02-21 23:13:08 +00:00
return ValidateHostCount(c)
}
func (c *Cluster) InvertIndexHosts() error {
c.EtcdHosts = make([]*hosts.Host, 0)
c.WorkerHosts = make([]*hosts.Host, 0)
c.ControlPlaneHosts = make([]*hosts.Host, 0)
2017-11-28 17:45:24 +00:00
for _, host := range c.Nodes {
newHost := hosts.Host{
RKEConfigNode: host,
ToAddLabels: map[string]string{},
ToDelLabels: map[string]string{},
ToAddTaints: []string{},
ToDelTaints: []string{},
2018-03-31 10:54:12 +00:00
DockerInfo: types.Info{
DockerRootDir: "/var/lib/docker",
},
}
for k, v := range host.Labels {
newHost.ToAddLabels[k] = v
}
2018-01-22 19:31:03 +00:00
newHost.IgnoreDockerVersion = c.IgnoreDockerVersion
2018-05-08 22:30:50 +00:00
if c.BastionHost.Address != "" {
// Add the bastion host information to each host object
newHost.BastionHost = c.BastionHost
}
for _, role := range host.Role {
2017-11-28 17:45:24 +00:00
logrus.Debugf("Host: " + host.Address + " has role: " + role)
switch role {
case services.ETCDRole:
newHost.IsEtcd = true
newHost.ToAddLabels[etcdRoleLabel] = "true"
c.EtcdHosts = append(c.EtcdHosts, &newHost)
case services.ControlRole:
newHost.IsControl = true
2018-03-23 18:14:11 +00:00
newHost.ToAddLabels[controlplaneRoleLabel] = "true"
c.ControlPlaneHosts = append(c.ControlPlaneHosts, &newHost)
case services.WorkerRole:
newHost.IsWorker = true
newHost.ToAddLabels[workerRoleLabel] = "true"
c.WorkerHosts = append(c.WorkerHosts, &newHost)
default:
2017-11-28 17:45:24 +00:00
return fmt.Errorf("Failed to recognize host [%s] role %s", host.Address, role)
}
}
if !newHost.IsEtcd {
newHost.ToDelLabels[etcdRoleLabel] = "true"
}
if !newHost.IsControl {
2018-03-23 18:14:11 +00:00
newHost.ToDelLabels[controlplaneRoleLabel] = "true"
}
if !newHost.IsWorker {
newHost.ToDelLabels[workerRoleLabel] = "true"
}
}
return nil
}
2018-08-20 04:37:04 +00:00
func (c *Cluster) SetUpHosts(ctx context.Context, rotateCerts bool) error {
2017-11-14 18:11:21 +00:00
if c.Authentication.Strategy == X509AuthenticationProvider {
log.Infof(ctx, "[certificates] Deploying kubernetes certificates to Cluster nodes")
hostList := hosts.GetUniqueHostList(c.EtcdHosts, c.ControlPlaneHosts, c.WorkerHosts)
2018-02-01 16:25:19 +00:00
var errgrp errgroup.Group
hostsQueue := util.GetObjectQueue(hostList)
for w := 0; w < WorkerThreads; w++ {
2018-02-01 16:25:19 +00:00
errgrp.Go(func() error {
var errList []error
for host := range hostsQueue {
2018-08-20 04:37:04 +00:00
err := pki.DeployCertificatesOnPlaneHost(ctx, host.(*hosts.Host), c.RancherKubernetesEngineConfig, c.Certificates, c.SystemImages.CertDownloader, c.PrivateRegistriesMap, rotateCerts)
if err != nil {
errList = append(errList, err)
}
}
return util.ErrList(errList)
2018-02-01 16:25:19 +00:00
})
}
2018-02-01 16:25:19 +00:00
if err := errgrp.Wait(); err != nil {
return err
}
if err := rebuildLocalAdminConfig(ctx, c); err != nil {
return err
}
log.Infof(ctx, "[certificates] Successfully deployed kubernetes certificates to Cluster nodes")
2018-03-28 19:46:28 +00:00
if c.CloudProvider.Name != "" {
if err := deployCloudProviderConfig(ctx, hostList, c.SystemImages.Alpine, c.PrivateRegistriesMap, c.CloudConfigFile); err != nil {
2018-03-28 19:46:28 +00:00
return err
}
log.Infof(ctx, "[%s] Successfully deployed kubernetes cloud config to Cluster nodes", CloudConfigServiceName)
}
}
return nil
}
2017-11-17 21:33:07 +00:00
func CheckEtcdHostsChanged(kubeCluster, currentCluster *Cluster) error {
2017-11-26 23:27:39 +00:00
if currentCluster != nil {
etcdChanged := hosts.IsHostListChanged(currentCluster.EtcdHosts, kubeCluster.EtcdHosts)
if etcdChanged {
return fmt.Errorf("Adding or removing Etcd nodes is not supported")
}
}
return nil
}
2018-02-21 23:13:08 +00:00
func removeFromHosts(hostToRemove *hosts.Host, hostList []*hosts.Host) []*hosts.Host {
for i := range hostList {
if hostToRemove.Address == hostList[i].Address {
return append(hostList[:i], hostList[i+1:]...)
}
}
return hostList
}
func removeFromRKENodes(nodeToRemove v3.RKEConfigNode, nodeList []v3.RKEConfigNode) []v3.RKEConfigNode {
for i := range nodeList {
if nodeToRemove.Address == nodeList[i].Address {
return append(nodeList[:i], nodeList[i+1:]...)
}
}
return nodeList
}