operator实战

1⃣️ 需求

我们将定义一个 crd ,spec 包含以下信息:

Replicas    # 副本数
Image        # 镜像
Resources    # 资源限制
Envs        # 环境变量
Ports        # 服务端口

2⃣️ 编码

初始化项目目录:

tony@192 k8s % pwd
/Users/tony/workspace/k8s
tony@192 k8s % mkdir -p app-operator/src/github.com/xuzhijvn/app
cd app-operator/src/github.com/xuzhijvn/app

初始化operator项目结构,并创建api:

 operator-sdk init --domain=huolala.cn --repo=github.com/xuzhijvn/app
 operator-sdk create api --group app --version v1 --kind App --resource=true --controller=true

修改 CRD 类型定义代码 api/v1/app_types.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 v1

import (
    appsv1 "k8s.io/api/apps/v1"
    corev1 "k8s.io/api/core/v1"
    metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// EDIT THIS FILE!  THIS IS SCAFFOLDING FOR YOU TO OWN!
// NOTE: json tags are required.  Any new fields you add must have json tags for the fields to be serialized.

// AppSpec defines the desired state of App
type AppSpec struct {
    // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster
    // Important: Run "make" to regenerate code after modifying this file

    // Foo is an example field of App. Edit app_types.go to remove/update
    //Foo string `json:"foo,omitempty"`
    Replicas  *int32                      `json:"replicas"`            // 副本数
    Image     string                      `json:"image"`               // 镜像
    Resources corev1.ResourceRequirements `json:"resources,omitempty"` // 资源限制
    Envs      []corev1.EnvVar             `json:"envs,omitempty"`      // 环境变量
    Ports     []corev1.ServicePort        `json:"ports,omitempty"`     // 服务端口
}

// AppStatus defines the observed state of App
type AppStatus struct {
    // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster
    // Important: Run "make" to regenerate code after modifying this file
    appsv1.DeploymentStatus `json:",inline"` // 直接引用 DeploymentStatus
}

//+kubebuilder:object:root=true
//+kubebuilder:subresource:status

// App is the Schema for the apps API
type App struct {
    metav1.TypeMeta   `json:",inline"`
    metav1.ObjectMeta `json:"metadata,omitempty"`

    Spec   AppSpec   `json:"spec,omitempty"`
    Status AppStatus `json:"status,omitempty"`
}

//+kubebuilder:object:root=true

// AppList contains a list of App
type AppList struct {
    metav1.TypeMeta `json:",inline"`
    metav1.ListMeta `json:"metadata,omitempty"`
    Items           []App `json:"items"`
}

func init() {
    SchemeBuilder.Register(&App{}, &AppList{})
}

新增 resource/deployment/deployment.go:

新增 resource/service/service.go

修改 controller 代码 controllers/app_controller.go

修改 CRD 资源定义 config/samples/app_v1_app.yaml

修改 Dockerfile

  • 添加了 goproxy 环境变量

  • 新增 COPY 自定义的文件夹 resource

  • gcr.io/distroless/static:nonroot 变更为 kubeimages/distroless-static:latest

3⃣️ 部署

xuzhijvn 项目根目录执行:

安装crd到集群

结果确认

构建镜像

==特别注意==☢️

⚠️ 1. 因为docker-build会执行测试,测试的时候需要连接github下载脚本运行,此时极有可能会报443的连接错误,所以我们把test注释掉。

image-20210627223227260

⚠️ 2. 下图位置默认的镜像地址是gcr.io/kubebuilder/kube-rbac-proxy:v0.8.0 这个地址国内无法拉取到镜像,所以需要替换成自己的镜像地址(可以先找台国外的服务器拉取下来,重新打tag后推送到自己的镜像仓库),如果不修改,容器ccr.ccs.tencentyun.com/huolala.cn/app:v1无法启动。

image-20210627223536610

⚠️ 3. 将 controller 部署到 k8s 集群的时候,可能会出现 RBAC 权限错误,解决方法是修改部署时的权限配置,这里我们使用最简单的方法是直接给 controller 绑定到 cluster-admin 集群管理员即可

image-20210627225840775

如果不修改,报错如下:

image-20210627230328638

推送镜像到仓库

这里直接使用docker push,因为make docker-push也只使用了docker push

部署

结果确认

image-20210628092101436

创建自定义资源

结果确认

参考链接🔗

Kubernetes Operator 快速入门教程

operator-sdk 实战开发

最后更新于

这有帮助吗?