详细步骤可以参考官方文档

https://docs.openshift.com/container-platform/4.3/operators/operator_sdk/osdk-getting-started.html

我这里只是记录一些中间过程和思考。

0.环境变量

GOROOT和GOPATH分开

[root@clientvm  ~]# cat .bash_profile
# .bash_profile # Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi # User specific environment and startup programs export GOROOT=/usr/local/go
export GOPATH=/
root export PATH=$PATH:$HOME/bin:/usr/local/bin:/usr/local/maven/bin:/usr/local/go/bin
export GUID=`hostname | awk -F. '{print $2}'` export KUBECONFIG=/root/cluster-/auth/kubeconfig

1.项目结构

operator-sdk new memcached-operator
[root@clientvm  ~/src/github.com/example-inc]# tree memcached-operator/
memcached-operator/
├── build
│   ├── bin
│   │   ├── entrypoint
│   │   └── user_setup
│   └── Dockerfile
├── cmd
│   └── manager
│   └── main.go
├── deploy
│   ├── operator.yaml
│   ├── role_binding.yaml
│   ├── role.yaml
│   └── service_account.yaml
├── go.mod
├── go.sum
├── pkg
│   ├── apis
│   │   └── apis.go
│   └── controller
│   └── controller.go
├── tools.go
└── version
└── version.go directories, files

2.添加CRD

operator-sdk add api \
--api-version=cache.example.com/v1alpha1 \
--kind=Memcached
[root@clientvm  ~/src/github.com/example-inc/memcached-operator]# tree pkg
pkg
├── apis
│   ├── addtoscheme_cache_v1alpha1.go
│   ├── apis.go
│   └── cache
│   ├── group.go
│   └── v1alpha1
│   ├── doc.go
│   ├── memcached_types.go
│   ├── register.go
│   ├── zz_generated.deepcopy.go
│   └── zz_generated.openapi.go
└── controller
└── controller.go directories, files

3.添加控制器

operator-sdk add controller \
--api-version=cache.example.com/v1alpha1 \
--kind=Memcached

INFO[0000] Generating controller version cache.example.com/v1alpha1 for kind Memcached.
INFO[0000] Created pkg/controller/memcached/memcached_controller.go
INFO[0000] Created pkg/controller/add_memcached.go
INFO[0000] Controller generation complete.

[root@clientvm  ~/src/github.com/example-inc/memcached-operator]# tree pkg
pkg
├── apis
│   ├── addtoscheme_cache_v1alpha1.go
│   ├── apis.go
│   └── cache
│   ├── group.go
│   └── v1alpha1
│   ├── doc.go
│   ├── memcached_types.go
│   ├── register.go
│   ├── zz_generated.deepcopy.go
│   └── zz_generated.openapi.go
└── controller
├── add_memcached.go
├── controller.go
└── memcached
└── memcached_controller.go directories, files

比较核心的就是memcached_controller.go这个文件,修改完后的参考

https://github.com/operator-framework/operator-sdk/blob/master/example/memcached-operator/memcached_controller.go.tmpl

主要是几个部分:

  • watch方法:自动生成的文件是watch pod, 而我们基于deployment部署,所以要修改。
err := c.Watch(&source.Kind{Type: &appsv1.Deployment{}}, &handler.EnqueueRequestForOwner{
IsController: true,
OwnerType: &cachev1alpha1.Memcached{},
})
  • Reconcile: 调节器,也就是根据CR的配置进行调整。
func (r *ReconcileMemcached) Reconcile(request reconcile.Request) (reconcile.Result, error)
  • deploymentForMemcached:决定了CR如何创建
// deploymentForMemcached returns a memcached Deployment object
func (r *ReconcileMemcached) deploymentForMemcached(m *cachev1alpha1.Memcached) *appsv1.Deployment {
ls := labelsForMemcached(m.Name)
replicas := m.Spec.Size dep := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Name: m.Name,
Namespace: m.Namespace,
},
Spec: appsv1.DeploymentSpec{
Replicas: &replicas,
Selector: &metav1.LabelSelector{
MatchLabels: ls,
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: ls,
},
Spec: corev1.PodSpec{
Containers: []corev1.Container{{
Image: "memcached:1.4.36-alpine",
Name: "memcached",
Command: []string{"memcached", "-m=64", "-o", "modern", "-v"},
Ports: []corev1.ContainerPort{{
ContainerPort: ,
Name: "memcached",
}},
}},
},
},
},
}
// Set Memcached instance as the owner and controller
controllerutil.SetControllerReference(m, dep, r.scheme)
return dep
}

这个方法在reconcil中调用,发现没有实例就自动创建。

found := &appsv1.Deployment{}
err = r.client.Get(context.TODO(), types.NamespacedName{Name: memcached.Name, Namespace: memcached.Namespace}, found)
if err != nil && errors.IsNotFound(err) {
// Define a new deployment
dep := r.deploymentForMemcached(memcached)
reqLogger.Info("Creating a new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
err = r.client.Create(context.TODO(), dep)
if err != nil {
reqLogger.Error(err, "Failed to create new Deployment", "Deployment.Namespace", dep.Namespace, "Deployment.Name", dep.Name)
return reconcile.Result{}, err
}
// Deployment created successfully - return and requeue
return reconcile.Result{Requeue: true}, nil
} else if err != nil {
reqLogger.Error(err, "Failed to get Deployment")
return reconcile.Result{}, err
}

4.进行下面的步骤

[root@clientvm  ~/src/github.com/example-inc/memcached-operator]# oc create     -f deploy/crds/cache.example.com_memcacheds_crd.yaml
customresourcedefinition.apiextensions.k8s.io/memcacheds.cache.example.com created
[root@clientvm ~/src/github.com/example-inc/memcached-operator]# ls
build/ cmd/ deploy/ go.mod go.sum pkg/ tools.go version/
[root@clientvm ~/src/github.com/example-inc/memcached-operator]# operator-sdk build quay.io/example/memcached-operator:v0.0.1
INFO[] Building OCI image quay.io/example/memcached-operator:v0.0.1
Sending build context to Docker daemon 40.1 MB
Step / : FROM registry.access.redhat.com/ubi8/ubi-minimal:latest
Trying to pull repository registry.access.redhat.com/ubi8/ubi-minimal ...
latest: Pulling from registry.access.redhat.com/ubi8/ubi-minimal
03e56b46bf0b: Pull complete
3a13cc2f5d65: Pull complete
Digest: sha256:9285da611437622492f9ef4229877efe302589f1401bbd4052e9bb261b3d4387
Status: Downloaded newer image for registry.access.redhat.com/ubi8/ubi-minimal:latest
---> db39bd4846dc
Step / : ENV OPERATOR /usr/local/bin/memcached-operator USER_UID USER_NAME memcached-operator
---> Running in 2afea6e66ac3
---> b57ea8f7ea83
Removing intermediate container 2afea6e66ac3
Step / : COPY build/_output/bin/memcached-operator ${OPERATOR}
---> 2c63ce7b17f5
Removing intermediate container e1c010812c09
Step / : COPY build/bin /usr/local/bin
---> 069feafcb1f1
Removing intermediate container abf95785f652
Step / : RUN /usr/local/bin/user_setup
---> Running in e1ef27d95dc1 + mkdir -p /root
+ chown : /root
+ chmod ug+rwx /root
+ chmod g+rw /etc/passwd
+ rm /usr/local/bin/user_setup
---> a1c897de8089
Removing intermediate container e1ef27d95dc1
Step / : ENTRYPOINT /usr/local/bin/entrypoint
---> Running in 31bb31653349
---> 58f90e9fdf8b
Removing intermediate container 31bb31653349
Step / : USER ${USER_UID}
---> Running in 9e905642d67f
---> 642d5912fcd9
Removing intermediate container 9e905642d67f
Successfully built 642d5912fcd9
INFO[] Operator build complete.

这是在本地生成了Operator的镜像,然后需要tag和推到自己的镜像仓库

[root@clientvm  ~/src/github.com/example-inc/memcached-operator]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
quay.io/example/memcached-operator v0.0.1 642d5912fcd9 seconds ago MB

然后按照文档操作继续。。。。。。

最新文章

  1. 从零开始,DIY一个jQuery(2)
  2. 百度地图JavaScript API自定义覆盖物、自定义信息窗口增删时的显示问题
  3. mysql 增删改查基本语句
  4. Python 获取学校图书馆OAPC账号对应的身份证号码
  5. mina 字节数组编解码器的写法 II
  6. bzoj 3198 [Sdoi2013]spring(容斥原理+Hash)
  7. android 30 下拉列表框:ArrayAdapter和Spinner.
  8. npm scripts 助力前端开发,实时刷新浏览器
  9. jsp中的c标签
  10. C语言基础知识点整理(函数/变量/常量/指针/数组/结构体)
  11. 【wannacry病毒之暗网】-如何访问"暗网"(慎入)
  12. TCP常见的定时器三次握手与四次挥手
  13. PHP、Java、Python、C、C++ 这几种编程语言都各有什么特点或优点
  14. 【SSH系列】---Hibernate的基本映射
  15. 04 SimpleAdapter
  16. codeforces 893F - Physical Education Lessons 动态开点线段树合并
  17. 令人血脉喷张的animate.css
  18. Java日期比较
  19. Shell 中expr的使用
  20. vs2017 xamarin新建单独UWP类库提示不兼容

热门文章

  1. junit 运行(eclipse + IDEA)
  2. python+appium+真机测试
  3. Java遍历字符串数组的几种方法
  4. NoSQLBooster如何MongoDB的部分文档从一个集合拷贝到另外一个集合中
  5. Linux中为什么执行自己的程序要在前面加./
  6. Uva10791 唯一分解定理模板
  7. 基于光盘配置yum源
  8. pyjsonrpc的使用
  9. iframe在iphone手机上的问题
  10. windows密码抓取工具-mimikatz