项目作者: neverCase

项目描述 :
k8s-api & Redis-operator & Mysql-operator
高级语言: Go
项目地址: git://github.com/neverCase/k8s-controller-custom-resource.git


k8s-controller-custom-resource

Features

  • k8s-api: supports watching and listing default resources (such as Service, Pod, Configmap) and another custom resources definition
  • redis-operator: including a simple master-slave mode which was main based on the resources of k8s.StatefulSet and k8s.Service
  • mysql-operator: the same with the redis-operator

Operators to do

  • core/v1/interfaces would add the storage plugins(e.g. nfs) later for dynamically creating pv and pvc

Api to do

  • ingress controller

RedisOperator

clone git, build docker image and compile controller

  1. $ git clone https://github.com/neverCase/k8s-controller-custom-resource.git
  2. $ cd k8s-controller-custom-resource
  3. # build image
  4. $ make mysql
  5. $ make redis
  6. # compile controller
  7. $ CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -o multiplexcrd cmd/multiplex/main.go

define the resource of the RedisOperator

  1. $ cat > redis-resource.yaml <<EOF
  2. apiVersion: apiextensions.k8s.io/v1beta1
  3. kind: CustomResourceDefinition
  4. metadata:
  5. name: redisoperators.nevercase.io
  6. spec:
  7. group: nevercase.io
  8. version: v1
  9. names:
  10. kind: RedisOperator
  11. plural: redisoperators
  12. scope: Namespaced
  13. EOF
  14. $ kubectl apply -f redis-resource.yaml
  15. customresourcedefinition.apiextensions.k8s.io/redisoperators.nevercase.io created

define demo file

  1. $ cat > example-redis.yaml <<EOF
  2. apiVersion: nevercase.io/v1
  3. kind: RedisOperator
  4. metadata:
  5. name: example-redis
  6. spec:
  7. masterSpec:
  8. spec:
  9. name: "redis-cn1"
  10. replicas: 1
  11. image: harbor.domain.com/helix-saga/redis-slave:1.1
  12. imagePullSecrets:
  13. - name: private-harbor
  14. volumePath: /mnt/nas1
  15. containerPorts:
  16. - containerPort: 6379
  17. protocol: TCP
  18. servicePorts:
  19. - port: 6379
  20. protocol: TCP
  21. targetPort: 6379
  22. resources:
  23. limits:
  24. memory: "1Gi"
  25. cpu: "100m"
  26. requests:
  27. memory: "0.5Gi"
  28. cpu: "100m"
  29. slaveSpec:
  30. spec:
  31. name: "redis-cn1"
  32. replicas: 4
  33. image: harbor.domain.com/helix-saga/redis-slave:1.1
  34. imagePullSecrets:
  35. - name: private-harbor
  36. volumePath: /mnt/nas1
  37. containerPorts:
  38. - containerPort: 6379
  39. protocol: TCP
  40. servicePorts:
  41. - port: 6379
  42. protocol: TCP
  43. targetPort: 6379
  44. resources:
  45. limits:
  46. memory: "1Gi"
  47. cpu: "100m"
  48. requests:
  49. memory: "0.5Gi"
  50. cpu: "100m"
  51. EOF
  52. $ kubectl apply -f example-redis.yaml
  53. redisoperator.nevercase.io/example-redis created

run the controller

  1. $ ./multiplexcrd -kubeconfig=$HOME/.kube/config -alsologtostderr=true
  2. I0603 14:48:38.844075 20412 controller.go:72] Setting up event handlers
  3. I0603 14:48:38.844243 20412 controller.go:195] Starting Foo controller
  4. I0603 14:48:38.844249 20412 controller.go:198] Waiting for informer caches to sync
  5. I0603 14:48:38.944352 20412 controller.go:209] Starting workers
  6. I0603 14:48:38.944366 20412 controller.go:215] Started workers
  7. ...
  8. I0603 14:48:47.721574 20412 event.go:255] Event(v1.ObjectReference{Kind:"RedisOperator", ... type: 'Normal' reason: 'Synced' Foo synced successfully

watch status

  1. $ kubectl get statefulset
  2. NAME READY AGE
  3. statefulset-redis-demo-master 1/1 46s
  4. statefulset-redis-demo-slave 4/4 46s
  5. $ kubectl get pod
  6. NAME READY STATUS RESTARTS AGE
  7. statefulset-redis-demo-master-0 1/1 Running 0 101s
  8. statefulset-redis-demo-slave-0 1/1 Running 0 101s
  9. statefulset-redis-demo-slave-1 1/1 Running 0 99s
  10. statefulset-redis-demo-slave-2 1/1 Running 0 98s
  11. statefulset-redis-demo-slave-3 1/1 Running 0 97s
  12. $ kubectl get svc
  13. NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
  14. service-redis-demo-master ClusterIP 10.96.110.148 <none> 6379/TCP 4m38s
  15. service-redis-demo-slave ClusterIP 10.96.0.120 <none> 6379/TCP 4m38s

MysqlOperator

The usage was the same with the RedisOperator.

New custom-controller

  1. opt := k8sCoreV1.NewOption(&mysqlOperatorV1.MysqlOperator{},
  2. controllerName,
  3. OperatorKindName,
  4. mysqlOperatorScheme.AddToScheme(scheme.Scheme),
  5. clientSet,
  6. fooInformer,
  7. fooInformer.Informer(),
  8. CompareResourceVersion,
  9. Get,
  10. Sync,
  11. SyncStatus)
  12. opts := k8sCoreV1.NewOptions()
  13. if err := opts.Add(opt); err != nil {
  14. klog.Fatal(err)
  15. }
  16. op := k8sCoreV1.NewKubernetesOperator(k8sClientSet, stopCh, controllerName, opts)
  17. kc := k8sCoreV1.NewKubernetesController(op)
  18. ...