目录
前言
一、CRD
二、创建数据库表(Mysql)
二、控制器开发
1.使用kubernetes的examplecontroller模板
2.在controller.go 中新增数据表监听方法
3.修改tools工具生成资源对象结构体定义
这里记录开发k8s控制器的一般方式,controller开发主要使用k8s提供的client-go库进行。
Controller监听集群内部资源对象的变化,编辑资源对象(增、删、改、查),根据不同与定义规则,对资源对象的当前状态进行调整。
CustomResourceDefinitions 资源定义对象
在集群内新增资源对象,和Controller配合使用可以进行集群扩展。
Custom resources 自定义资源描述对象
自定义资源对象的描述对象,它表示集群内一组对象集合。
定义了一个新的资源对象,它用于描述如何部署新应用。
新资源对象类别:ExampleRes
资源对象新增的属性:
deploymentName 部署deployment名称
replicas 副本数量
app 应用名称
cluster 应用的部署名称
image 使用的镜像名称
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
name: samplecontroller.k8s.io
spec:
group: samplecontroller.k8s.io
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
deploymentName:
type: string
replicas:
type: integer
minimum: 1
maximum: 10
app:
type: string
cluster:
type: string
image:
type: string
status:
type: object
properties:
availableReplicas:
type: integer
subresources:
status: {}
names:
kind: ExampleRes
plural: exampleres
scope: Namespaced
创建数据表,controller会监听这张表的数据变化,并创建出自定义资源对象及部署应用的资源对象
create table kubernetes_task
(
id int primary key auto_increment,
app varchar(100) null comment '应用名称',
cluster varchar(100) null comment '部署名称',
`image` varchar(100) null comment '使用的镜像名称',
instances int null comment '副本数量',
`status` varchar(50) null comment '部署状态,由k8s回写',
writetime datetime null comment '记录写入时间',
updatetime datetime null comment 'k8s处理时间'
)
可以使用kubernetes默认生成的controller模板,也可以使用k8s提供的tools重新生成。
该方法采用协程+延时周期性运行,读取mysql数据表中的新增数据,并部署deployment资源对象。
func (c *Controller) WatchEtcp() {
var err error
db_conn, err = sql.Open("mysql", "用户:密码+@tcp(IP:端口)/数据库名?charset=utf8&parseTime=True")
go func(_c *Controller) {
var rows *sql.Rows
for {
time.Sleep(time.Second * 3)
rows, err = db_conn.Query("select id,app,cluster,image,instances,writetime from kubernetes_task where updatetime is null")
if err != nil {
klog.Error(err)
continue
}
for rows.Next() {
var task K8STask = K8STask{}
err = rows.Scan(&task.id, &task.app, &task.cluster, &task.image, &task.instances, &task.writetime)
if err != nil {
klog.Error(err)
continue
}
foo := samplev1alpha1.ExampleRes{ObjectMeta: metav1.ObjectMeta{Name: fmt.Sprintf("exampleapp-%s-%s", task.app, task.cluster)}, Spec: samplev1alpha1.FooSpec{DeploymentName: "exampleapp-api",
Replicas: &task.instances, App: task.app, Cluster: task.cluster, Image: task.image}}
_, err = _c.sampleclientset.SamplecontrollerV1alpha1().Foos("default").
Create(context.TODO(), &foo, metav1.CreateOptions{})
if err != nil {
klog.Error(err)
continue
} else {
db_conn.Exec("update kubernetes_task set updatetime=now(),`status`='已部署' where id=?", task.id)
klog.Info(fmt.Sprintf("create %s %s %s", task.app, task.cluster, task.image))
}
}
rows.Close()
}
}(c)
}
该结构体用于controller处理资源对象时序列化。
type ExampleRes struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
Spec ExampleResSpec `json:"spec"`
Status ExampleResStatus `json:"status"`
}
type ExampleResSpec struct {
DeploymentName string `json:"deploymentName"`
Replicas *int32 `json:"replicas"`
App string `json:"app"`
Cluster string `json:"cluster"`
Image string `json:"image"`
}