OpenShift 4.3环境中创建基于Go的Operator
详细步骤可以参考官方文档
https://docs.openshift.com/container-platform/4.3/operators/operator_sdk/osdk-getting-started.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这个文件,修改完后的参考
主要是几个部分:
- 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
然后按照文档操作继续。。。。。。