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

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. 全网小说免费阅读下载APP

    先说主题:今天分享一个全网小说免费阅读下载APP.这篇文章是凌晨2点钟写的,原因呢可能有两点: 半夜无眠,一时兴起就想分享点有用的东西给大家,就问你感动不?其实吧,可能是晚上喝了点儿浓茶导致的无眠,所 ...

  2. memcached与redis比较

    1- memcached介绍 Memcached是一个自由开源的,高性能,分布式内存对象缓存系统. Memcached是以LiveJournal旗下Danga Interactive公司的Brad F ...

  3. pycharm out of memory 闪退

    不知道从什么时候开始,python开始报 out of memory. 把pycharm64.exe.vmoptions -Xmx 调成1024m或者2048m pycharm就打不开了 低了不能用, ...

  4. Wannafly Winter Camp 2020 Day 7A 序列 - 树状数组

    给定一个全排列,对于它的每一个子序列 \(s[1..p]\),对于每一个 \(i \in [1,p-1]\),给 \(s[i],s[i+1]\) 间的每一个值对应的桶 \(+1\),求最终每个桶的值. ...

  5. jrtp 使用

    jrtplib-3.11.1 使用jthread-1.3.3 # cmake 下载https://cmake.org/download/ 使用地址https://github.com/j0r1/JRT ...

  6. salt 安装 以及salt-api使用

    salt--master    和 salt-minion 控制端 被控制端 通过 salt-api 访问 salt-master  来控制salt-minion 执行 命令  返回结果 LINUX ...

  7. 纪中5日T2 1565. 神秘山庄

    1565. 神秘山庄 (Standard IO) 原题 题目描述 翠亨村是一个神秘的山庄,并不是因为它孕育了伟人孙中山,更神秘的是山庄里有N只鬼.M只兔子,当然还有你.其中每秒钟: 1. 恰有两个生物 ...

  8. JavaDay7(下)

    问题1描述 编写一个方法,返回一个double类型二维数组,数组中的元素通过解析字符串参数获得. 代码实现: public class ArrayParser { public static void ...

  9. Candies POJ - 3159 差分约束

    // #include<iostream> #include<cstring> #include<queue> #include<stack> #inc ...

  10. 从零开始的JAVA(1).输入

    理一遍JAVA的输入和输出,跟C语言还是有点不用的,虽然以前学过一点.不过好像忘的一干二净了哈哈.从头来一遍把,这次跟着翁恺老师GOGO 1.输出语句:System.out.println();--快 ...