ClusterManager: Implements support of remote clusters.
After this change users will be able to:
* Create cluster and add/remove servers to it
* Install apps on remote cluster
* Move already installed apps between clusters
* Apps running on server being removed will auto-migrate
to another server from that same cluster
This is achieved by:
* Installing and running minimal version of dodo on remote cluster
* Ingress-nginx is installed automatically on new clusters
* Next to nginx we run VPN client in the same pod, so that
default cluster can establish secure communication with it
* Multiple reverse proxies are configured to get to the
remote cluster service from ingress installed on default cluster.
Next steps:
* Support remote clusters in dodo apps (prototype ready)
* Clean up old cluster when moving app to the new one. Currently
old cluster keeps running app pods even though no ingress can
reach it anymore.
Change-Id: Iffc908c93416d4126a8e1c2832eae7b659cb8044
diff --git a/core/installer/cmd/app_manager.go b/core/installer/cmd/app_manager.go
index a6224a0..16ac83a 100644
--- a/core/installer/cmd/app_manager.go
+++ b/core/installer/cmd/app_manager.go
@@ -16,11 +16,13 @@
)
var appManagerFlags struct {
- sshKey string
- repoAddr string
- port int
- appRepoAddr string
- headscaleAPIAddr string
+ sshKey string
+ repoAddr string
+ port int
+ appRepoAddr string
+ headscaleAPIAddr string
+ dnsAPIAddr string
+ clusterProxyConfigPath string
}
func appManagerCmd() *cobra.Command {
@@ -58,6 +60,18 @@
"",
"",
)
+ cmd.Flags().StringVar(
+ &appManagerFlags.dnsAPIAddr,
+ "dns-api-addr",
+ "",
+ "",
+ )
+ cmd.Flags().StringVar(
+ &appManagerFlags.clusterProxyConfigPath,
+ "cluster-proxy-config-path",
+ "",
+ "",
+ )
return cmd
}
@@ -92,8 +106,15 @@
return err
}
hf := installer.NewGitHelmFetcher()
- vpnKeyGen := installer.NewHeadscaleAPIClient(appManagerFlags.headscaleAPIAddr)
- m, err := installer.NewAppManager(repoIO, nsc, jc, hf, vpnKeyGen, "/apps")
+ vpnAPIClient := installer.NewHeadscaleAPIClient(appManagerFlags.headscaleAPIAddr)
+ cnc := &installer.NginxProxyConfigurator{
+ // TODO(gio): read from env config
+ PrivateSubdomain: "p",
+ DNSAPIAddr: appManagerFlags.dnsAPIAddr,
+ Repo: repoIO,
+ NginxConfigPath: appManagerFlags.clusterProxyConfigPath,
+ }
+ m, err := installer.NewAppManager(repoIO, nsc, jc, hf, vpnAPIClient, cnc, "/apps")
if err != nil {
return err
}
@@ -117,16 +138,21 @@
} else {
r = installer.NewInMemoryAppRepository(installer.CreateStoreApps())
}
+ fr := installer.NewInMemoryAppRepository(installer.CreateAllEnvApps())
helmMon, err := newHelmReleaseMonitor()
if err != nil {
return err
}
s, err := welcome.NewAppManagerServer(
appManagerFlags.port,
+ repoIO,
m,
r,
+ fr,
tasks.NewFixedReconciler(env.Id, env.Id),
helmMon,
+ cnc,
+ vpnAPIClient,
)
if err != nil {
return err
diff --git a/core/installer/cmd/dodo_app.go b/core/installer/cmd/dodo_app.go
index 2fe1697..8512691 100644
--- a/core/installer/cmd/dodo_app.go
+++ b/core/installer/cmd/dodo_app.go
@@ -201,6 +201,8 @@
},
}
vpnKeyGen := installer.NewHeadscaleAPIClient(dodoAppFlags.headscaleAPIAddr)
+ // TOOD(gio): implement
+ var cnc installer.ClusterNetworkConfigurator
s, err := welcome.NewDodoAppServer(
st,
nf,
@@ -217,6 +219,7 @@
nsc,
jc,
vpnKeyGen,
+ cnc,
env,
dodoAppFlags.external,
dodoAppFlags.fetchUsersAddr,
diff --git a/core/installer/cmd/kube.go b/core/installer/cmd/kube.go
index f31ad8f..1a74731 100644
--- a/core/installer/cmd/kube.go
+++ b/core/installer/cmd/kube.go
@@ -2,10 +2,13 @@
import (
"github.com/giolekva/pcloud/core/installer"
+ "github.com/giolekva/pcloud/core/installer/kube"
)
func newNSCreator() (installer.NamespaceCreator, error) {
- return installer.NewNamespaceCreator(rootFlags.kubeConfig)
+ return installer.NewNamespaceCreator(kube.KubeConfigOpts{
+ KubeConfigPath: rootFlags.kubeConfig,
+ })
}
func newZoneFetcher() (installer.ZoneStatusFetcher, error) {
@@ -17,7 +20,9 @@
}
func newJobCreator() (installer.JobCreator, error) {
- clientset, err := installer.NewKubeConfig(rootFlags.kubeConfig)
+ clientset, err := kube.NewKubeClient(kube.KubeConfigOpts{
+ KubeConfigPath: rootFlags.kubeConfig,
+ })
if err != nil {
return nil, err
}
diff --git a/core/installer/cmd/launcher.go b/core/installer/cmd/launcher.go
index e671fe6..85e811f 100644
--- a/core/installer/cmd/launcher.go
+++ b/core/installer/cmd/launcher.go
@@ -74,7 +74,7 @@
if err != nil {
return err
}
- appManager, err := installer.NewAppManager(repoIO, nil, nil, nil, nil, "/apps")
+ appManager, err := installer.NewAppManager(repoIO, nil, nil, nil, nil, nil, "/apps")
if err != nil {
return err
}
diff --git a/core/installer/cmd/rewrite.go b/core/installer/cmd/rewrite.go
index 3e2961b..0f018e4 100644
--- a/core/installer/cmd/rewrite.go
+++ b/core/installer/cmd/rewrite.go
@@ -1,7 +1,6 @@
package main
import (
- "fmt"
"log"
"os"
@@ -62,16 +61,7 @@
log.Println("Creating repository")
r := installer.NewInMemoryAppRepository(installer.CreateAllApps())
hf := installer.NewGitHelmFetcher()
- mgr, err := installer.NewAppManager(repoIO, nil, nil, hf, nil, "/apps")
- if err != nil {
- return err
- }
- env, err := mgr.Config()
- if err != nil {
- return err
- }
- fmt.Printf("%+v\n", env)
- log.Println("Read config")
+ mgr, err := installer.NewAppManager(repoIO, nil, nil, hf, nil, nil, "/apps")
if err != nil {
return err
}