Skip to content

Commit ca6dffa

Browse files
committed
Support multicluster control plane
Signed-off-by: Tamal Saha <[email protected]>
1 parent 15c91e1 commit ca6dffa

File tree

4 files changed

+146
-90
lines changed

4 files changed

+146
-90
lines changed

cmd/addon-manager/main.go

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import (
3131
"k8s.io/client-go/informers"
3232
"k8s.io/client-go/kubernetes"
3333
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
34+
"k8s.io/client-go/tools/clientcmd"
3435
"k8s.io/klog/v2"
3536
"k8s.io/klog/v2/textlogger"
3637
"open-cluster-management.io/addon-framework/pkg/addonmanager"
@@ -70,6 +71,7 @@ func main() {
7071
var signerSecretNamespace, signerSecretName string
7172
var agentInstallAll bool
7273
var enableKubeApiProxy bool
74+
var mcKubeconfig string
7375

7476
logger := textlogger.NewLogger(textlogger.NewConfig())
7577
klog.SetOutput(os.Stdout)
@@ -93,37 +95,70 @@ func main() {
9395
"Configure the install strategy of agent on managed clusters. "+
9496
"Enabling this will automatically install agent on all managed cluster.")
9597
flag.BoolVar(&enableKubeApiProxy, "enable-kube-api-proxy", true, "Enable proxy to agent kube-apiserver")
98+
flag.StringVar(&mcKubeconfig, "multicluster-kubeconfig", "",
99+
"The path to multicluster-controlplane kubeconfig")
96100

97101
flag.Parse()
98102

99103
// pipe controller-runtime logs to klog
100104
ctrl.SetLogger(logger)
101105

102-
mgr, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
106+
hostManager, err := ctrl.NewManager(ctrl.GetConfigOrDie(), ctrl.Options{
103107
Scheme: scheme,
104108
Metrics: metricsserver.Options{BindAddress: metricsAddr},
105109
HealthProbeBindAddress: probeAddr,
106110
LeaderElection: enableLeaderElection,
107111
LeaderElectionID: "cluster-proxy-addon-manager",
108112
})
109113
if err != nil {
110-
setupLog.Error(err, "unable to start manager")
114+
setupLog.Error(err, "unable to create host manager")
111115
os.Exit(1)
112116
}
113117

114-
nativeClient, err := kubernetes.NewForConfig(mgr.GetConfig())
118+
hostNativeClient, err := kubernetes.NewForConfig(hostManager.GetConfig())
115119
if err != nil {
116120
setupLog.Error(err, "unable to set up kubernetes native client")
117121
os.Exit(1)
118122
}
119123

120-
addonClient, err := addonclient.NewForConfig(mgr.GetConfig())
124+
mcMode := mcKubeconfig != ""
125+
var mcManager ctrl.Manager
126+
var mcNativeClient kubernetes.Interface
127+
if mcMode {
128+
mcConfig, err := clientcmd.BuildConfigFromFlags("", mcKubeconfig)
129+
if err != nil {
130+
setupLog.Error(err, "unable to build multicluster rest config")
131+
os.Exit(1)
132+
}
133+
mcManager, err = ctrl.NewManager(mcConfig, ctrl.Options{
134+
Scheme: scheme,
135+
Metrics: metricsserver.Options{BindAddress: ""},
136+
HealthProbeBindAddress: "",
137+
LeaderElection: enableLeaderElection,
138+
LeaderElectionID: "cluster-proxy-addon-manager",
139+
})
140+
if err != nil {
141+
setupLog.Error(err, "unable to create mc manager")
142+
os.Exit(1)
143+
}
144+
145+
mcNativeClient, err = kubernetes.NewForConfig(mcManager.GetConfig())
146+
if err != nil {
147+
setupLog.Error(err, "unable to set up multicluster native client")
148+
os.Exit(1)
149+
}
150+
} else {
151+
mcManager = hostManager
152+
mcNativeClient = hostNativeClient
153+
}
154+
155+
addonClient, err := addonclient.NewForConfig(mcManager.GetConfig())
121156
if err != nil {
122157
setupLog.Error(err, "unable to set up ocm addon client")
123158
os.Exit(1)
124159
}
125160

126-
supportsV1CSR, supportsV1beta1CSR, err := addonutil.IsCSRSupported(nativeClient)
161+
supportsV1CSR, supportsV1beta1CSR, err := addonutil.IsCSRSupported(mcNativeClient)
127162
if err != nil {
128163
setupLog.Error(err, "unable to detect available CSR API versions")
129164
os.Exit(1)
@@ -138,43 +173,45 @@ func main() {
138173
os.Exit(1)
139174
}
140175

141-
nativeInformer := informers.NewSharedInformerFactoryWithOptions(nativeClient, 0)
176+
hostNativeInformer := informers.NewSharedInformerFactoryWithOptions(hostNativeClient, 0)
142177

143178
// loading self-signer
144179
selfSigner, err := selfsigned.NewSelfSignerFromSecretOrGenerate(
145-
nativeClient, signerSecretNamespace, signerSecretName)
180+
hostNativeClient, signerSecretNamespace, signerSecretName)
146181
if err != nil {
147182
setupLog.Error(err, "failed loading self-signer")
148183
os.Exit(1)
149184
}
150185

151186
if err := controllers.RegisterClusterManagementAddonReconciler(
152-
mgr,
187+
hostManager,
153188
selfSigner,
154-
nativeClient,
155-
nativeInformer.Core().V1().Secrets(),
189+
hostNativeClient,
190+
hostNativeInformer.Core().V1().Secrets(),
191+
mcManager,
192+
mcMode,
156193
supportsV1CSR,
157194
); err != nil {
158195
setupLog.Error(err, "unable to create controller", "controller", "ClusterManagementAddonReconciler")
159196
os.Exit(1)
160197
}
161198

162-
if err := controllers.RegisterServiceResolverReconciler(mgr); err != nil {
199+
if err := controllers.RegisterServiceResolverReconciler(mcManager); err != nil {
163200
setupLog.Error(err, "unable to create controller", "controller", "ServiceResolverReconciler")
164201
os.Exit(1)
165202
}
166203

167204
//+kubebuilder:scaffold:builder
168-
if err := mgr.AddHealthzCheck("healthz", healthz.Ping); err != nil {
205+
if err := hostManager.AddHealthzCheck("healthz", healthz.Ping); err != nil {
169206
setupLog.Error(err, "unable to set up health check")
170207
os.Exit(1)
171208
}
172-
if err := mgr.AddReadyzCheck("readyz", healthz.Ping); err != nil {
209+
if err := hostManager.AddReadyzCheck("readyz", healthz.Ping); err != nil {
173210
setupLog.Error(err, "unable to set up ready check")
174211
os.Exit(1)
175212
}
176213

177-
addonManager, err := addonmanager.New(mgr.GetConfig())
214+
addonManager, err := addonmanager.New(mcManager.GetConfig())
178215
if err != nil {
179216
setupLog.Error(err, "unable to set up ready check")
180217
os.Exit(1)
@@ -184,8 +221,9 @@ func main() {
184221
selfSigner,
185222
signerSecretNamespace,
186223
supportsV1CSR,
187-
mgr.GetClient(),
188-
nativeClient,
224+
mcManager.GetClient(),
225+
mcNativeClient,
226+
hostNativeClient,
189227
agentInstallAll,
190228
enableKubeApiProxy,
191229
addonClient,
@@ -202,16 +240,19 @@ func main() {
202240

203241
ctx, cancel := context.WithCancel(ctrl.SetupSignalHandler())
204242
defer cancel()
205-
go nativeInformer.Start(ctx.Done())
243+
go hostNativeInformer.Start(ctx.Done())
206244
go func() {
207245
if err := addonManager.Start(ctx); err != nil {
208246
setupLog.Error(err, "unable to start addon manager")
209247
os.Exit(1)
210248
}
211249
}()
212-
setupLog.Info("starting manager")
213-
if err := mgr.Start(ctx); err != nil {
214-
setupLog.Error(err, "problem running manager")
250+
if mcMode {
251+
go mcManager.Start(ctx)
252+
}
253+
setupLog.Info("starting host manager")
254+
if err := hostManager.Start(ctx); err != nil {
255+
setupLog.Error(err, "problem running host manager")
215256
os.Exit(1)
216257
}
217258
}

pkg/proxyagent/agent/agent.go

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -51,8 +51,9 @@ func NewAgentAddon(
5151
signer selfsigned.SelfSigner,
5252
signerNamespace string,
5353
v1CSRSupported bool,
54-
runtimeClient client.Client,
55-
nativeClient kubernetes.Interface,
54+
mcRtc client.Client,
55+
mcNativeClient kubernetes.Interface,
56+
hostNativeClient kubernetes.Interface,
5657
agentInstallAll bool,
5758
enableKubeApiProxy bool,
5859
addonClient addonclient.Interface) (agent.AgentAddon, error) {
@@ -93,7 +94,7 @@ func NewAgentAddon(
9394
CSRApproveCheck: func(cluster *clusterv1.ManagedCluster, addon *addonv1alpha1.ManagedClusterAddOn, csr *csrv1.CertificateSigningRequest) bool {
9495
return cluster.Spec.HubAcceptsClient
9596
},
96-
PermissionConfig: utils.NewRBACPermissionConfigBuilder(nativeClient).
97+
PermissionConfig: utils.NewRBACPermissionConfigBuilder(mcNativeClient).
9798
WithStaticRole(&rbacv1.Role{
9899
ObjectMeta: metav1.ObjectMeta{
99100
Name: "cluster-proxy-addon-agent",
@@ -134,7 +135,7 @@ func NewAgentAddon(
134135
utils.AddOnDeploymentConfigGVR,
135136
).
136137
WithGetValuesFuncs(
137-
GetClusterProxyValueFunc(runtimeClient, nativeClient, signerNamespace, caCertData, v1CSRSupported, enableKubeApiProxy),
138+
GetClusterProxyValueFunc(mcRtc, hostNativeClient, signerNamespace, caCertData, v1CSRSupported, enableKubeApiProxy),
138139
addonfactory.GetAddOnDeploymentConfigValues(
139140
utils.NewAddOnDeploymentConfigGetter(addonClient),
140141
toAgentAddOnChartValues(caCertData),
@@ -149,8 +150,8 @@ func NewAgentAddon(
149150
}
150151

151152
func GetClusterProxyValueFunc(
152-
runtimeClient client.Client,
153-
nativeClient kubernetes.Interface,
153+
mcRtc client.Client,
154+
hostNativeClient kubernetes.Interface,
154155
signerNamespace string,
155156
caCertData []byte,
156157
v1CSRSupported bool,
@@ -173,7 +174,7 @@ func GetClusterProxyValueFunc(
173174
}
174175

175176
proxyConfig := &proxyv1alpha1.ManagedProxyConfiguration{}
176-
if err := runtimeClient.Get(context.TODO(), types.NamespacedName{
177+
if err := mcRtc.Get(context.TODO(), types.NamespacedName{
177178
Name: managedProxyConfigurations[0],
178179
}, proxyConfig); err != nil {
179180
return nil, err
@@ -188,7 +189,7 @@ func GetClusterProxyValueFunc(
188189
// find the referenced proxy load-balancer prescribed in the proxy config if there's any
189190
var proxyServerLoadBalancer *corev1.Service
190191
if proxyConfig.Spec.ProxyServer.Entrypoint.Type == proxyv1alpha1.EntryPointTypeLoadBalancerService {
191-
entrySvc, err := nativeClient.CoreV1().
192+
entrySvc, err := hostNativeClient.CoreV1().
192193
Services(proxyConfig.Spec.ProxyServer.Namespace).
193194
Get(context.TODO(),
194195
proxyConfig.Spec.ProxyServer.Entrypoint.LoadBalancerService.Name,
@@ -228,7 +229,7 @@ func GetClusterProxyValueFunc(
228229
// "agent-client" to the managed clusters.
229230
certDataBase64, keyDataBase64 := "", ""
230231
if !v1CSRSupported {
231-
agentClientSecret, err := nativeClient.CoreV1().
232+
agentClientSecret, err := hostNativeClient.CoreV1().
232233
Secrets(signerNamespace).
233234
Get(context.TODO(), common.AgentClientSecretName, metav1.GetOptions{})
234235
if err != nil {
@@ -249,7 +250,7 @@ func GetClusterProxyValueFunc(
249250

250251
// List all available managedClusterSets
251252
managedClusterSetList := &clusterv1beta2.ManagedClusterSetList{}
252-
err = runtimeClient.List(context.TODO(), managedClusterSetList)
253+
err = mcRtc.List(context.TODO(), managedClusterSetList)
253254
if err != nil {
254255
return nil, err
255256
}
@@ -261,7 +262,7 @@ func GetClusterProxyValueFunc(
261262

262263
// List all available serviceResolvers
263264
serviceResolverList := &proxyv1alpha1.ManagedProxyServiceResolverList{}
264-
err = runtimeClient.List(context.TODO(), serviceResolverList)
265+
err = mcRtc.List(context.TODO(), serviceResolverList)
265266
if err != nil {
266267
return nil, err
267268
}

0 commit comments

Comments
 (0)