1
0
mirror of https://github.com/rancher/rke.git synced 2025-08-19 15:27:35 +00:00

Add local option to deploy/remove kubernetes on local machine

Remove insecure port from kube-api

Use cluster.yml config

Pass config dir to cluster up/remove
This commit is contained in:
galal-hussein 2017-12-22 03:01:53 +02:00
parent 5ed42880e4
commit 8685523038
9 changed files with 113 additions and 29 deletions

View File

@ -52,6 +52,9 @@ const (
KubeDNSAutoScalerImage = "kubedns_autoscaler_image" KubeDNSAutoScalerImage = "kubedns_autoscaler_image"
ServiceSidekickImage = "service_sidekick_image" ServiceSidekickImage = "service_sidekick_image"
NoneAuthorizationMode = "none" NoneAuthorizationMode = "none"
LocalNodeAddress = "127.0.0.1"
LocalNodeHostname = "localhost"
LocalNodeUser = "root"
) )
func (c *Cluster) DeployControlPlane(ctx context.Context) error { func (c *Cluster) DeployControlPlane(ctx context.Context) error {
@ -97,7 +100,12 @@ func ParseConfig(clusterFile string) (*v3.RancherKubernetesEngineConfig, error)
return &rkeConfig, nil return &rkeConfig, nil
} }
func ParseCluster(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig, clusterFilePath string, dockerDialerFactory, localConnDialerFactory hosts.DialerFactory) (*Cluster, error) { func ParseCluster(
ctx context.Context,
rkeConfig *v3.RancherKubernetesEngineConfig,
clusterFilePath, configDir string,
dockerDialerFactory,
localConnDialerFactory hosts.DialerFactory) (*Cluster, error) {
var err error var err error
c := &Cluster{ c := &Cluster{
RancherKubernetesEngineConfig: *rkeConfig, RancherKubernetesEngineConfig: *rkeConfig,
@ -126,7 +134,7 @@ func ParseCluster(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConf
if len(c.ConfigPath) == 0 { if len(c.ConfigPath) == 0 {
c.ConfigPath = DefaultClusterConfig c.ConfigPath = DefaultClusterConfig
} }
c.LocalKubeConfigPath = GetLocalKubeConfig(c.ConfigPath) c.LocalKubeConfigPath = GetLocalKubeConfig(c.ConfigPath, configDir)
return c, nil return c, nil
} }
@ -199,8 +207,11 @@ func (c *Cluster) setClusterImageDefaults() {
} }
} }
func GetLocalKubeConfig(configPath string) string { func GetLocalKubeConfig(configPath, configDir string) string {
baseDir := filepath.Dir(configPath) baseDir := filepath.Dir(configPath)
if len(configDir) > 0 {
baseDir = filepath.Dir(configDir)
}
fileName := filepath.Base(configPath) fileName := filepath.Base(configPath)
baseDir += "/" baseDir += "/"
return fmt.Sprintf("%s%s%s", baseDir, pki.KubeAdminConfigPrefix, fileName) return fmt.Sprintf("%s%s%s", baseDir, pki.KubeAdminConfigPrefix, fileName)
@ -287,3 +298,13 @@ func (c *Cluster) ApplyAuthzResources(ctx context.Context) error {
} }
return nil return nil
} }
func GetLocalRKENodeConfig() *v3.RKEConfigNode {
rkeLocalNode := &v3.RKEConfigNode{
Address: LocalNodeAddress,
HostnameOverride: LocalNodeHostname,
User: LocalNodeUser,
Role: []string{services.ControlRole, services.WorkerRole, services.ETCDRole},
}
return rkeLocalNode
}

View File

@ -12,7 +12,13 @@ import (
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
func (c *Cluster) TunnelHosts(ctx context.Context) error { func (c *Cluster) TunnelHosts(ctx context.Context, local bool) error {
if local {
if err := c.EtcdHosts[0].TunnelUpLocal(ctx); err != nil {
return fmt.Errorf("Failed to connect to docker for local host [%s]: %v", c.EtcdHosts[0].Address, err)
}
return nil
}
for i := range c.EtcdHosts { for i := range c.EtcdHosts {
if err := c.EtcdHosts[i].TunnelUp(ctx, c.DockerDialerFactory); err != nil { if err := c.EtcdHosts[i].TunnelUp(ctx, c.DockerDialerFactory); err != nil {
return fmt.Errorf("Failed to set up SSH tunneling for Etcd host [%s]: %v", c.EtcdHosts[i].Address, err) return fmt.Errorf("Failed to set up SSH tunneling for Etcd host [%s]: %v", c.EtcdHosts[i].Address, err)

View File

@ -27,6 +27,10 @@ func RemoveCommand() cli.Command {
Name: "force", Name: "force",
Usage: "Force removal of the cluster", Usage: "Force removal of the cluster",
}, },
cli.BoolFlag{
Name: "local",
Usage: "Deploy Kubernetes cluster locally",
},
} }
return cli.Command{ return cli.Command{
Name: "remove", Name: "remove",
@ -36,14 +40,19 @@ func RemoveCommand() cli.Command {
} }
} }
func ClusterRemove(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig, dialerFactory hosts.DialerFactory) error { func ClusterRemove(
log.Infof(ctx, "Tearing down Kubernetes cluster") ctx context.Context,
kubeCluster, err := cluster.ParseCluster(ctx, rkeConfig, clusterFilePath, dialerFactory, nil) rkeConfig *v3.RancherKubernetesEngineConfig,
dialerFactory hosts.DialerFactory,
local bool, configDir string) error {
logrus.Infof("Tearing down Kubernetes cluster")
kubeCluster, err := cluster.ParseCluster(ctx, rkeConfig, clusterFilePath, configDir, dialerFactory, nil)
if err != nil { if err != nil {
return err return err
} }
err = kubeCluster.TunnelHosts(ctx) err = kubeCluster.TunnelHosts(ctx, local)
if err != nil { if err != nil {
return err return err
} }
@ -59,6 +68,7 @@ func ClusterRemove(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineCon
} }
func clusterRemoveFromCli(ctx *cli.Context) error { func clusterRemoveFromCli(ctx *cli.Context) error {
var local bool
force := ctx.Bool("force") force := ctx.Bool("force")
if !force { if !force {
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
@ -77,10 +87,13 @@ func clusterRemoveFromCli(ctx *cli.Context) error {
return fmt.Errorf("Failed to resolve cluster file: %v", err) return fmt.Errorf("Failed to resolve cluster file: %v", err)
} }
clusterFilePath = filePath clusterFilePath = filePath
rkeConfig, err := cluster.ParseConfig(clusterFile) rkeConfig, err := cluster.ParseConfig(clusterFile)
if err != nil { if err != nil {
return fmt.Errorf("Failed to parse cluster file: %v", err) return fmt.Errorf("Failed to parse cluster file: %v", err)
} }
return ClusterRemove(context.Background(), rkeConfig, nil) if ctx.Bool("local") {
rkeConfig.Nodes = []v3.RKEConfigNode{*cluster.GetLocalRKENodeConfig()}
local = true
}
return ClusterRemove(context.Background(), rkeConfig, nil, local, "")
} }

View File

@ -23,6 +23,10 @@ func UpCommand() cli.Command {
Value: cluster.DefaultClusterConfig, Value: cluster.DefaultClusterConfig,
EnvVar: "RKE_CONFIG", EnvVar: "RKE_CONFIG",
}, },
cli.BoolFlag{
Name: "local",
Usage: "Deploy Kubernetes cluster locally",
},
} }
return cli.Command{ return cli.Command{
Name: "up", Name: "up",
@ -32,15 +36,20 @@ func UpCommand() cli.Command {
} }
} }
func ClusterUp(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig, dockerDialerFactory, localConnDialerFactory hosts.DialerFactory) (string, string, string, string, error) { func ClusterUp(
ctx context.Context,
rkeConfig *v3.RancherKubernetesEngineConfig,
dockerDialerFactory, localConnDialerFactory hosts.DialerFactory,
local bool, configDir string) (string, string, string, string, error) {
log.Infof(ctx, "Building Kubernetes cluster") log.Infof(ctx, "Building Kubernetes cluster")
var APIURL, caCrt, clientCert, clientKey string var APIURL, caCrt, clientCert, clientKey string
kubeCluster, err := cluster.ParseCluster(ctx, rkeConfig, clusterFilePath, dockerDialerFactory, localConnDialerFactory) kubeCluster, err := cluster.ParseCluster(ctx, rkeConfig, clusterFilePath, configDir, dockerDialerFactory, localConnDialerFactory)
if err != nil { if err != nil {
return APIURL, caCrt, clientCert, clientKey, err return APIURL, caCrt, clientCert, clientKey, err
} }
err = kubeCluster.TunnelHosts(ctx) err = kubeCluster.TunnelHosts(ctx, local)
if err != nil { if err != nil {
return APIURL, caCrt, clientCert, clientKey, err return APIURL, caCrt, clientCert, clientKey, err
} }
@ -105,6 +114,8 @@ func ClusterUp(ctx context.Context, rkeConfig *v3.RancherKubernetesEngineConfig,
} }
func clusterUpFromCli(ctx *cli.Context) error { func clusterUpFromCli(ctx *cli.Context) error {
var local bool
var localConnDialerFactory hosts.DialerFactory
clusterFile, filePath, err := resolveClusterFile(ctx) clusterFile, filePath, err := resolveClusterFile(ctx)
if err != nil { if err != nil {
return fmt.Errorf("Failed to resolve cluster file: %v", err) return fmt.Errorf("Failed to resolve cluster file: %v", err)
@ -115,6 +126,11 @@ func clusterUpFromCli(ctx *cli.Context) error {
if err != nil { if err != nil {
return fmt.Errorf("Failed to parse cluster file: %v", err) return fmt.Errorf("Failed to parse cluster file: %v", err)
} }
_, _, _, _, err = ClusterUp(context.Background(), rkeConfig, nil, nil) if ctx.Bool("local") {
rkeConfig.Nodes = []v3.RKEConfigNode{*cluster.GetLocalRKENodeConfig()}
localConnDialerFactory = hosts.LocalHealthcheckFactory
local = true
}
_, _, _, _, err = ClusterUp(context.Background(), rkeConfig, nil, localConnDialerFactory, local, "")
return err return err
} }

View File

@ -25,7 +25,7 @@ func VersionCommand() cli.Command {
} }
func getClusterVersion(ctx *cli.Context) error { func getClusterVersion(ctx *cli.Context) error {
localKubeConfig := cluster.GetLocalKubeConfig(ctx.String("config")) localKubeConfig := cluster.GetLocalKubeConfig(ctx.String("config"), "")
serverVersion, err := cluster.GetK8sVersion(localKubeConfig) serverVersion, err := cluster.GetK8sVersion(localKubeConfig)
if err != nil { if err != nil {
return err return err

21
hosts/local.go Normal file
View File

@ -0,0 +1,21 @@
package hosts
import (
"fmt"
"net"
)
func LocalHealthcheckFactory(h *Host) (func(network, address string) (net.Conn, error), error) {
dialer := &dialer{
host: h,
}
return dialer.DialHealthcheckLocally, nil
}
func (d *dialer) DialHealthcheckLocally(network, addr string) (net.Conn, error) {
conn, err := net.Dial("tcp", fmt.Sprintf("localhost:%d", d.host.LocalConnPort))
if err != nil {
return nil, fmt.Errorf("Failed to dial address [%s]: %v", d.host.Address, err)
}
return conn, err
}

View File

@ -31,13 +31,30 @@ func (h *Host) TunnelUp(ctx context.Context, dialerFactory DialerFactory) error
if err != nil { if err != nil {
return fmt.Errorf("Can't establish dialer connection: %v", err) return fmt.Errorf("Can't establish dialer connection: %v", err)
} }
// set Docker client // set Docker client
logrus.Debugf("Connecting to Docker API for host [%s]", h.Address) logrus.Debugf("Connecting to Docker API for host [%s]", h.Address)
h.DClient, err = client.NewClient("unix:///var/run/docker.sock", DockerAPIVersion, httpClient, nil) h.DClient, err = client.NewClient("unix:///var/run/docker.sock", DockerAPIVersion, httpClient, nil)
if err != nil { if err != nil {
return fmt.Errorf("Can't initiate NewClient: %v", err) return fmt.Errorf("Can't initiate NewClient: %v", err)
} }
return checkDockerVersion(ctx, h)
}
func (h *Host) TunnelUpLocal(ctx context.Context) error {
var err error
if h.DClient != nil {
return nil
}
// set Docker client
logrus.Debugf("Connecting to Docker API for host [%s]", h.Address)
h.DClient, err = client.NewEnvClient()
if err != nil {
return fmt.Errorf("Can't initiate NewClient: %v", err)
}
return checkDockerVersion(ctx, h)
}
func checkDockerVersion(ctx context.Context, h *Host) error {
info, err := h.DClient.Info(ctx) info, err := h.DClient.Info(ctx)
if err != nil { if err != nil {
return fmt.Errorf("Can't retrieve Docker Info: %v", err) return fmt.Errorf("Can't retrieve Docker Info: %v", err)
@ -53,7 +70,6 @@ func (h *Host) TunnelUp(ctx context.Context, dialerFactory DialerFactory) error
} else if !isvalid { } else if !isvalid {
log.Warnf(ctx, "Unsupported Docker version found [%s], supported versions are %v", info.ServerVersion, docker.K8sDockerVersions[K8sVersion]) log.Warnf(ctx, "Unsupported Docker version found [%s], supported versions are %v", info.ServerVersion, docker.K8sDockerVersions[K8sVersion])
} }
return nil return nil
} }

View File

@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"github.com/docker/docker/api/types/container" "github.com/docker/docker/api/types/container"
"github.com/docker/go-connections/nat"
"github.com/rancher/rke/docker" "github.com/rancher/rke/docker"
"github.com/rancher/rke/hosts" "github.com/rancher/rke/hosts"
"github.com/rancher/rke/pki" "github.com/rancher/rke/pki"
@ -18,7 +17,7 @@ func runKubeAPI(ctx context.Context, host *hosts.Host, etcdHosts []*hosts.Host,
if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole); err != nil { if err := docker.DoRunContainer(ctx, host.DClient, imageCfg, hostCfg, KubeAPIContainerName, host.Address, ControlRole); err != nil {
return err return err
} }
return runHealthcheck(ctx, host, KubeAPIPort, false, KubeAPIContainerName, df) return runHealthcheck(ctx, host, KubeAPIPort, true, KubeAPIContainerName, df)
} }
func removeKubeAPI(ctx context.Context, host *hosts.Host) error { func removeKubeAPI(ctx context.Context, host *hosts.Host) error {
@ -32,7 +31,7 @@ func buildKubeAPIConfig(host *hosts.Host, kubeAPIService v3.KubeAPIService, etcd
"kube-apiserver", "kube-apiserver",
"--insecure-bind-address=127.0.0.1", "--insecure-bind-address=127.0.0.1",
"--bind-address=0.0.0.0", "--bind-address=0.0.0.0",
"--insecure-port=8080", "--insecure-port=0",
"--secure-port=6443", "--secure-port=6443",
"--cloud-provider=", "--cloud-provider=",
"--allow_privileged=true", "--allow_privileged=true",
@ -63,14 +62,6 @@ func buildKubeAPIConfig(host *hosts.Host, kubeAPIService v3.KubeAPIService, etcd
}, },
NetworkMode: "host", NetworkMode: "host",
RestartPolicy: container.RestartPolicy{Name: "always"}, RestartPolicy: container.RestartPolicy{Name: "always"},
PortBindings: nat.PortMap{
"8080/tcp": []nat.PortBinding{
{
HostIP: "0.0.0.0",
HostPort: "8080",
},
},
},
} }
for arg, value := range kubeAPIService.ExtraArgs { for arg, value := range kubeAPIService.ExtraArgs {

View File

@ -28,7 +28,7 @@ const (
NginxProxyContainerName = "nginx-proxy" NginxProxyContainerName = "nginx-proxy"
SidekickContainerName = "service-sidekick" SidekickContainerName = "service-sidekick"
KubeAPIPort = 8080 KubeAPIPort = 6443
SchedulerPort = 10251 SchedulerPort = 10251
KubeControllerPort = 10252 KubeControllerPort = 10252
KubeletPort = 10250 KubeletPort = 10250