365 lines
12 KiB
Go
365 lines
12 KiB
Go
/*
|
|
Copyright 2021 Alibaba Group Holding Limited.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package v1
|
|
|
|
import (
|
|
"context"
|
|
systemtaskv1controllers "github.com/alibaba/polardbx-operator/pkg/operator/v1/systemtask/controllers"
|
|
"os"
|
|
|
|
promv1 "github.com/prometheus-operator/prometheus-operator/pkg/apis/monitoring/v1"
|
|
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
|
|
|
"k8s.io/apimachinery/pkg/runtime"
|
|
"k8s.io/client-go/kubernetes"
|
|
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
|
|
ctrl "sigs.k8s.io/controller-runtime"
|
|
"sigs.k8s.io/controller-runtime/pkg/reconcile"
|
|
|
|
polardbxv1 "github.com/alibaba/polardbx-operator/api/v1"
|
|
"github.com/alibaba/polardbx-operator/pkg/k8s/control"
|
|
"github.com/alibaba/polardbx-operator/pkg/operator/hint"
|
|
"github.com/alibaba/polardbx-operator/pkg/operator/v1/config"
|
|
polardbxv1controllers "github.com/alibaba/polardbx-operator/pkg/operator/v1/polardbx/controllers"
|
|
xstorev1controllers "github.com/alibaba/polardbx-operator/pkg/operator/v1/xstore/controllers"
|
|
"github.com/alibaba/polardbx-operator/pkg/webhook"
|
|
"github.com/alibaba/polardbx-operator/pkg/webhook/polardbxcluster"
|
|
)
|
|
|
|
var (
|
|
scheme = runtime.NewScheme()
|
|
)
|
|
|
|
func initScheme() {
|
|
_ = clientgoscheme.AddToScheme(scheme)
|
|
_ = polardbxv1.AddToScheme(scheme)
|
|
_ = promv1.AddToScheme(scheme)
|
|
_ = apiextensionsv1.AddToScheme(scheme)
|
|
}
|
|
|
|
func init() {
|
|
initScheme()
|
|
}
|
|
|
|
type Options struct {
|
|
Debug bool
|
|
|
|
MetricsAddr string
|
|
ListenPort int
|
|
WebhookListenPort int
|
|
LeaderElection bool
|
|
LeaderElectionNamespace string
|
|
MaxConcurrentReconciles int
|
|
CertDir string
|
|
|
|
ConfigPath string
|
|
}
|
|
|
|
var setupLog = ctrl.Log.WithName("setup")
|
|
|
|
type controllerOptions struct {
|
|
*control.BaseReconcileContext
|
|
ctrl.Manager
|
|
config.LoaderFactory
|
|
opts *Options
|
|
}
|
|
|
|
func setupXStoreControllers(opts controllerOptions) error {
|
|
xstoreReconciler := xstorev1controllers.XStoreReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("xstore"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := xstoreReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setupXStoreFollowerControllers(opts controllerOptions) error {
|
|
xstoreFollowerReconciler := xstorev1controllers.XStoreFollowerReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("xstore_follower"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
err := xstoreFollowerReconciler.SetupWithManager(opts.Manager)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func setupPolarDBXParameterControllers(opts controllerOptions) error {
|
|
polardbxParameterReconciler := polardbxv1controllers.PolarDBXParameterReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxparameter"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
err := polardbxParameterReconciler.SetupWithManager(opts.Manager)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setupPolarDBXControllers(opts controllerOptions) error {
|
|
polardbxReconciler := polardbxv1controllers.PolarDBXReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbx"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := polardbxReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
knobsReconciler := polardbxv1controllers.PolarDBXClusterKnobsReconciler{
|
|
Client: opts.Manager.GetClient(),
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxknobs"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := knobsReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
monitorReconciler := polardbxv1controllers.PolarDBXMonitorReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
Client: opts.Manager.GetClient(),
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxmonitor"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := monitorReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
logCollectReconciler := polardbxv1controllers.PolarDBXLogCollectorReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxlogcollector"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
|
|
if err := logCollectReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
systemTaskReconciler := systemtaskv1controllers.SystemTaskReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxsystemtask"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := systemTaskReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
polardbxBackupBinlogReconciler := polardbxv1controllers.PolarDBXBackupBinlogReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxbackupbinlog"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := polardbxBackupBinlogReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
backupScheduleReconciler := polardbxv1controllers.PolarDBXBackupScheduleReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxbackupschedule"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := backupScheduleReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func setupPolarDBXBackupControllers(opts controllerOptions) error {
|
|
pxcBackupReconciler := polardbxv1controllers.PolarDBXBackupReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("polardbxbackup"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
if err := pxcBackupReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
func setupXStoreBackupControllers(opts controllerOptions) error {
|
|
xstoreBackupReconciler := xstorev1controllers.XStoreBackupReconciler{
|
|
BaseRc: opts.BaseReconcileContext,
|
|
LoaderFactory: opts.LoaderFactory,
|
|
Logger: ctrl.Log.WithName("controller").WithName("xstorebackup"),
|
|
MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
}
|
|
|
|
err := xstoreBackupReconciler.SetupWithManager(opts.Manager)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
//func setupXStoreBackupScheduleControllers(opts controllerOptions) error {
|
|
// xstoreBackupReconciler := xstorev1controllers.XStoreBackupReconciler{
|
|
// BaseRc: opts.BaseReconcileContext,
|
|
// LoaderFactory: opts.LoaderFactory,
|
|
// Logger: ctrl.Log.WithName("controller").WithName("xstorebackup"),
|
|
// MaxConcurrency: opts.opts.MaxConcurrentReconciles,
|
|
// }
|
|
// if err := xstoreBackupReconciler.SetupWithManager(opts.Manager); err != nil {
|
|
// return err
|
|
// }
|
|
// return nil
|
|
//}
|
|
|
|
// Start starts all related controllers of PolarDB-X. The first parameter ctx is used to control the
|
|
// stop of the controllers. Recommendation is to use the context returned by `ctrl.SetupSignalHandler`
|
|
// to handle signals correctly. The second parameter opts defines the configurable options of controllers.
|
|
//
|
|
// Currently, these controllers are included:
|
|
// 1. Controller for PolarDBXCluster (v1)
|
|
// 2. Controller for XStore (v1)
|
|
// 3. Controllers for PolarDBXBackup, PolarDBXBinlogBackup (v1)
|
|
// 4. Controllers for XStoreBackup, XStoreBinlogBackup (v1)
|
|
// 5. Controllers for PolarDBXBackupSchedule, PolarDBXBinlogBackupSchedule (v1)
|
|
// 6. Controllers for PolarDBXParameter (v1)
|
|
func Start(ctx context.Context, opts Options) {
|
|
// Start instruction loader.
|
|
hint.StartLoader(ctx)
|
|
|
|
// Start operator config loader.
|
|
configLoaderFactory, err := config.NewConfigLoaderAndStartBackgroundRefresh(ctx,
|
|
config.LoadFromPath(opts.ConfigPath),
|
|
config.WithLogger(ctrl.Log.WithName("config")),
|
|
)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to start operator config loader.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Get REST config.
|
|
restConfig := ctrl.GetConfigOrDie()
|
|
clientset, err := kubernetes.NewForConfig(restConfig)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to new rest config.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
// New manager.
|
|
mgr, err := ctrl.NewManager(restConfig, ctrl.Options{
|
|
Scheme: scheme,
|
|
MetricsBindAddress: opts.MetricsAddr,
|
|
Port: opts.ListenPort,
|
|
LeaderElection: opts.LeaderElection,
|
|
LeaderElectionNamespace: opts.LeaderElectionNamespace,
|
|
LeaderElectionID: "polardbx.aliyun.com",
|
|
CertDir: opts.CertDir,
|
|
})
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to new manager.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
ctrlOpts := controllerOptions{
|
|
BaseReconcileContext: control.NewBaseReconcileContext(
|
|
mgr.GetClient(),
|
|
restConfig,
|
|
clientset,
|
|
scheme,
|
|
context.Background(),
|
|
reconcile.Request{},
|
|
),
|
|
Manager: mgr,
|
|
LoaderFactory: configLoaderFactory,
|
|
opts: &opts,
|
|
}
|
|
|
|
// Setup controllers.
|
|
err = setupXStoreControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for xstore.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
err = setupXStoreFollowerControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for xstore follower.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
err = setupPolarDBXBackupControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for polardbx backup")
|
|
os.Exit(1)
|
|
}
|
|
err = setupXStoreBackupControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for xstore backup.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
err = setupPolarDBXControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for polardbx.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
err = setupPolarDBXParameterControllers(ctrlOpts)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup controllers for polardbx.")
|
|
os.Exit(1)
|
|
}
|
|
|
|
// Setup webhooks.
|
|
if opts.WebhookListenPort < 0 {
|
|
// Disable if manually specified.
|
|
setupLog.Info("Webhooks disabled, will not start!")
|
|
} else if opts.WebhookListenPort > 0 {
|
|
// Start a standalone webhook server. TLS enabled or not is dynamically determined.
|
|
err = polardbxcluster.StartStandaloneWebhookServer(ctx, mgr, opts.WebhookListenPort, opts.ConfigPath, opts.CertDir)
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to start webhook server...")
|
|
os.Exit(1)
|
|
}
|
|
} else {
|
|
// Defaults ot setup on manager.
|
|
err = webhook.SetupWebhooks(ctx, mgr, opts.ConfigPath, configLoaderFactory())
|
|
if err != nil {
|
|
setupLog.Error(err, "Unable to setup webhooks...")
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
|
|
// Start.
|
|
setupLog.Info("Starting controllers...")
|
|
if err := mgr.Start(ctx); err != nil {
|
|
setupLog.Error(err, "Unable to start controllers.")
|
|
os.Exit(1)
|
|
}
|
|
}
|