github.com/jingruilea/kubeedge@v1.2.0-beta.0.0.20200410162146-4bb8902b3879/cloud/pkg/synccontroller/synccontroller.go (about) 1 package synccontroller 2 3 import ( 4 "os" 5 "strings" 6 "time" 7 8 v1 "k8s.io/api/core/v1" 9 "k8s.io/apimachinery/pkg/labels" 10 "k8s.io/apimachinery/pkg/util/wait" 11 "k8s.io/client-go/informers" 12 coreinformers "k8s.io/client-go/informers/core/v1" 13 "k8s.io/client-go/kubernetes" 14 corelisters "k8s.io/client-go/listers/core/v1" 15 "k8s.io/client-go/rest" 16 "k8s.io/client-go/tools/cache" 17 "k8s.io/client-go/tools/clientcmd" 18 "k8s.io/klog" 19 20 "github.com/kubeedge/beehive/pkg/core" 21 beehiveContext "github.com/kubeedge/beehive/pkg/core/context" 22 "github.com/kubeedge/beehive/pkg/core/model" 23 "github.com/kubeedge/kubeedge/cloud/pkg/apis/reliablesyncs/v1alpha1" 24 "github.com/kubeedge/kubeedge/cloud/pkg/client/clientset/versioned" 25 crdinformerfactory "github.com/kubeedge/kubeedge/cloud/pkg/client/informers/externalversions" 26 deviceinformer "github.com/kubeedge/kubeedge/cloud/pkg/client/informers/externalversions/devices/v1alpha1" 27 syncinformer "github.com/kubeedge/kubeedge/cloud/pkg/client/informers/externalversions/reliablesyncs/v1alpha1" 28 devicelister "github.com/kubeedge/kubeedge/cloud/pkg/client/listers/devices/v1alpha1" 29 synclister "github.com/kubeedge/kubeedge/cloud/pkg/client/listers/reliablesyncs/v1alpha1" 30 "github.com/kubeedge/kubeedge/cloud/pkg/synccontroller/config" 31 commonconst "github.com/kubeedge/kubeedge/common/constants" 32 configv1alpha1 "github.com/kubeedge/kubeedge/pkg/apis/componentconfig/cloudcore/v1alpha1" 33 ) 34 35 // SyncController use beehive context message layer 36 type SyncController struct { 37 enable bool 38 39 // informer 40 podInformer coreinformers.PodInformer 41 configMapInformer coreinformers.ConfigMapInformer 42 secretInformer coreinformers.SecretInformer 43 serviceInformer coreinformers.ServiceInformer 44 endpointInformer coreinformers.EndpointsInformer 45 nodeInformer coreinformers.NodeInformer 46 deviceInformer deviceinformer.DeviceInformer 47 clusterObjectSyncInformer syncinformer.ClusterObjectSyncInformer 48 objectSyncInformer syncinformer.ObjectSyncInformer 49 50 // synced 51 podSynced cache.InformerSynced 52 configMapSynced cache.InformerSynced 53 secretSynced cache.InformerSynced 54 serviceSynced cache.InformerSynced 55 endpointSynced cache.InformerSynced 56 nodeSynced cache.InformerSynced 57 deviceSynced cache.InformerSynced 58 clusterObjectSyncSynced cache.InformerSynced 59 objectSyncSynced cache.InformerSynced 60 61 // lister 62 podLister corelisters.PodLister 63 configMapLister corelisters.ConfigMapLister 64 secretLister corelisters.SecretLister 65 serviceLister corelisters.ServiceLister 66 endpointLister corelisters.EndpointsLister 67 nodeLister corelisters.NodeLister 68 deviceLister devicelister.DeviceLister 69 clusterObjectSyncLister synclister.ClusterObjectSyncLister 70 objectSyncLister synclister.ObjectSyncLister 71 } 72 73 func newSyncController(enable bool) *SyncController { 74 config, err := buildConfig() 75 if err != nil { 76 klog.Errorf("Failed to build config, err: %v", err) 77 os.Exit(1) 78 } 79 kubeClient := kubernetes.NewForConfigOrDie(config) 80 crdClient := versioned.NewForConfigOrDie(config) 81 82 kubeSharedInformers := informers.NewSharedInformerFactory(kubeClient, 0) 83 crdFactory := crdinformerfactory.NewSharedInformerFactory(crdClient, 0) 84 85 podInformer := kubeSharedInformers.Core().V1().Pods() 86 configMapInformer := kubeSharedInformers.Core().V1().ConfigMaps() 87 secretInformer := kubeSharedInformers.Core().V1().Secrets() 88 serviceInformer := kubeSharedInformers.Core().V1().Services() 89 endpointInformer := kubeSharedInformers.Core().V1().Endpoints() 90 nodeInformer := kubeSharedInformers.Core().V1().Nodes() 91 deviceInformer := crdFactory.Devices().V1alpha1().Devices() 92 clusterObjectSyncInformer := crdFactory.Reliablesyncs().V1alpha1().ClusterObjectSyncs() 93 objectSyncInformer := crdFactory.Reliablesyncs().V1alpha1().ObjectSyncs() 94 95 sctl := &SyncController{ 96 enable: enable, 97 98 podInformer: podInformer, 99 configMapInformer: configMapInformer, 100 secretInformer: secretInformer, 101 serviceInformer: serviceInformer, 102 endpointInformer: endpointInformer, 103 nodeInformer: nodeInformer, 104 deviceInformer: deviceInformer, 105 clusterObjectSyncInformer: clusterObjectSyncInformer, 106 objectSyncInformer: objectSyncInformer, 107 108 podSynced: podInformer.Informer().HasSynced, 109 configMapSynced: configMapInformer.Informer().HasSynced, 110 secretSynced: secretInformer.Informer().HasSynced, 111 serviceSynced: serviceInformer.Informer().HasSynced, 112 endpointSynced: endpointInformer.Informer().HasSynced, 113 nodeSynced: nodeInformer.Informer().HasSynced, 114 deviceSynced: deviceInformer.Informer().HasSynced, 115 clusterObjectSyncSynced: clusterObjectSyncInformer.Informer().HasSynced, 116 objectSyncSynced: objectSyncInformer.Informer().HasSynced, 117 118 podLister: podInformer.Lister(), 119 configMapLister: configMapInformer.Lister(), 120 secretLister: secretInformer.Lister(), 121 serviceLister: serviceInformer.Lister(), 122 endpointLister: endpointInformer.Lister(), 123 nodeLister: nodeInformer.Lister(), 124 clusterObjectSyncLister: clusterObjectSyncInformer.Lister(), 125 objectSyncLister: objectSyncInformer.Lister(), 126 } 127 128 return sctl 129 } 130 131 func Register(ec *configv1alpha1.SyncController, kubeAPIConfig *configv1alpha1.KubeAPIConfig) { 132 config.InitConfigure(ec, kubeAPIConfig) 133 core.Register(newSyncController(ec.Enable)) 134 } 135 136 // Name of controller 137 func (sctl *SyncController) Name() string { 138 return SyncControllerModuleName 139 } 140 141 // Group of controller 142 func (sctl *SyncController) Group() string { 143 return SyncControllerModuleGroup 144 } 145 146 // Group of controller 147 func (sctl *SyncController) Enable() bool { 148 return sctl.enable 149 } 150 151 // Start controller 152 func (sctl *SyncController) Start() { 153 go sctl.podInformer.Informer().Run(beehiveContext.Done()) 154 go sctl.configMapInformer.Informer().Run(beehiveContext.Done()) 155 go sctl.secretInformer.Informer().Run(beehiveContext.Done()) 156 go sctl.serviceInformer.Informer().Run(beehiveContext.Done()) 157 go sctl.endpointInformer.Informer().Run(beehiveContext.Done()) 158 go sctl.nodeInformer.Informer().Run(beehiveContext.Done()) 159 160 go sctl.deviceInformer.Informer().Run(beehiveContext.Done()) 161 go sctl.clusterObjectSyncInformer.Informer().Run(beehiveContext.Done()) 162 go sctl.objectSyncInformer.Informer().Run(beehiveContext.Done()) 163 164 if !cache.WaitForCacheSync(beehiveContext.Done(), 165 sctl.podSynced, 166 sctl.configMapSynced, 167 sctl.secretSynced, 168 sctl.serviceSynced, 169 sctl.endpointSynced, 170 sctl.nodeSynced, 171 sctl.deviceSynced, 172 sctl.clusterObjectSyncSynced, 173 sctl.objectSyncSynced, 174 ) { 175 klog.Errorf("unable to sync caches for sync controller") 176 return 177 } 178 179 go wait.Until(sctl.reconcile, 5*time.Second, beehiveContext.Done()) 180 } 181 182 func (sctl *SyncController) reconcile() { 183 allClusterObjectSyncs, err := sctl.clusterObjectSyncLister.List(labels.Everything()) 184 if err != nil { 185 klog.Errorf("Filed to list all the ClusterObjectSyncs: %v", err) 186 } 187 sctl.manageClusterObjectSync(allClusterObjectSyncs) 188 189 allObjectSyncs, err := sctl.objectSyncLister.List(labels.Everything()) 190 if err != nil { 191 klog.Errorf("Filed to list all the ObjectSyncs: %v", err) 192 } 193 sctl.manageObjectSync(allObjectSyncs) 194 195 sctl.manageCreateFailedObject() 196 } 197 198 // Compare the cluster scope objects that have been persisted to the edge with the cluster scope objects in K8s, 199 // and generate update and delete events to the edge 200 func (sctl *SyncController) manageClusterObjectSync(syncs []*v1alpha1.ClusterObjectSync) { 201 // TODO: Handle cluster scope resource 202 } 203 204 // Compare the namespace scope objects that have been persisted to the edge with the namespace scope objects in K8s, 205 // and generate update and delete events to the edge 206 func (sctl *SyncController) manageObjectSync(syncs []*v1alpha1.ObjectSync) { 207 for _, sync := range syncs { 208 switch sync.Spec.ObjectKind { 209 case model.ResourceTypePod: 210 sctl.managePod(sync) 211 case model.ResourceTypeConfigmap: 212 sctl.manageConfigMap(sync) 213 case model.ResourceTypeSecret: 214 sctl.manageSecret(sync) 215 case commonconst.ResourceTypeService: 216 sctl.manageService(sync) 217 case commonconst.ResourceTypeEndpoints: 218 sctl.manageEndpoint(sync) 219 // TODO: add device here 220 default: 221 klog.Errorf("Unsupported object kind: %v", sync.Spec.ObjectKind) 222 } 223 } 224 } 225 226 // BuildObjectSyncName builds the name of objectSync/clusterObjectSync 227 func BuildObjectSyncName(nodeName, UID string) string { 228 return nodeName + "." + UID 229 } 230 231 func getNodeName(syncName string) string { 232 tmps := strings.Split(syncName, ".") 233 return strings.Join(tmps[:len(tmps)-1], ".") 234 } 235 236 func getObjectUID(syncName string) string { 237 tmps := strings.Split(syncName, ".") 238 return tmps[len(tmps)-1] 239 } 240 241 func isFromEdgeNode(nodes []*v1.Node, nodeName string) bool { 242 for _, node := range nodes { 243 if node.Name == nodeName { 244 return true 245 } 246 } 247 return false 248 } 249 250 // build Config from flags 251 func buildConfig() (conf *rest.Config, err error) { 252 kubeConfig, err := clientcmd.BuildConfigFromFlags(config.Config.KubeAPIConfig.Master, 253 config.Config.KubeAPIConfig.KubeConfig) 254 if err != nil { 255 return nil, err 256 } 257 kubeConfig.QPS = float32(config.Config.KubeAPIConfig.QPS) 258 kubeConfig.Burst = int(config.Config.KubeAPIConfig.Burst) 259 kubeConfig.ContentType = "application/json" 260 261 return kubeConfig, nil 262 }