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:
parent
5ed42880e4
commit
8685523038
@ -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
|
||||||
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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, "")
|
||||||
}
|
}
|
||||||
|
24
cmd/up.go
24
cmd/up.go
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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
21
hosts/local.go
Normal 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
|
||||||
|
}
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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 {
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user