Skip to content

Commit

Permalink
Structure and config changes
Browse files Browse the repository at this point in the history
  • Loading branch information
galal-hussein committed Nov 28, 2017
1 parent c77d3b5 commit 41c4887
Show file tree
Hide file tree
Showing 22 changed files with 256 additions and 136 deletions.
16 changes: 8 additions & 8 deletions cluster.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,18 @@ network:
options:
foo: bar

hosts:
- advertised_hostname: server1
ip: 1.1.1.1
nodes:
- address: 1.1.1.1
user: ubuntu
role: [controlplane, etcd]
docker_socket: /var/run/docker.sock
advertise_address: 10.1.1.1
- advertised_hostname: server2
ip: 2.2.2.2
- address: 2.2.2.2
user: ubuntu
role: [worker]
advertise_address: 10.2.2.2
- address: example.com
user: ubuntu
role: [worker]
hostname_override: node3
internal_address: 192.168.1.6

services:
etcd:
Expand Down
2 changes: 1 addition & 1 deletion cluster/addons.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (c *Cluster) doAddonDeploy(addonYaml, resourceName string) error {

logrus.Infof("[addons] Executing deploy job..")

addonJob := addons.GetAddonsExcuteJob(resourceName, c.ControlPlaneHosts[0].AdvertisedHostname, c.Services.KubeAPI.Image)
addonJob := addons.GetAddonsExcuteJob(resourceName, c.ControlPlaneHosts[0].HostnameOverride, c.Services.KubeAPI.Image)
err = c.ApplySystemAddonExcuteJob(addonJob)
if err != nil {
return fmt.Errorf("Failed to deploy addon execute job: %v", err)
Expand Down
83 changes: 55 additions & 28 deletions cluster/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,19 @@ type Cluster struct {
}

const (
X509AuthenticationProvider = "x509"
DefaultClusterConfig = "cluster.yml"
StateConfigMapName = "cluster-state"
UpdateStateTimeout = 30
GetStateTimeout = 30
KubernetesClientTimeOut = 30
X509AuthenticationProvider = "x509"
DefaultClusterConfig = "cluster.yml"
DefaultServiceClusterIPRange = "10.233.0.0/18"
DefaultClusterCIDR = "10.233.64.0/18"
DefaultClusterDNSService = "10.233.0.3"
DefaultClusterDomain = "cluster.local"
DefaultInfraContainerImage = "gcr.io/google_containers/pause-amd64:3.0"
DefaultAuthStrategy = "x509"
DefaultNetworkPlugin = "flannel"
StateConfigMapName = "cluster-state"
UpdateStateTimeout = 30
GetStateTimeout = 30
KubernetesClientTimeOut = 30
)

func (c *Cluster) DeployClusterPlanes() error {
Expand Down Expand Up @@ -96,26 +103,46 @@ func parseClusterFile(clusterFile string) (*Cluster, error) {
if err != nil {
return nil, err
}
for i, host := range kubeCluster.Hosts {
if len(host.AdvertisedHostname) == 0 {
return nil, fmt.Errorf("Hostname for host (%d) is not provided", i+1)
} else if len(host.User) == 0 {
return nil, fmt.Errorf("User for host (%d) is not provided", i+1)
} else if len(host.Role) == 0 {
return nil, fmt.Errorf("Role for host (%d) is not provided", i+1)

} else if host.AdvertiseAddress == "" {
// if control_plane_ip is not set,
// default to the main IP
kubeCluster.Hosts[i].AdvertiseAddress = host.IP
// Setting cluster Defaults
kubeCluster.setClusterDefaults()

return &kubeCluster, nil
}

func (c *Cluster) setClusterDefaults() {
for i, host := range c.Nodes {
if len(host.InternalAddress) == 0 {
c.Nodes[i].InternalAddress = c.Nodes[i].Address
}
for _, role := range host.Role {
if role != services.ETCDRole && role != services.ControlRole && role != services.WorkerRole {
return nil, fmt.Errorf("Role [%s] for host (%d) is not recognized", role, i+1)
}
if len(host.HostnameOverride) == 0 {
// This is a temporary modification
c.Nodes[i].HostnameOverride = c.Nodes[i].Address
}
}
return &kubeCluster, nil
if len(c.Services.KubeAPI.ServiceClusterIPRange) == 0 {
c.Services.KubeAPI.ServiceClusterIPRange = DefaultServiceClusterIPRange
}
if len(c.Services.KubeController.ServiceClusterIPRange) == 0 {
c.Services.KubeController.ServiceClusterIPRange = DefaultServiceClusterIPRange
}
if len(c.Services.KubeController.ClusterCIDR) == 0 {
c.Services.KubeController.ClusterCIDR = DefaultClusterCIDR
}
if len(c.Services.Kubelet.ClusterDNSServer) == 0 {
c.Services.Kubelet.ClusterDNSServer = DefaultClusterDNSService
}
if len(c.Services.Kubelet.ClusterDomain) == 0 {
c.Services.Kubelet.ClusterDomain = DefaultClusterDomain
}
if len(c.Services.Kubelet.InfraContainerImage) == 0 {
c.Services.Kubelet.InfraContainerImage = DefaultInfraContainerImage
}
if len(c.Authentication.Strategy) == 0 {
c.Authentication.Strategy = DefaultAuthStrategy
}
if len(c.Network.Plugin) == 0 {
c.Network.Plugin = DefaultNetworkPlugin
}
}

func GetLocalKubeConfig(configPath string) string {
Expand Down Expand Up @@ -144,11 +171,11 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error {
cpToDelete := hosts.GetToDeleteHosts(currentCluster.ControlPlaneHosts, kubeCluster.ControlPlaneHosts)
for _, toDeleteHost := range cpToDelete {
if err := hosts.DeleteNode(&toDeleteHost, kubeClient); err != nil {
return fmt.Errorf("Failed to delete controlplane node %s from cluster", toDeleteHost.AdvertisedHostname)
return fmt.Errorf("Failed to delete controlplane node %s from cluster", toDeleteHost.Address)
}
// attempting to clean up the host
if err := reconcileHostCleaner(toDeleteHost, key, false); err != nil {
logrus.Warnf("[reconcile] Couldn't clean up controlplane node [%s]: %v", toDeleteHost.AdvertisedHostname, err)
logrus.Warnf("[reconcile] Couldn't clean up controlplane node [%s]: %v", toDeleteHost.Address, err)
continue
}
}
Expand All @@ -157,11 +184,11 @@ func ReconcileCluster(kubeCluster, currentCluster *Cluster) error {
wpToDelete := hosts.GetToDeleteHosts(currentCluster.WorkerHosts, kubeCluster.WorkerHosts)
for _, toDeleteHost := range wpToDelete {
if err := hosts.DeleteNode(&toDeleteHost, kubeClient); err != nil {
return fmt.Errorf("Failed to delete worker node %s from cluster", toDeleteHost.AdvertisedHostname)
return fmt.Errorf("Failed to delete worker node %s from cluster", toDeleteHost.Address)
}
// attempting to clean up the host
if err := reconcileHostCleaner(toDeleteHost, key, true); err != nil {
logrus.Warnf("[reconcile] Couldn't clean up worker node [%s]: %v", toDeleteHost.AdvertisedHostname, err)
logrus.Warnf("[reconcile] Couldn't clean up worker node [%s]: %v", toDeleteHost.Address, err)
continue
}
}
Expand Down Expand Up @@ -201,7 +228,7 @@ func rebuildLocalAdminConfig(kubeCluster *Cluster) error {
currentKubeConfig := kubeCluster.Certificates[pki.KubeAdminCommonName]
caCrt := kubeCluster.Certificates[pki.CACertName].Certificate
newConfig := pki.GetKubeConfigX509WithData(
"https://"+kubeCluster.ControlPlaneHosts[0].IP+":6443",
"https://"+kubeCluster.ControlPlaneHosts[0].Address+":6443",
pki.KubeAdminCommonName,
string(cert.EncodeCertPEM(caCrt)),
string(cert.EncodeCertPEM(currentKubeConfig.Certificate)),
Expand Down
8 changes: 4 additions & 4 deletions cluster/hosts.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ func (c *Cluster) InvertIndexHosts() error {
c.EtcdHosts = make([]hosts.Host, 0)
c.WorkerHosts = make([]hosts.Host, 0)
c.ControlPlaneHosts = make([]hosts.Host, 0)
for _, host := range c.Hosts {
for _, host := range c.Nodes {
for _, role := range host.Role {
logrus.Debugf("Host: " + host.AdvertisedHostname + " has role: " + role)
logrus.Debugf("Host: " + host.Address + " has role: " + role)
newHost := hosts.Host{
RKEConfigHost: host,
RKEConfigNode: host,
}
switch role {
case services.ETCDRole:
Expand All @@ -62,7 +62,7 @@ func (c *Cluster) InvertIndexHosts() error {
case services.WorkerRole:
c.WorkerHosts = append(c.WorkerHosts, newHost)
default:
return fmt.Errorf("Failed to recognize host [%s] role %s", host.AdvertisedHostname, role)
return fmt.Errorf("Failed to recognize host [%s] role %s", host.Address, role)
}
}
}
Expand Down
9 changes: 6 additions & 3 deletions cluster/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,19 @@ import (

const (
NetworkPluginResourceName = "rke-netwok-plugin"
FlannelNetworkPlugin = "flannel"
CalicoNetworkPlugin = "calico"
CanalNetworkPlugin = "canal"
)

func (c *Cluster) DeployNetworkPlugin() error {
logrus.Infof("[network] Setting up network plugin: %s", c.Network.Plugin)
switch c.Network.Plugin {
case "flannel":
case FlannelNetworkPlugin:
return c.doFlannelDeploy()
case "calico":
case CalicoNetworkPlugin:
return c.doCalicoDeploy()
case "canal":
case CanalNetworkPlugin:
return c.doCanalDeploy()
default:
return fmt.Errorf("[network] Unsupported network plugin: %s", c.Network.Plugin)
Expand Down
72 changes: 67 additions & 5 deletions cluster/validation.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,88 @@ package cluster
import (
"fmt"
"strings"

"github.com/rancher/rke/services"
)

func (c *Cluster) ValidateCluster() error {
// make sure cluster has at least one controlplane/etcd host
if len(c.ControlPlaneHosts) == 0 {
return fmt.Errorf("Cluster must have at least one control plane host")
}
if len(c.EtcdHosts) == 0 {
return fmt.Errorf("Cluster must have at least one etcd host")
if len(c.EtcdHosts)%2 == 0 {
return fmt.Errorf("Cluster must have odd number of etcd nodes")
}
if len(c.WorkerHosts) == 0 {
return fmt.Errorf("Cluster must have at least one worker plane host")
}

// validate hosts options
if err := validateHostsOptions(c); err != nil {
return err
}

// validate Auth options
if err := validateAuthOptions(c); err != nil {
return err
}

// validate Network options
if err := validateNetworkOptions(c); err != nil {
return err
}

// validate services options
err := validateServicesOption(c)
if err != nil {
if err := validateServicesOptions(c); err != nil {
return err
}
return nil
}

func validateServicesOption(c *Cluster) error {
func validateAuthOptions(c *Cluster) error {
if c.Authentication.Strategy != DefaultAuthStrategy {
return fmt.Errorf("Authentication strategy [%s] is not supported", c.Authentication.Strategy)
}
return nil
}

func validateNetworkOptions(c *Cluster) error {
if c.Network.Plugin != FlannelNetworkPlugin && c.Network.Plugin != CalicoNetworkPlugin && c.Network.Plugin != CanalNetworkPlugin {
return fmt.Errorf("Network plugin [%s] is not supported", c.Network.Plugin)
}
return nil
}

func validateHostsOptions(c *Cluster) error {
for i, host := range c.Nodes {
if len(host.Address) == 0 {
return fmt.Errorf("User for host (%d) is not provided", i+1)
}
if len(host.User) == 0 {
return fmt.Errorf("User for host (%d) is not provided", i+1)
}
if len(host.Role) == 0 {
return fmt.Errorf("Role for host (%d) is not provided", i+1)
}
for _, role := range host.Role {
if role != services.ETCDRole && role != services.ControlRole && role != services.WorkerRole {
return fmt.Errorf("Role [%s] for host (%d) is not recognized", role, i+1)
}
}
k := 0
for _, role := range host.Role {
if role == services.ControlRole || role == services.WorkerRole {
k++
}
}
if k > 1 {
return fmt.Errorf("Host (%d) can't contain both worker and controlplane roles", i+1)
}
}
return nil
}

func validateServicesOptions(c *Cluster) error {
servicesOptions := map[string]string{
"etcd_image": c.Services.Etcd.Image,
"kube_api_image": c.Services.KubeAPI.Image,
Expand Down
Loading

0 comments on commit 41c4887

Please sign in to comment.