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

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

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

OpenShift 4.3环境中创建基于Go的Operator的更多相关文章

  1. 她娇羞道“不用这样细致认真的说啊~~”———详细图解在Linux环境中创建运行C程序

    她娇羞说,不用这样细致认真的说啊———详细图解在Linux环境中创建运行C程序“不,这是对学习的负责”我认真说到 叮叮叮,停车,让我们看看如何在Linux虚拟机环境中,创建运行C程序 详细图解在Lin ...

  2. ASP.NET 在 Windows Azure 环境中使用基于 SQLServer 的 Session

    Session 嘛,占一点儿服务器资源,但是总归比 ViewState 和 Cookie 安全点儿,所以还是要用的. Windows Azure 环境中的 Web 服务器经由负载均衡调度,根本无法保证 ...

  3. MFC中 创建基于CFormView的文档视图程序

    在MFC中可以创建多种类型的窗口程序,如对话框程序.单文档结构程序(非文档/视图结构).单文档(文档/视图结构)以及多文档视图结构程序等. 在编写一般的小工具时,我们的首选显然是对话框程序,不过基于对 ...

  4. 在ASP.NET Core中创建基于Quartz.NET托管服务轻松实现作业调度

    在这篇文章中,我将介绍如何使用ASP.NET Core托管服务运行Quartz.NET作业.这样的好处是我们可以在应用程序启动和停止时很方便的来控制我们的Job的运行状态.接下来我将演示如何创建一个简 ...

  5. centos7无网络环境下创建基于scratch镜像的Linux镜像,并带有Java运行环境

    一.准备 将下载好的jdk以及scratch镜像放在同一文件夹下:这里放在linux:2.0 二.导入scratch镜像 #docker load -i scratch.tar 三.创建dockerf ...

  6. lanmp环境中创建个软连接

    进入default,创建关于框架的链接 然后编辑配置文件 这样就可以在线上访问了.

  7. linux环境中通过useradd命令,创建用户的时候指定用户的base-dir

    需求说明: 今天一个同事,问了一个这样的问题,在linux环境中,创建用户的时候,默认的是在/home目录下创建一个与用户名相同的家目录, 如何能够将这个/home更换成一个其他的,比如/opt/ap ...

  8. 详解Linux交互式shell脚本中创建对话框实例教程_linux服务器

    本教程我们通过实现来讲讲Linux交互式shell脚本中创建各种各样对话框,对话框在Linux中可以友好的提示操作者,感兴趣的朋友可以参考学习一下. 当你在终端环境下安装新的软件时,你可以经常看到信息 ...

  9. 在kubernetes集群中创建redis主从多实例

    分类 > 正文 在kubernetes集群中创建redis主从多实例 redis-slave镜像制作 redis-master镜像制作 创建kube的配置文件yaml 继续使用上次实验环境 ht ...

随机推荐

  1. 清北学堂—2020.1提高储备营—Day 4 afternoon(动态规划初步(一))

    qbxt Day 4 afternoon --2020.1.20 济南 主讲:顾霆枫 目录一览 1.动态规划初步 2.记忆化搜索 3.递推式动态规划 4.记忆话搜索与递推式动态规划的转化 5.状态转移 ...

  2. gRPC搭建使用方式

    gRpc 官网  链接 新建服务端项目 在服务端内先编写一个 .proto 文件 greet.proto syntax = "proto3"; service Greeter { ...

  3. 拓展lucas结论及模板

    lucas及其拓展 模板题 洛谷 P4720 本文侧向结论和代码实现, 推导请转至lucas定理及其拓展的推导 https://blog.csdn.net/yuyilahanbao/article/d ...

  4. EasyUI笔记(六)数据表格

    前言用asp.net结合easyui做个一个数据网格的页面,包括对数据的增删改查,界面如下:  一.UI界面 先写UI界面,代码如下,记得引入相关js和css文件 <body> <t ...

  5. LNMP+HTTPS

    title: "Lnmp + Https" date: 2019-08-28T16:18:20+08:00 draft: true --- 注:我的linux的ip地址为192.1 ...

  6. python + excel工资条自动生成

    年终绩效分配结果出来了,领导要求每人要清楚地知道自己的情况.要求:总绩效和各分类都要清楚.这就表示我们要给每人六个纸条,一个总的,五个分的.打出来,裁开,分发给每个人!累死人.所以,我就想能否每人生成 ...

  7. C语言中File的应用

    #C语言中规定我们使用文件必须初始化一个文件指针 FILE* pfile = NULL; #以a+追加的方式打开文件 返回值0为打开成功 int fp = fopen_s(&pfile, &q ...

  8. lint-staged 使用教程

    lint-staged 是一个在git暂存文件上运行linters的工具,当然如果你觉得每次修改一个文件就给所有文件执行一次lint检查不恶心的话,这个工具对你来说就没有什么意义了,请直接关闭即可. ...

  9. 在写论文的参考文献时,有的段落空格很大,有的段落则正常,原因及解决方法(wps)

    下图是一段原始的参考文献,可以看出第一行的空格很大: 原因: 当一个词占不下时,自动将单词移动到下一行,但是这一行又有很多字符,因此这时,软件会将空闲的位置用空白字符填满.第一行有两个空白字符,因此将 ...

  10. LeetCode 145. 二叉树的后序遍历 (用栈实现后序遍历二叉树的非递归算法)

    题目链接:https://leetcode-cn.com/problems/binary-tree-postorder-traversal/ 给定一个二叉树,返回它的 后序 遍历. 示例: 输入: [ ...