Operator 示例:使用 Redis 部署 PHP 留言板应用程序

  • 安装 Docker Desktop,并启动内置的 Kubernetes 集群
  • 注册一个hub.docker.com 账户,需要将本地构建好的镜像推送至公开仓库中
  • 安装 operator SDK CLI: brew install operator-sdk
  • 安装 Go: brew install go

本示例推荐的依赖版本:

  • Docker Desktop: >= 4.0.0
  • Kubernetes: >= 1.21.4
  • Operator-SDK: >= 1.11.0
  • Go: >= 1.17

jxlwqq 为笔者的 ID,命令行和代码中涉及的个人 ID,均需要替换为读者自己的,包括

  • --domain=
  • --repo=
  • //+kubebuilder:rbac:groups=
  • IMAGE_TAG_BASE ?=

使用 Operator SDK CLI 创建名为 guestbook-operator 的项目。

mkdir -p $HOME/projects/guestbook-operator
cd $HOME/projects/guestbook-operator
go env -w GOPROXY=https://goproxy.cn,direct
shell

operator-sdk init \
--domain=jxlwqq.github.io \
--repo=github.com/jxlwqq/guestbook-operator \
--skip-go-version-check
</code></pre>
<p>使用 Operator SDK CLI 创建自定义资源定义(CRD)API 和控制器。</p>
<p>运行以下命令创建带有组 app、版本 v1alpha1 和种类 Guestbook 的 API:</p>
<pre><code class="language-shell">operator-sdk create api \
--resource=true \
--controller=true \
--group=app \
--version=v1alpha1 \
--kind=Guestbook
</code></pre>
<p>定义 Guestbook 自定义资源(CR)的 API。</p>
<p>修改 api/v1alpha1/guestbook_types.go 中的 Go 类型定义,使其具有以下 spec 和 status</p>
<pre><code class="language-go">type GuestbookSpec struct {
    FrontendSize int32 :"frontendSize"
    RedisFollowerSize int32 :"redisFollowerSize"`
}

为资源类型更新生成的代码:

make generate

运行以下命令以生成和更新 CRD 清单:

make manifests

由于逻辑较为复杂,代码较为庞大,所以无法在此全部展示,完整的操作器代码请参见 controllers 目录。
在本例中,将生成的控制器文件 controllers/guestbook_controller.go 替换为以下示例实现:

/*
Copyright 2021.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.

You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

See the License for the specific language governing permissions and
limitations under the License.

*/

package controllers

import (
    "context"
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    "k8s.io/apimachinery/pkg/api/errors"

    "k8s.io/apimachinery/pkg/runtime"
    ctrl "sigs.k8s.io/controller-runtime"
    "sigs.k8s.io/controller-runtime/pkg/client"
    "sigs.k8s.io/controller-runtime/pkg/log"

    appv1alpha1 "github.com/jxlwqq/guestbook-operator/api/v1alpha1"
)

// GuestbookReconciler reconciles a Guestbook object
type GuestbookReconciler struct {
    client.Client
    Scheme *runtime.Scheme
}

//+kubebuilder:rbac:groups=app.jxlwqq.github.io,resources=guestbooks,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=app.jxlwqq.github.io,resources=guestbooks/status,verbs=get;update;patch
//+kubebuilder:rbac:groups=app.jxlwqq.github.io,resources=guestbooks/finalizers,verbs=update
//+kubebuilder:rbac:groups=apps,resources=deployments,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=service,verbs=get;list;watch;create;update;patch;delete
//+kubebuilder:rbac:groups=core,resources=pods,verbs=get;list;watch

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.

// TODO(user): Modify the Reconcile function to compare the state specified by
// the Guestbook object against the actual cluster state, and then
// perform operations to make the cluster state reflect the state specified by
// the user.

//
// For more details, check Reconcile and its Result here:
// - https://pkg.go.dev/sigs.k8s.io/controller-runtime@v0.9.2/pkg/reconcile
func (r *GuestbookReconciler) Reconcile(ctx context.Context, req ctrl.Request) (ctrl.Result, error) {
    reqLogger := log.FromContext(ctx)
    reqLogger.Info("Reconciling Guestbook")

    guestbook := &appv1alpha1.Guestbook{}
    err := r.Client.Get(context.TODO(), req.NamespacedName, guestbook)
    if err != nil {
        if errors.IsNotFound(err) {
            return ctrl.Result{}, nil
        }
        return ctrl.Result{}, err
    }

    var result = &ctrl.Result{}

    result, err = r.ensureDeployment(r.redisLeaderDeployment(guestbook))
    if result != nil {
        return *result, err
    }
    result, err = r.ensureService(r.redisLeaderService(guestbook))
    if result != nil {
        return *result, err
    }

    result, err = r.ensureDeployment(r.redisFollowerDeployment(guestbook))
    if result != nil {
        return *result, err
    }
    result, err = r.ensureService(r.redisFollowerService(guestbook))
    if result != nil {
        return *result, err
    }
    result, err = r.handleRedisFollowerChanges(guestbook)
    if result != nil {
        return *result, err
    }

    result, err = r.ensureDeployment(r.frontendDeployment(guestbook))
    if result != nil {
        return *result, err
    }
    result, err = r.ensureService(r.frontendService(guestbook))
    if result != nil {
        return *result, err
    }
    result, err = r.handleFrontendChanges(guestbook)
    if result != nil {
        return *result, err
    }

    return ctrl.Result{}, nil
}

// SetupWithManager sets up the controller with the Manager.

func (r *GuestbookReconciler) SetupWithManager(mgr ctrl.Manager) error {
    return ctrl.NewControllerManagedBy(mgr).
        For(&appv1alpha1.Guestbook{}).
        Owns(&appsv1.Deployment{}).
        Owns(&corev1.Service{}).
        Complete(r)
}

运行以下命令以生成和更新 CRD 清单:

make manifests

捆绑 Operator,并使用 Operator Lifecycle Manager(OLM)在集群中部署。

修改 Makefile 中 IMAGE_TAG_BASE 和 IMG:

IMAGE_TAG_BASE ?= docker.io/jxlwqq/guestbook-operator
IMG ?= $(IMAGE_TAG_BASE):latest

构建镜像:

make docker-build

将镜像推送到镜像仓库:

make docker-push

运行 make bundle 命令创建 Operator 捆绑包清单,并依次填入名称、作者等必要信息:

make bundle

构建捆绑包镜像:

make bundle-build

推送捆绑包镜像:

make bundle-push

使用 Operator Lifecycle Manager 部署 Operator:

切换至本地集群
kubectl config use-context docker-desktop
安装 olm
operator-sdk olm install
使用 Operator SDK 中的 OLM 集成在集群中运行 Operator
operator-sdk run bundle docker.io/jxlwqq/guestbook-operator-bundle:v0.0.1

编辑 config/samples/app_v1alpha1_guestbook.yaml 上的 Guestbook CR 清单示例,使其包含以下规格:

apiVersion: app.jxlwqq.github.io/v1alpha1
kind: Guestbook
metadata:
  name: guestbook-sample
spec:
  # Add fields here
  frontendSize: 2
  redisFollowerSize: 2

创建 CR:

kubectl apply -f config/samples/app_v1alpha1_guestbook.yaml

查看 Pod:

NAME                              READY   STATUS    RESTARTS   AGE
frontend-85595f5bf9-jrcp4         1/1     Running   0          9s
frontend-85595f5bf9-q8fkl         1/1     Running   0          9s
redis-follower-76c5cc5b79-fxxlq   1/1     Running   0          9s
redis-follower-76c5cc5b79-g8vnf   1/1     Running   0          9s
redis-leader-6666df964-vjhp2      1/1     Running   0          9s

查看 Service:

NAME             TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
frontend         NodePort    10.106.145.169           80:30693/TCP   24s
kubernetes       ClusterIP   10.96.0.1                443/TCP        4m58s
redis-follower   ClusterIP   10.108.30.112            6379/TCP       24s
redis-leader     ClusterIP   10.106.255.152           6379/TCP       24s

网页上会显示出 Guestbook 的表单页面。

更新 CR:

修改frontend 和 redis 副本数
kubectl patch guestbook guestbook-sample -p '{"spec":{"frontendSize": 3, "redisFollowerSize": 3}}' --type=merge

查看 Pod:

NAME                              READY   STATUS    RESTARTS   AGE
frontend-85595f5bf9-4pmfj         1/1     Running   0          4s
frontend-85595f5bf9-jrcp4         1/1     Running   0          50s
frontend-85595f5bf9-q8fkl         1/1     Running   0          50s
redis-follower-76c5cc5b79-bxbb4   1/1     Running   0          4s
redis-follower-76c5cc5b79-fxxlq   1/1     Running   0          50s
redis-follower-76c5cc5b79-g8vnf   1/1     Running   0          50s
redis-leader-6666df964-vjhp2      1/1     Running   0          50s
operator-sdk cleanup guestbook-operator
operator-sdk olm uninstall

Original: https://www.cnblogs.com/jxlwqq/p/15264489.html
Author: jxlwqq
Title: Operator 示例:使用 Redis 部署 PHP 留言板应用程序

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/516600/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • golang 标准库template的代码生成

    最近,随着 antd Pro v5 的升级,将项目进行了升级,现在生成的都是 ts 代码。这个项目的自动生成代码都是基于 golang 的标准库 template 的,所以这篇博客…

    Go语言 2023年5月25日
    049
  • 生产者消费者模型及Golang简单实现

    简介:介绍生产者消费者模型,及go简单实现的demo。 一、生产者消费者模型 生产者消费者模型:某个模块(函数等〉负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,…

    Go语言 2023年5月25日
    051
  • 基于Go语言实现好用的HTTP接口请求requests

    使用Go自带的net/http库可以发送各种HTTP请求。然而各种类型请求发送方式有点不太一致,这里参考Python requests库的使用方式,简单封装了一下。代码如下: 文件…

    Go语言 2023年5月29日
    064
  • 一次Kafka内存泄露排查经过

    一、现象 服务部署后内存总体呈上升趋势 二、排查过程 通过go tool pprof收集了三天内存数据 2月11号数据: 2月14号数据: 2月15号数据: 我们使用sarama客…

    Go语言 2023年5月25日
    064
  • Go语言之接口

    接口就是一系列方法的集合(规范行为) 在面向对象的领域里,接口一般这样定义:接口定义一个对象的行为,规范子类对象的行为。 在 Go 语言中的接口是非侵入式接口(接口没了,不影响代码…

    Go语言 2023年5月25日
    064
  • Sentinel-Go 源码系列(一)|开篇

    大家好呀,打算写一个 Go 语言组件源码分析系列,一是为了能学习下 Go 语言,看下别人是怎么写 Go 的,二是也掌握一个组件。 本次选择了 Sentinel-Go,一是对 Jav…

    Go语言 2023年5月25日
    070
  • TCP粘”包”问题浅析及解决方案Golang代码实现

    一、粘”包”问题简介 在socket网络编程中,都是端到端通信, 客户端端口+客户端IP+服务端端口+服务端IP+传输协议就组成一个可以唯一可以明确的标识一…

    Go语言 2023年5月25日
    063
  • 如何在 Go 中将 []byte 转换为 io.Reader?

    原文链接: 如何在 Go 中将 []byte 转换为 io.Reader? 在 stackoverflow 上看到一个问题,题主进行了一个网络请求,接口返回的是 []byte。如果…

    Go语言 2023年5月25日
    076
  • Context包源码解析(附面经)

    Context就相当于一个树状结构最后请回答一下这个问题:context包中的方法是线程安全吗? Context包中主要有一个接口和三个结构体 type Context inter…

    Go语言 2023年5月25日
    065
  • go-micro集成RabbitMQ实战和原理

    在go-micro中异步消息的收发是通过Broker这个组件来完成的,底层实现有RabbitMQ、Kafka、Redis等等很多种方式,这篇文章主要介绍go-micro使用Rabb…

    Go语言 2023年5月25日
    071
  • go泛型教程

    导读: 约束 使用方法 实现原理 跟其它语言的泛型进行对比 用例子学泛型 issues 泛型需满足 go1.18+ go使用interface作为约束,约束的意思是约束了这个泛型都…

    Go语言 2023年5月25日
    061
  • 从零开始搭建GoLang语言开发环境

    更多干货文章,更多最新文章,欢迎到作者主博客 菜鸟厚非 一、安装 GoLang 1.1 下载 首先访问 https://go.dev/dl/ 下载 GoLang,下载完成后双击安装…

    Go语言 2023年5月25日
    072
  • Go语言学习笔记1

    1.Go语言环境搭建及基础知识 Go语言官方网站(http://golang.org)代码包文档网站(http://godoc.org)Go语言中文网(http://studygo…

    Go语言 2023年5月29日
    068
  • 【译】eBPF 和 Go 经验初探

    原文地址:https://networkop.co.uk/post/2021-03-ebpf-intro/首发地址: 【译】eBPF 和 Go 经验初探本站相关文档:使用 Go 语…

    Go语言 2023年5月25日
    070
  • Go微服务框架go-kratos学习05:分布式链路追踪 OpenTelemetry 使用

    一、分布式链路追踪发展简介 1.1 分布式链路追踪介绍 关于分布式链路追踪的介绍,可以查看我前面的文章 微服务架构学习与思考(09):分布式链路追踪系统-dapper论文学习(ht…

    Go语言 2023年5月25日
    055
  • go语言标准库

    学习go 语言,如果不知道标准库,那很多能力就不知道,标准库应该是程序员可以背下来的 bufio bytes container crypto database debug enc…

    Go语言 2023年5月29日
    061
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球