k8s自定义controller三部曲之一:创建CRD(Custom Resource Definition)

本文涉及的产品
容器服务 Serverless 版 ACK Serverless,317元额度 多规格
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 通过自定义控制器开发深入理解k8s的控制器设计思想及其实现

欢迎访问我的GitHub

这里分类和汇总了欣宸的全部原创(含配套源码): https://github.com/zq2599/blog_demos

本篇概览

  • k8s系统中controller扮演着重要角色,开发自定义controller是深入学习和理解controller的有效途径,《k8s自定义controller三部曲》系列会逐步完成一次完整的自定义controller实战;

实战概要

整个三部曲的目标如下:

  1. 创建自定义API对象(Custom Resource Definition),名为Student
  2. 用代码生成工具生成informer和client相关代码;
  3. 创建并运行自定义控制器,k8s环境中所有Student相关的"增、删、改"操作都会被此控制器监听到,可以根据实际需求在控制器中编写业务代码;

环境信息

  • 实战环境的版本信息如下,请确保以下软件都已运行正常(Etcd只是用来查看数据的,可以选择不装),并且kubectl工具可以在k8s环境正常操作:
  1. 操作系统 :CentOS Linux release 7.6.1810
  2. Kubernetes:1.13
  3. Go版本:1.12
  4. Etcd:3.3.1(查看数据时用到,也可以不安装)

本篇概要

  • 本篇是三部曲的第一篇,我们先自定义一个API对象Student,然后让k8s接收Student的定义,这样我们在k8s创建Student对象时,k8s就能接收并保存了,就像先有了pod定义,才能创建pod一样;

三部曲所有文章链接

  1. 《k8s自定义controller三部曲之一:创建CRD(Custom Resource Definition)》
  2. 《k8s自定义controller三部曲之二:自动生成代码》
  3. 《k8s自定义controller三部曲之三:编写controller代码》

源码下载

  • 接下来详细讲述应用的编码过程,如果您不想自己写代码,也可以在GitHub下载完整的应用源码,地址和链接信息如下表所示:
名称 链接 备注
项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
  • 这个git项目中有多个文件夹,本章源码在k8s_customize_controller这个文件夹下,如下图红框所示:

在这里插入图片描述

创建CRD

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  # metadata.name的内容是由"复数名.分组名"构成,如下,students是复数名,bolingcavalry.k8s.io是分组名
  name: students.bolingcavalry.k8s.io
spec:
  # 分组名,在REST API中也会用到的,格式是: /apis/分组名/CRD版本
  group: bolingcavalry.k8s.io
  # list of versions supported by this CustomResourceDefinition
  versions:
    - name: v1
      # 是否有效的开关.
      served: true
      # 只有一个版本能被标注为storage
      storage: true
  # 范围是属于namespace的
  scope: Namespaced
  names:
    # 复数名
    plural: students
    # 单数名
    singular: student
    # 类型名
    kind: Student
    # 简称,就像service的简称是svc
    shortNames:
    - stu
  • 在student.yaml所在目录执行命令kubectl apply -f student.yaml,即可在k8s环境创建Student的定义,今后如果发起对类型为Student的对象的处理,k8s的api server就能识别到该对象类型了,如下所示,可以用kubectl get crdkubectl describe crd stu命令查看更多细节,stu是在student.yaml中定义的简称:
[root@master custom_controller]# kubectl apply -f student.yaml
customresourcedefinition.apiextensions.k8s.io/students.bolingcavalry.k8s.io created
[root@master custom_controller]# kubectl get crd
NAME                            CREATED AT
students.bolingcavalry.k8s.io   2019-03-30T13:33:13Z
[root@master custom_controller]# kubectl describe crd stu
Name:         students.bolingcavalry.k8s.io
Namespace:    
Labels:       <none>
Annotations:  kubectl.kubernetes.io/last-applied-configuration:
                {"apiVersion":"apiextensions.k8s.io/v1beta1","kind":"CustomResourceDefinition","metadata":{"annotations":{},"name":"students.bolingcavalry...
API Version:  apiextensions.k8s.io/v1beta1
Kind:         CustomResourceDefinition
Metadata:
  Creation Timestamp:  2019-03-30T13:33:13Z
  Generation:          1
  Resource Version:    292010
  Self Link:           /apis/apiextensions.k8s.io/v1beta1/customresourcedefinitions/students.bolingcavalry.k8s.io
  UID:                 5e4ceb6e-52f0-11e9-96e1-000c29f1f9c9
  ...
  ..
  .
  • 如果您已配置好etcdctl,可以访问k8s的etcd上存储的数据,那么执行以下命令,就可以看到新的CRD已经保存在etcd中了:
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key get /registry/apiextensions.k8s.io/customresourcedefinitions/ --prefix
  • 上述命令用来查看路径/registry/apiextensions.k8s.io/customresourcedefinitions/之下的所有键值对,可以见到刚才创建的CRD信息,如下:
/registry/apiextensions.k8s.io/customresourcedefinitions/students.bolingcavalry.k8s.io{
    "kind": "CustomResourceDefinition",
    "apiVersion": "apiextensions.k8s.io/v1beta1",
    "metadata": {
        "name": "students.bolingcavalry.k8s.io",
        "uid": "5e4ceb6e-52f0-11e9-96e1-000c29f1f9c9",
        "generation": 1,
        "creationTimestamp": "2019-03-30T13:33:13Z",
        "annotations": {
            "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"apiextensions.k8s.io/v1beta1\",\"kind\":\"CustomResourceDefinition\",\"metadata\":{\"annotations\":{},\"name\":\"students.bolingcavalry.k8s.io\"},\"spec\":{\"group\":\"bolingcavalry.k8s.io\",\"names\":{\"kind\":\"Student\",\"plural\":\"students\",\"shortNames\":[\"stu\"],\"singular\":\"student\"},\"scope\":\"Namespaced\",\"versions\":[{\"name\":\"v1\",\"served\":true,\"storage\":true}]}}\n"
        }
    },
    "spec": {
        "group": "bolingcavalry.k8s.io",
        "version": "v1",
        "names": {
            "plural": "students",
            "singular": "student",
            "shortNames": [
                "stu"
            ],
            "kind": "Student",
            "listKind": "StudentList"
        },
        "scope": "Namespaced",
        "versions": [
            {
                "name": "v1",
                "served": true,
                "storage": true
            }
        ],
        "conversion": {
            "strategy": "None"
        }
    },
    "status": {
        "conditions": [
            {
                "type": "NamesAccepted",
                "status": "True",
                "lastTransitionTime": "2019-03-30T13:33:13Z",
                "reason": "NoConflicts",
                "message": "no conflicts found"
            },
            {
                "type": "Established",
                "status": "True",
                "lastTransitionTime": null,
                "reason": "InitialNamesAccepted",
                "message": "the initial names have been accepted"
            }
        ],
        "acceptedNames": {
            "plural": "students",
            "singular": "student",
            "shortNames": [
                "stu"
            ],
            "kind": "Student",
            "listKind": "StudentList"
        },
        "storedVersions": [
            "v1"
        ]
    }
}

创建Student对象

  • 前面的步骤使得k8s能识别Student类型了,接下来创建个Student对象试试;
  • 创建object-student.yaml文件,内容如下:
apiVersion: bolingcavalry.k8s.io/v1
kind: Student
metadata:
  name: object-student
spec:
  name: "张三"
  school: "深圳中学"
  • 在object-student.yaml文件所在目录执行命令kubectl apply -f object-student.yaml,会看到提示创建成功:
[root@master custom_controller]# kubectl apply -f object-student.yaml
student.bolingcavalry.k8s.io/object-student created
  • 执行命令kubectl get stu可见已创建成功的Student对象:
[root@master custom_controller]# kubectl get stu
NAME             AGE
object-student   15s
  • 创建成功的Stutend对象存储在etcd中是什么样的呢,如果您的etcdctl已经配置好,执行以下命令即可:
ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/etc/kubernetes/pki/etcd/ca.crt --cert=/etc/kubernetes/pki/etcd/healthcheck-client.crt --key=/etc/kubernetes/pki/etcd/healthcheck-client.key get /registry/bolingcavalry.k8s.io/students/default/object-student --print-value-only
  • 控制台输出的就是该Student对象存储在etcd中的内容,如下:
{
    "apiVersion": "bolingcavalry.k8s.io/v1",
    "kind": "Student",
    "metadata": {
        "annotations": {
            "kubectl.kubernetes.io/last-applied-configuration": "{\"apiVersion\":\"bolingcavalry.k8s.io/v1\",\"kind\":\"Student\",\"metadata\":{\"annotations\":{},\"name\":\"object-student\",\"namespace\":\"default\"},\"spec\":{\"name\":\"张三\",\"school\":\"深圳中学\"}}\n"
        },
        "creationTimestamp": "2019-03-31T02:56:25Z",
        "generation": 1,
        "name": "object-student",
        "namespace": "default",
        "uid": "92927d0d-5360-11e9-9d2a-000c29f1f9c9"
    },
    "spec": {
        "name": "张三",
        "school": "深圳中学"
    }
}
  • 至此,自定义API对象(也就是CRD)就创建成功了,此刻我们只是让k8s能识别到Student这个对象的身份,但是当我们创建Student对象的时候,还没有触发任何业务(相对于创建Pod对象的时候,会触发kubelet在node节点创建docker容器),这也是后面的章节要完成的任务,点击链接进入下一段实战: 《k8s自定义controller三部曲之二:自动生成代码》

欢迎关注阿里云开发者社区博客:程序员欣宸

学习路上,你不孤单,欣宸原创一路相伴...
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
1月前
|
Kubernetes 负载均衡 应用服务中间件
k8s学习--ingress详细解释与应用(nginx ingress controller))
k8s学习--ingress详细解释与应用(nginx ingress controller))
167 0
|
3月前
|
存储 Kubernetes 监控
在K8S中,Resource Quotas是什么?如何做资源管理的?
在K8S中,Resource Quotas是什么?如何做资源管理的?
|
3月前
|
弹性计算 运维 Kubernetes
Kubernetes(K8S) Controller - Deployment 介绍
Kubernetes(K8S) Controller - Deployment 介绍
38 1
|
3月前
|
Kubernetes 容器 Perl
在K8S中,Replica Set和Replication Controller之间有什么区别?
在K8S中,Replica Set和Replication Controller之间有什么区别?
|
3月前
|
存储 Kubernetes 关系型数据库
Kubernetes(K8S) Controller - StatefulSet、DaemonSet 介绍
Kubernetes(K8S) Controller - StatefulSet、DaemonSet 介绍
33 0
|
5月前
|
Kubernetes 容器 Perl
k8s部署seata 报错 没有提供足够的身份验证信息 [ http-nio-7091-exec-2] [ty.JwtAuthenticationEntryPoint] [ commence] [] : Responding with unauthorized error. Message - Full authentication is required to access this resource
Kubernetes pod 在16:12时出现两次错误,错误信息显示需要完整认证才能访问资源。尽管有此错误,但页面可正常访问。附有yaml配置文件的图片。
445 2
|
6月前
|
运维 Kubernetes 容灾
kubernetes核心技术之Controller控制器知识总结
kubernetes核心技术之Controller控制器知识总结
60 1
|
22天前
|
JSON Kubernetes 容灾
ACK One应用分发上线:高效管理多集群应用
ACK One应用分发上线,主要介绍了新能力的使用场景
|
23天前
|
Kubernetes 持续交付 开发工具
ACK One GitOps:ApplicationSet UI简化多集群GitOps应用管理
ACK One GitOps新发布了多集群应用控制台,支持管理Argo CD ApplicationSet,提升大规模应用和集群的多集群GitOps应用分发管理体验。
|
1月前
|
Kubernetes Cloud Native 云计算
云原生之旅:Kubernetes 集群的搭建与实践
【8月更文挑战第67天】在云原生技术日益成为IT行业焦点的今天,掌握Kubernetes已成为每个软件工程师必备的技能。本文将通过浅显易懂的语言和实际代码示例,引导你从零开始搭建一个Kubernetes集群,并探索其核心概念。无论你是初学者还是希望巩固知识的开发者,这篇文章都将为你打开一扇通往云原生世界的大门。
120 17