Terminology
cloudprovider.Interface: https://github.com/kubernetes/cloud-provider/blob/master/cloud.go#L43
type loadbalancer interface: https://github.com/kubernetes/cloud-provider/blob/master/cloud.go#L106
- GetLoadbalancer
- GetLoadBalancerName
- EnsureLoadBalancer
- UpdateLoadBalancer
- EnsureLoadBalancerDeleted
Components
Cloud controller manager
k8s.io/kubernetes/cmd/cloud-controller-manager
one package: app, which contains the core logic of cloud-controller-manager.
Starts:
Ref: here
Service Controller
Service controller will be managing LoadBalancer type of service, see here for the initialization.
- Run() starts a group of workers here
- Worker() calls processNextWorkItem();
- processNextWorkItem() calls syncService();
- syncService() by default calls processServiceCreateOrUpdate();
- processServiceCreateOrUpdate() calls syncLoadBalancerIfNeeded() if needed;
- syncLoadBalancerIfNeeded() calls ensureLoadBalancer() if loadbalancer needs to be created;
- Calls cloud provider’s EnsureLoadBalancer through cloudprovider.Interface with a group of nodes;
Examples
vSphere out-of-tree Cloud Provider
- Vsphere-cloud-controller-manager is a cobra command which invokes app.Run;
- Run starts above mentioned four controllers and here;
As a result, vsphere-cloud-provider-manager is a concrete “implementation” of cloud-controller-manager upstream in the sense that:
- Leverages the same app package to Run;
- Implements cloudprovider.Interface;
Azure out-of-tree Cloud provider
- Azure cloud provider does the same thing here;
Aws out-of-tree Cloud Provider
- Aws cloud provider does the same thing here;
Openstack out-of-tree Cloud Provider
- Openstack cloud provider does the same thing here;
AliCloud Cloud Provider
AliCloud Cloud Provider is an exception, seems like it “copies” upstream cloud-controller-manager and other controllers’ code, and made its own modifications.
- Run calls MainLoop;
- MainLoop calls RunControllers;
- RunControllers calls runControllerPV and runControllerService, which in turn starts its own controllers;
Summary
To summarize, to implement an out-of-tree cloud provider:
the entry point is app.Run;
Have your own implementation of cloudprovider.Interface;
Register your own cluster provider by calling cloudprovider.RegisterCloudProvider, because cloud-controller-manager calls InitCloudProvider to initialize cloud provider instance;
InitCloudProvider uses configured name to get corresponding registered initialization function in an internal map, which can be updated by RegisterCloudProvider;
See example here in vsphere cloud provider;
Here is an example I created: https://github.com/maplain/dummy-k8s-cloud-provider
References
Cloud Controller Manager: https://kubernetes.io/docs/concepts/architecture/cloud-controller/
Develop an out-of-tree Cloud Provider: https://kubernetes.io/docs/tasks/administer-cluster/developing-cloud-controller-manager/#out-of-tree
KEP: https://github.com/kubernetes/enhancements/blob/master/keps/sig-cloud-provider/0002-cloud-controller-manager.md#remove-cloud-provider-code-from-kubernetes-core
Out-of-tree cloud providers
Vsphere: https://github.com/kubernetes/cloud-provider-vsphere
Alibaba: https://github.com/kubernetes/cloud-provider-alibaba-cloud
Azure: https://github.com/kubernetes/cloud-provider-azure
Openstack: https://github.com/kubernetes/cloud-provider-openstack
Aws: https://github.com/kubernetes/cloud-provider-aws
Common Packages
Klog for logging
Gcfg for config file, which has the same syntax as git