OpenShift 4.3环境中创建基于Go的Operator

Posted ericnie

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了OpenShift 4.3环境中创建基于Go的Operator相关的知识,希望对你有一定的参考价值。

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

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

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

0.环境变量

GOROOT和GOPATH分开

[root@clientvm 0 ~]# 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-6277/auth/kubeconfig

 

1.项目结构

operator-sdk new memcached-operator
[root@clientvm 0 ~/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

9 directories, 14 files

 

2.添加CRD

operator-sdk add api     --api-version=cache.example.com/v1alpha1     --kind=Memcached
[root@clientvm 0 ~/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

4 directories, 9 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 0 ~/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

5 directories, 11 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: 11211,
                            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 0 ~/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 0 ~/src/github.com/example-inc/memcached-operator]# ls
build/    cmd/  deploy/  go.mod  go.sum  pkg/  tools.go  version/
[root@clientvm 0 ~/src/github.com/example-inc/memcached-operator]# operator-sdk build quay.io/example/memcached-operator:v0.0.1
INFO[0047] Building OCI image quay.io/example/memcached-operator:v0.0.1 
Sending build context to Docker daemon  40.1 MB
Step 1/7 : 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 2/7 : ENV OPERATOR /usr/local/bin/memcached-operator USER_UID 1001 USER_NAME memcached-operator
 ---> Running in 2afea6e66ac3
 ---> b57ea8f7ea83
Removing intermediate container 2afea6e66ac3
Step 3/7 : COPY build/_output/bin/memcached-operator ${OPERATOR}
 ---> 2c63ce7b17f5
Removing intermediate container e1c010812c09
Step 4/7 : COPY build/bin /usr/local/bin
 ---> 069feafcb1f1
Removing intermediate container abf95785f652
Step 5/7 : RUN /usr/local/bin/user_setup
 ---> Running in e1ef27d95dc1

+ mkdir -p /root
+ chown 1001:0 /root
+ chmod ug+rwx /root
+ chmod g+rw /etc/passwd
+ rm /usr/local/bin/user_setup
 ---> a1c897de8089
Removing intermediate container e1ef27d95dc1
Step 6/7 : ENTRYPOINT /usr/local/bin/entrypoint
 ---> Running in 31bb31653349
 ---> 58f90e9fdf8b
Removing intermediate container 31bb31653349
Step 7/7 : USER ${USER_UID}
 ---> Running in 9e905642d67f
 ---> 642d5912fcd9
Removing intermediate container 9e905642d67f
Successfully built 642d5912fcd9
INFO[0051] Operator build complete.    

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

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

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

以上是关于OpenShift 4.3环境中创建基于Go的Operator的主要内容,如果未能解决你的问题,请参考以下文章

K8S与OpenShift,异同安在?

openshift 4.3 calico + multus

openshift 4.3中安装helm3并通过helm方式部署应用

如何在 Redhat-SSO 映像中为 OpenShift 启用相互 SSL 验证模式

在 Xcode 4.3 中创建没有情节提要的项目

如何使用 TypedRowControllerType 在 Eureka 4.3 中创建自定义演示者行?