参考连接:
https://github.com/kubernetes/community/blob/master/contributors/devel/sig-architecture/api-conventions.md
https://kubernetes.io/docs/concepts/extend-kubernetes/api-extension/custom-resources/
Kubernetes API
- 在Kubernetes中,所有的事物都被抽象成一种资源,并且提供相应的REST API (API Server)对这些资源进行操作
例如:查看某个Deployment
# 启动代理 kubectl proxy --port=8080 后可直接通过本地8080端口访问api-server
# 查看 deployments 列表
curl -XGET http://127.0.0.1:8080/apis/apps/v1/deployments/
# 查看某一个deployment
curl -XGET http://127.0.0.1:8080/apis/apps/v1/namespaces/default/deployments/nginx-deployment
#删除Deployment
curl -XDELETE http://127.0.0.1:8080/apis/apps/v1/namespaces/default/deployments/nginx-deployment
- Kubernetes中对资源更改类的API都是声明式的
所谓 "声明式",就是告诉Kubernetes系统我们需要什么 ,也就是"期望状态",然后Kubernetes系统(controller组件)自己去计算执行路径使”实际状态“达到”期望状态“ 。相对于命令式的API来说有以下几个好处:- 天然支持幂等操作
- 支持多个客户端同时进行操作,且业务层不需要考虑加锁
- 对资源操作的API URI一般为 /apis/<group>/<version>/<resource> 或者是 /apis/<group>/<version>/namespaces/<namespace>/<resourceName>
#yaml
apiVersion: apps/v1
kind: Deployment
spec:
...
group和version通常一起在apiVersion字段中一起出现。
空("",/apis/v1)、单个单词("extensions", "apps"等)、以及以"*.k8s.io"为结尾的group是k8s保留的group,我们自定义API时group建议用域名或者子域名(widget.mycompany.com)
- 提供扩展机制实现自定义资源
Kubernetes object
在Kubernetes系统中,对象是持久化的实体,用来描述一个集群,通常一个对象可以包含如下信息
1. 什么容器化的应用在运行(以及在哪个Node 上)
2. 应用可以使用的资源
3. 应用运行时的一些策略,比如重启策略、升级策略,以及容错策略
一旦你创建了一个对象后,Kubernetes会确保这个对象一直处于你所期望的状态
object 结构
-
apiVersion
对象所属的API的group和version -
kind
对象所属的资源类型 -
Metadata
-
每个对象在嵌套对象Metadata中必须包含以下几个值
namespace:用来划分虚拟集群,不同的namespace可以对资源进行隔离,一个namespace下的资源没有办法直接使用name访问其他namespace的资源(可以使用fully qualified domain name),默认是 default. (namespace 详细说明文档)。
name: 当前namespace下唯一标识此对象的字符串,在访问对象时,在URL对象中会使用此值. (标识符文档)。
uid:唯一的时空值(通常是RFC 4122生成的标识),用于区分已删除并重新创建的同名对象。一般由系统自动生成。 -
每个对象在嵌套对象Metadata中应该包含以下值
resourceVersion:一个字符串,标识对象内部的版本号。主要用来控制并发修改,这个字段由服务端生成及修改,客户端不能修改,在提交修改对象时传给服务端,如果与服务端的不一致,则修改失败(HTTP返回值为409, 更多并发控制参考)。
generation:表示所需spec的特定生成的序列号,由系统生成,每一次修改spec时会单调递增。
creationTimestamp:一个字符串,代表创建对象的日期和时间的RFC 3339日期。
deletionTimestamp:一个字符串,代表将删除该资源的日期和时间的RFC 3339日期。当用户请求正常删除时,此字段由服务器设置,客户端无法直接设置。在此字段中的时间过后,资源将被删除
labels:字符串键和值的映射,可用于组织和分类对象(请参阅标签docs)
annotations:字符串键和值的映射,外部工具可以使用它来存储和检索有关此对象的任意元数据(请参见 批注docs)
-
-
spec 和 status
按照约定,Kubernetes API区分对象的所需状态的规范(称为“ spec”的嵌套对象字段)和当前时间的对象状态(称为“ status”的嵌套对象字段)。
spec:对所需状态的完整描述,包括了用户提供的配置设置(例如:可以部署在哪些Nodes上,运行什么样容器,有多少个副本等等),并与API对象一起保存在稳定的存储中。如果删除了spec,则将从系统中清除该对象。
status:记录了系统中对象的当前状态,通常与API对象保存在一起。
通过POST或PUT修改object时,spec 会立即更新并且可见,然后系统对应的组件会使status与spec保持一致。但是会忽略对status的修改,对status的修改需要操作子资源 “/status”
可以用一个yaml来表示要创建的对象,例如:
apiVersion: apps/v1 # for versions before 1.9.0 use apps/v1beta2
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:
- containerPort: 80
通过yaml文件创建资源
kubectl create -f nginx.yaml
自定义资源
自定义资源是 k8s API的一种扩展机制,在一个运行的k8s集群中,可以通过动态注册出现和消失。集群管理员可以独立于集群本身更新自定义资源。
Should I add a custom resource to my Kubernetes Cluster?
Should I use a configMap or a custom resource?
Use a ConfigMap if any of the following apply:
* There is an existing, well-documented config file format, such as a `mysql.cnf` or `pom.xml`.
* You want to put the entire config file into one key of a configMap.
* The main use of the config file is for a program running in a Pod on your cluster to consume the file to configure itself.
* Consumers of the file prefer to consume via file in a Pod or environment variable in a pod, rather than the Kubernetes API.
* You want to perform rolling updates via Deployment, etc., when the file is updated.
> **Note:** Use a [secret](https://kubernetes.io/docs/concepts/configuration/secret/) for sensitive data, which is similar to a configMap but more secure.
Use a custom resource (CRD or Aggregated API) if most of the following apply:
* You want to use Kubernetes client libraries and CLIs to create and update the new resource.
* You want top-level support from `kubectl`; for example, `kubectl get my-object object-name`.
* You want to build new automation that watches for updates on the new object, and then CRUD other objects, or vice versa.
* You want to write automation that handles updates to the object.
* You want to use Kubernetes API conventions like `.spec`, `.status`, and `.metadata`.
* You want the object to be an abstraction over a collection of controlled resources, or a summarization of other resources
添加自定义资源
k8s提供两种方式添加自定义资源
- CRD,比较简单,无需任何编程即可创建
-
API Aggregation,需要编程,但可以更好地控制API行为,例如如何存储数据以及在API版本之间进行转换
用CRD的方式创建一个自定义资源
创建 CustomResourceDefinition
创建新的CustomResourceDefinition(CRD)时,Kubernetes API Server将为您指定的每个版本创建一个新的RESTful资源路径。如CRD scope字段中所指定,CRD可以是命名空间或群集作用域。与现有的内置对象一样,删除名称空间也会删除该名称空间中的所有自定义对象。CustomResourceDefinitions本身是非命名空间的,并且可用于所有命名空间。
例如,将以下CustomResourceDefinition保存到resourcedefinition.yaml:
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
# name must match the spec fields below, and be in the form: <plural>.<group>
name: crontabs.stable.example.com
spec:
# group name to use for REST API: /apis/<group>/<version>
group: stable.example.com
# list of versions supported by this CustomResourceDefinition
versions:
- name: v1
# Each version can be enabled/disabled by Served flag.
served: true
# One and only one version must be marked as the storage version.
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
cronSpec:
type: string
image:
type: string
replicas:
type: integer
# either Namespaced or Cluster
scope: Namespaced
names:
# plural name to be used in the URL: /apis/<group>/<version>/<plural>
plural: crontabs
# singular name to be used as an alias on the CLI and for display
singular: crontab
# kind is normally the CamelCased singular type. Your resource manifests use this.
kind: CronTab
# shortNames allow shorter string to match your resource on the CLI
shortNames:
- ct
并创建它
kubectl apply -f resourcedefinition.yaml
然后在以下位置创建一个新的namespace的RESTful API端点
/apis/stable.example.com/v1/namespaces/*/crontabs/...
通过使用此endpoint URL可以创建和管理自定义对象
创建自定义对象
创建CustomResourceDefinition对象后,可以创建自定义对象。自定义对象可以包含自定义字段。这些字段可以包含任意JSON。在以下示例中,cronSpec和image字段是在kind的自定义对象中设置的CronTab
将以下YAML保存到my-crontab.yaml:
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
name: my-new-cron-object
spec:
cronSpec: "* * * * */5"
image: my-awesome-cron-image
并创建它
kubectl apply -f my-crontab.yaml
然后,您可以使用kubectl管理CronTab对象。例如:
$ kubectl get crontab
NAME AGE
my-new-cron-object 46s
使用kubectl时,资源名称不区分大小写,并且您可以使用CRD中定义的单数或复数形式以及任何短名称,例如:查看原始的YAML数据
$ kubectl get ct -o yaml
apiVersion: v1
items:
- apiVersion: stable.example.com/v1
kind: CronTab
metadata:
annotations:
kubectl.kubernetes.io/last-applied-configuration: |
{"apiVersion":"stable.example.com/v1","kind":"CronTab","metadata":{"annotations":{},"name":"my-new-cron-object","namespace":"default"},"spec":{"cronSpec":"* * * * */5","image":"my-awesome-cron-image"}}
creationTimestamp: "2020-07-22T18:39:36Z"
generation: 1
name: my-new-cron-object
namespace: default
resourceVersion: "36291"
selfLink: /apis/stable.example.com/v1/namespaces/default/crontabs/my-new-cron-object
uid: 75ed49cb-759c-45d9-8ce4-366ecb110717
spec:
cronSpec: '* * * * */5'
image: my-awesome-cron-image
删除CustomResourceDefinition
删除CustomResourceDefinition时,服务器将卸载RESTful API端点并删除其中存储的所有自定义对象
$ kubectl delete -f resourcedefinition.yaml
$ kubectl get crontabs
Error from server (NotFound): Unable to list "stable.example.com/v1, Resource=crontabs": the server could not find the requested resource (get crontabs.stable.example.com)
自定义控制器
上面我们创建了一个自定义资源和自定义对象,例如 my-new-cron-object 中制定了容器的image,但是并没有对应的Pod运行起来。 因为自定义资源需要和自定义控制器结合起来,才能完成自定义对象的意图。
目前有以下几种方式创建自定义控制器
- using KUDO (Kubernetes Universal Declarative Operator)
- using kubebuilder
- using Metacontroller along with WebHooks that you implement yourself
- using the Operator Framework
网友评论