type FederatedTypeConfigSpec struct { // The configuration of the target type. If not set, the pluralName and // groupName fields will be set from the metadata.name of this resource. The // kind field must be set. TargetType APIResource `json:"targetType"` // Whether or not propagation to member clusters should be enabled. Propagation PropagationMode `json:"propagation"` // Configuration for the federated type that defines (via // template, placement and overrides fields) how the target type // should appear in multiple cluster. FederatedType APIResource `json:"federatedType"` // Configuration for the status type that holds information about which type // holds the status of the federated resource. If not provided, the group // and version will default to those provided for the federated type api // resource. // +optional StatusType *APIResource `json:"statusType,omitempty"` // Whether or not Status object should be populated. // +optional StatusCollection *StatusCollectionMode `json:"statusCollection,omitempty"` }
这里的 APIResource 其实就是 GVK 的组合:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
// APIResource defines how to configure the dynamic client for an API resource. type APIResource struct { // metav1.GroupVersion is not used since the json annotation of // the fields enforces them as mandatory. // Group of the resource. // +optional Group string`json:"group,omitempty"` // Version of the resource. Version string`json:"version"` // Camel-cased singular name of the resource (e.g. ConfigMap) Kind string`json:"kind"` // Lower-cased plural name of the resource (e.g. configmaps). If // not provided, it will be computed by lower-casing the kind and // suffixing an 's'. PluralName string`json:"pluralName"` // Scope of the resource. Scope apiextv1b1.ResourceScope `json:"scope"` }
deleted := typeConfig.DeletionTimestamp != nil if deleted { // 停止两个控制器 if syncRunning { c.stopController(typeConfig.Name, syncStopChan) } if statusRunning { c.stopController(statusKey, statusStopChan) } if typeConfig.IsNamespace() { klog.Infof("Reconciling all namespaced FederatedTypeConfig resources on deletion of %q", key) // 更新 FTC c.reconcileOnNamespaceFTCUpdate() } // 移除 Finalizer err := c.removeFinalizer(typeConfig) if err != nil { runtime.HandleError(errors.Wrapf(err, "Failed to remove finalizer from FederatedTypeConfig %q", key)) return util.StatusError } return util.StatusAllOK }
第四部分 FTC 资源 Finalizer 设置策略
这块其实是给新创建的 FTC 资源用的,主要是用于给 FTC 增加 Finalizer。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
// 确保 FTC 具有 Finalizer // 如果没有就添加 updated, err := c.ensureFinalizer(typeConfig) if err != nil { runtime.HandleError(errors.Wrapf(err, "Failed to ensure finalizer for FederatedTypeConfig %q", key)) return util.StatusError } elseif updated && typeConfig.IsNamespace() { // Detected creation of the namespace FTC. If there are existing FTCs // which did not start their sync controllers due to the lack of a // namespace FTC, then reconcile them now so they can start. klog.Infof("Reconciling all namespaced FederatedTypeConfig resources on finalizer update for %q", key) // 更新资源 c.reconcileOnNamespaceFTCUpdate() }
func(c *Controller)startSyncController(tc *corev1b1.FederatedTypeConfig)error { // TODO(marun) Consider using a shared informer for federated // namespace that can be shared between all controllers of a // cluster-scoped KubeFed control plane. A namespace-scoped // control plane would still have to use a non-shared informer due // to it not being possible to limit its scope. // 首先获取 FTC ftc := tc.DeepCopyObject().(*corev1b1.FederatedTypeConfig) // 获取联邦类型的 Kind kind := ftc.Spec.FederatedType.Kind // 对于 sync 控制器管理的资源都需要提供 ns 用于配合联邦命名空间 var fedNamespaceAPIResource *metav1.APIResource if ftc.GetNamespaced() { var err error fedNamespaceAPIResource, err = c.getFederatedNamespaceAPIResource() if err != nil { return errors.Wrapf(err, "Unable to start sync controller for %q due to missing FederatedTypeConfig for namespaces", kind) } }