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

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. 鼠标经过INPUT时自动获取焦点

    鼠标经过INPUT时自动获取焦点 <input type="text" name="addr" onMouseOver="this.focus( ...

  2. SVN使用经验

    转载于:Svn发布项目 个人使用体验: 关于svn的相关命令 从服务器检出创建的项目文件夹,向项目中添加文件,右键tortoiseSvn->add 然后右键SVN Commit,选择文件并输入提 ...

  3. js模拟form提交 导出数据

    //创建模拟提交formfunction dataExport(option) { var form = $("<form method='get'></form>& ...

  4. 简单java web制作思路

    经过俩天的摸索,和学姐的帮助下终于做出来一个简单地网页版的学生信息添加的系统.接下来说一下答题的思路: 首先我个人习惯先做网页界面,创建3个jsp文件分别是添加界面,成功界面,失败界面.这件看起来更加 ...

  5. IDA PRO

    链接:https://pan.baidu.com/s/1LTXhXra5Honpn3L9rfSOgA 提取码:7bwb 工具下载地址: https://www.jb51.net/softjc/5799 ...

  6. Uva1363(余数性质/减少枚举量)

    题意: 输入正整数n和k(范围均为1e9),求∑(k mod i),i从1~n 解法: 首先这道题直接暴力亲测会超时. 之后我们写几组数据之后可以发现当k/i的商相同的时候他们的余数成一个等差数列,而 ...

  7. pyqt5-下拉框联动效果

    from PyQt5.Qt import * class MyWindow(QWidget): def __init__(self): super().__init__() self.setWindo ...

  8. HTML5创建高德地图

    创建高德地图 功能真的很好很强大,有图有证据! 1.申请key值 去官网2.https://webapi.amap.com/maps?v=1.4.11&key=e22196035aaa10db ...

  9. MVC开发之注入容器Ninject的使用

    背景 在不使用注入容器之前,我们的项目往往存在着大量耦合的类,这使得我们在开发大型项目时难以维护.比如下面这个简单的MVC框架的例子,计算购物车的产品价格总和: /// <summary> ...

  10. 【巨杉数据库SequoiaDB】省级农信国产分布式数据库应用实践

    本文转载自<金融电子化> 原文链接:https://mp.weixin.qq.com/s/WGG91Rv9QTBHPsNVPG8Z5g 随着移动互联网的迅猛发展,分布式架构在互联网IT技术 ...