Karmada 컴포너트를 보았을 때, 다음과 같다.
Control Plane Components
Cluster registration mode에서는 karmada-agent가 선택사항일 수 있다.
Cluster Registration
Karmada는 Push와 Pull 모드를 멤버 클러스터를 관리하기 위해 지원한다.
두가지 Push와 Pull의 차이점은 매니페스트가 배포되었을때 멤버클러스터에 접근하는 방식이 다르다.
- Push mode :
멤버 클러스터의 kube-apiserver에 직접 접근하여 상태를 가져오고, 매니페스트를 배포한다.
kubectl-karmada-join을 통해 클러스터 등록한다.
- Pull mode :
멤버 클러스터에 직접 접근하지 않고 karmada-agent를 통해 접근한다.
kamadactl register를 통해 멤버 클러스터를 등록한다.
karmada-agent 역할
1) Karmada에 클러스터 등록 (Cluster 객체 생성)
2) 클러스터 상태 유지하고 Karmada에 보고
3) Karmada 실행 공간 (namespace)에서 매니페스트를 감시하고 감시된 리소스를 에이전트가 제공하는 클러스터에 배포
Push 모드는 중앙 집중형 관리와 빠른 반응 속도가 필요할 때 유리하며, 작은 수의 클러스터를 운영하거나 보안 모델을 단순하게 유지하고자 할 때 적합하다. Pull 모드는 대규모 클러스터 운영, 보안 요구 사항이 높은 환경, 확장성을 중시하는 상황에서 유리하다.
karmada api-server
karmada-aggregated-apiserver
karmada-scheduler
karmada-webhook
etcd
karmada-agent
karmada-agent는 클러스터 등록 모드에서 pull mode에서 멤버 클러스터를 배포할 때 쓰인다.
karmada-controller-manager
다양한 커스텀 컨트롤러 프로세스를 사용한다.
컨트롤러는 Karmada의 오브젝트를 바라볻아가, cluster API 서버에게 일반적인 쿠버네티스 리소스 만들라고 말한다.
컨트롤러 리스트는 다음과 같다.
https://github.com/karmada-io/karmada/blob/master/cmd/controller-manager/controller-manager.go
func main() {
ctx := controllerruntime.SetupSignalHandler()
// Starting from version 0.15.0, controller-runtime expects its consumers to set a logger through log.SetLogger.
// If SetLogger is not called within the first 30 seconds of a binaries lifetime, it will get
// set to a NullLogSink and report an error. Here's to silence the "log.SetLogger(...) was never called; logs will not be displayed" error
// by setting a logger through log.SetLogger.
// More info refer to: https://github.com/karmada-io/karmada/pull/4885.
controllerruntime.SetLogger(klog.Background())
cmd := app.NewControllerManagerCommand(ctx)
code := cli.Run(cmd)
os.Exit(code)
}
ctx := controllerruntime.SetupSignalHandler()
패키지의 함수로, SIGTERM과 SIGINT를 등록한다. 이 신호 중 하나에서 취소되는 컨텍스트가 반환된다. 두 번째 신호가 포착되면 프로그램은 종료 코드 1로 종료된다.
- SIGTERM : 프로그램 종료하는 일반적인 방법
- SIGINT : 유저가 직접 프로그램 종료를 지시 (ex, 유닉스 게열 운영 체제에서 ctrl c 입력시 SIGINT 시그널이 프로세스로 가고 종료됨)
둘 다 catch가 가능하고, 프로그램은 각 시그널 전송 받았을 때 자신으로 로직 처리가 가능하다.
controllerruntime.SetLogger(klog.Background())
모든 지연된 로거에 대해 구체적인 로깅을 설정한다. (func SetLogger(l logr, Logger) Log는 kubebuilder가 사용하는 기본 로거이다. 다른 logr.Logger에게 위임한다.
controller-runtime 라이브러리는 log.SetLogger를 통해 로거를 설정할 것을 기대합니다. (실제 logging을 위해서는 SetLogger를 호출해야한다.) 만약 SetLogger가 호출되지 않으면 30초 후에 NullLogSink로 설정되고 오류를 보고한다.
var (
Log = logr.New(rootLog)
)
+ Logr
컨트롤러 런타임의 모든 로깅은 logr이라는 패키지에 의해 정의된 인터페이스 세트를 사용하여 구조화된다. 하위 패키지 zap은 Zap이 지원하는 logr 설정을 위한 도움을 제공한다.
cmd := app.NewControllerManagerCommand(ctx)
새로운 컨트롤러 매니저 명령어를 생성한다.
NewControllerManagerCommand 함수는 ctx를 인수로 받아 controller-manager 명령어를 설정한다.
code := cli.Run(cmd)
앞에서 생성한 명령어 cmd를 실행하고, 그 결과로 종료 코드를 반환한다. cli를 통해 명령어 실행시키는 역할한다.
os.Exit(code)
cli.Run(cmd)로부터 반환된 종료 코드 사용하여 프로그램 종료한다. 운영체제에 프로그램이 어떻게 종료되었는지 신호를 보낸다.
// NewControllerManagerCommand creates a *cobra.Command object with default parameters
func NewControllerManagerCommand(ctx context.Context) *cobra.Command {
opts := options.NewOptions()
cmd := &cobra.Command{
Use: "karmada-controller-manager",
Long: `The karmada-controller-manager runs various controllers.
The controllers watch Karmada objects and then talk to the underlying clusters' API servers
to create regular Kubernetes resources.`,
RunE: func(_ *cobra.Command, _ []string) error {
// validate options
if errs := opts.Validate(); len(errs) != 0 {
return errs.ToAggregate()
}
return Run(ctx, opts)
},
}
fss := cliflag.NamedFlagSets{}
genericFlagSet := fss.FlagSet("generic")
// Add the flag(--kubeconfig) that is added by controller-runtime
// (https://github.com/kubernetes-sigs/controller-runtime/blob/v0.11.1/pkg/client/config/config.go#L39),
// and update the flag usage.
genericFlagSet.AddGoFlagSet(flag.CommandLine)
genericFlagSet.Lookup("kubeconfig").Usage = "Path to karmada control plane kubeconfig file."
opts.AddFlags(genericFlagSet, controllers.ControllerNames(), sets.List(controllersDisabledByDefault))
// Set klog flags
logsFlagSet := fss.FlagSet("logs")
klogflag.Add(logsFlagSet)
cmd.AddCommand(sharedcommand.NewCmdVersion("karmada-controller-manager"))
cmd.Flags().AddFlagSet(genericFlagSet)
cmd.Flags().AddFlagSet(logsFlagSet)
cols, _, _ := term.TerminalSize(cmd.OutOrStdout())
sharedcli.SetUsageAndHelpFunc(cmd, fss, cols)
return cmd
}
opts := options.NewOptions()
opts는 controller-manager의 옵션을 정의하는 NewOptions 객체를 생성한다.
cmd := &cobra.Command{ .. }
cmd는 cobra.Command 객체를 생성한다. 'cobra.Command'는 cli를 구축하는데 사용되는 라이브러리..!
Use와 Long 필드는 명령어의 사용법과 설명을 정의한다.
// Run runs the controller-manager with options. This should never exit.
func Run(ctx context.Context, opts *options.Options) error {
klog.Infof("karmada-controller-manager version: %s", version.Get())
profileflag.ListenAndServe(opts.ProfileOpts)
controlPlaneRestConfig, err := controllerruntime.GetConfig()
if err != nil {
panic(err)
}
controlPlaneRestConfig.QPS, controlPlaneRestConfig.Burst = opts.KubeAPIQPS, opts.KubeAPIBurst
controllerManager, err := controllerruntime.NewManager(controlPlaneRestConfig, controllerruntime.Options{
Logger: klog.Background(),
Scheme: gclient.NewSchema(),
Cache: cache.Options{SyncPeriod: &opts.ResyncPeriod.Duration},
LeaderElection: opts.LeaderElection.LeaderElect,
LeaderElectionID: opts.LeaderElection.ResourceName,
LeaderElectionNamespace: opts.LeaderElection.ResourceNamespace,
LeaseDuration: &opts.LeaderElection.LeaseDuration.Duration,
RenewDeadline: &opts.LeaderElection.RenewDeadline.Duration,
RetryPeriod: &opts.LeaderElection.RetryPeriod.Duration,
LeaderElectionResourceLock: opts.LeaderElection.ResourceLock,
HealthProbeBindAddress: net.JoinHostPort(opts.BindAddress, strconv.Itoa(opts.SecurePort)),
LivenessEndpointName: "/healthz",
Metrics: metricsserver.Options{BindAddress: opts.MetricsBindAddress},
MapperProvider: restmapper.MapperProvider,
BaseContext: func() context.Context {
return ctx
},
Controller: config.Controller{
GroupKindConcurrency: map[string]int{
workv1alpha1.SchemeGroupVersion.WithKind("Work").GroupKind().String(): opts.ConcurrentWorkSyncs,
workv1alpha2.SchemeGroupVersion.WithKind("ResourceBinding").GroupKind().String(): opts.ConcurrentResourceBindingSyncs,
workv1alpha2.SchemeGroupVersion.WithKind("ClusterResourceBinding").GroupKind().String(): opts.ConcurrentClusterResourceBindingSyncs,
clusterv1alpha1.SchemeGroupVersion.WithKind("Cluster").GroupKind().String(): opts.ConcurrentClusterSyncs,
schema.GroupVersionKind{Group: "", Version: "v1", Kind: "Namespace"}.GroupKind().String(): opts.ConcurrentNamespaceSyncs,
},
CacheSyncTimeout: opts.ClusterCacheSyncTimeout.Duration,
},
NewCache: func(config *rest.Config, opts cache.Options) (cache.Cache, error) {
opts.DefaultTransform = fedinformer.StripUnusedFields
return cache.New(config, opts)
},
})
if err != nil {
klog.Errorf("Failed to build controller manager: %v", err)
return err
}
if err := controllerManager.AddHealthzCheck("ping", healthz.Ping); err != nil {
klog.Errorf("Failed to add health check endpoint: %v", err)
return err
}
crtlmetrics.Registry.MustRegister(metrics.ClusterCollectors()...)
crtlmetrics.Registry.MustRegister(metrics.ResourceCollectors()...)
crtlmetrics.Registry.MustRegister(metrics.PoolCollectors()...)
setupControllers(controllerManager, opts, ctx.Done())
// blocks until the context is done.
if err := controllerManager.Start(ctx); err != nil {
klog.Errorf("controller manager exits unexpectedly: %v", err)
return err
}
// never reach here
return nil
}
참고한 글
https://karmada.io/docs/userguide/clustermanager/cluster-registration/
https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/manager/signals
https://pkg.go.dev/sigs.k8s.io/controller-runtime/pkg/log
'오픈소스' 카테고리의 다른 글
[Kyverno] Kyverno 이해하기 (0) | 2025.03.12 |
---|---|
[Opentelemetry] 오픈텔레메트리 소개와 역할 (0) | 2024.05.27 |
[Karmada] 오픈 소스 기여하기 1주차 (0) | 2024.05.21 |