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

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. 并发编程之J.U.C的第一篇

    并发编程之J.U.C AQS 原理 ReentrantLock 原理 1. 非公平锁实现原理 2)可重入原理 3. 可打断原理 5) 条件变量实现原理 3. 读写锁 3.1 ReentrantRead ...

  2. XGBoost学习笔记2

    XGBoost API 参数 分类问题 使用逻辑回归 # Import xgboost import xgboost as xgb # Create arrays for the features a ...

  3. 从应用的角度去学习Python--为孩子下载课本

    最近,孩子上课都没有课本,老师给发的是一个微信链接,打开看可以,打印打不全.怎么办?我就想既然能看,从爬虫的角度就一定可以抓下来! 在Chrome中打开网址,好家伙!一堆的Script之类的玩意儿.经 ...

  4. java-标准输入

    package InputDemo; public class InputDemo1 { public static void main(String[] args) { /* 1. java.uti ...

  5. Radmin Server v3.5.1 汉化破解绿色版 第四版

    下载:https://pan.baidu.com/s/1skOXffJ 使用方法:1.运行“安装.bat”,安装过程静默,安装后无托盘图标,不创建任何快捷方式.2.运行“设置.bat”,进入 radm ...

  6. Python 一键安装全部依赖包

    使用 pip requirements.txt 用来记录项目所有的依赖包和版本号,只需要一个简单的 pip 命令就能完成. pip freeze > requirements.txt 生成的文件 ...

  7. Java输入和输出数组(加逗号)

    输入示例 61,2,3,4,5,6 输出示例 1,2,3,4,5,61,2,3,4,5,6 import java.util.Scanner; public class Demo01 { public ...

  8. jquery的封装与对象学习

    1.封装学习 /// <reference path="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js" /> ...

  9. 谷歌 AI 负责人谈2020 年机器学习趋势:多任务和多模态会有大突破

    ​在上周加拿大温哥华举行的NeurIPS会议上,机器学习成为了中心议题. 来自世界范围内约1.3万名研究人员集中探讨了神经科学.如何解释神经网络输出以及人工智能如何帮助解决现实世界中的重大问题等焦点话 ...

  10. Codeforces Round #615 (Div. 3) 补题记录

    第一次搞CF,结果惨不忍睹...还是太菜了 A:要用到全部的钱,所以总数必须是3的倍数,而且初始状态下任意一人的钱数不能超过总数除以3,否则没法分了 (也就这个签到算是在我能力范围之内了....) # ...