Skip to content

Commit 9a35595

Browse files
authored
Merge pull request #460 from prashanth26/spliting-controllers2
Support for external machine controller (driver)
2 parents 4eff65a + f13e506 commit 9a35595

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+13469
-317
lines changed

LICENSE.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,12 @@ Alibaba Cloud Go Software Development Kit.
299299
https://github.com/aliyun/alibaba-cloud-sdk-go.
300300
Apache 2 license (https://github.com/aliyun/alibaba-cloud-sdk-go/blob/master/LICENSE)
301301

302+
gRPC-Go.
303+
https://github.com/grpc/grpc-go.
304+
Copyright 2017 gRPC authors.
305+
Apache 2 license (https://github.com/grpc/grpc-go/blob/master/LICENSE)
306+
307+
302308
------
303309
## BSD 3-clause "New" or "Revised" License
304310

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ start:
4242
--machine-safety-apiserver-statuscheck-period=1m \
4343
--machine-safety-orphan-vms-period=30m \
4444
--machine-safety-overshooting-period=1m \
45-
--v=2
45+
--v=3
4646

4747
#################################################################
4848
# Rules related to binary build, Docker image build and release #

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ kubectl create/get/delete machine vm1
1515

1616
Nodes/Machines/VMs are different terminologies used to represent similar things. We use these terms in the following way
1717

18-
1. VM: A virtual machine running on any cloud provider.
18+
1. VM: A virtual machine running on any cloud provider. It could also refer to a physical machine (PM) in case of a bare metal setup.
1919
1. Node: Native kubernetes node objects. The objects you get to see when you do a *"kubectl get nodes"*. Although nodes can be either physical/virtual machines, for the purposes of our discussions it refers to a VM.
2020
1. Machine: A VM that is provisioned/managed by the Machine Controller Manager.
2121

cmd/machine-controller-manager/app/controllermanager.go

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,9 @@ import (
3434

3535
machinescheme "github.com/gardener/machine-controller-manager/pkg/client/clientset/versioned/scheme"
3636
machineinformers "github.com/gardener/machine-controller-manager/pkg/client/informers/externalversions"
37-
machinecontroller "github.com/gardener/machine-controller-manager/pkg/controller"
38-
corecontroller "github.com/gardener/machine-controller-manager/pkg/util/controller"
37+
mcmcontroller "github.com/gardener/machine-controller-manager/pkg/controller"
38+
corecontroller "github.com/gardener/machine-controller-manager/pkg/util/clientbuilder/core"
39+
machinecontroller "github.com/gardener/machine-controller-manager/pkg/util/clientbuilder/machine"
3940
coreinformers "k8s.io/client-go/informers"
4041
kubescheme "k8s.io/client-go/kubernetes/scheme"
4142

@@ -63,12 +64,11 @@ const (
6364
controllerManagerAgentName = "machine-controller-manager"
6465
)
6566

66-
var openStackGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "openstackmachineclasses"}
67-
var awsGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "awsmachineclasses"}
68-
var azureGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "azuremachineclasses"}
69-
var gcpGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "gcpmachineclasses"}
70-
var alicloudGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "alicloudmachineclasses"}
71-
var packetGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "packetmachineclasses"}
67+
var (
68+
machineGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "machines"}
69+
machineSetGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "machinesets"}
70+
machineDeploymentGVR = schema.GroupVersionResource{Group: "machine.sapcloud.io", Version: "v1alpha1", Resource: "machinedeployments"}
71+
)
7272

7373
// Run runs the MCMServer. This should never exit.
7474
func Run(s *options.MCMServer) error {
@@ -224,7 +224,7 @@ func StartControllers(s *options.MCMServer,
224224
klog.Fatal(err)
225225
}
226226

227-
if availableResources[awsGVR] || availableResources[azureGVR] || availableResources[gcpGVR] || availableResources[openStackGVR] || availableResources[alicloudGVR] || availableResources[packetGVR] {
227+
if availableResources[machineGVR] || availableResources[machineSetGVR] || availableResources[machineDeploymentGVR] {
228228
klog.V(5).Infof("Creating shared informers; resync interval: %v", s.MinResyncPeriod)
229229

230230
controlMachineInformerFactory := machineinformers.NewFilteredSharedInformerFactory(
@@ -250,7 +250,7 @@ func StartControllers(s *options.MCMServer,
250250
machineSharedInformers := controlMachineInformerFactory.Machine().V1alpha1()
251251

252252
klog.V(5).Infof("Creating controllers...")
253-
machineController, err := machinecontroller.NewController(
253+
mcmcontroller, err := mcmcontroller.NewController(
254254
s.Namespace,
255255
controlMachineClient,
256256
controlCoreClient,
@@ -283,10 +283,10 @@ func StartControllers(s *options.MCMServer,
283283
targetCoreInformerFactory.Start(stop)
284284

285285
klog.V(5).Info("Running controller")
286-
go machineController.Run(int(s.ConcurrentNodeSyncs), stop)
286+
go mcmcontroller.Run(int(s.ConcurrentNodeSyncs), stop)
287287

288288
} else {
289-
return fmt.Errorf("unable to start machine controller: API GroupVersion %q or %q or %q or %q or %q or %q is not available; found %#v", awsGVR, azureGVR, gcpGVR, openStackGVR, alicloudGVR, packetGVR, availableResources)
289+
return fmt.Errorf("unable to start machine controller: API GroupVersion %q or %q or %q is not available; \nFound: %#v", machineGVR, machineSetGVR, machineDeploymentGVR, availableResources)
290290
}
291291

292292
select {}

docs/README.md

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,25 @@
11
# Documentation Index
22

3-
## Development
3+
## Using Out-of-Tree (External) provider support (Recommended)
44

5+
#### Development
6+
* [Adding support for a new cloud provider](development/cp_support_new.md)
7+
8+
## Using In-Tree provider support (:warning: DEPRECATED!)
9+
10+
##### Development
11+
12+
* [Adding support for a new cloud provider](development/cp_support_old.md)
513
* [Setting up a local development environment](development/local_setup.md)
614
* [Testing and Dependency Management](development/testing_and_dependencies.md)
7-
* [Adding support for a new cloud provider](development/new_cp_support.md)
815

9-
## Usage
16+
#### Usage
1017

1118
* [Setting up your usage environment](usage/prerequisite.md)
1219
* [Creating/Deleting machines (VM)](usage/machine.md)
1320
* [Maintaining machine replicas using machines-sets](usage/machine_set.md)
1421
* [Updating machines using machines-deployments](usage/machine_deployment.md)
1522

16-
## Deployment
23+
#### Deployment
1724

18-
* [Deploying the Machine Controller Manager into a Kubernetes cluster](deployment/kubernetes.md)
25+
* [Deploying the MCM into a Kubernetes cluster using IN-TREE providers](deployment/kubernetes.md)

docs/deployment/kubernetes.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,19 @@ $ make docker-image
3737
$ make push
3838
```
3939

40-
- Now you can deploy this docker image to your cluster. A sample development [file is given at](/kubernetes/deployment/deployment.yaml). By default, the deployment manages the cluster it is running in. Optionally, the kubeconfig could also be passed as a flag as described in `/kubernetes/deployment/deployment.yaml`. This is done when you want your controller running outside the cluster to be managed from.
40+
- Now you can deploy this docker image to your cluster. A sample development [file is given at](/kubernetes/deployment/in-tree/deployment.yaml). By default, the deployment manages the cluster it is running in. Optionally, the kubeconfig could also be passed as a flag as described in `/kubernetes/deployment/in-tree/deployment.yaml`. This is done when you want your controller running outside the cluster to be managed from.
4141
```bash
42-
$ kubectl apply -f kubernetes/deployment/deployment.yaml
42+
$ kubectl apply -f kubernetes/deployment/in-tree/deployment.yaml
4343
```
4444
- Also deploy the required clusterRole and clusterRoleBindings
4545
```bash
46-
$ kubectl apply -f kubernetes/deployment/clusterrole.yaml
47-
$ kubectl apply -f kubernetes/deployment/clusterrolebinding.yaml
46+
$ kubectl apply -f kubernetes/deployment/in-tree/clusterrole.yaml
47+
$ kubectl apply -f kubernetes/deployment/in-tree/clusterrolebinding.yaml
4848
```
4949

5050
## Configuring optional parameters while deploying
5151

52-
Machine-controller-manager supports several configurable parameters while deploying. Refer to [the following lines](/kubernetes/deployment/deployment.yaml#L21-L30), to know how each parameter can be configured, and what it's purpose is for.
52+
Machine-controller-manager supports several configurable parameters while deploying. Refer to [the following lines](/kubernetes/deployment/in-tree/deployment.yaml#L21-L30), to know how each parameter can be configured, and what it's purpose is for.
5353

5454
## Usage
5555

docs/development/cp_support_new.md

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
# Adding support for a new provider
2+
3+
Steps to be followed while implementing a new (hyperscale) provider are mentioned below. This is the easiest way to add a new provider support using a blueprint code.
4+
5+
However, you may also develop your machine controller from scratch which would provide you more flexibility. However make sure that your custom machine controller adhere's to the `Machine.Status` struct defined in the [MachineAPIs](/pkg/apis/machine/types.go) to make sure the MCM is able to act with higher level controllers like MachineSet and MachineDeployment controller. The key is the `Machine.Status.CurrentStatus.Phase` key that indicates the status of the machine object.
6+
7+
Our strong recommendation would be to follow the steps below as this provides most flexibility required to support machine management for adding new providers. And if you feel to extend the functionality feel free to update our [machine controller libraries](/pkg/util/provider).
8+
9+
## Setting up your repository
10+
11+
1. Create a new empty repository named `machine-controller-manager-provider-{provider-name}` on github username/project. Do not initialize this repository with a README.
12+
1. Copy the remote repository `URL` (HTTPS/SSH) to this repository which is displayed once you create this repository.
13+
1. Now on your local system, create directories as required. {your-github-username} given below could also be {github-project} depending on where you have created the new repository.
14+
```bash
15+
mkdir -p $GOPATH/src/github.com/{your-github-username}
16+
```
17+
1. Navigate to this created directory.
18+
```bash
19+
cd $GOPATH/src/github.com/{your-github-username}
20+
```
21+
1. Clone [this repository](https://github.com/gardener/machine-controller-manager-provider-sampleprovider) on your local machine.
22+
```bash
23+
git clone git@github.com:gardener/machine-controller-manager-provider-sampleprovider.git
24+
```
25+
1. Rename the directory from `machine-controller-manager-provider-sampleprovider` to `machine-controller-manager-provider-{provider-name}`.
26+
```bash
27+
mv machine-controller-manager-provider-sampleprovider machine-controller-manager-provider-{provider-name}
28+
```
29+
1. Navigate into the newly created directory.
30+
```bash
31+
cd machine-controller-manager-provider-{provider-name}
32+
```
33+
1. Update the remote `origin` URL to the newly created repository's URL you had copied above.
34+
```bash
35+
git remote set-url origin git@github.com:{your-github-username}/machine-controller-manager-provider-{provider-name}.git
36+
```
37+
1. Rename github project from `gardener` to `{github-org/your-github-username}` where ever you have cloned the repository above. Use the hack script given below to do the same.
38+
```bash
39+
make rename-project PROJECT_NAME={github-org/your-github-username}
40+
eg:
41+
make rename-project PROJECT_NAME=gardener (or)
42+
make rename-project PROJECT_NAME=githubusername
43+
```
44+
1. Rename all files and code from `SampleProvider` to your desired `{provider-name}`. Use the hack script given below to do the same. {provider-name} is case sensitive.
45+
```bash
46+
make rename-provider PROVIDER_NAME={provider-name}
47+
eg:
48+
make rename-provider PROVIDER_NAME=AmazonWebServices (or)
49+
make rename-provider PROVIDER_NAME=AWS
50+
```
51+
1. Now commit your changes and push it upstream.
52+
```bash
53+
git add -A
54+
git commit -m "Renamed SampleProvide to {provider-name}"
55+
git push origin master
56+
```
57+
58+
## Code changes required
59+
60+
The contract between he Machine Controller Manager (MCM) and the Machine Controller (MC) AKA driver has been [documented here](machine_error_codes.md) and the [machine error codes can be found here](/pkg/util/provider/machinecodes/codes/codes.go). You may refer to them for any queries.
61+
62+
:warning:
63+
- Keep in mind that, **there should to be a unique way to map between machine objects and VMs**. This can be done by mapping machine object names with VM-Name/ tags/ other metadata.
64+
- Optionally there should also be a unique way to map a VM to it's machine class object. This can be done by tagging VM objects with tags/resource-groups associated with the machine class.
65+
66+
#### Steps to integrate
67+
68+
1. Update the `pkg/provider/apis/provider_spec.go` specification file to reflect the structure of the `ProviderSpec` blob. It typically contains the machine template details in the `MachineClass` object. Follow the sample spec provided already in the file. A sample provider specification can be found [here](https://github.com/gardener/machine-controller-manager-provider-aws/blob/master/pkg/aws/apis/aws_provider_spec.go).
69+
1. Fill in the methods described at `pkg/provider/core.go` to manage VMs on your cloud provider. Comments are provided above each method to help you fill them up with desired `REQUEST` and `RESPONSE` parameters.
70+
- A sample provider implementation for these methods can be found [here](https://github.com/gardener/machine-controller-manager-provider-aws/blob/master/pkg/aws/core.go).
71+
- Fill in the required methods `CreateMachine()`, and `DeleteMachine()` methods.
72+
- Optionally fill in methods like `GetMachineStatus()`, `ListMachines()`, and `GetVolumeIDs()`. You may choose to fill these, once the working of the required methods seem to be working.
73+
- `GetVolumeIDs()` expects VolumeIDs to be decoded from the volumeSpec based on the cloud provider.
74+
1. Perform validation of APIs that you have described and make it a part of your methods as required at each requests.
75+
1. Write unit tests to make it work with your implementation by running `make test`.
76+
```bash
77+
make test
78+
```
79+
1. Re-generate the vendors, to update any new vendors imported.
80+
```bash
81+
make revendor
82+
```
83+
1. Update the sample YAML files on `kubernetes/` directory to provide sample files through which the working of the machine controller can be tested.
84+
1. Update `README.md` to reflect any additional changes
85+
86+
## Testing your code changes
87+
88+
Make sure `$TARGET_KUBECONFIG` points to the cluster where you wish to manage machines. `$CONTROL_NAMESPACE` represents the namespaces where MCM is looking for machine CR objects, and `$CONTROL_KUBECONFIG` points to the cluster which holds these machine CRs.
89+
90+
1. On the first terminal running at `$GOPATH/src/github.com/{github-org/your-github-username}/machine-controller-manager-provider-{provider-name}`,
91+
- Run the machine controller (driver) using the command below.
92+
```bash
93+
make start
94+
```
95+
1. On the second terminal pointing to `$GOPATH/src/github.com/gardener`,
96+
- Clone the [latest MCM code](https://github.com/gardener/machine-controller-manager)
97+
```bash
98+
git clone git@github.com:gardener/machine-controller-manager.git
99+
```
100+
- Navigate to the newly created directory.
101+
```bash
102+
cd machine-controller-manager
103+
```
104+
- Deploy the required CRDs from the machine-controller-manager repo,
105+
```bash
106+
kubectl apply -f kubernetes/crds.yaml
107+
```
108+
- Run the machine-controller-manager in the `cmi-client` branch
109+
```bash
110+
make start
111+
```
112+
1. On the third terminal pointing to `$GOPATH/src/github.com/{github-org/your-github-username}/machine-controller-manager-provider-{provider-name}`
113+
- Fill in the object files given below and deploy them as described below.
114+
- Deploy the `machine-class`
115+
```bash
116+
kubectl apply -f kubernetes/machine-class.yaml
117+
```
118+
- Deploy the `kubernetes secret` if required.
119+
```bash
120+
kubectl apply -f kubernetes/secret.yaml
121+
```
122+
- Deploy the `machine` object and make sure it joins the cluster successfully.
123+
```bash
124+
kubectl apply -f kubernetes/machine.yaml
125+
```
126+
- Once machine joins, you can test by deploying a machine-deployment.
127+
- Deploy the `machine-deployment` object and make sure it joins the cluster successfully.
128+
```bash
129+
kubectl apply -f kubernetes/machine-deployment.yaml
130+
```
131+
- Make sure to delete both the `machine` and `machine-deployment` object after use.
132+
```bash
133+
kubectl delete -f kubernetes/machine.yaml
134+
kubectl delete -f kubernetes/machine-deployment.yaml
135+
```
136+
137+
## Releasing your docker image
138+
139+
1. Make sure you have logged into gcloud/docker using the CLI.
140+
2. To release your docker image, run the following.
141+
```bash
142+
make release IMAGE_REPOSITORY=<link-to-image-repo>
143+
```
144+
3. A sample kubernetes deploy file can be found at `kubernetes/deployment.yaml`. Update the same (with your desired MCM and MC images) to deploy your MCM pod.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,5 @@ For adding support for a new cloud provider in the Machine Controller Manager, f
1515
1. Update `pkg/controller/controller.go` to add new providerMachineClassLister, providerMachineClassQueue, awsMachineClassSynced into the controller struct. Also initialize them in NewController() method.
1616
1. Add a new file `pkg/controller/providermachineclass.go` that allows re-queuing of machines which refer to an modified providerMachineClass.
1717
1. Update `pkg/controller/controller.go` to extend `WaitForCacheSync` and `.Shutdown()` similar to other cloud providers.
18-
1. Update the example ClusterRole in `kubernetes/deployment/clusterrole.yaml` to allow operations on your new machine class.
18+
1. Update the example ClusterRole in `kubernetes/deployment/in-tree/clusterrole.yaml` to allow operations on your new machine class.
1919
1. Update `pkg/controller/controller.go`, `pkg/controller/secret.go`, `pkg/controller/secret_util.go` to add event handlers to add/remove finalizers referenced by your machine Class. Refer [this commit](https://github.com/gardener/machine-controller-manager/pull/104/commits/013f70726b1057aed1cf7fe0f0449922ab9a256a).

docs/development/local_setup.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,11 @@ I1227 11:08:19.963638 55523 controllermanager.go:204] Starting shared informer
7777
I1227 11:08:20.766085 55523 controller.go:247] Starting machine-controller-manager
7878
```
7979

80+
:warning: The file `dev/target-kubeconfig.yaml` points to the cluster whose nodes you want to manage. `dev/control-kubeconfig.yaml` points to the cluster from where you want to manage the nodes from. However, `dev/control-kubeconfig.yaml` is optional.
81+
8082
The Machine Controller Manager should now be ready to manage the VMs in your kubernetes cluster.
8183

82-
:warning: The file `dev/target-kubeconfig.yaml` points to the cluster whose nodes you want to manage. `dev/control-kubeconfig.yaml` points to the cluster from where you want to manage the nodes from. However, `dev/control-kubeconfig.yaml` is optional.
84+
:warning: This is assuming that your MCM is built to manage machines for any in-tree supported providers. There is a new way to deploy and manage out of tree (external) support for providers whose development can be [found here](cp_support_new.md)
8385

8486
## Testing Machine Classes
8587

0 commit comments

Comments
 (0)