This project aims to take control of different cloud resources with kubernetes operator. By defining the CRD(CustomResourceDefinition) of the cloud resource, it's easy to execute the underlying cloud providers' API and get the status of the cloud resource.
This project will call the cloud Std-API generated by multicloud_service. Instead of using the official client-go offered by kubernetes, we use our own client-go package to interact with kubernetes cluster. We also provide user with a java client, java_sdk, which can be used to manage different cloud resources.
The figure below shows the full design of our project. This repository implement the Resource Controller
part of the project. As shown in the figure, it watches the CRD from kubernetes api server. Once there is an update of one CRD's liefcycle, it will call the cloud std API provided by multicloud_service
and save the response as an Event.
The following figure shows the work flow of this project.
API server
accepts one client request on CRD, and update infomarion saved in etcd.API server
noticeResource Listener
which is watching the CRD that there is a change in one CRD resource.- Based on the lifecycle of the CRD,
Resource Controller
will call the corresponding Std API, and save the response in anevent
. Resource Controller
will call aGet
API automatically after executing the lifecycle, and then update the domain based on the response.- If the lifecycle is a
delete
API, theResource Controller
will also delete the CRD Resource from kubernetes cluster. Similarly, if user only delete the CRD Resource,Resource Controller
will also call thedelete
API to delete cloud resource. (To avoid this happening, just stop cloudctl running)
- lifecycle is an object type and is used to save the cloud API json file.
- domain is used to save underlying cloud resource metadata.
- Users need to add some metadata of the cloud resouce, like UUID, which is used to find the specfic resource.
- Users need to define a secret which contains the authentication information. And the secretRef contains the secret's name and namespace.
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: openstackservers.doslab.io
spec:
group: doslab.io
names:
kind: OpenstackServer
plural: openstackservers
singular: openstackserver
scope: Namespaced
versions:
- additionalPrinterColumns:
- description: Server ID
jsonPath: .spec.id
name: ID
type: string
- description: Server Name
jsonPath: .spec.domain.name
name: Name
type: string
- description: Server Status
jsonPath: .spec.domain.status
name: Status
type: string
- description: host id is where the server is located in the cloud
jsonPath: .spec.domain.hostid
name: HostID
type: string
- description: image
jsonPath: .spec.domain.image.id
name: ImageID
type: string
- description: flavor
jsonPath: .spec.domain.flavor.id
name: FlavorID
type: string
name: v1
schema:
openAPIV3Schema:
description: VMInstance is the Schema for the vminstances API
properties:
apiVersion:
type: string
kind:
type: string
metadata:
type: object
spec:
description: spec defines the desired state of openstack server
properties:
domain:
type: object
x-kubernetes-preserve-unknown-fields: true
lifeCycle:
description: request to be execute
type: object
x-kubernetes-preserve-unknown-fields: true
# metadata
id:
type: string
# secret info requeired
secretRef:
description: SrereteRef
properties:
name:
description: secretName
type: string
namespace:
description: secretNamespace
type: string
required:
- name
- namespace
type: object
required:
- secretRef
type: object
status:
type: object
type: object
served: true
storage: true
subresources:
status: {}
In order to take control of the CRD, user need to offer a config file to cloudctl
.
CrdName
is the name in CustomResourceDefinition.InitJson
contains theGet
operation of the Std-API.ResourceController
call this to get the detailed infomation the cloud resource. The parameters required should be listed in the json as key-value, key is the name and value is empty string. WhenResourceController
try to execute the 'InitJson', it will fill the value based on the 'MetaInfos'.DeleteJson
contains thedelete
operation of the Std-API.ResourceController
will execute it when user try to delete the CRD in kubernetes.- Some metadata(which is required by std-API) of the CRD have different name and json path in different files. So we use
MetaInfos
to keep those information, takeid
as exampleSpecName
means the metadata's name define in CRD spec, which is 'id' in this case.DomainName
means the metadata's name define in CRD domin, which is 'id' in this case.CloudParaName
describe the metadata's name in std-API request(like GetComputeV2Servers...), which is 'id' in this case.InitJsonPath
describe the variableid
json path inInitJson
.- When the
ResourceController
called the request inInitJson
, it can get the detailed infomation of the cloud resource in the response. AndInitRespJsonPath
is used to parse that information and saved in the domain. IsArray
describes whether the 'Get' operation takes a list as input(like a list of server ids to get all the servers information).
{
"CrdName": "OpenstackServer",
"MetaInfos": [
{
"SpecName": "id",
"DomainName": "id",
"CloudParaName":"id",
"InitJsonPath": "GetComputeV2Servers.id",
"DeleteJsonPath": "DeleteComputeV2Servers.id",
"InitRespJsonPath": "server.id",
"IsArray": false
}
],
"InitJson": {
"GetComputeV2Servers": {
"id": ""
}
},
"DeleteJson": {
"DeleteComputeV2Servers": {
"id": ""
}
},
"DomainJsonPath":"server"
}
User can deploy this project by makefile.
make deploy
make undeploy
make install
make uninstall
The json below is used to Create a Openstack Server. The response will contains the server's UUID and will be filled in the spec.id. The controller will automatically execute the GET Request from the config's InitJson, and fill the domain with the response.
{
"apiVersion": "doslab.io/v1",
"kind": "OpenstackServer",
"metadata": {
"name": "openstack-server-create"
},
"spec": {
"lifeCycle": {
"CreateComputeV2Servers": {
"Opts": {
"Name": "test-create",
"ImageRef": "952b386b-6f30-46f6-b019-f522b157aa3a",
"FlavorRef": "3"
}
}
},
"id": "",
"secretRef": {
"namespace": "default",
"name": "openstack-compute-secret"
}
}
}
- 获取k8s token
kubectl create -f https://raw.githubusercontent.com/kubesys/client-go/master/account.yaml
kubectl -n kube-system describe secret $(kubectl -n kube-system get secret | grep kubernetes-client | awk '{print $1}') | grep "token:" | awk -F":" '{print$2}' | sed 's/ //g'
Resource Name | yaml | config | Create | Get | Update | Delete | document |
---|---|---|---|---|---|---|---|
Server | OpenstackServer | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |
Image | OpenstackImage | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |
Network | OpenstackNetwork | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |
Snapshot | OpenstackSnapshot | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |
Router | OpenstackRouter | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |
Disk | OpenstackDisk | Config File | Create API | Get API | Update API | Delete API | Create API Get API Update API Delete API |